support evaluation of constant < in expressions.
This commit is contained in:
parent
8376553349
commit
7ef3b44ab1
69
elab_expr.cc
69
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.34 2001/01/14 23:04:55 steve Exp $"
|
||||
#ident "$Id: elab_expr.cc,v 1.35 2001/02/09 05:44:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -145,6 +145,12 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
|||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a call to a system function, generate the proper expression
|
||||
* nodes to represent the call in the netlist. Since we don't support
|
||||
* size_tf functions, make assumptions about widths based on some
|
||||
* known function names.
|
||||
*/
|
||||
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned wid = 32;
|
||||
|
|
@ -152,11 +158,43 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
|||
if (name_ == "$time")
|
||||
wid = 64;
|
||||
|
||||
NetESFunc*fun = new NetESFunc(name_, wid, parms_.count());
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
|
||||
/* How many parameters are there? The Verilog language allows
|
||||
empty parameters in certain contexts, so the parser will
|
||||
allow things like func(1,,3). It will also cause func() to
|
||||
be interpreted as a single empty parameter.
|
||||
|
||||
Functions cannot really take empty parameters, but the
|
||||
case ``func()'' is the same as no parmaters at all. So
|
||||
catch that special case here. */
|
||||
unsigned nparms = parms_.count();
|
||||
if ((nparms == 1) && (parms_[0] == 0))
|
||||
nparms = 0;
|
||||
|
||||
NetESFunc*fun = new NetESFunc(name_, wid, nparms);
|
||||
|
||||
/* Now run through the expected parameters. If we find that
|
||||
there are missing parameters, print an error message. */
|
||||
|
||||
unsigned missing_parms = 0;
|
||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
|
||||
PExpr*expr = parms_[idx];
|
||||
NetExpr*tmp = expr->elaborate_expr(des, scope);
|
||||
fun->parm(idx, tmp);
|
||||
if (expr) {
|
||||
NetExpr*tmp = expr->elaborate_expr(des, scope);
|
||||
fun->parm(idx, tmp);
|
||||
|
||||
} else {
|
||||
missing_parms += 1;
|
||||
fun->parm(idx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (missing_parms > 0) {
|
||||
cerr << get_line() << ": error: The function " << name_
|
||||
<< " has been called with empty parameters." << endl;
|
||||
cerr << get_line() << ": : Verilog doesn't allow "
|
||||
<< "passing empty parameters to functions." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
return fun;
|
||||
|
|
@ -195,10 +233,24 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
|||
of the function being called. The scope of the called
|
||||
function is elaborated when the definition is elaborated. */
|
||||
|
||||
unsigned missing_parms = 0;
|
||||
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
|
||||
PExpr*tmp = parms_[idx];
|
||||
assert(tmp);
|
||||
parms[idx] = tmp->elaborate_expr(des, scope);
|
||||
if (tmp) {
|
||||
parms[idx] = tmp->elaborate_expr(des, scope);
|
||||
|
||||
} else {
|
||||
missing_parms += 1;
|
||||
parms[idx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing_parms > 0) {
|
||||
cerr << get_line() << ": error: The function " << name_
|
||||
<< " has been called with empty parameters." << endl;
|
||||
cerr << get_line() << ": : Verilog doesn't allow "
|
||||
<< "passing empty parameters to functions." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -545,6 +597,9 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.35 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.34 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
|
|
|
|||
11
elaborate.cc
11
elaborate.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elaborate.cc,v 1.206 2001/02/07 21:47:13 steve Exp $"
|
||||
#ident "$Id: elaborate.cc,v 1.207 2001/02/09 05:44:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -2031,10 +2031,10 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
|||
}
|
||||
|
||||
if (NetExpr*tmp = ce->eval_tree()) {
|
||||
if (dynamic_cast<NetEConst*>(tmp))
|
||||
if (dynamic_cast<NetEConst*>(tmp)) {
|
||||
cerr << get_line() << ": warning: condition expression "
|
||||
"is constant." << endl;
|
||||
|
||||
"of for-loop is constant." << endl;
|
||||
}
|
||||
ce = tmp;
|
||||
}
|
||||
|
||||
|
|
@ -2367,6 +2367,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
|||
|
||||
/*
|
||||
* $Log: elaborate.cc,v $
|
||||
* Revision 1.207 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.206 2001/02/07 21:47:13 steve
|
||||
* Fix expression widths for rvalues and parameters (PR#131,132)
|
||||
*
|
||||
|
|
|
|||
52
eval_tree.cc
52
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.22 2001/02/07 02:46:31 steve Exp $"
|
||||
#ident "$Id: eval_tree.cc,v 1.23 2001/02/09 05:44:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -161,6 +161,50 @@ NetEConst* NetEBComp::eval_eqeq_()
|
|||
}
|
||||
|
||||
|
||||
NetEConst* NetEBComp::eval_less_()
|
||||
{
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
if (r == 0) return 0;
|
||||
|
||||
verinum rv = r->value();
|
||||
if (! rv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Detect the case where the right side is greater that or
|
||||
equal to the largest value the left side can possibly
|
||||
have. */
|
||||
assert(left_->expr_width() > 0);
|
||||
verinum lv (verinum::V1, left_->expr_width());
|
||||
if (lv < rv) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
if (l == 0) return 0;
|
||||
lv = l->value();
|
||||
if (! lv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.has_sign() && rv.has_sign() && (lv.as_long() < rv.as_long())) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.as_ulong() < rv.as_ulong()) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
verinum result(verinum::V0, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_leeq_()
|
||||
{
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
|
|
@ -358,6 +402,9 @@ NetEConst* NetEBComp::eval_tree()
|
|||
case 'n': // not-equal (!=)
|
||||
return eval_neeq_();
|
||||
|
||||
case '<': // Less than
|
||||
return eval_less_();
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -843,6 +890,9 @@ NetEConst* NetEUReduce::eval_tree()
|
|||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.23 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.22 2001/02/07 02:46:31 steve
|
||||
* Support constant evaluation of / and % (PR#124)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.195 2001/01/18 03:16:35 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.196 2001/02/09 05:44:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -2182,6 +2182,7 @@ class NetEBComp : public NetEBinary {
|
|||
|
||||
private:
|
||||
NetEConst*eval_eqeq_();
|
||||
NetEConst*eval_less_();
|
||||
NetEConst*eval_leeq_();
|
||||
NetEConst*eval_neeq_();
|
||||
NetEConst*eval_eqeqeq_();
|
||||
|
|
@ -2852,6 +2853,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.196 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.195 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
*
|
||||
|
|
|
|||
30
verinum.cc
30
verinum.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: verinum.cc,v 1.25 2001/02/08 05:38:18 steve Exp $"
|
||||
#ident "$Id: verinum.cc,v 1.26 2001/02/09 05:44:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "verinum.h"
|
||||
|
|
@ -420,7 +420,7 @@ verinum::V operator <= (const verinum&left, const verinum&right)
|
|||
}
|
||||
|
||||
for (idx = right.len() ; idx > left.len() ; idx -= 1) {
|
||||
if (right[idx-1] != verinum::V0) return verinum::V0;
|
||||
if (right[idx-1] != verinum::V0) return verinum::V1;
|
||||
}
|
||||
|
||||
while (idx > 0) {
|
||||
|
|
@ -435,6 +435,29 @@ verinum::V operator <= (const verinum&left, const verinum&right)
|
|||
return verinum::V1;
|
||||
}
|
||||
|
||||
verinum::V operator < (const verinum&left, const verinum&right)
|
||||
{
|
||||
unsigned idx;
|
||||
for (idx = left.len() ; idx > right.len() ; idx -= 1) {
|
||||
if (left[idx-1] != verinum::V0) return verinum::V0;
|
||||
}
|
||||
|
||||
for (idx = right.len() ; idx > left.len() ; idx -= 1) {
|
||||
if (right[idx-1] != verinum::V0) return verinum::V1;
|
||||
}
|
||||
|
||||
while (idx > 0) {
|
||||
if (left[idx-1] == verinum::Vx) return verinum::Vx;
|
||||
if (left[idx-1] == verinum::Vz) return verinum::Vx;
|
||||
if (right[idx-1] == verinum::Vx) return verinum::Vx;
|
||||
if (right[idx-1] == verinum::Vz) return verinum::Vx;
|
||||
if (left[idx-1] > right[idx-1]) return verinum::V0;
|
||||
idx -= 1;
|
||||
}
|
||||
|
||||
return verinum::V0;
|
||||
}
|
||||
|
||||
static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c)
|
||||
{
|
||||
unsigned sum = 0;
|
||||
|
|
@ -743,6 +766,9 @@ verinum::V operator & (verinum::V l, verinum::V r)
|
|||
|
||||
/*
|
||||
* $Log: verinum.cc,v $
|
||||
* Revision 1.26 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.25 2001/02/08 05:38:18 steve
|
||||
* trim the length of unsized numbers.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: verinum.h,v 1.16 2001/02/07 02:46:31 steve Exp $"
|
||||
#ident "$Id: verinum.h,v 1.17 2001/02/09 05:44:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
|
|
@ -110,6 +110,7 @@ extern verinum::V operator & (verinum::V l, verinum::V r);
|
|||
|
||||
extern verinum::V operator == (const verinum&left, const verinum&right);
|
||||
extern verinum::V operator <= (const verinum&left, const verinum&right);
|
||||
extern verinum::V operator < (const verinum&left, const verinum&right);
|
||||
extern verinum operator + (const verinum&left, const verinum&right);
|
||||
extern verinum operator - (const verinum&left, const verinum&right);
|
||||
extern verinum operator * (const verinum&left, const verinum&right);
|
||||
|
|
@ -120,6 +121,9 @@ extern verinum v_not(const verinum&left);
|
|||
|
||||
/*
|
||||
* $Log: verinum.h,v $
|
||||
* Revision 1.17 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.16 2001/02/07 02:46:31 steve
|
||||
* Support constant evaluation of / and % (PR#124)
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue