From 24918b83be7df2ae6f9242d223849e23fa35acef Mon Sep 17 00:00:00 2001 From: Nick Brereton <85175726+nbstrike@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:25:40 -0400 Subject: [PATCH] Fix typedef scope resolution for parameterized class aliases (#5977) (#7319) --- src/V3LinkDot.cpp | 6 +++ test_regress/t/t_class_param_typedef8.py | 18 +++++++++ test_regress/t/t_class_param_typedef8.v | 48 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100755 test_regress/t/t_class_param_typedef8.py create mode 100644 test_regress/t/t_class_param_typedef8.v diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 9a39a4afd..7fee470a9 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -5799,6 +5799,12 @@ class LinkDotResolveVisitor final : public VNVisitor { iterate(cpackagep); return; } + // Defer non-typedef references through typedef aliases of parameterized classes. + if (m_statep->forPrimary() && !VN_IS(nodep->backp(), Typedef) + && isParamedClassRef(cpackagerefp)) { + iterate(cpackagep); + return; + } if (!cpackagerefp->classOrPackageSkipp()) { VSymEnt* const foundp = m_statep->resolveClassOrPackage( m_ds.m_dotSymp, cpackagerefp, true, false, "class/package reference"); diff --git a/test_regress/t/t_class_param_typedef8.py b/test_regress/t/t_class_param_typedef8.py new file mode 100755 index 000000000..6fe7d000c --- /dev/null +++ b/test_regress/t/t_class_param_typedef8.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('simulator') + +test.compile(verilator_flags2=["--binary"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_class_param_typedef8.v b/test_regress/t/t_class_param_typedef8.v new file mode 100644 index 000000000..0d0827ff1 --- /dev/null +++ b/test_regress/t/t_class_param_typedef8.v @@ -0,0 +1,48 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// 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 + +// issue #5977: class-scoped typedef in parameterized class should resolve when +// referenced through a module typedef alias. + +package axi_test; + class axi_ax_beat #( + parameter AW = 32, + parameter IW = 8, + parameter UW = 1 + ); + rand logic [IW-1:0] ax_id = '0; + rand logic [AW-1:0] ax_addr = '0; + rand logic [UW-1:0] ax_user = '0; + endclass + + class axi_driver #( + parameter int AW = 32, + parameter int IW = 8, + parameter int UW = 1 + ); + typedef axi_ax_beat #(.AW(AW), .IW(IW), .UW(UW)) ax_beat_t; + endclass +endpackage + +module t; + typedef axi_test::axi_driver #( + .AW(64), .IW(6), .UW(2) + ) drv_t; + + initial begin + automatic drv_t::ax_beat_t aw_beat = new; + automatic drv_t::ax_beat_t ar_beat = new; + + aw_beat.ax_addr = 64'h1234; + ar_beat.ax_addr = aw_beat.ax_addr + 64'd1; + if (ar_beat.ax_addr != 64'h1235) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule