support evaluation of constant < in expressions.
This commit is contained in:
parent
8376553349
commit
7ef3b44ab1
63
elab_expr.cc
63
elab_expr.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -145,6 +145,12 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||||
return tmp;
|
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
|
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
unsigned wid = 32;
|
unsigned wid = 32;
|
||||||
|
|
@ -152,11 +158,43 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||||
if (name_ == "$time")
|
if (name_ == "$time")
|
||||||
wid = 64;
|
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];
|
PExpr*expr = parms_[idx];
|
||||||
|
if (expr) {
|
||||||
NetExpr*tmp = expr->elaborate_expr(des, scope);
|
NetExpr*tmp = expr->elaborate_expr(des, scope);
|
||||||
fun->parm(idx, tmp);
|
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;
|
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
|
of the function being called. The scope of the called
|
||||||
function is elaborated when the definition is elaborated. */
|
function is elaborated when the definition is elaborated. */
|
||||||
|
|
||||||
|
unsigned missing_parms = 0;
|
||||||
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
|
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
|
||||||
PExpr*tmp = parms_[idx];
|
PExpr*tmp = parms_[idx];
|
||||||
assert(tmp);
|
if (tmp) {
|
||||||
parms[idx] = tmp->elaborate_expr(des, scope);
|
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 $
|
* $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
|
* Revision 1.34 2001/01/14 23:04:55 steve
|
||||||
* Generalize the evaluation of floating point delays, and
|
* Generalize the evaluation of floating point delays, and
|
||||||
* get it working with delay assignment statements.
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2031,10 +2031,10 @@ NetProc* PForStatement::elaborate(Design*des, const string&path) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NetExpr*tmp = ce->eval_tree()) {
|
if (NetExpr*tmp = ce->eval_tree()) {
|
||||||
if (dynamic_cast<NetEConst*>(tmp))
|
if (dynamic_cast<NetEConst*>(tmp)) {
|
||||||
cerr << get_line() << ": warning: condition expression "
|
cerr << get_line() << ": warning: condition expression "
|
||||||
"is constant." << endl;
|
"of for-loop is constant." << endl;
|
||||||
|
}
|
||||||
ce = tmp;
|
ce = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2367,6 +2367,9 @@ Design* elaborate(const map<string,Module*>&modules,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elaborate.cc,v $
|
* $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
|
* Revision 1.206 2001/02/07 21:47:13 steve
|
||||||
* Fix expression widths for rvalues and parameters (PR#131,132)
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#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
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# 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* NetEBComp::eval_leeq_()
|
||||||
{
|
{
|
||||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||||
|
|
@ -358,6 +402,9 @@ NetEConst* NetEBComp::eval_tree()
|
||||||
case 'n': // not-equal (!=)
|
case 'n': // not-equal (!=)
|
||||||
return eval_neeq_();
|
return eval_neeq_();
|
||||||
|
|
||||||
|
case '<': // Less than
|
||||||
|
return eval_less_();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -843,6 +890,9 @@ NetEConst* NetEUReduce::eval_tree()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: eval_tree.cc,v $
|
* $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
|
* Revision 1.22 2001/02/07 02:46:31 steve
|
||||||
* Support constant evaluation of / and % (PR#124)
|
* Support constant evaluation of / and % (PR#124)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2182,6 +2182,7 @@ class NetEBComp : public NetEBinary {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NetEConst*eval_eqeq_();
|
NetEConst*eval_eqeq_();
|
||||||
|
NetEConst*eval_less_();
|
||||||
NetEConst*eval_leeq_();
|
NetEConst*eval_leeq_();
|
||||||
NetEConst*eval_neeq_();
|
NetEConst*eval_neeq_();
|
||||||
NetEConst*eval_eqeqeq_();
|
NetEConst*eval_eqeqeq_();
|
||||||
|
|
@ -2852,6 +2853,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $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
|
* Revision 1.195 2001/01/18 03:16:35 steve
|
||||||
* NetMux needs a scope. (PR#115)
|
* 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
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#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
|
#endif
|
||||||
|
|
||||||
# include "verinum.h"
|
# 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) {
|
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) {
|
while (idx > 0) {
|
||||||
|
|
@ -435,6 +435,29 @@ verinum::V operator <= (const verinum&left, const verinum&right)
|
||||||
return verinum::V1;
|
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)
|
static verinum::V add_with_carry(verinum::V l, verinum::V r, verinum::V&c)
|
||||||
{
|
{
|
||||||
unsigned sum = 0;
|
unsigned sum = 0;
|
||||||
|
|
@ -743,6 +766,9 @@ verinum::V operator & (verinum::V l, verinum::V r)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: verinum.cc,v $
|
* $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
|
* Revision 1.25 2001/02/08 05:38:18 steve
|
||||||
* trim the length of unsized numbers.
|
* trim the length of unsized numbers.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#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
|
#endif
|
||||||
|
|
||||||
# include <string>
|
# 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::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);
|
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 $
|
* $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
|
* Revision 1.16 2001/02/07 02:46:31 steve
|
||||||
* Support constant evaluation of / and % (PR#124)
|
* Support constant evaluation of / and % (PR#124)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue