* Check whether a class is parameterized or not with AstClass::isParameterized method * Fix usage conflict of user2 pointer in V3Param.cpp
This commit is contained in:
parent
e66b28823d
commit
63db60f646
|
|
@ -3553,7 +3553,8 @@ private:
|
|||
if (nodep->user3SetOnce()) return;
|
||||
if (AstNode* const cpackagep = nodep->classOrPackageOpp()) {
|
||||
if (AstClassOrPackageRef* const cpackagerefp = VN_CAST(cpackagep, ClassOrPackageRef)) {
|
||||
if (cpackagerefp->paramsp()) {
|
||||
const AstClass* const clsp = VN_CAST(cpackagerefp->classOrPackageNodep(), Class);
|
||||
if (clsp && clsp->isParameterized()) {
|
||||
// Unable to link before the instantiation of parameter classes.
|
||||
// The class reference node has to be visited to properly link parameters.
|
||||
iterate(cpackagep);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
// For each cell:
|
||||
// If parameterized,
|
||||
// Determine all parameter widths, constant values.
|
||||
// (Interfaces also matter, as if an interface is parameterized
|
||||
// (Interfaces also matter, as if a module is parameterized
|
||||
// this effectively changes the width behavior of all that
|
||||
// reference the iface.)
|
||||
// Clone module cell calls, renaming with __{par1}_{par2}_...
|
||||
|
|
@ -227,6 +227,10 @@ class ParamProcessor final : public VNDeleter {
|
|||
// // (0=not processed, 1=iterated, but no number,
|
||||
// // 65+ parameter numbered)
|
||||
// NODE STATE - Shared with ParamVisitor
|
||||
// AstClass::user4p() // AstClass* Unchanged copy of the parameterized class node.
|
||||
// The class node may be modified according to parameter
|
||||
// values and an unchanged copy is needed to instantiate
|
||||
// classes with different parameters.
|
||||
// AstNodeModule::user5() // bool True if processed
|
||||
// AstGenFor::user5() // bool True if processed
|
||||
// AstVar::user5() // bool True if constant propagated
|
||||
|
|
@ -574,8 +578,8 @@ class ParamProcessor final : public VNDeleter {
|
|||
// Note all module internal variables will be re-linked to the new modules by clone
|
||||
// However links outside the module (like on the upper cells) will not.
|
||||
AstNodeModule* newmodp;
|
||||
if (srcModp->user2p()) {
|
||||
newmodp = VN_CAST(srcModp->user2p()->cloneTree(false), NodeModule);
|
||||
if (srcModp->user4p()) {
|
||||
newmodp = VN_CAST(srcModp->user4p()->cloneTree(false), NodeModule);
|
||||
} else {
|
||||
newmodp = srcModp->cloneTree(false);
|
||||
}
|
||||
|
|
@ -617,7 +621,7 @@ class ParamProcessor final : public VNDeleter {
|
|||
// Grab all I/O so we can remap our pins later
|
||||
// Note we allow multiple users of a parameterized model,
|
||||
// thus we need to stash this info.
|
||||
collectPins(clonemapp, newmodp, srcModp->user2p());
|
||||
collectPins(clonemapp, newmodp, srcModp->user4p());
|
||||
// Relink parameter vars to the new module
|
||||
relinkPins(clonemapp, paramsp);
|
||||
// Fix any interface references
|
||||
|
|
@ -856,14 +860,14 @@ class ParamProcessor final : public VNDeleter {
|
|||
|
||||
if (!any_overrides) {
|
||||
UINFO(8, "Cell parameters all match original values, skipping expansion.\n");
|
||||
// If it's the first use of the default instance, create a copy and store it in user2p.
|
||||
// user2p will also be used to check if the default instance is used.
|
||||
if (!srcModpr->user2p() && VN_IS(srcModpr, Class)) {
|
||||
// If it's the first use of the default instance, create a copy and store it in user4p.
|
||||
// user4p will also be used to check if the default instance is used.
|
||||
if (!srcModpr->user4p() && VN_IS(srcModpr, Class)) {
|
||||
AstClass* classCopyp = VN_AS(srcModpr, Class)->cloneTree(false);
|
||||
// It is a temporary copy of the original class node, stored in order to create
|
||||
// another instances. It is needed only during class instantiation.
|
||||
pushDeletep(classCopyp);
|
||||
srcModpr->user2p(classCopyp);
|
||||
srcModpr->user4p(classCopyp);
|
||||
storeOriginalParams(classCopyp);
|
||||
}
|
||||
} else if (AstNodeModule* const paramedModp
|
||||
|
|
@ -972,11 +976,7 @@ public:
|
|||
|
||||
class ParamVisitor final : public VNVisitor {
|
||||
// NODE STATE
|
||||
// AstNodeModule::user1 -> bool: already fixed level
|
||||
// AstClass::user2p -> AstClass*: Unchanged copy of the parameterized class node.
|
||||
// The class node may be modified according to parameter
|
||||
// values and an unchanged copy is needed to instantiate
|
||||
// classes with different parameters.
|
||||
// AstNodeModule::user1 -> bool: already fixed level (temporary)
|
||||
|
||||
// STATE
|
||||
ParamProcessor m_processor; // De-parameterize a cell, build modules
|
||||
|
|
@ -1435,7 +1435,7 @@ public:
|
|||
for (AstNodeModule* const modp : modps) netlistp->addModulesp(modp);
|
||||
|
||||
for (AstClass* const classp : m_paramClasses) {
|
||||
if (!classp->user2p()) {
|
||||
if (!classp->user4p()) {
|
||||
// The default value isn't referenced, so it can be removed
|
||||
VL_DO_DANGLING(pushDeletep(classp->unlinkFrBack()), classp);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -138,9 +138,9 @@ module t (/*AUTOARG*/);
|
|||
Wrap #(.P(16)) w16;
|
||||
Wrap2 #(.P(32)) w32;
|
||||
SelfRefClassTypeParam src_logic;
|
||||
SelfRefClassTypeParam::self_int_t src_int;
|
||||
SelfRefClassTypeParam#()::self_int_t src_int;
|
||||
SelfRefClassIntParam src1;
|
||||
SelfRefClassIntParam::self_int_t src10;
|
||||
SelfRefClassIntParam#()::self_int_t src10;
|
||||
IntQueue qi;
|
||||
ClsWithParamField cls_param_field;
|
||||
DictOperator #(DictWrapper) dict_op;
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ endclass
|
|||
Wrap #(.P(16)) w16;
|
||||
Wrap2 #(.P(32)) w32;
|
||||
SelfRefClassTypeParam src_logic;
|
||||
SelfRefClassTypeParam::self_int_t src_int;
|
||||
SelfRefClassTypeParam#()::self_int_t src_int;
|
||||
SelfRefClassIntParam src1;
|
||||
SelfRefClassIntParam::self_int_t src10;
|
||||
SelfRefClassIntParam#()::self_int_t src10;
|
||||
initial begin
|
||||
c12 = new;
|
||||
c4 = new;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2023 by Anthony Donlon.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test for bug4281
|
||||
|
||||
class CParam #(parameter PARAM=10);
|
||||
typedef int type_t;
|
||||
endclass
|
||||
|
||||
class CParam2 #(parameter PARAM=10);
|
||||
typedef int type_t;
|
||||
|
||||
typedef logic [PARAM-1:0] type2_t;
|
||||
endclass
|
||||
|
||||
`ifdef CONSTSIM
|
||||
module sub();
|
||||
parameter N = 32;
|
||||
for (genvar i = 0; i < N/8; i = i + 1) begin
|
||||
initial begin
|
||||
end
|
||||
end
|
||||
// Test for bug4281, usage conflict of user2 with constant simulator in V3Param.cpp
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
module t;
|
||||
`ifdef BAD_PAREN
|
||||
CParam::type_t val_0 = 100;
|
||||
`else
|
||||
CParam#()::type_t val_0 = 100;
|
||||
`endif
|
||||
CParam2#()::type_t val_2 = 200;
|
||||
|
||||
`ifdef CONSTSIM
|
||||
|
||||
sub i_sub();
|
||||
`endif
|
||||
|
||||
initial begin
|
||||
if (val_0 != 100) $stop;
|
||||
if (val_2 != 200) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
%Error: t/t_class_param_subtype.v:32:5: Reference to parameterized class without #() (IEEE 1800-2017 8.25.1)
|
||||
: ... Suggest use 'CParam#()'
|
||||
32 | CParam::type_t val_0 = 100;
|
||||
| ^~~~~~
|
||||
%Error: Exiting due to
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2022 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
|
||||
|
||||
scenarios(linter => 1);
|
||||
|
||||
top_filename("t/t_class_param_subtype.v");
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
v_flags2 => ['+define+BAD_PAREN'],
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2023 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
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
top_filename("t/t_class_param_subtype.v");
|
||||
|
||||
compile(
|
||||
v_flags2 => ['+define+CONSTSIM'],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Loading…
Reference in New Issue