diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 3a25a1a68..b5595a81c 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -57,6 +57,7 @@ private: AstNodeModule* m_modp = nullptr; // Current module AstNodeFTask* m_ftaskp = nullptr; // Current task AstNodeDType* m_dtypep = nullptr; // Current data type + VLifetime m_lifetime = VLifetime::STATIC; // Propagating lifetime // METHODS VL_DEBUG_FUNC; // Declare debug() @@ -107,11 +108,17 @@ private: if (!nodep->user1SetOnce()) { // Process only once. V3Config::applyFTask(m_modp, nodep); cleanFileline(nodep); + VL_RESTORER(m_ftaskp); + VL_RESTORER(m_lifetime); { m_ftaskp = nodep; + m_lifetime = nodep->lifetime(); + if (m_lifetime.isNone()) { + // Automatic always until we support static + m_lifetime = VLifetime::AUTOMATIC; + } iterateChildren(nodep); } - m_ftaskp = nullptr; } } virtual void visit(AstNodeFTaskRef* nodep) override { @@ -173,6 +180,13 @@ private: virtual void visit(AstVar* nodep) override { cleanFileline(nodep); + if (nodep->lifetime().isNone()) { + if (nodep->isFuncLocal() && nodep->isIO()) { + nodep->lifetime(VLifetime::AUTOMATIC); + } else { + nodep->lifetime(m_lifetime); + } + } if (nodep->isParam() && !nodep->valuep() && nodep->fileline()->language() < V3LangCode::L1800_2009) { nodep->v3error("Parameter requires default value, or use IEEE 1800-2009 or later."); @@ -224,25 +238,20 @@ private: FileLine* fl = nodep->valuep()->fileline(); if (nodep->isParam() || (m_ftaskp && nodep->isNonOutput())) { // 1. Parameters and function inputs: It's a default to use if not overridden - } else if (VN_IS(m_modp, Class)) { - // 2. Class member init become initials (as might call functions) - // later move into class constructor - nodep->addNextHere(new AstInitial( - fl, new AstAssign(fl, new AstVarRef(fl, nodep->name(), VAccess::WRITE), - nodep->valuep()->unlinkFrBack()))); - } else if (!m_ftaskp && nodep->isNonOutput()) { + } else if (!m_ftaskp && !VN_IS(m_modp, Class) && nodep->isNonOutput()) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: Default value on module input: " << nodep->prettyNameQ()); nodep->valuep()->unlinkFrBack()->deleteTree(); - } // 3. Under modules, it's an initial value to be loaded at time 0 via an AstInitial + } // 2. Under modules/class, it's an initial value to be loaded at time 0 via an + // AstInitial else if (m_valueModp) { // Making an AstAssign (vs AstAssignW) to a wire is an error, suppress it FileLine* newfl = new FileLine(fl); newfl->warnOff(V3ErrorCode::PROCASSWIRE, true); - nodep->addNextHere(new AstInitial( - newfl, - new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE), - nodep->valuep()->unlinkFrBack()))); + auto* assp + = new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE), + nodep->valuep()->unlinkFrBack()); + nodep->addNextHere(new AstInitial(newfl, assp)); } // 4. Under blocks, it's an initial value to be under an assign else { nodep->addNextHere(new AstAssign(fl, @@ -483,12 +492,17 @@ private: V3Config::applyModule(nodep); VL_RESTORER(m_modp); + VL_RESTORER(m_lifetime); { // Module: Create sim table for entire module and iterate cleanFileline(nodep); // m_modp = nodep; m_valueModp = nodep; + m_lifetime = nodep->lifetime(); + if (m_lifetime.isNone()) { + m_lifetime = VN_IS(nodep, Class) ? VLifetime::AUTOMATIC : VLifetime::STATIC; + } iterateChildren(nodep); } m_valueModp = nodep; diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index bf158a20a..1f7fdaff7 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -51,7 +51,6 @@ private: AstClass* m_classp = nullptr; // Class we're inside AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside AstNodeCoverOrAssert* m_assertp = nullptr; // Current assertion - VLifetime m_lifetime = VLifetime::STATIC; // Propagating lifetime int m_senitemCvtNum = 0; // Temporary signal counter // METHODS @@ -66,23 +65,17 @@ private: UINFO(8, "MODULE " << nodep << endl); if (nodep->dead()) return; VL_RESTORER(m_modp); - VL_RESTORER(m_lifetime); VL_RESTORER(m_senitemCvtNum); { m_modp = nodep; m_senitemCvtNum = 0; - m_lifetime = nodep->lifetime(); - if (m_lifetime.isNone()) m_lifetime = VLifetime::STATIC; iterateChildren(nodep); } } virtual void visit(AstClass* nodep) override { VL_RESTORER(m_classp); - VL_RESTORER(m_lifetime); { m_classp = nodep; - m_lifetime = nodep->lifetime(); - if (m_lifetime.isNone()) m_lifetime = VLifetime::AUTOMATIC; iterateChildren(nodep); } } @@ -106,13 +99,6 @@ private: if (m_classp && nodep->isParam()) nodep->v3warn(E_UNSUPPORTED, "Unsupported: class parameter"); if (m_ftaskp) nodep->funcLocal(true); - if (nodep->lifetime().isNone()) { - if (nodep->isFuncLocal() && nodep->isIO()) { - nodep->lifetime(VLifetime::AUTOMATIC); - } else { - nodep->lifetime(m_lifetime); - } - } if (nodep->isSigModPublic()) { nodep->sigModPublic(false); // We're done with this attribute m_modp->modPublic(true); // Avoid flattening if signals are exposed @@ -136,15 +122,11 @@ private: VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); return; } - VLifetime origLifetime = m_lifetime; { - m_lifetime = nodep->lifetime(); - if (m_lifetime.isNone()) m_lifetime = VLifetime::AUTOMATIC; m_ftaskp = nodep; iterateChildren(nodep); } m_ftaskp = nullptr; - m_lifetime = origLifetime; if (nodep->dpiExport()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); } } virtual void visit(AstNodeFTaskRef* nodep) override {