Unify all the r-value elaboration.

R-value expression elaboration happens in several places. Factor out
the common code so that they are all handled correctly and uniformly.
This commit is contained in:
Stephen Williams 2008-09-25 21:22:21 -07:00
parent 4919b70da6
commit 42d412c626
3 changed files with 28 additions and 53 deletions

View File

@ -44,19 +44,32 @@ static bool type_is_vectorable(ivl_variable_type_t type)
NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
ivl_variable_type_t data_type_lv, int expr_wid_lv,
PExpr*expr)
const PExpr*expr)
{
int expr_wid = 0;
bool unsized_flag = false;
switch (data_type_lv) {
case IVL_VT_REAL:
unsized_flag = true;
expr_wid = -2;
expr_wid_lv = -1;
break;
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
/* Find out what the r-value width is going to be. We
guess it will be the l-value width, but it may turn
out to be something else based on self-determined
widths inside. */
expr_wid = expr->test_width(des, scope, expr_wid_lv, expr_wid_lv, unsized_flag);
if (debug_elaborate) {
cerr << expr->get_fileline() << ": debug: r-value tested "
<< "width is " << expr_wid
<< ", min=" << expr_wid_lv
<< ", unsized_flag=" << (unsized_flag?"true":"false") << endl;
}
break;
case IVL_VT_VOID:
case IVL_VT_NO_TYPE:

View File

@ -99,31 +99,8 @@ void PGAssign::elaborate(Design*des, NetScope*scope) const
<< ", type=" << lval->data_type() << endl;
}
bool unsized_flag = false;
unsigned use_width = 0;
if (lval->data_type() == IVL_VT_REAL) {
unsized_flag = true;
use_width = pin(1)->test_width(des, scope, 0, 0, unsized_flag);
} else {
use_width = pin(1)->test_width(des, scope, lval->vector_width(),
lval->vector_width(), unsized_flag);
}
if (debug_elaborate) {
cerr << get_fileline() << ": debug: PGAssign: r-value tested "
<< "width is " << use_width
<< ", min=" << lval->vector_width()
<< ", unsized_flag=" << (unsized_flag?"true":"false") << endl;
}
int expr_wid = lval->vector_width();
if (use_width > (unsigned)expr_wid)
expr_wid = (int)use_width;
if (lval->data_type() == IVL_VT_REAL)
expr_wid = -2;
NetExpr*rval_expr = elab_and_eval(des, scope, pin(1),
expr_wid, lval->vector_width());
NetExpr*rval_expr = elaborate_rval_expr(des, scope, lval->data_type(),
lval->vector_width(), pin(1));
if (rval_expr == 0) {
cerr << get_fileline() << ": error: Unable to elaborate r-value: "
@ -1720,33 +1697,7 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
{
ivl_assert(*this, rval_);
/* Find out what the r-value width is going to be. We guess it
will be the l-value width, but it may turn out to be
something else based on self-determined widths inside. */
unsigned use_width = lv_width;
bool unsized_flag = false;
unsigned tmp_width = 0;
if (lv_type == IVL_VT_REAL) {
unsized_flag = true;
tmp_width = rval()->test_width(des, scope, 0, 0, unsized_flag);
} else {
tmp_width = rval()->test_width(des, scope, use_width, use_width, unsized_flag);
if (tmp_width > use_width)
use_width = tmp_width;
}
int expr_wid = use_width;
if (lv_type == IVL_VT_REAL) {
expr_wid = -2;
lv_width = 0;
}
/* Now elaborate to the expected width. Pass the lwidth to
prune any constant result to fit with the lvalue at hand. */
NetExpr*rv = elab_and_eval(des, scope, rval_, expr_wid, lv_width);
if (rv == 0) return 0;
NetExpr*rv = elaborate_rval_expr(des, scope, lv_type, lv_width, rval());
return rv;
}

View File

@ -147,6 +147,17 @@ class PExpr;
extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid,
int prune_width =-1);
/*
* This function elaborates an expression as if it is for the r-value
* of an assignment, The data_type_lv and expr_wid_lv are the type and
* with of the l-value, and the expr is the expression to
* elaborate. The result is the NetExpr elaborated and evaluated.
* (See elab_expr.cc)
*/
extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
ivl_variable_type_t data_type_lv,
int expr_wid_lv, const PExpr*expr);
/*
* This procedure elaborates an expression and if the elaboration is
* successful the original expression is replaced with the new one.