MOre thorough use of elab_and_eval function.

This commit is contained in:
steve 2004-03-07 20:04:10 +00:00
parent 4456937274
commit 9531920685
2 changed files with 25 additions and 61 deletions

View File

@ -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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: elaborate.cc,v 1.297 2004/02/20 18:53:34 steve Exp $" #ident "$Id: elaborate.cc,v 1.298 2004/03/07 20:04:10 steve Exp $"
#endif #endif
# include "config.h" # include "config.h"
@ -928,12 +928,7 @@ NetAssign_* PAssign_::elaborate_lval(Design*des, NetScope*scope) const
*/ */
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope) static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
{ {
NetExpr*dex = elab_and_eval(des, scope, expr);
NetExpr*dex = expr->elaborate_expr(des, scope);
if (NetExpr*tmp = dex->eval_tree()) {
delete dex;
dex = tmp;
}
/* If the delay expression is a real constant or vector /* If the delay expression is a real constant or vector
constant, then evaluate it, scale it to the local time constant, then evaluate it, scale it to the local time
@ -1010,17 +1005,9 @@ NetProc* PAssign::elaborate(Design*des, NetScope*scope) const
/* Elaborate the r-value expression, then try to evaluate it. */ /* Elaborate the r-value expression, then try to evaluate it. */
assert(rval()); assert(rval());
NetExpr*rv = rval()->elaborate_expr(des, scope); NetExpr*rv = elab_and_eval(des, scope, rval());
if (rv == 0)
return 0;
assert(rv); assert(rv);
/* Try to evaluate the expression, at least as far as possible. */
if (NetExpr*tmp = rv->eval_tree()) {
delete rv;
rv = tmp;
}
/* Rewrite delayed assignments as assignments that are /* Rewrite delayed assignments as assignments that are
delayed. For example, a = #<d> b; becomes: delayed. For example, a = #<d> b; becomes:
@ -1233,22 +1220,13 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
{ {
assert(scope); assert(scope);
NetExpr*expr = expr_->elaborate_expr(des, scope); NetExpr*expr = elab_and_eval(des, scope, expr_);
if (expr == 0) { if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate this case" cerr << get_line() << ": error: Unable to elaborate this case"
" expression." << endl; " expression." << endl;
return 0; return 0;
} }
/* Try to evaluate the case expression. */
if (! dynamic_cast<NetEConst*>(expr)) {
NetExpr*tmp = expr->eval_tree();
if (tmp != 0) {
delete expr;
expr = tmp;
}
}
/* Count the items in the case statement. Note that there may /* Count the items in the case statement. Note that there may
be some cases that have multiple guards. Count each as a be some cases that have multiple guards. Count each as a
separate item. */ separate item. */
@ -1294,17 +1272,7 @@ NetProc* PCase::elaborate(Design*des, NetScope*scope) const
NetExpr*gu = 0; NetExpr*gu = 0;
NetProc*st = 0; NetProc*st = 0;
assert(cur->expr[e]); assert(cur->expr[e]);
gu = cur->expr[e]->elaborate_expr(des, scope); gu = elab_and_eval(des, scope, cur->expr[e]);
/* Try to evaluate the guard expression down to a
simple constant. */
if (! dynamic_cast<NetEConst*>(gu)) {
NetExpr*tmp = gu->eval_tree();
if (tmp != 0) {
delete gu;
gu = tmp;
}
}
if (cur->stat) if (cur->stat)
st = cur->stat->elaborate(des, scope); st = cur->stat->elaborate(des, scope);
@ -1322,18 +1290,13 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
assert(scope); assert(scope);
// Elaborate and try to evaluate the conditional expression. // Elaborate and try to evaluate the conditional expression.
NetExpr*expr = expr_->elaborate_expr(des, scope); NetExpr*expr = elab_and_eval(des, scope, expr_);
if (expr == 0) { if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate" cerr << get_line() << ": error: Unable to elaborate"
" condition expression." << endl; " condition expression." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
NetExpr*tmp = expr->eval_tree();
if (tmp) {
delete expr;
expr = tmp;
}
// If the condition of the conditional statement is constant, // If the condition of the conditional statement is constant,
// then look at the value and elaborate either the if statement // then look at the value and elaborate either the if statement
@ -1540,7 +1503,7 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
if (port->port_type() == NetNet::POUTPUT) if (port->port_type() == NetNet::POUTPUT)
continue; continue;
NetExpr*rv = parms_[idx]->elaborate_expr(des, scope); NetExpr*rv = elab_and_eval(des, scope, parms_[idx]);
NetAssign_*lv = new NetAssign_(port); NetAssign_*lv = new NetAssign_(port);
NetAssign*pr = new NetAssign(lv, rv); NetAssign*pr = new NetAssign(lv, rv);
block->append(pr); block->append(pr);
@ -1953,6 +1916,8 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
const PExpr *pe = expr_[0]->expr(); const PExpr *pe = expr_[0]->expr();
/* Elaborate wait expression. Don't eval yet, we will do that
shortly, after we apply a reduction or. */
NetExpr*expr = pe->elaborate_expr(des, scope); NetExpr*expr = pe->elaborate_expr(des, scope);
if (expr == 0) { if (expr == 0) {
cerr << get_line() << ": error: Unable to elaborate" cerr << get_line() << ": error: Unable to elaborate"
@ -2188,19 +2153,16 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
/* Elaborate the condition expression. Try to evaluate it too, /* Elaborate the condition expression. Try to evaluate it too,
in case it is a constant. This is an interesting case in case it is a constant. This is an interesting case
worthy of a warning. */ worthy of a warning. */
NetExpr*ce = cond_->elaborate_expr(des, scope); NetExpr*ce = elab_and_eval(des, scope, cond_);
if (ce == 0) { if (ce == 0) {
delete top; delete top;
return 0; return 0;
} }
if (NetExpr*tmp = ce->eval_tree()) { if (dynamic_cast<NetEConst*>(ce)) {
if (dynamic_cast<NetEConst*>(tmp)) {
cerr << get_line() << ": warning: condition expression " cerr << get_line() << ": warning: condition expression "
"of for-loop is constant." << endl; "of for-loop is constant." << endl;
} }
ce = tmp;
}
/* All done, build up the loop. */ /* All done, build up the loop. */
@ -2265,18 +2227,13 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
{ {
assert(scope); assert(scope);
NetExpr*expr = expr_->elaborate_expr(des, scope); NetExpr*expr = elab_and_eval(des, scope, expr_);
if (expr == 0) { if (expr == 0) {
cerr << get_line() << ": Unable to elaborate" cerr << get_line() << ": Unable to elaborate"
" repeat expression." << endl; " repeat expression." << endl;
des->errors += 1; des->errors += 1;
return 0; return 0;
} }
NetExpr*tmp = expr->eval_tree();
if (tmp) {
delete expr;
expr = tmp;
}
NetProc*stat = statement_->elaborate(des, scope); NetProc*stat = statement_->elaborate(des, scope);
if (stat == 0) return 0; if (stat == 0) return 0;
@ -2392,7 +2349,7 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
*/ */
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
{ {
NetWhile*loop = new NetWhile(cond_->elaborate_expr(des, scope), NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_),
statement_->elaborate(des, scope)); statement_->elaborate(des, scope));
return loop; return loop;
} }
@ -2627,6 +2584,9 @@ Design* elaborate(list<perm_string>roots)
/* /*
* $Log: elaborate.cc,v $ * $Log: elaborate.cc,v $
* Revision 1.298 2004/03/07 20:04:10 steve
* MOre thorough use of elab_and_eval function.
*
* Revision 1.297 2004/02/20 18:53:34 steve * Revision 1.297 2004/02/20 18:53:34 steve
* Addtrbute keys are perm_strings. * Addtrbute keys are perm_strings.
* *

View File

@ -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
*/ */
#ifdef HAVE_CVS_IDENT #ifdef HAVE_CVS_IDENT
#ident "$Id: netmisc.h,v 1.18 2003/09/19 03:30:05 steve Exp $" #ident "$Id: netmisc.h,v 1.19 2004/03/07 20:04:11 steve Exp $"
#endif #endif
# include "netlist.h" # include "netlist.h"
@ -66,14 +66,18 @@ extern unsigned count_lval_width(const class NetAssign_*first);
/* /*
* This function elaborates an expression, and tries to evaluate it * This function elaborates an expression, and tries to evaluate it
* right away. It is useful for those places where the user is * right away. If the expression can be evaluated, this returns a
* supposed to supply a constant expression. * constant expression. If it cannot be evaluated, it returns whatever
* it can. If the expression cannot be elaborated, return 0.
*/ */
class PExpr; class PExpr;
extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe); extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
/* /*
* $Log: netmisc.h,v $ * $Log: netmisc.h,v $
* Revision 1.19 2004/03/07 20:04:11 steve
* MOre thorough use of elab_and_eval function.
*
* Revision 1.18 2003/09/19 03:30:05 steve * Revision 1.18 2003/09/19 03:30:05 steve
* Fix name search in elab_lval. * Fix name search in elab_lval.
* *