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. */
|
||||
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
|
||||
connect its output to the osig here. This will be the
|
||||
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->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') {
|
||||
NetPartSelect*sign_bit
|
||||
= 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));
|
||||
}
|
||||
|
||||
/* 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
|
||||
part-selected right expression at the pad values. */
|
||||
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)
|
||||
{
|
||||
assert(s);
|
||||
assert(npins>0);
|
||||
|
||||
verinum::V init_value = verinum::Vz;
|
||||
Link::DIR dir = Link::PASSIVE;
|
||||
|
|
|
|||
Loading…
Reference in New Issue