Evaluate <= and ?: in parameter expressions (PR#81)

This commit is contained in:
steve 2000-12-16 19:03:30 +00:00
parent c9881c115a
commit f4671a3082
5 changed files with 150 additions and 10 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: 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.
*

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: 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.
*

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

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

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