Compare commits

...
31 Commits
Author SHA1 Message Date
Wilson Snyder 77e7e2bf1c Version bump 2018-06-12 21:20:12 -04:00
Wilson Snyder 1c5c9e2435 cppcheck fixes 2018-06-12 21:14:20 -04:00
James Hutchinson f0ed4346b2 Fix to be in verilog 2005, bug1319.
Signed-off-by: Wilson Snyder <[email protected]>
2018-06-08 08:01:22 -04:00
John Coiner 94c8064798 Fix linear search; this is part of the fix for issue 1316. 2018-06-07 12:43:19 -04:00
Wilson Snyder cf0464c263 Internals: Cleanup V3EmitC common code. No functional change. From threads branch. 2018-05-29 19:55:42 -04:00
Wilson Snyder 6268db643c Commentary 2018-05-25 07:17:38 -04:00
Wilson Snyder fd98d231e4 Tests: Fix determinism of randomization. 2018-05-25 07:15:29 -04:00
Wilson Snyder 92649ba494 includes: Fix VL_RDTSC & misc stuff. 2018-05-24 22:17:44 -04:00
Wilson Snyder 0efe343494 Renamed --profile-cfuncs to --prof-cfuncs. 2018-05-20 09:12:29 -04:00
Wilson Snyder 84335b9580 Verilated: Cleanup command line parsing. Backport from pending v4 change. 2018-05-20 08:36:39 -04:00
Wilson Snyder e8b2c57610 Commentary 2018-05-19 14:50:28 -04:00
Wilson Snyder 5e22ca77ec Tests: Fix misc multithreaded issues, merge from threads branch. 2018-05-19 09:30:54 -04:00
Wilson Snyder b6e8133a4d When tracing, use scalars on single bit arrays to appease vcddiff. 2018-05-19 07:52:07 -04:00
Wilson Snyder 02a22c12ea Internals: Add missing [] to delete call in verilated_vcd_c.cpp, bug1309 2018-05-17 07:08:11 -04:00
Wilson Snyder fe917ba7f4 include: Merge misc thread runtime support. 2018-05-13 19:30:51 -04:00
Wilson Snyder 2c568603f6 Fix latex warning & misc Commentary 2018-05-13 19:21:08 -04:00
Wilson Snyder 51422e3ee8 Fix parsing error on bad missing #, bug1308. 2018-05-09 18:32:12 -04:00
Wilson Snyder 0ef3c10931 Pull some thread include changes from thread branch. 2018-05-08 21:43:32 -04:00
Wilson Snyder 35be80f789 Tests: Use vlt_all for any Verilator test. 2018-05-08 19:39:32 -04:00
Wilson Snyder c29e7619eb Tests: Support multiple scenario testing. 2018-05-07 20:42:28 -04:00
Wilson Snyder a265417727 Tests: Cleanup Perl indentations. No functional change. 2018-05-06 22:39:18 -04:00
Wilson Snyder b69af164f7 Commentary 2018-05-06 20:40:23 -04:00
Wilson Snyder ff61bb509c Tests: Fix race and dead code. 2018-05-05 07:44:52 -04:00
Wilson Snyder c8ba51581f Commentary 2018-04-30 20:34:52 -04:00
Wilson Snyder 29f1a9208e Commentary 2018-04-30 20:00:38 -04:00
Wilson Snyder 8b954dc381 Additional debug prints 2018-04-12 22:00:34 -04:00
John Coiner 767ac2547d Misc clang warning fixes.
Signed-off-by: Wilson Snyder <[email protected]>
2018-04-10 22:05:55 -04:00
Wilson Snyder a46aa2d62b Fix verilator_profcfunc on old gprofs. 2018-04-10 22:05:17 -04:00
Todd Strader 9219ddaece Report interface ports connected to wrong interface, bug1294. 2018-04-04 21:03:43 -04:00
Wilson Snyder c7c99d8553 Fix parsing "output signed" in V2K port list, msg2540. 2018-03-29 20:10:27 -04:00
Wilson Snyder e3354a0191 devel release 2018-03-17 12:01:59 -04:00
979 changed files with 6555 additions and 4584 deletions
+16 -1
View File
@@ -2,6 +2,21 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.924 2018-06-12
*** Renamed --profile-cfuncs to --prof-cfuncs.
**** Report interface ports connected to wrong interface, bug1294. [Todd Strader]
**** When tracing, use scalars on single bit arrays to appease vcddiff.
**** Fix parsing "output signed" in V2K port list, msg2540. [James Jung]
**** Fix parsing error on bad missing #, bug1308. [Dan Kirkham]
**** Fix $clog2 to be in verilog 2005, bug1319. [James Hutchinson]
* Verilator 3.922 2018-03-17
** Support IEEE 1800-2017 as default language.
@@ -2183,7 +2198,7 @@ Bug fixes:
* Verilator 3.501 2005/11/16 Stable
*** Add --profile-cfuncs for correlating profiles back to Verilog.
*** Add --prof-cfuncs for correlating profiles back to Verilog.
**** Fixed functions where regs are declared before inputs. [Danny Ding]
+3
View File
@@ -16,6 +16,9 @@
/obj_dir/
/obj_dbg/
/obj_opt/
/obj_vlt/
/obj_vltmt/
/obj_dist/
/INCA_libs/
/cov_work/
/logs/
+31 -21
View File
@@ -87,6 +87,9 @@ if ($opt_gdb) {
# Generic GDB interactive
run (("gdb"||$ENV{VERILATOR_GDB})
." ".verilator_bin()
# Note, uncomment to set breakpoints before running:
# ." -ex 'break main'"
# Note, we must use double-quotes ("run <switches>")
# and not single ('run <switches>') below. Bash swallows
# escapes as you would expect in a double-quoted string.
@@ -225,8 +228,8 @@ Verilator - Convert Verilog code to C++/SystemC
=head1 DESCRIPTION
Verilator converts synthesizable (not behavioral) Verilog code, plus some
Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into
Verilator converts synthesizable (generally not behavioral) Verilog code,
plus some Synthesis, SystemVerilog and a small subset of Verilog AMS into
C++ or SystemC code. It is not a complete simulator, but a compiler.
Verilator is invoked with parameters similar to GCC, Cadence
@@ -246,8 +249,8 @@ To get started, jump down to "EXAMPLE C++ EXECUTION".
=head1 ARGUMENT SUMMARY
This is a short summary of the arguments to Verilator. See the detailed
descriptions in the next sections for more information.
This is a short summary of the arguments to Verilator itself. See the
detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
{file.v} Verilog package, module and top module filenames
{file.c/cc/cpp} Optional C++ files to compile in
@@ -334,7 +337,7 @@ descriptions in the next sections for more information.
--pins-uint8 Specify types for top level ports
--pipe-filter <command> Filter all input through a script
--prefix <topname> Name of top level class
--profile-cfuncs Name functions for profiling
--prof-cfuncs Name functions for profiling
--private Debugging; see docs
--public Debugging; see docs
-pvalue+<name>=<value> Overwrite toplevel parameter
@@ -363,6 +366,7 @@ descriptions in the next sections for more information.
-v <filename> Verilog library
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
--version Displays program version and exits
--vpi Enable VPI compiles
-Wall Enable all style warnings
-Werror-<message> Convert warnings to errors
@@ -377,7 +381,9 @@ descriptions in the next sections for more information.
-y <dir> Directory to search for modules
=head1 ARGUMENTS
=head1 VERILATION ARGUMENTS
The following are the arguments that may be passed to Verilator itself.
=over 4
@@ -542,7 +548,7 @@ functions to avoid error C1061.
=back
=item --converge-limit <loops>
=item --converge-limit I<loops>
Rarely needed. Specifies the maximum number of runtime iterations before
creating a model failed to converge error. Defaults to 100.
@@ -651,9 +657,9 @@ when Verilating large models in --debug mode.
Outside of --debug mode, AstNode's should never be leaked and this option
has no effect.
=item --debugi <level>
=item --debugi I<level>
=item --debugi-<srcfile> <level>
=item --debugi-I<srcfile> I<level>
Rarely needed - for developer use. Set internal debugging level globally
to the specified debug level (1-10) or set the specified Verilator source
@@ -695,9 +701,9 @@ the Verilator Internals manual. --dump-tree is enabled automatically with
--debug, so "--debug --no-dump-tree" may be useful if the dump files are
large and not desired.
=item --dump-treei <level>
=item --dump-treei I<level>
=item --dump-treei-<srcfile> <level>
=item --dump-treei-I<srcfile> I<level>
Rarely needed - for developer use. Set internal tree dumping level
globally to a specific dumping level or set the specified Verilator source
@@ -711,7 +717,7 @@ Preprocess the source code, but do not compile, as with 'gcc -E'. Output
is written to standard out. Beware of enabling debugging messages, as they
will also go to standard out.
=item --error-limit <value>
=item --error-limit I<value>
After this number of errors or warnings are encountered, exit. Defaults to
50.
@@ -738,7 +744,7 @@ The file may contain // comments which are ignored to the end of the line.
Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment
variable.
=item -FI <file>
=item -FI I<file>
Force include of the specified C++ header file. All generated C++ files
will insert a #include of the specified file before any other includes. The
@@ -770,7 +776,7 @@ Double literals must contain a dot (.) and/or an exponent (e).
=item Strings
String must in double quotes ("). On the command line it is required to escape
String must in double quotes (""). On the command line it is required to escape
them properly, e.g. as -GSTR="\"My String\"" or -GSTR='"My String"'.
=back
@@ -896,7 +902,7 @@ otherwise manually create the Mdir before calling Verilator.
Specifies the name to prepend to all lower level classes. Defaults to
the same as --prefix.
=item --no-clk <signal-name>
=item --no-clk I<signal-name>
Prevent the specified signal from being marked as clock. See C<--clk>.
@@ -955,7 +961,7 @@ disables an optimization, an upper case letter enables it. This is
intended for debugging use only; see the source code for version-dependent
mappings of optimizations to -O letters.
=item -o <executable>
=item -o I<executable>
Specify the name for the final executable built if using --exe. Defaults
to the --prefix if not specified.
@@ -1054,7 +1060,7 @@ Specifies the name of the top level class and makefile. Defaults to V
prepended to the name of the --top-module switch, or V prepended to the
first Verilog filename passed on the command line.
=item --profile-cfuncs
=item --prof-cfuncs
Modify the created C++ functions to support profiling. The functions will
be minimized to contain one "basic" statement, generally a single always
@@ -1062,7 +1068,7 @@ block or wire statement. (Note this will slow down the executable by ~5%.)
Furthermore, the function name will be suffixed with the basename of the
Verilog module and line number the statement came from. This allows gprof
or oprofile reports to be correlated with the original Verilog source
statements.
statements. See also L<verilator_profcfunc>.
=item --private
@@ -1249,6 +1255,10 @@ Note -v is fairly standard across Verilog tools.
Synonyms for C<+1364-1995ext+>I<ext> and C<+1364-2001ext+>I<ext> respectively
=item --version
Displays program version and exits.
=item --vpi
Enable use of VPI and linking against the verilated_vpi.cpp files.
@@ -1368,7 +1378,7 @@ not otherwise initialized.
--x-initial=unique, the default, initializes variables using a function,
which determines the value to use each initialization. This gives greatest
flexibility and allows finding reset bugs. See L</"Unknown states">
flexibility and allows finding reset bugs. See L</"Unknown states">.
--x-initial=fast, is best for performance, and initializes all variables to
a state Verilator determines is optimal. This may allow further code
@@ -1629,7 +1639,7 @@ code with -DVL_INLINE_OPT=inline. This will inline functions, however this
requires that all cpp files be compiled in a single compiler run.
You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
Use Verilator's --prof-cfuncs, then GCC's -g -pg. You can then run
either oprofile or gprof to see where in the C++ code the time is spent.
Run the gprof output through verilator_profcfunc and it will tell you what
Verilog line numbers on which most of the time is being spent.
@@ -3701,7 +3711,7 @@ For example:
will toggle forever and thus the executable will give the didn't converge
error to prevent an infinite loop.
To debug this, run Verilator with --profile-cfuncs. Run make on the
To debug this, run Verilator with --prof-cfuncs. Run make on the
generated files with "OPT=-DVL_DEBUG". Then call Verilated::debug(1) in
your main.cpp.
+11 -3
View File
@@ -73,6 +73,14 @@ sub profcfunc {
$funcs{$func}{sec} += $sec;
$funcs{$func}{calls} += $calls;
}
# Older gprofs have no call column for single-call functions
# %time cumesec selfsec {stuff} name
elsif ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
my $pct=$1; my $sec=$2; my $calls=1; my $func=$3;
$funcs{$func}{pct} += $pct;
$funcs{$func}{sec} += $sec;
$funcs{$func}{calls} += $calls;
}
}
$fh->close;
@@ -191,11 +199,11 @@ __END__
=head1 NAME
verilator_profcfunc - Read gprof report created with --profile-cfuncs
verilator_profcfunc - Read gprof report created with --prof-cfuncs
=head1 SYNOPSIS
verilator --profile-cfuncs ....
verilator --prof-cfuncs ....
gcc --ggdb -pg ....
{run executable}
gprof
@@ -205,7 +213,7 @@ verilator_profcfunc - Read gprof report created with --profile-cfuncs
Verilator_profcfunc reads a profile report created by gprof. The names of
the functions are then transformed, assuming the user used verilator's
--profile-cfuncs, and a report printed showing the percentage of time, etc,
--prof-cfuncs, and a report printed showing the percentage of time, etc,
in each Verilog block.
=head1 ARGUMENTS
+1 -1
View File
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.922 2018-03-17])
AC_INIT([Verilator],[3.924 2018-06-12])
# When releasing, also update header of Changes file
# and commit using "devel release" or "Version bump" message
+67 -28
View File
@@ -40,9 +40,9 @@ VerilatedVoidCb Verilated::s_flushCb = NULL;
Verilated::Serialized Verilated::s_s;
VL_THREAD_LOCAL Verilated::ThreadLocal Verilated::t_s;
struct Verilated::CommandArgValues Verilated::s_args = {0, NULL};
Verilated::CommandArgValues Verilated::s_args;
VerilatedImp VerilatedImp::s_s;
VerilatedImp VerilatedImp::s_s;
//===========================================================================
// User definable functions
@@ -122,10 +122,16 @@ std::string _vl_string_vprintf(const char* formatp, va_list ap) VL_MT_SAFE {
va_list aq;
va_copy(aq, ap);
int len = VL_VSNPRINTF(NULL, 0, formatp, aq);
if (VL_UNLIKELY(len < 1)) return "";
va_end(aq);
if (VL_UNLIKELY(len < 1)) {
va_end(ap);
return "";
}
char* bufp = new char[len+1];
VL_VSNPRINTF(bufp, len+1, formatp, ap);
va_end(ap);
std::string out = std::string(bufp, len);
delete[] bufp;
return out;
@@ -159,7 +165,11 @@ void VL_DBG_MSGF(const char* formatp, ...) VL_MT_SAFE {
std::string out = _vl_string_vprintf(formatp, ap);
va_end(ap);
// printf("-imm-V{t%d,%" VL_PRI64 "d}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str());
VL_PRINTF_MT("-V{t%d,%" VL_PRI64 "d}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str());
// Using VL_PRINTF not VL_PRINTF_MT so that we can call VL_DBG_MSGF
// from within the guts of the thread execution machinery (and it goes
// to the screen and not into the queues we're debugging)
VL_PRINTF("-V{t%d,%" VL_PRI64 "u}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str());
}
#ifdef VL_THREADED
@@ -198,7 +208,7 @@ IData VL_RAND32() VL_MT_SAFE {
t_seeded = true;
long seedval;
{
VerilatedLockGuard guard(s_mutex);
VerilatedLockGuard lock(s_mutex);
seedval = lrand48()<<16 ^ lrand48();
if (!seedval) seedval++;
}
@@ -1599,7 +1609,8 @@ std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE {
Verilated::ThreadLocal::ThreadLocal()
:
#ifdef VL_THREADED
t_trainId(0),
t_mtaskId(0),
t_endOfEvalReqd(0),
#endif
t_dpiScopep(NULL), t_dpiFilename(0), t_dpiLineno(0) {
}
@@ -1607,7 +1618,7 @@ Verilated::ThreadLocal::~ThreadLocal() {
}
void Verilated::debug(int val) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
s_s.s_debug = val;
if (val) {
#ifdef VL_DEBUG
@@ -1618,23 +1629,23 @@ void Verilated::debug(int val) VL_MT_SAFE {
}
}
void Verilated::randReset(int val) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
s_s.s_randReset = val;
}
void Verilated::calcUnusedSigs(bool flag) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
s_s.s_calcUnusedSigs = flag;
}
void Verilated::gotFinish(bool flag) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
s_s.s_gotFinish = flag;
}
void Verilated::assertOn(bool flag) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
s_s.s_assertOn = flag;
}
void Verilated::fatalOnVpiError(bool flag) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
s_s.s_fatalOnVpiError = flag;
}
@@ -1656,7 +1667,7 @@ const char* Verilated::catName(const char* n1, const char* n2) VL_MT_SAFE {
}
void Verilated::flushCb(VerilatedVoidCb cb) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
if (s_flushCb == cb) {} // Ok - don't duplicate
else if (!s_flushCb) { s_flushCb=cb; }
else {
@@ -1666,14 +1677,14 @@ void Verilated::flushCb(VerilatedVoidCb cb) VL_MT_SAFE {
}
void Verilated::flushCall() VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
if (s_flushCb) (*s_flushCb)();
fflush(stderr);
fflush(stdout);
}
void Verilated::commandArgs(int argc, const char** argv) VL_MT_SAFE {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
s_args.argc = argc;
s_args.argv = argv;
VerilatedImp::commandArgs(argc,argv);
@@ -1711,16 +1722,6 @@ void Verilated::scopesDump() VL_MT_SAFE {
VerilatedImp::scopesDump();
}
void Verilated::numThreads(unsigned threads) VL_MT_SAFE {
VerilatedImp::numThreads(threads);
}
unsigned Verilated::numThreads() VL_MT_SAFE {
return VerilatedImp::numThreads();
}
void Verilated::spawnThreads() VL_MT_SAFE {
VerilatedImp::spawnThreads();
}
const VerilatedScope* Verilated::scopeFind(const char* namep) VL_MT_SAFE {
return VerilatedImp::scopeFind(namep);
}
@@ -1734,8 +1735,8 @@ const VerilatedScopeNameMap* Verilated::scopeNameMap() VL_MT_SAFE {
}
#ifdef VL_THREADED
void Verilated::endOfThreadTrainGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
VL_DEBUG_IF(VL_DBG_MSGF("End of thread train\n"););
void Verilated::endOfThreadMTaskGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
VL_DEBUG_IF(VL_DBG_MSGF("End of thread mtask\n"););
VerilatedThreadMsgQueue::flush(evalMsgQp);
}
@@ -1745,6 +1746,44 @@ void Verilated::endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
}
#endif
//===========================================================================
// VerilatedImp:: Methods
void VerilatedImp::internalsDump() VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_argMutex);
VL_PRINTF_MT("internalsDump:\n");
versionDump();
VL_PRINTF_MT(" Argv:");
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
VL_PRINTF_MT(" %s",it->c_str());
}
VL_PRINTF_MT("\n");
scopesDump();
exportsDump();
userDump();
}
void VerilatedImp::versionDump() VL_MT_SAFE {
VL_PRINTF_MT(" Version: %s %s\n",
Verilated::productName(), Verilated::productVersion());
}
void VerilatedImp::commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) {
VerilatedLockGuard lock(s_s.m_argMutex);
s_s.m_argVec.clear(); // Always clear
commandArgsAddGuts(argc, argv);
}
void VerilatedImp::commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) {
VerilatedLockGuard lock(s_s.m_argMutex);
commandArgsAddGuts(argc, argv);
}
void VerilatedImp::commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex) {
if (!s_s.m_argVecLoaded) s_s.m_argVec.clear();
for (int i=0; i<argc; ++i) {
s_s.m_argVec.push_back(argv[i]);
}
s_s.m_argVecLoaded = true; // Can't just test later for empty vector, no arguments is ok
}
//======================================================================
// VerilatedSyms:: Methods
@@ -1943,7 +1982,7 @@ void VerilatedScope::scopeDump() const {
//===========================================================================
// VerilatedOneThreaded:: Methods
#ifdef VL_THREADED
#if defined(VL_THREADED) && defined(VL_DEBUG)
void VerilatedAssertOneThread::fatal_different() VL_MT_SAFE {
VL_FATAL_MT(__FILE__, __LINE__, "", "Routine called that is single threaded, but called from"
" a different thread then the expected constructing thread");
+53 -31
View File
@@ -111,6 +111,8 @@ extern vluint32_t VL_THREAD_ID() VL_MT_SAFE;
#if VL_THREADED
#define VL_LOCK_SPINS 50000 /// Number of times to spin for a mutex before relaxing
/// Mutex, wrapped to allow -fthread_safety checks
class VL_CAPABILITY("mutex") VerilatedMutex {
private:
@@ -119,9 +121,19 @@ class VL_CAPABILITY("mutex") VerilatedMutex {
VerilatedMutex() {}
~VerilatedMutex() {}
/// Acquire/lock mutex
void lock() VL_ACQUIRE() { m_mutex.lock(); }
void lock() VL_ACQUIRE() {
// Try to acquire the lock by spinning. If the wait is short,
// avoids a trap to the OS plus OS scheduler overhead.
if (VL_LIKELY(try_lock())) return; // Short circuit loop
for (int i = 0; i < VL_LOCK_SPINS; ++i) {
if (VL_LIKELY(try_lock())) return;
VL_CPU_RELAX();
}
// Spinning hasn't worked, pay the cost of blocking.
m_mutex.lock();
}
/// Release/unlock mutex
void unlock() VL_RELEASE() { m_mutex.unlock(); }
void unlock() VL_RELEASE() { m_mutex.unlock(); }
/// Try to acquire mutex. Returns true on success, and false on failure.
bool try_lock() VL_TRY_ACQUIRE(true) { return m_mutex.try_lock(); }
};
@@ -143,14 +155,21 @@ class VL_SCOPED_CAPABILITY VerilatedLockGuard {
#else // !VL_THREADED
// Empty classes to avoid #ifdefs everywhere
class VerilatedMutex {};
/// Empty non-threaded mutex to avoid #ifdefs in consuming code
class VerilatedMutex {
public:
void lock() {}
void unlock() {}
};
/// Empty non-threaded lock guard to avoid #ifdefs in consuming code
class VerilatedLockGuard {
VL_UNCOPYABLE(VerilatedLockGuard);
public:
explicit VerilatedLockGuard(VerilatedMutex&) {}
~VerilatedLockGuard() {}
};
#endif // VL_THREADED
/// Remember the calling thread at construction time, and make sure later calls use same thread
@@ -167,9 +186,7 @@ public:
// METHODS
/// Check that the current thread ID is the same as the construction thread ID
void check() VL_MT_UNSAFE_ONE {
// Memoize results in local thread, to prevent slow get_id() call
VL_THREAD_LOCAL bool t_okThread = (m_threadid == VL_THREAD_ID());
if (!VL_LIKELY(t_okThread)) {
if (!VL_LIKELY(m_threadid == VL_THREAD_ID())) {
fatal_different();
}
}
@@ -315,15 +332,16 @@ class Verilated {
static VerilatedVoidCb s_flushCb; ///< Flush callback function
static struct Serialized { // All these members serialized/deserialized
// Slow path
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
// Fast path
int s_debug; ///< See accessors... only when VL_DEBUG set
bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
bool s_gotFinish; ///< A $finish statement executed
bool s_assertOn; ///< Assertions are enabled
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
Serialized();
// Slow path
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
Serialized();
~Serialized() {}
} s_s;
// no need to be save-restored (serialized) the
@@ -331,12 +349,14 @@ class Verilated {
static struct CommandArgValues {
int argc;
const char** argv;
CommandArgValues() : argc(0), argv(NULL) {}
~CommandArgValues() {}
} s_args;
// Not covered by mutex, as per-thread
static VL_THREAD_LOCAL struct ThreadLocal {
#ifdef VL_THREADED
vluint32_t t_trainId; ///< Current train# executing on this thread
vluint32_t t_mtaskId; ///< Current mtask# executing on this thread
vluint32_t t_endOfEvalReqd; ///< Messages may be pending, thread needs endOf-eval calls
#endif
const VerilatedScope* t_dpiScopep; ///< DPI context scope
@@ -394,7 +414,8 @@ public:
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs
static void commandArgs(int argc, const char** argv) VL_MT_SAFE;
static void commandArgs(int argc, char** argv) VL_MT_SAFE { commandArgs(argc, const_cast<const char**>(argv)); }
static void commandArgs(int argc, char** argv) VL_MT_SAFE {
commandArgs(argc, const_cast<const char**>(argv)); }
static void commandArgsAdd(int argc, const char** argv);
static CommandArgValues* getCommandArgs() VL_MT_SAFE { return &s_args; }
/// Match plusargs with a given prefix. Returns static char* valid only for a single call
@@ -418,17 +439,6 @@ public:
/// releases - contact the authors before production use.
static void scopesDump() VL_MT_SAFE;
/// Set the number of threads to execute on.
/// 0x0 = use all available CPU threads, or 1 if no support compiled in
/// Ignored after spawnThreads() has been called
static void numThreads(unsigned threads) VL_MT_SAFE;
static unsigned numThreads() VL_MT_SAFE;
/// Spawn child threads, using numThreads() as # of threads
/// Verilator calls this automatically on the first eval() call
/// User code may call it earlier if desired
/// Once called the first time, later calls are ignored
static void spawnThreads() VL_MT_SAFE;
public:
// METHODS - INTERNAL USE ONLY (but public due to what uses it)
// Internal: Create a new module name by concatenating two strings
@@ -455,22 +465,29 @@ public:
static size_t serializedSize() VL_PURE { return sizeof(s_s); }
static void* serializedPtr() VL_MT_UNSAFE { return &s_s; } // Unsafe, for Serialize only
#ifdef VL_THREADED
/// Set the trainId, called when a train starts
static void trainId(vluint32_t id) VL_MT_SAFE { t_s.t_trainId = id; }
static vluint32_t trainId() VL_MT_SAFE { return t_s.t_trainId; }
/// Set the mtaskId, called when an mtask starts
static void mtaskId(vluint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
static vluint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; }
static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; }
/// Called at end of each thread train, before finishing eval
static void endOfThreadTrain(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) { endOfThreadTrainGuts(evalMsgQp); } }
/// Called at end of each thread mtask, before finishing eval
static void endOfThreadMTask(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) { endOfThreadMTaskGuts(evalMsgQp); }
}
/// Called at end of eval loop
static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) { endOfEvalGuts(evalMsgQp); } }
// It doesn't work to set endOfEvalReqd on the threadpool thread
// and then check it on the eval thread since it's thread local.
// It should be ok to call into endOfEvalGuts, it returns immediately
// if there are no transactions.
endOfEvalGuts(evalMsgQp);
}
#endif
private:
#ifdef VL_THREADED
static void endOfThreadTrainGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
static void endOfThreadMTaskGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
static void endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
#endif
};
@@ -527,6 +544,11 @@ extern QData VL_RAND_RESET_Q(int obits); ///< Random reset a signal
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp); ///< Random reset a signal
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); ///< Zero reset a signal (slow - else use VL_ZERO_W)
#if VL_THREADED
/// Return high-precision counter for profiling, or 0x0 if not available
inline QData VL_RDTSC_Q() { vluint64_t val; VL_RDTSC(val); return val; }
#endif
/// Math
extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool is_modulus);
+3 -1
View File
@@ -186,14 +186,16 @@ endif
debug-make::
@echo
@echo CPPFLAGS: $(CPPFLAGS)
@echo VM_PREFIX: $(VM_PREFIX)
@echo VM_PARALLEL_BUILDS: $(VM_PARALLEL_BUILDS)
@echo VM_CLASSES_FAST: $(VM_CLASSES_FAST)
@echo VM_CLASSES_SLOW: $(VM_CLASSES_SLOW)
@echo VM_SUPPORT_FAST: $(VM_SUPPORT_FAST)
@echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW)
@echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST)
@echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW)
@echo CPPFLAGS: $(CPPFLAGS)
@echo VK_OBJS: $(VK_OBJS)
@echo
######################################################################
+7 -7
View File
@@ -233,12 +233,12 @@ public:
// PUBLIC METHODS
void clear() VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
clearGuts();
}
void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
if (matchp && matchp[0]) {
ItemList newlist;
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
@@ -254,7 +254,7 @@ public:
}
void zero() VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
(*it)->zero();
}
@@ -262,18 +262,18 @@ public:
// We assume there's always call to i/f/p in that order
void inserti (VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
assert(!m_insertp);
m_insertp = itemp;
}
void insertf (const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
m_insertFilenamep = filenamep;
m_insertLineno = lineno;
}
void insertp (const char* ckeyps[MAX_KEYS],
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
assert(m_insertp);
// First two key/vals are filename
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
@@ -328,7 +328,7 @@ public:
void write(const char* filename) VL_EXCLUDES(m_mutex) {
Verilated::quiesce();
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
#ifndef VM_COVERAGE
VL_FATAL_MT("",0,"","%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
#endif
+43 -93
View File
@@ -49,25 +49,25 @@ class VerilatedScope;
// Threaded message passing
#ifdef VL_THREADED
/// Message, enqueued on a train, and consumed on the main eval thread
/// Message, enqueued on an mtask, and consumed on the main eval thread
class VerilatedMsg {
public:
// TYPES
struct Cmp {
bool operator() (const VerilatedMsg& a, const VerilatedMsg& b) const {
return a.trainId() < b.trainId(); }
return a.mtaskId() < b.mtaskId(); }
};
private:
// MEMBERS
vluint32_t m_trainId; ///< Train that did enqueue
vluint32_t m_mtaskId; ///< MTask that did enqueue
std::function<void()> m_cb; ///< Lambda to execute when message received
public:
// CONSTRUCTORS
VerilatedMsg(const std::function<void()>& cb)
: m_trainId(Verilated::trainId()), m_cb(cb) {}
: m_mtaskId(Verilated::mtaskId()), m_cb(cb) {}
~VerilatedMsg() {}
// METHODS
vluint32_t trainId() const { return m_trainId; }
vluint32_t mtaskId() const { return m_mtaskId; }
/// Execute the lambda function
void run() const { m_cb(); }
};
@@ -84,7 +84,9 @@ class VerilatedEvalMsgQueue {
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); ///< Message queue
public:
// CONSTRUCTORS
VerilatedEvalMsgQueue() : m_depth(0) { }
VerilatedEvalMsgQueue() : m_depth(0) {
assert(atomic_is_lock_free(&m_depth));
}
~VerilatedEvalMsgQueue() { }
private:
VL_UNCOPYABLE(VerilatedEvalMsgQueue);
@@ -92,8 +94,7 @@ public:
// METHODS
//// Add message to queue (called by producer)
void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) {
Verilated::endOfEvalReqdInc(); // No mutex, threadsafe
VerilatedLockGuard guard(m_mutex);
VerilatedLockGuard lock(m_mutex);
m_queue.insert(msg); // Pass by value to copy the message into queue
++m_depth;
}
@@ -114,10 +115,9 @@ public:
m_queue.erase(it);
m_mutex.unlock();
m_depth--; // Ok if outside critical section as only this code checks the value
Verilated::endOfEvalReqdDec(); // No mutex, threadsafe
{
VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from trainId=%d\n", msg.trainId()););
msg.run();
VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from mtaskId=%d\n", msg.mtaskId()););
msg.run();
}
}
}
@@ -143,8 +143,15 @@ private:
public:
/// Add message to queue, called by producer
static void post(const VerilatedMsg& msg) VL_MT_SAFE {
Verilated::endOfEvalReqdInc();
threadton().m_queue.push(msg); // Pass by value to copy the message into queue
// Handle calls to threaded routines outside
// of any mtask -- if an initial block calls $finish, say.
if (Verilated::mtaskId() == 0) {
// No queueing, just do the action immediately
msg.run();
} else {
Verilated::endOfEvalReqdInc();
threadton().m_queue.push(msg); // Pass by value to copy the message into queue
}
}
/// Push all messages to the eval's queue
static void flush(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
@@ -192,15 +199,10 @@ class VerilatedImp {
std::vector<FILE*> m_fdps VL_GUARDED_BY(m_fdMutex); ///< File descriptors
std::deque<IData> m_fdFree VL_GUARDED_BY(m_fdMutex); ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
// Threads
VerilatedMutex m_threadMutex; ///< Protect m_numThreads, etc
bool m_spawned VL_GUARDED_BY(m_threadMutex); ///< Already called spawnThreads()
unsigned m_numThreads VL_GUARDED_BY(m_threadMutex); ///< Number of threads user requested, 0x0=all cpus
public: // But only for verilated*.cpp
// CONSTRUCTORS
VerilatedImp()
: m_argVecLoaded(false), m_exportNext(0), m_spawned(false), m_numThreads(0) {
: m_argVecLoaded(false), m_exportNext(0) {
m_fdps.resize(3);
m_fdps[0] = stdin;
m_fdps[1] = stdout;
@@ -210,33 +212,16 @@ public: // But only for verilated*.cpp
private:
VL_UNCOPYABLE(VerilatedImp);
public:
static void internalsDump() VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_argMutex);
VL_PRINTF_MT("internalsDump:\n");
VL_PRINTF_MT(" Argv:");
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
VL_PRINTF_MT(" %s",it->c_str());
}
VL_PRINTF_MT("\n");
VL_PRINTF_MT(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
scopesDump();
exportsDump();
userDump();
}
// METHODS - debug
static void internalsDump() VL_MT_SAFE;
static void versionDump() VL_MT_SAFE;
// METHODS - arguments
public:
static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) {
VerilatedLockGuard guard(s_s.m_argMutex);
s_s.m_argVec.clear(); // Always clear
commandArgsAddGuts(argc, argv);
}
static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) {
VerilatedLockGuard guard(s_s.m_argMutex);
commandArgsAddGuts(argc, argv);
}
static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) {
VerilatedLockGuard guard(s_s.m_argMutex);
VerilatedLockGuard lock(s_s.m_argMutex);
// Note prefixp does not include the leading "+"
size_t len = strlen(prefixp);
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
@@ -253,11 +238,7 @@ public:
return "";
}
private:
static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex) {
if (!s_s.m_argVecLoaded) s_s.m_argVec.clear();
for (int i=0; i<argc; ++i) s_s.m_argVec.push_back(argv[i]);
s_s.m_argVecLoaded = true; // Can't just test later for empty vector, no arguments is ok
}
static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex);
public:
// METHODS - user scope tracking
@@ -265,14 +246,14 @@ public:
// There's often many more scopes than userdata's and thus having a ~48byte
// per map overhead * N scopes would take much more space and cache thrashing.
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_userMapMutex);
VerilatedLockGuard lock(s_s.m_userMapMutex);
UserMap::iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey));
if (it != s_s.m_userMap.end()) it->second = userData;
// When we support VL_THREADs, we need a lock around this insert, as it's runtime
else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep,userKey),userData));
}
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_userMapMutex);
VerilatedLockGuard lock(s_s.m_userMapMutex);
UserMap::const_iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey));
if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second;
else return NULL;
@@ -281,7 +262,7 @@ private:
/// Symbol table destruction cleans up the entries for each scope.
static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope on destruction, so we simply iterate.
VerilatedLockGuard guard(s_s.m_userMapMutex);
VerilatedLockGuard lock(s_s.m_userMapMutex);
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ) {
if (it->first.first == scopep) {
s_s.m_userMap.erase(it++);
@@ -291,7 +272,7 @@ private:
}
}
static void userDump() VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_userMapMutex); // Avoid it changing in middle of dump
VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump
bool first = true;
for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; }
@@ -304,27 +285,27 @@ public: // But only for verilated*.cpp
// METHODS - scope name
static void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope at construction
VerilatedLockGuard guard(s_s.m_nameMutex);
VerilatedLockGuard lock(s_s.m_nameMutex);
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it == s_s.m_nameMap.end()) {
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(),scopep));
}
}
static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT
VerilatedLockGuard lock(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT
VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.find(namep);
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
else return NULL;
}
static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope at destruction
VerilatedLockGuard guard(s_s.m_nameMutex);
VerilatedLockGuard lock(s_s.m_nameMutex);
userEraseScope(scopep);
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
}
static void scopesDump() VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_nameMutex);
VerilatedLockGuard lock(s_s.m_nameMutex);
VL_PRINTF_MT(" scopesDump:\n");
for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
const VerilatedScope* scopep = it->second;
@@ -348,7 +329,7 @@ public: // But only for verilated*.cpp
// miss at the cost of a multiply, and all lookups move to slowpath.
static int exportInsert(const char* namep) VL_MT_SAFE {
// Slow ok - called once/function at creation
VerilatedLockGuard guard(s_s.m_exportMutex);
VerilatedLockGuard lock(s_s.m_exportMutex);
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
if (it == s_s.m_exportMap.end()) {
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
@@ -358,7 +339,7 @@ public: // But only for verilated*.cpp
}
}
static int exportFind(const char* namep) VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_exportMutex);
VerilatedLockGuard lock(s_s.m_exportMutex);
ExportNameMap::const_iterator it=s_s.m_exportMap.find(namep);
if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second;
std::string msg = (std::string("%Error: Testbench C called ")+namep
@@ -368,14 +349,14 @@ public: // But only for verilated*.cpp
}
static const char* exportName(int funcnum) VL_MT_SAFE {
// Slowpath; find name for given export; errors only so no map to reverse-map it
VerilatedLockGuard guard(s_s.m_exportMutex);
VerilatedLockGuard lock(s_s.m_exportMutex);
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
if (it->second == funcnum) return it->first;
}
return "*UNKNOWN*";
}
static void exportsDump() VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_exportMutex);
VerilatedLockGuard lock(s_s.m_exportMutex);
bool first = true;
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; }
@@ -390,7 +371,7 @@ public: // But only for verilated*.cpp
static IData fdNew(FILE* fp) VL_MT_SAFE {
if (VL_UNLIKELY(!fp)) return 0;
// Bit 31 indicates it's a descriptor not a MCD
VerilatedLockGuard guard(s_s.m_fdMutex);
VerilatedLockGuard lock(s_s.m_fdMutex);
if (s_s.m_fdFree.empty()) {
// Need to create more space in m_fdps and m_fdFree
size_t start = s_s.m_fdps.size();
@@ -403,7 +384,7 @@ public: // But only for verilated*.cpp
}
static void fdDelete(IData fdi) VL_MT_SAFE {
IData idx = VL_MASK_I(31) & fdi;
VerilatedLockGuard guard(s_s.m_fdMutex);
VerilatedLockGuard lock(s_s.m_fdMutex);
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return;
if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free
s_s.m_fdps[idx] = NULL;
@@ -411,41 +392,10 @@ public: // But only for verilated*.cpp
}
static inline FILE* fdToFp(IData fdi) VL_MT_SAFE {
IData idx = VL_MASK_I(31) & fdi;
VerilatedLockGuard guard(s_s.m_fdMutex); // This might get slow, if it does we can cache it
VerilatedLockGuard lock(s_s.m_fdMutex); // This might get slow, if it does we can cache it
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL;
return s_s.m_fdps[idx];
}
public: // But only for verilated*.cpp
// METHODS - Threading
static void numThreads(unsigned threads) VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_threadMutex);
if (!s_s.m_spawned) s_s.m_numThreads = threads;
}
static unsigned numThreads() VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_threadMutex);
#ifdef VL_THREADED
unsigned threads = s_s.m_numThreads;
if (threads == 0x0) {
threads = std::thread::hardware_concurrency(); // Or 0=unknown, C++11
}
if (threads<1) threads = 1;
return threads;
#else
return 0;
#endif
}
static void spawnThreads() VL_MT_SAFE {
VerilatedLockGuard guard(s_s.m_threadMutex);
if (!s_s.m_spawned) {
// Convert numThreads from 0 to the spawned number
numThreads(numThreads());
s_s.m_spawned = true;
#ifdef VL_THREADED
// THREADED-TODO startup threads
#endif
}
}
};
//======================================================================
+4 -4
View File
@@ -61,18 +61,18 @@ private:
static Singleton& singleton() { static Singleton s; return s; }
public:
static void pushVcd(VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) {
VerilatedLockGuard guard(singleton().s_vcdMutex);
VerilatedLockGuard lock(singleton().s_vcdMutex);
singleton().s_vcdVecp.push_back(vcdp);
}
static void removeVcd(const VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) {
VerilatedLockGuard guard(singleton().s_vcdMutex);
VerilatedLockGuard lock(singleton().s_vcdMutex);
VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), vcdp);
if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); }
}
static void flush_all() VL_EXCLUDES(singleton().s_vcdMutex) VL_MT_UNSAFE_ONE {
// Thread safety: Although this function is protected by a mutex so perhaps
// in the future we can allow tracing in separate threads, vcdp->flush() assumes call from single thread
VerilatedLockGuard guard(singleton().s_vcdMutex);
VerilatedLockGuard lock(singleton().s_vcdMutex);
for (VcdVec::const_iterator it=singleton().s_vcdVecp.begin(); it!=singleton().s_vcdVecp.end(); ++it) {
VerilatedVcd* vcdp = *it;
vcdp->flush();
@@ -343,7 +343,7 @@ void VerilatedVcd::bufferResize(vluint64_t minsize) {
memcpy(m_wrBufp, oldbufp, m_writep - oldbufp);
m_writep = m_wrBufp + (m_writep - oldbufp);
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
delete oldbufp; oldbufp=NULL;
delete [] oldbufp; oldbufp=NULL;
}
}
+3 -2
View File
@@ -473,11 +473,12 @@ public:
m_errorInfo.level = level;
return this;
}
void setMessage(std::string file, PLI_INT32 line, const std::string& message, ...) {
void setMessage(std::string file, PLI_INT32 line, const char* message, ...) {
// message cannot be a const string& as va_start cannot use a reference
static VL_THREAD_LOCAL std::string filehold;
va_list args;
va_start(args, message);
VL_VSNPRINTF(m_buff, sizeof(m_buff), message.c_str(), args);
VL_VSNPRINTF(m_buff, sizeof(m_buff), message, args);
va_end(args);
m_errorInfo.state = vpiPLI;
filehold = file;
+39
View File
@@ -353,6 +353,45 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
# define VL_ROUND(n) round(n)
#endif
//=========================================================================
// Performance counters
#if VL_THREADED
/// The vluint64_t argument is loaded with a high-performance counter for profiling
/// or 0x0 if not implemeted on this platform
# if defined(__i386__) || defined(__x86_64__)
# define VL_RDTSC(val) { \
vluint32_t hi, lo; \
asm volatile("rdtsc" : "=a" (lo), "=d" (hi)); \
(val) = ((vluint64_t)lo) | (((vluint64_t)hi)<<32); \
}
# elif defined(__aarch64__)
# define VL_RDTSC(val) asm volatile("mrs %[rt],PMCCNTR_EL0" : [rt] "=r" (val));
# else
// We just silently ignore unknown OSes, as only leads to missing statistics
# define VL_RDTSC(val) (val) = 0;
# endif
#endif
//=========================================================================
// Threading related OS-specific functions
#if VL_THREADED
# if defined(__i386__) || defined(__x86_64__)
/// For more efficient busy waiting on SMT CPUs, let the processor know
/// we're just waiting so it can let another thread run
# define VL_CPU_RELAX() asm volatile("rep; nop" ::: "memory")
# elif defined(__ia64__)
# define VL_CPU_RELAX() asm volatile("hint @pause" ::: "memory")
# elif defined(__aarch64__)
# define VL_CPU_RELAX() asm volatile("yield" ::: "memory")
# elif defined(__powerpc64__)
# define VL_CPU_RELAX() asm volatile("or 1, 1, 1; or 2, 2, 2;" ::: "memory")
# else
# error "Missing VL_CPU_RELAX() definition. Or, don't use VL_THREADED"
# endif
#endif
//=========================================================================
#endif /*guard*/
+1 -1
View File
@@ -749,7 +749,7 @@ File a bug (if there isn't already) so others know what you're working on.
=item 2.
Make a testcase in the test_regress/t/t_EXAMPLE format, see L<TESTING>.
Make a testcase in the test_regress/t/t_EXAMPLE format, see L</TESTING>.
=item 3.
+1 -1
View File
@@ -2069,7 +2069,7 @@ public:
class AstNodeRange : public AstNode {
// A range, sized or unsized
public:
AstNodeRange(FileLine* fl) : AstNode (fl) { }
explicit AstNodeRange(FileLine* fl) : AstNode (fl) { }
ASTNODE_BASE_FUNCS(NodeRange)
};
+1 -1
View File
@@ -149,7 +149,7 @@ public:
class AstUnsizedRange : public AstNodeRange {
// Unsized range specification, for open arrays
public:
AstUnsizedRange(FileLine* fl) : AstNodeRange(fl) { }
explicit AstUnsizedRange(FileLine* fl) : AstNodeRange(fl) { }
ASTNODE_NODE_FUNCS(UnsizedRange)
virtual string emitC() { V3ERROR_NA; return ""; }
virtual string emitVerilog() { return "[]"; }
+2 -1
View File
@@ -150,7 +150,8 @@ private:
AstActive* createActivePost(AstVarRef* varrefp) {
AstActive* newactp = new AstActive (varrefp->fileline(), "sequentdly",
m_activep->sensesp());
m_activep->addNext(newactp);
// Was addNext(), but addNextHere() avoids a linear search.
m_activep->addNextHere(newactp);
return newactp;
}
void checkActivePost(AstVarRef* varrefp, AstActive* oldactivep) {
+60 -52
View File
@@ -78,7 +78,8 @@ public:
typedef enum {EVL_CLASS_IO, EVL_CLASS_SIG, EVL_CLASS_TEMP, EVL_CLASS_PAR, EVL_CLASS_ALL,
EVL_FUNC_ALL} EisWhich;
void emitVarList(AstNode* firstp, EisWhich which, const string& prefixIfImp);
void emitVarCtors();
void emitVarCtors(bool* firstp);
void emitCtorSep(bool* firstp);
bool emitSimpleOk(AstNodeMath* nodep);
void emitIQW(AstNode* nodep) {
// Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g
@@ -898,6 +899,7 @@ class EmitCImp : EmitCStmts {
puts(modClassName(m_modp)+"::"+nodep->name()
+"\\n\"); );\n");
// Declare and set vlTOPp
if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n");
if (nodep->initsp()) putsDecoration("// Variables\n");
@@ -994,6 +996,7 @@ class EmitCImp : EmitCStmts {
void emitSettleLoop(std::string eval_call, bool initial);
void emitWrapEval(AstNodeModule* modp);
void emitInt(AstNodeModule* modp);
void maybeSplit(AstNodeModule* modp);
public:
EmitCImp() {
@@ -1086,12 +1089,20 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
}
}
void EmitCStmts::emitVarCtors() {
void EmitCStmts::emitCtorSep(bool* firstp) {
if (*firstp) {
puts(" : "); *firstp = false;
} else {
puts(", ");
}
if (ofp()->exceededWidth()) puts("\n ");
}
void EmitCStmts::emitVarCtors(bool* firstp) {
if (!m_ctorVarsVec.empty()) {
ofp()->indentInc();
puts("\n");
puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer
bool first = true;
for (vector<AstVar*>::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
AstVar* varp = *it;
bool isArray = !varp->dtypeSkipRefp()->castBasicDType();
@@ -1100,9 +1111,7 @@ void EmitCStmts::emitVarCtors() {
puts(varp->name());
puts("\n");
} else {
if (first) { puts(" : "); first=false; }
else puts(", ");
if (ofp()->exceededWidth()) puts("\n ");
emitCtorSep(firstp);
puts(varp->name());
puts("("); putsQuoted(varp->name()); puts(")");
}
@@ -1526,12 +1535,14 @@ void EmitCImp::emitCoverageDecl(AstNodeModule* modp) {
void EmitCImp::emitCtorImp(AstNodeModule* modp) {
puts("\n");
bool first = true;
if (optSystemC() && modp->isTop()) {
puts("VL_SC_CTOR_IMP("+modClassName(modp)+")");
} else {
puts("VL_CTOR_IMP("+modClassName(modp)+")");
puts("VL_CTOR_IMP("+modClassName(modp)+")");
first = false; // VL_CTOR_IMP includes the first ':'
}
emitVarCtors();
emitVarCtors(&first);
puts(" {\n");
emitCellCtors(modp);
emitSensitives();
@@ -1779,18 +1790,18 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("if (VL_UNLIKELY(__Vm_inhibitSim)) return;\n");
}
if (v3Global.opt.threads()) { // THREADED-TODO move to per-train
uint32_t trainId = 0;
putsDecoration("// Train "+cvtToStr(trainId)+" start\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"Train starting, trainId="+cvtToStr(trainId)+"\\n\"););\n");
puts("Verilated::trainId("+cvtToStr(trainId)+");\n");
if (v3Global.opt.threads() == 1) {
uint32_t mtaskId = 0;
putsDecoration("// MTask "+cvtToStr(mtaskId)+" start\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"MTask starting, mtaskId="+cvtToStr(mtaskId)+"\\n\"););\n");
puts("Verilated::mtaskId("+cvtToStr(mtaskId)+");\n");
}
emitSettleLoop(
(string("VL_DEBUG_IF(VL_DBG_MSGF(\"+ Clock loop\\n\"););\n")
+ (v3Global.opt.trace() ? "vlSymsp->__Vm_activity = true;\n" : "")
+ "_eval(vlSymsp);"), false);
if (v3Global.opt.threads()) { // THREADED-TODO move to end of all trains on thread
puts("Verilated::endOfThreadTrain(vlSymsp->__Vm_evalMsgQp);\n");
if (v3Global.opt.threads() == 1) {
puts("Verilated::endOfThreadMTask(vlSymsp->__Vm_evalMsgQp);\n");
}
if (v3Global.opt.threads()) {
puts("Verilated::endOfEval(vlSymsp->__Vm_evalMsgQp);\n");
@@ -2216,6 +2227,17 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
//######################################################################
void EmitCImp::maybeSplit(AstNodeModule* modp) {
if (splitNeeded()) {
// Close old file
delete m_ofp; m_ofp=NULL;
// Open a new file
m_ofp = newOutCFile(modp, !m_fast, true/*source*/, splitFilenumInc());
emitImp(modp);
}
splitSizeInc(10); // Even blank functions get a file with a low csplit
}
void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) {
// Output a module
m_modp = modp;
@@ -2226,37 +2248,18 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) {
UINFO(0," Emitting "<<modClassName(modp)<<endl);
}
if (optSystemC()) {
if (m_fast) {
m_ofp = newOutCFile (modp, !m_fast, false/*source*/);
emitInt (modp);
delete m_ofp; m_ofp=NULL;
}
m_ofp = newOutCFile (modp, !m_fast, true/*source*/);
}
else {
if (m_fast) {
m_ofp = newOutCFile (modp, !m_fast, false/*source*/);
emitInt (modp);
delete m_ofp; m_ofp=NULL;
}
m_ofp = newOutCFile (modp, !m_fast, true/*source*/);
if (m_fast) {
m_ofp = newOutCFile(modp, !m_fast, false/*source*/);
emitInt(modp);
delete m_ofp; m_ofp=NULL;
}
emitImp (modp);
m_ofp = newOutCFile(modp, !m_fast, true/*source*/);
emitImp(modp);
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCFunc* funcp = nodep->castCFunc()) {
if (splitNeeded()) {
// Close old file
delete m_ofp; m_ofp=NULL;
// Open a new file
m_ofp = newOutCFile (modp, !m_fast, true/*source*/, splitFilenumInc());
emitImp (modp);
}
splitSizeInc(10); // Even blank functions get a file with a low csplit
maybeSplit(modp);
mainDoFunc(funcp);
}
}
@@ -2405,14 +2408,20 @@ class EmitCTrace : EmitCStmts {
string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL
|| m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB)
? "full":"chg");
bool emitWidth = false;
if (nodep->dtypep()->basicp()->isDouble()) {
puts("vcdp->"+full+"Double");
} else if (nodep->isWide() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep)) {
puts("vcdp->"+full+"Array");
emitWidth = true;
} else if (nodep->isQuad()) {
puts("vcdp->"+full+"Quad ");
} else if (nodep->declp()->bitRange().ranged()) {
emitWidth = true;
} else if (nodep->declp()->bitRange().ranged()
// 1 element smaller to use Bit dump
&& nodep->declp()->bitRange().elements() != 1) {
puts("vcdp->"+full+"Bus ");
emitWidth = true;
} else {
puts("vcdp->"+full+"Bit ");
}
@@ -2420,8 +2429,7 @@ class EmitCTrace : EmitCStmts {
+ ((arrayindex<0) ? 0 : (arrayindex*nodep->declp()->widthWords()))));
puts(",");
emitTraceValue(nodep, arrayindex);
if (!nodep->dtypep()->basicp()->isDouble() // When float/double no longer have widths this can go
&& (nodep->declp()->bitRange().ranged() || emitTraceIsScBv(nodep) || emitTraceIsScBigUint(nodep))) {
if (emitWidth) {
puts(","+cvtToStr(nodep->declp()->widthMin()));
}
puts(");\n");
@@ -2558,19 +2566,19 @@ void V3EmitC::emitc() {
UINFO(2,__FUNCTION__<<": "<<endl);
// Process each module in turn
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
if (v3Global.opt.outputSplit()) {
{ EmitCImp imp; imp.main(nodep, false, true); }
{ EmitCImp imp; imp.main(nodep, true, false); }
} else {
{ EmitCImp imp; imp.main(nodep, true, true); }
}
if (v3Global.opt.outputSplit()) {
{ EmitCImp fast; fast.main(nodep, false, true); }
{ EmitCImp slow; slow.main(nodep, true, false); }
} else {
{ EmitCImp both; both.main(nodep, true, true); }
}
}
}
void V3EmitC::emitcTrace() {
UINFO(2,__FUNCTION__<<": "<<endl);
if (v3Global.opt.trace()) {
{ EmitCTrace imp (true); imp.main(); }
{ EmitCTrace imp (false); imp.main(); }
{ EmitCTrace slow(true); slow.main(); }
{ EmitCTrace fast(false); fast.main(); }
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ class LifePostDlyVisitor : public LifePostBaseVisitor {
private:
// NODE STATE
// Cleared on entire tree
// AstVarScope::user() -> Sequence # of first virtex setting this var.
// AstVarScope::user() -> Sequence # of first vertex setting this var.
// AstVarScope::user2() -> Sequence # of last consumption of this var
// AstVarScope::user4() -> AstVarScope*: Passed to LifePostElim to substitute this var
AstUser1InUse m_inuser1;
+3 -2
View File
@@ -676,7 +676,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-pins-sc-biguint", flag/*ref*/) ){ m_pinsScBigUint = flag; m_pinsBv = 513; }
else if ( onoff (sw, "-pins-uint8", flag/*ref*/) ){ m_pinsUint8 = flag; }
else if ( !strcmp (sw, "-private") ) { m_public = false; }
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/) ) { m_profileCFuncs = flag; }
else if ( onoff (sw, "-prof-cfuncs", flag/*ref*/) ) { m_profCFuncs = flag; }
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/) ) { m_profCFuncs = flag; } // Undocumented, for backward compat
else if ( onoff (sw, "-public", flag/*ref*/) ) { m_public = flag; }
else if ( !strncmp(sw, "-pvalue+", strlen("-pvalue+"))) { addParameter(string(sw+strlen("-pvalue+")), false); }
else if ( onoff (sw, "-relative-cfuncs", flag/*ref*/) ) { m_relativeCFuncs = flag; }
@@ -1234,7 +1235,7 @@ V3Options::V3Options() {
m_pinsScUint = false;
m_pinsScBigUint = false;
m_pinsUint8 = false;
m_profileCFuncs = false;
m_profCFuncs = false;
m_preprocOnly = false;
m_preprocNoLine = false;
m_public = false;
+4 -3
View File
@@ -86,7 +86,7 @@ class V3Options {
bool m_pinsScUint; // main switch: --pins-sc-uint
bool m_pinsScBigUint;// main switch: --pins-sc-biguint
bool m_pinsUint8; // main switch: --pins-uint8
bool m_profileCFuncs;// main switch: --profile-cfuncs
bool m_profCFuncs; // main switch: --prof-cfuncs
bool m_public; // main switch: --public
bool m_relativeCFuncs; // main switch: --relative-cfuncs
bool m_relativeIncludes; // main switch: --relative-includes
@@ -244,7 +244,7 @@ class V3Options {
bool pinsScUint() const { return m_pinsScUint; }
bool pinsScBigUint() const { return m_pinsScBigUint; }
bool pinsUint8() const { return m_pinsUint8; }
bool profileCFuncs() const { return m_profileCFuncs; }
bool profCFuncs() const { return m_profCFuncs; }
bool allPublic() const { return m_public; }
bool lintOnly() const { return m_lintOnly; }
bool ignc() const { return m_ignc; }
@@ -265,7 +265,8 @@ class V3Options {
int outputSplitCFuncs() const { return m_outputSplitCFuncs; }
int outputSplitCTrace() const { return m_outputSplitCTrace; }
int pinsBv() const { return m_pinsBv; }
int threads() const { return m_threads; }
int threads() const { return m_threads; }
bool mtasks() const { return (m_threads > 1); }
int traceDepth() const { return m_traceDepth; }
int traceMaxArray() const { return m_traceMaxArray; }
int traceMaxWidth() const { return m_traceMaxWidth; }
+2 -2
View File
@@ -548,7 +548,7 @@ private:
: (domainp->hasSettle() ? "_settle"
: (domainp->isMulti() ? "_multiclk" : "_sequent"))));
name = name+"__"+scopep->nameDotless()+"__"+cvtToStr(funcnum);
if (v3Global.opt.profileCFuncs()) {
if (v3Global.opt.profCFuncs()) {
name += "__PROF__"+forWhatp->fileline()->profileFuncname();
}
return name;
@@ -1525,7 +1525,7 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
}
else { // Normal logic
// Make or borrow a CFunc to contain the new statements
if (v3Global.opt.profileCFuncs()
if (v3Global.opt.profCFuncs()
|| (v3Global.opt.outputSplitCFuncs()
&& v3Global.opt.outputSplitCFuncs() < m_pomNewStmts)) {
// Put every statement into a unique function to ease profiling or reduce function size
+8
View File
@@ -652,6 +652,14 @@ void ParamVisitor::visitCell(AstCell* nodep) {
longname += "_" + paramSmallName(srcModp, pinp->modVarp()) + paramValueNumber(pinIrefp);
any_overrides = true;
ifaceRefRefs.push_back(make_pair(portIrefp,pinIrefp));
if (portIrefp->ifacep() != pinIrefp->ifacep()
// Might be different only due to param cloning, so check names too
&& portIrefp->ifaceName() != pinIrefp->ifaceName()) {
pinp->v3error("Port '"<<pinp->prettyName()<<"' expects '"
<<AstNode::prettyName(portIrefp->ifaceName())
<<"' interface but pin connects '"
<<AstNode::prettyName(pinIrefp->ifaceName())<<"' interface");
}
}
}
}
+2 -1
View File
@@ -220,7 +220,8 @@ uint64_t VHashSha1::digestUInt64() {
const string& binhash = digestBinary();
uint64_t out = 0;
for (size_t byte=0; byte<sizeof(uint64_t); ++byte) {
out = (out<<8) | binhash[byte];
unsigned char c = binhash[byte];
out = (out<<8) | c;
}
return out;
}
+1 -1
View File
@@ -487,6 +487,6 @@ void V3Unroll::unrollAll(AstNetlist* nodep) {
}
void V3Unroll::unrollGen(AstNodeFor* nodep, const string& beginName) {
UINFO(2,__FUNCTION__<<": "<<endl);
UINFO(5,__FUNCTION__<<": "<<endl);
UnrollVisitor visitor (nodep, true, beginName);
}
+2 -2
View File
@@ -27,7 +27,7 @@ my $header = ("\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geome
);
foreach my $line (<STDIN>) {
$line =~ s/(\\begin{document})/${header}$1/;
$line =~ s/(\\tableofcontents)/\\begin{titlepage} \\maketitle \\end{titlepage}\n$1/;
$line =~ s/(\\begin\{document\})/${header}$1/;
$line =~ s/(\\tableofcontents)/\\begin\{titlepage\} \\maketitle \\end\{titlepage\}\n$1/;
print "$line";
}
+2 -1
View File
@@ -422,6 +422,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/* Verilog 2005 */
<V05,S05,S09,S12,S17,SAX>{
/* System Tasks */
"$clog2" { FL; return yD_CLOG2; }
/* Keywords */
"uwire" { FL; return yWIRE; }
}
@@ -430,7 +432,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
<S05,S09,S12,S17,SAX>{
/* System Tasks */
"$bits" { FL; return yD_BITS; }
"$clog2" { FL; return yD_CLOG2; }
"$countones" { FL; return yD_COUNTONES; }
"$dimensions" { FL; return yD_DIMENSIONS; }
"$error" { FL; return yD_ERROR; }
+7 -4
View File
@@ -948,19 +948,21 @@ port<nodep>: // ==IEEE: port
{ $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE
{ $$=$4; VARDTYPE($3); $$->addNextNull(VARDONEP($$,$5,$6)); }
| portDirNetE signing portSig variable_dimensionListE sigAttrListE
{ $$=$3; VARDTYPE(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2)); $$->addNextNull(VARDONEP($$,$4,$5)); }
| portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE
{ $$=$4; VARDTYPE(GRAMMARP->addRange(new AstBasicDType($3->fileline(), LOGIC_IMPLICIT, $2), $3,true)); $$->addNextNull(VARDONEP($$,$5,$6)); }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE
{ $$=$2; /*VARDTYPE-same*/ $$->addNextNull(VARDONEP($$,$3,$4)); }
//
| portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$3; VARDTYPE($2); AstVar* vp=VARDONEP($$,$4,$5); $$->addNextNull(vp); vp->valuep($7); }
{ $$=$3; VARDTYPE($2); if (AstVar* vp=VARDONEP($$,$4,$5)) { $$->addNextNull(vp); vp->valuep($7); } }
| portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
{ $$=$4; VARDTYPE($3); if (AstVar* vp=VARDONEP($$,$5,$6)) { $$->addNextNull(vp); vp->valuep($8); } }
| portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$4; VARDTYPE($3); AstVar* vp=VARDONEP($$,$5,$6); $$->addNextNull(vp); vp->valuep($8); }
{ $$=$4; VARDTYPE($3); if (AstVar* vp=VARDONEP($$,$5,$6)) { $$->addNextNull(vp); vp->valuep($8); } }
| portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr
{ $$=$2; /*VARDTYPE-same*/ AstVar* vp=VARDONEP($$,$3,$4); $$->addNextNull(vp); vp->valuep($6); }
{ $$=$2; /*VARDTYPE-same*/ if (AstVar* vp=VARDONEP($$,$3,$4)) { $$->addNextNull(vp); vp->valuep($6); } }
;
portDirNetE: // IEEE: part of port, optional net type and/or direction
@@ -3843,6 +3845,7 @@ vltOnFront<errcodeen>:
%%
int V3ParseImp::bisonParse() {
// Use --debugi-bison 9 to enable this
if (PARSEP->debugBison()>=9) yydebug = 1;
return yyparse();
}
+1
View File
@@ -1,5 +1,6 @@
*.old
obj_dir
obj_*
vcs.key
csrc
cov_work
+2 -4
View File
@@ -33,8 +33,6 @@ ifneq ($(NC_ROOT),)
#PRODUCTS += --nc
endif
PRODUCTS += --vlt
# Run tests in parallel. Requires Parallel::Forker to be installed.
ifeq ($(CFG_WITH_LONGTESTS),yes)
DRIVER_FLAGS += -j 0
@@ -46,7 +44,7 @@ endif
.PHONY: test
test:
$(PERL) driver.pl $(DRIVER_FLAGS) $(PRODUCTS)
$(PERL) driver.pl $(DRIVER_FLAGS) --vlt --dist
######################################################################
@@ -82,4 +80,4 @@ print-cxx-version:
######################################################################
maintainer-copy::
clean mostlyclean distclean maintainer-clean::
-rm -rf obj_dir simv* simx* csrc cov_work INCA_libs *.log *.key logs vc_hdrs.h
-rm -rf obj_* simv* simx* csrc cov_work INCA_libs *.log *.key logs vc_hdrs.h
+6 -1
View File
@@ -28,8 +28,13 @@ VPATH += ../../$(VM_USER_DIR)
# Needed by DPI tests
CPPFLAGS += -DVERILATOR=1
# Needed by tracing routines
# Debugging
CPPFLAGS += -DVL_DEBUG=1
# Assertions disabled as SystemC libraries are not clean
#CPPFLAGS += -D_GLIBCXX_DEBUG
# Needed by tracing routines
CPPFLAGS += -DTEST_OBJ_DIR=$(TEST_OBJ_DIR)
CPPFLAGS += -DVM_PREFIX=$(VM_PREFIX)
CPPFLAGS += -DVM_PREFIX_INCLUDE="<$(VM_PREFIX).h>"
CPPFLAGS += $(CPPFLAGS_DRIVER)
+215 -118
View File
@@ -1,4 +1,6 @@
#!/usr/bin/perl -w
: # -*-Mode: perl;-*- use perl, wherever it is
eval 'exec perl -wS $0 ${1+"$@"}'
if 0;
# See copyright, etc in below POD section.
######################################################################
@@ -33,6 +35,18 @@ $SIG{TERM} = sub { $Fork->kill_tree_all('TERM') if $Fork; die "Quitting...\n"; }
#======================================================================
# Map of all scenarios, with the names used to enable them
our %All_Scenarios
= (dist => [ "dist"],
atsim => ["simulator", "atsim"],
ghdl => ["simulator", "ghdl"],
iv => ["simulator", "iv"],
ms => ["simulator", "ms"],
nc => ["simulator", "nc"],
vcs => ["simulator", "vcs"],
vlt => ["simulator", "vlt_all", "vlt"],
);
#======================================================================
# main
@@ -44,23 +58,18 @@ our @Orig_ARGV_Sw; foreach (@Orig_ARGV) { push @Orig_ARGV_Sw, $_ if /^-/ && !/^
our $Start = time();
$Debug = 0;
my $opt_atsim;
my $opt_benchmark;
my @opt_tests;
my $opt_dist;
my $opt_gdb;
my $opt_gdbbt;
my $opt_gdbsim;
my $opt_ghdl;
my $opt_iv;
my $opt_jobs = 1;
my $opt_ms;
my $opt_nc;
my $opt_optimize;
my %opt_scenarios;
my $opt_site;
my $opt_stop;
my $opt_trace;
my $opt_vlt;
my $opt_vcs;
my $opt_verbose;
my $Opt_Verilated_Debug;
our $Opt_Unsupported;
@@ -69,35 +78,35 @@ our @Opt_Driver_Verilator_Flags;
Getopt::Long::config ("pass_through");
if (! GetOptions (
"benchmark:i" => sub { $opt_benchmark = $_[1] ? $_[1] : 1; },
"debug" => \&debug,
#debugi see parameter()
"atsim|athdl!"=> \$opt_atsim,
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
"gdbsim!" => \$opt_gdbsim,
"ghdl!" => \$opt_ghdl,
"golden!" => sub { $ENV{HARNESS_UPDATE_GOLDEN} = 1; },
"help" => \&usage,
"iverilog!" => \$opt_iv,
"j=i" => \$opt_jobs,
"ms!" => \$opt_ms,
"nc!" => \$opt_nc,
"optimize:s" => \$opt_optimize,
"site!" => \$opt_site,
"stop!" => \$opt_stop,
"trace!" => \$opt_trace,
"unsupported!"=> \$Opt_Unsupported,
"v3!" => \$opt_vlt, # Old
"vl!" => \$opt_vlt, # Old
"vlt!" => \$opt_vlt,
"vcs!" => \$opt_vcs,
"verbose!" => \$opt_verbose,
"verilation!" => \$Opt_Verilation, # Undocumented debugging
"verilated_debug!" => \$Opt_Verilated_Debug,
#W see parameter()
"<>" => \&parameter,
)) {
"benchmark:i" => sub { $opt_benchmark = $_[1] ? $_[1] : 1; },
"debug" => \&debug,
#debugi see parameter()
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
"gdbsim!" => \$opt_gdbsim,
"golden!" => sub { $ENV{HARNESS_UPDATE_GOLDEN} = 1; },
"help" => \&usage,
"j=i" => \$opt_jobs,
"optimize:s" => \$opt_optimize,
"site!" => \$opt_site,
"stop!" => \$opt_stop,
"trace!" => \$opt_trace,
"unsupported!"=> \$Opt_Unsupported,
"verbose!" => \$opt_verbose,
"verilation!" => \$Opt_Verilation, # Undocumented debugging
"verilated_debug!" => \$Opt_Verilated_Debug,
#W see parameter()
# Scenarios
"atsim|athdl!"=> sub { $opt_scenarios{atsim} = $_[1]; },
"dist!" => sub { $opt_scenarios{dist} = $_[1]; },
"ghdl!" => sub { $opt_scenarios{ghdl} = $_[1]; },
"iverilog!" => sub { $opt_scenarios{iverilog} = $_[1]; },
"ms!" => sub { $opt_scenarios{ms} = $_[1]; },
"nc!" => sub { $opt_scenarios{nc} = $_[1]; },
"vlt!" => sub { $opt_scenarios{vlt} = $_[1]; },
"vcs!" => sub { $opt_scenarios{vcs} = $_[1]; },
"<>" => \&parameter,
)) {
die "%Error: Bad usage, try '$0 --help'\n";
}
@@ -105,8 +114,9 @@ $opt_jobs = calc_jobs() if defined $opt_jobs && $opt_jobs==0;
$Fork->max_proc($opt_jobs);
if (!$opt_atsim && !$opt_ghdl && !$opt_iv && !$opt_vcs && !$opt_ms && !$opt_nc && !$opt_vlt) {
$opt_vlt = 1;
if ((scalar keys %opt_scenarios) < 1) {
$opt_scenarios{dist} = 1;
$opt_scenarios{vlt} = 1;
}
our @Test_Dirs = "t";
@@ -128,20 +138,17 @@ if ($#opt_tests>=2 && $opt_jobs>=2) {
open(STDIN, "+>/dev/null");
}
mkdir "obj_dir";
our $Log_Filename = "obj_dir/driver_".strftime("%Y%m%d_%H%M%S.log", localtime);
mkdir "obj_dist";
our $Log_Filename = "obj_dist/driver_".strftime("%Y%m%d_%H%M%S.log", localtime);
my $LeftCnt=0; my $OkCnt=0; my $FailCnt=0; my $SkipCnt=0; my $UnsupCnt=0;
my @fails;
foreach my $testpl (@opt_tests) {
one_test(pl_filename => $testpl, atsim=>1) if $opt_atsim;
one_test(pl_filename => $testpl, ghdl=>1) if $opt_ghdl;
one_test(pl_filename => $testpl, iv=>1) if $opt_iv;
one_test(pl_filename => $testpl, ms=>1) if $opt_ms;
one_test(pl_filename => $testpl, nc=>1) if $opt_nc;
one_test(pl_filename => $testpl, vcs=>1) if $opt_vcs;
one_test(pl_filename => $testpl, vlt=>1, 'v3'=>1) if $opt_vlt;
foreach my $scenario (sort keys %opt_scenarios) {
next if !$opt_scenarios{$scenario};
one_test(pl_filename => $testpl, $scenario=>1);
}
}
$Fork->wait_all(); # Wait for all children to finish
@@ -159,25 +166,18 @@ sub one_test {
my $test = VTest->new(@params);
$test->oprint("="x50,"\n");
unlink $test->{status_filename};
$test->prep;
$test->read;
if ($test->ok) {
$test->oprint("Test PASSED\n");
} elsif ($test->skips && !$test->errors) {
$test->oprint("%Skip: $test->{skips}\n");
} elsif ($test->unsupporteds && !$test->errors) {
$test->oprint("%Unsupported: $test->{unsupporteds}\n");
} else {
$test->error("Missing ok\n") if !$test->errors;
$test->oprint("%Error: $test->{errors}\n");
}
$test->write_status;
$test->_prep;
$test->_read;
# Don't put anything other than _exit after _read,
# as may call _exit via another path
$test->_exit;
},
run_on_finish => sub {
my $test = VTest->new(@params);
$test->read_status;
$test->_read_status;
if ($test->ok) {
$OkCnt++;
} elsif ($test->scenario_off && !$test->errors) {
} elsif ($test->skips && !$test->errors) {
$SkipCnt++;
} elsif ($test->unsupporteds && !$test->errors) {
@@ -187,7 +187,9 @@ sub one_test {
my $j = ($opt_jobs>1?" -j":"");
push @fails, ("\t#".$test->soprint("%Error: $test->{errors}\n")
."\t\tmake$j && test_regress/"
.$test->{pl_filename}." ".join(' ',@Orig_ARGV_Sw)."\n");
.$test->{pl_filename}
." ".join(' ', _args_scenario())
." --".$test->{scenario}."\n");
$FailCnt++;
report(\@fails, $Log_Filename);
my $other = "";
@@ -278,6 +280,21 @@ sub report {
int($delta/60),$delta%60);
}
sub _args_scenario {
# Return command line with scenarios stripped
my @out;
arg:
foreach my $arg (@Orig_ARGV_Sw) {
foreach my $allsc (keys %All_Scenarios) {
foreach my $allscarg (@{$All_Scenarios{$allsc}}) {
next arg if ("--$allscarg" eq $arg);
}
}
push @out, $arg;
}
return @out;
}
#######################################################################
#######################################################################
#######################################################################
@@ -299,18 +316,19 @@ sub new {
$self->{name} ||= $2 if $self->{pl_filename} =~ m!^(.*/)?([^/]*)\.pl$!;
$self->{mode} = "";
$self->{mode} ||= "atsim" if $self->{atsim};
$self->{mode} ||= "ghdl" if $self->{ghdl};
$self->{mode} ||= "vcs" if $self->{vcs};
$self->{mode} ||= "vlt" if $self->{vlt};
$self->{mode} ||= "nc" if $self->{nc};
$self->{mode} ||= "ms" if $self->{ms};
$self->{mode} ||= "iv" if $self->{iv};
$self->{scenario} = "";
$self->{scenario} ||= "dist" if $self->{dist};
$self->{scenario} ||= "atsim" if $self->{atsim};
$self->{scenario} ||= "ghdl" if $self->{ghdl};
$self->{scenario} ||= "vcs" if $self->{vcs};
$self->{scenario} ||= "vlt" if $self->{vlt};
$self->{scenario} ||= "nc" if $self->{nc};
$self->{scenario} ||= "ms" if $self->{ms};
$self->{scenario} ||= "iv" if $self->{iv};
# For backward compatibility, the verilator tests have no prefix
$self->{obj_dir} ||= ("obj_dir/".($self->{mode} eq 'vlt' ? "" : $self->{mode}."_")
."$self->{name}");
mkdir "obj_$self->{scenario}";
$self->{obj_dir} ||= ("obj_$self->{scenario}/$self->{name}");
foreach my $dir (@::Test_Dirs) {
# t_dir used both absolutely and under obj_dir
@@ -339,6 +357,7 @@ sub new {
v_flags => [split(/\s+/,(" -f input.vc "
.($self->{t_dir} !~ m!/test_regress! # Don't include standard dir, only site's
? " +incdir+$self->{t_dir} -y $self->{t_dir}" : "")
. " +define+TEST_OBJ_DIR=$self->{obj_dir}"
.($opt_verbose ? " +define+TEST_VERBOSE=1":"")
.($opt_benchmark ? " +define+TEST_BENCHMARK=$opt_benchmark":"")
.($opt_trace ? " +define+WAVES=1":"")
@@ -388,7 +407,6 @@ sub new {
ms_run_flags => [split(/\s+/,"-lib $self->{obj_dir}/work -c -do 'run -all;quit' ")],
# Verilator
vlt => 0,
'v3' => 0,
verilator_flags => ["-cc",
"-Mdir $self->{obj_dir}",
"-OD", # As currently disabled unless -O3
@@ -402,6 +420,8 @@ sub new {
%$self};
bless $self, $class;
$self->{vlt_all} = $self->{vlt}; # Any Verilator scenario
$self->{VM_PREFIX} ||= "V".$self->{name};
$self->{stats} ||= "$self->{obj_dir}/V".$self->{name}."__stats.txt";
$self->{status_filename} ||= "$self->{obj_dir}/V".$self->{name}.".status";
@@ -425,46 +445,82 @@ sub new {
}
sub soprint {
my $self = shift;
my $str = "$self->{mode}/$self->{name}: ".join('',@_);
my $self = (ref $_[0] ? shift : $Self);
my $str = "$self->{scenario}/$self->{name}: ".join('',@_);
$str =~ s/\n\n+$/\n/s;
return $str;
}
sub oprint {
my $self = shift;
my $self = (ref $_[0] ? shift : $Self);
print $self->soprint(@_);
}
sub error {
my $self = shift;
my $self = (ref $_[0] ? shift : $Self);
my $msg = join('',@_);
warn "%Warning: $self->{mode}/$self->{name}: ".$msg."\n";
# Called from tests as: error("Reason message"[, ...]);
warn "%Warning: $self->{scenario}/$self->{name}: ".$msg."\n";
$self->{errors} ||= $msg;
}
sub skip {
my $self = shift;
my $self = (ref $_[0] ? shift : $Self);
my $msg = join('',@_);
warn "%Skip: $self->{mode}/$self->{name}: ".$msg."\n";
# Called from tests as: skip("Reason message"[, ...]);
warn "-Skip: $self->{scenario}/$self->{name}: ".$msg."\n";
$self->{skips} ||= "Skip: ".$msg;
}
sub unsupported {
my $self = shift;
my $self = (ref $_[0] ? shift : $Self);
my $msg = join('',@_);
warn "%Unsupported: $self->{mode}/$self->{name}: ".$msg."\n";
# Called from tests as: unsupported("Reason message"[, ...]);
warn "-Unsupported: $self->{scenario}/$self->{name}: ".$msg."\n";
if (!$::Opt_Unsupported) {
$self->{unsupporteds} ||= "Unsupported: ".$msg;
}
}
sub prep {
sub scenarios {
my $self = (ref $_[0] ? shift : $Self);
my %params = (@_);
# Called from tests as: scenarios(...);
# to specify which scenarios this test runs under.
# Where ... is one cases listed in All_Scenarios
if ((scalar keys %params) < 1) {
$params{simulators} = 1;
}
my %enabled_scenarios;
foreach my $scenario (keys %params) {
my $value = $params{$scenario};
my $hit = 0;
foreach my $allsc (keys %All_Scenarios) {
foreach my $allscarg (@{$All_Scenarios{$allsc}}) {
if ($scenario eq $allscarg) {
$hit = 1;
$enabled_scenarios{$allsc} = 1;
}
}
}
if (!$hit) {
$self->error("scenarios('$scenario' => ...) has unknown scenario '$scenario',");
}
}
if (!$enabled_scenarios{$self->{scenario}}) {
$self->skip("scenario '$self->{scenario}' not enabled for test");
$self->{scenario_off} ||= 1;
$self->_exit();
}
}
sub _prep {
my $self = shift;
mkdir $self->{obj_dir}; # Ok if already exists
}
sub read {
sub _read {
my $self = shift;
# Read the control file
(-r $self->{pl_filename})
@@ -474,7 +530,23 @@ sub read {
require $self->{pl_filename};
}
sub write_status {
sub _exit {
my $self = shift;
if ($self->ok) {
$self->oprint("Self PASSED\n");
} elsif ($self->skips && !$self->errors) {
$self->oprint("%Skip: $self->{skips}\n");
} elsif ($self->unsupporteds && !$self->errors) {
$self->oprint("%Unsupported: $self->{unsupporteds}\n");
} else {
$self->error("Missing ok\n") if !$self->errors;
$self->oprint("%Error: $self->{errors}\n");
}
$self->_write_status;
exit(0);
}
sub _write_status {
my $self = shift;
my $filename = $self->{status_filename};
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
@@ -483,11 +555,15 @@ sub write_status {
$fh->close();
}
sub read_status {
sub _read_status {
my $self = shift;
my $filename = $self->{status_filename};
use vars qw($VAR1);
local $VAR1;
if (!-r $filename) {
$self->error("driver.pl _read_status file missing: $filename");
return;
}
require $filename or die "%Error: $! $filename,";
if ($VAR1) {
%{$self} = %{$VAR1};
@@ -660,7 +736,7 @@ sub compile {
fails=>$param{fails},
cmd=>\@cmd);
}
elsif ($param{vlt}) {
elsif ($param{vlt_all}) {
my @cmdargs = $self->compile_vlt_flags(%param);
if ($self->sc && !$self->have_sc) {
@@ -686,6 +762,7 @@ sub compile {
"-C ".$self->{obj_dir},
"-f ".getcwd()."/Makefile_obj",
"VM_PREFIX=$self->{VM_PREFIX}",
"TEST_OBJ_DIR=$self->{obj_dir}",
"CPPFLAGS_DRIVER=-D".uc($self->{name}),
($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""),
($param{make_main}?"":"MAKE_MAIN=0"),
@@ -696,7 +773,7 @@ sub compile {
}
}
else {
$self->error("No compile step for this simulator");
$self->error("No compile step defined for '$self->{scenario}' scenario");
}
if ($param{make_pli}) {
@@ -793,7 +870,7 @@ sub execute {
expect=>$param{vcs_run_expect}, # non-verilator expect isn't the same
);
}
elsif ($param{vlt}
elsif ($param{vlt_all}
#&& (!$param{needs_v4} || -r "$ENV{VERILATOR_ROOT}/src/V3Gate.cpp")
) {
$param{executable} ||= "$self->{obj_dir}/$param{VM_PREFIX}";
@@ -817,7 +894,7 @@ sub execute {
sub inline_checks {
my $self = (ref $_[0]? shift : $Self);
return 1 if $self->errors || $self->skips || $self->unsupporteds;
return 1 if !$self->{vlt};
return 1 if !$self->{vlt_all};
my %param = (%{$self}, @_); # Default arguments are from $self
@@ -875,6 +952,11 @@ sub errors {
return $self->{errors};
}
sub scenario_off {
my $self = (ref $_[0]? shift : $Self);
return $self->{scenario_off};
}
sub skips {
my $self = (ref $_[0]? shift : $Self);
return $self->{skips};
@@ -1128,6 +1210,7 @@ sub _make_main {
}
print $fh " Verilated::commandArgs(argc, argv);\n";
print $fh " Verilated::debug(".($self->{verilated_debug}?1:0).");\n";
print $fh " srand48(5);\n"; # Ensure determinism
print $fh " Verilated::randReset(".$self->{verilated_randReset}.");\n" if defined $self->{verilated_randReset};
print $fh " topp = new $VM_PREFIX (\"top\");\n";
my $set;
@@ -1529,8 +1612,8 @@ sub cxx_version {
our $_Cfg_With_Threaded;
sub cfg_with_threaded {
my $out = `make -f ../Makefile print-cfg-with-threaded`;
return ($out =~ /yes/i) ? 1:0;
$_Cfg_With_Threaded ||= `make -f ../Makefile print-cfg-with-threaded`;
return ($_Cfg_With_Threaded =~ /yes/i) ? 1:0;
}
sub file_grep_not {
@@ -1844,10 +1927,6 @@ not matter. This makes it easier to extend or modify the test in future.
=over 4
=item --atsim
Run using ATSIM simulator.
=item --benchmark [<cycles>]
Show execution times of each step. If an optional number is given,
@@ -1885,10 +1964,6 @@ print backtrace information. Requires --debug.
Run Verilator generated executable under the debugger.
=item --ghdl
Run using GHDL simulator.
=item --golden
Update golden files, equivalent to setting HARNESS_UPDATE_GOLDEN=1.
@@ -1897,23 +1972,11 @@ Update golden files, equivalent to setting HARNESS_UPDATE_GOLDEN=1.
Displays this message and program version and exits.
=item --iverilog
Run using Icarus Verilog simulator.
=item --j #
Run number of parallel tests, or 0 to determine the count based on the
number of cores installed. Requires Perl's Parallel::Forker package.
=item --ms
Run using ModelSim simulator.
=item --nc
Run using Cadence NC-Verilog simulator.
=item --optimize
Randomly turn on/off different optimizations. With specific flags,
@@ -1935,18 +1998,52 @@ Set the simulator specific flags to request waveform tracing.
Run tests even if marked as unsupported.
=item --vcs
Run using Synopsys VCS simulator.
=item --verbose
Compile and run the test in verbose mode. This means C<TEST_VERBOSE> will
be defined for the test (Verilog and any C++/SystemC wrapper).
=back
=head1 SCENARIO ARGUMENTS
The following options control which simulator is used, and which tests are
run. Multiple flags may be used to run multiple simulators/scenarios
simultaneously.
=over 4
=item --atsim
Run ATSIM simulator tests.
=item --dist
Run simulator-agnostic distribution tests.
=item --ghdl
Run GHDL simulator tests.
=item --iverilog
Run Icarus Verilog simulator tests.
=item --ms
Run ModelSim simulator tests.
=item --nc
Run Cadence NC-Verilog simulator tests.
=item --vcs
Run Synopsys VCS simulator tests.
=item --vlt
Run using Verilator. Defaults set unless another simulator is requested.
Run Verilator tests. Default unless another scenario flag is provided.
=back
+1 -1
View File
@@ -19,4 +19,4 @@ $ENV{PWD} = Cwd::getcwd(); # Else chdir leaves the .. which confuses later comm
@args = map { s!.*test_regress/!!; $_; } @args;
exec("./driver.pl", @args);
die;
die "$!, in exec";
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+6 -4
View File
@@ -11,16 +11,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# after building so we make sure to run with --gdbbt, so if it dumps we'll
# get a trace.
scenarios(simulator => 1);
$DEBUG_QUIET = "--debug --debugi 0 --gdbbt --no-dump-tree";
$Self->run(cmd=>["perl", "../bin/verilator", $DEBUG_QUIET, "-V"]);
run(cmd => ["perl", "../bin/verilator", $DEBUG_QUIET, "-V"]);
compile (
compile(
verilator_flags2 => [$DEBUG_QUIET, "--trace"],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -11,16 +11,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# after building so we make sure to run with --gdbbt, so if it dumps we'll
# get a trace.
scenarios(simulator => 1);
top_filename("t/t_a_first_cc.v");
$DEBUG_QUIET = "--debug --debugi 0 --gdbbt --no-dump-tree";
compile (
compile(
verilator_flags2 => [$DEBUG_QUIET, "-sc --trace"],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+2 -2
View File
@@ -7,12 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} or $Self->skip("Verilator only test");
scenarios(vlt_all => 1);
top_filename("t/t_altera_lpm.v");
(my $module = $Self->{name}) =~ s/.*t_altera_//;
compile (
compile(
verilator_flags2 => ["--top-module ${module}"]
);
+7 -5
View File
@@ -7,12 +7,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
scenarios(simulator => 1);
execute (
check_finished=>1,
);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;
+8 -6
View File
@@ -7,13 +7,15 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2 => ["-Wno-CLKDATA"],
);
scenarios(simulator => 1);
execute (
check_finished=>1,
);
compile(
verilator_flags2 => ["-Wno-CLKDATA"],
);
execute(
check_finished => 1,
);
ok(1);
1;
+8 -6
View File
@@ -7,17 +7,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2 => ["--stats"],
);
scenarios(simulator => 1);
compile(
verilator_flags2 => ["--stats"],
);
if ($Self->{vlt}) {
file_grep ($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 6);
}
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
ok(1);
1;
+6 -4
View File
@@ -7,16 +7,18 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
verilator_flags2 => ["--stats"],
);
if ($Self->{vlt}) {
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 0);
}
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+9 -7
View File
@@ -7,17 +7,19 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2 => ["--stats"],
);
scenarios(simulator => 1);
if ($Self->{vlt}) {
compile(
verilator_flags2 => ["--stats"],
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 0);
}
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
ok(1);
1;
+5 -3
View File
@@ -7,9 +7,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
fails=>1,
expect=>
scenarios(simulator => 1);
compile(
fails => 1,
expect =>
q{%Error: t/t_array_backw_index_bad.v:\d+: Slice selection '\[1:3\]' has backward indexing versus data type's '\[3:0\]'
%Error: t/t_array_backw_index_bad.v:\d+: Slice selection '\[3:1\]' has backward indexing versus data type's '\[0:3\]'
%Error: t/t_array_backw_index_bad.v:\d+: Slice selection index '\[4:3\]' outside data type's '\[3:0\]'
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+6 -3
View File
@@ -6,14 +6,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# 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.
scenarios(simulator => 1);
top_filename("t/t_array_interface.v");
compile (
compile(
v_flags2 => ["-Oi"],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+7 -5
View File
@@ -7,12 +7,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
scenarios(simulator => 1);
execute (
check_finished=>1,
);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;
+7 -6
View File
@@ -7,14 +7,15 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug446");
scenarios(simulator => 1);
$Self->{vlt_all} and unsupported("Verilator unsupported, bug446");
compile (
);
compile(
);
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
ok(1);
1;
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+3 -1
View File
@@ -7,7 +7,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
ok(1);
+9 -7
View File
@@ -7,14 +7,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
scenarios(simulator => 1);
execute (
check_finished=>1,
);
compile(
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute(
check_finished => 1,
);
ok(1);
1;
+11 -9
View File
@@ -7,21 +7,23 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_basic.v");
compile (
verilator_flags2 => ['--assert --cc --coverage-user'],
);
compile(
verilator_flags2 => ['--assert --cc --coverage-user'],
);
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
#Needs work
print "-Info: NOT checking for coverage\n";
#file_grep ($Self->{coverage_filename}, qr/t=>'psl_cover',o=>'cover',c=>2\);/);
#file_grep ($Self->{coverage_filename}, qr/DefaultClock.*,c=>1\);/);
#file_grep ($Self->{coverage_filename}, qr/ToggleLogIf.*,c=>9\);/);
#file_grep($Self->{coverage_filename}, qr/t=>'psl_cover',o=>'cover',c=>2\);/);
#file_grep($Self->{coverage_filename}, qr/DefaultClock.*,c=>1\);/);
#file_grep($Self->{coverage_filename}, qr/ToggleLogIf.*,c=>9\);/);
ok(1);
1;
+11 -8
View File
@@ -7,17 +7,20 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_basic.v");
compile (
v_flags2 => ['+define+FAILING_ASSERTIONS',
$Self->{v3}?'--assert':($Self->{nc}?'+assert':'')],
fails => $Self->{nc},
);
compile(
v_flags2 => ['+define+FAILING_ASSERTIONS',
($Self->{vlt_all} ? '--assert'
: ($Self->{nc} ? '+assert' : ''))],
fails => $Self->{nc},
);
execute (
fails => $Self->{vlt},
);
execute(
fails => $Self->{vlt_all},
);
ok(1);
1;
+8 -6
View File
@@ -7,15 +7,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_basic.v");
compile (
v_flags2 => [],
);
compile(
v_flags2 => [],
);
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
ok(1);
1;
+5 -3
View File
@@ -7,12 +7,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--assert'],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,13 +7,15 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+5 -3
View File
@@ -7,13 +7,15 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
check_finished=>0,
execute(
check_finished => 0,
fails => 1,
expect =>
'.*%Warning: t_assert_comp_bad.v:\d+: Assertion failed in top.t.genblk1: User compile-time warning
+22 -20
View File
@@ -7,39 +7,41 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_cover.v");
compile (
verilator_flags2 => ['--assert --cc --coverage-user'],
nc_flags2 => ["+nccovoverwrite +nccoverage+all +nccovtest+$Self->{name}"]
);
compile(
verilator_flags2 => ['--assert --cc --coverage-user'],
nc_flags2 => ["+nccovoverwrite +nccoverage+all +nccovtest+$Self->{name}"]
);
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
if ($Self->{nc}) {
my $name = $Self->{name};
my $cf = "$Self->{obj_dir}/${name}__nccover.cf";
{
my $fh = IO::File->new(">$cf") or die "%Error: $! writing $cf,";
$fh->printf("report_summary -module *\n");
$fh->printf("report_detail -both -instance *\n");
$fh->printf("report_html -both -instance * > $Self->{obj_dir}/${name}__nccover.html\n");
$fh->close;
my $fh = IO::File->new(">$cf") or die "%Error: $! writing $cf,";
$fh->printf("report_summary -module *\n");
$fh->printf("report_detail -both -instance *\n");
$fh->printf("report_html -both -instance * > $Self->{obj_dir}/${name}__nccover.html\n");
$fh->close;
}
$Self->run(logfile=>"$Self->{obj_dir}/${name}__nccover.log",
tee=>0,
cmd=>[($ENV{VERILATOR_ICCR}||'iccr'),
"-test ${name} ${cf}"]);
run(logfile => "$Self->{obj_dir}/${name}__nccover.log",
tee => 0,
cmd => [($ENV{VERILATOR_ICCR}||'iccr'),
"-test ${name} ${cf}"]);
}
file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==4/);
file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==5/);
file_grep ($Self->{run_log_filename}, qr/COVER: Cyc==6/);
file_grep($Self->{run_log_filename}, qr/COVER: Cyc==4/);
file_grep($Self->{run_log_filename}, qr/COVER: Cyc==5/);
file_grep($Self->{run_log_filename}, qr/COVER: Cyc==6/);
# Allow old Perl format dump, or new binary dump
file_grep ($Self->{coverage_filename}, qr/(cyc_eq_5.*,c=>[^0]|cyc_eq_5.* [1-9][0-9]*\n)/);
file_grep($Self->{coverage_filename}, qr/(cyc_eq_5.*,c=>[^0]|cyc_eq_5.* [1-9][0-9]*\n)/);
ok(1);
1;
+8 -6
View File
@@ -7,15 +7,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_cover.v");
compile (
v_flags2 => [],
);
compile(
v_flags2 => [],
);
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
ok(1);
1;
+7 -5
View File
@@ -7,14 +7,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
fails=>1,
expect=>
scenarios(simulator => 1);
compile(
v_flags2 => ["--lint-only"],
fails => 1,
expect =>
'%Error: t/t_assert_dup_bad.v:\d+: Duplicate declaration of block: covlabel
%Error: t/t_assert_dup_bad.v:\d+: ... Location of original declaration
%Error: Exiting due to.*',
);
);
ok(1);
1;
+5 -3
View File
@@ -7,11 +7,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+6 -4
View File
@@ -7,18 +7,20 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_elab.v");
unlink("$Self->{obj_dir}/t_assert_elab_bad.log");
compile (
compile(
v_flags2 => ['+define+FAILING_ASSERTIONS',
$Self->{v3}?'--assert':($Self->{nc}?'+assert':'')],
$Self->{vlt_all} ? '--assert' : ($Self->{nc} ? '+assert':'')],
fails => 1,
);
execute (
fails => $Self->{vlt},
execute(
fails => $Self->{vlt_all},
);
file_grep ("$Self->{obj_dir}/vlt_compile.log",
+5 -3
View File
@@ -7,12 +7,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--assert --cc'],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+4 -2
View File
@@ -7,14 +7,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_property.v");
compile (
compile(
v_flags2 => ['+define+FAIL_ASSERT_1'],
verilator_flags2 => ['--assert --cc'],
);
execute (
execute(
fails => 1
);
+4 -2
View File
@@ -7,14 +7,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_property.v");
compile (
compile(
v_flags2 => ['+define+FAIL_ASSERT_2'],
verilator_flags2 => ['--assert --cc'],
);
execute (
execute(
fails => 1
);
+5 -3
View File
@@ -7,12 +7,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
verilator_flags2 => ['--assert'],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+9 -7
View File
@@ -7,14 +7,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
scenarios(simulator => 1);
execute (
check_finished=>1,
);
compile(
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute(
check_finished => 1,
);
ok(1);
1;
+12 -10
View File
@@ -7,20 +7,22 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_synth.v");
compile (
v_flags2 => ['+define+FAILING_FULL'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
compile(
v_flags2 => ['+define+FAILING_FULL'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
check_finished=>0,
fails=> $Self->{vlt},
expect=>
execute(
check_finished => 0,
fails => $Self->{vlt_all},
expect =>
'%Error: t_assert_synth.v:\d+: Assertion failed in top.t: synthesis full_case'
);
);
ok(1);
1;
+12 -10
View File
@@ -7,19 +7,21 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_synth.v");
compile (
v_flags2 => ['+define+FAILING_FULL',
'+define+FAILING_PARALLEL',
'+define+FAILING_OH',
'+define+FAILING_OC',
],
);
compile(
v_flags2 => ['+define+FAILING_FULL',
'+define+FAILING_PARALLEL',
'+define+FAILING_OH',
'+define+FAILING_OC',
],
);
execute (
check_finished=>1,
);
execute(
check_finished => 1,
);
ok(1);
1;
+12 -10
View File
@@ -7,20 +7,22 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
top_filename("t/t_assert_synth.v");
compile (
v_flags2 => ['+define+FAILING_PARALLEL'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
compile(
v_flags2 => ['+define+FAILING_PARALLEL'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
check_finished=>0,
fails => $Self->{v3},
expect=>
execute(
check_finished => 0,
fails => $Self->{vlt_all},
expect =>
'%Error: t_assert_synth.v:\d+: Assertion failed in top.t: synthesis parallel_case'
);
);
ok(1);
1;
+5 -3
View File
@@ -7,12 +7,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
scenarios(simulator => 1);
compile(
verilator_flags2 => ["-O0 -OG"],
);
execute (
check_finished=>1,
execute(
check_finished => 1,
);
ok(1);
+7 -5
View File
@@ -7,12 +7,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
scenarios(simulator => 1);
execute (
check_finished=>1,
);
compile(
);
execute(
check_finished => 1,
);
ok(1);
1;

Some files were not shown because too many files have changed in this diff Show More