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:
parent
4263f791f6
commit
90bfebd578
13
elab_expr.cc
13
elab_expr.cc
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
10
elab_sig.cc
10
elab_sig.cc
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
44
elaborate.cc
44
elaborate.cc
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue