diff --git a/src/V3Ast.h b/src/V3Ast.h index d08b4b8ab..03236e147 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -981,61 +981,53 @@ inline std::ostream& operator<<(std::ostream& os, const VParseRefExp& rhs) { class VNumRange final { public: - int m_hi = 0; // HI part, HI always >= LO - int m_lo = 0; // LO - union { - int mu_flags; - struct { - bool m_ranged : 1; // Has a range - bool m_littleEndian : 1; // Bit vector is little endian - }; - }; + int m_left = 0; + int m_right = 0; + bool m_ranged = false; // Has a range bool operator==(const VNumRange& rhs) const { - return m_hi == rhs.m_hi && m_lo == rhs.m_lo && mu_flags == rhs.mu_flags; + return m_left == rhs.m_left && m_right == rhs.m_right && m_ranged == rhs.m_ranged; } bool operator<(const VNumRange& rhs) const { - if ((m_hi < rhs.m_hi)) return true; - if (!(m_hi == rhs.m_hi)) return false; // lhs > rhs - if ((m_lo < rhs.m_lo)) return true; - if (!(m_lo == rhs.m_lo)) return false; // lhs > rhs - if ((mu_flags < rhs.mu_flags)) return true; - if (!(mu_flags == rhs.mu_flags)) return false; // lhs > rhs + if ((m_left < rhs.m_left)) return true; + if (!(m_left == rhs.m_left)) return false; // lhs > rhs + if ((m_right < rhs.m_right)) return true; + if (!(m_right == rhs.m_right)) return false; // lhs > rhs + if ((m_ranged < rhs.m_ranged)) return true; + if (!(m_ranged == rhs.m_ranged)) return false; // lhs > rhs return false; } // - class LeftRight {}; - VNumRange() - : mu_flags{0} {} - VNumRange(int hi, int lo, bool littleEndian) - : mu_flags{0} { - init(hi, lo, littleEndian); - } - VNumRange(LeftRight, int left, int right) - : mu_flags{0} { - init((right > left) ? right : left, (right > left) ? left : right, (right > left)); - } + VNumRange() {} + VNumRange(int hi, int lo, bool littleEndian) { init(hi, lo, littleEndian); } + VNumRange(int left, int right) + : m_left{left} + , m_right{right} + , m_ranged{true} {} ~VNumRange() = default; // MEMBERS void init(int hi, int lo, bool littleEndian) { - m_hi = hi; - m_lo = lo; - mu_flags = 0; + if (lo > hi) { + int t = hi; + hi = lo; + lo = t; + } + m_left = littleEndian ? lo : hi; + m_right = littleEndian ? hi : lo; m_ranged = true; - m_littleEndian = littleEndian; } - int hi() const { return m_hi; } - int lo() const { return m_lo; } - int left() const { return littleEndian() ? lo() : hi(); } // How to show a declaration - int right() const { return littleEndian() ? hi() : lo(); } + int left() const { return m_left; } + int right() const { return m_right; } + int hi() const { return m_left > m_right ? m_left : m_right; } // How to show a declaration + int lo() const { return m_left > m_right ? m_right : m_left; } // How to show a declaration int leftToRightInc() const { return littleEndian() ? 1 : -1; } int elements() const { return hi() - lo() + 1; } bool ranged() const { return m_ranged; } - bool littleEndian() const { return m_littleEndian; } + bool littleEndian() const { return m_left < m_right; } int hiMaxSelect() const { return (lo() < 0 ? hi() - lo() : hi()); } // Maximum value a [] select may index bool representableByWidth() const { // Could be represented by just width=1, or [width-1:0] - return (!m_ranged || (m_lo == 0 && m_hi >= 1 && !m_littleEndian)); + return (!m_ranged || (m_right == 0 && m_left >= 1)); } void dump(std::ostream& str) const { if (ranged()) { @@ -2491,12 +2483,11 @@ public: virtual void dump(std::ostream& str) const override; // For basicp() we reuse the size to indicate a "fake" basic type of same size virtual AstBasicDType* basicp() const override { - return (isFourstate() ? VN_CAST( - findLogicRangeDType(VNumRange(width() - 1, 0, false), width(), numeric()), - BasicDType) - : VN_CAST(findBitRangeDType(VNumRange(width() - 1, 0, false), - width(), numeric()), - BasicDType)); + return (isFourstate() + ? VN_CAST(findLogicRangeDType(VNumRange{width() - 1, 0}, width(), numeric()), + BasicDType) + : VN_CAST(findBitRangeDType(VNumRange{width() - 1, 0}, width(), numeric()), + BasicDType)); } virtual AstNodeDType* skipRefp() const override { return (AstNodeDType*)this; } virtual AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } @@ -2526,9 +2517,9 @@ public: const auto it = m_members.find(name); return (it == m_members.end()) ? nullptr : it->second; } - static int lsb() { return 0; } - int msb() const { return dtypep()->width() - 1; } // Packed classes look like arrays - VNumRange declRange() const { return VNumRange(msb(), lsb(), false); } + static int lo() { return 0; } + int hi() const { return dtypep()->width() - 1; } // Packed classes look like arrays + VNumRange declRange() const { return VNumRange{hi(), lo()}; } }; class AstNodeArrayDType VL_NOT_FINAL : public AstNodeDType { @@ -2554,17 +2545,17 @@ public: } virtual bool same(const AstNode* samep) const override { const AstNodeArrayDType* asamep = static_cast(samep); - return (msb() == asamep->msb() && subDTypep() == asamep->subDTypep() + return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep() && rangenp()->sameTree(asamep->rangenp())); } // HashedDT doesn't recurse, so need to check children virtual bool similarDType(AstNodeDType* samep) const override { const AstNodeArrayDType* asamep = static_cast(samep); - return (asamep && type() == samep->type() && msb() == asamep->msb() + return (asamep && type() == samep->type() && hi() == asamep->hi() && rangenp()->sameTree(asamep->rangenp()) && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp())); } virtual V3Hash sameHash() const override { - return V3Hash(V3Hash(m_refDTypep), V3Hash(msb()), V3Hash(lsb())); + return V3Hash(V3Hash(m_refDTypep), V3Hash(hi()), V3Hash(lo())); } virtual AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* childDTypep() const { return VN_CAST(op1p(), NodeDType); } @@ -2588,8 +2579,10 @@ public: virtual int widthTotalBytes() const override { return elementsConst() * subDTypep()->widthTotalBytes(); } - int msb() const; - int lsb() const; + int left() const; + int right() const; + int hi() const; + int lo() const; int elementsConst() const; VNumRange declRange() const; }; @@ -3004,12 +2997,12 @@ inline void AstNodeVarRef::varp(AstVar* varp) { inline bool AstNodeDType::isFourstate() const { return basicp()->isFourstate(); } inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); } -inline int AstNodeArrayDType::msb() const { return rangep()->msbConst(); } -inline int AstNodeArrayDType::lsb() const { return rangep()->lsbConst(); } +inline int AstNodeArrayDType::left() const { return rangep()->leftConst(); } +inline int AstNodeArrayDType::right() const { return rangep()->rightConst(); } +inline int AstNodeArrayDType::hi() const { return rangep()->hiConst(); } +inline int AstNodeArrayDType::lo() const { return rangep()->loConst(); } inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); } -inline VNumRange AstNodeArrayDType::declRange() const { - return VNumRange(msb(), lsb(), rangep()->littleEndian()); -} +inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right()}; } inline const char* AstNodeFTaskRef::broken() const { BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 9394042a6..aeb8ef8bd 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -185,46 +185,25 @@ public: class AstRange final : public AstNodeRange { // Range specification, for use under variables and cells -private: - bool m_littleEndian : 1; // Bit vector is little endian public: - AstRange(FileLine* fl, AstNode* msbp, AstNode* lsbp) + AstRange(FileLine* fl, AstNode* leftp, AstNode* rightp) : ASTGEN_SUPER(fl) { - m_littleEndian = false; - setOp2p(msbp); - setOp3p(lsbp); + setOp2p(leftp); + setOp3p(rightp); } - AstRange(FileLine* fl, int msb, int lsb) + AstRange(FileLine* fl, int left, int right) : ASTGEN_SUPER(fl) { - m_littleEndian = false; - setOp2p(new AstConst(fl, msb)); - setOp3p(new AstConst(fl, lsb)); + setOp2p(new AstConst(fl, left)); + setOp3p(new AstConst(fl, right)); } AstRange(FileLine* fl, const VNumRange& range) : ASTGEN_SUPER(fl) { - m_littleEndian = range.littleEndian(); - setOp2p(new AstConst(fl, range.hi())); - setOp3p(new AstConst(fl, range.lo())); + setOp2p(new AstConst(fl, range.left())); + setOp3p(new AstConst(fl, range.right())); } ASTNODE_NODE_FUNCS(Range) - AstNode* msbp() const { return op2p(); } // op2 = Msb expression - AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression - AstNode* leftp() const { - return littleEndian() ? lsbp() : msbp(); - } // How to show a declaration - AstNode* rightp() const { return littleEndian() ? msbp() : lsbp(); } - int msbConst() const { - AstConst* constp = VN_CAST(msbp(), Const); - return (constp ? constp->toSInt() : 0); - } - int lsbConst() const { - AstConst* constp = VN_CAST(lsbp(), Const); - return (constp ? constp->toSInt() : 0); - } - int elementsConst() const { - return (msbConst() > lsbConst()) ? msbConst() - lsbConst() + 1 - : lsbConst() - msbConst() + 1; - } + AstNode* leftp() const { return op2p(); } + AstNode* rightp() const { return op3p(); } int leftConst() const { AstConst* constp = VN_CAST(leftp(), Const); return (constp ? constp->toSInt() : 0); @@ -233,9 +212,18 @@ public: AstConst* constp = VN_CAST(rightp(), Const); return (constp ? constp->toSInt() : 0); } - int leftToRightInc() const { return littleEndian() ? 1 : -1; } - bool littleEndian() const { return m_littleEndian; } - void littleEndian(bool flag) { m_littleEndian = flag; } + int hiConst() const { + int l = leftConst(); + int r = rightConst(); + return l > r ? l : r; + } + int loConst() const { + int l = leftConst(); + int r = rightConst(); + return l > r ? r : l; + } + int elementsConst() const { return hiConst() - loConst() + 1; } + bool littleEndian() const { return leftConst() < rightConst(); } virtual void dump(std::ostream& str) const override; virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual V3Hash sameHash() const override { return V3Hash(); } @@ -924,22 +912,20 @@ public: bool isDpiPrimitive() const { // DPI uses a primitive type return !isDpiBitVec() && !isDpiLogicVec(); } - // Generally the msb/lsb/etc funcs should be used instead + // Generally the lo/hi/left/right funcs should be used instead of nrange() const VNumRange& nrange() const { return m.m_nrange; } - int msb() const { return (rangep() ? rangep()->msbConst() : m.m_nrange.hi()); } - int lsb() const { return (rangep() ? rangep()->lsbConst() : m.m_nrange.lo()); } - int left() const { return littleEndian() ? lsb() : msb(); } // How to show a declaration - int right() const { return littleEndian() ? msb() : lsb(); } + int hi() const { return (rangep() ? rangep()->hiConst() : m.m_nrange.hi()); } + int lo() const { return (rangep() ? rangep()->loConst() : m.m_nrange.lo()); } + int left() const { return littleEndian() ? lo() : hi(); } // How to show a declaration + int right() const { return littleEndian() ? hi() : lo(); } bool littleEndian() const { return (rangep() ? rangep()->littleEndian() : m.m_nrange.littleEndian()); } bool implicit() const { return keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT; } - VNumRange declRange() const { - return isRanged() ? VNumRange(msb(), lsb(), littleEndian()) : VNumRange(); - } + VNumRange declRange() const { return isRanged() ? VNumRange{left(), right()} : VNumRange{}; } void cvtRangeConst() { // Convert to smaller representation - if (rangep() && VN_IS(rangep()->msbp(), Const) && VN_IS(rangep()->lsbp(), Const)) { - m.m_nrange.init(rangep()->msbConst(), rangep()->lsbConst(), rangep()->littleEndian()); + if (rangep() && VN_IS(rangep()->leftp(), Const) && VN_IS(rangep()->rightp(), Const)) { + m.m_nrange = VNumRange{rangep()->leftConst(), rangep()->rightConst()}; rangep()->unlinkFrBackWithNext()->deleteTree(); rangep(nullptr); } @@ -1658,8 +1644,8 @@ public: AstSelExtract(FileLine* fl, AstNode* fromp, AstNode* msbp, AstNode* lsbp) : ASTGEN_SUPER(fl, fromp, msbp, lsbp) {} ASTNODE_NODE_FUNCS(SelExtract) - AstNode* msbp() const { return rhsp(); } - AstNode* lsbp() const { return thsp(); } + AstNode* leftp() const { return rhsp(); } + AstNode* rightp() const { return thsp(); } }; class AstSelBit final : public AstNodePreSel { diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 548d7ce43..d7699cc66 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -310,9 +310,9 @@ private: const ToggleEnt& above, AstVar* varp, AstVar* chgVarp) { // Constant if (const AstBasicDType* bdtypep = VN_CAST(dtypep, BasicDType)) { if (bdtypep->isRanged()) { - for (int index_docs = bdtypep->lsb(); index_docs < bdtypep->msb() + 1; - index_docs++) { - int index_code = index_docs - bdtypep->lsb(); + for (int index_docs = bdtypep->lo(); index_docs < bdtypep->hi() + 1; + ++index_docs) { + int index_code = index_docs - bdtypep->lo(); ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]", new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code, 1), @@ -325,8 +325,8 @@ private: toggleVarBottom(above, varp); } } else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { - for (int index_docs = adtypep->lsb(); index_docs <= adtypep->msb(); ++index_docs) { - int index_code = index_docs - adtypep->lsb(); + for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) { + int index_code = index_docs - adtypep->lo(); ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]", new AstArraySel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code), @@ -337,9 +337,9 @@ private: newent.cleanup(); } } else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) { - for (int index_docs = adtypep->lsb(); index_docs <= adtypep->msb(); ++index_docs) { + for (int index_docs = adtypep->lo(); index_docs <= adtypep->hi(); ++index_docs) { AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp(); - int index_code = index_docs - adtypep->lsb(); + int index_code = index_docs - adtypep->lo(); ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]", new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code * subtypep->width(), subtypep->width()), diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 4d069deda..719016a04 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -631,7 +631,7 @@ public: putbs(", "); // Need real storage width puts(cvtToStr(nodep->memp()->dtypep()->subDTypep()->widthMin())); - uint32_t array_lsb = 0; + uint32_t array_lo = 0; { const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef); if (!varrefp) { @@ -642,9 +642,9 @@ public: = VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) { putbs(", "); puts(cvtToStr(varrefp->varp()->dtypep()->arrayUnpackedElements())); - array_lsb = adtypep->lsb(); + array_lo = adtypep->lo(); putbs(", "); - puts(cvtToStr(array_lsb)); + puts(cvtToStr(array_lo)); } else { nodep->v3error(nodep->verilogKwd() << " loading other than unpacked/associative-array variable"); @@ -658,7 +658,7 @@ public: if (nodep->lsbp()) { iterateAndNextNull(nodep->lsbp()); } else { - puts(cvtToStr(array_lsb)); + puts(cvtToStr(array_lo)); } putbs(", "); if (nodep->msbp()) { @@ -710,7 +710,7 @@ public: puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width putbs(","); bool memory = false; - uint32_t array_lsb = 0; + uint32_t array_lo = 0; uint32_t array_size = 0; { const AstVarRef* varrefp = VN_CAST(nodep->memp(), VarRef); @@ -720,14 +720,14 @@ public: } else if (const AstUnpackArrayDType* adtypep = VN_CAST(varrefp->varp()->dtypeSkipRefp(), UnpackArrayDType)) { memory = true; - array_lsb = adtypep->lsb(); + array_lo = adtypep->lo(); array_size = adtypep->elementsConst(); } else { nodep->v3error(nodep->verilogKwd() << " loading other than unpacked-array variable"); } } - puts(cvtToStr(array_lsb)); + puts(cvtToStr(array_lo)); putbs(","); puts(cvtToStr(array_size)); putbs(", "); @@ -740,7 +740,7 @@ public: if (nodep->startp()) { iterateAndNextNull(nodep->startp()); } else { - puts(cvtToStr(array_lsb)); + puts(cvtToStr(array_lo)); } putbs(", "); if (nodep->countp()) { @@ -1789,7 +1789,7 @@ class EmitCImp final : EmitCStmts { return emitVarResetRecurse(varp, adtypep->subDTypep(), depth + 1, ".atDefault()" + cvtarray); } else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) { - UASSERT_OBJ(adtypep->msb() >= adtypep->lsb(), varp, + UASSERT_OBJ(adtypep->hi() >= adtypep->lo(), varp, "Should have swapped msb & lsb earlier."); string ivar = string("__Vi") + cvtToStr(depth); string pre = ("for (int " + ivar + "=" + cvtToStr(0) + "; " + ivar + "<" @@ -1921,7 +1921,7 @@ void EmitCStmts::emitVarDecl(const AstVar* nodep, const string& prefixIfImp) { emitDeclArrayBrackets(nodep); // If it's a packed struct/array then nodep->width is the whole // thing, msb/lsb is just lowest dimension - puts("," + cvtToStr(basicp->lsb() + nodep->width() - 1) + "," + cvtToStr(basicp->lsb())); + puts("," + cvtToStr(basicp->lo() + nodep->width() - 1) + "," + cvtToStr(basicp->lo())); if (nodep->isWide()) puts("," + cvtToStr(nodep->widthWords())); puts(");\n"); } else { @@ -2600,7 +2600,7 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) { for (AstUnpackArrayDType* arrayp = VN_CAST(elementp, UnpackArrayDType); arrayp; arrayp = VN_CAST(elementp, UnpackArrayDType)) { int vecnum = vects++; - UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp, + UASSERT_OBJ(arrayp->hi() >= arrayp->lo(), varp, "Should have swapped msb & lsb earlier."); string ivar = string("__Vi") + cvtToStr(vecnum); puts("for (int __Vi" + cvtToStr(vecnum) + "=" + cvtToStr(0)); @@ -2687,11 +2687,11 @@ void EmitCImp::emitSensitives() { arrayp; arrayp = VN_CAST(arrayp->subDTypep()->skipRefp(), UnpackArrayDType)) { int vecnum = vects++; - UASSERT_OBJ(arrayp->msb() >= arrayp->lsb(), varp, + UASSERT_OBJ(arrayp->hi() >= arrayp->lo(), varp, "Should have swapped msb & lsb earlier."); string ivar = string("__Vi") + cvtToStr(vecnum); - puts("for (int __Vi" + cvtToStr(vecnum) + "=" + cvtToStr(arrayp->lsb())); - puts("; " + ivar + "<=" + cvtToStr(arrayp->msb())); + puts("for (int __Vi" + cvtToStr(vecnum) + "=" + cvtToStr(arrayp->lo())); + puts("; " + ivar + "<=" + cvtToStr(arrayp->hi())); puts("; ++" + ivar + ") {\n"); } puts("sensitive << " + varp->nameProtect()); diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 168437852..8c505b36b 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -752,9 +752,9 @@ void EmitCSyms::emitSymImp() { // Range is always first, it's not in "C" order if (basicp->isRanged()) { bounds += " ,"; - bounds += cvtToStr(basicp->msb()); + bounds += cvtToStr(basicp->hi()); bounds += ","; - bounds += cvtToStr(basicp->lsb()); + bounds += cvtToStr(basicp->lo()); pdim++; } for (AstNodeDType* dtypep = varp->dtypep(); dtypep;) { @@ -762,9 +762,9 @@ void EmitCSyms::emitSymImp() { = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node if (const AstNodeArrayDType* adtypep = VN_CAST(dtypep, NodeArrayDType)) { bounds += " ,"; - bounds += cvtToStr(adtypep->msb()); + bounds += cvtToStr(adtypep->hi()); bounds += ","; - bounds += cvtToStr(adtypep->lsb()); + bounds += cvtToStr(adtypep->lo()); if (VN_IS(dtypep, PackArrayDType)) { pdim++; } else { diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 664f6ddbd..16665c9e9 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -513,11 +513,11 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { } virtual void visit(AstRange* nodep) override { puts("["); - if (VN_IS(nodep->msbp(), Const) && VN_IS(nodep->lsbp(), Const)) { + if (VN_IS(nodep->leftp(), Const) && VN_IS(nodep->rightp(), Const)) { // Looks nicer if we print [1:0] rather than [32'sh1:32sh0] - puts(cvtToStr(VN_CAST(nodep->leftp(), Const)->toSInt())); + puts(cvtToStr(nodep->leftConst())); puts(":"); - puts(cvtToStr(VN_CAST(nodep->rightp(), Const)->toSInt())); + puts(cvtToStr(nodep->rightConst())); puts("]"); } else { iterateAndNextNull(nodep->leftp()); @@ -570,7 +570,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { puts(" "); } else if (nodep->isRanged()) { puts(" ["); - puts(cvtToStr(nodep->msb())); + puts(cvtToStr(nodep->hi())); puts(":0] "); } } diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index b5d113238..91dad4008 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -207,7 +207,7 @@ private: UINFO(8, " dv-vec-VAR " << nodep << endl); AstUnpackArrayDType* arrdtype = VN_CAST(nodep->dtypep(), UnpackArrayDType); AstNode* prevp = nullptr; - for (int i = arrdtype->lsb(); i <= arrdtype->msb(); ++i) { + for (int i = arrdtype->lo(); i <= arrdtype->hi(); ++i) { string varNewName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__"; UINFO(8, "VAR name insert " << varNewName << " " << nodep << endl); if (!m_deModVars.find(varNewName)) { @@ -255,7 +255,7 @@ private: for (int i = 0; i < m_cellRangep->elementsConst(); i++) { m_instSelNum = m_cellRangep->littleEndian() ? (m_cellRangep->elementsConst() - 1 - i) : i; - int instNum = m_cellRangep->lsbConst() + i; + int instNum = m_cellRangep->loConst() + i; AstCell* newp = nodep->cloneTree(false); nodep->addNextHere(newp); @@ -341,10 +341,11 @@ private: // Arrayed instants: one bit for each of the instants (each // assign is 1 pinwidth wide) if (m_cellRangep->littleEndian()) { - nodep->exprp()->v3warn(LITENDIAN, "Little endian cell range connecting to " - "vector: left < right of cell range: [" - << m_cellRangep->leftConst() << ":" - << m_cellRangep->rightConst() << "]"); + nodep->exprp()->v3warn( + LITENDIAN, + "Little endian cell range connecting to vector: left < right of cell range: [" + << m_cellRangep->leftConst() << ":" << m_cellRangep->rightConst() + << "]"); } AstNode* exprp = nodep->exprp()->unlinkFrBack(); bool inputPin = nodep->modVarp()->isNonOutput(); @@ -396,7 +397,7 @@ private: AstNode* prevPinp = nullptr; // Clone the var referenced by the pin, and clone each var referenced by the varref // Clone pin varp: - for (int i = pinArrp->lsb(); i <= pinArrp->msb(); ++i) { + for (int i = pinArrp->lo(); i <= pinArrp->hi(); ++i) { string varNewName = pinVarp->name() + "__BRA__" + cvtToStr(i) + "__KET__"; AstVar* varNewp = nullptr; @@ -529,7 +530,7 @@ public: && connectXRefp->varp()->isIfaceRef()) { } else if (!alwaysCvt && connBasicp && pinBasicp && connBasicp->width() == pinBasicp->width() - && connBasicp->lsb() == pinBasicp->lsb() + && connBasicp->lo() == pinBasicp->lo() && !connectRefp->varp() ->isSc() // Need the signal as a 'shell' to convert types && connBasicp->width() == pinVarp->width()) { diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index ea1d7b2f5..9a27791a5 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -151,16 +151,16 @@ private: cleanFileline(nodep); iterateChildren(nodep); if (nodep->rangep()) { - if (!VN_IS(nodep->rangep()->msbp(), Const) // - || !VN_IS(nodep->rangep()->lsbp(), Const)) { + if (!VN_IS(nodep->rangep()->leftp(), Const) // + || !VN_IS(nodep->rangep()->rightp(), Const)) { nodep->v3error("Enum ranges must be integral, per spec"); } - int msb = nodep->rangep()->msbConst(); - int lsb = nodep->rangep()->lsbConst(); - int increment = (msb > lsb) ? -1 : 1; + int left = nodep->rangep()->leftConst(); + int right = nodep->rangep()->rightConst(); + int increment = (left > right) ? -1 : 1; int offset_from_init = 0; AstNode* addp = nullptr; - for (int i = msb; i != (lsb + increment); i += increment, offset_from_init++) { + for (int i = left; i != (right + increment); i += increment, offset_from_init++) { string name = nodep->name() + cvtToStr(i); AstNode* valuep = nullptr; if (nodep->valuep()) { diff --git a/src/V3Simulate.h b/src/V3Simulate.h index edec6cffe..920df2704 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -152,7 +152,7 @@ private: int msb = lsb + width - 1; V3Number fieldNum(nump, width); fieldNum.opSel(*nump, msb, lsb); - int arrayElem = arrayp->lsb() + element; + int arrayElem = arrayp->lo() + element; out << arrayElem << " = " << prettyNumber(&fieldNum, childTypep); if (element < arrayElements - 1) out << ", "; } diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index 83ae80e89..ac88d2def 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -405,7 +405,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl { static int outerMostSizeOfUnpackedArray(AstVar* nodep) { AstUnpackArrayDType* dtypep = VN_CAST(nodep->dtypep()->skipRefp(), UnpackArrayDType); UASSERT_OBJ(dtypep, nodep, "Must be unapcked array"); - return dtypep->msb() - dtypep->lsb() + 1; + return dtypep->elementsConst(); } void setContextAndIterateChildren(AstNode* nodep) { @@ -585,7 +585,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl { const VNumRange selRange{nodep->declRange().hi() + dtypep->declRange().lo(), nodep->declRange().lo() + dtypep->declRange().lo(), nodep->declRange().littleEndian()}; - UASSERT_OBJ(dtypep->lsb() <= selRange.lo() && selRange.hi() <= dtypep->msb(), nodep, + UASSERT_OBJ(dtypep->lo() <= selRange.lo() && selRange.hi() <= dtypep->hi(), nodep, "Range check for AstSliceSel must have been finished in V3Width.cpp"); UINFO(4, "add " << nodep << " for " << refp->varp()->prettyName() << "\n"); m_refs.tryAdd(m_contextp, refp, nodep, nodep->declRange().hi(), @@ -614,12 +614,12 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl { AstVar* varp = newVar(nodep->fileline(), AstVarType::VAR, name, dtypep); // Variable will be registered in the caller side. UINFO(3, varp->prettyNameQ() - << " is created lsb:" << dtypep->lsb() << " msb:" << dtypep->msb() << "\n"); + << " is created lsb:" << dtypep->lo() << " msb:" << dtypep->hi() << "\n"); // Use AstAssign if true, otherwise AstAssignW const bool use_simple_assign = (context && VN_IS(context, NodeFTaskRef)) || (assignp && VN_IS(assignp, Assign)); - for (int i = 0; i <= dtypep->msb() - dtypep->lsb(); ++i) { + for (int i = 0; i < dtypep->elementsConst(); ++i) { AstNode* lhsp = newVarRef(nodep->fileline(), vars.at(start_idx + i), lvalue ? VAccess::WRITE : VAccess::READ); AstNode* rhsp = new AstArraySel( @@ -689,10 +689,10 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl { const bool needNext = VN_IS(subTypep, UnpackArrayDType); // Still unpacked array. std::vector vars; // Add the split variables - for (vlsint32_t i = 0; i <= dtypep->msb() - dtypep->lsb(); ++i) { + for (vlsint32_t i = 0; i < dtypep->elementsConst(); ++i) { // Unpacked array is traced as var(idx), not var[idx]. const std::string name - = varp->name() + AstNode::encodeName('(' + cvtToStr(i + dtypep->lsb()) + ')'); + = varp->name() + AstNode::encodeName('(' + cvtToStr(i + dtypep->lo()) + ')'); AstVar* newp = newVar(varp->fileline(), AstVarType::VAR, name, subTypep); newp->propagateAttrFrom(varp); // If varp is an IO, varp will remain and will be traced. @@ -722,7 +722,7 @@ class SplitUnpackedVarVisitor final : public AstNVisitor, public SplitVarImpl { refp = VN_CAST(selp->fromp(), VarRef); UASSERT_OBJ(refp, selp, "Unexpected op is registered"); adtypep = VN_CAST(selp->dtypep()->skipRefp(), UnpackArrayDType); - lsb = adtypep->lsb(); + lsb = adtypep->lo(); } AstVarRef* newrefp = createTempVar(sit->context(), refp, adtypep, varp->name(), vars, lsb, refp->access(), sit->ftask()); @@ -922,8 +922,8 @@ public: points.emplace_back(std::make_pair(it->msb() + 1, true)); // End of a region } if (skipUnused && !m_rhs.empty()) { // Range to be read must be kept, so add points here - int lsb = m_basicp->msb() + 1; - int msb = m_basicp->lsb() - 1; + int lsb = m_basicp->hi() + 1; + int msb = m_basicp->lo() - 1; for (size_t i = 0; i < m_rhs.size(); ++i) { lsb = std::min(lsb, m_rhs[i].lsb()); msb = std::max(msb, m_rhs[i].msb()); @@ -933,8 +933,8 @@ public: points.emplace_back(std::make_pair(msb + 1, true)); } if (!skipUnused) { // All bits are necessary - points.emplace_back(std::make_pair(m_basicp->lsb(), false)); - points.emplace_back(std::make_pair(m_basicp->msb() + 1, true)); + points.emplace_back(std::make_pair(m_basicp->lo(), false)); + points.emplace_back(std::make_pair(m_basicp->hi() + 1, true)); } std::sort(points.begin(), points.end(), SortByFirst()); @@ -985,10 +985,10 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl { UASSERT_OBJ(!nodep->classOrPackagep(), nodep, "variable in package must have been dropped beforehand."); const AstBasicDType* basicp = refit->second.basicp(); - refit->second.append(PackedVarRefEntry(nodep, basicp->lsb(), varp->width()), + refit->second.append(PackedVarRefEntry(nodep, basicp->lo(), varp->width()), nodep->access()); UINFO(5, varp->prettyName() - << " Entire bit of [" << basicp->lsb() << ":+" << varp->width() << "] \n"); + << " Entire bit of [" << basicp->lo() << "+:" << varp->width() << "] \n"); } virtual void visit(AstSel* nodep) override { AstVarRef* vrefp = VN_CAST(nodep->fromp(), VarRef); @@ -1010,12 +1010,12 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl { VN_CAST(nodep->widthp(), Const)}}; // GCC 3.8.0 wants {{}} if (consts[0] && consts[1]) { // OK refit->second.append( - PackedVarRefEntry(nodep, consts[0]->toSInt() + refit->second.basicp()->lsb(), + PackedVarRefEntry(nodep, consts[0]->toSInt() + refit->second.basicp()->lo(), consts[1]->toUInt()), vrefp->access()); UINFO(5, varp->prettyName() << " [" << consts[0]->toSInt() << ":+" << consts[1]->toSInt() - << "] lsb:" << refit->second.basicp()->lsb() << "\n"); + << "] lsb:" << refit->second.basicp()->lo() << "\n"); } else { nodep->v3warn(SPLITVAR, vrefp->prettyNameQ() << notSplitMsg @@ -1081,7 +1081,8 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl { void createVars(AstVar* varp, const AstBasicDType* basicp, std::vector& vars) { for (size_t i = 0; i < vars.size(); ++i) { SplitNewVar* newvarp = &vars[i]; - int left = newvarp->msb(), right = newvarp->lsb(); + int left = newvarp->msb(); + int right = newvarp->lsb(); if (basicp->littleEndian()) std::swap(left, right); const std::string name = (left == right) @@ -1101,8 +1102,8 @@ class SplitPackedVarVisitor final : public AstNVisitor, public SplitVarImpl { break; default: UASSERT_OBJ(false, basicp, "Only bit and logic are allowed"); } - dtypep->rangep(new AstRange(varp->fileline(), newvarp->msb(), newvarp->lsb())); - dtypep->rangep()->littleEndian(basicp->littleEndian()); + dtypep->rangep(new AstRange{varp->fileline(), VNumRange{newvarp->msb(), newvarp->lsb(), + basicp->littleEndian()}}); newvarp->varp(new AstVar(varp->fileline(), AstVarType::VAR, name, dtypep)); newvarp->varp()->propagateAttrFrom(varp); newvarp->varp()->funcLocal(varp->isFuncLocal() || varp->isFuncReturn()); diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index fcd5e7e03..43c392c68 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -447,7 +447,8 @@ private: FileLine* const flp = m_topScopep->fileline(); AstNodeDType* const newScalarDtp = new AstBasicDType(flp, VFlagLogicPacked(), 1); v3Global.rootp()->typeTablep()->addTypesp(newScalarDtp); - AstRange* const newArange = new AstRange(flp, VNumRange(m_activityNumber - 1, 0, false)); + AstRange* const newArange + = new AstRange{flp, VNumRange{static_cast(m_activityNumber) - 1, 0}}; AstNodeDType* const newArrDtp = new AstUnpackArrayDType(flp, newScalarDtp, newArange); v3Global.rootp()->typeTablep()->addTypesp(newArrDtp); AstVar* const newvarp diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index ba248b720..d7b851a29 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -99,7 +99,7 @@ private: // misreflects one element VNumRange bitRange; if (widthOverride) { - bitRange = VNumRange(widthOverride - 1, 0, false); + bitRange = VNumRange{widthOverride - 1, 0}; } else if (const AstBasicDType* const bdtypep = m_traValuep->dtypep()->basicp()) { bitRange = bdtypep->nrange(); } @@ -238,13 +238,13 @@ private: } else { // Unroll now, as have no other method to get right signal names AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump(); - for (int i = nodep->lsb(); i <= nodep->msb(); ++i) { + for (int i = nodep->lo(); i <= nodep->hi(); ++i) { VL_RESTORER(m_traShowname); VL_RESTORER(m_traValuep); { m_traShowname += string("(") + cvtToStr(i) + string(")"); m_traValuep = new AstArraySel( - nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lsb()); + nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lo()); m_traValuep->dtypep(subtypep); iterate(subtypep); @@ -263,14 +263,14 @@ private: addTraceDecl(VNumRange(), nodep->width()); } else { AstNodeDType* const subtypep = nodep->subDTypep()->skipRefToEnump(); - for (int i = nodep->lsb(); i <= nodep->msb(); ++i) { + for (int i = nodep->lo(); i <= nodep->hi(); ++i) { VL_RESTORER(m_traShowname); VL_RESTORER(m_traValuep); { m_traShowname += string("(") + cvtToStr(i) + string(")"); - m_traValuep = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), - (i - nodep->lsb()) * subtypep->width(), - subtypep->width()); + m_traValuep + = new AstSel(nodep->fileline(), m_traValuep->cloneTree(true), + (i - nodep->lo()) * subtypep->width(), subtypep->width()); m_traValuep->dtypep(subtypep); iterate(subtypep); VL_DO_CLEAR(m_traValuep->deleteTree(), m_traValuep = nullptr); diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 36077d610..50fbaae42 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -90,14 +90,14 @@ private: int lsb = bit + 1; if (bits != "") bits += ","; if (lsb == msb) { - bits += cvtToStr(lsb + bdtypep->lsb()); + bits += cvtToStr(lsb + bdtypep->lo()); } else { if (bdtypep->littleEndian()) { - bits += cvtToStr(lsb + bdtypep->lsb()) + ":" - + cvtToStr(msb + bdtypep->lsb()); + bits + += cvtToStr(lsb + bdtypep->lo()) + ":" + cvtToStr(msb + bdtypep->lo()); } else { - bits += cvtToStr(msb + bdtypep->lsb()) + ":" - + cvtToStr(lsb + bdtypep->lsb()); + bits + += cvtToStr(msb + bdtypep->lo()) + ":" + cvtToStr(lsb + bdtypep->lo()); } } prev = false; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index cfe7efb8d..0b4a685e7 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -752,21 +752,10 @@ private: // Signed: unsigned output, input either // Convert all range values to constants UINFO(6, "RANGE " << nodep << endl); - V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node - V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node - checkConstantOrReplace(nodep->msbp(), "MSB of bit range isn't a constant"); - checkConstantOrReplace(nodep->lsbp(), "LSB of bit range isn't a constant"); - int msb = nodep->msbConst(); - int lsb = nodep->lsbConst(); - if (msb < lsb) { - // Little endian bits are legal, just remember to swap - // Warning is in V3Width to avoid false warnings when in "off" generate if's - nodep->littleEndian(!nodep->littleEndian()); - // Internally we'll always have msb() be the greater number - // We only need to correct when doing [] AstSel extraction, - // and when tracing the vector. - nodep->msbp()->swapWith(nodep->lsbp()); - } + V3Const::constifyParamsEdit(nodep->leftp()); // May relink pointed to node + V3Const::constifyParamsEdit(nodep->rightp()); // May relink pointed to node + checkConstantOrReplace(nodep->leftp(), "left side of bit range isn't a constant"); + checkConstantOrReplace(nodep->rightp(), "right side of bit range isn't a constant"); if (m_vup->prelim()) { // Don't need to iterate because V3Const already constified int width = nodep->elementsConst(); @@ -807,7 +796,7 @@ private: int width = nodep->widthConst(); UASSERT_OBJ(nodep->dtypep(), nodep, "dtype wasn't set"); // by V3WidthSel if (VN_IS(nodep->lsbp(), Const) && nodep->msbConst() < nodep->lsbConst()) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: MSB < LSB of bit extract: " + nodep->v3warn(E_UNSUPPORTED, "Unsupported: left < right of bit extract: " << nodep->msbConst() << "<" << nodep->lsbConst()); width = (nodep->lsbConst() - nodep->msbConst() + 1); nodep->dtypeSetLogicSized(width, VSigning::UNSIGNED); @@ -903,8 +892,8 @@ private: int fromlsb; AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp(); if (const AstUnpackArrayDType* adtypep = VN_CAST(fromDtp, UnpackArrayDType)) { - frommsb = adtypep->msb(); - fromlsb = adtypep->lsb(); + frommsb = adtypep->hi(); + fromlsb = adtypep->lo(); if (fromlsb > frommsb) { int t = frommsb; frommsb = fromlsb; @@ -1929,7 +1918,7 @@ private: // "foo[0]" from a parameter but not a wire nodep->dtypeChgWidthSigned(width, nodep->valuep()->widthMin(), VSigning::fromBool(issigned)); - nodep->dtypep(nodep->findLogicRangeDType(VNumRange(0, 0, false), + nodep->dtypep(nodep->findLogicRangeDType(VNumRange{0, 0}, nodep->valuep()->widthMin(), VSigning::fromBool(issigned))); } else { diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 37f5959ff..3c3526e01 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -96,8 +96,8 @@ private: } else if (adtypep->isRanged()) { UASSERT_OBJ( !(adtypep->rangep() - && (!VN_IS(adtypep->rangep()->msbp(), Const) - || !VN_IS(adtypep->rangep()->lsbp(), Const))), + && (!VN_IS(adtypep->rangep()->leftp(), Const) + || !VN_IS(adtypep->rangep()->rightp(), Const))), nodep, "Non-constant variable range; errored earlier"); // in constifyParam(bfdtypep) fromRange = adtypep->declRange(); @@ -324,12 +324,12 @@ private: UINFO(6, "SELEXTRACT " << nodep << endl); // if (debug() >= 9) nodep->dumpTree(cout, "--SELEX0: "); // Below 2 lines may change nodep->widthp() - V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node - V3Const::constifyParamsEdit(nodep->msbp()); // May relink pointed to node + V3Const::constifyParamsEdit(nodep->leftp()); // May relink pointed to node + V3Const::constifyParamsEdit(nodep->rightp()); // May relink pointed to node // if (debug() >= 9) nodep->dumpTree(cout, "--SELEX3: "); - checkConstantOrReplace(nodep->lsbp(), + checkConstantOrReplace(nodep->leftp(), "First value of [a:b] isn't a constant, maybe you want +: or -:"); - checkConstantOrReplace(nodep->msbp(), + checkConstantOrReplace(nodep->rightp(), "Second value of [a:b] isn't a constant, maybe you want +: or -:"); AstNode* fromp = nodep->lhsp()->unlinkFrBack(); AstNode* msbp = nodep->rhsp()->unlinkFrBack(); @@ -351,9 +351,9 @@ private: nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // Slice - AstSliceSel* newp = new AstSliceSel( - nodep->fileline(), fromp, - VNumRange(VNumRange::LeftRight(), msb - fromRange.lo(), lsb - fromRange.lo())); + AstSliceSel* newp + = new AstSliceSel{nodep->fileline(), fromp, + VNumRange{msb - fromRange.lo(), lsb - fromRange.lo()}}; nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } diff --git a/test_regress/t/t_xml_tag.out b/test_regress/t/t_xml_tag.out index 7c50f6d85..191ce8023 100644 --- a/test_regress/t/t_xml_tag.out +++ b/test_regress/t/t_xml_tag.out @@ -72,8 +72,8 @@ - +