diff --git a/include/std.sv b/include/std.sv new file mode 100644 index 000000000..7b27bc98b --- /dev/null +++ b/include/std.sv @@ -0,0 +1,106 @@ +// DESCRIPTION: Verilator: built-in packages and classes +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2022 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 +// +//************************************************************************* + +// verilator lint_off DECLFILENAME +// verilator lint_off TIMESCALEMOD +// verilator lint_off UNUSEDSIGNAL +package std; + class mailbox #(type T); + protected int m_bound; + protected T m_queue[$]; + + function new(int bound = 0); + m_bound = bound; + endfunction + + function int num(); + return m_queue.size(); + endfunction + + task put(T message); + `ifdef VERILATOR_TIMING + if (m_bound != 0) + wait (m_queue.size() < m_bound); + m_queue.push_back(message); + `endif + endtask + + function int try_put(T message); + if (num() < m_bound) begin + m_queue.push_back(message); + return 1; + end + return 0; + endfunction + + task get(ref T message); + `ifdef VERILATOR_TIMING + wait (m_queue.size() > 0); + message = m_queue.pop_front(); + `endif + endtask + + function int try_get(ref T message); + if (num() > 0) begin + message = m_queue.pop_front(); + return 1; + end + return 0; + endfunction + + task peek(ref T message); + `ifdef VERILATOR_TIMING + wait (m_queue.size() > 0); + message = m_queue[0]; + `endif + endtask + + function int try_peek(ref T message); + if (num() > 0) begin + message = m_queue[0]; + return 1; + end + return 0; + endfunction + endclass + + class semaphore; + protected int m_keyCount; + + function new(int keyCount = 0); + m_keyCount = keyCount; + endfunction + + function void put(int keyCount = 1); + m_keyCount += keyCount; + endfunction + + task get(int keyCount = 1); + `ifdef VERILATOR_TIMING + wait (m_keyCount >= keyCount); + m_keyCount -= keyCount; + `endif + endtask + + function int try_get(int keyCount = 1); + if (m_keyCount >= keyCount) begin + m_keyCount -= keyCount; + return 1; + end + return 0; + endfunction + endclass +endpackage + +// verilator lint_off IMPORTSTAR +import std::*; diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 6b816d971..a3ae3b246 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1086,6 +1086,7 @@ class AstNetlist final : public AstNode { AstTypeTable* const m_typeTablep; // Reference to top type table, for faster lookup AstConstPool* const m_constPoolp; // Reference to constant pool, for faster lookup AstPackage* m_dollarUnitPkgp = nullptr; // $unit + AstPackage* m_stdPackagep = nullptr; // SystemVerilog std package AstCFunc* m_evalp = nullptr; // The '_eval' function AstCFunc* m_evalNbap = nullptr; // The '_eval__nba' function AstVarScope* m_dpiExportTriggerp = nullptr; // The DPI export trigger variable @@ -1119,6 +1120,8 @@ public: void dpiExportTriggerp(AstVarScope* varScopep) { m_dpiExportTriggerp = varScopep; } AstVar* delaySchedulerp() const { return m_delaySchedulerp; } void delaySchedulerp(AstVar* const varScopep) { m_delaySchedulerp = varScopep; } + void stdPackagep(AstPackage* const packagep) { m_stdPackagep = packagep; } + AstPackage* stdPackagep() const { return m_stdPackagep; } AstTopScope* topScopep() const { return m_topScopep; } void createTopScope(AstScope* scopep); VTimescale timeunit() const { return m_timeunit; } diff --git a/src/V3Global.cpp b/src/V3Global.cpp index dd9ec4ac5..20daa8177 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -63,6 +63,13 @@ void V3Global::readFiles() { "Cannot find file containing module: "); } + if (usesStdPackage()) { + // Parse the std package + parser.parseFile(new FileLine{FileLine::commandLineFilename()}, + V3Options::getStdPackagePath(), false, + "Cannot find std.sv containing built-in std:: definitions: "); + } + // Read libraries // To be compatible with other simulators, // this needs to be done after the top file is read diff --git a/src/V3Global.h b/src/V3Global.h index 7108f4148..6c8f8dc86 100644 --- a/src/V3Global.h +++ b/src/V3Global.h @@ -107,6 +107,7 @@ class V3Global final { bool m_dpi = false; // Need __Dpi include files bool m_hasEvents = false; // Design uses SystemVerilog named events bool m_hasClasses = false; // Design uses SystemVerilog classes + bool m_usesStdPackage = false; // Design uses the std package bool m_usesTiming = false; // Design uses timing constructs bool m_hasForceableSignals = false; // Need to apply V3Force pass bool m_hasSCTextSections = false; // Has `systemc_* sections that need to be emitted @@ -152,6 +153,8 @@ public: void setHasEvents() { m_hasEvents = true; } bool hasClasses() const { return m_hasClasses; } void setHasClasses() { m_hasClasses = true; } + bool usesStdPackage() const { return m_usesStdPackage; } + void setUsesStdPackage() { m_usesStdPackage = true; } bool usesTiming() const { return m_usesTiming; } void setUsesTiming() { m_usesTiming = true; } bool hasForceableSignals() const { return m_hasForceableSignals; } diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 127d472a3..5d844725c 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -50,6 +50,7 @@ private: using ImplTypedefMap = std::map, AstTypedef*>; // STATE + AstPackage* const m_stdPackagep; // SystemVerilog std package AstVar* m_varp = nullptr; // Variable we're under ImplTypedefMap m_implTypedef; // Created typedefs for each std::unordered_set m_filelines; // Filelines that have been seen @@ -600,6 +601,11 @@ private: VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } + void visit(AstClassOrPackageRef* nodep) override { + if (nodep->name() == "std" && !nodep->classOrPackagep()) { + nodep->classOrPackagep(m_stdPackagep); + } + } void visit(AstNode* nodep) override { // Default: Just iterate @@ -609,7 +615,10 @@ private: public: // CONSTRUCTORS - explicit LinkParseVisitor(AstNetlist* rootp) { iterate(rootp); } + explicit LinkParseVisitor(AstNetlist* rootp) + : m_stdPackagep{rootp->stdPackagep()} { + iterate(rootp); + } ~LinkParseVisitor() override = default; }; diff --git a/src/V3Options.cpp b/src/V3Options.cpp index a345cd810..4f14b672e 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -706,6 +706,8 @@ string V3Options::getenvVERILATOR_ROOT() { return var; } +string V3Options::getStdPackagePath() { return getenvVERILATOR_ROOT() + "/include/std.sv"; } + string V3Options::getSupported(const string& var) { // If update below, also update V3Options::showVersion() if (var == "COROUTINES" && coroutineSupport()) { diff --git a/src/V3Options.h b/src/V3Options.h index 1dcb95edf..6fd2e8ac7 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -666,6 +666,7 @@ public: static string getenvSYSTEMC_INCLUDE(); static string getenvSYSTEMC_LIBDIR(); static string getenvVERILATOR_ROOT(); + static string getStdPackagePath(); static string getSupported(const string& var); static bool systemCSystemWide(); static bool systemCFound(); // SystemC installed, or environment points to it diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index c73b6b64c..e6f1705ca 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -532,14 +532,17 @@ void V3ParseImp::tokenPipelineSym() { && (*(yylval.strp) == "mailbox" // IEEE-standard class || *(yylval.strp) == "process" // IEEE-standard class || *(yylval.strp) == "semaphore")) { // IEEE-standard class + v3Global.setUsesStdPackage(); yylval.scp = nullptr; if (token == yaID__LEX) token = yaID__aTYPE; } else { // Not found yylval.scp = nullptr; if (token == yaID__CC) { - // IEEE does require this, but we may relax this as UVM breaks it, so allow bbox - // for today - if (!v3Global.opt.bboxUnsup()) { + if (!m_afterColonColon && *(yylval.strp) == "std") { + v3Global.setUsesStdPackage(); + } else if (!v3Global.opt.bboxUnsup()) { + // IEEE does require this, but we may relax this as UVM breaks it, so allow + // bbox for today // We'll get a parser error eventually but might not be obvious // is missing package, and this confuses people static int warned = false; @@ -554,6 +557,7 @@ void V3ParseImp::tokenPipelineSym() { } } } + m_afterColonColon = token == yP_COLONCOLON; yylval.token = token; // effectively returns yylval } diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index de7ee0ef7..961e87216 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -150,6 +150,7 @@ class V3ParseImp final { VOptionBool m_unconnectedDrive; // Last unconnected drive int m_lexPrevToken = 0; // previous parsed token (for lexer) + bool m_afterColonColon = false; // The previous token was '::' std::deque m_tokensAhead; // Tokens we parsed ahead of parser std::deque m_stringps; // Created strings for later cleanup diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 3613b6ca3..ab687a457 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -3291,6 +3291,16 @@ private: VL_DANGLING(index_exprp); // May have been edited return VN_AS(nodep->pinsp(), Arg)->exprp(); } + void methodCallWarnTiming(AstMethodCall* const nodep, const std::string& className) { + if (v3Global.opt.timing().isSetFalse()) { + nodep->v3warn(E_NOTIMING, + className << "::" << nodep->name() << "() requires --timing"); + } else if (!v3Global.opt.timing().isSetTrue()) { + nodep->v3warn(E_NEEDTIMINGOPT, "Use --timing or --no-timing to specify how " + << className << "::" << nodep->name() + << "() should be handled"); + } + } void methodCallClass(AstMethodCall* nodep, AstClassRefDType* adtypep) { // No need to width-resolve the class, as it was done when we did the child AstClass* const first_classp = adtypep->classp(); @@ -3300,6 +3310,26 @@ private: } UASSERT_OBJ(first_classp, nodep, "Unlinked"); for (AstClass* classp = first_classp; classp;) { + if (nodep->fileline()->timingOn()) { + if (classp->name() == "semaphore" + || VString::startsWith(classp->name(), "mailbox")) { + // Find the package the class is in + AstNode* pkgItemp = classp; + while (pkgItemp->backp() && pkgItemp->backp()->nextp() == pkgItemp) { + pkgItemp = pkgItemp->backp(); + } + AstPackage* const packagep = VN_CAST(pkgItemp->backp(), Package); + // Check if it's std + if (packagep && packagep->name() == "std") { + if (classp->name() == "semaphore" && nodep->name() == "get") { + methodCallWarnTiming(nodep, "semaphore"); + } else if (nodep->name() == "put" || nodep->name() == "get" + || nodep->name() == "peek") { + methodCallWarnTiming(nodep, "mailbox"); + } + } + } + } if (AstNodeFTask* const ftaskp = VN_CAST(classp->findMember(nodep->name()), NodeFTask)) { userIterate(ftaskp, nullptr); diff --git a/src/verilog.y b/src/verilog.y index 61cb9e552..289b4e6fb 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1162,6 +1162,13 @@ package_declaration: // ==IEEE: package_declaration packageFront: yPACKAGE lifetimeE idAny ';' { $$ = new AstPackage{$3, *$3}; + if ($$->name() == "std") { + if ($$->fileline()->filename() != V3Options::getStdPackagePath()) { + $$->v3error("Redeclaring the 'std' package is not allowed"); + } else { + PARSEP->rootp()->stdPackagep(VN_AS($$, Package)); + } + } $$->inLibrary(true); // packages are always libraries; don't want to make them a "top" $$->lifetime($2); $$->modTrace(GRAMMARP->allTracingOn($$->fileline())); diff --git a/test_regress/t/t_mailbox.out b/test_regress/t/t_mailbox.out deleted file mode 100644 index d09756948..000000000 --- a/test_regress/t/t_mailbox.out +++ /dev/null @@ -1,6 +0,0 @@ -%Error: t/t_mailbox.v:24:4: Can't find typedef: 'mailbox' - 24 | mailbox #(int) m; - | ^~~~~~~ -%Error: Internal Error: t/t_mailbox.v:24:14: ../V3LinkDot.cpp:#: Pin not under instance? - 24 | mailbox #(int) m; - | ^~~ diff --git a/test_regress/t/t_mailbox.pl b/test_regress/t/t_mailbox.pl index 2ad4a887d..d7ae01e91 100755 --- a/test_regress/t/t_mailbox.pl +++ b/test_regress/t/t_mailbox.pl @@ -10,14 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -compile( - fails => $Self->{vlt_all}, - expect_filename => $Self->{golden_filename}, - ); +if (!$Self->have_coroutines) { + skip("No coroutine support"); +} +else { + compile( + verilator_flags2 => ["--exe --main --timing -Wall"], + make_main => 0, + ); -execute( - check_finished => 1, - ) if !$Self->{vlt_all}; + execute( + check_finished => 1, + ); +} ok(1); 1; diff --git a/test_regress/t/t_mailbox.v b/test_regress/t/t_mailbox.v index 64e2ba175..e4402f606 100644 --- a/test_regress/t/t_mailbox.v +++ b/test_regress/t/t_mailbox.v @@ -20,6 +20,7 @@ `define MAILBOX_T mailbox `endif +// verilator lint_off DECLFILENAME module t(/*AUTOARG*/); `MAILBOX_T #(int) m; int msg; diff --git a/test_regress/t/t_mailbox_bad.out b/test_regress/t/t_mailbox_bad.out index 218a34ad3..3ef286864 100644 --- a/test_regress/t/t_mailbox_bad.out +++ b/test_regress/t/t_mailbox_bad.out @@ -1,6 +1,5 @@ -%Error: t/t_mailbox_bad.v:8:4: Can't find typedef: 'mailbox' - 8 | mailbox #(int) m; - | ^~~~~~~ -%Error: Internal Error: t/t_mailbox_bad.v:8:14: ../V3LinkDot.cpp:#: Pin not under instance? - 8 | mailbox #(int) m; - | ^~~ +%Error: t/t_mailbox_bad.v:12:13: Class method 'bad_method' not found in class 'mailbox__Tz1' + : ... In instance t + 12 | if (m.bad_method() != 0) $stop; + | ^~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_mailbox_std.out b/test_regress/t/t_mailbox_std.out deleted file mode 100644 index d09756948..000000000 --- a/test_regress/t/t_mailbox_std.out +++ /dev/null @@ -1,6 +0,0 @@ -%Error: t/t_mailbox.v:24:4: Can't find typedef: 'mailbox' - 24 | mailbox #(int) m; - | ^~~~~~~ -%Error: Internal Error: t/t_mailbox.v:24:14: ../V3LinkDot.cpp:#: Pin not under instance? - 24 | mailbox #(int) m; - | ^~~ diff --git a/test_regress/t/t_mailbox_std.pl b/test_regress/t/t_mailbox_std.pl index 3b640c6e1..54f95ce97 100755 --- a/test_regress/t/t_mailbox_std.pl +++ b/test_regress/t/t_mailbox_std.pl @@ -10,17 +10,21 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -top_filename("t/t_mailbox.v"); +if (!$Self->have_coroutines) { + skip("No coroutine support"); +} +else { + top_filename("t/t_mailbox.v"); -compile( - v_flags2 => ["+define+T_MAILBOX+std::mailbox"], - fails => $Self->{vlt_all}, - expect_filename => $Self->{golden_filename}, - ); + compile( + verilator_flags2 => ["--exe --main --timing -Wall -DMAILBOX_T=std::mailbox"], + make_main => 0, + ); -execute( - check_finished => 1, - ) if !$Self->{vlt_all}; + execute( + check_finished => 1, + ); +} ok(1); 1; diff --git a/test_regress/t/t_notiming.out b/test_regress/t/t_notiming.out index b625df546..e12212acd 100644 --- a/test_regress/t/t_notiming.out +++ b/test_regress/t/t_notiming.out @@ -30,4 +30,20 @@ : ... In instance t 27 | initial #2 $stop; | ^ +%Error-NOTIMING: t/t_notiming.v:33:10: mailbox::put() requires --timing + : ... In instance t + 33 | m.put(i); + | ^~~ +%Error-NOTIMING: t/t_notiming.v:34:10: mailbox::get() requires --timing + : ... In instance t + 34 | m.get(i); + | ^~~ +%Error-NOTIMING: t/t_notiming.v:35:10: mailbox::peek() requires --timing + : ... In instance t + 35 | m.peek(i); + | ^~~~ +%Error-NOTIMING: t/t_notiming.v:36:10: semaphore::get() requires --timing + : ... In instance t + 36 | s.get(); + | ^~~ %Error: Exiting due to diff --git a/test_regress/t/t_notiming.v b/test_regress/t/t_notiming.v index 649888e1f..ae163d23c 100644 --- a/test_regress/t/t_notiming.v +++ b/test_regress/t/t_notiming.v @@ -25,6 +25,16 @@ module t; initial #1 ->e; initial #2 $stop; // timeout + + mailbox#(int) m = new; + semaphore s = new; + initial begin + int i; + m.put(i); + m.get(i); + m.peek(i); + s.get(); + end endmodule `ifdef VERILATOR_TIMING diff --git a/test_regress/t/t_semaphore.out b/test_regress/t/t_semaphore.out deleted file mode 100644 index 95ce89973..000000000 --- a/test_regress/t/t_semaphore.out +++ /dev/null @@ -1,7 +0,0 @@ -%Error: t/t_semaphore.v:21:4: Can't find typedef: 'semaphore' - 21 | semaphore s; - | ^~~~~~~~~ -%Error: t/t_semaphore.v:22:4: Can't find typedef: 'semaphore' - 22 | semaphore s2; - | ^~~~~~~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_semaphore.pl b/test_regress/t/t_semaphore.pl index 2ad4a887d..d7ae01e91 100755 --- a/test_regress/t/t_semaphore.pl +++ b/test_regress/t/t_semaphore.pl @@ -10,14 +10,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -compile( - fails => $Self->{vlt_all}, - expect_filename => $Self->{golden_filename}, - ); +if (!$Self->have_coroutines) { + skip("No coroutine support"); +} +else { + compile( + verilator_flags2 => ["--exe --main --timing -Wall"], + make_main => 0, + ); -execute( - check_finished => 1, - ) if !$Self->{vlt_all}; + execute( + check_finished => 1, + ); +} ok(1); 1; diff --git a/test_regress/t/t_semaphore.v b/test_regress/t/t_semaphore.v index 500fac7e8..6635cff9d 100644 --- a/test_regress/t/t_semaphore.v +++ b/test_regress/t/t_semaphore.v @@ -16,11 +16,11 @@ `define SEMAPHORE_T semaphore `endif +// verilator lint_off DECLFILENAME module t(/*AUTOARG*/); // From UVM: `SEMAPHORE_T s; `SEMAPHORE_T s2; - int msg; initial begin s = new(1); diff --git a/test_regress/t/t_semaphore_bad.out b/test_regress/t/t_semaphore_bad.out index c07616459..2fc1c33cb 100644 --- a/test_regress/t/t_semaphore_bad.out +++ b/test_regress/t/t_semaphore_bad.out @@ -1,4 +1,5 @@ -%Error: t/t_semaphore_bad.v:8:4: Can't find typedef: 'semaphore' - 8 | semaphore s; - | ^~~~~~~~~ +%Error: t/t_semaphore_bad.v:12:13: Class method 'bad_method' not found in class 'semaphore' + : ... In instance t + 12 | if (s.bad_method() != 0) $stop; + | ^~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_semaphore_std.out b/test_regress/t/t_semaphore_std.out deleted file mode 100644 index 95ce89973..000000000 --- a/test_regress/t/t_semaphore_std.out +++ /dev/null @@ -1,7 +0,0 @@ -%Error: t/t_semaphore.v:21:4: Can't find typedef: 'semaphore' - 21 | semaphore s; - | ^~~~~~~~~ -%Error: t/t_semaphore.v:22:4: Can't find typedef: 'semaphore' - 22 | semaphore s2; - | ^~~~~~~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_semaphore_std.pl b/test_regress/t/t_semaphore_std.pl index ece82f871..7fcb5b404 100755 --- a/test_regress/t/t_semaphore_std.pl +++ b/test_regress/t/t_semaphore_std.pl @@ -10,17 +10,21 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -top_filename("t/t_semaphore.v"); +if (!$Self->have_coroutines) { + skip("No coroutine support"); +} +else { + top_filename("t/t_semaphore.v"); -compile( - v_flags2 => ["+define+T_SEMAPHORE+std::semaphore"], - fails => $Self->{vlt_all}, - expect_filename => $Self->{golden_filename}, - ); + compile( + verilator_flags2 => ["--exe --main --timing -Wall -DSEMAPHORE_T=std::semaphore"], + make_main => 0, + ); -execute( - check_finished => 1, - ) if !$Self->{vlt_all}; + execute( + check_finished => 1, + ); +} ok(1); 1; diff --git a/test_regress/t/t_std_identifier.out b/test_regress/t/t_std_identifier.out new file mode 100644 index 000000000..1b970e684 --- /dev/null +++ b/test_regress/t/t_std_identifier.out @@ -0,0 +1,5 @@ +%Error-PKGNODECL: t/t_std_identifier.v:16:20: Package/class 'std' not found, and needs to be predeclared (IEEE 1800-2017 26.3) + 16 | int baz = foo::std::bar; + | ^~~ + ... For error description see https://verilator.org/warn/PKGNODECL?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_semaphore_parse.pl b/test_regress/t/t_std_identifier.pl similarity index 65% rename from test_regress/t/t_semaphore_parse.pl rename to test_regress/t/t_std_identifier.pl index 8149e4600..3e2acea9f 100755 --- a/test_regress/t/t_semaphore_parse.pl +++ b/test_regress/t/t_std_identifier.pl @@ -2,18 +2,21 @@ 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 +# Copyright 2022 by Antmicro Ltd. 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); - -top_filename("t_semaphore.v"); +scenarios(linter => 1); lint( - verilator_flags2 => ["--debug-exit-uvm"], + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +lint( + verilator_flags2 => ["-DTEST_DECLARE_STD"], ); ok(1); diff --git a/test_regress/t/t_std_identifier.v b/test_regress/t/t_std_identifier.v new file mode 100644 index 000000000..882fb5658 --- /dev/null +++ b/test_regress/t/t_std_identifier.v @@ -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, 2022 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +package foo; +`ifdef TEST_DECLARE_STD + class std; + static int bar; + endclass +`endif +endpackage + +module t; + int baz = foo::std::bar; +endmodule diff --git a/test_regress/t/t_std_pkg_bad.out b/test_regress/t/t_std_pkg_bad.out new file mode 100644 index 000000000..54a735e56 --- /dev/null +++ b/test_regress/t/t_std_pkg_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_std_pkg_bad.v:7:9: Redeclaring the 'std' package is not allowed + 7 | package std; + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_mailbox_parse.pl b/test_regress/t/t_std_pkg_bad.pl similarity index 71% rename from test_regress/t/t_mailbox_parse.pl rename to test_regress/t/t_std_pkg_bad.pl index 6074d4d9a..19ba90d40 100755 --- a/test_regress/t/t_mailbox_parse.pl +++ b/test_regress/t/t_std_pkg_bad.pl @@ -2,18 +2,17 @@ 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 +# Copyright 2022 by Antmicro Ltd. 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); - -top_filename("t_mailbox.v"); +scenarios(linter => 1); lint( - verilator_flags2 => ["--debug-exit-uvm"], + fails => 1, + expect_filename => $Self->{golden_filename}, ); ok(1); diff --git a/test_regress/t/t_std_pkg_bad.v b/test_regress/t/t_std_pkg_bad.v new file mode 100644 index 000000000..c1969368e --- /dev/null +++ b/test_regress/t/t_std_pkg_bad.v @@ -0,0 +1,11 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +package std; +endpackage + +module t; +endmodule diff --git a/test_regress/t/t_timing_unset1.out b/test_regress/t/t_timing_unset1.out index c6bcbb64a..eb8c53eb8 100644 --- a/test_regress/t/t_timing_unset1.out +++ b/test_regress/t/t_timing_unset1.out @@ -31,4 +31,20 @@ : ... In instance t 27 | initial #2 $stop; | ^ +%Error-NEEDTIMINGOPT: t/t_notiming.v:33:10: Use --timing or --no-timing to specify how mailbox::put() should be handled + : ... In instance t + 33 | m.put(i); + | ^~~ +%Error-NEEDTIMINGOPT: t/t_notiming.v:34:10: Use --timing or --no-timing to specify how mailbox::get() should be handled + : ... In instance t + 34 | m.get(i); + | ^~~ +%Error-NEEDTIMINGOPT: t/t_notiming.v:35:10: Use --timing or --no-timing to specify how mailbox::peek() should be handled + : ... In instance t + 35 | m.peek(i); + | ^~~~ +%Error-NEEDTIMINGOPT: t/t_notiming.v:36:10: Use --timing or --no-timing to specify how semaphore::get() should be handled + : ... In instance t + 36 | s.get(); + | ^~~ %Error: Exiting due to