From d406efdcf966218bbce0bc4834e6fde306f4cf53 Mon Sep 17 00:00:00 2001 From: jalcim Date: Mon, 2 Mar 2026 15:15:34 -0500 Subject: [PATCH] Fix recursive constant function in $unit scope (#7174) (#7178) --- docs/CONTRIBUTORS | 1 + src/V3Scope.cpp | 1 + test_regress/t/t_func_unit_recursive.py | 18 ++++++++++++ test_regress/t/t_func_unit_recursive.v | 38 +++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100755 test_regress/t/t_func_unit_recursive.py create mode 100644 test_regress/t/t_func_unit_recursive.v diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 5ac1958e1..de64a9a88 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -99,6 +99,7 @@ Ivan Vnučec Iztok Jeras Jake Merdich Jakub Wasilewski +jalcim James Bailey James Hanlon James Hutchinson diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index b10ac4999..29c3cc534 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -259,6 +259,7 @@ class ScopeVisitor final : public VNVisitor { clonep = nodep->cloneTree(false); } nodep->user2p(clonep); + clonep->user2p(clonep); // For recursive self-references after cloneTree m_scopep->addBlocksp(clonep); // We iterate under the *clone* iterateChildren(clonep); diff --git a/test_regress/t/t_func_unit_recursive.py b/test_regress/t/t_func_unit_recursive.py new file mode 100755 index 000000000..8a938befd --- /dev/null +++ b/test_regress/t/t_func_unit_recursive.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() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_func_unit_recursive.v b/test_regress/t/t_func_unit_recursive.v new file mode 100644 index 000000000..40096c953 --- /dev/null +++ b/test_regress/t/t_func_unit_recursive.v @@ -0,0 +1,38 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 jalcim +// SPDX-License-Identifier: CC0-1.0 + +// Recursive constant function defined at file scope ($unit). +// Without the V3Scope.cpp fix, this triggers: +// %Error: Internal Error: V3Scope.cpp: No clone for package function + +function automatic integer gate_depth; + input integer way; + integer d1, d2, sc, n1, n2; + begin + if (way <= 1) gate_depth = 0; + else if (way <= 4) gate_depth = 1; + else begin + sc = $clog2(way); + n1 = 1 << (sc - 1); + n2 = way - n1; + d1 = gate_depth(n1); + d2 = gate_depth(n2); + gate_depth = ((d1 > d2) ? d1 : d2) + 1; + end + end +endfunction + +module t; + localparam D5 = gate_depth(5); + localparam D8 = gate_depth(8); + + initial begin + if (D5 !== 2) $stop; + if (D8 !== 2) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule