Support a bunch of unary operators in parameter expressions.

This commit is contained in:
steve 2001-01-02 04:21:13 +00:00
parent b6a18098c7
commit 120a211e68
4 changed files with 104 additions and 37 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: elab_expr.cc,v 1.31 2000/12/10 22:01:35 steve Exp $"
#ident "$Id: elab_expr.cc,v 1.32 2001/01/02 04:21:13 steve Exp $"
#endif
@ -511,7 +511,7 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
break;
case '!': // Logical NOT
case '&': // Reduction AND
case '|': // Reduction or
case '|': // Reduction OR
case '^': // Reduction XOR
case 'A': // Reduction NAND (~&)
case 'N': // Reduction NOR (~|)
@ -529,6 +529,9 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
/*
* $Log: elab_expr.cc,v $
* Revision 1.32 2001/01/02 04:21:13 steve
* Support a bunch of unary operators in parameter expressions.
*
* Revision 1.31 2000/12/10 22:01:35 steve
* Support decimal constants in behavioral delays.
*

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: elab_pexpr.cc,v 1.6 2000/12/16 19:03:30 steve Exp $"
#ident "$Id: elab_pexpr.cc,v 1.7 2001/01/02 04:21:13 steve Exp $"
#endif
# include "PExpr.h"
@ -168,12 +168,25 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
tmp = new NetEUBits(op_, ip);
tmp->set_line(*this);
break;
case '!': // Logical NOT
case '&': // Reduction AND
case '|': // Reduction OR
case '^': // Reduction XOR
case 'A': // Reduction NAND (~&)
case 'N': // Reduction NOR (~|)
case 'X': // Reduction NXOR (~^)
tmp = new NetEUReduce(op_, ip);
tmp->set_line(*this);
break;
}
return tmp;
}
/*
* $Log: elab_pexpr.cc,v $
* Revision 1.7 2001/01/02 04:21:13 steve
* Support a bunch of unary operators in parameter expressions.
*
* Revision 1.6 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: eval_tree.cc,v 1.17 2001/01/02 03:23:40 steve Exp $"
#ident "$Id: eval_tree.cc,v 1.18 2001/01/02 04:21:14 steve Exp $"
#endif
# include "netlist.h"
@ -585,18 +585,23 @@ NetExpr* NetETernary::eval_tree()
return rc;
}
void NetEUnary::eval_expr_()
{
if (dynamic_cast<NetEConst*>(expr_))
return;
NetExpr*oper = expr_->eval_tree();
if (oper == 0)
return;
delete expr_;
expr_ = oper;
}
NetEConst* NetEUnary::eval_tree()
{
eval_expr_();
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;
@ -604,31 +609,11 @@ NetEConst* NetEUnary::eval_tree()
switch (op_) {
case '!': {
/* Evaluate the unary logical not by first scanning
the operand value for V1 and Vx bits. If we find
any V1 bits we know that the value is TRUE, so
the result of ! is V0. If there are no V1 bits
but there are some Vx/Vz bits, the result is
unknown. Otherwise, the result is V1. */
unsigned v1 = 0, vx = 0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1) {
switch (val.get(idx)) {
case verinum::V0:
break;
case verinum::V1:
v1 += 1;
break;
default:
vx += 1;
break;
}
}
verinum out(v1? verinum::V0 : (vx? verinum::Vx : verinum::V1));
return new NetEConst(out);
}
case '~': {
/* Bitwise not is even simpler then logical
not. Just invert all the bits of the operand and
make the new value with the same dimensions. */
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
switch (val.get(idx)) {
case verinum::V0:
@ -656,9 +641,69 @@ NetEConst* NetEUBits::eval_tree()
return NetEUnary::eval_tree();
}
NetEConst* NetEUReduce::eval_tree()
{
eval_expr_();
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
if (rval == 0)
return 0;
verinum val = rval->value();
verinum::V res;
switch (op_) {
case '!': {
/* Evaluate the unary logical not by first scanning
the operand value for V1 and Vx bits. If we find
any V1 bits we know that the value is TRUE, so
the result of ! is V0. If there are no V1 bits
but there are some Vx/Vz bits, the result is
unknown. Otherwise, the result is V1. */
unsigned v1 = 0, vx = 0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1) {
switch (val.get(idx)) {
case verinum::V0:
break;
case verinum::V1:
v1 += 1;
break;
default:
vx += 1;
break;
}
}
res = v1? verinum::V0 : (vx? verinum::Vx : verinum::V1);
}
case '&': {
res = verinum::V1;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
res = res & val.get(idx);
break;
}
case '|': {
res = verinum::V0;
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
res = res | val.get(idx);
break;
}
default:
return 0;
}
return new NetEConst(verinum(res, 1));
}
/*
* $Log: eval_tree.cc,v $
* Revision 1.18 2001/01/02 04:21:14 steve
* Support a bunch of unary operators in parameter expressions.
*
* Revision 1.17 2001/01/02 03:23:40 steve
* Evaluate constant &, | and unary ~.
*

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.189 2001/01/02 03:23:40 steve Exp $"
#ident "$Id: netlist.h,v 1.190 2001/01/02 04:21:14 steve Exp $"
#endif
/*
@ -2423,6 +2423,8 @@ class NetEUnary : public NetExpr {
protected:
char op_;
NetExpr* expr_;
void eval_expr_();
};
class NetEUBits : public NetEUnary {
@ -2443,6 +2445,7 @@ class NetEUReduce : public NetEUnary {
~NetEUReduce();
virtual NetNet* synthesize(Design*);
virtual NetEConst* eval_tree();
};
@ -2840,6 +2843,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.190 2001/01/02 04:21:14 steve
* Support a bunch of unary operators in parameter expressions.
*
* Revision 1.189 2001/01/02 03:23:40 steve
* Evaluate constant &, | and unary ~.
*