forked from github/verilator
Support virtual class
This commit is contained in:
parent
3d073c9534
commit
917d3b0fb3
2
Changes
2
Changes
@ -9,7 +9,7 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
** Support hierarchical Verilation (#2206). [Yutetsu TAKATSUKASA]
|
||||
|
||||
**** Support class extern.
|
||||
**** Support (with limitations) class extern, class extends, virtual class.
|
||||
|
||||
**** Support $urandom, $urandom_range without stability.
|
||||
|
||||
|
@ -1036,7 +1036,7 @@ private:
|
||||
// Unless public, v3Descope will not uniquify function names even if duplicate per-scope,
|
||||
// so make it unique now.
|
||||
string suffix; // So, make them unique
|
||||
if (!nodep->taskPublic()) suffix = "_" + m_scopep->nameDotless();
|
||||
if (!nodep->taskPublic() && !nodep->classMethod()) suffix = "_" + m_scopep->nameDotless();
|
||||
string name = ((nodep->name() == "new") ? "new" : prefix + nodep->name() + suffix);
|
||||
AstCFunc* cfuncp = new AstCFunc(
|
||||
nodep->fileline(), name, m_scopep,
|
||||
@ -1049,6 +1049,7 @@ private:
|
||||
cfuncp->dpiExport(nodep->dpiExport());
|
||||
cfuncp->dpiImportWrapper(nodep->dpiImport());
|
||||
cfuncp->isStatic(!(nodep->dpiImport() || nodep->taskPublic() || nodep->classMethod()));
|
||||
cfuncp->isVirtual(nodep->isVirtual());
|
||||
cfuncp->pure(nodep->pure());
|
||||
if (nodep->name() == "new") {
|
||||
cfuncp->isConstructor(true);
|
||||
|
@ -2028,7 +2028,6 @@ private:
|
||||
virtual void visit(AstClass* nodep) override {
|
||||
if (nodep->didWidthAndSet()) return;
|
||||
userIterateChildren(nodep, nullptr); // First size all members
|
||||
if (nodep->isVirtual()) nodep->v3warn(E_UNSUPPORTED, "Unsupported: virtual class");
|
||||
nodep->repairCache();
|
||||
}
|
||||
virtual void visit(AstClassRefDType* nodep) override {
|
||||
@ -2739,7 +2738,10 @@ private:
|
||||
// Either made explicitly or V3LinkDot made implicitly
|
||||
classp->v3fatalSrc("Can't find class's new");
|
||||
}
|
||||
|
||||
if (classp->isVirtual()) {
|
||||
nodep->v3error(
|
||||
"Illegal to call 'new' using an abstract virtual class (IEEE 1800-2017 8.21)");
|
||||
}
|
||||
userIterate(nodep->taskp(), nullptr);
|
||||
userIterateChildren(nodep, nullptr);
|
||||
processFTaskRefArgs(nodep);
|
||||
@ -3771,9 +3773,6 @@ private:
|
||||
nodep->didWidth(true);
|
||||
return;
|
||||
}
|
||||
if (nodep->isVirtual() || nodep->pureVirtual()) {
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: 'virtual' class method");
|
||||
}
|
||||
// Function hasn't been widthed, so make it so.
|
||||
// Would use user1 etc, but V3Width called from too many places to spend a user
|
||||
nodep->doingWidth(true);
|
||||
|
@ -1,7 +0,0 @@
|
||||
%Error-UNSUPPORTED: t/t_class_virtual.v:8:25: Unsupported: 'virtual' class method
|
||||
8 | virtual function int hello;
|
||||
| ^~~~~
|
||||
%Error-UNSUPPORTED: t/t_class_virtual.v:7:9: Unsupported: virtual class
|
||||
7 | virtual class VBase;
|
||||
| ^~~~~
|
||||
%Error: Exiting due to
|
@ -8,11 +8,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
scenarios(simulator => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
@ -10,14 +10,13 @@ virtual class VBase;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
`ifndef VERILATOR
|
||||
virtual class VA extends VBase;
|
||||
class VA extends VBase;
|
||||
virtual function int hello;
|
||||
return 2;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
virtual class VB extends VBase;
|
||||
class VB extends VBase;
|
||||
virtual function int hello;
|
||||
return 3;
|
||||
endfunction
|
||||
@ -28,6 +27,10 @@ module t;
|
||||
VA va = new;
|
||||
VB vb = new;
|
||||
VBase b;
|
||||
|
||||
if (va.hello() != 2) $stop;
|
||||
if (vb.hello() != 3) $stop;
|
||||
|
||||
b = va;
|
||||
if (b.hello() != 2) $stop;
|
||||
b = vb;
|
||||
@ -36,4 +39,3 @@ module t;
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
`endif
|
||||
|
5
test_regress/t/t_class_virtual_bad.out
Normal file
5
test_regress/t/t_class_virtual_bad.out
Normal file
@ -0,0 +1,5 @@
|
||||
%Error: t/t_class_virtual_bad.v:12:17: Illegal to call 'new' using an abstract virtual class (IEEE 1800-2017 8.21)
|
||||
: ... In instance t
|
||||
12 | VBase b = new;
|
||||
| ^~~
|
||||
%Error: Exiting due to
|
19
test_regress/t/t_class_virtual_bad.pl
Executable file
19
test_regress/t/t_class_virtual_bad.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 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(vlt => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
14
test_regress/t/t_class_virtual_bad.v
Normal file
14
test_regress/t/t_class_virtual_bad.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, 2019 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
virtual class VBase;
|
||||
endclass
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
VBase b = new; // Error
|
||||
end
|
||||
endmodule
|
@ -8,11 +8,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(vlt => 1);
|
||||
scenarios(simulator => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
compile(
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
@ -4,6 +4,21 @@
|
||||
// any use, without warranty, 2019 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
virtual class VC;
|
||||
pure virtual task hello();
|
||||
virtual class VBase;
|
||||
pure virtual function int hello();
|
||||
endclass
|
||||
|
||||
class VA extends VBase;
|
||||
virtual function int hello;
|
||||
return 2;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
VA va = new;
|
||||
if (va.hello() != 2) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user