Support static methods and typedefs in classes (#2615)
This commit is contained in:
parent
1c2384cb3d
commit
7c4259bc0a
|
|
@ -36,6 +36,7 @@ Julien Margetts
|
||||||
Kaleb Barrett
|
Kaleb Barrett
|
||||||
Kanad Kanhere
|
Kanad Kanhere
|
||||||
Kevin Kiningham
|
Kevin Kiningham
|
||||||
|
Krzysztof Bieganski
|
||||||
Kuba Ober
|
Kuba Ober
|
||||||
Ludwig Rogiers
|
Ludwig Rogiers
|
||||||
Lukasz Dalek
|
Lukasz Dalek
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ private:
|
||||||
AstUser1InUse m_inuser1;
|
AstUser1InUse m_inuser1;
|
||||||
string m_prefix; // String prefix to add to name based on hier
|
string m_prefix; // String prefix to add to name based on hier
|
||||||
AstScope* m_classScopep = nullptr; // Package moving scopes into
|
AstScope* m_classScopep = nullptr; // Package moving scopes into
|
||||||
|
AstScope* m_packageScopep = nullptr; // Class package scope
|
||||||
|
AstNodeFTask* m_ftaskp = nullptr; // Current task
|
||||||
typedef std::vector<std::pair<AstNode*, AstScope*>> MoveVector;
|
typedef std::vector<std::pair<AstNode*, AstScope*>> MoveVector;
|
||||||
MoveVector m_moves;
|
MoveVector m_moves;
|
||||||
|
|
||||||
|
|
@ -76,12 +78,14 @@ private:
|
||||||
packagep->addStmtp(scopep);
|
packagep->addStmtp(scopep);
|
||||||
// Iterate
|
// Iterate
|
||||||
VL_RESTORER(m_prefix);
|
VL_RESTORER(m_prefix);
|
||||||
|
VL_RESTORER(m_classScopep);
|
||||||
|
VL_RESTORER(m_packageScopep);
|
||||||
{
|
{
|
||||||
m_classScopep = classScopep;
|
m_classScopep = classScopep;
|
||||||
|
m_packageScopep = scopep;
|
||||||
m_prefix = nodep->name() + "__02e"; // .
|
m_prefix = nodep->name() + "__02e"; // .
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
}
|
}
|
||||||
m_classScopep = nullptr;
|
|
||||||
}
|
}
|
||||||
virtual void visit(AstPackage* nodep) override {
|
virtual void visit(AstPackage* nodep) override {
|
||||||
VL_RESTORER(m_prefix);
|
VL_RESTORER(m_prefix);
|
||||||
|
|
@ -94,11 +98,28 @@ private:
|
||||||
virtual void visit(AstVar* nodep) override {
|
virtual void visit(AstVar* nodep) override {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
// Don't move now, or wouldn't keep interating the class
|
// Don't move now, or wouldn't keep interating the class
|
||||||
// TODO move class statics only
|
// TODO move class statics too
|
||||||
// if (m_classScopep) {
|
if (m_ftaskp && m_ftaskp->lifetime().isStatic()) {
|
||||||
// m_moves.push_back(make_pair(nodep, m_classScopep));
|
m_moves.push_back(make_pair(nodep, m_packageScopep));
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void visit(AstVarScope* nodep) override {
|
||||||
|
iterateChildren(nodep);
|
||||||
|
nodep->varp()->user1p(nodep);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void visit(AstNodeFTask* nodep) override {
|
||||||
|
VL_RESTORER(m_ftaskp);
|
||||||
|
{
|
||||||
|
m_ftaskp = nodep;
|
||||||
|
iterateChildren(nodep);
|
||||||
|
if (nodep->lifetime().isStatic()) {
|
||||||
|
m_moves.push_back(make_pair(nodep, m_packageScopep));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void visit(AstCFunc* nodep) override {
|
virtual void visit(AstCFunc* nodep) override {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
// Don't move now, or wouldn't keep interating the class
|
// Don't move now, or wouldn't keep interating the class
|
||||||
|
|
@ -116,8 +137,13 @@ public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit ClassVisitor(AstNetlist* nodep) { iterate(nodep); }
|
explicit ClassVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||||
virtual ~ClassVisitor() override {
|
virtual ~ClassVisitor() override {
|
||||||
for (MoveVector::iterator it = m_moves.begin(); it != m_moves.end(); ++it) {
|
for (auto moved : m_moves) {
|
||||||
it->second->addVarp(it->first->unlinkFrBack());
|
if (VN_IS(moved.first, NodeFTask)) {
|
||||||
|
moved.second->addActivep(moved.first->unlinkFrBack());
|
||||||
|
} else if (VN_IS(moved.first, Var)) {
|
||||||
|
AstVarScope* scopep = VN_CAST(moved.first->user1p(), VarScope);
|
||||||
|
moved.second->addVarp(scopep->unlinkFrBack());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1004,7 +1004,12 @@ class LinkDotFindVisitor : public AstNVisitor {
|
||||||
}
|
}
|
||||||
// Create symbol table for the task's vars
|
// Create symbol table for the task's vars
|
||||||
string name = string{nodep->isExternProto() ? "extern " : ""} + nodep->name();
|
string name = string{nodep->isExternProto() ? "extern " : ""} + nodep->name();
|
||||||
m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, m_packagep);
|
auto pkgp = m_packagep;
|
||||||
|
// Set the class as package for static class methods
|
||||||
|
if (nodep->lifetime().isStatic() && VN_IS(m_curSymp->nodep(), Class)) {
|
||||||
|
pkgp = VN_CAST(m_curSymp->nodep(), Class);
|
||||||
|
}
|
||||||
|
m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, pkgp);
|
||||||
m_curSymp->fallbackp(oldCurSymp);
|
m_curSymp->fallbackp(oldCurSymp);
|
||||||
// Convert the func's range to the output variable
|
// Convert the func's range to the output variable
|
||||||
// This should probably be done in the Parser instead, as then we could
|
// This should probably be done in the Parser instead, as then we could
|
||||||
|
|
@ -2114,12 +2119,7 @@ private:
|
||||||
"Bad package link");
|
"Bad package link");
|
||||||
AstClassOrPackageRef* cpackagerefp
|
AstClassOrPackageRef* cpackagerefp
|
||||||
= VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
= VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
|
||||||
packagep = cpackagerefp->packagep();
|
packagep = cpackagerefp->classOrPackagep();
|
||||||
if (!packagep && cpackagerefp->classOrPackagep()) {
|
|
||||||
nodep->v3warn(E_UNSUPPORTED,
|
|
||||||
"Unsupported: Class '::' references: "
|
|
||||||
<< AstNode::prettyNameQ(cpackagerefp->name()));
|
|
||||||
}
|
|
||||||
UASSERT_OBJ(packagep, m_ds.m_dotp->lhsp(), "Bad package link");
|
UASSERT_OBJ(packagep, m_ds.m_dotp->lhsp(), "Bad package link");
|
||||||
m_ds.m_dotSymp = m_statep->getNodeSym(packagep);
|
m_ds.m_dotSymp = m_statep->getNodeSym(packagep);
|
||||||
m_ds.m_dotPos = DP_SCOPE;
|
m_ds.m_dotPos = DP_SCOPE;
|
||||||
|
|
@ -2485,9 +2485,8 @@ private:
|
||||||
if (cpackagerefp->paramsp()) {
|
if (cpackagerefp->paramsp()) {
|
||||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
|
nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
|
||||||
}
|
}
|
||||||
UASSERT_OBJ(VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef)->packagep(),
|
UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link");
|
||||||
m_ds.m_dotp->lhsp(), "Bad package link");
|
nodep->packagep(cpackagerefp->classOrPackagep());
|
||||||
nodep->packagep(VN_CAST(m_ds.m_dotp->lhsp(), ClassOrPackageRef)->packagep());
|
|
||||||
m_ds.m_dotPos = DP_SCOPE;
|
m_ds.m_dotPos = DP_SCOPE;
|
||||||
m_ds.m_dotp = nullptr;
|
m_ds.m_dotp = nullptr;
|
||||||
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
|
||||||
|
|
@ -2694,9 +2693,6 @@ private:
|
||||||
virtual void visit(AstNodeFTask* nodep) override {
|
virtual void visit(AstNodeFTask* nodep) override {
|
||||||
UINFO(5, " " << nodep << endl);
|
UINFO(5, " " << nodep << endl);
|
||||||
checkNoDot(nodep);
|
checkNoDot(nodep);
|
||||||
if (nodep->classMethod() && nodep->lifetime().isStatic()) {
|
|
||||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'static' class method");
|
|
||||||
}
|
|
||||||
if (nodep->isExternDef()) {
|
if (nodep->isExternDef()) {
|
||||||
if (!m_curSymp->findIdFallback("extern " + nodep->name())) {
|
if (!m_curSymp->findIdFallback("extern " + nodep->name())) {
|
||||||
nodep->v3error("extern not found that declares " + nodep->prettyNameQ());
|
nodep->v3error("extern not found that declares " + nodep->prettyNameQ());
|
||||||
|
|
@ -2802,7 +2798,7 @@ private:
|
||||||
if (cpackagerefp->packagep()) {
|
if (cpackagerefp->packagep()) {
|
||||||
nodep->packagep(cpackagerefp->packagep());
|
nodep->packagep(cpackagerefp->packagep());
|
||||||
} else {
|
} else {
|
||||||
cpackagep->v3warn(E_UNSUPPORTED, "Unsupported: Class '::' reference");
|
nodep->packagep(cpackagerefp->classOrPackagep());
|
||||||
// if (cpackagerefp->paramsp()) {
|
// if (cpackagerefp->paramsp()) {
|
||||||
// nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
|
// nodep->v3warn(E_UNSUPPORTED, "Unsupported: parameterized packages");
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ private:
|
||||||
virtual void visit(AstVar* nodep) override {
|
virtual void visit(AstVar* nodep) override {
|
||||||
cleanFileline(nodep);
|
cleanFileline(nodep);
|
||||||
if (nodep->lifetime().isNone()) {
|
if (nodep->lifetime().isNone()) {
|
||||||
if (nodep->isFuncLocal() && nodep->isIO()) {
|
if (m_ftaskp) {
|
||||||
nodep->lifetime(VLifetime::AUTOMATIC);
|
nodep->lifetime(VLifetime::AUTOMATIC);
|
||||||
} else {
|
} else {
|
||||||
nodep->lifetime(m_lifetime);
|
nodep->lifetime(m_lifetime);
|
||||||
|
|
|
||||||
|
|
@ -2845,9 +2845,24 @@ private:
|
||||||
for (AstClass* classp = first_classp; classp;) {
|
for (AstClass* classp = first_classp; classp;) {
|
||||||
if (AstNodeFTask* ftaskp = VN_CAST(classp->findMember(nodep->name()), NodeFTask)) {
|
if (AstNodeFTask* ftaskp = VN_CAST(classp->findMember(nodep->name()), NodeFTask)) {
|
||||||
userIterate(ftaskp, nullptr);
|
userIterate(ftaskp, nullptr);
|
||||||
nodep->taskp(ftaskp);
|
if (ftaskp->lifetime().isStatic()) {
|
||||||
nodep->dtypeFrom(ftaskp);
|
AstNode* argsp = nullptr;
|
||||||
if (VN_IS(ftaskp, Task)) nodep->makeStatement();
|
if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext();
|
||||||
|
AstNodeFTaskRef* newp = nullptr;
|
||||||
|
if (VN_IS(ftaskp, Task)) {
|
||||||
|
newp = new AstTaskRef(nodep->fileline(), ftaskp->name(), argsp);
|
||||||
|
} else {
|
||||||
|
newp = new AstFuncRef(nodep->fileline(), ftaskp->name(), argsp);
|
||||||
|
}
|
||||||
|
newp->taskp(ftaskp);
|
||||||
|
newp->packagep(classp);
|
||||||
|
nodep->replaceWith(newp);
|
||||||
|
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||||
|
} else {
|
||||||
|
nodep->taskp(ftaskp);
|
||||||
|
nodep->dtypeFrom(ftaskp);
|
||||||
|
if (VN_IS(ftaskp, Task)) nodep->makeStatement();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
classp = classp->extendsp() ? classp->extendsp()->classp() : nullptr;
|
classp = classp->extendsp() ? classp->extendsp()->classp() : nullptr;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
%Error-UNSUPPORTED: t/t_class2.v:35:16: Unsupported: Class '::' references: 'Cls'
|
|
||||||
35 | if (Cls::ENUM_VAL != 22) $stop;
|
|
||||||
| ^~~~~~~~
|
|
||||||
%Error: Internal Error: t/t_class2.v:35:11: ../V3LinkDot.cpp:#: Bad package link
|
|
||||||
35 | if (Cls::ENUM_VAL != 22) $stop;
|
|
||||||
| ^~~
|
|
||||||
... See the manual and https://verilator.org for more assistance.
|
|
||||||
|
|
@ -11,13 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||||
scenarios(simulator => 1);
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
compile(
|
compile(
|
||||||
fails => $Self->{vlt_all},
|
|
||||||
expect_filename => $Self->{golden_filename},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
execute(
|
execute(
|
||||||
check_finished => 1,
|
check_finished => 1,
|
||||||
) if !$Self->{vlt_all};
|
);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
1;
|
1;
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,14 @@ endclass : Cls
|
||||||
Cls c;
|
Cls c;
|
||||||
Cls d;
|
Cls d;
|
||||||
|
|
||||||
|
Cls::enum_t e;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// Alternate between two versions to make sure we don't
|
// Alternate between two versions to make sure we don't
|
||||||
// constant propagate between them.
|
// constant propagate between them.
|
||||||
c = new;
|
c = new;
|
||||||
d = new;
|
d = new;
|
||||||
|
e = Cls::ENUM_VAL;
|
||||||
c.imembera = 10;
|
c.imembera = 10;
|
||||||
d.imembera = 11;
|
d.imembera = 11;
|
||||||
c.imemberb = 20;
|
c.imemberb = 20;
|
||||||
|
|
@ -34,6 +37,8 @@ endclass : Cls
|
||||||
if (Pkg::ENUMP_VAL != 33) $stop;
|
if (Pkg::ENUMP_VAL != 33) $stop;
|
||||||
if (Cls::ENUM_VAL != 22) $stop;
|
if (Cls::ENUM_VAL != 22) $stop;
|
||||||
if (c.ENUM_VAL != 22) $stop;
|
if (c.ENUM_VAL != 22) $stop;
|
||||||
|
if (e != Cls::ENUM_VAL) $stop;
|
||||||
|
if (e != 22) $stop;
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
%Error-UNSUPPORTED: t/t_class_name.v:12:16: Unsupported: 'static' class method
|
|
||||||
: ... In instance t
|
|
||||||
12 | static task static_name;
|
|
||||||
| ^~~~~~~~~~~
|
|
||||||
%Error: Exiting due to
|
|
||||||
|
|
@ -11,13 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||||
scenarios(simulator => 1);
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
compile(
|
compile(
|
||||||
fails => $Self->{vlt_all},
|
|
||||||
expect_filename => $Self->{golden_filename},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
execute(
|
execute(
|
||||||
check_finished => 1,
|
check_finished => 1,
|
||||||
) if !$Self->{vlt_all};
|
);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
1;
|
1;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2020 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
class Cls;
|
||||||
|
|
||||||
|
static task static_task(int x);
|
||||||
|
$write("Called static task: %d\n", x);
|
||||||
|
if (x != 16) $stop;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
static function int static_function(int x);
|
||||||
|
$write("Called static function: %d\n", x);
|
||||||
|
if (x != 23) $stop;
|
||||||
|
return 42;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endclass : Cls
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/);
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
int x;
|
||||||
|
Cls::static_task(16);
|
||||||
|
x = Cls::static_function(23);
|
||||||
|
$write("Static function result: %d\n", x);
|
||||||
|
if (x != 42) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
%Error-UNSUPPORTED: t/t_class_typedef.v:12:4: Unsupported: Class '::' reference
|
|
||||||
12 | uvm_resource_types::rsrc_q_t rtab [string];
|
|
||||||
| ^~~~~~~~~~~~~~~~~~
|
|
||||||
%Error: t/t_class_typedef.v:12:24: Can't find typedef: 'rsrc_q_t'
|
|
||||||
12 | uvm_resource_types::rsrc_q_t rtab [string];
|
|
||||||
| ^~~~~~~~
|
|
||||||
%Error-UNSUPPORTED: t/t_class_typedef.v:14:4: Unsupported: Class '::' reference
|
|
||||||
14 | uvm_resource_types#(1,2,3)::rsrc_q_t rtab_paramed [string];
|
|
||||||
| ^~~~~~~~~~~~~~~~~~
|
|
||||||
%Error: t/t_class_typedef.v:14:32: Can't find typedef: 'rsrc_q_t'
|
|
||||||
14 | uvm_resource_types#(1,2,3)::rsrc_q_t rtab_paramed [string];
|
|
||||||
| ^~~~~~~~
|
|
||||||
%Error: Exiting due to
|
|
||||||
|
|
@ -11,13 +11,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||||
scenarios(simulator => 1);
|
scenarios(simulator => 1);
|
||||||
|
|
||||||
compile(
|
compile(
|
||||||
fails => $Self->{vlt_all},
|
|
||||||
expect_filename => $Self->{golden_filename},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
execute(
|
execute(
|
||||||
check_finished => 1,
|
check_finished => 1,
|
||||||
) if !$Self->{vlt_all};
|
);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
1;
|
1;
|
||||||
|
|
|
||||||
|
|
@ -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 2003 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;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2020 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/);
|
||||||
|
|
||||||
|
class Cls;
|
||||||
|
|
||||||
|
static function int static_task();
|
||||||
|
return 42;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endclass : Cls
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
if (Cls::static_task() != 42) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -2,10 +2,6 @@
|
||||||
: ... In instance t
|
: ... In instance t
|
||||||
20 | static int st = 2; st++; return st;
|
20 | static int st = 2; st++; return st;
|
||||||
| ^~
|
| ^~
|
||||||
%Error-UNSUPPORTED: t/t_var_static.v:27:11: Unsupported: 'static' function/task variables
|
|
||||||
: ... In instance t
|
|
||||||
27 | int st = 2; st++; return st;
|
|
||||||
| ^~
|
|
||||||
%Error-UNSUPPORTED: t/t_var_static.v:30:18: Unsupported: 'static' function/task variables
|
%Error-UNSUPPORTED: t/t_var_static.v:30:18: Unsupported: 'static' function/task variables
|
||||||
: ... In instance t
|
: ... In instance t
|
||||||
30 | static int st = 2; st++; return st;
|
30 | static int st = 2; st++; return st;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue