Internals: Identify $unit package by netlist pointer

This commit is contained in:
Geza Lore
2026-09-26 07:48:56 +01:00
parent 435af6afe6
commit 33d63ac0b0
6 changed files with 8 additions and 10 deletions
+2
View File
@@ -149,6 +149,8 @@ bool AstActive::hasCombo() const { return m_sentreep->hasCombo(); }
bool AstActive::hasInitial() const { return m_sentreep->hasInitial(); }
bool AstActive::hasStatic() const { return m_sentreep->hasStatic(); }
bool AstNodeModule::isDollarUnit() const { return this == v3Global.rootp()->dollarUnitPkgp(); }
AstAlways::AstAlways(AstAssignW* assignp)
: ASTGEN_SUPER_Always(assignp->fileline(), assignp)
, m_keyword{VAlwaysKwd::CONT_ASSIGN} {}
+1 -2
View File
@@ -358,6 +358,7 @@ public:
bool maybePointedTo() const override VL_MT_SAFE { return true; }
string name() const override VL_MT_STABLE { return m_name; }
virtual bool timescaleMatters() const = 0;
inline bool isDollarUnit() const; // Is the $unit package
// ACCESSORS
void name(const string& name) override { m_name = name; }
string origName() const override { return m_origName; }
@@ -3231,8 +3232,6 @@ public:
ASTGEN_MEMBERS_AstPackage;
string verilogKwd() const override { return "package"; }
bool timescaleMatters() const override { return !isDollarUnit(); }
static string dollarUnitName() { return AstNode::encodeName("$unit"); }
bool isDollarUnit() const { return name() == dollarUnitName(); }
};
class AstPrimitive final : public AstNodeModule {
// A primitive declaration
+1 -1
View File
@@ -1918,7 +1918,7 @@ AstNetlist::AstNetlist()
: ASTGEN_SUPER_Netlist(new FileLine{FileLine::builtInFilename()})
, m_typeTablep{new AstTypeTable{fileline()}}
, m_constPoolp{new AstConstPool{fileline()}}
, m_dollarUnitPkgp{new AstPackage{fileline(), AstPackage::dollarUnitName(), "work"}} {
, m_dollarUnitPkgp{new AstPackage{fileline(), AstNode::encodeName("$unit"), "work"}} {
addMiscsp(m_typeTablep);
addMiscsp(m_constPoolp);
// packages are always libraries; don't want to make them a "top"
+2 -4
View File
@@ -670,7 +670,7 @@ class DeadVisitor final : public VNVisitor {
nextmodp = VN_AS(modp->nextp(), NodeModule);
// Keep $unit until m_elimCells stages. Note v3Global.opt.serializeOnly()
// won't reach this stage, and will always have an empty $unit. That's ok.
const bool keep = !m_elimCells && modp == v3Global.rootp()->dollarUnitPkgp();
const bool keep = !m_elimCells && modp->isDollarUnit();
if (modp->dead() || (!modp->isTop() && modp->user1() == 0 && !keep)) {
// > 2 because L1 is the wrapper, L2 is the top user module
UINFO(4, " Dead module " << modp);
@@ -681,9 +681,7 @@ class DeadVisitor final : public VNVisitor {
cellp->modp()->user1Inc(-1);
});
}
if (modp == v3Global.rootp()->dollarUnitPkgp()) {
v3Global.rootp()->dollarUnitPkgp(nullptr);
}
if (modp->isDollarUnit()) v3Global.rootp()->dollarUnitPkgp(nullptr);
deleting(modp);
retry = true;
}
+1 -1
View File
@@ -469,7 +469,7 @@ class LinkCellsVisitor final : public VNVisitor {
if (nodep->fileline()->filebasenameNoExt() != nodep->prettyName()
&& !v3Global.opt.isLibraryFile(nodep->fileline()->filename(), nodep->libname())
&& !VN_IS(nodep, NotFoundModule) && !nodep->recursiveClone()
&& nodep != v3Global.rootp()->dollarUnitPkgp() && m_modDepth == 1) {
&& !nodep->isDollarUnit() && m_modDepth == 1) {
// We only complain once per file, otherwise library-like files
// have a huge mess of warnings
const auto itFoundPair = m_declfnWarned.insert(nodep->fileline()->filename());
+1 -2
View File
@@ -1220,8 +1220,7 @@ class LinkDotFindVisitor final : public VNVisitor {
AstNodeModule* const modulesp = nodep->modulesp();
UASSERT_OBJ(modulesp, nodep, "$unit should always be in the netlist");
if (!modulesp->nextp()) {
UASSERT_OBJ(modulesp == v3Global.rootp()->dollarUnitPkgp(), modulesp,
"Sole module should be $unit");
UASSERT_OBJ(modulesp->isDollarUnit(), modulesp, "Sole module should be $unit");
if (!modulesp->stmtsp()) nodep->v3error("No top level module found");
}
for (AstNodeModule* modp = nodep->modulesp(); modp && modp->isTop();