diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index 95bd05954..917123be6 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -477,7 +477,13 @@ class SplitUnpackedVarVisitor final : public VNVisitor, public SplitVarImpl { UINFO(4, "Start checking " << nodep->prettyNameQ()); if (!VN_IS(nodep, Module)) { UINFO(4, "Skip " << nodep->prettyNameQ()); - nodep->foreach([this](AstVarXRef* const nodep) { handleVarXRef(nodep); }); + nodep->foreach([this](AstNodeVarRef* const nodep) { + if (AstVarXRef* const varXRefp = VN_CAST(nodep, VarXRef)) { + handleVarXRef(varXRefp); + } else if (m_modp) { + iterate(VN_AS(nodep, VarRef)); + } + }); return; } UASSERT_OBJ(!m_modp, m_modp, "Nested module declaration"); diff --git a/test_regress/t/t_class_nested_split_var.py b/test_regress/t/t_class_nested_split_var.py new file mode 100755 index 000000000..c87a1e49f --- /dev/null +++ b/test_regress/t/t_class_nested_split_var.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# 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-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=["--binary"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_class_nested_split_var.v b/test_regress/t/t_class_nested_split_var.v new file mode 100644 index 000000000..c4124f775 --- /dev/null +++ b/test_regress/t/t_class_nested_split_var.v @@ -0,0 +1,40 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain +// SPDX-FileCopyrightText: 2026 Antmicro +// SPDX-License-Identifier: CC0-1.0 + +`ifdef VERILATOR +// The '$c(1)' is there to prevent inlining of the signal by V3Gate. +`define IMPURE_ONE ($c(1)) +`else +// Use standard $random. The chance of getting 2 consecutive zeroes is negligible. +`define IMPURE_ONE (|($random | $random)) +`endif + +module t; + bit [2:0] y; + bit [2:0] z; + assign z[0] = 1'b1; + assign z[1] = !(y[0]); + assign z[2] = !(|y[1:0]); + class Foo; + bit foo; + + task run(); + foo = `IMPURE_ONE; + if (z !== 3'b001) begin + $error("Failed: got %0b, expected %0b", z, 3'b001); + end + if (foo != 1'b1) $stop; + endtask + endclass + Foo test; + initial begin + static Foo foo = new; + #10 y = 3'b111; + #1 foo.run(); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule