forked from github/verilator
Support access to constructs inside type parameters (#3702)
This changeset brings support for accesses like: class Cls#(type TYPE1); TYPE1::some_method(); endclass It is done by delaying dot resolution on type parameters until they get resolved by V3Param, and doing a more thorough reference skip.
This commit is contained in:
parent
5688d1a935
commit
627a144b83
@ -912,6 +912,7 @@ public:
|
||||
dtypep(nullptr); // V3Width will resolve
|
||||
}
|
||||
ASTGEN_MEMBERS_AstParamTypeDType;
|
||||
void dump(std::ostream& str = std::cout) const override;
|
||||
AstNodeDType* getChildDTypep() const override { return childDTypep(); }
|
||||
AstNodeDType* subDTypep() const override { return dtypep() ? dtypep() : childDTypep(); }
|
||||
AstBasicDType* basicp() const override VL_MT_SAFE { return subDTypep()->basicp(); }
|
||||
|
@ -1719,12 +1719,25 @@ void AstTimeImport::dump(std::ostream& str) const {
|
||||
void AstTypedef::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
if (attrPublic()) str << " [PUBLIC]";
|
||||
if (subDTypep()) {
|
||||
str << " -> ";
|
||||
subDTypep()->dump(str);
|
||||
}
|
||||
}
|
||||
void AstNodeRange::dump(std::ostream& str) const { this->AstNode::dump(str); }
|
||||
void AstRange::dump(std::ostream& str) const {
|
||||
this->AstNodeRange::dump(str);
|
||||
if (littleEndian()) str << " [LITTLE]";
|
||||
}
|
||||
void AstParamTypeDType::dump(std::ostream& str) const {
|
||||
this->AstNodeDType::dump(str);
|
||||
if (subDTypep()) {
|
||||
str << " -> ";
|
||||
subDTypep()->dump(str);
|
||||
} else {
|
||||
str << " -> UNLINKED";
|
||||
}
|
||||
}
|
||||
void AstRefDType::dump(std::ostream& str) const {
|
||||
this->AstNodeDType::dump(str);
|
||||
if (typedefp() || subDTypep()) {
|
||||
@ -2095,7 +2108,8 @@ void AstClassOrPackageRef::dump(std::ostream& str) const {
|
||||
}
|
||||
AstNodeModule* AstClassOrPackageRef::classOrPackagep() const {
|
||||
AstNode* foundp = m_classOrPackageNodep;
|
||||
while (auto* const anodep = VN_CAST(foundp, Typedef)) foundp = anodep->subDTypep();
|
||||
if (auto* const anodep = VN_CAST(foundp, Typedef)) foundp = anodep->subDTypep();
|
||||
if (auto* const anodep = VN_CAST(foundp, NodeDType)) foundp = anodep->skipRefp();
|
||||
if (auto* const anodep = VN_CAST(foundp, ClassRefDType)) foundp = anodep->classp();
|
||||
return VN_CAST(foundp, NodeModule);
|
||||
}
|
||||
|
@ -2069,11 +2069,13 @@ private:
|
||||
}
|
||||
|
||||
bool isParamedClassRef(const AstNode* nodep) {
|
||||
// Is this a parametrized reference to a class, or a reference to class parameter
|
||||
if (const auto* classRefp = VN_CAST(nodep, ClassOrPackageRef)) {
|
||||
if (classRefp->paramsp()) return true;
|
||||
const auto* classp = classRefp->classOrPackageNodep();
|
||||
while (const auto* typedefp = VN_CAST(classp, Typedef)) classp = typedefp->subDTypep();
|
||||
return VN_IS(classp, ClassRefDType) && VN_AS(classp, ClassRefDType)->paramsp();
|
||||
return (VN_IS(classp, ClassRefDType) && VN_AS(classp, ClassRefDType)->paramsp())
|
||||
|| VN_IS(classp, ParamTypeDType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2633,8 +2635,9 @@ private:
|
||||
// Class: Recurse inside or cleanup not founds
|
||||
// checkNoDot not appropriate, can be under a dot
|
||||
AstNode::user5ClearTree();
|
||||
UASSERT_OBJ(m_statep->forPrimary() || nodep->classOrPackagep(), nodep,
|
||||
"ClassRef has unlinked class");
|
||||
UASSERT_OBJ(m_statep->forPrimary() || VN_IS(nodep->classOrPackageNodep(), ParamTypeDType)
|
||||
|| nodep->classOrPackagep(),
|
||||
nodep, "ClassRef has unlinked class");
|
||||
UASSERT_OBJ(m_statep->forPrimary() || !nodep->paramsp(), nodep,
|
||||
"class reference parameter not removed by V3Param");
|
||||
VL_RESTORER(m_ds);
|
||||
|
@ -936,11 +936,13 @@ class ParamVisitor final : public VNVisitor {
|
||||
srcModp = modCellp->modp();
|
||||
} else if (const auto* classRefp = VN_CAST(cellp, ClassOrPackageRef)) {
|
||||
srcModp = classRefp->classOrPackagep();
|
||||
if (VN_IS(classRefp->classOrPackageNodep(), ParamTypeDType)) continue;
|
||||
} else if (const auto* classRefp = VN_CAST(cellp, ClassRefDType)) {
|
||||
srcModp = classRefp->classp();
|
||||
} else {
|
||||
cellp->v3fatalSrc("Expected module parametrization");
|
||||
}
|
||||
UASSERT_OBJ(srcModp, cellp, "Unlinked class ref");
|
||||
|
||||
// Update path
|
||||
string someInstanceName(modp->someInstanceName());
|
||||
|
21
test_regress/t/t_class_param_type.pl
Executable file
21
test_regress/t/t_class_param_type.pl
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2020 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);
|
||||
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
32
test_regress/t/t_class_param_type.v
Normal file
32
test_regress/t/t_class_param_type.v
Normal file
@ -0,0 +1,32 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2022 by Arkadiusz Kozdra.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// See also t_class_param.v
|
||||
|
||||
class Parcls #(type T);
|
||||
static function int get_p;
|
||||
return T::get_p();
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class Cls;
|
||||
static function int get_p;
|
||||
return 20;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
typedef Cls cls_t;
|
||||
typedef cls_t cls2_t;
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
initial begin
|
||||
if (Parcls#(cls2_t)::get_p() != 20) $stop;
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user