During test_width is not the time to assert on no_type

unary expressions that have problems should not assert in the
test_width method. Instead, let the error propagate back and be
handled during expression elaboration. This found a few places
where expression widths/types weren't probed before elaboration.
This commit is contained in:
Stephen Williams 2008-11-26 15:37:38 -08:00
parent 4263f791f6
commit 90bfebd578
6 changed files with 58 additions and 20 deletions

View File

@ -1628,6 +1628,7 @@ NetExpr* PEIdent::calculate_up_do_base_(Design*des, NetScope*scope) const
ivl_assert(*this, index_tail.lsb != 0);
ivl_assert(*this, index_tail.msb != 0);
probe_expr_width(des, scope, index_tail.msb);
NetExpr*tmp = elab_and_eval(des, scope, index_tail.msb, -1);
return tmp;
}
@ -1702,8 +1703,13 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
break;
}
case index_component_t::SEL_BIT:
use_width = 1;
break;
{ ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.msb);
probe_expr_width(des, scope, index_tail.msb);
}
use_width = 1;
break;
default:
ivl_assert(*this, 0);
}
@ -2874,7 +2880,6 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope,
bool flag = false;
expr_->test_width(des, scope, 0, 0, sub_type, flag);
expr_type_ = sub_type;
ivl_assert(*expr_, expr_type_ != IVL_VT_NO_TYPE);
}
expr_width_ = 1;
@ -2922,6 +2927,8 @@ NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope,
NetExpr*ip = expr_->elaborate_expr(des, scope, expr_wid, false);
if (ip == 0) return 0;
ivl_assert(*expr_, expr_type_ != IVL_VT_NO_TYPE);
NetExpr*tmp;
switch (op_) {
default:

View File

@ -114,6 +114,7 @@ static void elaborate_parm_item_(perm_string name,
tmp->high_open_flag = range->high_open_flag;
if (range->low_expr) {
probe_expr_width(des, scope, range->low_expr);
tmp->low_expr = elab_and_eval(des, scope, range->low_expr, -1);
ivl_assert(*range->low_expr, tmp->low_expr);
} else {
@ -130,6 +131,7 @@ static void elaborate_parm_item_(perm_string name,
tmp->high_expr = tmp->low_expr;
} else if (range->high_expr) {
probe_expr_width(des, scope, range->high_expr);
tmp->high_expr = elab_and_eval(des, scope, range->high_expr, -1);
ivl_assert(*range->high_expr, tmp->high_expr);
} else {

View File

@ -530,6 +530,9 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
case PTF_REG:
case PTF_REG_S:
if (return_type_.range) {
probe_expr_width(des, scope, (*return_type_.range)[0]);
probe_expr_width(des, scope, (*return_type_.range)[1]);
NetExpr*me = elab_and_eval(des, scope,
(*return_type_.range)[0], -1);
assert(me);
@ -823,6 +826,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
bool bad_lsb = false, bad_msb = false;
/* If they exist get the port definition MSB and LSB */
if (port_set_ && port_msb_ != 0) {
probe_expr_width(des, scope, port_msb_);
NetExpr*texpr = elab_and_eval(des, scope, port_msb_, -1);
if (! eval_as_long(pmsb, texpr)) {
@ -837,6 +841,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete texpr;
probe_expr_width(des, scope, port_lsb_);
texpr = elab_and_eval(des, scope, port_lsb_, -1);
if (! eval_as_long(plsb, texpr)) {
@ -859,6 +864,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
/* If they exist get the net/etc. definition MSB and LSB */
if (net_set_ && net_msb_ != 0 && !bad_msb && !bad_lsb) {
probe_expr_width(des, scope, net_msb_);
NetExpr*texpr = elab_and_eval(des, scope, net_msb_, -1);
if (! eval_as_long(nmsb, texpr)) {
@ -873,6 +879,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
delete texpr;
probe_expr_width(des, scope, net_lsb_);
texpr = elab_and_eval(des, scope, net_lsb_, -1);
if (! eval_as_long(nlsb, texpr)) {
@ -964,6 +971,9 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
if (lidx_ || ridx_) {
assert(lidx_ && ridx_);
probe_expr_width(des, scope, lidx_);
probe_expr_width(des, scope, ridx_);
NetExpr*lexp = elab_and_eval(des, scope, lidx_, -1);
NetExpr*rexp = elab_and_eval(des, scope, ridx_, -1);

View File

@ -700,7 +700,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
const PExpr*ex = pin(idx);
PExpr*ex = pin(idx);
if (ex == 0) {
cerr << get_fileline() << ": error: Logic gate port "
"expressions are not optional." << endl;
@ -713,6 +713,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
} else {
unsigned use_width = array_count * instance_width;
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool flag = false;
ex->test_width(des, scope, 0, use_width, tmp_type, flag);
NetExpr*tmp = elab_and_eval(des, scope, ex,
use_width, use_width);
sig = tmp->synthesize(des, scope);
@ -1171,10 +1174,14 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
width. We use that, then, to decide how to hook
it up.
v NOTE that this also handles the case that the
NOTE that this also handles the case that the
port is actually empty on the inside. We assume
in that case that the port is input. */
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool flag = false;
pins[idx]->test_width(des, scope, 0, desired_vector_width,
tmp_type, flag);
NetExpr*tmp_expr = elab_and_eval(des, scope, pins[idx],
desired_vector_width,
desired_vector_width);
@ -1790,6 +1797,7 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
*/
static NetExpr*elaborate_delay_expr(PExpr*expr, Design*des, NetScope*scope)
{
probe_expr_width(des, scope, expr);
NetExpr*dex = elab_and_eval(des, scope, expr, -1);
/* If the delay expression is a real constant or vector
@ -2280,17 +2288,8 @@ NetProc* PCondit::elaborate(Design*des, NetScope*scope) const
cerr << get_fileline() << ": debug: Elaborate condition statement"
<< " with conditional: " << *expr_ << endl;
// Run a test-width on the condition so that its types are
// worked out for elaboration later on.
ivl_variable_type_t rtype = IVL_VT_NO_TYPE;
bool rflag = false;
unsigned expr_wid = expr_->test_width(des, scope, 0, 0, rtype, rflag);
if (debug_elaborate)
cerr << get_fileline() << ": debug: Test width of condition expression"
<< " returns wid=" << expr_wid << ", type=" << rtype
<< ", flag=" << rflag << endl;
// Elaborate and try to evaluate the conditional expression.
probe_expr_width(des, scope, expr_);
NetExpr*expr = elab_and_eval(des, scope, expr_, -1);
if (expr == 0) {
cerr << get_fileline() << ": error: Unable to elaborate"
@ -2545,6 +2544,10 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
NetAssign_*lv = new NetAssign_(port);
unsigned wid = count_lval_width(lv);
ivl_variable_type_t tmp_type = IVL_VT_NO_TYPE;
bool flag = false;
parms_[idx]->test_width(des, scope, 0, wid, tmp_type, flag);
NetExpr*rv = elab_and_eval(des, scope, parms_[idx], wid);
rv->set_width(wid);
rv = pad_to_width(rv, wid, *this);
@ -2650,8 +2653,9 @@ NetCAssign* PCAssign::elaborate(Design*des, NetScope*scope) const
return 0;
unsigned lwid = count_lval_width(lval);
ivl_variable_type_t ltype = lval->expr_type();
NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid);
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
if (rexp == 0)
return 0;
@ -3054,10 +3058,12 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
return 0;
}
const PExpr *pe = expr_[0]->expr();
PExpr *pe = expr_[0]->expr();
/* Elaborate wait expression. Don't eval yet, we will do that
shortly, after we apply a reduction or. */
probe_expr_width(des, scope, pe);
NetExpr*expr = pe->elaborate_expr(des, scope, -1, false);
if (expr == 0) {
cerr << get_fileline() << ": error: Unable to elaborate"
@ -3248,8 +3254,9 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
return 0;
unsigned lwid = count_lval_width(lval);
ivl_variable_type_t ltype = lval->expr_type();
NetExpr*rexp = elab_and_eval(des, scope, expr_, lwid);
NetExpr*rexp = elaborate_rval_expr(des, scope, ltype, lwid, expr_);
if (rexp == 0)
return 0;
@ -3591,8 +3598,9 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
*/
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
{
NetWhile*loop = new NetWhile(elab_and_eval(des, scope, cond_, -1),
statement_->elaborate(des, scope));
probe_expr_width(des, scope, cond_);
NetExpr*tmp = elab_and_eval(des, scope, cond_, -1);
NetWhile*loop = new NetWhile(tmp, statement_->elaborate(des, scope));
return loop;
}
@ -3683,6 +3691,7 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
them for the timescale/precision of the scope. */
for (unsigned idx = 0 ; idx < ndelays ; idx += 1) {
PExpr*exp = delays[idx];
probe_expr_width(des, scope, exp);
NetExpr*cur = elab_and_eval(des, scope, exp, 0);
if (NetEConst*cur_con = dynamic_cast<NetEConst*> (cur)) {
@ -3720,6 +3729,7 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
NetNet*condit_sig = 0;
if (conditional && condition) {
probe_expr_width(des, scope, condition);
NetExpr*tmp = elab_and_eval(des, scope, condition, -1);
ivl_assert(*condition, tmp);

View File

@ -250,6 +250,13 @@ NetExpr* condition_reduce(NetExpr*expr)
return cmp;
}
void probe_expr_width(Design*des, NetScope*scope, PExpr*pe)
{
ivl_variable_type_t expr_type = IVL_VT_NO_TYPE;
bool flag = false;
pe->test_width(des, scope, 0, 0, expr_type, flag);
}
NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid, int prune_width)
{

View File

@ -154,6 +154,8 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
const PExpr*pe, int expr_wid,
int prune_width =-1);
void probe_expr_width(Design*des, NetScope*scope, PExpr*pe);
/*
* 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