Evaluate <= and ?: in parameter expressions (PR#81)
This commit is contained in:
parent
c9881c115a
commit
f4671a3082
11
PExpr.cc
11
PExpr.cc
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.cc,v 1.20 2000/12/10 22:01:35 steve Exp $"
|
||||
#ident "$Id: PExpr.cc,v 1.21 2000/12/16 19:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PExpr.h"
|
||||
|
|
@ -222,9 +222,11 @@ PETernary::~PETernary()
|
|||
{
|
||||
}
|
||||
|
||||
bool PETernary::is_constant(Module*) const
|
||||
bool PETernary::is_constant(Module*m) const
|
||||
{
|
||||
return false;
|
||||
return expr_->is_constant(m)
|
||||
&& tru_->is_constant(m)
|
||||
&& fal_->is_constant(m);
|
||||
}
|
||||
|
||||
PEUnary::PEUnary(char op, PExpr*ex)
|
||||
|
|
@ -243,6 +245,9 @@ bool PEUnary::is_constant(Module*m) const
|
|||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.21 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.20 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
*
|
||||
|
|
|
|||
6
PExpr.h
6
PExpr.h
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.h,v 1.46 2000/12/10 22:01:35 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.47 2000/12/16 19:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
|
|
@ -401,6 +401,7 @@ class PETernary : public PExpr {
|
|||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
||||
private:
|
||||
|
|
@ -431,6 +432,9 @@ class PECallFunction : public PExpr {
|
|||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.47 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.46 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.5 2000/06/13 05:22:16 steve Exp $"
|
||||
#ident "$Id: elab_pexpr.cc,v 1.6 2000/12/16 19:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PExpr.h"
|
||||
|
|
@ -138,6 +138,17 @@ NetEConst* PEString::elaborate_pexpr(Design*des, NetScope*scope) const
|
|||
return elaborate_expr(des, scope);
|
||||
}
|
||||
|
||||
NetETernary* PETernary::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*c = expr_->elaborate_pexpr(des, scope);
|
||||
NetExpr*t = tru_->elaborate_pexpr(des, scope);
|
||||
NetExpr*f = fal_->elaborate_pexpr(des, scope);
|
||||
if (c == 0) return 0;
|
||||
if (t == 0) return 0;
|
||||
if (f == 0) return 0;
|
||||
return new NetETernary(c, t, f);
|
||||
}
|
||||
|
||||
NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
{
|
||||
NetExpr*ip = expr_->elaborate_pexpr(des, scope);
|
||||
|
|
@ -163,6 +174,9 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
|||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.6 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.5 2000/06/13 05:22:16 steve
|
||||
* Support concatenation in parameter expressions.
|
||||
*
|
||||
|
|
|
|||
119
eval_tree.cc
119
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.13 2000/09/29 04:42:56 steve Exp $"
|
||||
#ident "$Id: eval_tree.cc,v 1.14 2000/12/16 19:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
|
@ -101,6 +101,10 @@ NetEConst* NetEBComp::eval_leeq_()
|
|||
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
|
||||
|
|
@ -112,7 +116,26 @@ NetEConst* NetEBComp::eval_leeq_()
|
|||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
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_neeq_()
|
||||
|
|
@ -290,7 +313,7 @@ NetEConst* NetEBShift::eval_tree()
|
|||
return res;
|
||||
}
|
||||
|
||||
NetExpr* NetEConcat::eval_tree()
|
||||
NetEConst* NetEConcat::eval_tree()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
|
||||
|
|
@ -369,6 +392,93 @@ NetExpr* NetEParam::eval_tree()
|
|||
return res->dup_expr();
|
||||
}
|
||||
|
||||
/*
|
||||
* A ternary expression evaluation is controlled by the condition
|
||||
* expression. If the condition evaluates to true or false, then
|
||||
* return the evaluated true or false expression. If the condition
|
||||
* evaluates to x or z, then merge the constant bits of the true and
|
||||
* false expressions.
|
||||
*/
|
||||
NetExpr* NetETernary::eval_tree()
|
||||
{
|
||||
NetExpr*tmp;
|
||||
|
||||
/* Evaluate the cond_ to a constant. If it already is a
|
||||
constant, then there is nothing to do. */
|
||||
|
||||
NetEConst*c = dynamic_cast<NetEConst*>(cond_);
|
||||
if (c == 0) {
|
||||
tmp = cond_->eval_tree();
|
||||
c = dynamic_cast<NetEConst*>(tmp);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
|
||||
delete cond_;
|
||||
cond_ = c;
|
||||
}
|
||||
|
||||
|
||||
/* If the condition is 1 or 0, return the true or false
|
||||
expression. Try to evaluate the expression down as far as
|
||||
we can. */
|
||||
|
||||
if (c->value().get(0) == verinum::V1) {
|
||||
tmp = true_val_->eval_tree();
|
||||
return tmp? tmp : true_val_;
|
||||
}
|
||||
|
||||
if (c->value().get(0) == verinum::V0) {
|
||||
tmp = false_val_->eval_tree();
|
||||
return tmp? tmp : false_val_;
|
||||
}
|
||||
|
||||
|
||||
/* Here we have a more complex case. We need to evaluate both
|
||||
expressions down to constants then compare the values to
|
||||
build up a constant result. */
|
||||
|
||||
NetEConst*t = dynamic_cast<NetEConst*>(true_val_);
|
||||
if (t == 0) {
|
||||
tmp = true_val_->eval_tree();
|
||||
t = dynamic_cast<NetEConst*>(tmp);
|
||||
if (t == 0)
|
||||
return 0;
|
||||
|
||||
delete true_val_;
|
||||
true_val_ = t;
|
||||
}
|
||||
|
||||
|
||||
NetEConst*f = dynamic_cast<NetEConst*>(false_val_);
|
||||
if (f == 0) {
|
||||
tmp = false_val_->eval_tree();
|
||||
f = dynamic_cast<NetEConst*>(tmp);
|
||||
if (f == 0)
|
||||
return 0;
|
||||
|
||||
delete false_val_;
|
||||
false_val_ = f;
|
||||
}
|
||||
|
||||
unsigned size = t->expr_width();
|
||||
assert(size == f->expr_width());
|
||||
|
||||
verinum val (verinum::V0, size);
|
||||
for (unsigned idx = 0 ; idx < size ; idx += 1) {
|
||||
verinum::V tv = t->value().get(idx);
|
||||
verinum::V fv = f->value().get(idx);
|
||||
|
||||
if (tv == fv)
|
||||
val.set(idx, tv);
|
||||
else
|
||||
val.set(idx, verinum::Vx);
|
||||
}
|
||||
|
||||
NetEConst*rc = new NetEConst(val);
|
||||
rc->set_line(*this);
|
||||
return rc;
|
||||
}
|
||||
|
||||
NetEConst* NetEUnary::eval_tree()
|
||||
{
|
||||
NetExpr*oper = expr_->eval_tree();
|
||||
|
|
@ -413,6 +523,9 @@ NetEConst* NetEUnary::eval_tree()
|
|||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.14 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.13 2000/09/29 04:42:56 steve
|
||||
* Cnstant evaluation of NE.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.187 2000/12/16 01:45:48 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.188 2000/12/16 19:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -2262,7 +2262,7 @@ class NetEConcat : public NetExpr {
|
|||
|
||||
virtual bool set_width(unsigned w);
|
||||
virtual NetEConcat* dup_expr() const;
|
||||
virtual NetExpr* eval_tree();
|
||||
virtual NetEConst* eval_tree();
|
||||
virtual NetNet*synthesize(Design*);
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
|
@ -2375,6 +2375,7 @@ class NetETernary : public NetExpr {
|
|||
const NetExpr*false_expr() const;
|
||||
|
||||
virtual NetETernary* dup_expr() const;
|
||||
virtual NetExpr* eval_tree();
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
|
@ -2837,6 +2838,9 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
|||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.188 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.187 2000/12/16 01:45:48 steve
|
||||
* Detect recursive instantiations (PR#2)
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue