From bbcb9315f329724e159d232d4a89f8d16c98c6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Fri, 19 Sep 2025 15:44:34 +0200 Subject: [PATCH] Fix loss of clock attribute in Dfg variable removal (#6453) --- src/V3DfgOptimizer.cpp | 2 +- src/V3DfgRegularize.cpp | 6 ++-- test_regress/t/t_dfg_regularize_clk.py | 18 ++++++++++ test_regress/t/t_dfg_regularize_clk.v | 48 ++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_dfg_regularize_clk.py create mode 100644 test_regress/t/t_dfg_regularize_clk.v diff --git a/src/V3DfgOptimizer.cpp b/src/V3DfgOptimizer.cpp index 7dfb6a543..1df67ad7f 100644 --- a/src/V3DfgOptimizer.cpp +++ b/src/V3DfgOptimizer.cpp @@ -255,7 +255,7 @@ class DataflowOptimize final { static void markExternallyReferencedVariables(AstNetlist* netlistp, bool scoped) { netlistp->foreach([scoped](AstNode* nodep) { - // Check variabel flags + // Check variable flags if (scoped) { if (AstVarScope* const vscp = VN_CAST(nodep, VarScope)) { const AstVar* const varp = vscp->varp(); diff --git a/src/V3DfgRegularize.cpp b/src/V3DfgRegularize.cpp index 9853f2bbe..75995eee1 100644 --- a/src/V3DfgRegularize.cpp +++ b/src/V3DfgRegularize.cpp @@ -79,7 +79,7 @@ class DfgRegularize final { } // Given a variable and its driver, return true iff the variable can be - // repalced with its driver. Record replacement to be applied in the Ast + // replaced with its driver. Record replacement to be applied in the Ast // in user2p of the replaced variable. bool replaceable(DfgVertexVar* varp, DfgVertex* srcp) { // The given variable has no external references, and is read in the module @@ -92,8 +92,10 @@ class DfgRegularize final { if (const DfgVarPacked* const drvp = srcp->cast()) { // Record replacement nodep->user2p(drvp->nodep()); - // The repalcement will be read in the module, mark as such so it doesn't get removed. + // The replacement will be read in the module, mark as such so it doesn't get removed. drvp->setHasModRdRefs(); + drvp->varp()->propagateAttrFrom(varp->varp()); + if (varp->varp()->isUsedClock()) drvp->varp()->usedClock(true); return true; } diff --git a/test_regress/t/t_dfg_regularize_clk.py b/test_regress/t/t_dfg_regularize_clk.py new file mode 100755 index 000000000..4ee18ef12 --- /dev/null +++ b/test_regress/t/t_dfg_regularize_clk.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=["--hierarchical", "--trace"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_dfg_regularize_clk.v b/test_regress/t/t_dfg_regularize_clk.v new file mode 100644 index 000000000..ed833c7c2 --- /dev/null +++ b/test_regress/t/t_dfg_regularize_clk.v @@ -0,0 +1,48 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkd(gotv, + expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +module sub ( + input clk, + input b +); /*verilator hier_block*/ + reg tmp_clk; + assign tmp_clk = clk; + + always @(posedge tmp_clk) begin + $display("[%0t] triggered by clk", $time); + end + + int count = 0; + always @(b) begin +`ifdef TEST_VERBOSE + $display("[%0t] triggered by b", $time); +`endif + ++count; + end + final `checkd(count, 2); +endmodule + +module t ( /*AUTOARG*/ + // Inputs + clk +); + input clk; + logic b = 1; + + sub sub (.*); + + int cyc = 0; + always @(posedge clk) begin + cyc <= cyc + 1; + if (cyc >= 2) begin + $finish; + end + end +endmodule