Improve net bit select calculations.

This commit is contained in:
Stephen Williams 2012-04-30 11:48:33 -07:00
parent abf8274e4b
commit 8ea1e49768
3 changed files with 45 additions and 16 deletions

View File

@ -328,6 +328,8 @@ class PEIdent : public PExpr {
// elaborate/calculate, or false if there is some sort of
// source error.
bool calculate_bits_(Design*, NetScope*, long&msb, bool&defined) const;
// The calculate_parts_ method calculates the range
// expressions of a part select for the current object. The
// part select expressions are elaborated and evaluated, and

View File

@ -1879,6 +1879,43 @@ bool PEIdent::calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
return evaluate_index_prefix(des, scope, prefix_indices, index);
}
bool PEIdent::calculate_bits_(Design*des, NetScope*scope,
long&msb, bool&defined) const
{
defined = true;
const name_component_t&name_tail = path_.back();
ivl_assert(*this, !name_tail.index.empty());
const index_component_t&index_tail = name_tail.index.back();
ivl_assert(*this, index_tail.sel == index_component_t::SEL_BIT);
ivl_assert(*this, index_tail.msb && !index_tail.lsb);
/* This handles bit selects. In this case, there in one
bit select expressions which must be constant. */
NetExpr*msb_ex = elab_and_eval(des, scope, index_tail.msb, -1, true);
NetEConst*msb_c = dynamic_cast<NetEConst*>(msb_ex);
if (msb_c == 0) {
cerr << index_tail.msb->get_fileline() << ": error: "
"Bit select expressionsmust be constant."
<< endl;
cerr << index_tail.msb->get_fileline() << ": : "
"This msb expression violates the rule: "
<< *index_tail.msb << endl;
des->errors += 1;
/* Attempt to recover from error. */
msb = 0;
} else {
if (! msb_c->value().is_defined())
defined = false;
msb = msb_c->value().as_long();
}
delete msb_ex;
return true;
}
/*
* Given that the msb_ and lsb_ are part select expressions, this
* function calculates their values. Note that this method does *not*

View File

@ -360,24 +360,14 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
case index_component_t::SEL_BIT:
if (name_tail.index.size() > sig->array_dimensions()) {
verinum*mval = index_tail.msb->eval_const(des, scope);
if (mval == 0) {
cerr << get_fileline() << ": error: Index of " << path_ <<
" needs to be constant in this context." <<
endl;
cerr << get_fileline() << ": : Index expression is: "
<< *index_tail.msb << endl;
cerr << get_fileline() << ": : Context scope is: "
<< scope_path(scope) << endl;
des->errors += 1;
return false;
}
assert(mval);
midx = sig->sb_to_idx(prefix_indices, mval->as_long());
long msb;
bool bit_defined_flag;
/* bool flag = */ calculate_bits_(des, scope, msb, bit_defined_flag);
ivl_assert(*this, bit_defined_flag);
midx = sig->sb_to_idx(prefix_indices, msb);
if (midx >= (long)sig->vector_width()) {
cerr << get_fileline() << ": error: Index " << sig->name()
<< "[" << mval->as_long() << "] is out of range."
<< "[" << msb << "] is out of range."
<< endl;
des->errors += 1;
midx = 0;