diff --git a/netmisc.cc b/netmisc.cc index 8adb4c507..7a2ea5abd 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -476,13 +476,6 @@ void indices_to_expressions(Design*des, NetScope*scope, { ivl_assert(*loc, count <= src.size()); - int need_wid = ceil(log2(need_addr)) + 1; - if (debug_elaborate) { - cerr << loc->get_fileline() << ": indices_to_expressions: " - << "To address " << need_addr << " words, " - << "we need " << need_wid << " bits." << endl; - } - flags.invalid = false; flags.variable = false; flags.undefined = false; @@ -497,7 +490,7 @@ void indices_to_expressions(Design*des, NetScope*scope, } ivl_assert(*loc, cur->msb); - NetExpr*word_index = elab_and_eval_min_width(des, scope, cur->msb, need_wid, need_const); + NetExpr*word_index = elab_and_eval_lossless(des, scope, cur->msb, -2, need_const); if (word_index == 0) flags.invalid = true; @@ -741,13 +734,13 @@ NetExpr* condition_reduce(NetExpr*expr) static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe, int context_width, bool need_const, bool annotatable, - bool width_is_min, + bool force_expand, ivl_variable_type_t cast_type) { PExpr::width_mode_t mode = PExpr::SIZED; if ((context_width == -2) && !gn_strict_expr_width_flag) mode = PExpr::EXPAND; - if (width_is_min) + if (force_expand) mode = PExpr::EXPAND; pe->test_width(des, scope, mode); @@ -769,7 +762,7 @@ static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe, << "returns type=" << pe->expr_type() << ", context_width=" << context_width << ", signed=" << pe->has_sign() - << ", width_is_min=" << width_is_min + << ", force_expand=" << force_expand << ", expr_width=" << expr_width << ", mode=" << PExpr::width_mode_name(mode) << endl; cerr << pe->get_fileline() << ": : " @@ -778,7 +771,7 @@ static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe, // If we can get the same result using a smaller expression // width, do so. - if ((context_width > 0) && (!width_is_min) + if ((context_width > 0) && (!force_expand) && (pe->expr_type() != IVL_VT_REAL) && (expr_width > (unsigned)context_width)) { expr_width = max(pe->min_width(), (unsigned)context_width); @@ -822,7 +815,7 @@ static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe, // If the context_width sent is is actually the minimim width, // then raise the context_width to be big enough for the // lossless expression. - if (width_is_min && context_width > 0) { + if (force_expand && context_width > 0) { context_width = max(context_width, (int)expr_width); } @@ -844,11 +837,15 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe, need_const, annotatable, false, cast_type); } -NetExpr* elab_and_eval_min_width(Design*des, NetScope*scope, PExpr*pe, +/* + * This variant of elab_and_eval does the expression losslessly, no + * matter what the generation of verilog. This is in support of + * certain special contexts, notably index expressions. + */ +NetExpr* elab_and_eval_lossless(Design*des, NetScope*scope, PExpr*pe, int context_width, bool need_const, bool annotatable, ivl_variable_type_t cast_type) { - ivl_assert(*pe, context_width > 0); return do_elab_and_eval(des, scope, pe, context_width, need_const, annotatable, true, cast_type); } diff --git a/netmisc.h b/netmisc.h index 024445248..86537e36a 100644 --- a/netmisc.h +++ b/netmisc.h @@ -246,7 +246,7 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope, bool annotatable =false, ivl_variable_type_t cast_type =IVL_VT_NO_TYPE); -extern NetExpr* elab_and_eval_min_width(Design*des, NetScope*scope, +extern NetExpr* elab_and_eval_lossless(Design*des, NetScope*scope, PExpr*pe, int context_width, bool need_const =false, bool annotatable =false,