diff --git a/Changes b/Changes index deb9a126d..86cfdcfa9 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix parameter pins interspersed with cells broke in 3.840. [Bernard Deadman] +**** Fix large shift error on large shift constants. [David Welch] + * Verilator 3.841 2012/09/03 diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 8e76277ef..ca39ebbb5 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1821,9 +1821,19 @@ private: int width=nodep->width(); int ewidth=nodep->widthMin(); nodep->lhsp()->iterateAndNext(*this,WidthVP(width,ewidth,FINAL).p()); widthCheck(nodep,"LHS",nodep->lhsp(),width,ewidth); - if (nodep->rhsp()->width()>32) - nodep->rhsp()->v3error("Unsupported: Shifting of by over 32-bit number isn't supported." - <<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n"); + if (nodep->rhsp()->width()>32) { + AstConst* shiftp = nodep->rhsp()->castConst(); + if (shiftp && shiftp->num().mostSetBitP1() <= 32) { + // If (number)<<96'h1, then make it into (number)<<32'h1 + V3Number num (shiftp->fileline(), 32, 0); num.opAssign(shiftp->num()); + AstNode* shiftp = nodep->rhsp(); + nodep->rhsp()->replaceWith(new AstConst(shiftp->fileline(), num)); + shiftp->deleteTree(); shiftp=NULL; + } else { + nodep->rhsp()->v3error("Unsupported: Shifting of by over 32-bit number isn't supported." + <<" (This isn't a shift of 32 bits, but a shift of 2^32, or 4 billion!)\n"); + } + } } return nodep; // May edit } diff --git a/test_regress/t/t_math_shift.v b/test_regress/t/t_math_shift.v index 3069a3d40..796c7403b 100644 --- a/test_regress/t/t_math_shift.v +++ b/test_regress/t/t_math_shift.v @@ -40,6 +40,8 @@ module t (/*AUTOARG*/ if (5'sb10110>>>2 != 5'sb11101) $stop; if (5'sb10110<<2 != 5'sb11000) $stop; if (5'sb10110<<<2 != 5'sb11000) $stop; + // Allow >64 bit shifts if the shift amount is a constant + if ((64'sh458c2de282e30f8b >> 68'sh4) !== 64'sh0458c2de282e30f8) $stop; end if (cyc==2) begin amt <= 32'd28;