From 91159da30d3e80c2af5ba93a8a11bf452869fb5d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 2 Feb 2013 12:43:28 -0500 Subject: [PATCH] Fix enums with X values. Test in next commit. --- Changes | 2 ++ src/V3Number.cpp | 10 ++++++++++ src/V3Number.h | 3 ++- src/V3Unknown.cpp | 6 ++++++ src/V3Width.cpp | 7 +------ 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Changes b/Changes index 5a441de4c..8b3ad40a3 100644 --- a/Changes +++ b/Changes @@ -30,6 +30,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix package logic var compile error. +**** Fix enums with X values. + * Verilator 3.844 2013/01/09 diff --git a/src/V3Number.cpp b/src/V3Number.cpp index c22f99507..3026666b3 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -625,6 +625,16 @@ bool V3Number::isLt(const V3Number& rhs) const { } return 0; } +bool V3Number::isLtXZ(const V3Number& rhs) const { + // Include X/Z in comparisons for sort ordering + for (int bit=0; bitwidth(),rhs.width()); bit++) { + if (this->bitIs1(bit) && rhs.bitIs0(bit)) { return 1; } + if (rhs.bitIs1(bit) && this->bitIs0(bit)) { return 0; } + if (this->bitIsXZ(bit)) { return 1; } + if (rhs.bitIsXZ(bit)) { return 0; } + } + return 0; +} int V3Number::widthMin() const { for(int bit=width()-1; bit>0; bit--) { diff --git a/src/V3Number.h b/src/V3Number.h index 151dc7b7b..8437b5501 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -166,6 +166,7 @@ public: bool isEqAllOnes(int optwidth=0) const; bool isCaseEq(const V3Number& rhsp) const; // operator== bool isLt(const V3Number& rhsp) const; // operator< + bool isLtXZ(const V3Number& rhsp) const; // operator< with XZ compared void isSigned(bool ssigned) { m_signed=ssigned; } bool isUnknown() const; uint32_t toUInt() const; @@ -180,7 +181,7 @@ public: uint32_t mostSetBitP1() const; // Highest bit set plus one, IE for 16 return 5, for 0 return 0. // Operators - bool operator<(const V3Number& rhs) const { return isLt(rhs); } + bool operator<(const V3Number& rhs) const { return isLtXZ(rhs); } // STATICS static int log2b(uint32_t num); diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index b5239a88c..f68cbe603 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -168,6 +168,11 @@ private: m_constXCvt = true; nodep->bodysp()->iterateAndNext(*this); } + virtual void visit(AstNodeDType* nodep, AstNUser*) { + m_constXCvt = false; // Avoid loosing the X's in casex + nodep->iterateChildren(*this); + m_constXCvt = true; + } void visitEqNeqCase(AstNodeBiop* nodep) { UINFO(4," N/EQCASE->EQ "<lhsp()); // lhsp may change @@ -283,6 +288,7 @@ private: } else { // Make a Vxrand variable // We use the special XTEMP type so it doesn't break pure functions + if (!m_modp) nodep->v3fatalSrc("X number not under module"); string newvarname = ((string)"__Vxrand" +cvtToStr(m_modp->varNumGetInc())); AstVar* newvarp diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 06c8ec05d..d3e8fa49d 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -115,7 +115,6 @@ private: // STATE bool m_paramsOnly; // Computing parameter value; limit operation AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations - AstNodeCase* m_casep; // Current case statement CaseItem is under AstFunc* m_funcp; // Current function AstInitial* m_initialp; // Current initial block AstAttrOf* m_attrp; // Current attribute @@ -1215,12 +1214,10 @@ private: virtual void visit(AstNodeCase* nodep, AstNUser*) { // TOP LEVEL NODE - AstNodeCase* lastCasep = m_casep; - m_casep = nodep; nodep->exprp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p()); for (AstCaseItem* nextip, *itemp = nodep->itemsp(); itemp; itemp=nextip) { nextip = itemp->nextp()->castCaseItem(); // Prelim may cause the node to get replaced - if (!m_casep->castGenCase()) itemp->bodysp()->iterateAndNext(*this); + if (!nodep->castGenCase()) itemp->bodysp()->iterateAndNext(*this); for (AstNode* nextcp, *condp = itemp->condsp(); condp; condp=nextcp) { nextcp = condp->nextp(); // Prelim may cause the node to get replaced condp->iterate(*this,WidthVP(ANYSIZE,0,PRELIM).p()); condp=NULL; @@ -1244,7 +1241,6 @@ private: } } widthCheck(nodep,"Case expression",nodep->exprp(),width,mwidth); - m_casep = lastCasep; } virtual void visit(AstNodeFor* nodep, AstNUser*) { // TOP LEVEL NODE @@ -2532,7 +2528,6 @@ public: // // don't wish to trigger errors m_paramsOnly = paramsOnly; m_cellRangep = NULL; - m_casep = NULL; m_funcp = NULL; m_initialp = NULL; m_attrp = NULL;