diff --git a/include/verilated_force.h b/include/verilated_force.h index 36f47979d..795d7d934 100644 --- a/include/verilated_force.h +++ b/include/verilated_force.h @@ -105,11 +105,11 @@ private: int m_msb; // Inclusive upper bit for scalar path or element index for unpacked int m_rhsLsb; // Destination index that maps to RHS index 0 const void* m_rhsDatap; // Pointer to RHS storage - int m_bitLsb = 0; + int m_bitLsb = 0; int m_bitMsb = 0; int m_elemWidth = 0; - bool operator<(const Entry& other) const { + bool operator<(const Entry& other) const { return m_msb != other.m_msb ? m_msb < other.m_msb : m_bitLsb < other.m_bitLsb; } }; @@ -141,9 +141,9 @@ private: std::size_t trimElementBitRange(int elem, int bitLsb, int bitMsb) { auto it = std::lower_bound(m_entries.begin(), m_entries.end(), elem, - [](const Entry& e, int idx) {return e.m_msb m_lsb <= elem) { - if(it->m_elemWidth == 0 || it->m_bitMsb < bitLsb || it ->m_bitLsb > bitMsb) { + [](const Entry& e, int idx) { return e.m_msb < idx; }); + while (it != m_entries.end() && it->m_lsb <= elem) { + if (it->m_elemWidth == 0 || it->m_bitMsb < bitLsb || it->m_bitLsb > bitMsb) { ++it; continue; } @@ -166,7 +166,7 @@ private: it = m_entries.erase(it); } auto ins = std::lower_bound(m_entries.begin(), m_entries.end(), elem, - [](const Entry& e, int idx) {return e.m_msb < idx; }); + [](const Entry& e, int idx) { return e.m_msb < idx; }); while (ins != m_entries.end() && ins->m_lsb <= elem && (ins->m_elemWidth == 0 || ins->m_bitLsb <= bitLsb)) { ++ins; @@ -238,15 +238,15 @@ private: template static typename std::enable_if::value, Elem>::type blendElem(Elem cur, const Entry& e) { - if(e.m_elemWidth == 0) return *static_cast(e.m_rhsDatap); + if (e.m_elemWidth == 0) return *static_cast(e.m_rhsDatap); const Entry bitEntry{e.m_bitLsb, e.m_bitMsb, e.m_rhsLsb, e.m_rhsDatap, 0, 0, 0}; return applyEntry(cur, bitEntry); } template - static typename std::enable_if::value, Elem>::type - blendElem(Elem cur, const Entry& e) { - if(e.m_elemWidth == 0) return *static_cast(e.m_rhsDatap); + static typename std::enable_if::value, Elem>::type blendElem(Elem cur, + const Entry& e) { + if (e.m_elemWidth == 0) return *static_cast(e.m_rhsDatap); Elem res = cur; const Entry bitEntry{e.m_bitLsb, e.m_bitMsb, e.m_rhsLsb, e.m_rhsDatap, 0, 0, 0}; applyEntry(res, bitEntry, e.m_bitLsb, e.m_bitMsb, 0); @@ -293,7 +293,7 @@ public: for (int idx = startIdx; idx <= endIdx; idx++) { const std::size_t uidx = static_cast(idx); Elem& dst = VlForceArrayIndexer::elem(result, uidx); - if(entry.m_elemWidth == 0){ + if (entry.m_elemWidth == 0) { const Elem* const rhsBasep = static_cast(entry.m_rhsDatap); const int rhsIndex = idx - entry.m_rhsLsb; dst = rhsBasep[rhsIndex]; @@ -366,7 +366,6 @@ public: const std::size_t at = trimElementBitRange(lsb, bitLsb, bitMsb); m_entries.insert(m_entries.begin() + at, Entry{lsb, msb, rhsLsb, rhsDatap, bitLsb, bitMsb, elemWidth}); - } void release(int lsb, int msb) { diff --git a/src/V3Force.cpp b/src/V3Force.cpp index dc65d7395..3a7b51ce9 100644 --- a/src/V3Force.cpp +++ b/src/V3Force.cpp @@ -1095,8 +1095,8 @@ class ForceConvertVisitor final : public VNVisitor { const AstSel* const selLhsp = VN_CAST(lhsp, Sel); const bool arrayBitSel = info.m_hasArraySel && selLhsp && ForceState::getArraySelInfo(lhsp).m_hasBitSel - && ForceState::isBitwiseDType(selLhsp->fromp()) - && (info.m_padMsb - info.m_padLsb + 1) < selLhsp->fromp()->width(); + && ForceState::isBitwiseDType(selLhsp->fromp()) + && (info.m_padMsb - info.m_padLsb + 1) < selLhsp->fromp()->width(); AstNodeExpr* const rhsDatap = ForceState::buildRhsDataExpr(flp, info); AstCExpr* const rhsAddrp = new AstCExpr{flp}; rhsAddrp->add("&("); @@ -1108,7 +1108,7 @@ class ForceConvertVisitor final : public VNVisitor { addForceCallp->addPinsp(ForceState::makeConst32(flp, info.m_rangeMsb)); addForceCallp->addPinsp(rhsAddrp); addForceCallp->addPinsp( - ForceState::makeConst32(flp, arrayBitSel ? info.m_padLsb : info.m_rangeLsb)); + ForceState::makeConst32(flp, arrayBitSel ? info.m_padLsb : info.m_rangeLsb)); if (arrayBitSel) { addForceCallp->addPinsp(ForceState::makeConst32(flp, info.m_padLsb)); addForceCallp->addPinsp(ForceState::makeConst32(flp, info.m_padMsb)); @@ -1153,12 +1153,11 @@ class ForceConvertVisitor final : public VNVisitor { const ForceState::ForceRangeInfo rangeInfo = m_state.getForceRangeInfo(lhsp, releasedVarp, false); - const AstSel* const selLhsp = VN_CAST(lhsp, Sel); const bool arrayBitSel = rangeInfo.m_hasArraySel && selLhsp && rangeInfo.m_arrayInfo.m_hasBitSel - && ForceState::isBitwiseDType(selLhsp->fromp()) - && (rangeInfo.m_padMsb - rangeInfo.m_padLsb + 1) < selLhsp->fromp()->width(); + && ForceState::isBitwiseDType(selLhsp->fromp()) + && (rangeInfo.m_padMsb - rangeInfo.m_padLsb + 1) < selLhsp->fromp()->width(); AstCMethodHard* const releaseCallp = new AstCMethodHard{ flp, new AstVarRef{flp, varInfo->m_forceVecVscp, VAccess::WRITE}, VCMethod::FORCE_RELEASE, ForceState::makeConst32(flp, rangeInfo.m_rangeLsb)}; diff --git a/test_regress/t/t_force_unpacked_bitsel.py b/test_regress/t/t_force_unpacked_bitsel.py old mode 100644 new mode 100755