Support a bunch of unary operators in parameter expressions.
This commit is contained in:
parent
b6a18098c7
commit
120a211e68
|
|
@ -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.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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -511,7 +511,7 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||||
break;
|
break;
|
||||||
case '!': // Logical NOT
|
case '!': // Logical NOT
|
||||||
case '&': // Reduction AND
|
case '&': // Reduction AND
|
||||||
case '|': // Reduction or
|
case '|': // Reduction OR
|
||||||
case '^': // Reduction XOR
|
case '^': // Reduction XOR
|
||||||
case 'A': // Reduction NAND (~&)
|
case 'A': // Reduction NAND (~&)
|
||||||
case 'N': // Reduction NOR (~|)
|
case 'N': // Reduction NOR (~|)
|
||||||
|
|
@ -529,6 +529,9 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_expr.cc,v $
|
* $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
|
* Revision 1.31 2000/12/10 22:01:35 steve
|
||||||
* Support decimal constants in behavioral delays.
|
* Support decimal constants in behavioral delays.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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_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
|
#endif
|
||||||
|
|
||||||
# include "PExpr.h"
|
# include "PExpr.h"
|
||||||
|
|
@ -168,12 +168,25 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||||
tmp = new NetEUBits(op_, ip);
|
tmp = new NetEUBits(op_, ip);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
break;
|
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;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: elab_pexpr.cc,v $
|
* $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
|
* Revision 1.6 2000/12/16 19:03:30 steve
|
||||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||||
*
|
*
|
||||||
|
|
|
||||||
103
eval_tree.cc
103
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.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
|
#endif
|
||||||
|
|
||||||
# include "netlist.h"
|
# include "netlist.h"
|
||||||
|
|
@ -585,18 +585,23 @@ NetExpr* NetETernary::eval_tree()
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetEConst* NetEUnary::eval_tree()
|
void NetEUnary::eval_expr_()
|
||||||
{
|
{
|
||||||
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
|
if (dynamic_cast<NetEConst*>(expr_))
|
||||||
if (rval == 0) {
|
return;
|
||||||
|
|
||||||
NetExpr*oper = expr_->eval_tree();
|
NetExpr*oper = expr_->eval_tree();
|
||||||
if (oper == 0) return 0;
|
if (oper == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
delete expr_;
|
delete expr_;
|
||||||
expr_ = oper;
|
expr_ = oper;
|
||||||
rval = dynamic_cast<NetEConst*>(oper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetEConst* NetEUnary::eval_tree()
|
||||||
|
{
|
||||||
|
eval_expr_();
|
||||||
|
NetEConst*rval = dynamic_cast<NetEConst*>(expr_);
|
||||||
if (rval == 0)
|
if (rval == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -604,31 +609,11 @@ NetEConst* NetEUnary::eval_tree()
|
||||||
|
|
||||||
switch (op_) {
|
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 '~': {
|
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)
|
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||||
switch (val.get(idx)) {
|
switch (val.get(idx)) {
|
||||||
case verinum::V0:
|
case verinum::V0:
|
||||||
|
|
@ -656,9 +641,69 @@ NetEConst* NetEUBits::eval_tree()
|
||||||
return NetEUnary::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 $
|
* $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
|
* Revision 1.17 2001/01/02 03:23:40 steve
|
||||||
* Evaluate constant &, | and unary ~.
|
* Evaluate constant &, | and unary ~.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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.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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2423,6 +2423,8 @@ class NetEUnary : public NetExpr {
|
||||||
protected:
|
protected:
|
||||||
char op_;
|
char op_;
|
||||||
NetExpr* expr_;
|
NetExpr* expr_;
|
||||||
|
|
||||||
|
void eval_expr_();
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetEUBits : public NetEUnary {
|
class NetEUBits : public NetEUnary {
|
||||||
|
|
@ -2443,6 +2445,7 @@ class NetEUReduce : public NetEUnary {
|
||||||
~NetEUReduce();
|
~NetEUReduce();
|
||||||
|
|
||||||
virtual NetNet* synthesize(Design*);
|
virtual NetNet* synthesize(Design*);
|
||||||
|
virtual NetEConst* eval_tree();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2840,6 +2843,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: netlist.h,v $
|
* $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
|
* Revision 1.189 2001/01/02 03:23:40 steve
|
||||||
* Evaluate constant &, | and unary ~.
|
* Evaluate constant &, | and unary ~.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue