Fix for pr1879226, large constant shift values
Addresses pr1879226 on a couple of levels. Analysis: NetNet* PEBinary::elaborate_net_shift_() didn't flag dist==lwidth as a case where all bits of the input are shifted away, which made it create a real concatenator for this case. It attempted to create NetNet*tmp with zero width, which doesn't work; (lsb,msb) ends up as (0,-1), which is later interpreted as a 2-bit wide net. Added an assert to the NetNet constructor to catch any other lurking attempts to create zero-width nets. Added short-circuit code to handle the case where all bits of the input are shifted away. This case used to be "handled" by an assert failure.
This commit is contained in:
parent
76039cf595
commit
31afec57b1
16
elab_net.cc
16
elab_net.cc
|
|
@ -1110,12 +1110,6 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||||
the left signal again. */
|
the left signal again. */
|
||||||
if (dist == 0) return lsig;
|
if (dist == 0) return lsig;
|
||||||
|
|
||||||
/* Another very special case: constant shift the entire
|
|
||||||
value away. The result is a const. */
|
|
||||||
if (dist > lwidth) {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The construction that I'm making will ultimately
|
/* The construction that I'm making will ultimately
|
||||||
connect its output to the osig here. This will be the
|
connect its output to the osig here. This will be the
|
||||||
result that I return from this function. */
|
result that I return from this function. */
|
||||||
|
|
@ -1154,6 +1148,8 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||||
zero->local_flag(true);
|
zero->local_flag(true);
|
||||||
zero->set_line(*this);
|
zero->set_line(*this);
|
||||||
|
|
||||||
|
/* Padding bits are zero in most cases, but copies of
|
||||||
|
* the sign bit in the case of a signed right shift */
|
||||||
if (op_ == 'R') {
|
if (op_ == 'R') {
|
||||||
NetPartSelect*sign_bit
|
NetPartSelect*sign_bit
|
||||||
= new NetPartSelect(lsig, lsig->vector_width()-1,
|
= new NetPartSelect(lsig, lsig->vector_width()-1,
|
||||||
|
|
@ -1180,6 +1176,14 @@ NetNet* PEBinary::elaborate_net_shift_(Design*des, NetScope*scope,
|
||||||
connect(zero->pin(0), zero_c->pin(0));
|
connect(zero->pin(0), zero_c->pin(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If all data bits get shifted away, connect the zero or
|
||||||
|
* padding bits directly to output, and stop before building the
|
||||||
|
* concatenation. */
|
||||||
|
if (dist >= lwidth) {
|
||||||
|
connect(osig->pin(0), zero->pin(0));
|
||||||
|
return osig;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make a concatenation operator that will join the
|
/* Make a concatenation operator that will join the
|
||||||
part-selected right expression at the pad values. */
|
part-selected right expression at the pad values. */
|
||||||
NetConcat*cc = new NetConcat(scope, scope->local_symbol(),
|
NetConcat*cc = new NetConcat(scope, scope->local_symbol(),
|
||||||
|
|
|
||||||
|
|
@ -402,6 +402,7 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
|
||||||
local_flag_(false), eref_count_(0), lref_count_(0)
|
local_flag_(false), eref_count_(0), lref_count_(0)
|
||||||
{
|
{
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(npins>0);
|
||||||
|
|
||||||
verinum::V init_value = verinum::Vz;
|
verinum::V init_value = verinum::Vz;
|
||||||
Link::DIR dir = Link::PASSIVE;
|
Link::DIR dir = Link::PASSIVE;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue