diff --git a/elab_net.cc b/elab_net.cc index 27c47137a..a04140f56 100644 --- a/elab_net.cc +++ b/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(), diff --git a/netlist.cc b/netlist.cc index a403a3f1b..485315e45 100644 --- a/netlist.cc +++ b/netlist.cc @@ -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;