diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 219397bac..86e2de882 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2071,6 +2071,7 @@ public: bool isPrimaryIO() const VL_MT_SAFE { return m_primaryIO; } bool isPrimaryInish() const { return isPrimaryIO() && isNonOutput(); } bool isIfaceRef() const { return varType() == VVarType::IFACEREF; } + void setIfaceRef() { m_varType = VVarType::IFACEREF; } bool isIfaceParent() const { return m_isIfaceParent; } bool isInternal() const { return m_isInternal; } bool isSignal() const { return varType().isSignal(); } diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index bd27b2f32..becf8b566 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -109,6 +109,7 @@ class LinkCellsVisitor final : public VNVisitor { // Below state needs to be preserved between each module call. AstNodeModule* m_modp = nullptr; // Current module + AstVar* m_varp = nullptr; // Current variable VSymGraph m_mods; // Symbol table of all module names LinkCellsGraph m_graph; // Linked graph of all cell interconnects LibraryVertex* m_libVertexp = nullptr; // Vertex at root of all libraries @@ -248,6 +249,9 @@ class LinkCellsVisitor final : public VNVisitor { pinp->param(true); if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum())); } + // Parser didn't know what was interface, resolve now + // For historical reasons virtual interface reference variables remain VARs + if (m_varp && !nodep->isVirtual()) m_varp->setIfaceRef(); // Note cannot do modport resolution here; modports are allowed underneath generates } @@ -525,6 +529,10 @@ class LinkCellsVisitor final : public VNVisitor { pinp->param(true); if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum())); } + if (m_varp) { // Parser didn't know what was interface, resolve now + const AstNodeModule* const varModp = findModuleSym(nodep->name()); + if (VN_IS(varModp, Iface)) m_varp->setIfaceRef(); + } } void visit(AstClassOrPackageRef* nodep) override { iterateChildren(nodep); @@ -538,6 +546,17 @@ class LinkCellsVisitor final : public VNVisitor { } } + void visit(AstVar* nodep) override { + { + VL_RESTORER(m_varp); + m_varp = nodep; + iterateAndNextNull(nodep->childDTypep()); + } + iterateAndNextNull(nodep->delayp()); + iterateAndNextNull(nodep->valuep()); + iterateAndNextNull(nodep->attrsp()); + } + void visit(AstNode* nodep) override { iterateChildren(nodep); } // METHODS diff --git a/src/verilog.y b/src/verilog.y index 2ce3e4b08..17c249cb3 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1528,12 +1528,14 @@ port: // ==IEEE: port // // Expanded interface_port_header // // We use instantCb here because the non-port form looks just like a module instantiation portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE - { $$ = $3; VARDECL(IFACEREF); VARIO(NONE); + { // VAR for now, but V3LinkCells may call setIfcaeRef on it later + $$ = $3; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, "", *$2}; VARDTYPE(dtp); addNextNull($$, VARDONEP($$, $4, $5)); } | portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE - { $$ = $5; VARDECL(IFACEREF); VARIO(NONE); + { // VAR for now, but V3LinkCells may call setIfcaeRef on it later + $$ = $5; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, $4, "", *$2, *$4}; VARDTYPE(dtp); addNextNull($$, VARDONEP($$, $6, $7)); }