mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
77e7e2bf1c | ||
|
|
1c5c9e2435 | ||
|
|
f0ed4346b2 | ||
|
|
94c8064798 | ||
|
|
cf0464c263 | ||
|
|
6268db643c | ||
|
|
fd98d231e4 | ||
|
|
92649ba494 | ||
|
|
0efe343494 | ||
|
|
84335b9580 | ||
|
|
e8b2c57610 | ||
|
|
5e22ca77ec | ||
|
|
b6e8133a4d | ||
|
|
02a22c12ea | ||
|
|
fe917ba7f4 | ||
|
|
2c568603f6 | ||
|
|
51422e3ee8 | ||
|
|
0ef3c10931 | ||
|
|
35be80f789 | ||
|
|
c29e7619eb | ||
|
|
a265417727 | ||
|
|
b69af164f7 | ||
|
|
ff61bb509c | ||
|
|
c8ba51581f | ||
|
|
29f1a9208e | ||
|
|
8b954dc381 | ||
|
|
767ac2547d | ||
|
|
a46aa2d62b | ||
|
|
9219ddaece | ||
|
|
c7c99d8553 | ||
|
|
e3354a0191 |
@@ -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]
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
/obj_dir/
|
||||
/obj_dbg/
|
||||
/obj_opt/
|
||||
/obj_vlt/
|
||||
/obj_vltmt/
|
||||
/obj_dist/
|
||||
/INCA_libs/
|
||||
/cov_work/
|
||||
/logs/
|
||||
|
||||
+31
-21
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
######################################################################
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,5 +1,6 @@
|
||||
*.old
|
||||
obj_dir
|
||||
obj_*
|
||||
vcs.key
|
||||
csrc
|
||||
cov_work
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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()
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
"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]; },
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
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
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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\]'
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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,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,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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
Reference in New Issue
Block a user