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 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]
|
||||
|
|
|
@ -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_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_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
|
||||
#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
|
||||
// (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<<VL_BITBIT_I(bit)))
|
||||
lhsr = ((lhsr & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
|
||||
| (rhs<<VL_BITBIT_I(bit)));
|
||||
}
|
||||
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)));
|
||||
}
|
||||
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)));
|
||||
}
|
||||
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) {
|
||||
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)));
|
||||
}
|
||||
// Alternative form that is an instruction faster when rhs is constant one.
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
lhsr = (lhsr | (VL_ULL(1)<<VL_BITBIT_Q(bit)));
|
||||
}
|
||||
static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
|
||||
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
|
||||
#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
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class CastVisitor : public AstNVisitor {
|
|||
private:
|
||||
// NODE STATE
|
||||
// Entire netlist:
|
||||
// AstNode::user() // bool. Indicates node is of known size
|
||||
|
||||
// STATE
|
||||
//int debug() { return 9; }
|
||||
|
@ -76,6 +77,7 @@ private:
|
|||
//if (debug()>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() {}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue