Fix width calculation for expressions containing a specparam.

This patch adds code to properly calculate the type and width of a
specparam when it is used in an expression.

This patch also fixes a compiler crash when an unknown identifier is
used in a delay expression.
This commit is contained in:
Martin Whitaker 2011-05-23 22:08:36 +01:00 committed by Stephen Williams
parent f3497e0c66
commit 6d0e5c2e89
2 changed files with 33 additions and 0 deletions

View File

@ -124,6 +124,9 @@ static NetExpr*calculate_val(Design*des, NetScope*scope, PExpr*expr)
static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
{
if (expr == 0)
return 0;
if (dynamic_cast<NetESignal*> (expr))
return expr;

View File

@ -1868,6 +1868,36 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
return expr_width_;
}
// The width of a specparam is the width of the specparam value
// (as evaluated earlier). Note that specparams aren't fully
// supported yet, so this code is likely to need rework when
// they are.
if (gn_specify_blocks_flag) {
map<perm_string,NetScope::spec_val_t>::const_iterator specp;
perm_string key = peek_tail_name(path_);
if (path_.size() == 1
&& ((specp = scope->specparams.find(key)) != scope->specparams.end())) {
NetScope::spec_val_t value = (*specp).second;
if (value.type == IVL_VT_REAL) {
expr_type_ = IVL_VT_REAL;
expr_width_ = 1;
min_width_ = 1;
signed_flag_ = true;
} else {
verinum val (value.integer);
expr_type_ = IVL_VT_BOOL;
expr_width_ = val.len();
min_width_ = expr_width_;
signed_flag_ = true;
if (mode < LOSSLESS)
mode = LOSSLESS;
}
return expr_width_;
}
}
// Not a net, and not a parameter? Give up on the type, but
// set the width to 0.
expr_type_ = IVL_VT_NO_TYPE;