This commit is contained in:
parent
407fc74195
commit
b2fa3fb54e
|
|
@ -152,6 +152,7 @@ Krzysztof Sychla
|
||||||
Kuba Ober
|
Kuba Ober
|
||||||
Lan Zongwei
|
Lan Zongwei
|
||||||
Larry Doolittle
|
Larry Doolittle
|
||||||
|
Leela Pakanati
|
||||||
Liam Braun
|
Liam Braun
|
||||||
Luca Colagrande
|
Luca Colagrande
|
||||||
Ludwig Rogiers
|
Ludwig Rogiers
|
||||||
|
|
|
||||||
|
|
@ -810,17 +810,32 @@ class ParamProcessor final {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to resolve DOT to RefDType for class type references
|
// Helper to resolve DOT to RefDType for class type references.
|
||||||
|
// If the class is parameterized and not yet specialized, specialize it first.
|
||||||
|
// This handles cases like: iface #(param_class#(value)::typedef_name)
|
||||||
void resolveDotToTypedef(AstNode* exprp) {
|
void resolveDotToTypedef(AstNode* exprp) {
|
||||||
AstDot* const dotp = VN_CAST(exprp, Dot);
|
AstDot* const dotp = VN_CAST(exprp, Dot);
|
||||||
if (!dotp) return;
|
if (!dotp) return;
|
||||||
const AstClassOrPackageRef* const classRefp = VN_CAST(dotp->lhsp(), ClassOrPackageRef);
|
AstClassOrPackageRef* const classRefp = VN_CAST(dotp->lhsp(), ClassOrPackageRef);
|
||||||
if (!classRefp) return;
|
if (!classRefp) return;
|
||||||
const AstClass* const lhsClassp = VN_CAST(classRefp->classOrPackageSkipp(), Class);
|
|
||||||
if (!lhsClassp) return;
|
|
||||||
AstParseRef* const parseRefp = VN_CAST(dotp->rhsp(), ParseRef);
|
AstParseRef* const parseRefp = VN_CAST(dotp->rhsp(), ParseRef);
|
||||||
if (!parseRefp) return;
|
if (!parseRefp) return;
|
||||||
|
|
||||||
|
const AstClass* lhsClassp = VN_CAST(classRefp->classOrPackageSkipp(), Class);
|
||||||
|
if (classRefp->paramsp()) {
|
||||||
|
// ClassOrPackageRef has parameters - may need to specialize the class
|
||||||
|
AstClass* const srcClassp = VN_CAST(classRefp->classOrPackageNodep(), Class);
|
||||||
|
if (srcClassp && srcClassp->hasGParam()) {
|
||||||
|
// Specialize if the reference still points to the generic class
|
||||||
|
if (lhsClassp == srcClassp || !lhsClassp) {
|
||||||
|
UINFO(9, "resolveDotToTypedef: specializing " << srcClassp->name() << endl);
|
||||||
|
classRefDeparam(classRefp, srcClassp);
|
||||||
|
lhsClassp = VN_CAST(classRefp->classOrPackageSkipp(), Class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lhsClassp) return;
|
||||||
|
|
||||||
AstTypedef* const tdefp
|
AstTypedef* const tdefp
|
||||||
= VN_CAST(m_memberMap.findMember(lhsClassp, parseRefp->name()), Typedef);
|
= VN_CAST(m_memberMap.findMember(lhsClassp, parseRefp->name()), Typedef);
|
||||||
if (tdefp) {
|
if (tdefp) {
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Test that parameterized class typedefs work as interface type parameters
|
||||||
|
// See issue #6983
|
||||||
|
|
||||||
|
// verilog_format: off
|
||||||
|
`define stop $stop
|
||||||
|
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
|
||||||
|
// verilog_format: on
|
||||||
|
|
||||||
|
class flux_st #(parameter int WIDTH=32);
|
||||||
|
typedef struct packed { logic [WIDTH-1:0] data; } pld_t;
|
||||||
|
endclass
|
||||||
|
|
||||||
|
interface flux_if #(parameter type PLD_T = logic);
|
||||||
|
logic rdy;
|
||||||
|
logic vld;
|
||||||
|
PLD_T pld;
|
||||||
|
modport drive (input rdy, output vld, output pld);
|
||||||
|
modport sink (output rdy, input vld, input pld);
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
module t;
|
||||||
|
// Test using parameterized class typedef as interface type parameter
|
||||||
|
flux_if #(flux_st#(64)::pld_t) w_flux_st ();
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
`checkd($bits(w_flux_st.pld), 64);
|
||||||
|
w_flux_st.pld.data = 64'hDEADBEEF_CAFEBABE;
|
||||||
|
`checkd(w_flux_st.pld.data, 64'hDEADBEEF_CAFEBABE);
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue