Fix reading another parameter resolves to 0 in cloned modules (#8086) (#8069)

This commit is contained in:
em2machine 2026-08-15 12:06:25 +02:00 committed by GitHub
parent 3334576b1d
commit 93401038c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 64 additions and 1 deletions

View File

@ -1442,9 +1442,19 @@ class ParamProcessor final {
// Cast/CastSize default values are not yet folded by V3Width.
// Constify here so the comparison below sees a Const node.
// Other node kinds are handled in the branches above.
//
// Only fold when the cast is self-contained. modvarp is the
// parameter on the shared module template and constifyParamsEdit
// is destructive: a default that reads another parameter
// (VarRef) or a type parameter (RefDType) must be evaluated per
// instance, and folding it here would evaluate it against the
// template's own defaults and bake that in for every later
// instance that relies on the default.
if (modvarp->valuep()
&& (VN_IS(modvarp->valuep(), Cast) || VN_IS(modvarp->valuep(), CastSize))) {
V3Const::constifyParamsEdit(modvarp->valuep());
const bool dependent = modvarp->valuep()->exists(
[](AstNode* np) { return VN_IS(np, VarRef) || VN_IS(np, RefDType); });
if (!dependent) V3Const::constifyParamsEdit(modvarp->valuep());
}
UINFO(9, "cellPinCleanup: after constify " << pinp);
// String constants are parsed as logic arrays and converted to strings in V3Const.

View File

@ -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()

View File

@ -0,0 +1,35 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
// verilog_format: on
// A parameter whose default is a cast of a member of a struct-typed
// parameter.
typedef struct packed {int unsigned CAP;} cfg_t;
module m #(
parameter cfg_t cfg = '{CAP: 0},
parameter int unsigned p_cap = int'(cfg.CAP)
);
endmodule
module t;
localparam cfg_t c = '{CAP: 32};
m #(.cfg(c), .p_cap(64)) u_over (); // explicit override, elaborated first
m #(.cfg(c)) u_dflt (); // takes the default: int'(cfg.CAP) == 32
initial begin
`checkd(u_over.p_cap, 64);
`checkd(u_dflt.p_cap, 32); // 0 before the fix
$write("*-* All Finished *-*\n");
$finish;
end
endmodule