diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 9ecfb4782..228ad6b8b 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -1199,20 +1199,20 @@ public: //###################################################################### // This visitor records classes that are referenced with parameter pins -class ClassPinsMarkVisitor final : public VNVisitorConst { +class ClassRefUnlinkerVisitor final : public VNVisitor { public: - explicit ClassPinsMarkVisitor(AstNetlist* netlistp) { iterateConst(netlistp); } + explicit ClassRefUnlinkerVisitor(AstNetlist* netlistp) { iterate(netlistp); } void visit(AstClassOrPackageRef* nodep) override { if (nodep->paramsp()) { if (AstClass* const classp = VN_CAST(nodep->classOrPackageSkipp(), Class)) { - classp->user3p(classp); + if (!classp->user3p()) VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } } } void visit(AstClass* nodep) override {} // don't iterate inside classes - void visit(AstNode* nodep) override { iterateChildrenConst(nodep); } + void visit(AstNode* nodep) override { iterateChildren(nodep); } }; //###################################################################### @@ -1683,7 +1683,7 @@ public: iterate(netlistp); // Mark classes which cannot be removed because they are still referenced - ClassPinsMarkVisitor markVisitor{netlistp}; + ClassRefUnlinkerVisitor markVisitor{netlistp}; relinkDots(); diff --git a/test_regress/t/t_bug6421.py b/test_regress/t/t_bug6421.py new file mode 100755 index 000000000..6812c4542 --- /dev/null +++ b/test_regress/t/t_bug6421.py @@ -0,0 +1,16 @@ +#!/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_flags=["--binary"]) + +test.passes() diff --git a/test_regress/t/t_bug6421.v b/test_regress/t/t_bug6421.v new file mode 100644 index 000000000..67e747b4c --- /dev/null +++ b/test_regress/t/t_bug6421.v @@ -0,0 +1,38 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +package uvm_pkg; +class uvm_queue #(type T=int); +endclass +class m_uvm_waiter; +endclass +class uvm_config_db#(type T=int); + static local uvm_queue#(m_uvm_waiter) m_waiters[string]; + static function void set(int a, string b, string c, int d); + endfunction +endclass +endpackage +package sfr_agent_pkg; +class sfr_monitor_abstract; +endclass +endpackage: sfr_agent_pkg +module sfr_monitor_bfm #(ADDR_WIDTH = 8, + DATA_WIDTH = 8) + ( + input [ADDR_WIDTH-1:0] address); + import uvm_pkg::*; + import sfr_agent_pkg::*; int SFR_MONITOR; +initial begin + uvm_config_db #(sfr_monitor_abstract)::set(null, "uvm_test_top", "SFR_MONITOR", SFR_MONITOR); +end +endmodule: sfr_monitor_bfm +module hdl_top; +parameter DATA_WIDTH = 32; +parameter ADDR_WIDTH = 32; +sfr_monitor_bfm #(.ADDR_WIDTH(ADDR_WIDTH), + .DATA_WIDTH(DATA_WIDTH)) SFR_MONITOR( + .address(42)); +endmodule