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:
parent
199b32709c
commit
7fc3e6c168
2
Changes
2
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 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]
|
||||||
|
|
|
||||||
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//===================================================================
|
//===================================================================
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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() {}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue