diff --git a/eval_tree.cc b/eval_tree.cc index 3619f9200..acf63de12 100644 --- a/eval_tree.cc +++ b/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.16 2001/01/01 21:49:33 steve Exp $" +#ident "$Id: eval_tree.cc,v 1.17 2001/01/02 03:23:40 steve Exp $" #endif # include "netlist.h" @@ -72,6 +72,72 @@ NetEConst* NetEBAdd::eval_tree() return new NetEConst(val); } +NetEConst* NetEBBits::eval_tree() +{ + eval_sub_tree_(); + + NetEConst*lc = dynamic_cast(left_); + if (lc == 0) return 0; + NetEConst*rc = dynamic_cast(right_); + if (rc == 0) return 0; + + verinum lval = lc->value(); + verinum rval = rc->value(); + + unsigned lwid = lc->expr_width(); + if (lwid == 0) lwid = lval.len(); + + unsigned rwid = rc->expr_width(); + if (rwid == 0) rwid = rval.len(); + + unsigned wid = expr_width(); + if (wid == 0) + wid = (rwid > lwid)? rwid : lwid; + + verinum res (verinum::V0, wid); + + if (lwid > wid) + lwid = wid; + if (rwid > wid) + rwid = wid; + + switch (op()) { + + case '|': { + unsigned cnt = lwid; + if (cnt > wid) cnt = wid; + if (cnt > rwid) cnt = rwid; + for (unsigned idx = 0 ; idx < cnt ; idx += 1) + res.set(idx, lval.get(idx) | rval.get(idx)); + + if (lwid < rwid) + for (unsigned idx = lwid ; idx < rwid ; idx += 1) + res.set(idx, lval.get(idx)); + + if (rwid < lwid) + for (unsigned idx = rwid ; idx < lwid ; idx += 1) + res.set(idx, rval.get(idx)); + + break; + } + + case '&': { + unsigned cnt = lwid; + if (cnt > wid) cnt = wid; + if (cnt > rwid) cnt = rwid; + for (unsigned idx = 0 ; idx < cnt ; idx += 1) + res.set(idx, lval.get(idx) & rval.get(idx)); + + break; + } + + default: + return 0; + } + + return new NetEConst(res); +} + NetEConst* NetEBComp::eval_eqeq_() { NetEConst*l = dynamic_cast(left_); @@ -521,8 +587,15 @@ NetExpr* NetETernary::eval_tree() NetEConst* NetEUnary::eval_tree() { - NetExpr*oper = expr_->eval_tree(); - NetEConst*rval = dynamic_cast(oper); + NetEConst*rval = dynamic_cast(expr_); + if (rval == 0) { + NetExpr*oper = expr_->eval_tree(); + if (oper == 0) return 0; + + delete expr_; + expr_ = oper; + rval = dynamic_cast(oper); + } if (rval == 0) return 0; @@ -555,14 +628,40 @@ NetEConst* NetEUnary::eval_tree() return new NetEConst(out); } + case '~': { + for (unsigned idx = 0 ; idx < val.len() ; idx += 1) + switch (val.get(idx)) { + case verinum::V0: + val.set(idx, verinum::V1); + break; + case verinum::V1: + val.set(idx, verinum::V0); + break; + default: + val.set(idx, verinum::Vx); + } + + return new NetEConst(val); + } + default: delete rval; return 0; } } + +NetEConst* NetEUBits::eval_tree() +{ + return NetEUnary::eval_tree(); +} + + /* * $Log: eval_tree.cc,v $ + * Revision 1.17 2001/01/02 03:23:40 steve + * Evaluate constant &, | and unary ~. + * * Revision 1.16 2001/01/01 21:49:33 steve * Fix shift and ternary operators in parameter expressions (PR#86) * diff --git a/netlist.h b/netlist.h index 8b052f748..a63ade472 100644 --- a/netlist.h +++ b/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.188 2000/12/16 19:03:30 steve Exp $" +#ident "$Id: netlist.h,v 1.189 2001/01/02 03:23:40 steve Exp $" #endif /* @@ -2141,6 +2141,7 @@ class NetEBBits : public NetEBinary { virtual bool set_width(unsigned w); virtual NetEBBits* dup_expr() const; + virtual NetEConst* eval_tree(); virtual NetNet* synthesize(Design*); }; @@ -2432,6 +2433,7 @@ class NetEUBits : public NetEUnary { virtual NetNet* synthesize(Design*); + virtual NetEConst* eval_tree(); }; class NetEUReduce : public NetEUnary { @@ -2838,6 +2840,9 @@ extern ostream& operator << (ostream&, NetNet::Type); /* * $Log: netlist.h,v $ + * Revision 1.189 2001/01/02 03:23:40 steve + * Evaluate constant &, | and unary ~. + * * Revision 1.188 2000/12/16 19:03:30 steve * Evaluate <= and ?: in parameter expressions (PR#81) * diff --git a/verinum.cc b/verinum.cc index 810b0589e..90494b65b 100644 --- a/verinum.cc +++ b/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.21 2000/12/10 22:01:36 steve Exp $" +#ident "$Id: verinum.cc,v 1.22 2001/01/02 03:23:40 steve Exp $" #endif # include "verinum.h" @@ -548,8 +548,37 @@ verinum operator * (const verinum&left, const verinum&right) return result; } +verinum::V operator | (verinum::V l, verinum::V r) +{ + if (l == verinum::V1) + return verinum::V1; + if (r == verinum::V1) + return verinum::V1; + if (l != verinum::V0) + return verinum::Vx; + if (r != verinum::V0) + return verinum::Vx; + return verinum::V0; +} + +verinum::V operator & (verinum::V l, verinum::V r) +{ + if (l == verinum::V0) + return verinum::V0; + if (r == verinum::V0) + return verinum::V0; + if (l != verinum::V1) + return verinum::Vx; + if (r != verinum::V1) + return verinum::Vx; + return verinum::V1; +} + /* * $Log: verinum.cc,v $ + * Revision 1.22 2001/01/02 03:23:40 steve + * Evaluate constant &, | and unary ~. + * * Revision 1.21 2000/12/10 22:01:36 steve * Support decimal constants in behavioral delays. * @@ -585,38 +614,5 @@ verinum operator * (const verinum&left, const verinum&right) * * Revision 1.10 1999/10/10 23:29:37 steve * Support evaluating + operator at compile time. - * - * Revision 1.9 1999/07/20 05:12:22 steve - * Implement the set method. - * - * Revision 1.8 1999/05/13 04:02:09 steve - * More precise handling of verinum bit lengths. - * - * Revision 1.7 1999/05/09 01:38:33 steve - * Add implementation of integer to verunum constructor. - * - * Revision 1.6 1998/12/20 02:05:41 steve - * Function to calculate wire initial value. - * - * Revision 1.5 1998/11/11 00:01:51 steve - * Check net ranges in declarations. - * - * Revision 1.4 1998/11/09 19:03:26 steve - * Oops, forgot return from operator<< - * - * Revision 1.3 1998/11/09 18:55:35 steve - * Add procedural while loops, - * Parse procedural for loops, - * Add procedural wait statements, - * Add constant nodes, - * Add XNOR logic gate, - * Make vvm output look a bit prettier. - * - * Revision 1.2 1998/11/07 17:04:48 steve - * Properly dump 0 length numbers. - * - * Revision 1.1 1998/11/03 23:29:07 steve - * Introduce verilog to CVS. - * */ diff --git a/verinum.h b/verinum.h index 50b87a4f7..e5b683573 100644 --- a/verinum.h +++ b/verinum.h @@ -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.13 2000/12/10 22:01:36 steve Exp $" +#ident "$Id: verinum.h,v 1.14 2001/01/02 03:23:40 steve Exp $" #endif # include @@ -100,6 +100,9 @@ class ostream; extern ostream& operator<< (ostream&, const verinum&); extern ostream& operator<< (ostream&, verinum::V); +extern verinum::V operator | (verinum::V l, verinum::V r); +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 operator + (const verinum&left, const verinum&right); @@ -111,6 +114,9 @@ extern verinum v_not(const verinum&left); /* * $Log: verinum.h,v $ + * Revision 1.14 2001/01/02 03:23:40 steve + * Evaluate constant &, | and unary ~. + * * Revision 1.13 2000/12/10 22:01:36 steve * Support decimal constants in behavioral delays. *