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
|
// elaborate/calculate, or false if there is some sort of
|
||||||
// source error.
|
// source error.
|
||||||
|
|
||||||
|
bool calculate_bits_(Design*, NetScope*, long&msb, bool&defined) const;
|
||||||
|
|
||||||
// The calculate_parts_ method calculates the range
|
// The calculate_parts_ method calculates the range
|
||||||
// expressions of a part select for the current object. The
|
// expressions of a part select for the current object. The
|
||||||
// part select expressions are elaborated and evaluated, and
|
// 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);
|
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
|
* Given that the msb_ and lsb_ are part select expressions, this
|
||||||
* function calculates their values. Note that this method does *not*
|
* 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:
|
case index_component_t::SEL_BIT:
|
||||||
if (name_tail.index.size() > sig->array_dimensions()) {
|
if (name_tail.index.size() > sig->array_dimensions()) {
|
||||||
verinum*mval = index_tail.msb->eval_const(des, scope);
|
long msb;
|
||||||
if (mval == 0) {
|
bool bit_defined_flag;
|
||||||
cerr << get_fileline() << ": error: Index of " << path_ <<
|
/* bool flag = */ calculate_bits_(des, scope, msb, bit_defined_flag);
|
||||||
" needs to be constant in this context." <<
|
ivl_assert(*this, bit_defined_flag);
|
||||||
endl;
|
midx = sig->sb_to_idx(prefix_indices, msb);
|
||||||
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());
|
|
||||||
if (midx >= (long)sig->vector_width()) {
|
if (midx >= (long)sig->vector_width()) {
|
||||||
cerr << get_fileline() << ": error: Index " << sig->name()
|
cerr << get_fileline() << ": error: Index " << sig->name()
|
||||||
<< "[" << mval->as_long() << "] is out of range."
|
<< "[" << msb << "] is out of range."
|
||||||
<< endl;
|
<< endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
midx = 0;
|
midx = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue