diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index 2c473b467..af07574f4 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -207,13 +207,15 @@ private: nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo)"); } if (v3Global.assertDTypesResolved()) { - if (nodep->width() != nodep->widthMin()) { - nodep->v3fatalSrc("Width != WidthMin"); - } if (!nodep->width() && nodep->castNodeMath()) { nodep->v3fatalSrc("Math node has no assigned width"); } } + if (v3Global.assertWidthsMatch()) { + if (nodep->width() != nodep->widthMin()) { + nodep->v3fatalSrc("Width != WidthMin"); + } + } nodep->iterateChildren(*this); BrokenTable::setUnder(nodep,false); } diff --git a/src/V3Global.h b/src/V3Global.h index 90c9d6169..bb8e668e5 100644 --- a/src/V3Global.h +++ b/src/V3Global.h @@ -43,7 +43,8 @@ class V3Global { // Globals AstNetlist* m_rootp; // Root of entire netlist int m_debugFileNumber; // Number to append to debug files created - bool m_assertDTypesResolved; // Tree should have width()==widthMin() + bool m_assertDTypesResolved; // Tree should have dtypep()'s + bool m_assertWidthsMatch; // Tree should have width()==widthMin() bool m_needHInlines; // Need __Inlines file bool m_needHeavy; // Need verilated_heavy.h include bool m_dpi; // Need __Dpi include files @@ -57,6 +58,7 @@ public: V3Global() { m_debugFileNumber = 0; m_assertDTypesResolved = false; + m_assertWidthsMatch = false; m_needHInlines = false; m_needHeavy = false; m_dpi = false; @@ -67,11 +69,13 @@ public: // ACCESSORS (general) AstNetlist* rootp() const { return m_rootp; } bool assertDTypesResolved() const { return m_assertDTypesResolved; } + bool assertWidthsMatch() const { return m_assertWidthsMatch; } // METHODS void readFiles(); void checkTree(); void assertDTypesResolved(bool flag) { m_assertDTypesResolved = flag; } + void assertWidthsMatch(bool flag) { m_assertWidthsMatch = flag; } string debugFilename(const string& nameComment, int newNumber=0) { ++m_debugFileNumber; if (newNumber) m_debugFileNumber = newNumber; diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index e3702b5ea..7ad5d1e4f 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -284,7 +284,7 @@ void V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* mod rhsp = new AstExtend (pinp->fileline(), rhsp); } } else if (pinp->width() < rhsp->width()) { - rhsp = new AstSel (pinp->fileline(), rhsp, 0, pinp->widthMin()); + rhsp = new AstSel (pinp->fileline(), rhsp, 0, pinp->width()); } rhsp->widthSignedFrom(pinp); assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsp); diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 3caaca866..89217a983 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -237,7 +237,7 @@ private: = new AstVar (fl, AstVarType::MODULETEMP, "__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(), new AstArrayDType (fl, - new AstBasicDType(fl, AstLogicPacked(), outvarp->widthMin()), + new AstBasicDType(fl, AstLogicPacked(), outvarp->width()), new AstRange (fl, VL_MASK_I(m_inWidth), 0))); tablevarp->isConst(true); tablevarp->isStatic(true); diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 743068ab7..138447982 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -621,13 +621,13 @@ private: stmt += "VL_CVT_VP_Q("; ket += ")"; } - else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->widthMin() != 1 && portp->isQuad()) { + else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1 && portp->isQuad()) { // SV is vector, Verilator isn't stmt += "VL_SET_QW("; ket += ")"; } if (!cvt - && portp->basicp() && portp->basicp()->isBitLogic() && portp->widthMin() != 1 && !portp->isWide() && !portp->isQuad()) + && portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1 && !portp->isWide() && !portp->isQuad()) stmt += "*"; // it's a svBitVecVal, which other code won't think is arrayed (as WData aren't), but really is stmt += frName; stmt += ket; @@ -778,7 +778,7 @@ private: if (args != "") { args+= ", "; } if (bitvec) {} else if (portp->isOutput()) args += "&"; - else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->widthMin() != 1) args += "&"; // it's a svBitVecVal + else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->width() != 1) args += "&"; // it's a svBitVecVal args += portp->name()+"__Vcvt"; diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 880ca190b..fc2d4931c 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -239,8 +239,9 @@ private: if (enp->width() != enrhsp->width()) { if (enrhsp->width1()) { // it seems from my futzing that the linter guarantees this condition - enrhsp = new AstReplicate(enrhsp->fileline(), enrhsp, new AstConst(enrhsp->fileline(), V3Number(enrhsp->fileline(), 32, enp->width()))); - enrhsp->width(enp->width(), enp->widthMin()); + enrhsp = new AstReplicate(enrhsp->fileline(), enrhsp, + new AstConst(enrhsp->fileline(), V3Number(enrhsp->fileline(), 32, enp->width()))); + enrhsp->width(enp->width(), enp->width()); //minwidth==width } else { enrhsp->v3error("Don't know how to deal with selection logic wider than 1 bit"); } @@ -571,7 +572,7 @@ private: AstVarRef *rp = findVarRef(pinp); rp->replaceWith(new AstVarRef(nodep->fileline(), enp, true)); rp->deleteTree(); - pinp->width(enp->width(),enp->widthMin()); + pinp->width(enp->width(),enp->width()); // minwidth==width pinp->modVarp(enchildp); m_cellp->addPinsp(pinp); refp->user1p(enp); diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 905816907..c99b80b9f 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -332,9 +332,9 @@ private: maxmsb = (varrefp->varp()->width()-1); } else { // If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp - maxmsb = basefromp->widthMin()-1; + maxmsb = basefromp->width()-1; } - int maxlsb = maxmsb - nodep->widthMin() + 1; + int maxlsb = maxmsb - nodep->width() + 1; if (debug()>=9) nodep->dumpTree(cout,"sel_old: "); V3Number maxlsbnum (nodep->fileline(), nodep->lsbp()->width(), maxlsb); @@ -386,7 +386,7 @@ private: maxmsb = adtypep->elementsConst()-1; } else if (AstConst* lhconstp = basefromp->castConst()) { // If it's a PARAMETER[bit], then basefromp may be a constant instead of a varrefp - maxmsb = lhconstp->widthMin(); + maxmsb = lhconstp->width(); } else { nodep->v3fatalSrc("No VarRef or Const under ArraySel\n"); } diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 8adaabed0..49574bb86 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -181,6 +181,7 @@ void process () { // Commit to the widths we've chosen; Make widthMin==width V3Width::widthCommit(v3Global.rootp()); v3Global.assertDTypesResolved(true); + v3Global.assertWidthsMatch(true); //v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("widthcommit.tree")); // Coverage insertion @@ -485,7 +486,7 @@ void process () { // Here down, widthMin() is the Verilog width, and width() is the C++ width // Bits between widthMin() and width() are irrelevant, but may be non zero. - v3Global.assertDTypesResolved(false); + v3Global.assertWidthsMatch(false); // Make all operations a multiple of 32 bits V3Clean::cleanAll(v3Global.rootp());