From 7182e8d937e6b705f92ab6a9ff99f062bdea6614 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 17 Feb 2026 02:05:05 -0500 Subject: [PATCH] Internals: Track what variables get user initial assignment. --- src/V3AstNodeOther.h | 4 ++++ src/V3AstNodes.cpp | 2 ++ src/V3LinkParse.cpp | 2 ++ src/V3Undriven.cpp | 5 ++++- test_regress/t/t_json_only_debugcheck.out | 2 +- test_regress/t/t_json_only_first.out | 4 ++-- test_regress/t/t_json_only_flat.out | 4 ++-- 7 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index f76b9edde..932aedaa9 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1914,6 +1914,7 @@ class AstVar final : public AstNode { bool m_isConst : 1; // Table contains constant data bool m_isContinuously : 1; // Ever assigned continuously (for force/release) bool m_hasStrengthAssignment : 1; // Is on LHS of assignment with strength specifier + bool m_hasUserInit : 1; // Has initial assignment by user at parse time bool m_isStatic : 1; // Static C variable (for Verilog see instead lifetime()) bool m_isPulldown : 1; // Tri0 bool m_isPullup : 1; // Tri1 @@ -1967,6 +1968,7 @@ class AstVar final : public AstNode { m_isConst = false; m_isContinuously = false; m_hasStrengthAssignment = false; + m_hasUserInit = false; m_isStatic = false; m_isPulldown = false; m_isPullup = false; @@ -2126,6 +2128,8 @@ public: void gotNansiType(bool flag) { m_gotNansiType = flag; } bool hasStrengthAssignment() const { return m_hasStrengthAssignment; } void hasStrengthAssignment(bool flag) { m_hasStrengthAssignment = flag; } + bool hasUserInit() const { return m_hasUserInit; } + void hasUserInit(bool flag) { m_hasUserInit = flag; } bool isDpiOpenArray() const VL_MT_SAFE { return m_isDpiOpenArray; } void isDpiOpenArray(bool flag) { m_isDpiOpenArray = flag; } bool isHideLocal() const { return m_isHideLocal; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index da424cfa8..353e18d9b 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2859,6 +2859,7 @@ void AstVar::dump(std::ostream& str) const { } else if (isFuncLocal()) { str << " [FUNC]"; } + if (hasUserInit()) str << " [UINIT]"; if (isDpiOpenArray()) str << " [DPIOPENA]"; if (ignorePostWrite()) str << " [IGNPWR]"; if (ignoreSchedWrite()) str << " [IGNWR]"; @@ -2896,6 +2897,7 @@ void AstVar::dumpJson(std::ostream& str) const { dumpJsonBoolFuncIf(str, isParam); dumpJsonBoolFuncIf(str, attrScBv); dumpJsonBoolFuncIf(str, attrSFormat); + dumpJsonBoolFuncIf(str, hasUserInit); dumpJsonBoolFuncIf(str, ignorePostWrite); dumpJsonBoolFuncIf(str, ignoreSchedWrite); dumpJsonGen(str); diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index e16758430..d79275375 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -317,6 +317,8 @@ class LinkParseVisitor final : public VNVisitor { void visit(AstVar* nodep) override { cleanFileline(nodep); + UINFO(9, "VAR " << nodep); + if (nodep->valuep()) nodep->hasUserInit(true); if (nodep->lifetime().isStatic() && m_insideLoop && nodep->valuep()) { nodep->lifetime(VLifetime::AUTOMATIC_IMPLICIT); nodep->v3warn(STATICVAR, "Static variable with assignment declaration declared in a " diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index d9a7a31e7..9074d7140 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -185,7 +185,8 @@ public: // Combine bits into overall state AstVar* const nodep = m_varp; - if (initStaticp() && procWritep() && !nodep->isClassMember() && !nodep->isFuncLocal()) { + if (initStaticp() && procWritep() && nodep->hasUserInit() && !nodep->isClassMember() + && !nodep->isFuncLocal()) { initStaticp()->v3warn( PROCASSINIT, "Procedural assignment to declaration with initial value: " @@ -536,6 +537,8 @@ class UndrivenVisitor final : public VNVisitorConst { void visit(AstAssign* nodep) override { VL_RESTORER(m_inProcAssign); m_inProcAssign = true; + // Don't count default initialization as a driver to a net/variable + if (VN_IS(nodep->rhsp(), CReset)) return; iterateChildrenConst(nodep); } void visit(AstAssignDly* nodep) override { diff --git a/test_regress/t/t_json_only_debugcheck.out b/test_regress/t/t_json_only_debugcheck.out index e92e99bb6..f4d5c9b74 100644 --- a/test_regress/t/t_json_only_debugcheck.out +++ b/test_regress/t/t_json_only_debugcheck.out @@ -7,7 +7,7 @@ {"type":"VAR","name":"__Vtrigprevexpr___TOP__clk__0","addr":"(N)","loc":"d,11:8,11:9","dtypep":"(K)","origName":"__Vtrigprevexpr___TOP__clk__0","verilogName":"__Vtrigprevexpr___TOP__clk__0","direction":"NONE","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"__VactPhaseResult","addr":"(O)","loc":"d,11:8,11:9","dtypep":"(P)","origName":"__VactPhaseResult","verilogName":"__VactPhaseResult","direction":"NONE","noReset":true,"lifetime":"NONE","varType":"MODULETEMP","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"__VnbaPhaseResult","addr":"(Q)","loc":"d,11:8,11:9","dtypep":"(P)","origName":"__VnbaPhaseResult","verilogName":"__VnbaPhaseResult","direction":"NONE","noReset":true,"lifetime":"NONE","varType":"MODULETEMP","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.cyc","addr":"(R)","loc":"d,23:17,23:20","dtypep":"(S)","origName":"cyc","verilogName":"cyc","direction":"NONE","lifetime":"VSTATICI","varType":"VAR","dtypeName":"integer","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.cyc","addr":"(R)","loc":"d,23:17,23:20","dtypep":"(S)","origName":"cyc","verilogName":"cyc","direction":"NONE","lifetime":"VSTATICI","varType":"VAR","dtypeName":"integer","hasUserInit":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"__VactIterCount","addr":"(T)","loc":"d,11:8,11:9","dtypep":"(U)","origName":"__VactIterCount","verilogName":"__VactIterCount","direction":"NONE","noReset":true,"lifetime":"NONE","varType":"MODULETEMP","dtypeName":"bit","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"__VactTriggered","addr":"(V)","loc":"d,11:8,11:9","dtypep":"(W)","origName":"__VactTriggered","verilogName":"__VactTriggered","direction":"NONE","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"__VnbaTriggered","addr":"(X)","loc":"d,11:8,11:9","dtypep":"(W)","origName":"__VnbaTriggered","verilogName":"__VnbaTriggered","direction":"NONE","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, diff --git a/test_regress/t/t_json_only_first.out b/test_regress/t/t_json_only_first.out index 5a517d865..9fc577f6f 100644 --- a/test_regress/t/t_json_only_first.out +++ b/test_regress/t/t_json_only_first.out @@ -55,14 +55,14 @@ ]}, {"type":"MODULE","name":"mod1__W4","addr":"(M)","loc":"d,31:8,31:12","origName":"mod1","verilogName":"mod1","level":2,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"WIDTH","addr":"(LB)","loc":"d,32:15,32:20","dtypep":"(MB)","origName":"WIDTH","verilogName":"WIDTH","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"GPARAM","dtypeName":"logic","isGParam":true,"isParam":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], + {"type":"VAR","name":"WIDTH","addr":"(LB)","loc":"d,32:15,32:20","dtypep":"(MB)","origName":"WIDTH","verilogName":"WIDTH","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"GPARAM","dtypeName":"logic","isGParam":true,"isParam":true,"hasUserInit":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], "valuep": [ {"type":"CONST","name":"32'sh4","addr":"(NB)","loc":"d,19:18,19:19","dtypep":"(MB)"} ],"attrsp": []}, {"type":"VAR","name":"clk","addr":"(R)","loc":"d,34:24,34:27","dtypep":"(I)","origName":"clk","verilogName":"clk","direction":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"d","addr":"(U)","loc":"d,35:30,35:31","dtypep":"(G)","origName":"d","verilogName":"d","direction":"INPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"q","addr":"(O)","loc":"d,36:30,36:31","dtypep":"(G)","origName":"q","verilogName":"q","direction":"OUTPUT","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"IGNORED","addr":"(OB)","loc":"d,39:15,39:22","dtypep":"(MB)","origName":"IGNORED","verilogName":"IGNORED","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], + {"type":"VAR","name":"IGNORED","addr":"(OB)","loc":"d,39:15,39:22","dtypep":"(MB)","origName":"IGNORED","verilogName":"IGNORED","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], "valuep": [ {"type":"CONST","name":"32'sh1","addr":"(PB)","loc":"d,39:25,39:26","dtypep":"(MB)"} ],"attrsp": []}, diff --git a/test_regress/t/t_json_only_flat.out b/test_regress/t/t_json_only_flat.out index 6934916c5..2bf01765b 100644 --- a/test_regress/t/t_json_only_flat.out +++ b/test_regress/t/t_json_only_flat.out @@ -9,14 +9,14 @@ {"type":"VAR","name":"t.clk","addr":"(M)","loc":"d,13:10,13:13","dtypep":"(J)","origName":"clk","verilogName":"clk","direction":"NONE","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.d","addr":"(N)","loc":"d,14:16,14:17","dtypep":"(H)","origName":"d","verilogName":"d","direction":"NONE","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.between","addr":"(O)","loc":"d,17:22,17:29","dtypep":"(H)","origName":"between","verilogName":"between","direction":"NONE","lifetime":"VSTATICI","varType":"VAR","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.cell1.WIDTH","addr":"(P)","loc":"d,32:15,32:20","dtypep":"(Q)","origName":"WIDTH","verilogName":"WIDTH","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"GPARAM","dtypeName":"logic","isGParam":true,"isParam":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], + {"type":"VAR","name":"t.cell1.WIDTH","addr":"(P)","loc":"d,32:15,32:20","dtypep":"(Q)","origName":"WIDTH","verilogName":"WIDTH","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"GPARAM","dtypeName":"logic","isGParam":true,"isParam":true,"hasUserInit":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], "valuep": [ {"type":"CONST","name":"32'sh4","addr":"(R)","loc":"d,19:18,19:19","dtypep":"(Q)"} ],"attrsp": []}, {"type":"VAR","name":"t.cell1.clk","addr":"(S)","loc":"d,34:24,34:27","dtypep":"(J)","origName":"clk","verilogName":"clk","direction":"NONE","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.cell1.d","addr":"(T)","loc":"d,35:30,35:31","dtypep":"(H)","origName":"d","verilogName":"d","direction":"NONE","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.cell1.q","addr":"(U)","loc":"d,36:30,36:31","dtypep":"(H)","origName":"q","verilogName":"q","direction":"NONE","lifetime":"VSTATICI","varType":"PORT","dtypeName":"logic","sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.cell1.IGNORED","addr":"(V)","loc":"d,39:15,39:22","dtypep":"(Q)","origName":"IGNORED","verilogName":"IGNORED","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], + {"type":"VAR","name":"t.cell1.IGNORED","addr":"(V)","loc":"d,39:15,39:22","dtypep":"(Q)","origName":"IGNORED","verilogName":"IGNORED","direction":"NONE","isConst":true,"lifetime":"VSTATICI","varType":"LPARAM","dtypeName":"logic","isParam":true,"hasUserInit":true,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], "valuep": [ {"type":"CONST","name":"32'sh1","addr":"(W)","loc":"d,39:25,39:26","dtypep":"(Q)"} ],"attrsp": []},