Improve net bit select calculations.
This commit is contained in:
parent
abf8274e4b
commit
8ea1e49768
2
PExpr.h
2
PExpr.h
|
|
@ -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
|
||||
|
|
|
|||
37
elab_expr.cc
37
elab_expr.cc
|
|
@ -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*
|
||||
|
|
|
|||
22
elab_net.cc
22
elab_net.cc
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue