diff --git a/src/V3Const.cpp b/src/V3Const.cpp index e8abc71dd..5ed7840c5 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -3028,6 +3028,12 @@ class ConstVisitor final : public VNVisitor { void visit(AstArraySel* nodep) override { iterateAndNextNull(nodep->bitp()); + // Multi-dimensional param array access (fromp is a chain of ArraySels): + // delegate to V3Simulate to natively handles InitArray chains + if (m_required && VN_IS(nodep->fromp(), ArraySel)) { + replaceWithSimulation(nodep); + return; + } if (VN_IS(nodep->bitp(), Const) && VN_IS(nodep->fromp(), VarRef) // Need to make sure it's an array object so don't mis-allow a constant (bug509.) diff --git a/test_regress/t/t_param_array2dim.py b/test_regress/t/t_param_array2dim.py new file mode 100755 index 000000000..8a938befd --- /dev/null +++ b/test_regress/t/t_param_array2dim.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_param_array2dim.v b/test_regress/t/t_param_array2dim.v new file mode 100644 index 000000000..00762ae62 --- /dev/null +++ b/test_regress/t/t_param_array2dim.v @@ -0,0 +1,43 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2020 Dustin Richmond +// SPDX-License-Identifier: CC0-1.0 + +// Test: 2D array parameter passed to sub-modules via generate loops + +module baz + #( + parameter integer type_p = '0 + ) + (); + +endmodule + +module t + #( + parameter integer n_x_p = 4 + ,parameter integer n_y_p = 4 + ,parameter integer twodim_p [0:n_y_p-1][0:n_x_p-1] = '{n_y_p{'{n_x_p{0}}}} + ) + (); + + genvar r, c; + + for (r = 0; r < n_y_p; r = r+1) + begin: y + for (c = 0; c < n_x_p; c=c+1) + begin: x + baz + #(.type_p(twodim_p[r][c])) + baz_i + (); + end + end + + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_param_pattern_2d_init.py b/test_regress/t/t_param_pattern_2d_init.py new file mode 100755 index 000000000..8a938befd --- /dev/null +++ b/test_regress/t/t_param_pattern_2d_init.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_param_pattern_2d_init.v b/test_regress/t/t_param_pattern_2d_init.v new file mode 100644 index 000000000..92857c82e --- /dev/null +++ b/test_regress/t/t_param_pattern_2d_init.v @@ -0,0 +1,41 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Greg Davill +// 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 t ( /*AUTOARG*/); + + // Test: 2D array localparam with pattern initialization + localparam logic [31:0] MATRIX[2][3] = '{'{32'hA0, 32'hA1, 32'hA2}, '{32'hB0, 32'hB1, 32'hB2}}; + + // Deriving a localparam from a 2D array element + localparam logic [31:0] DERIVED_A0 = MATRIX[0][0]; + localparam logic [31:0] DERIVED_B2 = MATRIX[1][2]; + + // Use derived values as sub-module parameters to force elaboration-time resolution + sub #(.VAL(MATRIX[0][1])) u_sub (); + + initial begin + `checkh(DERIVED_A0, 32'hA0); + `checkh(DERIVED_B2, 32'hB2); + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule + +module sub #( + parameter logic [31:0] VAL = 0 +) (); + initial begin + if (VAL !== 32'hA1) begin + $display("%%Error: sub VAL='h%x expected 'hA1", VAL); + $stop; + end + end +endmodule diff --git a/test_regress/t/t_param_pattern_3d_init.py b/test_regress/t/t_param_pattern_3d_init.py new file mode 100755 index 000000000..8a938befd --- /dev/null +++ b/test_regress/t/t_param_pattern_3d_init.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_param_pattern_3d_init.v b/test_regress/t/t_param_pattern_3d_init.v new file mode 100644 index 000000000..ca9a3f801 --- /dev/null +++ b/test_regress/t/t_param_pattern_3d_init.v @@ -0,0 +1,31 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Greg Davill +// 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 t ( /*AUTOARG*/); + + // Test: 3D array localparam with pattern initialization + localparam logic [31:0] CUBE[2][2][2] = '{ + '{'{32'h00, 32'h01}, '{32'h10, 32'h11}}, + '{'{32'h20, 32'h21}, '{32'h30, 32'h31}} + }; + + // Deriving a localparam from a 3D array element + localparam logic [31:0] CUBE_VAL = CUBE[1][0][1]; + + initial begin + `checkh(CUBE_VAL, 32'h21); + `checkh(CUBE[0][0][0], 32'h00); + `checkh(CUBE[0][1][1], 32'h11); + `checkh(CUBE[1][1][0], 32'h30); + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule