Make certain all index expressions have their width probed.

It is possible for an identifier to have multiple index expressions.
(For example, a part select of a memory word.) Make sure all the
index expressions are probed for width and type.

And also, note that the unary ! returns BOOL or LOGIC, not just
the type of its operand. It is slightly different from the other
unary operators in that way.
This commit is contained in:
Stephen Williams 2009-02-18 16:02:58 -08:00
parent d94e65de4f
commit b23825e45d
1 changed files with 26 additions and 2 deletions

View File

@ -1864,6 +1864,19 @@ bool PEIdent::calculate_param_range_(Design*des, NetScope*scope,
return true;
}
static void probe_index_expr_width(Design*des, NetScope*scope,
const name_component_t&name)
{
for (list<index_component_t>::const_iterator cur = name.index.begin()
; cur != name.index.end() ; cur ++) {
if (cur->msb)
probe_expr_width(des, scope, cur->msb);
if (cur->lsb)
probe_expr_width(des, scope, cur->lsb);
}
}
unsigned PEIdent::test_width(Design*des, NetScope*scope,
unsigned min, unsigned lval,
ivl_variable_type_t&expr_type__,
@ -1884,6 +1897,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
const name_component_t&name_tail = path_.back();
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
if (!name_tail.index.empty()) {
probe_index_expr_width(des, scope, name_tail);
const index_component_t&index_tail = name_tail.index.back();
use_sel = index_tail.sel;
}
@ -1913,7 +1927,6 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
{ 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;
@ -3182,7 +3195,6 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope,
bool&unsized_flag)
{
switch (op_) {
case '!':
case '&': // Reduction AND
case '|': // Reduction OR
case '^': // Reduction XOR
@ -3199,6 +3211,18 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope,
expr_type__ = expr_type_;
return expr_width_;
case '!':
{
ivl_variable_type_t sub_type = IVL_VT_NO_TYPE;
bool flag = false;
expr_->test_width(des, scope, 0, 0, sub_type, flag);
expr_type_ = (sub_type==IVL_VT_BOOL)? IVL_VT_BOOL : IVL_VT_LOGIC;
}
// Logical ! always returns a single-bit LOGIC or BOOL value.
expr_width_ = 1;
expr_type__ = expr_type_;
return expr_width_;
}
unsigned test_wid = expr_->test_width(des, scope, min, lval, expr_type__, unsized_flag);