diff --git a/Changes b/Changes index 4b8df470d..e41de2bd7 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix divide-by-zero errors in constant propagator. [Rodney Sinclair] +**** Fix wrong result with obscure signed-shift underneath a "? :". + * Verilator 3.654 10/18/2007 **** Don't exit early if many warnings but no errors are found. [Stan Mayer] diff --git a/include/verilated.h b/include/verilated.h index e781886e5..b67eff2f8 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -210,9 +210,9 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo // Base macros /// Return true if data[bit] set -#define VL_BITISSET_I(data,bit) (data & (1UL<>VL_WORDSIZE); } @@ -225,13 +225,13 @@ static inline QData VL_CVT_FP_Q(FILE* fp) { union { FILE* fp; QData q; } u; u.q // Sign extend such that if MSB set, we get ffff_ffff, else 0s // (Requires clean input) -#define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - 1UL)) +#define VL_SIGN_I(nbits,lhs) ((lhs) >> VL_BITBIT_I((nbits) - VL_UL(1))) #define VL_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1))) #define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits,lhs))) // Sign bit extended up to MSB, doesn't include unsigned portion // Optimization bug in GCC 3.3 returns different bitmasks to later states for -static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(1UL<<(lbits-1)))); } +static inline IData VL_EXTENDSIGN_I(int lbits, IData lhs) { return (-((lhs)&(VL_UL(1)<<(lbits-1)))); } static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); } // Debugging prints @@ -304,15 +304,15 @@ static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp,WDataInP lwp){ // EMIT_RULE: VL_ASSIGNBIT: rclean=clean; static inline void VL_ASSIGNBIT_II(int, int bit, CData& lhsr, IData rhs) { - lhsr = ((lhsr & ~(1UL<8) castp->dumpTree(cout,"-castins: "); // insureLower32Cast(castp); + nodep->user(1); // Now must be of known size } int castSize (AstNode* nodep) { if (nodep->isQuad()) return VL_QUADSIZE; @@ -84,7 +86,8 @@ private: else return VL_WORDSIZE; } void insureCast(AstNode* nodep) { - if (castSize(nodep->backp()) != castSize(nodep)) { + if (castSize(nodep->backp()) != castSize(nodep) + || !nodep->user()) { insertCast(nodep, castSize(nodep->backp())); } } @@ -102,15 +105,21 @@ private: // VISITORS virtual void visit(AstNodeUniop* nodep, AstNUser*) { nodep->iterateChildren(*this); + nodep->user(nodep->lhsp()->user()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); } virtual void visit(AstNodeBiop* nodep, AstNUser*) { nodep->iterateChildren(*this); + nodep->user(nodep->lhsp()->user() + | nodep->rhsp()->user()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); } virtual void visit(AstNodeTriop* nodep, AstNUser*) { nodep->iterateChildren(*this); + nodep->user(nodep->lhsp()->user() + | nodep->rhsp()->user() + | nodep->thsp()->user()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); if (nodep->sizeMattersThs()) insureCast(nodep->thsp()); @@ -118,9 +127,11 @@ private: virtual void visit(AstCast* nodep, AstNUser*) { nodep->iterateChildren(*this); insureLower32Cast(nodep); + nodep->user(1); } virtual void visit(AstUnaryMin* nodep, AstNUser*) { nodep->iterateChildren(*this); + nodep->user(nodep->lhsp()->user()); if (nodep->lhsp()->widthMin()==1) { // We want to avoid a GCC "converting of negative value" warning // from our expansion of @@ -140,6 +151,13 @@ private: // CData x=3; out = (QData)(x<<30); insertCast (nodep, castSize(nodep)); } + nodep->user(1); + } + virtual void visit(AstConst* nodep, AstNUser*) { + // Constants are of unknown size if smaller then 33 bits, becase + // we're too lazy to wrap every constant in the universe in + // ((IData)#). + nodep->user(nodep->isQuad() || nodep->isWide()); } // NOPs @@ -154,6 +172,7 @@ private: public: // CONSTUCTORS CastVisitor(AstNetlist* nodep) { + AstNode::userClearTree(); nodep->accept(*this); } virtual ~CastVisitor() {} diff --git a/test_regress/t/t_math_vgen.v b/test_regress/t/t_math_vgen.v index 76d9aec40..8991911f6 100644 --- a/test_regress/t/t_math_vgen.v +++ b/test_regress/t/t_math_vgen.v @@ -263,6 +263,17 @@ module t (/*AUTOARG*/ //============================================================ + reg signed [ 5:0] W123_is_3f ; //=3F + + always @(posedge clk) begin + W123_is_3f <= 6'sh3f; + end + always @(posedge clk) begin + if (((~ ((32'sh088d1bcb) <<< W123_is_3f)) >>> 6'sh3f) != 32'shffffffff) if (check) $stop; + end + + //============================================================ + always @ (posedge clk) begin if (cyc!=0) begin cyc <= cyc + 1;