Fix %m in hierarchical models (#8575)

The model of a hierarchical block, or of a --lib-create library, is
named after the %m of its instance in the parent model, but %m within it
also used to include the name of its top module (l2-name within the
partition), adding an extra level per block. %m now matches across
non-hierarchical, --hierarchical and manual --lib-create builds.

before: top.t.u_sub.sub.u_leaf.leaf
after:  top.t.u_sub.u_leaf
This commit is contained in:
Geza Lore
2026-10-02 14:20:41 +01:00
committed by GitHub
parent 93e9660ea5
commit e4cc6cadca
5 changed files with 135 additions and 2 deletions
+13 -1
View File
@@ -57,6 +57,8 @@ class ScopeVisitor final : public VNVisitor {
AstCell* m_aboveCellp = nullptr; // Cell that instantiates this module
AstScope* m_aboveScopep = nullptr; // Scope that instantiates this scope
bool m_last = false; // Scoping the last instantiation of the current module
// The name length of the scope of the library top module instance, while within it
size_t m_libTopNameLen = 0;
std::unordered_map<AstNodeModule*, AstScope*>
m_classOrPackageScopes; // Scopes for each class or package
@@ -136,12 +138,18 @@ class ScopeVisitor final : public VNVisitor {
cleanupVarRefs();
}
void visit(AstNodeModule* nodep) override {
VL_RESTORER(m_libTopNameLen);
// Create required blocks and add to module
string scopename;
if (!m_aboveScopep) {
scopename = "TOP";
} else {
scopename = m_aboveScopep->name() + "." + m_aboveCellp->name();
// The top module is the only module directly under 'TOP'
if (!v3Global.opt.libCreate().empty() && m_aboveScopep->isTop()
&& VN_IS(nodep, Module)) {
m_libTopNameLen = scopename.size();
}
}
UINFO(4, " MOD AT " << scopename << " " << nodep);
@@ -318,7 +326,11 @@ class ScopeVisitor final : public VNVisitor {
}
void visit(AstScopeName* nodep) override {
// If there's a %m in the display text, we add a special node that will contain the name()
const string prefix = "__DOT__"s + m_scopep->name();
std::string scopeName = m_scopep->name();
// Drop the "l2-name" (name of the top module) for library builds, otherwise
// would get "top.u_lib.lib.foo" instead of correct hierarchical path "top.u_lib.foo"
if (m_libTopNameLen) scopeName = "TOP" + scopeName.substr(m_libTopNameLen);
const string prefix = "__DOT__"s + scopeName;
// TOP and above will be the user's name().
// Note 'TOP.' is stripped by scopePrettyName
// To keep correct visual order, must add before existing