Was a little too aggressive with the lossless elab_and_eval
The index expressions ARE self-sized context, we just need to force the EXPAND flag to make this work.
This commit is contained in:
parent
dfaed128c0
commit
078a3fd409
27
netmisc.cc
27
netmisc.cc
|
|
@ -476,13 +476,6 @@ void indices_to_expressions(Design*des, NetScope*scope,
|
||||||
{
|
{
|
||||||
ivl_assert(*loc, count <= src.size());
|
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.invalid = false;
|
||||||
flags.variable = false;
|
flags.variable = false;
|
||||||
flags.undefined = false;
|
flags.undefined = false;
|
||||||
|
|
@ -497,7 +490,7 @@ void indices_to_expressions(Design*des, NetScope*scope,
|
||||||
}
|
}
|
||||||
ivl_assert(*loc, cur->msb);
|
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)
|
if (word_index == 0)
|
||||||
flags.invalid = true;
|
flags.invalid = true;
|
||||||
|
|
@ -741,13 +734,13 @@ NetExpr* condition_reduce(NetExpr*expr)
|
||||||
|
|
||||||
static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
|
static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
|
||||||
int context_width, bool need_const, bool annotatable,
|
int context_width, bool need_const, bool annotatable,
|
||||||
bool width_is_min,
|
bool force_expand,
|
||||||
ivl_variable_type_t cast_type)
|
ivl_variable_type_t cast_type)
|
||||||
{
|
{
|
||||||
PExpr::width_mode_t mode = PExpr::SIZED;
|
PExpr::width_mode_t mode = PExpr::SIZED;
|
||||||
if ((context_width == -2) && !gn_strict_expr_width_flag)
|
if ((context_width == -2) && !gn_strict_expr_width_flag)
|
||||||
mode = PExpr::EXPAND;
|
mode = PExpr::EXPAND;
|
||||||
if (width_is_min)
|
if (force_expand)
|
||||||
mode = PExpr::EXPAND;
|
mode = PExpr::EXPAND;
|
||||||
|
|
||||||
pe->test_width(des, scope, mode);
|
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()
|
<< "returns type=" << pe->expr_type()
|
||||||
<< ", context_width=" << context_width
|
<< ", context_width=" << context_width
|
||||||
<< ", signed=" << pe->has_sign()
|
<< ", signed=" << pe->has_sign()
|
||||||
<< ", width_is_min=" << width_is_min
|
<< ", force_expand=" << force_expand
|
||||||
<< ", expr_width=" << expr_width
|
<< ", expr_width=" << expr_width
|
||||||
<< ", mode=" << PExpr::width_mode_name(mode) << endl;
|
<< ", mode=" << PExpr::width_mode_name(mode) << endl;
|
||||||
cerr << pe->get_fileline() << ": : "
|
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
|
// If we can get the same result using a smaller expression
|
||||||
// width, do so.
|
// width, do so.
|
||||||
if ((context_width > 0) && (!width_is_min)
|
if ((context_width > 0) && (!force_expand)
|
||||||
&& (pe->expr_type() != IVL_VT_REAL)
|
&& (pe->expr_type() != IVL_VT_REAL)
|
||||||
&& (expr_width > (unsigned)context_width)) {
|
&& (expr_width > (unsigned)context_width)) {
|
||||||
expr_width = max(pe->min_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,
|
// If the context_width sent is is actually the minimim width,
|
||||||
// then raise the context_width to be big enough for the
|
// then raise the context_width to be big enough for the
|
||||||
// lossless expression.
|
// lossless expression.
|
||||||
if (width_is_min && context_width > 0) {
|
if (force_expand && context_width > 0) {
|
||||||
context_width = max(context_width, (int)expr_width);
|
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);
|
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,
|
int context_width, bool need_const, bool annotatable,
|
||||||
ivl_variable_type_t cast_type)
|
ivl_variable_type_t cast_type)
|
||||||
{
|
{
|
||||||
ivl_assert(*pe, context_width > 0);
|
|
||||||
return do_elab_and_eval(des, scope, pe, context_width,
|
return do_elab_and_eval(des, scope, pe, context_width,
|
||||||
need_const, annotatable, true, cast_type);
|
need_const, annotatable, true, cast_type);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -246,7 +246,7 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope,
|
||||||
bool annotatable =false,
|
bool annotatable =false,
|
||||||
ivl_variable_type_t cast_type =IVL_VT_NO_TYPE);
|
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,
|
PExpr*pe, int context_width,
|
||||||
bool need_const =false,
|
bool need_const =false,
|
||||||
bool annotatable =false,
|
bool annotatable =false,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue