mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 12:17:35 +00:00
Internals: Parsing and tests for class interfaces
This commit is contained in:
parent
ba8700f99d
commit
8d2be855f5
@ -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)
|
||||
|
@ -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.'
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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 ]"
|
||||
|
@ -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;
|
||||
| ^~~~~~~~~~
|
||||
|
14
test_regress/t/t_implements.out
Normal file
14
test_regress/t/t_implements.out
Normal 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
23
test_regress/t/t_implements.pl
Executable 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;
|
70
test_regress/t/t_implements.v
Normal file
70
test_regress/t/t_implements.v
Normal 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
|
5
test_regress/t/t_implements_collision.out
Normal file
5
test_regress/t/t_implements_collision.out
Normal 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
|
23
test_regress/t/t_implements_collision.pl
Executable file
23
test_regress/t/t_implements_collision.pl
Executable 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;
|
37
test_regress/t/t_implements_collision.v
Normal file
37
test_regress/t/t_implements_collision.v
Normal 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
|
5
test_regress/t/t_implements_collision_bad.out
Normal file
5
test_regress/t/t_implements_collision_bad.out
Normal 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
|
19
test_regress/t/t_implements_collision_bad.pl
Executable file
19
test_regress/t/t_implements_collision_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
24
test_regress/t/t_implements_collision_bad.v
Normal file
24
test_regress/t/t_implements_collision_bad.v
Normal 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
|
11
test_regress/t/t_implements_contents_bad.out
Normal file
11
test_regress/t/t_implements_contents_bad.out
Normal 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
|
19
test_regress/t/t_implements_contents_bad.pl
Executable file
19
test_regress/t/t_implements_contents_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
14
test_regress/t/t_implements_contents_bad.v
Normal file
14
test_regress/t/t_implements_contents_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, 2023 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
interface class Icls;
|
||||
int badi;
|
||||
task badtask;
|
||||
endtask
|
||||
endclass
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
endmodule
|
5
test_regress/t/t_implements_missing_bad.out
Normal file
5
test_regress/t/t_implements_missing_bad.out
Normal 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
|
19
test_regress/t/t_implements_missing_bad.pl
Executable file
19
test_regress/t/t_implements_missing_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
21
test_regress/t/t_implements_missing_bad.v
Normal file
21
test_regress/t/t_implements_missing_bad.v
Normal 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
|
5
test_regress/t/t_implements_nested_bad.out
Normal file
5
test_regress/t/t_implements_nested_bad.out
Normal 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
|
19
test_regress/t/t_implements_nested_bad.pl
Executable file
19
test_regress/t/t_implements_nested_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
14
test_regress/t/t_implements_nested_bad.v
Normal file
14
test_regress/t/t_implements_nested_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, 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
|
5
test_regress/t/t_implements_new_bad.out
Normal file
5
test_regress/t/t_implements_new_bad.out
Normal 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
|
19
test_regress/t/t_implements_new_bad.pl
Executable file
19
test_regress/t/t_implements_new_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
17
test_regress/t/t_implements_new_bad.v
Normal file
17
test_regress/t/t_implements_new_bad.v
Normal 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
|
5
test_regress/t/t_implements_noinherit_bad.out
Normal file
5
test_regress/t/t_implements_noinherit_bad.out
Normal 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
|
19
test_regress/t/t_implements_noinherit_bad.pl
Executable file
19
test_regress/t/t_implements_noinherit_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
20
test_regress/t/t_implements_noinherit_bad.v
Normal file
20
test_regress/t/t_implements_noinherit_bad.v
Normal 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
|
13
test_regress/t/t_implements_noninterface_bad.out
Normal file
13
test_regress/t/t_implements_noninterface_bad.out
Normal 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
|
19
test_regress/t/t_implements_noninterface_bad.pl
Executable file
19
test_regress/t/t_implements_noninterface_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
21
test_regress/t/t_implements_noninterface_bad.v
Normal file
21
test_regress/t/t_implements_noninterface_bad.v
Normal 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
|
4
test_regress/t/t_implements_notfound_bad.out
Normal file
4
test_regress/t/t_implements_notfound_bad.out
Normal 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
|
19
test_regress/t/t_implements_notfound_bad.pl
Executable file
19
test_regress/t/t_implements_notfound_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(linter => 1);
|
||||
|
||||
lint(
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
12
test_regress/t/t_implements_notfound_bad.v
Normal file
12
test_regress/t/t_implements_notfound_bad.v
Normal 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
|
Loading…
Reference in New Issue
Block a user