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 100644 index 000000000..e41ab0cdd --- /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 +# +# Copyright 2026 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_func_unit_recursive.v b/test_regress/t/t_func_unit_recursive.v new file mode 100644 index 000000000..249e86c9e --- /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, for +// any use, without warranty, 2026 by 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