forked from github/verilator
Support class type params without defaults (#3693)
This commit is contained in:
parent
bec0b7d4d0
commit
22243d1e49
@ -161,6 +161,7 @@ private:
|
||||
bool m_forPrimary; // First link
|
||||
bool m_forPrearray; // Compress cell__[array] refs
|
||||
bool m_forScopeCreation; // Remove VarXRefs for V3Scope
|
||||
bool m_removeVoidParamedClasses; // Remove classes with void params
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
@ -207,6 +208,7 @@ public:
|
||||
m_forPrimary = (step == LDS_PRIMARY);
|
||||
m_forPrearray = (step == LDS_PARAMED || step == LDS_PRIMARY);
|
||||
m_forScopeCreation = (step == LDS_SCOPED);
|
||||
m_removeVoidParamedClasses = (step == LDS_PARAMED);
|
||||
s_errorThisp = this;
|
||||
V3Error::errorExitCb(preErrorDumpHandler); // If get error, dump self
|
||||
}
|
||||
@ -220,6 +222,7 @@ public:
|
||||
bool forPrimary() const { return m_forPrimary; }
|
||||
bool forPrearray() const { return m_forPrearray; }
|
||||
bool forScopeCreation() const { return m_forScopeCreation; }
|
||||
bool removeVoidParamedClasses() const { return m_removeVoidParamedClasses; }
|
||||
|
||||
// METHODS
|
||||
static string nodeTextType(AstNode* nodep) {
|
||||
@ -902,6 +905,18 @@ class LinkDotFindVisitor final : public VNVisitor {
|
||||
void visit(AstClass* nodep) override {
|
||||
UASSERT_OBJ(m_curSymp, nodep, "Class not under module/package/$unit");
|
||||
UINFO(8, " " << nodep << endl);
|
||||
// Remove classes that have void params, as they were only used for the parametrization
|
||||
// step and will not be instantiated
|
||||
if (m_statep->removeVoidParamedClasses()) {
|
||||
for (auto* stmtp = nodep->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (auto* dtypep = VN_CAST(stmtp, ParamTypeDType)) {
|
||||
if (VN_IS(dtypep->subDTypep(), VoidDType)) {
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
VL_RESTORER(m_scope);
|
||||
VL_RESTORER(m_classOrPackagep);
|
||||
VL_RESTORER(m_modSymp);
|
||||
|
@ -209,18 +209,16 @@ private:
|
||||
}
|
||||
if (VN_IS(nodep->subDTypep(), ParseTypeDType)) {
|
||||
// It's a parameter type. Use a different node type for this.
|
||||
AstNodeDType* const dtypep = VN_CAST(nodep->valuep(), NodeDType);
|
||||
if (!dtypep) {
|
||||
nodep->v3error(
|
||||
"Parameter type's initial value isn't a type: " << nodep->prettyNameQ());
|
||||
nodep->unlinkFrBack();
|
||||
} else {
|
||||
AstNodeDType* dtypep = VN_CAST(nodep->valuep(), NodeDType);
|
||||
if (dtypep) {
|
||||
dtypep->unlinkFrBack();
|
||||
AstNode* const newp = new AstParamTypeDType(
|
||||
nodep->fileline(), nodep->varType(), nodep->name(), VFlagChildDType(), dtypep);
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
} else {
|
||||
dtypep = new AstVoidDType{nodep->fileline()};
|
||||
}
|
||||
AstNode* const newp = new AstParamTypeDType{nodep->fileline(), nodep->varType(),
|
||||
nodep->name(), VFlagChildDType{}, dtypep};
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -801,6 +801,15 @@ class ParamProcessor final {
|
||||
srcModpr = modInfop->m_modp;
|
||||
}
|
||||
|
||||
for (auto* stmtp = srcModpr->stmtsp(); stmtp; stmtp = stmtp->nextp()) {
|
||||
if (auto* dtypep = VN_CAST(stmtp, ParamTypeDType)) {
|
||||
if (VN_IS(dtypep->subDTypep(), VoidDType)) {
|
||||
nodep->v3error("Missing type parameter: " << dtypep->prettyNameQ());
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the parameters from the cell; they're not relevant any longer.
|
||||
if (paramsp) paramsp->unlinkFrBackWithNext()->deleteTree();
|
||||
return any_overrides;
|
||||
@ -822,8 +831,11 @@ class ParamProcessor final {
|
||||
}
|
||||
|
||||
void classRefDeparam(AstClassRefDType* nodep, AstNodeModule*& srcModpr) {
|
||||
if (nodeDeparamCommon(nodep, srcModpr, nodep->paramsp(), nullptr, false))
|
||||
nodep->classp(VN_AS(srcModpr, Class));
|
||||
if (nodeDeparamCommon(nodep, srcModpr, nodep->paramsp(), nullptr, false)) {
|
||||
AstClass* const classp = VN_AS(srcModpr, Class);
|
||||
nodep->classp(classp);
|
||||
nodep->classOrPackagep(classp);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -2882,7 +2882,9 @@ list_of_param_assignments<varp>: // ==IEEE: list_of_param_assignments
|
||||
|
||||
type_assignment<varp>: // ==IEEE: type_assignment
|
||||
// // note exptOrDataType being a data_type is only for yPARAMETER yTYPE
|
||||
idAny/*new-parameter*/ sigAttrListE '=' data_type
|
||||
idAny/*new-parameter*/ sigAttrListE
|
||||
{ $$ = VARDONEA($<fl>1, *$1, nullptr, $2); }
|
||||
| idAny/*new-parameter*/ sigAttrListE '=' data_type
|
||||
{ $$ = VARDONEA($<fl>1, *$1, nullptr, $2); $$->valuep($4); }
|
||||
;
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
%Error-PINNOTFOUND: t/t_class_param_bad.v:12:11: Parameter pin not found: 'PARAMBAD'
|
||||
: ... Suggested alternative: 'PARAMB'
|
||||
12 | Cls #(.PARAMBAD(1)) c;
|
||||
| ^~~~~~~~
|
||||
... For error description see https://verilator.org/warn/PINNOTFOUND?v=latest
|
||||
%Error-PINNOTFOUND: t/t_class_param_bad.v:13:14: Parameter pin not found: '__paramNumber2'
|
||||
13 | Cls #(13, 1) cd;
|
||||
| ^
|
||||
%Error: Exiting due to
|
9
test_regress/t/t_class_param_bad1.out
Normal file
9
test_regress/t/t_class_param_bad1.out
Normal file
@ -0,0 +1,9 @@
|
||||
%Error-PINNOTFOUND: t/t_class_param_bad1.v:12:11: Parameter pin not found: 'PARAMBAD'
|
||||
: ... Suggested alternative: 'PARAMB'
|
||||
12 | Cls #(.PARAMBAD(1)) c;
|
||||
| ^~~~~~~~
|
||||
... For error description see https://verilator.org/warn/PINNOTFOUND?v=latest
|
||||
%Error-PINNOTFOUND: t/t_class_param_bad1.v:13:14: Parameter pin not found: '__paramNumber2'
|
||||
13 | Cls #(13, 1) cd;
|
||||
| ^
|
||||
%Error: Exiting due to
|
5
test_regress/t/t_class_param_bad2.out
Normal file
5
test_regress/t/t_class_param_bad2.out
Normal file
@ -0,0 +1,5 @@
|
||||
%Error: t/t_class_param_bad2.v:12:4: Missing type parameter: 'PARAMB'
|
||||
: ... In instance t
|
||||
12 | Cls c;
|
||||
| ^~~
|
||||
%Error: Exiting due to
|
19
test_regress/t/t_class_param_bad2.pl
Executable file
19
test_regress/t/t_class_param_bad2.pl
Executable file
@ -0,0 +1,19 @@
|
||||
#!/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 Antmicro Ltd. 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);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
14
test_regress/t/t_class_param_bad2.v
Normal file
14
test_regress/t/t_class_param_bad2.v
Normal file
@ -0,0 +1,14 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2022 by Antmicro Ltd.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
class Cls #(type PARAMB);
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
Cls c; // Missing type param
|
||||
|
||||
endmodule
|
@ -14,7 +14,7 @@ virtual class vclass #(type CTYPE_t = arg_class_t, int I = 0);
|
||||
pure virtual function void funcname(paramed_class_t #(CTYPE_t) v);
|
||||
endclass
|
||||
|
||||
class paramed_class_t #(type TYPE = int, int I = 0);
|
||||
class paramed_class_t #(type TYPE, int I = 0);
|
||||
TYPE memb;
|
||||
endclass
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user