From b23825e45d734487467561d9f83e4ebfd98f06a0 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 18 Feb 2009 16:02:58 -0800 Subject: [PATCH] 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. --- elab_expr.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 83510e528..c2b5af310 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -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::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);