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:
Larry Doolittle 2008-01-29 08:59:55 -08:00 committed by Stephen Williams
parent 76039cf595
commit 31afec57b1
2 changed files with 11 additions and 6 deletions

View File

@ -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(),

View File

@ -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;