From 2e4fb380e1b3401c0d9b80c43766cfc921d3a59e Mon Sep 17 00:00:00 2001 From: wsxarcher Date: Tue, 24 Mar 2026 00:20:42 +0100 Subject: [PATCH] Error compile time --- src/V3Dumpvars.h | 4 +--- src/V3EmitCFunc.h | 13 +------------ src/V3LinkDot.cpp | 15 ++++++++++++--- test_regress/t/t_trace_dumpvars_cpptop.v | 2 +- test_regress/t/t_trace_dumpvars_cpptop2.out | 7 +++++-- test_regress/t/t_trace_dumpvars_cpptop2.py | 6 +++--- test_regress/t/t_trace_dumpvars_missing_scope.out | 7 +++++-- test_regress/t/t_trace_dumpvars_missing_scope.py | 5 ++--- 8 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/V3Dumpvars.h b/src/V3Dumpvars.h index 58b200369..29c7eaf41 100644 --- a/src/V3Dumpvars.h +++ b/src/V3Dumpvars.h @@ -22,10 +22,9 @@ // Tagged $dumpvars target string. During compile-time resolution in V3LinkDot // each target is tagged with a prefix that tells EmitC how to emit the -// corresponding runtime code. The three tag types are: +// corresponding runtime code. The tag types are: // Resolved – fully resolved to a compile-time hierarchy path // RuntimeRoot – first component must match the C++ wrapper root name at runtime -// Missing – proven invalid at compile time; emit VL_FATAL_MT at runtime struct DumpvarsTag final { const char* const prefix; const size_t prefixLen; @@ -42,6 +41,5 @@ struct DumpvarsTag final { constexpr DumpvarsTag kDumpvarsResolved{"@dumpvars:"}; constexpr DumpvarsTag kDumpvarsRuntimeRoot{"@dumpvars_root:"}; -constexpr DumpvarsTag kDumpvarsMissing{"@dumpvars_missing:"}; #endif // Guard diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 0a6d0bd07..f035a867f 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -951,15 +951,6 @@ public: puts(levelExpr); puts(", __vlDvHier); }\n"); } - void emitDumpVarsTargetMissing(const AstDumpCtl* nodep, const string& target) { - putns(nodep, "VL_FATAL_MT(\""); - puts(V3OutFormatter::quoteNameControls(protect(nodep->fileline()->filename()))); - puts("\", "); - puts(cvtToStr(nodep->fileline()->lineno())); - puts(", \"\", \"$dumpvars target not found: "); - puts(V3OutFormatter::quoteNameControls(target)); - puts("\");\n"); - } // Emit $dumpvars filter logic when scope info is available. void emitDumpVarsWithScope(AstDumpCtl* nodep) { UASSERT_OBJ(nodep->scopeNamep(), nodep, "$dumpvars missing AstScopeName"); @@ -981,9 +972,7 @@ public: if (nodep->targetsp()) { for (AstNode* tp = nodep->targetsp(); tp; tp = tp->nextp()) { const string target = VN_AS(tp, Text)->text(); - if (kDumpvarsMissing.matches(target)) { - emitDumpVarsTargetMissing(nodep, kDumpvarsMissing.strip(target)); - } else if (kDumpvarsRuntimeRoot.matches(target)) { + if (kDumpvarsRuntimeRoot.matches(target)) { emitDumpVarsAddRuntimeRoot(nodep, kDumpvarsRuntimeRoot.strip(target), levelExpr); } else { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 281c289d2..200cf76da 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -3272,11 +3272,19 @@ class LinkDotResolveVisitor final : public VNVisitor { if (!resolved.empty()) return kDumpvarsResolved.make(resolved); } - // Step 3: Single-component name — defer to runtime root matching. + // Step 3: Single-component name — defer to runtime root matching + // unless Verilator generates the main (--main/--binary), in which case + // the root name is known at compile time and we can reject mismatches. const string::size_type dotPos = target.find('.'); const string firstComp = (dotPos != string::npos) ? target.substr(0, dotPos) : target; - if (dotPos == string::npos) return kDumpvarsRuntimeRoot.make(target); + if (dotPos == string::npos) { + if (v3Global.opt.main()) { + fl->v3error("$dumpvars target not found: " << target); + return target; + } + return kDumpvarsRuntimeRoot.make(target); + } // Step 4: Multi-component "X.y.z" where X might be the runtime root. const string remaining = target.substr(dotPos + 1); @@ -3287,7 +3295,8 @@ class LinkDotResolveVisitor final : public VNVisitor { runtimeMatchSymp, true)) { return kDumpvarsRuntimeRoot.make(target); } - return kDumpvarsMissing.make(target); + fl->v3error("$dumpvars target not found: " << target); + return target; } UINFO(5, "$dumpvars target '" << target << "' not found in hierarchy" << endl); diff --git a/test_regress/t/t_trace_dumpvars_cpptop.v b/test_regress/t/t_trace_dumpvars_cpptop.v index 36d6717b4..42a8df11c 100644 --- a/test_regress/t/t_trace_dumpvars_cpptop.v +++ b/test_regress/t/t_trace_dumpvars_cpptop.v @@ -25,7 +25,7 @@ module t( initial begin $dumpfile(`STRINGIFY(`TEST_DUMPFILE)); // cpptop is defined in the C++ testbench as the root of the trace hierarchy, so $dumpvars(0, cpptop) should dump everything. - $dumpvars(0, cpptop); + $dumpvars(0, cpptop, cpptop.t); end endmodule diff --git a/test_regress/t/t_trace_dumpvars_cpptop2.out b/test_regress/t/t_trace_dumpvars_cpptop2.out index a7c3702fa..7660a7232 100644 --- a/test_regress/t/t_trace_dumpvars_cpptop2.out +++ b/test_regress/t/t_trace_dumpvars_cpptop2.out @@ -1,2 +1,5 @@ -%Error: t/t_trace_dumpvars_cpptop2.v:27: $dumpvars target not found: cpptop.notfound -Aborting... +%Error: t/t_trace_dumpvars_cpptop2.v:27:5: $dumpvars target not found: cpptop.notfound + 27 | $dumpvars(0, cpptop, cpptop.notfound); + | ^~~~~~~~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: Exiting due to diff --git a/test_regress/t/t_trace_dumpvars_cpptop2.py b/test_regress/t/t_trace_dumpvars_cpptop2.py index 01cc8352d..eab934d19 100644 --- a/test_regress/t/t_trace_dumpvars_cpptop2.py +++ b/test_regress/t/t_trace_dumpvars_cpptop2.py @@ -12,14 +12,14 @@ import vltest_bootstrap test.scenarios('vlt') test.compile( + fails=True, make_main=False, verilator_flags2=[ '--cc', '--exe', '--trace-vcd', 't/t_trace_dumpvars_cpptop.cpp', - ]) - -test.execute(fails=True, expect_filename=test.golden_filename) + ], + expect_filename=test.golden_filename) test.passes() diff --git a/test_regress/t/t_trace_dumpvars_missing_scope.out b/test_regress/t/t_trace_dumpvars_missing_scope.out index 52442ede3..7272e6db5 100644 --- a/test_regress/t/t_trace_dumpvars_missing_scope.out +++ b/test_regress/t/t_trace_dumpvars_missing_scope.out @@ -1,2 +1,5 @@ -%Error: t/t_trace_dumpvars_missing_scope.v:28: $dumpvars target not found: missing_module -Aborting... +%Error: t/t_trace_dumpvars_missing_scope.v:28:5: $dumpvars target not found: missing_module + 28 | $dumpvars(0, missing_module); + | ^~~~~~~~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: Exiting due to diff --git a/test_regress/t/t_trace_dumpvars_missing_scope.py b/test_regress/t/t_trace_dumpvars_missing_scope.py index 84fe07456..c834b7d2a 100644 --- a/test_regress/t/t_trace_dumpvars_missing_scope.py +++ b/test_regress/t/t_trace_dumpvars_missing_scope.py @@ -11,8 +11,7 @@ import vltest_bootstrap test.scenarios('vlt') -test.compile(verilator_flags2=['--binary --trace-vcd']) - -test.execute(fails=True, expect_filename=test.golden_filename) +test.compile(fails=True, verilator_flags2=['--binary --trace-vcd'], + expect_filename=test.golden_filename) test.passes()