From 3b623dc12e31c9c04657711289123e0c3f34f9cd Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 27 Sep 2025 08:22:17 -0400 Subject: [PATCH] Internals: Refactor to create VCMethod (#3715). No functional change intended. --- src/V3AssertPre.cpp | 7 +- src/V3Ast.cpp | 22 ++++ src/V3AstAttr.h | 241 +++++++++++++++++++++++++++++++++++++++++ src/V3AstNodeExpr.h | 14 +-- src/V3AstNodes.cpp | 93 +--------------- src/V3Begin.cpp | 10 +- src/V3Const.cpp | 4 +- src/V3Delayed.cpp | 7 +- src/V3DfgPasses.cpp | 2 +- src/V3Hasher.cpp | 2 +- src/V3Randomize.cpp | 60 +++++----- src/V3Sched.cpp | 31 +++--- src/V3SchedTiming.cpp | 6 +- src/V3SenExprBuilder.h | 12 +- src/V3Task.cpp | 7 +- src/V3Timing.cpp | 25 +++-- src/V3Width.cpp | 138 +++++++++++++---------- src/V3WidthCommit.cpp | 4 +- src/V3WidthSel.cpp | 25 +++-- src/Verilator.cpp | 1 + 20 files changed, 467 insertions(+), 244 deletions(-) diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index a61e63f8f..030d6a3a2 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -233,7 +233,8 @@ private: new AstSenItem{flp, VEdgeType::ET_CHANGED, skewedReadRefp->cloneTree(false)}); AstCMethodHard* const trigp = new AstCMethodHard{ nodep->fileline(), - new AstVarRef{flp, m_clockingp->ensureEventp(), VAccess::READ}, "isTriggered"}; + new AstVarRef{flp, m_clockingp->ensureEventp(), VAccess::READ}, + VCMethod::EVENT_IS_TRIGGERED}; trigp->dtypeSetBit(); ifp->condp(new AstLogAnd{flp, ifp->condp()->unlinkFrBack(), trigp}); m_clockingp->addNextHere(new AstAlwaysReactive{flp, senTreep, ifp}); @@ -285,7 +286,7 @@ private: // Create a process like this: // always queue.push(); AstCMethodHard* const pushp = new AstCMethodHard{ - flp, new AstVarRef{flp, queueVarp, VAccess::WRITE}, "push", + flp, new AstVarRef{flp, queueVarp, VAccess::WRITE}, VCMethod::DYN_PUSH, new AstTime{nodep->fileline(), m_modp->timeunit()}}; pushp->addPinsp(exprp->cloneTreePure(false)); pushp->dtypeSetVoid(); @@ -294,7 +295,7 @@ private: // Create a process like this: // always @ queue.pop(, /*out*/); AstCMethodHard* const popp = new AstCMethodHard{ - flp, new AstVarRef{flp, queueVarp, VAccess::READWRITE}, "pop", + flp, new AstVarRef{flp, queueVarp, VAccess::READWRITE}, VCMethod::DYN_POP, new AstTime{nodep->fileline(), m_modp->timeunit()}}; popp->addPinsp(skewp->unlinkFrBack()); popp->addPinsp(refp); diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index a50382885..deb546937 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -49,6 +49,28 @@ bool VNUser4InUse::s_userBusy = false; int AstNodeDType::s_uniqueNum = 0; +V3AST_VCMETHOD_ITEMDATA_DECL; + +//====================================================================== +// VCMethod information + +VCMethod VCMethod::arrayMethod(const string& name) { + for (auto& it : s_itemData) + if (it.m_name == name) return it.m_e; + v3fatalSrc("Not a method name known to VCMethod::s_itemData: '" << name << '\''); + return VCMethod{}; +} +void VCMethod::selfTest() { + int i = 0; + for (auto& it : s_itemData) { + VCMethod exp{i}; + UASSERT_STATIC(it.m_e == exp, + "VCMethod::s_itemData table rows are out-of-order, starting at row "s + + cvtToStr(i) + " '" + +it.m_name + '\''); + ++i; + } +} + //###################################################################### // VNType diff --git a/src/V3AstAttr.h b/src/V3AstAttr.h index 7b56848df..3aee37f08 100644 --- a/src/V3AstAttr.h +++ b/src/V3AstAttr.h @@ -703,6 +703,247 @@ inline std::ostream& operator<<(std::ostream& os, const VBranchPred& rhs) { // ###################################################################### +class VCMethod final { +public: + // Entries in this table need to match below VCMethod::s_itemData[] table + enum en : uint8_t { + _NONE, // Unknown + ARRAY_AND, + ARRAY_AT, + ARRAY_AT_BACK, + ARRAY_AT_WRITE, + ARRAY_FIND, + ARRAY_FIND_FIRST, + ARRAY_FIND_FIRST_INDEX, + ARRAY_FIND_INDEX, + ARRAY_FIND_LAST, + ARRAY_FIND_LAST_INDEX, + ARRAY_FIRST, + ARRAY_INSIDE, + ARRAY_LAST, + ARRAY_MAX, + ARRAY_MIN, + ARRAY_NEXT, + ARRAY_OR, + ARRAY_POP_BACK, + ARRAY_POP_FRONT, + ARRAY_PREV, + ARRAY_PRODUCT, + ARRAY_PUSH_BACK, + ARRAY_PUSH_FRONT, + ARRAY_REVERSE, + ARRAY_RSORT, + ARRAY_R_AND, + ARRAY_R_OR, + ARRAY_R_PRODUCT, + ARRAY_R_SUM, + ARRAY_R_XOR, + ARRAY_SHUFFLE, + ARRAY_SORT, + ARRAY_SUM, + ARRAY_UNIQUE, + ARRAY_UNIQUE_INDEX, + ARRAY_XOR, + ASSOC_CLEAR, + ASSOC_ERASE, + ASSOC_EXISTS, + ASSOC_FIRST, + ASSOC_NEXT, + ASSOC_SIZE, + CLASS_SET_RANDMODE, + DYN_AT_WRITE_APPEND, + DYN_AT_WRITE_APPEND_BACK, + DYN_CLEAR, + DYN_ERASE, + DYN_INSERT, + DYN_POP, + DYN_POP_FRONT, + DYN_PUSH, + DYN_PUSH_FRONT, + DYN_RENEW, + DYN_RENEW_COPY, + DYN_RESIZE, + DYN_SIZE, + DYN_SLICE, + DYN_SLICE_BACK_BACK, + DYN_SLICE_FRONT_BACK, + EVENT_CLEAR_FIRED, + EVENT_CLEAR_TRIGGERED, + EVENT_FIRE, + EVENT_IS_FIRED, + EVENT_IS_TRIGGERED, + FORK_DONE, + FORK_INIT, + FORK_JOIN, + RANDOMIZER_BASIC_STD_RANDOMIZATION, + RANDOMIZER_CLEAR, + RANDOMIZER_HARD, + RANDOMIZER_WRITE_VAR, + RNG_GET_RANDSTATE, + RNG_SET_RANDSTATE, + SCHED_ANY_TRIGGERED, + SCHED_AWAITING_CURRENT_TIME, + SCHED_COMMIT, + SCHED_DELAY, + SCHED_DO_POST_UPDATES, + SCHED_ENQUEUE, + SCHED_EVALUATE, + SCHED_EVALUATION, + SCHED_POST_UPDATE, + SCHED_RESUME, + SCHED_RESUMPTION, + SCHED_TRIGGER, + SCHED_TRIGGERED, + TRIGGER_AND_NOT, + TRIGGER_ANY, + TRIGGER_CLEAR, + TRIGGER_SET_BIT, + TRIGGER_SET_WORD, + TRIGGER_THIS_OR, + TRIGGER_WORD, + UNPACKED_ASSIGN, + UNPACKED_FILL, + UNPACKED_NEQ, + _ENUM_MAX // Leave last + }; + +private: + struct Item final { + enum en m_e; // Method's enum mnemonic, for checking + const char* m_name; // Method name, printed into C++ + bool m_pure; // Method being called is pure + }; + static Item s_itemData[]; + +public: + enum en m_e; + VCMethod() + : m_e{_NONE} {} + // cppcheck-suppress noExplicitConstructor + constexpr VCMethod(en _e) + : m_e{_e} {} + explicit VCMethod(int _e) + : m_e(static_cast(_e)) {} // Need () or GCC 4.8 false warning + constexpr operator en() const { return m_e; } + const char* ascii() const VL_PURE { return s_itemData[m_e].m_name; } + bool isPure() const VL_PURE { return s_itemData[m_e].m_pure; } + // Return array method for given name + static VCMethod arrayMethod(const string& name); + static void selfTest(); +}; +constexpr bool operator==(const VCMethod& lhs, const VCMethod& rhs) { return lhs.m_e == rhs.m_e; } +constexpr bool operator==(const VCMethod& lhs, VCMethod::en rhs) { return lhs.m_e == rhs; } +constexpr bool operator==(VCMethod::en lhs, const VCMethod& rhs) { return lhs == rhs.m_e; } +inline std::ostream& operator<<(std::ostream& os, const VCMethod& rhs) { + return os << rhs.ascii(); +} + +// Entries in this table need to match above VCMethod enum table +// +// {Mnemonic, C++ method, pure} +#define V3AST_VCMETHOD_ITEMDATA_DECL \ + VCMethod::Item VCMethod::s_itemData[] \ + = {{_NONE, "_none", false}, \ + {ARRAY_AND, "and", true}, \ + {ARRAY_AT, "at", true}, \ + {ARRAY_AT_BACK, "atBack", true}, \ + {ARRAY_AT_WRITE, "atWrite", true}, \ + {ARRAY_FIND, "find", true}, \ + {ARRAY_FIND_FIRST, "find_first", true}, \ + {ARRAY_FIND_FIRST_INDEX, "find_first_index", true}, \ + {ARRAY_FIND_INDEX, "find_index", true}, \ + {ARRAY_FIND_LAST, "find_last", true}, \ + {ARRAY_FIND_LAST_INDEX, "find_last_index", true}, \ + {ARRAY_FIRST, "first", false}, \ + {ARRAY_INSIDE, "inside", true}, \ + {ARRAY_LAST, "last", false}, \ + {ARRAY_MAX, "max", true}, \ + {ARRAY_MIN, "min", true}, \ + {ARRAY_NEXT, "next", false}, \ + {ARRAY_OR, "or", true}, \ + {ARRAY_POP_BACK, "pop_back", false}, \ + {ARRAY_POP_FRONT, "pop_front", false}, \ + {ARRAY_PREV, "prev", false}, \ + {ARRAY_PRODUCT, "product", true}, \ + {ARRAY_PUSH_BACK, "push_back", false}, \ + {ARRAY_PUSH_FRONT, "push_front", false}, \ + {ARRAY_REVERSE, "reverse", false}, \ + {ARRAY_RSORT, "rsort", false}, \ + {ARRAY_R_AND, "r_and", true}, \ + {ARRAY_R_OR, "r_or", true}, \ + {ARRAY_R_PRODUCT, "r_product", true}, \ + {ARRAY_R_SUM, "r_sum", true}, \ + {ARRAY_R_XOR, "r_xor", true}, \ + {ARRAY_SHUFFLE, "shuffle", false}, \ + {ARRAY_SORT, "sort", false}, \ + {ARRAY_SUM, "sum", true}, \ + {ARRAY_UNIQUE, "unique", true}, \ + {ARRAY_UNIQUE_INDEX, "unique_index", true}, \ + {ARRAY_XOR, "xor", true}, \ + {ASSOC_CLEAR, "clear", false}, \ + {ASSOC_ERASE, "erase", false}, \ + {ASSOC_EXISTS, "exists", true}, \ + {ASSOC_FIRST, "first", false}, \ + {ASSOC_NEXT, "next", false}, \ + {ASSOC_SIZE, "size", true}, \ + {CLASS_SET_RANDMODE, "set_randmode", false}, \ + {DYN_AT_WRITE_APPEND, "atWriteAppend", false}, \ + {DYN_AT_WRITE_APPEND_BACK, "atWriteAppendBack", false}, \ + {DYN_CLEAR, "clear", false}, \ + {DYN_ERASE, "erase", false}, \ + {DYN_INSERT, "insert", false}, \ + {DYN_POP, "pop", false}, \ + {DYN_POP_FRONT, "pop_front", false}, \ + {DYN_PUSH, "push", false}, \ + {DYN_PUSH_FRONT, "push_front", false}, \ + {DYN_RENEW, "renew", false}, \ + {DYN_RENEW_COPY, "renew_copy", false}, \ + {DYN_RESIZE, "resize", false}, \ + {DYN_SIZE, "size", true}, \ + {DYN_SLICE, "slice", true}, \ + {DYN_SLICE_BACK_BACK, "sliceBackBack", true}, \ + {DYN_SLICE_FRONT_BACK, "sliceFrontBack", true}, \ + {EVENT_CLEAR_FIRED, "clearFired", false}, \ + {EVENT_CLEAR_TRIGGERED, "clearTriggered", false}, \ + {EVENT_FIRE, "fire", false}, \ + {EVENT_IS_FIRED, "isFired", true}, \ + {EVENT_IS_TRIGGERED, "isTriggered", true}, \ + {FORK_DONE, "done", false}, \ + {FORK_INIT, "init", false}, \ + {FORK_JOIN, "join", false}, \ + {RANDOMIZER_BASIC_STD_RANDOMIZATION, "basicStdRandomization", false}, \ + {RANDOMIZER_CLEAR, "clear", false}, \ + {RANDOMIZER_HARD, "hard", false}, \ + {RANDOMIZER_WRITE_VAR, "write_var", false}, \ + {RNG_GET_RANDSTATE, "__Vm_rng.get_randstate", true}, \ + {RNG_SET_RANDSTATE, "__Vm_rng.set_randstate", false}, \ + {SCHED_ANY_TRIGGERED, "anyTriggered", false}, \ + {SCHED_AWAITING_CURRENT_TIME, "awaitingCurrentTime", true}, \ + {SCHED_COMMIT, "commit", false}, \ + {SCHED_DELAY, "delay", false}, \ + {SCHED_DO_POST_UPDATES, "doPostUpdates", false}, \ + {SCHED_ENQUEUE, "enqueue", false}, \ + {SCHED_EVALUATE, "evaluate", false}, \ + {SCHED_EVALUATION, "evaluation", false}, \ + {SCHED_POST_UPDATE, "postUpdate", false}, \ + {SCHED_RESUME, "resume", false}, \ + {SCHED_RESUMPTION, "resumption", false}, \ + {SCHED_TRIGGER, "trigger", false}, \ + {SCHED_TRIGGERED, "triggered", false}, \ + {TRIGGER_AND_NOT, "andNot", false}, \ + {TRIGGER_ANY, "any", true}, \ + {TRIGGER_CLEAR, "clear", false}, \ + {TRIGGER_SET_BIT, "setBit", false}, \ + {TRIGGER_SET_WORD, "setWord", false}, \ + {TRIGGER_THIS_OR, "thisOr", false}, \ + {TRIGGER_WORD, "word", true}, \ + {UNPACKED_ASSIGN, "assign", false}, \ + {UNPACKED_FILL, "fill", false}, \ + {UNPACKED_NEQ, "neq", true}, \ + {_ENUM_MAX, "_ENUM_MAX", false}}; + +// ###################################################################### + class VCaseType final { public: enum en : uint8_t { CT_CASE, CT_CASEX, CT_CASEZ, CT_CASEINSIDE }; diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 111e6e9f6..85db37c01 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -618,24 +618,22 @@ class AstCMethodHard final : public AstNodeExpr { // PARENTS: stmt/expr // @astgen op1 := fromp : AstNodeExpr // Subject of method call // @astgen op2 := pinsp : List[AstNodeExpr] // Arguments - string m_name; // Name of method + VCMethod m_method; // Which method to call bool m_pure = false; // Pure optimizable bool m_usePtr = false; // Use '->' not '.' public: - AstCMethodHard(FileLine* fl, AstNodeExpr* fromp, const string& name, - AstNodeExpr* pinsp = nullptr) + AstCMethodHard(FileLine* fl, AstNodeExpr* fromp, VCMethod method, AstNodeExpr* pinsp = nullptr) : ASTGEN_SUPER_CMethodHard(fl) - , m_name{name} { + , m_method{method} { this->fromp(fromp); addPinsp(pinsp); setPurity(); } ASTGEN_MEMBERS_AstCMethodHard; - string name() const override VL_MT_STABLE { return m_name; } // * = Var name - void name(const string& name) override { m_name = name; } + string name() const override VL_MT_STABLE { return method().ascii(); } bool sameNode(const AstNode* samep) const override { const AstCMethodHard* const asamep = VN_DBG_AS(samep, CMethodHard); - return (m_name == asamep->m_name); + return (m_method == asamep->m_method); } bool isPure() override { return m_pure; } int instrCount() const override; @@ -644,6 +642,8 @@ public: bool cleanOut() const override { return true; } bool usePtr() const { return m_usePtr; } void usePtr(bool flag) { m_usePtr = flag; } + VCMethod method() const VL_MT_STABLE { return m_method; } + void method(VCMethod value) { m_method = value; } private: void setPurity(); diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 15ea7eee0..f23a769c4 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -91,12 +91,10 @@ bool AstNodeFTaskRef::getPurityRecurse() const { AstNodeFTask* const taskp = this->taskp(); // Unlinked yet, so treat as impure if (!taskp) return false; - // First compute the purity of arguments for (AstNode* pinp = this->pinsp(); pinp; pinp = pinp->nextp()) { if (!pinp->isPure()) return false; } - return taskp->isPure(); } bool AstNodeFTaskRef::isGateOptimizable() const { return m_taskp && m_taskp->isGateOptimizable(); } @@ -3144,94 +3142,17 @@ void AstCAwait::dump(std::ostream& str) const { void AstCAwait::dumpJson(std::ostream& str) const { dumpJsonGen(str); } int AstCMethodHard::instrCount() const { if (const AstBasicDType* const basicp = fromp()->dtypep()->basicp()) { - // TODO: add a more structured description of library methods, rather than using string - // matching. See issue #3715. - if (basicp->isTriggerVec() && m_name == "word") { + if (basicp->isTriggerVec() && m_method == VCMethod::TRIGGER_WORD) { // This is an important special case for scheduling so we compute it precisely, // it is simply a load. return INSTR_COUNT_LD; } } - return 0; + return 0; // TODO } void AstCMethodHard::setPurity() { - static const std::map isPureMethod{{"__Vm_rng.get_randstate", true}, - {"__Vm_rng.set_randstate", false}, - {"andNot", false}, - {"any", true}, - {"anyTriggered", false}, - {"assign", false}, - {"at", true}, - {"atBack", true}, - {"atWrite", true}, - {"awaitingCurrentTime", true}, - {"basicStdRandomization", false}, - {"clear", false}, - {"clearFired", false}, - {"commit", false}, - {"delay", false}, - {"done", false}, - {"enqueue", false}, - {"erase", false}, - {"evaluate", false}, - {"evaluation", false}, - {"exists", true}, - {"fill", false}, - {"find", true}, - {"find_first", true}, - {"find_first_index", true}, - {"find_index", true}, - {"find_last", true}, - {"find_last_index", true}, - {"fire", false}, - {"first", false}, - {"hard", false}, - {"init", false}, - {"insert", false}, - {"inside", true}, - {"isFired", true}, - {"isTriggered", true}, - {"join", false}, - {"last", false}, - {"max", true}, - {"min", true}, - {"neq", true}, - {"next", false}, - {"pop", false}, - {"pop_back", false}, - {"pop_front", false}, - {"prev", false}, - {"push", false}, - {"push_back", false}, - {"push_front", false}, - {"r_and", true}, - {"r_or", true}, - {"r_product", true}, - {"r_sum", true}, - {"r_xor", true}, - {"renew", false}, - {"renew_copy", false}, - {"resize", false}, - {"resume", false}, - {"reverse", false}, - {"rsort", false}, - {"setBit", false}, - {"setWord", false}, - {"set_randmode", false}, - {"shuffle", false}, - {"size", true}, - {"slice", true}, - {"sliceBackBack", true}, - {"sliceFrontBack", true}, - {"sort", false}, - {"thisOr", false}, - {"trigger", false}, - {"unique", true}, - {"unique_index", true}, - {"word", true}, - {"write_var", false}}; - - if (name() == "atWriteAppend" || name() == "atWriteAppendBack") { + if (method() == VCMethod::DYN_AT_WRITE_APPEND + || method() == VCMethod::DYN_AT_WRITE_APPEND_BACK) { m_pure = false; // Treat atWriteAppend as pure if the argument is a loop iterator if (const AstNodeExpr* const argp = pinsp()) { @@ -3241,11 +3162,7 @@ void AstCMethodHard::setPurity() { } return; } - auto isPureIt = isPureMethod.find(name()); - // cppcheck-suppress derefInvalidIteratorRedundantCheck - UASSERT_OBJ(isPureIt != isPureMethod.end(), this, "Unknown purity of method " + name()); - // cppcheck-suppress derefInvalidIteratorRedundantCheck - m_pure = isPureIt->second; + m_pure = method().isPure(); if (!m_pure) return; if (!fromp()->isPure()) m_pure = false; if (!m_pure) return; diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index e6db8ec4b..8d445dd44 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -485,9 +485,9 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { ? new AstArraySel{fl, subfromp->cloneTreePure(false), new AstVarRef{fl, nestedIndexp, VAccess::READ}} : subfromp->cloneTreePure(false), - "size"}; + VCMethod::DYN_SIZE}; AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ}; - subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp}; + subfromp = new AstCMethodHard{fl, subfromp, VCMethod::ARRAY_AT, varRefp}; subfromp->dtypep(fromDtp); rightp->dtypeSetSigned32(); rightp->protect(false); @@ -503,15 +503,15 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { first_varp->usedLoopIdx(true); first_varp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); AstNodeExpr* const firstp - = new AstCMethodHard{fl, subfromp->cloneTreePure(false), "first", + = new AstCMethodHard{fl, subfromp->cloneTreePure(false), VCMethod::ASSOC_FIRST, new AstVarRef{fl, varp, VAccess::READWRITE}}; firstp->dtypeSetSigned32(); AstNodeExpr* const nextp - = new AstCMethodHard{fl, subfromp->cloneTreePure(false), "next", + = new AstCMethodHard{fl, subfromp->cloneTreePure(false), VCMethod::ASSOC_NEXT, new AstVarRef{fl, varp, VAccess::READWRITE}}; nextp->dtypeSetSigned32(); AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ}; - subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp}; + subfromp = new AstCMethodHard{fl, subfromp, VCMethod::ARRAY_AT, varRefp}; subfromp->dtypep(fromDtp); AstNode* const first_clearp = new AstAssign{fl, new AstVarRef{fl, first_varp, VAccess::WRITE}, diff --git a/src/V3Const.cpp b/src/V3Const.cpp index d6e2e9faf..fa199d4aa 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -3012,8 +3012,8 @@ class ConstVisitor final : public VNVisitor { if (const AstCMethodHard* const aCallp = VN_CAST(ap, CMethodHard)) { const AstCMethodHard* const bCallp = VN_AS(bp, CMethodHard); - if (aCallp->name() < bCallp->name()) return -1; - if (aCallp->name() > bCallp->name()) return 1; + if (aCallp->method() < bCallp->method()) return -1; + if (aCallp->method() > bCallp->method()) return 1; if (const int c = cmp(aCallp->fromp(), bCallp->fromp())) return c; const AstNodeExpr* aPinsp = aCallp->pinsp(); const AstNodeExpr* bPinsp = bCallp->pinsp(); diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 870120a1f..3b46cf250 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -859,8 +859,8 @@ class DelayedVisitor final : public VNVisitor { AstAlwaysPost* const postp = new AstAlwaysPost{flp}; activep->addStmtsp(postp); // Add the commit - AstCMethodHard* const callp - = new AstCMethodHard{flp, new AstVarRef{flp, queueVscp, VAccess::READWRITE}, "commit"}; + AstCMethodHard* const callp = new AstCMethodHard{ + flp, new AstVarRef{flp, queueVscp, VAccess::READWRITE}, VCMethod::SCHED_COMMIT}; callp->dtypeSetVoid(); callp->addPinsp(new AstVarRef{flp, vscp, VAccess::WRITE}); postp->addStmtsp(callp->makeStmt()); @@ -969,7 +969,8 @@ class DelayedVisitor final : public VNVisitor { // Enqueue the update at the site of the original NBA AstCMethodHard* const callp = new AstCMethodHard{ - flp, new AstVarRef{flp, vscpInfo.valueQueueKit().vscp, VAccess::READWRITE}, "enqueue"}; + flp, new AstVarRef{flp, vscpInfo.valueQueueKit().vscp, VAccess::READWRITE}, + VCMethod::SCHED_ENQUEUE}; callp->dtypeSetVoid(); callp->addPinsp(valuep); if (partial) callp->addPinsp(maskp); diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index f544ef1ba..cbf87a0f0 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -280,7 +280,7 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) { } { // tab.fill(0) AstCMethodHard* const callp = new AstCMethodHard{ - flp, new AstVarRef{flp, tabVtxp->varp(), VAccess::WRITE}, "fill"}; + flp, new AstVarRef{flp, tabVtxp->varp(), VAccess::WRITE}, VCMethod::UNPACKED_FILL}; callp->addPinsp(new AstConst{flp, AstConst::BitFalse{}}); callp->dtypeSetVoid(); initp->addStmtsp(callp->makeStmt()); diff --git a/src/V3Hasher.cpp b/src/V3Hasher.cpp index a8e835d3c..8a60ef83b 100644 --- a/src/V3Hasher.cpp +++ b/src/V3Hasher.cpp @@ -293,7 +293,7 @@ class HasherVisitor final : public VNVisitorConst { } void visit(AstCMethodHard* nodep) override { m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [this, nodep]() { // - m_hash += nodep->name(); + m_hash += nodep->method(); }); } void visit(AstCAwait* nodep) override { diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index f05a2f34e..0b7d9767e 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -233,7 +233,8 @@ class RandomizeMarkVisitor final : public VNVisitor { nodep->v3error("Cannot call 'rand_mode()' on packed array element"); valid = false; } else if (AstCMethodHard* const methodHardp = VN_CAST(fromp, CMethodHard)) { - if (methodHardp->name() == "at" || methodHardp->name() == "atWrite") { + if (methodHardp->method() == VCMethod::ARRAY_AT + || methodHardp->method() == VCMethod::ARRAY_AT_WRITE) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'rand_mode()' on dynamic array element"); valid = false; @@ -622,7 +623,7 @@ class ConstraintExprVisitor final : public VNVisitor { AstNodeDType* const arrDtp = arrayp->unlinkFrBack()->dtypep(); AstNodeExpr* selp = nullptr; if (VN_IS(arrDtp, QueueDType) || VN_IS(arrDtp, DynArrayDType)) - selp = new AstCMethodHard{fl, arrayp, "at", idxp}; + selp = new AstCMethodHard{fl, arrayp, VCMethod::ARRAY_AT, idxp}; else if (VN_IS(arrDtp, UnpackArrayDType)) selp = new AstArraySel{fl, arrayp, idxp}; else if (VN_IS(arrDtp, AssocArrayDType)) @@ -662,7 +663,7 @@ class ConstraintExprVisitor final : public VNVisitor { nodep->fileline(), new AstVarRef{varp->fileline(), VN_AS(m_randModeVarp->user2p(), NodeModule), m_randModeVarp, VAccess::READ}, - "at", new AstConst{nodep->fileline(), randMode.index}}; + VCMethod::ARRAY_AT, new AstConst{nodep->fileline(), randMode.index}}; atp->dtypeSetUInt32(); exprp = new AstCond{varp->fileline(), atp, exprp, constFormatp}; } else { @@ -675,7 +676,7 @@ class ConstraintExprVisitor final : public VNVisitor { varp->fileline(), new AstVarRef{varp->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp, VAccess::READWRITE}, - "write_var"}; + VCMethod::RANDOMIZER_WRITE_VAR}; uint32_t dimension = 0; if (VN_IS(varp->dtypep(), UnpackArrayDType) || VN_IS(varp->dtypep(), DynArrayDType) || VN_IS(varp->dtypep(), QueueDType) || VN_IS(varp->dtypep(), AssocArrayDType)) { @@ -991,7 +992,7 @@ class ConstraintExprVisitor final : public VNVisitor { nodep->fileline(), new AstVarRef{nodep->fileline(), VN_AS(m_genp->user2p(), NodeModule), m_genp, VAccess::READWRITE}, - "hard", nodep->exprp()->unlinkFrBack()}; + VCMethod::RANDOMIZER_HARD, nodep->exprp()->unlinkFrBack()}; callp->dtypeSetVoid(); nodep->replaceWith(callp->makeStmt()); VL_DO_DANGLING(nodep->deleteTree(), nodep); @@ -1000,7 +1001,7 @@ class ConstraintExprVisitor final : public VNVisitor { if (editFormat(nodep)) return; FileLine* const fl = nodep->fileline(); - if (nodep->name() == "at" && nodep->fromp()->user1()) { + if (nodep->method() == VCMethod::ARRAY_AT && nodep->fromp()->user1()) { iterateChildren(nodep); AstNodeExpr* pinp = nodep->pinsp()->unlinkFrBack(); if (VN_IS(pinp, SFormatF) && m_structSel) VN_AS(pinp, SFormatF)->name("%x"); @@ -1015,7 +1016,7 @@ class ConstraintExprVisitor final : public VNVisitor { return; } - if (nodep->name() == "inside") { + if (nodep->method() == VCMethod::ARRAY_INSIDE) { bool randArr = nodep->fromp()->user1(); AstVar* const newVarp @@ -1455,7 +1456,7 @@ class RandomizeVisitor final : public VNVisitor { FileLine* const fl = ftaskp->fileline(); AstCMethodHard* const setRandModep = new AstCMethodHard{ fl, new AstVarRef{fl, VN_AS(genp->user2p(), NodeModule), genp, VAccess::WRITE}, - "set_randmode", + VCMethod::CLASS_SET_RANDMODE, new AstVarRef{fl, VN_AS(randModeVarp->user2p(), NodeModule), randModeVarp, VAccess::READ}}; setRandModep->dtypeSetVoid(); @@ -1506,7 +1507,7 @@ class RandomizeVisitor final : public VNVisitor { FileLine* fl = modeVarp->fileline(); AstCMethodHard* const dynarrayNewp = new AstCMethodHard{fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE}, - "resize", new AstConst{fl, modeCount}}; + VCMethod::DYN_RESIZE, new AstConst{fl, modeCount}}; dynarrayNewp->dtypeSetVoid(); AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask); UASSERT_OBJ(newp, classp, "No new() in class"); @@ -1520,10 +1521,11 @@ class RandomizeVisitor final : public VNVisitor { AstVar* const iterVarp = new AstVar{fl, VVarType::BLOCKTEMP, "i", lhsp->findUInt32DType()}; iterVarp->funcLocal(inTask); iterVarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); - AstCMethodHard* const sizep = new AstCMethodHard{fl, lhsp, "size", nullptr}; + AstCMethodHard* const sizep = new AstCMethodHard{fl, lhsp, VCMethod::DYN_SIZE, nullptr}; sizep->dtypeSetUInt32(); - AstCMethodHard* const setp = new AstCMethodHard{ - fl, lhsp->cloneTree(false), "atWrite", new AstVarRef{fl, iterVarp, VAccess::READ}}; + AstCMethodHard* const setp + = new AstCMethodHard{fl, lhsp->cloneTree(false), VCMethod::ARRAY_AT_WRITE, + new AstVarRef{fl, iterVarp, VAccess::READ}}; setp->dtypeSetUInt32(); AstNode* const stmtsp = iterVarp; stmtsp->addNext( @@ -1550,7 +1552,7 @@ class RandomizeVisitor final : public VNVisitor { if (mode.usesMode) { AstCMethodHard* const atp = new AstCMethodHard{ fl, new AstVarRef{fl, VN_AS(modeVarp->user2p(), Class), modeVarp, VAccess::READ}, - "at", new AstConst{fl, mode.index}}; + VCMethod::ARRAY_AT, new AstConst{fl, mode.index}}; atp->dtypeSetUInt32(); return new AstIf{fl, atp, stmtp}; } @@ -1651,7 +1653,8 @@ class RandomizeVisitor final : public VNVisitor { AstNodeExpr* const tempExprp = tempElementp ? tempElementp : exprp; AstVarRef* const tempRefp = new AstVarRef{fl, newRandLoopIndxp, VAccess::READ}; if (VN_IS(tempDTypep, DynArrayDType)) { - tempElementp = new AstCMethodHard{fl, tempExprp, "atWrite", tempRefp}; + tempElementp + = new AstCMethodHard{fl, tempExprp, VCMethod::ARRAY_AT_WRITE, tempRefp}; } else if (VN_IS(tempDTypep, UnpackArrayDType)) { AstNodeArrayDType* const aryDTypep = VN_CAST(tempDTypep, NodeArrayDType); // Adjust the bitp to ensure it covers all possible indices @@ -1665,7 +1668,8 @@ class RandomizeVisitor final : public VNVisitor { } else if (VN_IS(tempDTypep, AssocArrayDType)) { tempElementp = new AstAssocSel{fl, tempExprp, tempRefp}; } else if (VN_IS(tempDTypep, QueueDType)) { - tempElementp = new AstCMethodHard{fl, tempExprp, "atWriteAppend", tempRefp}; + tempElementp + = new AstCMethodHard{fl, tempExprp, VCMethod::DYN_AT_WRITE_APPEND, tempRefp}; } tempElementp->dtypep(tempDTypep->subDTypep()); tempDTypep = tempDTypep->virtRefDTypep(); @@ -1797,7 +1801,7 @@ class RandomizeVisitor final : public VNVisitor { AstCMethodHard* const clearp = new AstCMethodHard{ fileline, new AstVarRef{fileline, VN_AS(genp->user2p(), NodeModule), genp, VAccess::READWRITE}, - "clear"}; + VCMethod::RANDOMIZER_CLEAR}; clearp->dtypeSetVoid(); return clearp->makeStmt(); } @@ -1909,7 +1913,7 @@ class RandomizeVisitor final : public VNVisitor { nodep->fileline(), new AstVarRef{fl, VN_AS(randModeVarp->user2p(), NodeModule), randModeVarp, VAccess::WRITE}, - "atWrite", new AstConst{nodep->fileline(), randMode.index}}; + VCMethod::ARRAY_AT_WRITE, new AstConst{nodep->fileline(), randMode.index}}; setp->dtypeSetUInt32(); newp->addStmtsp(new AstAssign{fl, setp, new AstConst{fl, 0}}); } @@ -1973,8 +1977,8 @@ class RandomizeVisitor final : public VNVisitor { // mode const RandomizeMode rmode = {.asInt = receiverp->user1()}; UASSERT_OBJ(rmode.usesMode, ftaskRefp, "Failed to set usesMode"); - AstCMethodHard* const setp - = new AstCMethodHard{fl, lhsp, "atWrite", new AstConst{fl, rmode.index}}; + AstCMethodHard* const setp = new AstCMethodHard{fl, lhsp, VCMethod::ARRAY_AT_WRITE, + new AstConst{fl, rmode.index}}; setp->dtypeSetUInt32(); m_stmtp->replaceWith(new AstAssign{fl, setp, rhsp}); } else { @@ -1988,8 +1992,8 @@ class RandomizeVisitor final : public VNVisitor { UASSERT_OBJ(receiverp, ftaskRefp, "Should have receiver"); const RandomizeMode rmode = {.asInt = receiverp->user1()}; UASSERT_OBJ(rmode.usesMode, ftaskRefp, "Failed to set usesMode"); - AstCMethodHard* const setp - = new AstCMethodHard{fl, lhsp, "atWrite", new AstConst{fl, rmode.index}}; + AstCMethodHard* const setp = new AstCMethodHard{fl, lhsp, VCMethod::ARRAY_AT_WRITE, + new AstConst{fl, rmode.index}}; setp->dtypeSetUInt32(); ftaskRefp->replaceWith(setp); VL_DO_DANGLING(pushDeletep(ftaskRefp), ftaskRefp); @@ -2057,9 +2061,9 @@ class RandomizeVisitor final : public VNVisitor { tmpVarps = AstNode::addNext(tmpVarps, randModeTmpVarp); } const RandomizeMode randMode = {.asInt = randVarp->user1()}; - AstCMethodHard* setp - = new AstCMethodHard{fl, makeSiblingRefp(exprp, randModeVarp, VAccess::WRITE), - "atWrite", new AstConst{fl, randMode.index}}; + AstCMethodHard* setp = new AstCMethodHard{ + fl, makeSiblingRefp(exprp, randModeVarp, VAccess::WRITE), + VCMethod::ARRAY_AT_WRITE, new AstConst{fl, randMode.index}}; setp->dtypeSetUInt32(); setStmtsp = AstNode::addNext(setStmtsp, new AstAssign{fl, setp, new AstConst{fl, 1}}); @@ -2306,7 +2310,7 @@ class RandomizeVisitor final : public VNVisitor { AstCMethodHard* const basicMethodp = new AstCMethodHard{ nodep->fileline(), new AstVarRef{nodep->fileline(), stdrand, VAccess::READWRITE}, - "basicStdRandomization"}; + VCMethod::RANDOMIZER_BASIC_STD_RANDOMIZATION}; AstVar* const refvarp = new AstVar{exprp->fileline(), VVarType::MEMBER, "__Varg"s + std::to_string(++argn), exprp->dtypep()}; @@ -2456,7 +2460,9 @@ class RandomizeVisitor final : public VNVisitor { void visit(AstCMethodHard* nodep) override { iterateChildren(nodep); FileLine* const fl = nodep->fileline(); - if (m_constraintp && nodep->fromp()->user1() && nodep->name() == "size") { + if (m_constraintp && nodep->fromp()->user1() + && (nodep->method() == VCMethod::ASSOC_SIZE + || nodep->method() == VCMethod::DYN_SIZE)) { AstClass* const classp = VN_AS(m_modp, Class); AstVarRef* const queueVarRefp = VN_CAST(nodep->fromp(), VarRef); if (!queueVarRefp) { @@ -2480,7 +2486,7 @@ class RandomizeVisitor final : public VNVisitor { m_constraintp->user3p(resizerTaskp); } AstCMethodHard* const resizep - = new AstCMethodHard{fl, nodep->fromp()->unlinkFrBack(), "resize", + = new AstCMethodHard{fl, nodep->fromp()->unlinkFrBack(), VCMethod::DYN_RESIZE, new AstVarRef{fl, sizeVarp, VAccess::READ}}; resizep->dtypep(nodep->findVoidDType()); resizerTaskp->addStmtsp(new AstStmtExpr{fl, resizep}); diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index 2c177d7a6..a7b96f7d7 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -221,8 +221,8 @@ EvalLoop createEvalLoop( phaseFuncp->addStmtsp(phasePrepp); // Check if any triggers are fired, save the result - AstCMethodHard* const callp - = new AstCMethodHard{flp, new AstVarRef{flp, trigp, VAccess::READ}, "any"}; + AstCMethodHard* const callp = new AstCMethodHard{ + flp, new AstVarRef{flp, trigp, VAccess::READ}, VCMethod::TRIGGER_ANY}; callp->dtypeSetBit(); phaseFuncp->addStmtsp( new AstAssign{flp, new AstVarRef{flp, executeFlagp, VAccess::WRITE}, callp}); @@ -523,7 +523,7 @@ struct TriggerKit final { void addFirstIterationTriggerAssignment(AstVarScope* flagp, uint32_t index) const { FileLine* const flp = flagp->fileline(); AstVarRef* const vrefp = new AstVarRef{flp, m_vscp, VAccess::WRITE}; - AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setBit"}; + AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_BIT}; callp->addPinsp(new AstConst{flp, index}); callp->addPinsp(new AstVarRef{flp, flagp, VAccess::READ}); callp->dtypeSetVoid(); @@ -534,7 +534,7 @@ struct TriggerKit final { void addExtraTriggerAssignment(AstVarScope* extraTriggerVscp, uint32_t index) const { FileLine* const flp = extraTriggerVscp->fileline(); AstVarRef* const vrefp = new AstVarRef{flp, m_vscp, VAccess::WRITE}; - AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setBit"}; + AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_BIT}; callp->addPinsp(new AstConst{flp, index}); callp->addPinsp(new AstVarRef{flp, extraTriggerVscp, VAccess::READ}); callp->dtypeSetVoid(); @@ -570,7 +570,7 @@ AstSenTree* createTriggerSenTree(AstNetlist* netlistp, AstVarScope* const vscp, const uint32_t wordIndex = index / 64; const uint32_t bitIndex = index % 64; AstCMethodHard* const callp - = new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}}; + = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_WORD, new AstConst{flp, wordIndex}}; callp->dtypeSetUInt64(); AstNodeExpr* const termp = new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp}; @@ -663,8 +663,8 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp, // Add a print to the dumping function if there are no triggers pending { - AstCMethodHard* const callp - = new AstCMethodHard{flp, new AstVarRef{flp, vscp, VAccess::READ}, "any"}; + AstCMethodHard* const callp = new AstCMethodHard{ + flp, new AstVarRef{flp, vscp, VAccess::READ}, VCMethod::TRIGGER_ANY}; callp->dtypeSetBit(); AstIf* const ifp = new AstIf{flp, callp}; dumpp->addStmtsp(ifp); @@ -674,7 +674,7 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp, // Set the given trigger to the given value const auto setTrigBit = [&](uint32_t index, AstNodeExpr* valp) { AstVarRef* const vrefp = new AstVarRef{flp, vscp, VAccess::WRITE}; - AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setBit"}; + AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_BIT}; callp->addPinsp(new AstConst{flp, index}); callp->addPinsp(valp); callp->dtypeSetVoid(); @@ -687,7 +687,7 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp, const uint32_t wordIndex = index / 64; const uint32_t bitIndex = index % 64; AstCMethodHard* const callp - = new AstCMethodHard{flp, vrefp, "word", new AstConst{flp, wordIndex}}; + = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_WORD, new AstConst{flp, wordIndex}}; callp->dtypeSetUInt64(); AstNodeExpr* const termp = new AstAnd{flp, new AstConst{flp, AstConst::Unsized64{}, 1ULL << bitIndex}, callp}; @@ -776,7 +776,8 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp, } // Set the whole word in the trigger vector AstVarRef* const vrefp = new AstVarRef{flp, vscp, VAccess::WRITE}; - AstCMethodHard* const callp = new AstCMethodHard{flp, vrefp, "setWord"}; + AstCMethodHard* const callp + = new AstCMethodHard{flp, vrefp, VCMethod::TRIGGER_SET_WORD}; callp->addPinsp(new AstConst{flp, triggerBitIdx / TRIG_VEC_WORD_SIZE}); callp->addPinsp(trigExprps[0]); callp->dtypeSetVoid(); @@ -1015,7 +1016,7 @@ AstNode* createInputCombLoop(AstNetlist* netlistp, AstCFunc* const initFuncp, AstStmtExpr* createTriggerClearCall(FileLine* const flp, AstVarScope* const vscp) { // Trigger AstVarRef* const refp = new AstVarRef{flp, vscp, VAccess::WRITE}; - AstCMethodHard* const callp = new AstCMethodHard{flp, refp, "clear"}; + AstCMethodHard* const callp = new AstCMethodHard{flp, refp, VCMethod::TRIGGER_CLEAR}; callp->dtypeSetVoid(); return callp->makeStmt(); } @@ -1024,7 +1025,7 @@ AstStmtExpr* createTriggerSetCall(FileLine* const flp, AstVarScope* const toVscp AstVarScope* const fromVscp) { AstVarRef* const lhsp = new AstVarRef{flp, toVscp, VAccess::WRITE}; AstVarRef* const argp = new AstVarRef{flp, fromVscp, VAccess::READ}; - AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, "thisOr", argp}; + AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, VCMethod::TRIGGER_THIS_OR, argp}; callp->dtypeSetVoid(); return callp->makeStmt(); } @@ -1035,7 +1036,7 @@ AstStmtExpr* createTriggerAndNotCall(FileLine* const flp, AstVarScope* const lhs AstVarRef* const opap = new AstVarRef{flp, aVscp, VAccess::READ}; AstVarRef* const opbp = new AstVarRef{flp, bVscp, VAccess::READ}; opap->addNext(opbp); - AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, "andNot", opap}; + AstCMethodHard* const callp = new AstCMethodHard{flp, lhsp, VCMethod::TRIGGER_AND_NOT, opap}; callp->dtypeSetVoid(); return callp->makeStmt(); } @@ -1125,8 +1126,8 @@ void createEval(AstNetlist* netlistp, // AstIf* const ifp = new AstIf{flp, new AstVarRef{flp, nbaEventTriggerp, VAccess::READ}}; ifp->addThensp(setVar(continuep, 1)); ifp->addThensp(setVar(nbaEventTriggerp, 0)); - AstCMethodHard* const firep - = new AstCMethodHard{flp, new AstVarRef{flp, nbaEventp, VAccess::WRITE}, "fire"}; + AstCMethodHard* const firep = new AstCMethodHard{ + flp, new AstVarRef{flp, nbaEventp, VAccess::WRITE}, VCMethod::EVENT_FIRE}; firep->dtypeSetVoid(); ifp->addThensp(firep->makeStmt()); return ifp; diff --git a/src/V3SchedTiming.cpp b/src/V3SchedTiming.cpp index 3c4cd78ce..7b5d25a72 100644 --- a/src/V3SchedTiming.cpp +++ b/src/V3SchedTiming.cpp @@ -126,7 +126,7 @@ AstCCall* TimingKit::createCommit(AstNetlist* const netlistp) { auto* const newactp = new AstActive{flp, "", negSentreep}; // Create the commit call and put it in the commit function auto* const commitp = new AstCMethodHard{ - flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, "commit"}; + flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, VCMethod::SCHED_COMMIT}; if (resumep->pinsp()) commitp->addPinsp(resumep->pinsp()->cloneTree(false)); commitp->dtypeSetVoid(); newactp->addStmtsp(commitp->makeStmt()); @@ -184,7 +184,7 @@ TimingKit prepareTiming(AstNetlist* const netlistp) { FileLine* const flp = sentreep->fileline(); // Create a resume() call on the timing scheduler auto* const resumep = new AstCMethodHard{ - flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, "resume"}; + flp, new AstVarRef{flp, schedulerp, VAccess::READWRITE}, VCMethod::SCHED_RESUME}; resumep->dtypeSetVoid(); if (schedulerp->dtypep()->basicp()->isTriggerScheduler()) { UASSERT_OBJ(methodp->pinsp(), methodp, @@ -197,7 +197,7 @@ TimingKit prepareTiming(AstNetlist* const netlistp) { } } else if (schedulerp->dtypep()->basicp()->isDynamicTriggerScheduler()) { auto* const postp = resumep->cloneTree(false); - postp->name("doPostUpdates"); + postp->method(VCMethod::SCHED_DO_POST_UPDATES); m_postUpdatesr = AstNode::addNext(m_postUpdatesr, postp->makeStmt()); } // Put it in an active and put that in the global resume function diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h index 498f3d61c..ddedc20ed 100644 --- a/src/V3SenExprBuilder.h +++ b/src/V3SenExprBuilder.h @@ -133,7 +133,8 @@ private: } if (VN_IS(exprp->dtypep()->skipRefp(), UnpackArrayDType)) { - AstCMethodHard* const cmhp = new AstCMethodHard{flp, wrPrev(), "assign", rdCurr()}; + AstCMethodHard* const cmhp + = new AstCMethodHard{flp, wrPrev(), VCMethod::UNPACKED_ASSIGN, rdCurr()}; cmhp->dtypeSetVoid(); m_results.m_postUpdates.push_back(cmhp->makeStmt()); } else { @@ -160,7 +161,8 @@ private: if (VN_IS(senp->dtypep()->skipRefp(), UnpackArrayDType)) { // operand order reversed to avoid calling neq() method on non-VlUnpacked type, see // issue #5125 - AstCMethodHard* const resultp = new AstCMethodHard{flp, prevp(), "neq", currp()}; + AstCMethodHard* const resultp + = new AstCMethodHard{flp, prevp(), VCMethod::UNPACKED_NEQ, currp()}; resultp->dtypeSetBit(); return {resultp, true}; } @@ -176,13 +178,15 @@ private: { // Clear 'fired' state when done // No need to check if the event was fired, we need the flag clear regardless - AstCMethodHard* const clearp = new AstCMethodHard{flp, currp(), "clearFired"}; + AstCMethodHard* const clearp + = new AstCMethodHard{flp, currp(), VCMethod::EVENT_CLEAR_FIRED}; clearp->dtypeSetVoid(); m_results.m_postUpdates.push_back(clearp->makeStmt()); } // Get 'fired' state - AstCMethodHard* const callp = new AstCMethodHard{flp, currp(), "isFired"}; + AstCMethodHard* const callp + = new AstCMethodHard{flp, currp(), VCMethod::EVENT_IS_FIRED}; callp->dtypeSetBit(); return {callp, false}; } diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 87cf8da7e..edf1db57b 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -506,10 +506,11 @@ class TaskVisitor final : public VNVisitor { refArgOk = true; } else if (AstCMethodHard* const cMethodp = VN_CAST(pinp, CMethodHard)) { if (VN_IS(cMethodp->fromp()->dtypep()->skipRefp(), QueueDType)) { - refArgOk = cMethodp->name() == "atWriteAppend" - || cMethodp->name() == "atWriteAppendBack"; + refArgOk = cMethodp->method() == VCMethod::DYN_AT_WRITE_APPEND + || cMethodp->method() == VCMethod::DYN_AT_WRITE_APPEND_BACK; } else { - refArgOk = cMethodp->name() == "at" || cMethodp->name() == "atBack"; + refArgOk = cMethodp->method() == VCMethod::ARRAY_AT + || cMethodp->method() == VCMethod::ARRAY_AT_BACK; } } if (refArgOk) { diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp index e9dcd8988..a53ad8d6a 100644 --- a/src/V3Timing.cpp +++ b/src/V3Timing.cpp @@ -543,7 +543,7 @@ class TimingControlVisitor final : public VNVisitor { FileLine* const flp = m_scopeTopp->fileline(); auto* const awaitingCurrentTimep = new AstCMethodHard{flp, new AstVarRef{flp, getCreateDelayScheduler(), VAccess::READ}, - "awaitingCurrentTime"}; + VCMethod::SCHED_AWAITING_CURRENT_TIME}; awaitingCurrentTimep->dtypeSetBit(); m_delaySensesp = new AstSenTree{flp, new AstSenItem{flp, VEdgeType::ET_TRUE, awaitingCurrentTimep}}; @@ -566,7 +566,7 @@ class TimingControlVisitor final : public VNVisitor { FileLine* const flp = m_scopeTopp->fileline(); auto* const awaitingCurrentTimep = new AstCMethodHard{ flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::READ}, - "evaluate"}; + VCMethod::SCHED_EVALUATE}; awaitingCurrentTimep->dtypeSetBit(); m_dynamicSensesp = new AstSenTree{flp, new AstSenItem{flp, VEdgeType::ET_TRUE, awaitingCurrentTimep}}; @@ -712,7 +712,7 @@ class TimingControlVisitor final : public VNVisitor { void addForkDone(AstBegin* const beginp, AstVarScope* const forkVscp) const { FileLine* const flp = beginp->fileline(); auto* const donep = new AstCMethodHard{ - beginp->fileline(), new AstVarRef{flp, forkVscp, VAccess::WRITE}, "done"}; + beginp->fileline(), new AstVarRef{flp, forkVscp, VAccess::WRITE}, VCMethod::FORK_DONE}; donep->dtypeSetVoid(); addDebugInfo(donep); beginp->addStmtsp(donep->makeStmt()); @@ -735,13 +735,13 @@ class TimingControlVisitor final : public VNVisitor { if (forkp->joinType().joinAny()) joinCount = 1; // Set the join counter auto* const initp = new AstCMethodHard{flp, new AstVarRef{flp, forkVscp, VAccess::WRITE}, - "init", new AstConst{flp, joinCount}}; + VCMethod::FORK_INIT, new AstConst{flp, joinCount}}; initp->dtypeSetVoid(); addProcessInfo(initp); forkp->addHereThisAsNext(initp->makeStmt()); // Await the join at the end - auto* const joinp - = new AstCMethodHard{flp, new AstVarRef{flp, forkVscp, VAccess::WRITE}, "join"}; + auto* const joinp = new AstCMethodHard{flp, new AstVarRef{flp, forkVscp, VAccess::WRITE}, + VCMethod::FORK_JOIN}; joinp->dtypeSetVoid(); addProcessInfo(joinp); addDebugInfo(joinp); @@ -884,7 +884,8 @@ class TimingControlVisitor final : public VNVisitor { } // Replace self with a 'co_await dlySched.delay()' AstCMethodHard* const delayMethodp = new AstCMethodHard{ - flp, new AstVarRef{flp, getCreateDelayScheduler(), VAccess::WRITE}, "delay", valuep}; + flp, new AstVarRef{flp, getCreateDelayScheduler(), VAccess::WRITE}, + VCMethod::SCHED_DELAY, valuep}; delayMethodp->dtypeSetVoid(); addProcessInfo(delayMethodp); addDebugInfo(delayMethodp); @@ -922,7 +923,7 @@ class TimingControlVisitor final : public VNVisitor { // call auto* const evalMethodp = new AstCMethodHard{ flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::WRITE}, - "evaluation"}; + VCMethod::SCHED_EVALUATION}; evalMethodp->dtypeSetVoid(); addProcessInfo(evalMethodp); auto* const sentreep = nodep->sentreep(); @@ -954,21 +955,21 @@ class TimingControlVisitor final : public VNVisitor { // If it was, a call to the scheduler's evaluate() will return true AstCMethodHard* const anyTriggeredMethodp = new AstCMethodHard{ flp, new AstVarRef{flp, getCreateDynamicTriggerScheduler(), VAccess::WRITE}, - "anyTriggered", new AstVarRef{flp, trigvscp, VAccess::READ}}; + VCMethod::SCHED_ANY_TRIGGERED, new AstVarRef{flp, trigvscp, VAccess::READ}}; anyTriggeredMethodp->dtypeSetVoid(); loopp->addStmtsp(anyTriggeredMethodp->makeStmt()); // If the post update is destructive (e.g. event vars are cleared), create an await for // the post update step if (destructivePostUpdate(sentreep)) { AstCAwait* const awaitPostUpdatep = awaitEvalp->cloneTree(false); - VN_AS(awaitPostUpdatep->exprp(), CMethodHard)->name("postUpdate"); + VN_AS(awaitPostUpdatep->exprp(), CMethodHard)->method(VCMethod::SCHED_POST_UPDATE); loopp->addStmtsp(awaitPostUpdatep->makeStmt()); } // Put the post updates at the end of the loop for (AstNodeStmt* const stmtp : senResults.m_postUpdates) loopp->addStmtsp(stmtp); // Finally, await the resumption step in 'act' AstCAwait* const awaitResumep = awaitEvalp->cloneTree(false); - VN_AS(awaitResumep->exprp(), CMethodHard)->name("resumption"); + VN_AS(awaitResumep->exprp(), CMethodHard)->method(VCMethod::SCHED_RESUMPTION); AstNode::addNext(loopp, awaitResumep->makeStmt()); // Replace the event control with the loop nodep->replaceWith(loopp); @@ -979,7 +980,7 @@ class TimingControlVisitor final : public VNVisitor { // Replace self with a 'co_await trigSched.trigger()' auto* const triggerMethodp = new AstCMethodHard{ flp, new AstVarRef{flp, getCreateTriggerSchedulerp(sentreep), VAccess::WRITE}, - "trigger"}; + VCMethod::SCHED_TRIGGER}; triggerMethodp->dtypeSetVoid(); // If it should be committed immediately, pass true, otherwise false triggerMethodp->addPinsp(nodep->user2() ? new AstConst{flp, AstConst::BitTrue{}} diff --git a/src/V3Width.cpp b/src/V3Width.cpp index aee13075e..851395f17 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1800,7 +1800,8 @@ class WidthVisitor final : public VNVisitor { switch (nodep->attrType()) { case VAttrType::DIM_SIZE: { AstNodeExpr* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeExpr); - AstNode* const newp = new AstCMethodHard{nodep->fileline(), fromp, "size"}; + AstNode* const newp + = new AstCMethodHard{nodep->fileline(), fromp, VCMethod::DYN_SIZE}; newp->dtypeSetSigned32(); newp->didWidth(true); newp->protect(false); @@ -1819,7 +1820,7 @@ class WidthVisitor final : public VNVisitor { case VAttrType::DIM_HIGH: { AstNodeExpr* const fromp = VN_AS(nodep->fromp()->unlinkFrBack(), NodeExpr); AstNodeExpr* const sizep - = new AstCMethodHard{nodep->fileline(), fromp, "size"}; + = new AstCMethodHard{nodep->fileline(), fromp, VCMethod::DYN_SIZE}; sizep->dtypeSetSigned32(); sizep->didWidth(true); sizep->protect(false); @@ -3076,8 +3077,8 @@ class WidthVisitor final : public VNVisitor { || VN_IS(itemDtp, QueueDType)) { // Unsupported in parameters AstNodeExpr* const cexprp = exprp->cloneTreePure(true); - AstNodeExpr* const inewp - = new AstCMethodHard{nodep->fileline(), itemp->unlinkFrBack(), "inside", cexprp}; + AstNodeExpr* const inewp = new AstCMethodHard{nodep->fileline(), itemp->unlinkFrBack(), + VCMethod::ARRAY_INSIDE, cexprp}; iterateCheckTyped(nodep, "inside value", cexprp, itemDtp->subDTypep(), BOTH); VL_DANGLING(cexprp); // Might have been replaced inewp->dtypeSetBit(); @@ -3708,7 +3709,7 @@ class WidthVisitor final : public VNVisitor { || nodep->name() == "size") { methodOkArguments(nodep, 0, 0); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "size"}; // So don't need num() + VCMethod::ASSOC_SIZE}; // So don't need num() newp->dtypeSetSigned32(); } else if (nodep->name() == "first" // function int first(ref index) || nodep->name() == "last" // @@ -3724,21 +3725,21 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 1, 1); iterateCheckSelf(nodep, "argument", methodArg(nodep, 0), SELF, BOTH); AstNodeExpr* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep); - newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists", - index_exprp->unlinkFrBack()}; + newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::ASSOC_EXISTS, index_exprp->unlinkFrBack()}; newp->dtypeSetLogicUnsized(32, 1, VSigning::SIGNED); } else if (nodep->name() == "delete") { // function void delete([input integer index]) methodOkArguments(nodep, 0, 1); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); if (!nodep->pinsp()) { newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "clear"}; + VCMethod::ASSOC_CLEAR}; newp->dtypeSetVoid(); } else { iterateCheckSelf(nodep, "argument", methodArg(nodep, 0), SELF, BOTH); AstNodeExpr* const index_exprp = methodCallWildcardIndexExpr(nodep, adtypep); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "erase", index_exprp->unlinkFrBack()}; + VCMethod::ASSOC_ERASE, index_exprp->unlinkFrBack()}; newp->dtypeSetVoid(); } } else if (nodep->name() == "sort" || nodep->name() == "rsort" @@ -3754,14 +3755,14 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "r_" + nodep->name(), withp}; + VCMethod::arrayMethod("r_" + nodep->name()), withp}; newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep()); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "min" || nodep->name() == "max" || nodep->name() == "unique") { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name()}; + VCMethod::arrayMethod(nodep->name())}; newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep())); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "find" || nodep->name() == "find_first" @@ -3772,7 +3773,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep())); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "map") { @@ -3796,7 +3797,7 @@ class WidthVisitor final : public VNVisitor { || nodep->name() == "size") { methodOkArguments(nodep, 0, 0); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "size"}; // So don't need num() + VCMethod::ASSOC_SIZE}; // So don't need num() newp->dtypeSetSigned32(); } else if (nodep->name() == "first" // function int first(ref index) || nodep->name() == "last" // @@ -3806,9 +3807,10 @@ class WidthVisitor final : public VNVisitor { iterateCheckTyped(nodep, "argument", methodArg(nodep, 0), adtypep->keyDTypep(), BOTH); AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); methodCallLValueRecurse(nodep, index_exprp, VAccess::READWRITE); - newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), // first/last/next/prev - index_exprp->unlinkFrBack()}; + newp + = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::arrayMethod(nodep->name()), // first/last/next/prev + index_exprp->unlinkFrBack()}; newp->dtypeSetSigned32(); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "exists") { // function int exists(input index) @@ -3816,22 +3818,22 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 1, 1); iterateCheckTyped(nodep, "argument", methodArg(nodep, 0), adtypep->keyDTypep(), BOTH); AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); - newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "exists", - index_exprp->unlinkFrBack()}; + newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::ASSOC_EXISTS, index_exprp->unlinkFrBack()}; newp->dtypeSetLogicUnsized(32, 1, VSigning::SIGNED); } else if (nodep->name() == "delete") { // function void delete([input integer index]) methodOkArguments(nodep, 0, 1); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); if (!nodep->pinsp()) { newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "clear"}; + VCMethod::ASSOC_CLEAR}; newp->dtypeSetVoid(); } else { iterateCheckTyped(nodep, "argument", methodArg(nodep, 0), adtypep->keyDTypep(), BOTH); AstNodeExpr* const index_exprp = methodCallAssocIndexExpr(nodep, adtypep); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "erase", index_exprp->unlinkFrBack()}; + VCMethod::ASSOC_ERASE, index_exprp->unlinkFrBack()}; newp->dtypeSetVoid(); } } else if (nodep->name() == "sort" || nodep->name() == "rsort" @@ -3846,7 +3848,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "r_" + nodep->name(), withp}; + VCMethod::arrayMethod("r_" + nodep->name()), withp}; newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep()); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "min" || nodep->name() == "max" || nodep->name() == "unique" @@ -3856,7 +3858,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; if (nodep->name() == "unique_index") { newp->dtypep(queueDTypeIndexedBy(adtypep->keyDTypep())); } else { @@ -3870,7 +3872,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep())); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "find_index" || nodep->name() == "find_first_index" @@ -3880,7 +3882,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; newp->dtypep(queueDTypeIndexedBy(adtypep->keyDTypep())); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "map") { @@ -3915,16 +3917,31 @@ class WidthVisitor final : public VNVisitor { } void methodCallLValueRecurse(AstMethodCall* nodep, AstNode* childp, const VAccess& access) { if (AstCMethodHard* const ichildp = VN_CAST(childp, CMethodHard)) { - const std::string name = ichildp->name(); - if (name == "at" || name == "atWrite" || name == "atBack" || name == "atWriteAppend" - || name == "atWriteAppendBack") { + bool methAt = false; + bool methAtBack = false; + bool methAtWrite = false; + switch (ichildp->method()) { + case VCMethod::ARRAY_AT: // FALLTHRU + methAt = true; + break; + case VCMethod::ARRAY_AT_BACK: // FALLTHRU + methAtBack = true; + break; + case VCMethod::ARRAY_AT_WRITE: // FALLTHRU + case VCMethod::DYN_AT_WRITE_APPEND: // FALLTHRU + case VCMethod::DYN_AT_WRITE_APPEND_BACK: // + methAtWrite = true; + break; + default: break; + } + if (methAt || methAtBack || methAtWrite) { const AstNodeDType* const fromDtypep = ichildp->fromp()->dtypep()->skipRefp(); if (VN_IS(fromDtypep, QueueDType) || VN_IS(fromDtypep, DynArrayDType)) { // Change access methods to writable ones - if (name == "at") { - ichildp->name("atWrite"); - } else if (name == "atBack") { - ichildp->name("atWriteAppendBack"); + if (methAt) { + ichildp->method(VCMethod::ARRAY_AT_WRITE); + } else if (methAtBack) { + ichildp->method(VCMethod::DYN_AT_WRITE_APPEND_BACK); } } methodCallLValueRecurse(nodep, ichildp->fromp(), access); @@ -3958,7 +3975,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; newp->dtypeSetVoid(); } else if (nodep->name() == "min" || nodep->name() == "max" || nodep->name() == "unique" || nodep->name() == "unique_index") { @@ -3967,7 +3984,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; if (nodep->name() == "unique_index") { newp->dtypep(newp->findQueueIndexDType()); } else { @@ -3982,7 +3999,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; newp->dtypep(queueDTypeIndexedBy(adtypep->subDTypep())); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "find_index" || nodep->name() == "find_first_index" @@ -3993,7 +4010,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), withp}; + VCMethod::arrayMethod(nodep->name()), withp}; newp->dtypep(newp->findQueueIndexDType()); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if (nodep->name() == "map") { @@ -4008,23 +4025,26 @@ class WidthVisitor final : public VNVisitor { if (nodep->name() == "at") { // Created internally for [] methodOkArguments(nodep, 1, 1); iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH); - newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "at"}; + newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::ARRAY_AT}; newp->dtypeFrom(adtypep->subDTypep()); } else if (nodep->name() == "atWrite") { // Created internally for [] methodOkArguments(nodep, 1, 1); iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); - newp - = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "atWrite"}; + newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::ARRAY_AT_WRITE}; newp->dtypeFrom(adtypep->subDTypep()); } else if (nodep->name() == "size") { methodOkArguments(nodep, 0, 0); - newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size"}; + newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::DYN_SIZE}; newp->dtypeSetSigned32(); } else if (nodep->name() == "delete") { // function void delete() methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); - newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "clear"}; + newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::DYN_CLEAR}; newp->dtypeSetVoid(); } else if (nodep->name() == "and" || nodep->name() == "or" || nodep->name() == "xor" || nodep->name() == "sum" || nodep->name() == "product") { @@ -4035,7 +4055,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "r_" + nodep->name(), withp}; + VCMethod::arrayMethod("r_" + nodep->name()), withp}; newp->dtypeFrom(adtypep->subDTypep()); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if ((newp = methodCallArray(nodep, adtypep))) { @@ -4057,7 +4077,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 1, 1); iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name()}; + VCMethod::arrayMethod(nodep->name())}; newp->dtypeFrom(adtypep->subDTypep()); } else if (nodep->name() == "atWriteAppend" || nodep->name() == "atWriteAppendBack") { // Created internally for [] @@ -4065,31 +4085,32 @@ class WidthVisitor final : public VNVisitor { iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name()}; + VCMethod::arrayMethod(nodep->name())}; newp->dtypeFrom(adtypep->subDTypep()); } else if (nodep->name() == "num" // function int num() || nodep->name() == "size") { methodOkArguments(nodep, 0, 0); - newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), "size"}; + newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), + VCMethod::DYN_SIZE}; newp->dtypeSetSigned32(); } else if (nodep->name() == "delete") { // function void delete([input integer index]) methodOkArguments(nodep, 0, 1); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::WRITE); if (!nodep->pinsp()) { newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "clear"}; + VCMethod::DYN_CLEAR}; newp->dtypeSetVoid(); } else { iterateCheckSigned32(nodep, "argument", methodArg(nodep, 0), BOTH); AstNodeExpr* const index_exprp = methodCallQueueIndexExpr(nodep); if (index_exprp->isZero()) { // delete(0) is a pop_front newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "pop_front"}; + VCMethod::DYN_POP_FRONT}; newp->dtypeFrom(adtypep->subDTypep()); newp->dtypeSetVoid(); } else { newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "erase", index_exprp->unlinkFrBack()}; + VCMethod::DYN_ERASE, index_exprp->unlinkFrBack()}; newp->dtypeSetVoid(); } } @@ -4102,11 +4123,11 @@ class WidthVisitor final : public VNVisitor { iterateCheckTyped(nodep, "insert value", argp->exprp(), adtypep->subDTypep(), BOTH); if (index_exprp->isZero()) { // insert(0, ...) is a push_front newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "push_front", argp->exprp()->unlinkFrBack()}; + VCMethod::DYN_PUSH_FRONT, argp->exprp()->unlinkFrBack()}; newp->dtypeSetVoid(); } else { newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), index_exprp->unlinkFrBack()}; + VCMethod::DYN_INSERT, index_exprp->unlinkFrBack()}; newp->addPinsp(argp->exprp()->unlinkFrBack()); newp->dtypeSetVoid(); } @@ -4115,7 +4136,7 @@ class WidthVisitor final : public VNVisitor { // Returns element, so method both consumes (reads) and modifies the queue methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READWRITE); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name()}; + VCMethod::arrayMethod(nodep->name())}; newp->dtypeFrom(adtypep->subDTypep()); } else if (nodep->name() == "push_back" || nodep->name() == "push_front") { methodOkArguments(nodep, 1, 1); @@ -4124,7 +4145,8 @@ class WidthVisitor final : public VNVisitor { AstArg* const argp = VN_AS(nodep->pinsp(), Arg); iterateCheckTyped(nodep, "push value", argp->exprp(), adtypep->subDTypep(), BOTH); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - nodep->name(), argp->exprp()->unlinkFrBack()}; + VCMethod::arrayMethod(nodep->name()), + argp->exprp()->unlinkFrBack()}; newp->dtypeSetVoid(); } else if (nodep->name() == "and" || nodep->name() == "or" || nodep->name() == "xor" || nodep->name() == "sum" || nodep->name() == "product") { @@ -4134,7 +4156,7 @@ class WidthVisitor final : public VNVisitor { methodOkArguments(nodep, 0, 0); methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "r_" + nodep->name(), withp}; + VCMethod::arrayMethod("r_" + nodep->name()), withp}; newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep()); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); } else if ((newp = methodCallArray(nodep, adtypep))) { @@ -4353,7 +4375,7 @@ class WidthVisitor final : public VNVisitor { v3Global.useRandomizeMethods(true); AstCMethodHard* const newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "__Vm_rng.get_randstate", nullptr}; + VCMethod::RNG_GET_RANDSTATE, nullptr}; newp->usePtr(true); newp->dtypeSetString(); nodep->replaceWith(newp); @@ -4368,7 +4390,7 @@ class WidthVisitor final : public VNVisitor { v3Global.useRandomizeMethods(true); AstCMethodHard* const newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "__Vm_rng.set_randstate", exprp->unlinkFrBack()}; + VCMethod::RNG_SET_RANDSTATE, exprp->unlinkFrBack()}; newp->usePtr(true); newp->dtypeSetString(); nodep->replaceWith(newp); @@ -4456,7 +4478,7 @@ class WidthVisitor final : public VNVisitor { methodCallLValueRecurse(nodep, nodep->fromp(), VAccess::READ); AstCMethodHard* const newp = new AstCMethodHard{nodep->fileline(), nodep->fromp()->unlinkFrBack(), - "r_" + nodep->name(), withp}; + VCMethod::arrayMethod("r_" + nodep->name()), withp}; newp->dtypeFrom(withp ? withp->dtypep() : adtypep->subDTypep()); if (!nodep->firstAbovep()) newp->dtypeSetVoid(); newp->protect(false); @@ -4503,7 +4525,7 @@ class WidthVisitor final : public VNVisitor { if (nodep->name() == "triggered") { methodOkArguments(nodep, 0, 0); AstCMethodHard* const callp = new AstCMethodHard{ - nodep->fileline(), nodep->fromp()->unlinkFrBack(), "isTriggered"}; + nodep->fileline(), nodep->fromp()->unlinkFrBack(), VCMethod::EVENT_IS_TRIGGERED}; callp->dtypeSetBit(); nodep->replaceWith(callp); VL_DO_DANGLING(pushDeletep(nodep), nodep); @@ -5634,10 +5656,10 @@ class WidthVisitor final : public VNVisitor { AstCMethodHard* newp; if (!dynp->rhsp()) { newp = new AstCMethodHard{nodep->fileline(), nodep->lhsp()->unlinkFrBack(), - "renew", dynp->sizep()->unlinkFrBack()}; + VCMethod::DYN_RENEW, dynp->sizep()->unlinkFrBack()}; } else { newp = new AstCMethodHard{nodep->fileline(), nodep->lhsp()->unlinkFrBack(), - "renew_copy", dynp->sizep()->unlinkFrBack()}; + VCMethod::DYN_RENEW_COPY, dynp->sizep()->unlinkFrBack()}; newp->addPinsp(dynp->rhsp()->unlinkFrBack()); } newp->didWidth(true); diff --git a/src/V3WidthCommit.cpp b/src/V3WidthCommit.cpp index 774d1a1e4..c42bee437 100644 --- a/src/V3WidthCommit.cpp +++ b/src/V3WidthCommit.cpp @@ -488,8 +488,8 @@ private: } void visit(AstCMethodHard* nodep) override { VL_RESTORER(m_dynsizedelem); - if (nodep->name() == "atWrite" || nodep->name() == "atWriteAppend" - || nodep->name() == "at") + if (nodep->method() == VCMethod::ARRAY_AT || nodep->method() == VCMethod::ARRAY_AT_WRITE + || nodep->method() == VCMethod::DYN_AT_WRITE_APPEND) m_dynsizedelem = true; iterateChildren(nodep); editDType(nodep); diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index b15e68be8..75bf1ef1e 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -286,9 +286,10 @@ class WidthSelVisitor final : public VNVisitor { VL_DO_DANGLING(pushDeletep(nodep), nodep); } else if (const AstDynArrayDType* const adtypep = VN_CAST(ddtypep, DynArrayDType)) { // SELBIT(array, index) -> CMETHODCALL(queue, "at", index) - const char* methodName = nodep->access().isWriteOrRW() ? "atWrite" : "at"; + const VCMethod method + = nodep->access().isWriteOrRW() ? VCMethod::ARRAY_AT_WRITE : VCMethod::ARRAY_AT; AstCMethodHard* const newp - = new AstCMethodHard{nodep->fileline(), fromp, methodName, rhsp}; + = new AstCMethodHard{nodep->fileline(), fromp, method, rhsp}; newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference UINFOTREE(9, newp, "", "SELBTq"); nodep->replaceWith(newp); @@ -296,12 +297,16 @@ class WidthSelVisitor final : public VNVisitor { } else if (const AstQueueDType* const adtypep = VN_CAST(ddtypep, QueueDType)) { // SELBIT(array, index) -> CMETHODCALL(queue, "at", index) AstCMethodHard* newp; - const char* methodName = nodep->access().isWriteOrRW() ? "atWriteAppend" : "at"; if (AstNodeExpr* const backnessp = selQueueBackness(rhsp)) { - newp = new AstCMethodHard{nodep->fileline(), fromp, - std::string(methodName) + "Back", backnessp}; + const VCMethod method = nodep->access().isWriteOrRW() + ? VCMethod::DYN_AT_WRITE_APPEND_BACK + : VCMethod::ARRAY_AT_BACK; + newp = new AstCMethodHard{nodep->fileline(), fromp, method, backnessp}; } else { - newp = new AstCMethodHard{nodep->fileline(), fromp, methodName, rhsp}; + const VCMethod method = nodep->access().isWriteOrRW() + ? VCMethod::DYN_AT_WRITE_APPEND + : VCMethod::ARRAY_AT; + newp = new AstCMethodHard{nodep->fileline(), fromp, method, rhsp}; } newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off queue reference UINFOTREE(9, newp, "", "SELBTq"); @@ -379,10 +384,10 @@ class WidthSelVisitor final : public VNVisitor { // queue size, this allows a single queue reference, to support // for equations in side effects that select the queue to // operate upon. - std::string name = (qleftBacknessp ? "sliceBackBack" - : qrightBacknessp ? "sliceFrontBack" - : "slice"); - AstCMethodHard* const newp = new AstCMethodHard{nodep->fileline(), fromp, name}; + VCMethod method = (qleftBacknessp ? VCMethod::DYN_SLICE_BACK_BACK + : qrightBacknessp ? VCMethod::DYN_SLICE_FRONT_BACK + : VCMethod::DYN_SLICE); + AstCMethodHard* const newp = new AstCMethodHard{nodep->fileline(), fromp, method}; if (qleftBacknessp) { VL_DO_DANGLING(pushDeletep(qleftp), qleftp); newp->addPinsp(qleftBacknessp); diff --git a/src/Verilator.cpp b/src/Verilator.cpp index be46c7687..3b82360b7 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -701,6 +701,7 @@ static bool verilate(const string& argString) { if (v3Global.opt.debugSelfTest()) { V3Os::selfTest(); V3Number::selfTest(); + VCMethod::selfTest(); VString::selfTest(); VHashSha256::selfTest(); VSpellCheck::selfTest();