Internals: Move static resolution to LinkParse.

This commit is contained in:
Wilson Snyder 2020-10-15 21:08:24 -04:00
parent 5d8019f941
commit d4df94d866
2 changed files with 27 additions and 31 deletions

View File

@ -57,6 +57,7 @@ private:
AstNodeModule* m_modp = nullptr; // Current module AstNodeModule* m_modp = nullptr; // Current module
AstNodeFTask* m_ftaskp = nullptr; // Current task AstNodeFTask* m_ftaskp = nullptr; // Current task
AstNodeDType* m_dtypep = nullptr; // Current data type AstNodeDType* m_dtypep = nullptr; // Current data type
VLifetime m_lifetime = VLifetime::STATIC; // Propagating lifetime
// METHODS // METHODS
VL_DEBUG_FUNC; // Declare debug() VL_DEBUG_FUNC; // Declare debug()
@ -107,11 +108,17 @@ private:
if (!nodep->user1SetOnce()) { // Process only once. if (!nodep->user1SetOnce()) { // Process only once.
V3Config::applyFTask(m_modp, nodep); V3Config::applyFTask(m_modp, nodep);
cleanFileline(nodep); cleanFileline(nodep);
VL_RESTORER(m_ftaskp);
VL_RESTORER(m_lifetime);
{ {
m_ftaskp = nodep; m_ftaskp = nodep;
m_lifetime = nodep->lifetime();
if (m_lifetime.isNone()) {
// Automatic always until we support static
m_lifetime = VLifetime::AUTOMATIC;
}
iterateChildren(nodep); iterateChildren(nodep);
} }
m_ftaskp = nullptr;
} }
} }
virtual void visit(AstNodeFTaskRef* nodep) override { virtual void visit(AstNodeFTaskRef* nodep) override {
@ -173,6 +180,13 @@ private:
virtual void visit(AstVar* nodep) override { virtual void visit(AstVar* nodep) override {
cleanFileline(nodep); 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() if (nodep->isParam() && !nodep->valuep()
&& nodep->fileline()->language() < V3LangCode::L1800_2009) { && nodep->fileline()->language() < V3LangCode::L1800_2009) {
nodep->v3error("Parameter requires default value, or use IEEE 1800-2009 or later."); nodep->v3error("Parameter requires default value, or use IEEE 1800-2009 or later.");
@ -224,25 +238,20 @@ private:
FileLine* fl = nodep->valuep()->fileline(); FileLine* fl = nodep->valuep()->fileline();
if (nodep->isParam() || (m_ftaskp && nodep->isNonOutput())) { if (nodep->isParam() || (m_ftaskp && nodep->isNonOutput())) {
// 1. Parameters and function inputs: It's a default to use if not overridden // 1. Parameters and function inputs: It's a default to use if not overridden
} else if (VN_IS(m_modp, Class)) { } else if (!m_ftaskp && !VN_IS(m_modp, Class) && nodep->isNonOutput()) {
// 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()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Default value on module input: " nodep->v3warn(E_UNSUPPORTED, "Unsupported: Default value on module input: "
<< nodep->prettyNameQ()); << nodep->prettyNameQ());
nodep->valuep()->unlinkFrBack()->deleteTree(); 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) { else if (m_valueModp) {
// Making an AstAssign (vs AstAssignW) to a wire is an error, suppress it // Making an AstAssign (vs AstAssignW) to a wire is an error, suppress it
FileLine* newfl = new FileLine(fl); FileLine* newfl = new FileLine(fl);
newfl->warnOff(V3ErrorCode::PROCASSWIRE, true); newfl->warnOff(V3ErrorCode::PROCASSWIRE, true);
nodep->addNextHere(new AstInitial( auto* assp
newfl, = new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE),
new AstAssign(newfl, new AstVarRef(newfl, nodep->name(), VAccess::WRITE), nodep->valuep()->unlinkFrBack());
nodep->valuep()->unlinkFrBack()))); nodep->addNextHere(new AstInitial(newfl, assp));
} // 4. Under blocks, it's an initial value to be under an assign } // 4. Under blocks, it's an initial value to be under an assign
else { else {
nodep->addNextHere(new AstAssign(fl, nodep->addNextHere(new AstAssign(fl,
@ -483,12 +492,17 @@ private:
V3Config::applyModule(nodep); V3Config::applyModule(nodep);
VL_RESTORER(m_modp); VL_RESTORER(m_modp);
VL_RESTORER(m_lifetime);
{ {
// Module: Create sim table for entire module and iterate // Module: Create sim table for entire module and iterate
cleanFileline(nodep); cleanFileline(nodep);
// //
m_modp = nodep; m_modp = nodep;
m_valueModp = nodep; m_valueModp = nodep;
m_lifetime = nodep->lifetime();
if (m_lifetime.isNone()) {
m_lifetime = VN_IS(nodep, Class) ? VLifetime::AUTOMATIC : VLifetime::STATIC;
}
iterateChildren(nodep); iterateChildren(nodep);
} }
m_valueModp = nodep; m_valueModp = nodep;

View File

@ -51,7 +51,6 @@ private:
AstClass* m_classp = nullptr; // Class we're inside AstClass* m_classp = nullptr; // Class we're inside
AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside
AstNodeCoverOrAssert* m_assertp = nullptr; // Current assertion AstNodeCoverOrAssert* m_assertp = nullptr; // Current assertion
VLifetime m_lifetime = VLifetime::STATIC; // Propagating lifetime
int m_senitemCvtNum = 0; // Temporary signal counter int m_senitemCvtNum = 0; // Temporary signal counter
// METHODS // METHODS
@ -66,23 +65,17 @@ private:
UINFO(8, "MODULE " << nodep << endl); UINFO(8, "MODULE " << nodep << endl);
if (nodep->dead()) return; if (nodep->dead()) return;
VL_RESTORER(m_modp); VL_RESTORER(m_modp);
VL_RESTORER(m_lifetime);
VL_RESTORER(m_senitemCvtNum); VL_RESTORER(m_senitemCvtNum);
{ {
m_modp = nodep; m_modp = nodep;
m_senitemCvtNum = 0; m_senitemCvtNum = 0;
m_lifetime = nodep->lifetime();
if (m_lifetime.isNone()) m_lifetime = VLifetime::STATIC;
iterateChildren(nodep); iterateChildren(nodep);
} }
} }
virtual void visit(AstClass* nodep) override { virtual void visit(AstClass* nodep) override {
VL_RESTORER(m_classp); VL_RESTORER(m_classp);
VL_RESTORER(m_lifetime);
{ {
m_classp = nodep; m_classp = nodep;
m_lifetime = nodep->lifetime();
if (m_lifetime.isNone()) m_lifetime = VLifetime::AUTOMATIC;
iterateChildren(nodep); iterateChildren(nodep);
} }
} }
@ -106,13 +99,6 @@ private:
if (m_classp && nodep->isParam()) if (m_classp && nodep->isParam())
nodep->v3warn(E_UNSUPPORTED, "Unsupported: class parameter"); nodep->v3warn(E_UNSUPPORTED, "Unsupported: class parameter");
if (m_ftaskp) nodep->funcLocal(true); 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()) { if (nodep->isSigModPublic()) {
nodep->sigModPublic(false); // We're done with this attribute nodep->sigModPublic(false); // We're done with this attribute
m_modp->modPublic(true); // Avoid flattening if signals are exposed m_modp->modPublic(true); // Avoid flattening if signals are exposed
@ -136,15 +122,11 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
return; return;
} }
VLifetime origLifetime = m_lifetime;
{ {
m_lifetime = nodep->lifetime();
if (m_lifetime.isNone()) m_lifetime = VLifetime::AUTOMATIC;
m_ftaskp = nodep; m_ftaskp = nodep;
iterateChildren(nodep); iterateChildren(nodep);
} }
m_ftaskp = nullptr; m_ftaskp = nullptr;
m_lifetime = origLifetime;
if (nodep->dpiExport()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); } if (nodep->dpiExport()) { nodep->scopeNamep(new AstScopeName(nodep->fileline())); }
} }
virtual void visit(AstNodeFTaskRef* nodep) override { virtual void visit(AstNodeFTaskRef* nodep) override {