Internals: Parsing and tests for class interfaces

This commit is contained in:
Wilson Snyder 2023-01-28 16:30:47 -05:00
parent ba8700f99d
commit 8d2be855f5
35 changed files with 585 additions and 19 deletions

View File

@ -799,19 +799,24 @@ public:
VTimescale timeunit() const { return m_timeunit; }
};
class AstClassExtends final : public AstNode {
// class extends class name, or class implements class name
// Children: List of AstParseRef for packages/classes
// during early parse, then moves to dtype
// @astgen op1 := childDTypep : Optional[AstNodeDType]
// @astgen op2 := classOrPkgsp : Optional[AstNode]
const bool m_isImplements = false; // class implements
public:
AstClassExtends(FileLine* fl, AstNode* classOrPkgsp)
: ASTGEN_SUPER_ClassExtends(fl) {
AstClassExtends(FileLine* fl, AstNode* classOrPkgsp, bool isImplements)
: ASTGEN_SUPER_ClassExtends(fl)
, m_isImplements{isImplements} {
this->classOrPkgsp(classOrPkgsp); // Only for parser
}
ASTGEN_MEMBERS_AstClassExtends;
void dump(std::ostream& str) const override;
bool hasDType() const override { return true; }
string verilogKwd() const override { return "extends"; }
string verilogKwd() const override { return isImplements() ? "implements" : "extends"; }
AstClass* classp() const; // Class being extended (after link)
bool isImplements() const { return m_isImplements; }
};
class AstClocking final : public AstNode {
// Parents: MODULE
@ -2094,14 +2099,15 @@ public:
// === AstNodeModule ===
class AstClass final : public AstNodeModule {
// @astgen op4 := extendsp : Optional[AstClassExtends]
// @astgen op4 := extendsp : List[AstClassExtends]
// TYPES
using MemberNameMap = std::map<const std::string, AstNode*>;
// MEMBERS
MemberNameMap m_members; // Members or method children
AstClassPackage* m_classOrPackagep = nullptr; // Class package this is under
bool m_virtual = false; // Virtual class
bool m_extended = false; // Is extension or extended by other classes
bool m_interfaceClass = false; // Interface class
bool m_virtual = false; // Virtual class
void insertCache(AstNode* nodep);
public:
@ -2129,6 +2135,8 @@ public:
}
bool isExtended() const { return m_extended; }
void isExtended(bool flag) { m_extended = flag; }
bool isInterfaceClass() const { return m_interfaceClass; }
void isInterfaceClass(bool flag) { m_interfaceClass = flag; }
bool isVirtual() const { return m_virtual; }
void isVirtual(bool flag) { m_virtual = flag; }
// Return true if this class is an extension of base class (SLOW)

View File

@ -1458,6 +1458,7 @@ bool AstClass::isClassExtendedFrom(const AstClass* refClassp, const AstClass* ba
void AstClass::dump(std::ostream& str) const {
this->AstNodeModule::dump(str);
if (isExtended()) str << " [EXT]";
if (isInterfaceClass()) str << " [IFCCLS]";
if (isVirtual()) str << " [VIRT]";
}
const char* AstClass::broken() const {
@ -1471,6 +1472,10 @@ void AstClass::cloneRelink() {
m_classOrPackagep = m_classOrPackagep->clonep();
}
}
void AstClassExtends::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (isImplements()) str << " [IMPLEMENTS]";
}
AstClass* AstClassExtends::classp() const {
const AstClassRefDType* refp = VN_CAST(dtypep(), ClassRefDType);
if (VL_UNLIKELY(!refp)) { // LinkDot uses this for 'super.'

View File

@ -748,6 +748,7 @@ class LinkDotFindVisitor final : public VNVisitor {
string m_scope; // Scope text
const AstNodeBlock* m_blockp = nullptr; // Current Begin/end block
const AstNodeFTask* m_ftaskp = nullptr; // Current function/task
bool m_inInterfaceClass = false; // Inside a class interface
bool m_inRecursion = false; // Inside a recursive module
int m_paramNum = 0; // Parameter number, for position based connection
bool m_explicitNew = false; // Hit a "new" function
@ -916,6 +917,9 @@ 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);
if (nodep->isInterfaceClass()) {
nodep->v3warn(E_UNSUPPORTED, "Unsupported: interface classes");
}
// Remove classes that have void params, as they were only used for the parameterization
// step and will not be instantiated
if (m_statep->removeVoidParamedClasses()) {
@ -930,6 +934,7 @@ class LinkDotFindVisitor final : public VNVisitor {
}
VL_RESTORER(m_scope);
VL_RESTORER(m_classOrPackagep);
VL_RESTORER(m_inInterfaceClass);
VL_RESTORER(m_modSymp);
VL_RESTORER(m_curSymp);
VL_RESTORER(m_paramNum);
@ -940,6 +945,7 @@ class LinkDotFindVisitor final : public VNVisitor {
VSymEnt* const upperSymp = m_curSymp;
m_scope = m_scope + "." + nodep->name();
m_classOrPackagep = nodep;
m_inInterfaceClass = nodep->isInterfaceClass();
m_curSymp = m_modSymp
= m_statep->insertBlock(upperSymp, nodep->name(), nodep, m_classOrPackagep);
m_statep->insertMap(m_curSymp, m_scope);
@ -1068,6 +1074,10 @@ class LinkDotFindVisitor final : public VNVisitor {
VL_RESTORER(m_curSymp);
VSymEnt* upSymp = m_curSymp;
{
if (m_inInterfaceClass && !nodep->pureVirtual()) {
nodep->v3error("Interface class functions must be pure virtual"
<< " (IEEE 1800-2017 8.26)");
}
// Change to appropriate package if extern declaration (vs definition)
if (nodep->classOrPackagep()) {
AstClassOrPackageRef* const cpackagerefp
@ -1190,6 +1200,11 @@ class LinkDotFindVisitor final : public VNVisitor {
// Var: Remember its name for later resolution
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Var not under module?");
iterateChildren(nodep);
if (m_inInterfaceClass && !nodep->isParam() && !nodep->isFuncLocal()
&& !nodep->isFuncReturn()) {
nodep->v3error("Interface class cannot contain non-parameter members"
<< " (IEEE 1800-2017 8.26)");
}
if (!m_statep->forScopeCreation()) {
// Find under either a task or the module's vars
const VSymEnt* foundp = m_curSymp->findIdFallback(nodep->name());
@ -3226,6 +3241,16 @@ private:
if (classp == nodep) {
cextp->v3error("Attempting to extend class "
<< nodep->prettyNameQ() << " from itself");
} else if (cextp->isImplements() && !classp->isInterfaceClass()) {
cextp->v3error(
"Attempting to implement from non-interface class "
<< classp->prettyNameQ() << '\n'
<< "... Suggest use 'extends'");
} else if (!cextp->isImplements() && !nodep->isInterfaceClass()
&& classp->isInterfaceClass()) {
cextp->v3error("Attempting to extend from interface class "
<< classp->prettyNameQ() << '\n'
<< "... Suggest use 'implements'");
} else {
cextp->childDTypep(classRefDtypep);
classp->isExtended(true);
@ -3240,8 +3265,9 @@ private:
const string suggest = m_statep->suggestSymFallback(
m_curSymp, cpackagerefp->name(), LinkNodeMatcherClass{});
cpackagerefp->v3error(
"Class to extend not found: "
<< cpackagerefp->prettyNameQ() << '\n'
"Class for '"
<< cextp->verilogKwd() // extends/implements
<< "' not found: " << cpackagerefp->prettyNameQ() << '\n'
<< (suggest.empty() ? "" : cpackagerefp->warnMore() + suggest));
}
}

View File

@ -94,6 +94,7 @@ public:
bool m_varDeclTyped = false; // Var got reg/wire for dedup check
bool m_pinAnsi = false; // In ANSI port list
bool m_tracingParse = true; // Tracing disable for parser
bool m_inImplements = false; // Is inside class implements list
bool m_insideProperty = false; // Is inside property declaration
bool m_typedPropertyPort = false; // True if typed property port occurred on port lists
bool m_modportImpExpActive
@ -6466,8 +6467,8 @@ class_declaration<nodep>: // ==IEEE: part of class_declaration
}
/*cont*/ class_itemListE yENDCLASS endLabelE
{ $$ = $1; $1->addMembersp($2);
$1->extendsp($3);
$1->addMembersp($4);
$1->addExtendsp($3);
$1->addExtendsp($4);
$1->addMembersp($7);
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7, $1, $9); }
@ -6483,9 +6484,10 @@ classFront<classp>: // IEEE: part of class_declaration
// // IEEE: part of interface_class_declaration
| yINTERFACE yCLASS lifetimeE idAny/*class_identifier*/
{ $$ = new AstClass{$2, *$4};
$$->isInterfaceClass(true);
$$->lifetime($3);
SYMP->pushNew($<classp>$);
BBUNSUP($2, "Unsupported: interface classes"); }
v3Global.setHasClasses(); }
;
classVirtualE<cbool>:
@ -6510,25 +6512,30 @@ classExtendsList<classExtendsp>: // IEEE: part of class_declaration
classExtendsOne<classExtendsp>: // IEEE: part of class_declaration
class_typeExtImpList
{ $$ = new AstClassExtends{$1->fileline(), $1};
{ $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements};
$<scp>$ = $<scp>1; }
//
| class_typeExtImpList '(' list_of_argumentsE ')'
{ $$ = new AstClassExtends{$1->fileline(), $1};
{ $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements};
$<scp>$ = $<scp>1;
if ($3) BBUNSUP($3, "Unsupported: extends with parameters"); }
;
classImplementsE<nodep>: // IEEE: part of class_declaration
classImplementsE<classExtendsp>: // IEEE: part of class_declaration
// // All 1800-2012
/* empty */ { $$ = nullptr; }
| yIMPLEMENTS classImplementsList { $$ = $2; }
/* empty */ { $$ = nullptr; $<scp>$ = nullptr; }
| yIMPLEMENTS
/*mid*/ { GRAMMARP->m_inImplements = true; $<scp>$ = nullptr; }
/*cont*/ classImplementsList
{ $$ = $3; $<scp>$ = $<scp>3;
GRAMMARP->m_inImplements = false; }
;
classImplementsList<nodep>: // IEEE: part of class_declaration
classImplementsList<classExtendsp>: // IEEE: part of class_declaration
// // All 1800-2012
class_typeExtImpList { $$ = nullptr; BBUNSUP($1, "Unsupported: implements class"); }
| classImplementsList ',' class_typeExtImpList { $$ = addNextNull($1, $3); }
classExtendsOne { $$ = $1; $<scp>$ = $<scp>1; }
| classImplementsList ',' classExtendsOne
{ $$ = addNextNull($1, $3); $<scp>$ = $<scp>3; }
;
class_typeExtImpList<nodep>: // IEEE: class_type: "[package_scope] id [ parameter_value_assignment ]"

View File

@ -1,4 +1,4 @@
%Error: t/t_class_extends_nf_bad.v:10:19: Class to extend not found: 'IsNotFound'
%Error: t/t_class_extends_nf_bad.v:10:19: Class for 'extends' not found: 'IsNotFound'
: ... Suggested alternative: 'IsFound'
10 | class Cls extends IsNotFound;
| ^~~~~~~~~~

View File

@ -0,0 +1,14 @@
%Error-UNSUPPORTED: t/t_implements.v:7:11: Unsupported: interface classes
7 | interface class Icempty;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_implements.v:10:11: Unsupported: interface classes
10 | interface class Icls1;
| ^~~~~
%Error-UNSUPPORTED: t/t_implements.v:17:11: Unsupported: interface classes
17 | interface class Iext1 extends Icls1;
| ^~~~~
%Error-UNSUPPORTED: t/t_implements.v:21:11: Unsupported: interface classes
21 | interface class Icls2;
| ^~~~~
%Error: Exiting due to

23
test_regress/t/t_implements.pl Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2019 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(
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);
execute(
check_finished => 1,
) if !$Self->{vlt_all};
ok(1);
1;

View File

@ -0,0 +1,70 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface class Icempty;
endclass : Icempty
interface class Icls1;
localparam LP1 = 1;
pure virtual function int icf1;
pure virtual function int icfboth;
pure virtual function int icfpartial;
endclass
interface class Iext1 extends Icls1;
pure virtual function int icf101;
endclass
interface class Icls2;
pure virtual function int icf2;
pure virtual function int icfboth;
endclass
virtual class Base implements Iext1, Icls2;
virtual function int icf1;
return 1;
endfunction
virtual function int icf101;
return 101;
endfunction
virtual function int icf2;
return 2;
endfunction
virtual function int icfboth;
return 3;
endfunction
pure virtual function int icfpartial;
endclass
class Cls extends Base;
virtual function int icfpartial;
return 62;
endfunction
endclass
module t(/*AUTOARG*/);
Cls c;
Iext1 i1;
initial begin
if (Icls1::LP1 != 1) $stop;
c = new;
if (c.icf1() != 1) $stop;
if (c.icf101() != 101) $stop;
if (c.icf2() != 2) $stop;
if (c.icfpartial() != 62) $stop;
i1 = c;
if (i1.icf1() != 1) $stop;
if (i1.icf101() != 101) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,5 @@
%Error-UNSUPPORTED: t/t_implements_collision.v:15:41: Multiple inheritance illegal on non-interface classes (IEEE 1800-2017 8.13), and unsupported for interface classes.
15 | interface class IclsBoth extends Icls1, Icls2;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View File

@ -0,0 +1,23 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2019 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(
fails => $Self->{vlt_all},
expect_filename => $Self->{golden_filename},
);
execute(
check_finished => 1,
) if !$Self->{vlt_all};
ok(1);
1;

View File

@ -0,0 +1,37 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface class Icls1;
pure virtual function int icfboth;
endclass
interface class Icls2;
pure virtual function int icfboth;
endclass
interface class IclsBoth extends Icls1, Icls2;
pure virtual function int icfboth;
endclass
class Cls implements IclsBoth;
virtual function int icfboth;
return 3;
endfunction
endclass
module t(/*AUTOARG*/);
Cls c;
initial begin
c = new;
if (c.ifcboth() != 3) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,5 @@
%Error-UNSUPPORTED: t/t_implements_collision_bad.v:15:41: Multiple inheritance illegal on non-interface classes (IEEE 1800-2017 8.13), and unsupported for interface classes.
15 | interface class IclsBoth extends Icls1, Icls2;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -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, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface class Icls1;
pure virtual function int icfboth;
endclass
interface class Icls2;
pure virtual function int icfboth;
endclass
interface class IclsBoth extends Icls1, Icls2;
// Bad collision on icfboth
endclass
class Cls implements IclsBoth;
endclass
module t (/*AUTOARG*/);
Cls c;
endmodule

View File

@ -0,0 +1,11 @@
%Error-UNSUPPORTED: t/t_implements_contents_bad.v:7:11: Unsupported: interface classes
7 | interface class Icls;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_implements_contents_bad.v:8:8: Interface class cannot contain non-parameter members (IEEE 1800-2017 8.26)
8 | int badi;
| ^~~~
%Error: t/t_implements_contents_bad.v:9:9: Interface class functions must be pure virtual (IEEE 1800-2017 8.26)
9 | task badtask;
| ^~~~~~~
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View 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, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface class Icls;
int badi;
task badtask;
endtask
endclass
module t (/*AUTOARG*/);
endmodule

View File

@ -0,0 +1,5 @@
%Error-UNSUPPORTED: t/t_implements_missing_bad.v:7:11: Unsupported: interface classes
7 | interface class Icls1;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,21 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface class Icls1;
pure virtual function int icf1;
pure virtual function int icf2;
endclass
class Cls implements Icls1;
virtual function int icf1;
return 1;
endfunction
// Bad missing icf2
endclass
module t (/*AUTOARG*/);
Cls c;
endmodule

View File

@ -0,0 +1,5 @@
%Error-UNSUPPORTED: t/t_implements_nested_bad.v:8:14: Unsupported: class within class
8 | interface class bad_cannot_nest;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View 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, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
class Cls;
interface class bad_cannot_nest;
endclass
endclass
module t (/*AUTOARG*/);
Cls c;
endmodule

View File

@ -0,0 +1,5 @@
%Error-UNSUPPORTED: t/t_implements_new_bad.v:7:11: Unsupported: interface classes
7 | interface class Icls;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,17 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface class Icls;
endclass
module t (/*AUTOARG*/);
Icls c;
initial begin
c = new; // Bad
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,5 @@
%Error-UNSUPPORTED: t/t_implements_noinherit_bad.v:7:11: Unsupported: interface classes
7 | interface class Icls;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,20 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
interface class Icls;
localparam IP = 1;
typedef int i_t;
endclass
class Cls implements Icls;
function void f;
$display(IP); // Bad
endfunction
endclass
module t (/*AUTOARG*/);
Cls c;
endmodule

View File

@ -0,0 +1,13 @@
%Error-UNSUPPORTED: t/t_implements_noninterface_bad.v:13:11: Unsupported: interface classes
13 | interface class Icls;
| ^~~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: t/t_implements_noninterface_bad.v:10:26: Attempting to implement from non-interface class 'NotIcls'
... Suggest use 'extends'
10 | class ClsBad1 implements NotIcls;
| ^~~~~~~
%Error: t/t_implements_noninterface_bad.v:16:23: Attempting to extend from interface class 'Icls'
... Suggest use 'implements'
16 | class ClsBad2 extends Icls;
| ^~~~
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,21 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
class NotIcls;
endclass
class ClsBad1 implements NotIcls;
endclass
interface class Icls;
endclass
class ClsBad2 extends Icls;
endclass
module t (/*AUTOARG*/);
Cls c;
endmodule

View File

@ -0,0 +1,4 @@
%Error: t/t_implements_notfound_bad.v:7:23: Class for 'implements' not found: 'Inotfound'
7 | class ClsI implements Inotfound;
| ^~~~~~~~~
%Error: Exiting due to

View 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(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,12 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
class ClsI implements Inotfound;
endclass
module t (/*AUTOARG*/);
ClsI ci;
endmodule