Fix missing CAST required above some CONSTs

git-svn-id: file://localhost/svn/verilator/trunk/verilator@963 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder 2007-10-31 19:22:26 +00:00
parent 199b32709c
commit 7fc3e6c168
5 changed files with 48 additions and 13 deletions

View File

@ -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 divide-by-zero errors in constant propagator. [Rodney Sinclair]
**** Fix wrong result with obscure signed-shift underneath a "? :".
* Verilator 3.654 10/18/2007 * Verilator 3.654 10/18/2007
**** Don't exit early if many warnings but no errors are found. [Stan Mayer] **** Don't exit early if many warnings but no errors are found. [Stan Mayer]

View File

@ -210,9 +210,9 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo
// Base macros // Base macros
/// Return true if data[bit] set /// Return true if data[bit] set
#define VL_BITISSET_I(data,bit) (data & (1UL<<VL_BITBIT_I(bit))) #define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<<VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit))) #define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit)))
#define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (1UL<<VL_BITBIT_I(bit))) #define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
/// Create two 32-bit words from quadword /// Create two 32-bit words from quadword
#define VL_SET_WQ(decl,data) { decl[0]=(data); decl[1]=((data)>>VL_WORDSIZE); } #define VL_SET_WQ(decl,data) { decl[0]=(data); decl[1]=((data)>>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 // Sign extend such that if MSB set, we get ffff_ffff, else 0s
// (Requires clean input) // (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_SIGN_Q(nbits,lhs) ((lhs) >> VL_BITBIT_Q((nbits) - VL_ULL(1)))
#define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits,lhs))) #define VL_SIGNONES_I(nbits,lhs) (-(VL_SIGN_I(nbits,lhs)))
// Sign bit extended up to MSB, doesn't include unsigned portion // Sign bit extended up to MSB, doesn't include unsigned portion
// Optimization bug in GCC 3.3 returns different bitmasks to later states for // 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)))); } static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL_ULL(1)<<(lbits-1)))); }
// Debugging prints // Debugging prints
@ -304,15 +304,15 @@ static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp,WDataInP lwp){
// EMIT_RULE: VL_ASSIGNBIT: rclean=clean; // EMIT_RULE: VL_ASSIGNBIT: rclean=clean;
static inline void VL_ASSIGNBIT_II(int, int bit, CData& lhsr, IData rhs) { static inline void VL_ASSIGNBIT_II(int, int bit, CData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit))) lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_II(int, int bit, SData& lhsr, IData rhs) { static inline void VL_ASSIGNBIT_II(int, int bit, SData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit))) lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_II(int, int bit, IData& lhsr, IData rhs) { static inline void VL_ASSIGNBIT_II(int, int bit, IData& lhsr, IData rhs) {
lhsr = ((lhsr & ~(1UL<<VL_BITBIT_I(bit))) lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) { static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) {
@ -321,25 +321,25 @@ static inline void VL_ASSIGNBIT_QI(int, int bit, QData& lhsr, QData rhs) {
} }
static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) { static inline void VL_ASSIGNBIT_WI(int, int bit, WDataOutP owp, IData rhs) {
IData orig = owp[VL_BITWORD_I(bit)]; IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = (orig & ~(1UL<<VL_BITBIT_I(bit)) owp[VL_BITWORD_I(bit)] = (orig & ~(VL_UL(1)<<VL_BITBIT_I(bit))
| (rhs<<VL_BITBIT_I(bit))); | (rhs<<VL_BITBIT_I(bit)));
} }
// Alternative form that is an instruction faster when rhs is constant one. // Alternative form that is an instruction faster when rhs is constant one.
static inline void VL_ASSIGNBIT_IO(int, int bit, CData& lhsr, IData) { static inline void VL_ASSIGNBIT_IO(int, int bit, CData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit))); lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_IO(int, int bit, SData& lhsr, IData) { static inline void VL_ASSIGNBIT_IO(int, int bit, SData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit))); lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_IO(int, int bit, IData& lhsr, IData) { static inline void VL_ASSIGNBIT_IO(int, int bit, IData& lhsr, IData) {
lhsr = (lhsr | (1UL<<VL_BITBIT_I(bit))); lhsr = (lhsr | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
static inline void VL_ASSIGNBIT_QO(int, int bit, QData& lhsr, IData) { static inline void VL_ASSIGNBIT_QO(int, int bit, QData& lhsr, IData) {
lhsr = (lhsr | (VL_ULL(1)<<VL_BITBIT_Q(bit))); lhsr = (lhsr | (VL_ULL(1)<<VL_BITBIT_Q(bit)));
} }
static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) { static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
IData orig = owp[VL_BITWORD_I(bit)]; IData orig = owp[VL_BITWORD_I(bit)];
owp[VL_BITWORD_I(bit)] = (orig | (1UL<<VL_BITBIT_I(bit))); owp[VL_BITWORD_I(bit)] = (orig | (VL_UL(1)<<VL_BITBIT_I(bit)));
} }
//=================================================================== //===================================================================

View File

@ -68,6 +68,9 @@
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant # define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
#endif #endif
// This is not necessarily the same as #UL, depending on what the IData typedef is.
#define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant
//========================================================================= //=========================================================================
// Basic integer types // Basic integer types

View File

@ -60,6 +60,7 @@ class CastVisitor : public AstNVisitor {
private: private:
// NODE STATE // NODE STATE
// Entire netlist: // Entire netlist:
// AstNode::user() // bool. Indicates node is of known size
// STATE // STATE
//int debug() { return 9; } //int debug() { return 9; }
@ -76,6 +77,7 @@ private:
//if (debug()>8) castp->dumpTree(cout,"-castins: "); //if (debug()>8) castp->dumpTree(cout,"-castins: ");
// //
insureLower32Cast(castp); insureLower32Cast(castp);
nodep->user(1); // Now must be of known size
} }
int castSize (AstNode* nodep) { int castSize (AstNode* nodep) {
if (nodep->isQuad()) return VL_QUADSIZE; if (nodep->isQuad()) return VL_QUADSIZE;
@ -84,7 +86,8 @@ private:
else return VL_WORDSIZE; else return VL_WORDSIZE;
} }
void insureCast(AstNode* nodep) { void insureCast(AstNode* nodep) {
if (castSize(nodep->backp()) != castSize(nodep)) { if (castSize(nodep->backp()) != castSize(nodep)
|| !nodep->user()) {
insertCast(nodep, castSize(nodep->backp())); insertCast(nodep, castSize(nodep->backp()));
} }
} }
@ -102,15 +105,21 @@ private:
// VISITORS // VISITORS
virtual void visit(AstNodeUniop* nodep, AstNUser*) { virtual void visit(AstNodeUniop* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
} }
virtual void visit(AstNodeBiop* nodep, AstNUser*) { virtual void visit(AstNodeBiop* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user()
| nodep->rhsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
} }
virtual void visit(AstNodeTriop* nodep, AstNUser*) { virtual void visit(AstNodeTriop* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user()
| nodep->rhsp()->user()
| nodep->thsp()->user());
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp()); if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp()); if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
if (nodep->sizeMattersThs()) insureCast(nodep->thsp()); if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
@ -118,9 +127,11 @@ private:
virtual void visit(AstCast* nodep, AstNUser*) { virtual void visit(AstCast* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
insureLower32Cast(nodep); insureLower32Cast(nodep);
nodep->user(1);
} }
virtual void visit(AstUnaryMin* nodep, AstNUser*) { virtual void visit(AstUnaryMin* nodep, AstNUser*) {
nodep->iterateChildren(*this); nodep->iterateChildren(*this);
nodep->user(nodep->lhsp()->user());
if (nodep->lhsp()->widthMin()==1) { if (nodep->lhsp()->widthMin()==1) {
// We want to avoid a GCC "converting of negative value" warning // We want to avoid a GCC "converting of negative value" warning
// from our expansion of // from our expansion of
@ -140,6 +151,13 @@ private:
// CData x=3; out = (QData)(x<<30); // CData x=3; out = (QData)(x<<30);
insertCast (nodep, castSize(nodep)); 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 // NOPs
@ -154,6 +172,7 @@ private:
public: public:
// CONSTUCTORS // CONSTUCTORS
CastVisitor(AstNetlist* nodep) { CastVisitor(AstNetlist* nodep) {
AstNode::userClearTree();
nodep->accept(*this); nodep->accept(*this);
} }
virtual ~CastVisitor() {} virtual ~CastVisitor() {}

View File

@ -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 always @ (posedge clk) begin
if (cyc!=0) begin if (cyc!=0) begin
cyc <= cyc + 1; cyc <= cyc + 1;