diff --git a/elab_expr.cc b/elab_expr.cc index 21e302b06..2e6fba336 100644 --- a/elab_expr.cc +++ b/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: diff --git a/elab_scope.cc b/elab_scope.cc index cf617a640..d7ca9853c 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -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 { diff --git a/elab_sig.cc b/elab_sig.cc index 167f068a7..618911fa4 100644 --- a/elab_sig.cc +++ b/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); diff --git a/elaborate.cc b/elaborate.cc index bd67391b0..222fd7555 100644 --- a/elaborate.cc +++ b/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 (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); diff --git a/netmisc.cc b/netmisc.cc index b223795d3..54faac2f7 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -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) { diff --git a/netmisc.h b/netmisc.h index c51ba02f7..d5ff896ae 100644 --- a/netmisc.h +++ b/netmisc.h @@ -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