From 53c59e7ac78a2b5f925cbf2b550ab28711c8c954 Mon Sep 17 00:00:00 2001 From: Artur Bieniek Date: Mon, 18 Aug 2025 14:51:25 +0200 Subject: [PATCH] Fix referencing module variables above classes (#6304) Signed-off-by: Artur Bieniek --- src/V3Scope.cpp | 15 ++++++++++--- test_regress/t/t_class_modscope.py | 18 ++++++++++++++++ test_regress/t/t_class_modscope.v | 34 ++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_class_modscope.py create mode 100644 test_regress/t/t_class_modscope.v diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index cc89adb07..ea29b1fa2 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -68,9 +68,18 @@ class ScopeVisitor final : public VNVisitor { UASSERT_OBJ(it2 != m_packageScopes.end(), nodep, "Can't locate package scope"); scopep = it2->second; } - const auto it3 = m_varScopes.find(std::make_pair(nodep->varp(), scopep)); - UASSERT_OBJ(it3 != m_varScopes.end(), nodep, "Can't locate varref scope"); - AstVarScope* const varscp = it3->second; + // Search up the scope hierarchy for the variable + AstVarScope* varscp = nullptr; + AstScope* searchScopep = scopep; + while (searchScopep) { + const auto it3 = m_varScopes.find(std::make_pair(nodep->varp(), searchScopep)); + if (it3 != m_varScopes.end()) { + varscp = it3->second; + break; + } + searchScopep = searchScopep->aboveScopep(); + } + UASSERT_OBJ(varscp, nodep, "Can't locate varref scope"); nodep->varScopep(varscp); } } diff --git a/test_regress/t/t_class_modscope.py b/test_regress/t/t_class_modscope.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_class_modscope.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('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_class_modscope.v b/test_regress/t/t_class_modscope.v new file mode 100644 index 000000000..a2cfb24cd --- /dev/null +++ b/test_regress/t/t_class_modscope.v @@ -0,0 +1,34 @@ +// 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 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +module m(); + class c; + static function void fstatic(); + `checkh(v, 42); + v++; + endfunction + function void fnonstatic(); + `checkh(v, 43); + v++; + endfunction + endclass + + c classinst; + int v; + + initial begin + v=42; + `checkh(v, 42); + c::fstatic(); + classinst = new(); + classinst.fnonstatic(); + `checkh(v, 44); + $finish; + end +endmodule