Evaluate constant &, | and unary ~.

This commit is contained in:
steve 2001-01-02 03:23:40 +00:00
parent 112936d661
commit b6a18098c7
4 changed files with 145 additions and 39 deletions

View File

@ -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<NetEConst*>(left_);
if (lc == 0) return 0;
NetEConst*rc = dynamic_cast<NetEConst*>(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<NetEConst*>(left_);
@ -521,8 +587,15 @@ NetExpr* NetETernary::eval_tree()
NetEConst* NetEUnary::eval_tree()
{
NetExpr*oper = expr_->eval_tree();
NetEConst*rval = dynamic_cast<NetEConst*>(oper);
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
if (rval == 0) {
NetExpr*oper = expr_->eval_tree();
if (oper == 0) return 0;
delete expr_;
expr_ = oper;
rval = dynamic_cast<NetEConst*>(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)
*

View File

@ -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)
*

View File

@ -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.
*
*/

View File

@ -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 <string>
@ -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.
*