diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index c0eb2912c..865086b72 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1344,9 +1344,13 @@ class LinkDotFindVisitor final : public VNVisitor { iterateChildren(nodep); nodep->user2(false); nodep->user4(true); - // Interfaces need another pass when signals are resolved - if (AstIface* const ifacep = VN_CAST(nodep, Iface)) { - m_statep->insertIfaceModSym(ifacep, m_curSymp); + // Interfaces need another pass when signals are resolved. When creating + // scopes this is done from the AstScopes in LinkDotScopeVisitor instead, as + // only those entries hold the AstVarScopes the modport items resolve against. + if (!m_statep->forScopeCreation()) { + if (AstIface* const ifacep = VN_CAST(nodep, Iface)) { + m_statep->insertIfaceModSym(ifacep, m_curSymp); + } } } else if (isHierBlockWrapper(nodep->name())) { UINFO(5, "Module is hierarchical block, must not be dead: " << nodep); @@ -2684,6 +2688,11 @@ private: VL_RESTORER(m_modSymp); VL_RESTORER(m_scopep); m_modSymp = m_statep->getScopeSym(nodep); + // Interfaces need another pass when signals are resolved. Register the scope's + // entry, as that is the one holding the AstVarScopes. + if (AstIface* const ifacep = VN_CAST(nodep->modp(), Iface)) { + m_statep->insertIfaceModSym(ifacep, m_modSymp); + } m_scopep = nodep; iterateChildren(nodep); } diff --git a/test_regress/t/t_hier_block_no_inline.py b/test_regress/t/t_hier_block_no_inline.py new file mode 100755 index 000000000..8de73c51a --- /dev/null +++ b/test_regress/t/t_hier_block_no_inline.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.priority(30) +test.scenarios('vlt') +test.top_filename = "t/t_hier_block.v" + +# Compilation of hierarchical blocks is skipped if their libs exist +test.clean_objs() + +test.compile(v_flags2=['t/t_hier_block.cpp'], + verilator_flags2=['-fno-inline', '--hierarchical', '--Wno-TIMESCALEMOD']) + +test.execute() + +test.passes()