diff --git a/Changes b/Changes index d8f1a6089..a1bc78d6e 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,9 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.885 devel +**** Fix false warnings on non-power-2 enums using .next/.prev. + + * Verilator 3.884 2016-05-18 ** Support parameter type, bug376. [Alan Hunter, et al] diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 5223c9569..aefc35ab6 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1493,6 +1493,7 @@ private: nodep->v3error("Unsupported: Arguments passed to enum.next method"); } // Need a runtime lookup table. Yuk. + // Most enums unless overridden are 32 bits, so we size array based on max enum value used. // Ideally we would have a fast algorithm when a number is // of small width and complete and so can use an array, and // a map for when the value is many bits and sparse. @@ -1508,10 +1509,15 @@ private: return; } } + int selwidth = V3Number::log2b(msbdim)+1; // Width to address a bit AstVar* varp = enumVarp(adtypep, attrType, msbdim); AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false); varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp()); - AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, nodep->fromp()->unlinkFrBack()); + AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, + // Select in case widths are off due to msblen!=width + new AstSel(nodep->fileline(), + nodep->fromp()->unlinkFrBack(), + 0, selwidth)); nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); } else { nodep->v3error("Unknown built-in enum method '"<fromp()->prettyTypeName()<<"'"); @@ -3413,7 +3419,7 @@ private: } AstVar* enumVarp(AstEnumDType* nodep, AstAttrType attrType, uint32_t msbdim) { // Return a variable table which has specified dimension properties for this variable - TableMap::iterator pos = m_tableMap.find(make_pair(nodep,attrType)); + TableMap::iterator pos = m_tableMap.find(make_pair(nodep, attrType)); if (pos != m_tableMap.end()) { return pos->second; } @@ -3422,7 +3428,7 @@ private: if (attrType == AstAttrType::ENUM_NAME) { basep = nodep->findStringDType(); } else { - basep = nodep->findSigned32DType(); + basep = nodep->dtypep(); } AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(), basep, diff --git a/test_regress/t/t_enum_type_methods.v b/test_regress/t/t_enum_type_methods.v index ea2ffaec1..431244ac7 100644 --- a/test_regress/t/t_enum_type_methods.v +++ b/test_regress/t/t_enum_type_methods.v @@ -12,11 +12,11 @@ module t (/*AUTOARG*/ ); input clk; - typedef enum { - E01 = 1, - E03 = 3, - E04 = 4 - } my_t; + typedef enum [3:0] { + E01 = 1, + E03 = 3, + E04 = 4 + } my_t; integer cyc=0; my_t e;