Make binary expressions use their tested width in self-determined context
Operands to reduction unary operators are self determined, so evaluate the operands that way. But this means that binary expressions in this context should take pains to use their test_width tested expression width. This exposed a case where the test_width methods were not called for self-determined expressions. Fix that too.
This commit is contained in:
parent
d7ae1ed204
commit
46a22e9ea2
1
PExpr.cc
1
PExpr.cc
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
PExpr::PExpr()
|
||||
{
|
||||
expr_width_ = 0;
|
||||
expr_type_ = IVL_VT_NO_TYPE;
|
||||
}
|
||||
|
||||
|
|
|
|||
21
elab_expr.cc
21
elab_expr.cc
|
|
@ -246,8 +246,18 @@ NetExpr* PEBinary::elaborate_expr(Design*des, NetScope*scope,
|
|||
assert(left_);
|
||||
assert(right_);
|
||||
|
||||
NetExpr*lp = left_->elaborate_expr(des, scope, expr_wid, false);
|
||||
NetExpr*rp = right_->elaborate_expr(des, scope, expr_wid, false);
|
||||
// The context passes in the width that this expression is
|
||||
// expected to use. But if that width is <0, we are in a
|
||||
// self-determined context and we must use the width that was
|
||||
// calculated by a previous call to test_with.
|
||||
int use_wid = expr_wid;
|
||||
if (use_wid < 0 && expr_type_ != IVL_VT_REAL) {
|
||||
ivl_assert(*this, expr_width_ > 0);
|
||||
use_wid = expr_width_;
|
||||
}
|
||||
|
||||
NetExpr*lp = left_->elaborate_expr(des, scope, use_wid, false);
|
||||
NetExpr*rp = right_->elaborate_expr(des, scope, use_wid, false);
|
||||
if ((lp == 0) || (rp == 0)) {
|
||||
delete lp;
|
||||
delete rp;
|
||||
|
|
@ -3604,7 +3614,12 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope,
|
|||
{
|
||||
ivl_variable_type_t sub_type = IVL_VT_NO_TYPE;
|
||||
bool flag = false;
|
||||
expr_->test_width(des, scope, 0, 0, sub_type, flag);
|
||||
unsigned swid = expr_->test_width(des, scope, 0, 0, sub_type, flag);
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Test width of sub-expression of " << op_
|
||||
<< " returns " << swid << "." << endl;
|
||||
|
||||
expr_type_ = sub_type;
|
||||
}
|
||||
expr_width_ = 1;
|
||||
|
|
|
|||
|
|
@ -203,6 +203,12 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
|||
|
||||
case index_component_t::SEL_IDX_DO:
|
||||
case index_component_t::SEL_IDX_UP: {
|
||||
// These are not used, but they need to have a default value.
|
||||
ivl_variable_type_t expr_type_tmp = IVL_VT_NO_TYPE;
|
||||
bool unsized_flag_tmp = false;
|
||||
index_tail.msb->test_width(des, scope,
|
||||
integer_width, integer_width,
|
||||
expr_type_tmp, unsized_flag_tmp);
|
||||
need_constant_expr = true;
|
||||
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
need_constant_expr = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue