Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Put off evaluation of concatenation repeat expresions

 until after parameters are defined. This allows parms
 to be used in repeat expresions.

 Add the builtin $signed system function.
  • Loading branch information...
commit 8667b9a35dc2571db704ac814b7880d17ca77f5d 1 parent 00defb0
steve authored
View
29 README.txt
@@ -405,6 +405,35 @@ constructs.
- force to nets are not supported. Force to variables, and
assign/deassign, are supported.
+5.0 Nonstandard Constructs
+
+Icarus Verilog includes some features that are not part of the
+IEEE1364 standard, but have well defined meaning. These are extensions
+to the language.
+
+ $sizeof(<expr>)
+ This system function returns the size in bits of the
+ expression that is its argument. The result of this
+ function is undefined if the argument doesn't have a
+ self-determined size.
+
+ Builtin system functions
+
+ Certain of the system functions have well defined meanings, so
+ can theoretically be evaluated at compile time, instead of
+ using runtime VPI code. Doing so means that VPI cannot
+ override the definitions of functions handled in this
+ manner. On the other hand, this makes them synthesizeable, and
+ also allows for more agressive constant propagation. The
+ functions handled in this manner are:
+
+ $signed
+ $sizeof
+ $unsigned
+
+ Implementations of these system functions in VPI modules will
+ be ignored.
+
6.0 CREDITS
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
View
13 design_dump.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: design_dump.cc,v 1.122 2002/03/09 02:10:22 steve Exp $"
+#ident "$Id: design_dump.cc,v 1.123 2002/05/05 21:11:49 steve Exp $"
#endif
# include "config.h"
@@ -850,8 +850,8 @@ void NetEBinary::dump(ostream&o) const
void NetEConcat::dump(ostream&o) const
{
- if (repeat_ != 1)
- o << repeat_;
+ if (repeat_)
+ o << *repeat_;
if (parms_[0])
o << "{" << *parms_[0];
@@ -980,6 +980,13 @@ void Design::dump(ostream&o) const
/*
* $Log: design_dump.cc,v $
+ * Revision 1.123 2002/05/05 21:11:49 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.122 2002/03/09 02:10:22 steve
* Add the NetUserFunc netlist node.
*
View
37 elab_expr.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: elab_expr.cc,v 1.57 2002/04/27 05:03:46 steve Exp $"
+#ident "$Id: elab_expr.cc,v 1.58 2002/05/05 21:11:49 steve Exp $"
#endif
# include "config.h"
@@ -182,6 +182,29 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
return sub;
}
+ /* Interpret the internal $sizeof system function to return
+ the bit width of the sub-expression. The value of the
+ sub-expression is not used, so the expression itself can be
+ deleted. */
+ if (strcmp(path_.peek_name(0), "$sizeof") == 0) {
+ if ((parms_.count() != 1) || (parms_[0] == 0)) {
+ cerr << get_line() << ": error: The $sizeof() function "
+ << "takes exactly one(1) argument." << endl;
+ des->errors += 1;
+ return 0;
+ }
+
+ PExpr*expr = parms_[0];
+ NetExpr*sub = expr->elaborate_expr(des, scope, true);
+ verinum val (sub->expr_width(), sizeof(unsigned));
+ delete sub;
+
+ sub = new NetEConst(val);
+ sub->set_line(*this);
+
+ return sub;
+ }
+
unsigned wid = 32;
if (strcmp(path_.peek_name(0), "$time") == 0)
@@ -322,7 +345,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
{
- unsigned repeat = 1;
+ NetExpr* repeat = 0;
/* If there is a repeat expression, then evaluate the constant
value and set the repeat count. */
@@ -338,10 +361,9 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
cerr << get_line() << ": : The expression is: "
<< *tmp << endl;
des->errors += 1;
- return 0;
}
- repeat = rep->value().as_ulong();
+ repeat = rep;
}
/* Make the empty concat expression. */
@@ -842,6 +864,13 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
/*
* $Log: elab_expr.cc,v $
+ * Revision 1.58 2002/05/05 21:11:49 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.57 2002/04/27 05:03:46 steve
* Preserve stringiness string part select and concatenation.
*
View
28 elab_pexpr.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: elab_pexpr.cc,v 1.13 2002/01/28 00:52:41 steve Exp $"
+#ident "$Id: elab_pexpr.cc,v 1.14 2002/05/05 21:11:50 steve Exp $"
#endif
# include "config.h"
@@ -66,28 +66,21 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
*/
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
{
- unsigned repeat = 1;
+ NetExpr* repeat = 0;
/* If there is a repeat expression, then evaluate the constant
- value and set the repeat count.
-
- XXXX Potential bug XXX In principle, the repeat expression
- can have a parameter name in it. Since where are in the
- working of parameters now, we will not be able to
- accurately evaluate such expressions. So eventually, I will
- need to be able to defer the evaluation of the expression. */
+ value and set the repeat count. */
if (repeat_) {
- verinum*vrep = repeat_->eval_const(des, scope);
- if (vrep == 0) {
+ repeat = repeat_->elaborate_pexpr(des, scope);
+ if (repeat == 0) {
cerr << get_line() << ": error: "
"concatenation repeat expression cannot be evaluated."
<< endl;
des->errors += 1;
- return 0;
}
- repeat = vrep->as_ulong();
- delete vrep;
+ /* continue on even if the repeat expression doesn't
+ work, as we can find more errors. */
}
/* Make the empty concat expression. */
@@ -224,6 +217,13 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
/*
* $Log: elab_pexpr.cc,v $
+ * Revision 1.14 2002/05/05 21:11:50 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.13 2002/01/28 00:52:41 steve
* Add support for bit select of parameters.
* This leads to a NetESelect node and the
View
30 eval_tree.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: eval_tree.cc,v 1.37 2002/04/27 05:03:46 steve Exp $"
+#ident "$Id: eval_tree.cc,v 1.38 2002/05/05 21:11:50 steve Exp $"
#endif
# include "config.h"
@@ -705,6 +705,9 @@ NetEConst* NetEBShift::eval_tree()
NetEConst* NetEConcat::eval_tree()
{
+ unsigned repeat_val = repeat();
+
+ unsigned gap = 0;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
// Parameter not here? This is an error, but presumably
@@ -712,10 +715,13 @@ NetEConst* NetEConcat::eval_tree()
if (parms_[idx] == 0)
continue;
+
// If this parameter is already a constant, all is well
// so go on.
- if (dynamic_cast<NetEConst*>(parms_[idx]))
+ if (dynamic_cast<NetEConst*>(parms_[idx])) {
+ gap += parms_[idx]->expr_width();
continue;
+ }
// Finally, try to evaluate the parameter expression
// that is here. If I succeed, reset the parameter to
@@ -725,23 +731,24 @@ NetEConst* NetEConcat::eval_tree()
if (expr) {
delete parms_[idx];
parms_[idx] = expr;
+ gap += expr->expr_width();
}
}
// Handle the special case that the repeat expression is
// zero. In this case, just return a 0 value with the expected
// width.
- if (repeat_ == 0) {
+ if (repeat_val == 0) {
verinum val (verinum::V0, expr_width());
NetEConst*res = new NetEConst(val);
res->set_width(val.len());
return res;
}
- // Figure out the width of the repeated expression, and make a
- // verinum to hold the result.
- unsigned gap = expr_width() / repeat_;
- verinum val (verinum::Vx, repeat_ * gap);
+ // At this point, the "gap" is the width of a single repeat of
+ // the concatenation. The total width of the result is the gap
+ // times the repeat count.
+ verinum val (verinum::Vx, repeat_val * gap);
// build up the result from least significant to most.
@@ -754,7 +761,7 @@ NetEConst* NetEConcat::eval_tree()
verinum tmp = expr->value();
for (unsigned bit = 0; bit < tmp.len(); bit += 1, cur += 1)
- for (unsigned rep = 0 ; rep < repeat_ ; rep += 1)
+ for (unsigned rep = 0 ; rep < repeat_val ; rep += 1)
val.set(rep*gap+cur, tmp[bit]);
is_string_flag = is_string_flag && tmp.is_string();
@@ -1079,6 +1086,13 @@ NetEConst* NetEUReduce::eval_tree()
/*
* $Log: eval_tree.cc,v $
+ * Revision 1.38 2002/05/05 21:11:50 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.37 2002/04/27 05:03:46 steve
* Preserve stringiness string part select and concatenation.
*
View
95 net_expr.cc
@@ -17,12 +17,98 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT)
-#ident "$Id: net_expr.cc,v 1.2 2002/01/29 22:36:31 steve Exp $"
+#ident "$Id: net_expr.cc,v 1.3 2002/05/05 21:11:50 steve Exp $"
#endif
# include "config.h"
# include "netlist.h"
+NetEConcat::NetEConcat(unsigned cnt, NetExpr* r)
+: parms_(cnt), repeat_(r)
+{
+ if (repeat_ == 0) {
+ repeat_calculated_ = true;
+ repeat_value_ = 1;
+ } else {
+ repeat_calculated_ = false;
+ }
+
+ expr_width(0);
+}
+
+NetEConcat::~NetEConcat()
+{
+ for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
+ delete parms_[idx];
+}
+
+void NetEConcat::set(unsigned idx, NetExpr*e)
+{
+ assert(idx < parms_.count());
+ assert(parms_[idx] == 0);
+ parms_[idx] = e;
+ expr_width( expr_width() + e->expr_width() );
+}
+
+NetEConcat* NetEConcat::dup_expr() const
+{
+ NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
+ for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
+ if (parms_[idx]) {
+ NetExpr*tmp = parms_[idx]->dup_expr();
+ assert(tmp);
+ dup->parms_[idx] = tmp;
+ }
+
+
+ dup->expr_width(expr_width());
+ return dup;
+}
+
+unsigned NetEConcat::repeat()
+{
+ if (repeat_calculated_)
+ return repeat_value_;
+
+ assert(repeat_);
+
+ if (! dynamic_cast<NetEConst*>(repeat_)) {
+ NetExpr*tmp = repeat_->eval_tree();
+ if (tmp != 0) {
+ delete repeat_;
+ repeat_ = tmp;
+ }
+ }
+
+ NetEConst*repeat_const = dynamic_cast<NetEConst*>(repeat_);
+
+ /* This should not be possible, as it was checked earlier to
+ assure that this is a constant expression. */
+ if (repeat_const == 0) {
+ cerr << get_line() << ": internal error: repeat expression "
+ << "is not a compile time constant." << endl;
+ cerr << get_line() << ": : Expression is: "
+ << *repeat_ << endl;
+ repeat_calculated_ = true;
+ repeat_value_ = 1;
+ return 1;
+ }
+
+ repeat_calculated_ = true;
+ repeat_value_ = repeat_const->value().as_ulong();
+
+ delete repeat_;
+ repeat_ = 0;
+
+ return repeat_value_;
+}
+
+unsigned NetEConcat::repeat() const
+{
+ assert(repeat_calculated_);
+ return repeat_value_;
+}
+
NetESelect::NetESelect(NetExpr*exp, NetExpr*base, unsigned wid)
: expr_(exp), base_(base)
{
@@ -60,6 +146,13 @@ bool NetESelect::set_width(unsigned w)
/*
* $Log: net_expr.cc,v $
+ * Revision 1.3 2002/05/05 21:11:50 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.2 2002/01/29 22:36:31 steve
* include config.h to eliminate warnings.
*
View
44 netlist.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: netlist.cc,v 1.184 2002/04/21 04:59:08 steve Exp $"
+#ident "$Id: netlist.cc,v 1.185 2002/05/05 21:11:50 steve Exp $"
#endif
# include "config.h"
@@ -1983,41 +1983,6 @@ NetEBShift* NetEBShift::dup_expr() const
return result;
}
-NetEConcat::NetEConcat(unsigned cnt, unsigned r)
-: parms_(cnt), repeat_(r)
-{
- expr_width(0);
-}
-
-NetEConcat::~NetEConcat()
-{
- for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
- delete parms_[idx];
-}
-
-void NetEConcat::set(unsigned idx, NetExpr*e)
-{
- assert(idx < parms_.count());
- assert(parms_[idx] == 0);
- parms_[idx] = e;
- expr_width( expr_width() + repeat_*e->expr_width() );
-}
-
-NetEConcat* NetEConcat::dup_expr() const
-{
- NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
- for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
- if (parms_[idx]) {
- NetExpr*tmp = parms_[idx]->dup_expr();
- assert(tmp);
- dup->parms_[idx] = tmp;
- }
-
-
- dup->expr_width(expr_width());
- return dup;
-}
-
NetEConst::NetEConst(const verinum&val)
: NetExpr(val.len()), value_(val)
{
@@ -2394,6 +2359,13 @@ const NetProc*NetTaskDef::proc() const
/*
* $Log: netlist.cc,v $
+ * Revision 1.185 2002/05/05 21:11:50 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.184 2002/04/21 04:59:08 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.
View
18 netlist.h
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: netlist.h,v 1.235 2002/04/21 22:31:02 steve Exp $"
+#ident "$Id: netlist.h,v 1.236 2002/05/05 21:11:50 steve Exp $"
#endif
/*
@@ -2332,13 +2332,14 @@ class NetEBShift : public NetEBinary {
class NetEConcat : public NetExpr {
public:
- NetEConcat(unsigned cnt, unsigned repeat =1);
+ NetEConcat(unsigned cnt, NetExpr* repeat =0);
~NetEConcat();
// Manipulate the parameters.
void set(unsigned idx, NetExpr*e);
- unsigned repeat() const { return repeat_; }
+ unsigned repeat();
+ unsigned repeat() const;
unsigned nparms() const { return parms_.count() ; }
NetExpr* parm(unsigned idx) const { return parms_[idx]; }
@@ -2352,7 +2353,9 @@ class NetEConcat : public NetExpr {
private:
svector<NetExpr*>parms_;
- unsigned repeat_;
+ NetExpr* repeat_;
+ unsigned repeat_value_;
+ bool repeat_calculated_;
};
/*
@@ -2977,6 +2980,13 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
+ * Revision 1.236 2002/05/05 21:11:50 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.235 2002/04/21 22:31:02 steve
* Redo handling of assignment internal delays.
* Leave it possible for them to be calculated
View
11 set_width.cc
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
-#ident "$Id: set_width.cc,v 1.21 2002/04/27 04:49:27 steve Exp $"
+#ident "$Id: set_width.cc,v 1.22 2002/05/05 21:11:50 steve Exp $"
#endif
# include "config.h"
@@ -220,7 +220,7 @@ bool NetEConcat::set_width(unsigned w)
if (parms_[idx] != 0)
sum += parms_[idx]->expr_width();
- sum *= repeat_;
+ sum *= repeat();
expr_width(sum);
if (sum != w) return false;
return true;
@@ -357,6 +357,13 @@ bool NetEUReduce::set_width(unsigned w)
/*
* $Log: set_width.cc,v $
+ * Revision 1.22 2002/05/05 21:11:50 steve
+ * Put off evaluation of concatenation repeat expresions
+ * until after parameters are defined. This allows parms
+ * to be used in repeat expresions.
+ *
+ * Add the builtin $signed system function.
+ *
* Revision 1.21 2002/04/27 04:49:27 steve
* If the verinum is already right, no need to reset it.
*
Please sign in to comment.
Something went wrong with that request. Please try again.