parent
9a6b24fca4
commit
990ee994db
|
|
@ -958,6 +958,9 @@ class ParamProcessor final {
|
|||
m_paramIndex.clear();
|
||||
for (AstNode* stmtp = classp->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (AstParamTypeDType* paramTypep = VN_CAST(stmtp, ParamTypeDType)) {
|
||||
// Only consider formal class type parameters (generic parameters),
|
||||
// not localparam type declarations inside the class body.
|
||||
if (!paramTypep->isGParam()) continue;
|
||||
m_paramIndex.emplace(paramTypep, m_classParams.size());
|
||||
m_classParams.emplace_back(paramTypep, -1);
|
||||
}
|
||||
|
|
@ -1194,6 +1197,24 @@ public:
|
|||
VL_UNCOPYABLE(ParamProcessor);
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// This visitor records classes that are referenced with parameter pins
|
||||
class ClassPinsMarkVisitor final : public VNVisitorConst {
|
||||
|
||||
public:
|
||||
explicit ClassPinsMarkVisitor(AstNetlist* netlistp) { iterateConst(netlistp); }
|
||||
|
||||
void visit(AstClassOrPackageRef* nodep) override {
|
||||
if (nodep->paramsp()) {
|
||||
if (AstClass* const classp = VN_CAST(nodep->classOrPackageSkipp(), Class)) {
|
||||
classp->user3p(classp);
|
||||
}
|
||||
}
|
||||
}
|
||||
void visit(AstClass* nodep) override {} // don't iterate inside classes
|
||||
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Process parameter visitor
|
||||
|
||||
|
|
@ -1661,6 +1682,9 @@ public:
|
|||
// Relies on modules already being in top-down-order
|
||||
iterate(netlistp);
|
||||
|
||||
// Mark classes which cannot be removed because they are still referenced
|
||||
ClassPinsMarkVisitor markVisitor{netlistp};
|
||||
|
||||
relinkDots();
|
||||
|
||||
// Re-sort module list to be in topological order and fix-up incorrect levels. We need to
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2025 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('vlt')
|
||||
|
||||
test.compile()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2025 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
package pk1;
|
||||
typedef struct packed {
|
||||
int AddrBits;
|
||||
int DataBits;
|
||||
} cfg_t;
|
||||
endpackage
|
||||
|
||||
virtual class a_class_t #(
|
||||
parameter pk1::cfg_t CFG = 0
|
||||
);
|
||||
// verilator lint_off ASCRANGE
|
||||
localparam type addr_t = logic [CFG.AddrBits-1:0];
|
||||
localparam type data_t = logic [CFG.DataBits-1:0];
|
||||
// verilator lint_on ASCRANGE
|
||||
|
||||
typedef struct packed {
|
||||
addr_t addr;
|
||||
data_t data;
|
||||
} pkt_t;
|
||||
endclass
|
||||
|
||||
interface ifc #(
|
||||
parameter pk1::cfg_t CFG = 0
|
||||
);
|
||||
a_class_t #(CFG)::pkt_t p;
|
||||
endinterface
|
||||
|
||||
module a_to_b #(
|
||||
parameter pk1::cfg_t ACFG = 0
|
||||
) (
|
||||
ifc bus
|
||||
);
|
||||
// sturf
|
||||
endmodule
|
||||
|
||||
module t;
|
||||
localparam pk1::cfg_t ACFG = '{AddrBits : 64, DataBits : 64};
|
||||
|
||||
ifc #(.CFG(ACFG)) the_bus ();
|
||||
|
||||
a_to_b #(ACFG) a_to_b (.bus(the_bus));
|
||||
endmodule
|
||||
Loading…
Reference in New Issue