Remove --no-threads; require --threads 1 for single threaded (#3703).

This commit is contained in:
Kamil Rakoczy 2022-11-05 13:47:34 +01:00 committed by GitHub
parent 8d61cea366
commit d6126c4b32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 283 additions and 378 deletions

View File

@ -322,7 +322,7 @@ CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
cppcheck: $(CPPCHECK_DEP)
%.cppcheck: %.cpp
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 -DVL_THREADED=1 $(CPPCHECK_INC) $<
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $<
CLANGTIDY = clang-tidy
CLANGTIDY_FLAGS = -config='' \
@ -330,7 +330,7 @@ CLANGTIDY_FLAGS = -config='' \
-checks='-fuchsia-*,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-init-variables,-cppcoreguidelines-avoid-goto,-modernize-avoid-c-arrays,-readability-magic-numbers,-readability-simplify-boolean-expr,-cppcoreguidelines-macro-usage' \
CLANGTIDY_DEP = $(subst .cpp,.cpp.tidy,$(CPPCHECK_CPP))
CLANGTIDY_DEFS = -DVL_DEBUG=1 -DVL_THREADED=1 -DVL_CPPCHECK=1
CLANGTIDY_DEFS = -DVL_DEBUG=1 -DVL_CPPCHECK=1
clang-tidy: $(CLANGTIDY_DEP)
%.cpp.tidy: %.cpp

View File

@ -1213,15 +1213,18 @@ Summary:
.. option:: --threads <threads>
.. option:: --no-threads
With "--threads 0" or "--no-threads", the default, the generated model
is not thread safe. With "--threads 1", the generated model is single
threaded but may run in a multithreaded environment. With "--threads N",
With "--threads 1", the default, the generated model is single threaded
but may run in a multithreaded environment. With "--threads N",
where N >= 2, the model is generated to run multithreaded on up to N
threads. See :ref:`Multithreading`. This option also applies to
:vlopt:`--trace` (but not :vlopt:`--trace-fst`).
.. option:: --no-threads
Deprecated and has no effect (ignored).
In versions prior to 5.004, created a model which was not thread safe.
.. option:: --threads-dpi all
.. option:: --threads-dpi none

View File

@ -183,11 +183,6 @@ Multithreading
Verilator supports multithreaded simulation models.
With :vlopt:`--no-threads`, the default, the model is not thread safe, and
any use of more than one thread calling into one or even different
Verilated models may result in unpredictable behavior. This gives the
highest single thread performance.
With :vlopt:`--threads 1 <--threads>`, the generated model is single
threaded, however the support libraries are multithread safe. This allows
different instantiations of model(s) to potentially each be run under a
@ -203,13 +198,6 @@ oversubscription, the Verilated model should not livelock nor deadlock,
however, you can expect performance to be far worse than it would be with
proper ratio of threads and CPU cores.
The remainder of this section describe behavior with :vlopt:`--threads 1
<--threads>` or :vlopt:`--threads {N} <--threads>` (not
:vlopt:`--no-threads`).
:code:`VL_THREADED` is defined in the C++ code when compiling a threaded
Verilated module, causing the Verilated support classes become threadsafe.
The thread used for constructing a model must be the same thread that calls
:code:`eval()` into the model, this is called the "eval thread". The thread
used to perform certain global operations such as saving and tracing must

View File

@ -37,5 +37,4 @@ PREDEFINED = \
"VL_NOT_FINAL=" \
"VL_PURE=" \
"VL_REQUIRES()=" \
"VL_THREAD_LOCAL=" \
"__restrict=" \

View File

@ -27,7 +27,7 @@
//
// verilated.o may exist both in --lib-create (incrementally linked .a/.so)
// and the main module. Both refer the same instance of static
// variables/VL_THREAD_LOCAL in verilated.o such as Verilated, or
// variables/thread_local in verilated.o such as Verilated, or
// VerilatedImpData. This is important to share that state, but the
// sharing may cause a double-free error when shutting down because the
// loader will insert a constructor/destructor at each reference to
@ -68,9 +68,7 @@
# include <direct.h> // mkdir
#endif
#ifdef VL_THREADED
# include "verilated_threads.h"
#endif
#include "verilated_threads.h"
// clang-format on
#include "verilated_trace.h"
@ -96,7 +94,7 @@ VerilatedContext* Verilated::s_lastContextp = nullptr;
// Keep below together in one cache line
// Internal note: Globals may multi-construct, see verilated.cpp top.
VL_THREAD_LOCAL Verilated::ThreadLocal Verilated::t_s;
thread_local Verilated::ThreadLocal Verilated::t_s;
//===========================================================================
// User definable functions
@ -193,43 +191,27 @@ void vl_warn(const char* filename, int linenum, const char* hier, const char* ms
// Wrapper to call certain functions via messages when multithreaded
void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg{[=]() { //
vl_finish(filename, linenum, hier);
}});
#else
vl_finish(filename, linenum, hier);
#endif
}
void VL_STOP_MT(const char* filename, int linenum, const char* hier, bool maybe) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg{[=]() { //
vl_stop_maybe(filename, linenum, hier, maybe);
}});
#else
vl_stop_maybe(filename, linenum, hier, maybe);
#endif
}
void VL_FATAL_MT(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg{[=]() { //
vl_fatal(filename, linenum, hier, msg);
}});
#else
vl_fatal(filename, linenum, hier, msg);
#endif
}
void VL_WARN_MT(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg{[=]() { //
vl_warn(filename, linenum, hier, msg);
}});
#else
vl_warn(filename, linenum, hier, msg);
#endif
}
//===========================================================================
@ -252,24 +234,16 @@ std::string _vl_string_vprintf(const char* formatp, va_list ap) VL_MT_SAFE {
}
uint64_t _vl_dbg_sequence_number() VL_MT_SAFE {
#ifdef VL_THREADED
static std::atomic<uint64_t> sequence;
#else
static uint64_t sequence = 0;
#endif
return ++sequence;
}
uint32_t VL_THREAD_ID() VL_MT_SAFE {
#ifdef VL_THREADED
// Alternative is to use std::this_thread::get_id, but that returns a
// hard-to-read number and is very slow
static std::atomic<uint32_t> s_nextId(0);
static VL_THREAD_LOCAL uint32_t t_myId = ++s_nextId;
static thread_local uint32_t t_myId = ++s_nextId;
return t_myId;
#else
return 0;
#endif
}
void VL_DBG_MSGF(const char* formatp, ...) VL_MT_SAFE {
@ -288,7 +262,6 @@ void VL_DBG_MSGF(const char* formatp, ...) VL_MT_SAFE {
VL_PRINTF("-V{t%u,%" PRIu64 "}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str());
}
#ifdef VL_THREADED
void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
va_list ap;
va_start(ap, formatp);
@ -298,7 +271,6 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
VL_PRINTF("%s", out.c_str());
}});
}
#endif
//===========================================================================
// Random -- Mostly called at init time, so not inline.
@ -317,8 +289,8 @@ static uint32_t vl_sys_rand32() VL_MT_UNSAFE {
}
uint64_t vl_rand64() VL_MT_SAFE {
static VL_THREAD_LOCAL uint64_t t_state[2];
static VL_THREAD_LOCAL uint32_t t_seedEpoch = 0;
static thread_local uint64_t t_state[2];
static thread_local uint32_t t_seedEpoch = 0;
// For speed, we use a thread-local epoch number to know when to reseed
// A thread always belongs to a single context, so this works out ok
if (VL_UNLIKELY(t_seedEpoch != VerilatedContextImp::randSeedEpoch())) {
@ -762,7 +734,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
// Note uses a single buffer internally; presumes only one usage per printf
// Note also assumes variables < 64 are not wide, this assumption is
// sometimes not true in low-level routines written here in verilated.cpp
static VL_THREAD_LOCAL char t_tmp[VL_VALUE_STRING_MAX_WIDTH];
static thread_local char t_tmp[VL_VALUE_STRING_MAX_WIDTH];
const char* pctp = nullptr; // Most recent %##.##g format
bool inPct = false;
bool widthSet = false;
@ -1160,7 +1132,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
// Read a Verilog $sscanf/$fscanf style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
static VL_THREAD_LOCAL char t_tmp[VL_VALUE_STRING_MAX_WIDTH];
static thread_local char t_tmp[VL_VALUE_STRING_MAX_WIDTH];
int floc = fbits - 1;
IData got = 0;
bool inPct = false;
@ -1453,7 +1425,7 @@ void VL_FCLOSE_I(IData fdi) VL_MT_SAFE {
}
void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
@ -1464,7 +1436,7 @@ void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE
}
void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
@ -1475,7 +1447,7 @@ void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE
}
void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
@ -1486,7 +1458,7 @@ void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE
}
void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
@ -1497,7 +1469,7 @@ void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE
}
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
@ -1518,7 +1490,7 @@ void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, .
}
std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
@ -1529,7 +1501,7 @@ std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE {
}
void VL_WRITEF(const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
va_start(ap, formatp);
@ -1541,7 +1513,7 @@ void VL_WRITEF(const char* formatp, ...) VL_MT_SAFE {
void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
static VL_THREAD_LOCAL std::string t_output; // static only for speed
static thread_local std::string t_output; // static only for speed
t_output = "";
va_list ap;
@ -1771,7 +1743,7 @@ IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_S
const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE {
const std::string& match = Verilated::threadContextp()->impp()->argPlusMatch(prefixp);
static VL_THREAD_LOCAL char t_outstr[VL_VALUE_STRING_MAX_WIDTH];
static thread_local char t_outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match.empty()) return nullptr;
char* dp = t_outstr;
for (const char* sp = match.c_str() + std::strlen(prefixp) + 1; // +1 to skip the "+"
@ -1865,7 +1837,7 @@ IData VL_ATOI_N(const std::string& str, int base) VL_PURE {
static const char* memhFormat(int nBits) {
assert((nBits >= 1) && (nBits <= 32));
static VL_THREAD_LOCAL char t_buf[32];
static thread_local char t_buf[32];
switch ((nBits - 1) / 4) {
case 0: VL_SNPRINTF(t_buf, 32, "%%01x"); break;
case 1: VL_SNPRINTF(t_buf, 32, "%%02x"); break;
@ -1883,7 +1855,7 @@ static const char* memhFormat(int nBits) {
static const char* formatBinary(int nBits, uint32_t bits) {
assert((nBits >= 1) && (nBits <= 32));
static VL_THREAD_LOCAL char t_buf[64];
static thread_local char t_buf[64];
for (int i = 0; i < nBits; i++) {
const bool isOne = bits & (1 << (nBits - 1 - i));
t_buf[i] = (isOne ? '1' : '0');
@ -2474,7 +2446,6 @@ void VerilatedContext::threads(unsigned n) {
"%Error: Cannot set simulation threads after the thread pool has been created.");
}
#if VL_THREADED
if (m_threads == n) return; // To avoid unnecessary warnings
m_threads = n;
const unsigned hardwareThreadsAvailable = std::thread::hardware_concurrency();
@ -2483,13 +2454,6 @@ void VerilatedContext::threads(unsigned n) {
"to %u. This will likely cause significant slowdown.\n",
hardwareThreadsAvailable, m_threads);
}
#else
if (n > 1) {
VL_PRINTF_MT("%%Warning: Verilator run-time library built without VL_THREADS. Ignoring "
"call to 'VerilatedContext::threads' with argument %u.\n",
n);
}
#endif
}
void VerilatedContext::commandArgs(int argc, const char** argv) VL_MT_SAFE_EXCLUDES(m_argMutex) {
@ -2505,7 +2469,7 @@ void VerilatedContext::commandArgsAdd(int argc, const char** argv)
const char* VerilatedContext::commandArgsPlusMatch(const char* prefixp)
VL_MT_SAFE_EXCLUDES(m_argMutex) {
const std::string& match = impp()->argPlusMatch(prefixp);
static VL_THREAD_LOCAL char t_outstr[VL_VALUE_STRING_MAX_WIDTH];
static thread_local char t_outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match.empty()) return "";
char* dp = t_outstr;
for (const char* sp = match.c_str(); *sp && (dp - t_outstr) < (VL_VALUE_STRING_MAX_WIDTH - 2);)
@ -2537,9 +2501,7 @@ void VerilatedContext::addModel(VerilatedModel* modelp) {
VerilatedVirtualBase* VerilatedContext::threadPoolp() {
if (m_threads == 1) return nullptr;
#if VL_THREADED
if (!m_threadPool) m_threadPool.reset(new VlThreadPool{this, m_threads - 1});
#endif
return m_threadPool.get();
}
@ -2701,9 +2663,7 @@ void VerilatedContext::randSeed(int val) VL_MT_SAFE {
m_s.m_randSeed = val;
const uint64_t newEpoch = VerilatedContextImp::s().s_randSeedEpoch + 1;
// Obververs must see new epoch AFTER seed updated
#ifdef VL_THREADED
std::atomic_signal_fence(std::memory_order_release);
#endif
VerilatedContextImp::s().s_randSeedEpoch = newEpoch;
}
uint64_t VerilatedContextImp::randSeedDefault64() const VL_MT_SAFE {
@ -2760,16 +2720,12 @@ VerilatedSyms::VerilatedSyms(VerilatedContext* contextp)
: _vm_contextp__(contextp ? contextp : Verilated::threadContextp()) {
VerilatedContext::checkMagic(_vm_contextp__);
Verilated::threadContextp(_vm_contextp__);
#ifdef VL_THREADED
__Vm_evalMsgQp = new VerilatedEvalMsgQueue;
#endif
}
VerilatedSyms::~VerilatedSyms() {
VerilatedContext::checkMagic(_vm_contextp__);
#ifdef VL_THREADED
delete __Vm_evalMsgQp;
#endif
}
//===========================================================================
@ -2791,8 +2747,8 @@ void Verilated::debug(int level) VL_MT_SAFE {
const char* Verilated::catName(const char* n1, const char* n2, const char* delimiter) VL_MT_SAFE {
// Used by symbol table creation to make module names
static VL_THREAD_LOCAL char* t_strp = nullptr;
static VL_THREAD_LOCAL size_t t_len = 0;
static thread_local char* t_strp = nullptr;
static thread_local size_t t_len = 0;
const size_t newlen = std::strlen(n1) + std::strlen(n2) + std::strlen(delimiter) + 1;
if (VL_UNLIKELY(!t_strp || newlen > t_len)) {
if (t_strp) delete[] t_strp;
@ -2843,11 +2799,7 @@ void Verilated::removeFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE {
}
void Verilated::runFlushCallbacks() VL_MT_SAFE {
// Flush routines may call flush, so avoid mutex deadlock
#ifdef VL_THREADED
static std::atomic<int> s_recursing;
#else
static int s_recursing = 0;
#endif
if (!s_recursing++) {
const VerilatedLockGuard lock{VlCbStatic.s_flushMutex};
runCallbacks(VlCbStatic.s_flushCbs);
@ -2870,11 +2822,7 @@ void Verilated::removeExitCb(VoidPCb cb, void* datap) VL_MT_SAFE {
removeCb(cb, datap, VlCbStatic.s_exitCbs);
}
void Verilated::runExitCallbacks() VL_MT_SAFE {
#ifdef VL_THREADED
static std::atomic<int> s_recursing;
#else
static int s_recursing = 0;
#endif
if (!s_recursing++) {
const VerilatedLockGuard lock{VlCbStatic.s_exitMutex};
runCallbacks(VlCbStatic.s_exitCbs);
@ -2908,17 +2856,14 @@ void Verilated::mkdir(const char* dirname) VL_MT_UNSAFE {
}
void Verilated::quiesce() VL_MT_SAFE {
#ifdef VL_THREADED
// Wait until all threads under this evaluation are quiet
// THREADED-TODO
#endif
}
int Verilated::exportFuncNum(const char* namep) VL_MT_SAFE {
return VerilatedImp::exportFind(namep);
}
#ifdef VL_THREADED
void Verilated::endOfThreadMTaskGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
VL_DEBUG_IF(VL_DBG_MSGF("End of thread mtask\n"););
VerilatedThreadMsgQueue::flush(evalMsgQp);
@ -2932,7 +2877,6 @@ void Verilated::endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
VL_DEBUG_IF(VL_DBG_MSGF("End-of-eval cleanup\n"););
evalMsgQp->process();
}
#endif
//===========================================================================
// VerilatedImp:: Methods
@ -3138,7 +3082,7 @@ void VerilatedHierarchy::remove(VerilatedScope* fromp, VerilatedScope* top) {
//===========================================================================
// VerilatedOneThreaded:: Methods
#if defined(VL_THREADED) && defined(VL_DEBUG)
#ifdef VL_DEBUG
void VerilatedAssertOneThread::fatal_different() VL_MT_SAFE {
VL_FATAL_MT(__FILE__, __LINE__, "",
"Routine called that is single threaded, but called from"

View File

@ -54,11 +54,9 @@
#include <unordered_set>
#include <vector>
// <iostream> avoided to reduce compile time
#ifdef VL_THREADED
# include <atomic>
# include <mutex>
# include <thread>
#endif
#include <atomic>
#include <mutex>
#include <thread>
// Allow user to specify their own include file
#ifdef VL_VERILATED_INCLUDE
@ -149,8 +147,6 @@ enum VerilatedVarFlags {
// Return current thread ID (or 0), not super fast, cache if needed
extern uint32_t VL_THREAD_ID() VL_MT_SAFE;
#if VL_THREADED
#define VL_LOCK_SPINS 50000 /// Number of times to spin for a mutex before yielding
/// Mutex, wrapped to allow -fthread_safety checks
@ -202,34 +198,12 @@ public:
void unlock() VL_RELEASE() VL_MT_SAFE { m_mutexr.unlock(); }
};
#else // !VL_THREADED
// Empty non-threaded mutex to avoid #ifdefs in consuming code
class VerilatedMutex final {
public:
void lock() {} // LCOV_EXCL_LINE
void unlock() {} // LCOV_EXCL_LINE
};
// Empty non-threaded lock guard to avoid #ifdefs in consuming code
class VerilatedLockGuard final {
VL_UNCOPYABLE(VerilatedLockGuard);
public:
explicit VerilatedLockGuard(VerilatedMutex&) {}
~VerilatedLockGuard() = default;
void lock() {} // LCOV_EXCL_LINE
void unlock() {} // LCOV_EXCL_LINE
};
#endif // VL_THREADED
// Internals: Remember the calling thread at construction time, and make
// sure later calls use same thread
class VerilatedAssertOneThread final {
// MEMBERS
#if defined(VL_THREADED) && defined(VL_DEBUG)
#ifdef VL_DEBUG
uint32_t m_threadid; // Thread that is legal
public:
// CONSTRUCTORS
@ -250,7 +224,7 @@ public:
}
}
static void fatal_different() VL_MT_SAFE;
#else // !VL_THREADED || !VL_DEBUG
#else // !VL_DEBUG
public:
void check() {}
#endif
@ -343,7 +317,7 @@ class VerilatedContext VL_NOT_FINAL {
protected:
// MEMBERS
// Slow path variables
mutable VerilatedMutex m_mutex; // Mutex for most s_s/s_ns members, when VL_THREADED
mutable VerilatedMutex m_mutex; // Mutex for most s_s/s_ns members
struct Serialized { // All these members serialized/deserialized
// No std::strings or pointers or will serialize badly!
@ -397,11 +371,7 @@ protected:
// Implementation details
const std::unique_ptr<VerilatedContextImpData> m_impdatap;
// Number of threads to use for simulation (size of m_threadPool + 1 for main thread)
#ifdef VL_THREADED
unsigned m_threads = std::thread::hardware_concurrency();
#else
const unsigned m_threads = 1;
#endif
// The thread pool shared by all models added to this context
std::unique_ptr<VerilatedVirtualBase> m_threadPool;
// The execution profiler shared by all models added to this context
@ -611,9 +581,7 @@ public: // But for internal use only
// MEMBERS
// Keep first so is at zero offset for fastest code
VerilatedContext* const _vm_contextp__; // Context for current model
#ifdef VL_THREADED
VerilatedEvalMsgQueue* __Vm_evalMsgQp;
#endif
explicit VerilatedSyms(VerilatedContext* contextp); // Pass null for default context
~VerilatedSyms();
};
@ -694,17 +662,15 @@ class Verilated final {
static VerilatedContext* s_lastContextp; // Last context constructed/attached
// Not covered by mutex, as per-thread
static VL_THREAD_LOCAL struct ThreadLocal {
static thread_local struct ThreadLocal {
// No non-POD objects here due to this:
// Internal note: Globals may multi-construct, see verilated.cpp top.
// Fast path
VerilatedContext* t_contextp = nullptr; // Thread's context
#ifdef VL_THREADED
uint32_t t_mtaskId = 0; // mtask# executing on this thread
// Messages maybe pending on thread, needs end-of-eval calls
uint32_t t_endOfEvalReqd = 0;
#endif
const VerilatedScope* t_dpiScopep = nullptr; // DPI context scope
const char* t_dpiFilename = nullptr; // DPI context filename
int t_dpiLineno = 0; // DPI context line number
@ -911,7 +877,6 @@ public:
static int dpiLineno() VL_MT_SAFE { return t_s.t_dpiLineno; }
static int exportFuncNum(const char* namep) VL_MT_SAFE;
#ifdef VL_THREADED
// Internal: Set the mtaskId, called when an mtask starts
// Per thread, so no need to be in VerilatedContext
static void mtaskId(uint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
@ -925,12 +890,9 @@ public:
}
// Internal: Called at end of eval loop
static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
#endif
private:
#ifdef VL_THREADED
static void endOfThreadMTaskGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
#endif
};
void VerilatedContext::debug(int val) VL_MT_SAFE { Verilated::debug(val); }

View File

@ -130,19 +130,8 @@ endif
#######################################################################
##### Threaded builds
ifneq ($(VM_C11),0)
ifneq ($(VM_C11),)
VK_C11=1
endif
endif
ifneq ($(VM_THREADS),0)
ifneq ($(VM_THREADS),)
CPPFLAGS += -DVL_THREADED
VK_C11=1
VK_LIBS_THREADED=1
endif
endif
CPPFLAGS += $(CFG_CXXFLAGS_STD_NEWEST)
LDLIBS += $(CFG_LDLIBS_THREADS)
ifneq ($(VM_TIMING),0)
ifneq ($(VM_TIMING),)
@ -150,18 +139,6 @@ ifneq ($(VM_TIMING),0)
endif
endif
ifneq ($(VK_C11),0)
ifneq ($(VK_C11),)
# Need C++11 at least, so always default to newest
CPPFLAGS += $(CFG_CXXFLAGS_STD_NEWEST)
endif
endif
ifneq ($(VK_LIBS_THREADED),0)
ifneq ($(VK_LIBS_THREADED),)
LDLIBS += $(CFG_LDLIBS_THREADS)
endif
endif
#######################################################################
### Aggregates

View File

@ -28,10 +28,8 @@
#include "verilated_fst_c.h"
// GTKWave configuration
#ifdef VL_THREADED
# define HAVE_LIBPTHREAD
# define FST_WRITER_PARALLEL
#endif
#define HAVE_LIBPTHREAD
#define FST_WRITER_PARALLEL
// Include the GTKWave implementation directly
#define FST_CONFIG_INCLUDE "fst_config.h"
@ -248,14 +246,11 @@ void VerilatedFst::declDouble(uint32_t code, const char* name, int dtypenum, fst
// Get/commit trace buffer
VerilatedFst::Buffer* VerilatedFst::getTraceBuffer() {
#ifdef VL_THREADED
if (offload()) return new OffloadBuffer{*this};
#endif
return new Buffer{*this};
}
void VerilatedFst::commitTraceBuffer(VerilatedFst::Buffer* bufp) {
#ifdef VL_THREADED
if (offload()) {
OffloadBuffer* const offloadBufferp = static_cast<OffloadBuffer*>(bufp);
if (offloadBufferp->m_offloadBufferWritep) {
@ -263,7 +258,6 @@ void VerilatedFst::commitTraceBuffer(VerilatedFst::Buffer* bufp) {
return; // Buffer will be deleted by the offload thread
}
}
#endif
delete bufp;
}

View File

@ -73,11 +73,7 @@ extern void VL_WARN_MT(const char* filename, int linenum, const char* hier,
// clang-format off
/// Print a string, multithread safe. Eventually VL_PRINTF will get called.
#ifdef VL_THREADED
extern void VL_PRINTF_MT(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
#else
# define VL_PRINTF_MT VL_PRINTF // The following parens will take care of themselves
#endif
// clang-format on
/// Print a debug message from internals with standard prefix, with printf style format

View File

@ -41,10 +41,8 @@
#include <string>
#include <utility>
#include <vector>
#ifdef VL_THREADED
# include <functional>
# include <queue>
#endif
#include <functional>
#include <queue>
// clang-format on
class VerilatedScope;
@ -52,7 +50,6 @@ class VerilatedScope;
//======================================================================
// Threaded message passing
#ifdef VL_THREADED
// Message, enqueued on an mtask, and consumed on the main eval thread
class VerilatedMsg final {
public:
@ -152,7 +149,7 @@ private:
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
// METHODS
static VerilatedThreadMsgQueue& threadton() {
static VL_THREAD_LOCAL VerilatedThreadMsgQueue t_s;
static thread_local VerilatedThreadMsgQueue t_s;
return t_s;
}
@ -178,7 +175,6 @@ public:
}
}
};
#endif // VL_THREADED
// FILE* list constructed from a file-descriptor
class VerilatedFpList final {

View File

@ -20,9 +20,7 @@
#include "verilated_profiler.h"
#if VL_THREADED
#include "verilated_threads.h"
#endif
#include <fstream>
#include <string>
@ -32,7 +30,7 @@
// Internal note: Globals may multi-construct, see verilated.cpp top.
VL_THREAD_LOCAL VlExecutionProfiler::ExecutionTrace VlExecutionProfiler::t_trace;
thread_local VlExecutionProfiler::ExecutionTrace VlExecutionProfiler::t_trace;
constexpr const char* const VlExecutionRecord::s_ascii[];
@ -105,7 +103,6 @@ void VlExecutionProfiler::configure() {
VerilatedVirtualBase* VlExecutionProfiler::construct(VerilatedContext& context) {
VlExecutionProfiler* const selfp = new VlExecutionProfiler{context};
#if VL_THREADED
if (VlThreadPool* const threadPoolp = static_cast<VlThreadPool*>(context.threadPoolp())) {
for (int i = 0; i < threadPoolp->numThreads(); ++i) {
// Data to pass to worker thread initialization
@ -126,7 +123,6 @@ VerilatedVirtualBase* VlExecutionProfiler::construct(VerilatedContext& context)
threadPoolp->workerp(i)->wait();
}
}
#endif
return selfp;
}
@ -172,9 +168,7 @@ void VlExecutionProfiler::dump(const char* filenamep, uint64_t tickEnd)
Verilated::threadContextp()->profExecWindow());
const unsigned threads = static_cast<unsigned>(m_traceps.size());
fprintf(fp, "VLPROF stat threads %u\n", threads);
#ifdef VL_THREADED
fprintf(fp, "VLPROF stat yields %" PRIu64 "\n", VlMTaskVertex::yields());
#endif
// Copy /proc/cpuinfo into this output so verilator_gantt can be run on
// a different machine

View File

@ -151,7 +151,7 @@ class VlExecutionProfiler final : public VerilatedVirtualBase {
// STATE
VerilatedContext& m_context; // The context this profiler is under
static VL_THREAD_LOCAL ExecutionTrace t_trace; // thread-local trace buffers
static thread_local ExecutionTrace t_trace; // thread-local trace buffers
mutable VerilatedMutex m_mutex;
// Map from thread id to &t_trace of given thread
std::map<uint32_t, ExecutionTrace*> m_traceps VL_GUARDED_BY(m_mutex);

View File

@ -27,15 +27,6 @@
#include "verilated.h" // for VerilatedMutex and clang annotations
#ifndef VL_THREADED
// Hitting this likely means verilated_threads.cpp is being compiled when
// 'verilator --threads' was not used. 'verilator --threads' sets
// VL_THREADED.
// Alternatively it is always safe but may harm performance to always
// define VL_THREADED for all compiles.
#error "verilated_threads.h/cpp expected VL_THREADED (from verilator --threads)"
#endif
#include <atomic>
#include <condition_variable>
#include <set>

View File

@ -35,10 +35,8 @@
#include <unordered_set>
#include <vector>
#ifdef VL_THREADED
# include <deque>
# include <thread>
#endif
#include <deque>
#include <thread>
// clang-format on
@ -48,7 +46,6 @@ class VerilatedTraceBuffer;
template <class T_Buffer>
class VerilatedTraceOffloadBuffer;
#ifdef VL_THREADED
//=============================================================================
// Offloaded tracing
@ -117,7 +114,6 @@ public:
SHUTDOWN = 0xf // Shutdown worker thread, also marks end of buffer
};
};
#endif
//=============================================================================
// VerilatedTraceConfig
@ -186,10 +182,9 @@ private:
, m_userp{userp} {}
};
bool m_offload = false; // Use the offload thread (ignored if !VL_THREADED)
bool m_parallel = false; // Use parallel tracing (ignored if !VL_THREADED)
bool m_offload = false; // Use the offload thread
bool m_parallel = false; // Use parallel tracing
#ifdef VL_THREADED
struct ParallelWorkerData {
const dumpCb_t m_cb; // The callback
void* const m_userp; // The use pointer to pass to the callback
@ -209,7 +204,6 @@ private:
// Passed a ParallelWorkerData*, second argument is ignored
static void parallelWorkerTask(void*, bool);
#endif
protected:
uint32_t* m_sigs_oldvalp = nullptr; // Previous value store
@ -251,7 +245,6 @@ private:
// Close the file on termination
static void onExit(void* selfp) VL_MT_UNSAFE_ONE;
#ifdef VL_THREADED
// Number of total offload buffers that have been allocated
uint32_t m_numOffloadBuffers = 0;
// Size of offload buffers
@ -282,7 +275,6 @@ private:
// Shut down and join worker, if it's running, otherwise do nothing
void shutdownOffloadWorker();
#endif
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedTrace);
@ -317,13 +309,8 @@ protected:
void closeBase();
void flushBase();
#ifdef VL_THREADED
bool offload() const { return m_offload; }
bool parallel() const { return m_parallel; }
#else
static constexpr bool offload() { return false; }
static constexpr bool parallel() { return false; }
#endif
//=========================================================================
// Virtual functions to be provided by the format specific implementation
@ -475,7 +462,6 @@ public:
}
};
#ifdef VL_THREADED
//=============================================================================
// VerilatedTraceOffloadBuffer
@ -548,6 +534,5 @@ public:
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
}
};
#endif
#endif // guard

View File

@ -26,10 +26,8 @@
#include "verilated_intrinsics.h"
#include "verilated_trace.h"
#ifdef VL_THREADED
# include "verilated_threads.h"
# include <list>
#endif
#include "verilated_threads.h"
#include <list>
#if 0
# include <iostream>
@ -78,7 +76,6 @@ static std::string doubleToTimescale(double value) {
return valuestr; // Gets converted to string, so no ref to stack
}
#ifdef VL_THREADED
//=========================================================================
// Buffer management
@ -250,14 +247,11 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::shutdownOffloadWorker() {
m_workerThread.reset(nullptr);
}
#endif
//=============================================================================
// Life cycle
template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::closeBase() {
#ifdef VL_THREADED
if (offload()) {
shutdownOffloadWorker();
while (m_numOffloadBuffers) {
@ -265,12 +259,10 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::closeBase() {
--m_numOffloadBuffers;
}
}
#endif
}
template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::flushBase() {
#ifdef VL_THREADED
if (offload()) {
// Hand an empty buffer to the worker thread
uint32_t* const bufferp = getOffloadBuffer();
@ -280,7 +272,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::flushBase() {
// this ensures all previous buffers have been processed.
waitForOffloadBuffer(bufferp);
}
#endif
}
//=============================================================================
@ -368,7 +359,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::traceInit() VL_MT_UNSAFE {
Verilated::addFlushCb(VerilatedTrace<VL_SUB_T, VL_BUF_T>::onFlush, this);
Verilated::addExitCb(VerilatedTrace<VL_SUB_T, VL_BUF_T>::onExit, this);
#ifdef VL_THREADED
if (offload()) {
// Compute offload buffer size. we need to be able to store a new value for
// each signal, which is 'nextCode()' entries after the init callbacks
@ -381,7 +371,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::traceInit() VL_MT_UNSAFE {
m_workerThread.reset(
new std::thread{&VerilatedTrace<VL_SUB_T, VL_BUF_T>::offloadWorkerThreadMain, this});
}
#endif
}
template <>
@ -468,7 +457,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dumpvars(int level, const std::string&
}
}
#ifdef VL_THREADED
template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::parallelWorkerTask(void* datap, bool) {
ParallelWorkerData* const wdp = reinterpret_cast<ParallelWorkerData*>(datap);
@ -493,11 +481,9 @@ VL_ATTR_NOINLINE void VerilatedTrace<VL_SUB_T, VL_BUF_T>::ParallelWorkerData::wa
m_cv.wait(lock, [this] { return m_ready.load(std::memory_order_relaxed); });
m_waiting = false;
}
#endif
template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runCallbacks(const std::vector<CallbackRecord>& cbVec) {
#ifdef VL_THREADED
if (parallel()) {
// If tracing in parallel, dispatch to the thread pool
VlThreadPool* threadPoolp = static_cast<VlThreadPool*>(m_contextp->threadPoolp());
@ -538,7 +524,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runCallbacks(const std::vector<Callback
// Done
return;
}
#endif
// Fall back on sequential execution
for (const CallbackRecord& cbr : cbVec) {
Buffer* const traceBufferp = getTraceBuffer();
@ -551,15 +536,11 @@ template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runOffloadedCallbacks(
const std::vector<CallbackRecord>& cbVec) {
// Fall back on sequential execution
#ifdef VL_THREADED
for (const CallbackRecord& cbr : cbVec) {
Buffer* traceBufferp = getTraceBuffer();
cbr.m_dumpOffloadCb(cbr.m_userp, static_cast<OffloadBuffer*>(traceBufferp));
commitTraceBuffer(traceBufferp);
}
#else
if (!cbVec.empty()) VL_FATAL_MT(__FILE__, __LINE__, "", "Unreachable");
#endif
}
template <>
@ -586,11 +567,8 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
if (!preChangeDump()) return;
}
#ifdef VL_THREADED
uint32_t* bufferp = nullptr;
#endif
if (offload()) {
#ifdef VL_THREADED
// Currently only incremental dumps run on the worker thread
if (VL_LIKELY(!m_fullDump)) {
// Get the offload buffer we are about to fill
@ -607,9 +585,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
flushBase();
emitTimeChange(timeui);
}
#else
VL_FATAL_MT(__FILE__, __LINE__, "", "Unreachable");
#endif
} else {
// Update time point
emitTimeChange(timeui);
@ -636,7 +611,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
cbr.m_cleanupCb(cbr.m_userp, self());
}
#ifdef VL_THREADED
if (offload() && VL_LIKELY(bufferp)) {
// Mark end of the offload buffer we just filled
*m_offloadBufferWritep++ = VerilatedTraceOffloadCommand::END;
@ -651,7 +625,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
// Pass it to the worker thread
m_offloadBuffersToWorker.put(bufferp);
}
#endif
}
//=============================================================================
@ -685,11 +658,6 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addModel(VerilatedModel* modelp)
// Get the desired trace config from the model
const std::unique_ptr<VerilatedTraceConfig> configp = modelp->traceConfig();
#ifndef VL_THREADED
if (configp->m_useOffloading) {
VL_FATAL_MT(__FILE__, __LINE__, "", "Cannot use trace offloading without VL_THREADED");
}
#endif
// Configure trace base class
if (!firstModel) {
@ -915,7 +883,6 @@ void VerilatedTraceBuffer<VL_BUF_T>::fullDouble(uint32_t* oldp, double newval) {
emitDouble(code, newval);
}
#ifdef VL_THREADED
//=========================================================================
// VerilatedTraceOffloadBuffer
@ -934,6 +901,5 @@ VerilatedTraceOffloadBuffer<VL_BUF_T>::VerilatedTraceOffloadBuffer(VL_SUB_T& own
m_offloadBufferWritep += 2;
}
}
#endif
#endif // VL_CPPCHECK

View File

@ -367,7 +367,7 @@ public:
// Can't just overload operator[] or provide a "at" reference to set,
// because we need to be able to insert only when the value is set
T_Value& at(int32_t index) {
static VL_THREAD_LOCAL T_Value s_throwAway;
static thread_local T_Value s_throwAway;
// Needs to work for dynamic arrays, so does not use T_MaxSize
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) {
s_throwAway = atDefault();
@ -378,7 +378,7 @@ public:
}
// Accessing. Verilog: v = assoc[index]
const T_Value& at(int32_t index) const {
static VL_THREAD_LOCAL T_Value s_throwAway;
static thread_local T_Value s_throwAway;
// Needs to work for dynamic arrays, so does not use T_MaxSize
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) {
return atDefault();

View File

@ -230,12 +230,10 @@ VerilatedVcd::~VerilatedVcd() {
if (m_wrBufp) VL_DO_CLEAR(delete[] m_wrBufp, m_wrBufp = nullptr);
deleteNameMap();
if (m_filep && m_fileNewed) VL_DO_CLEAR(delete m_filep, m_filep = nullptr);
#ifdef VL_THREADED
if (parallel()) {
assert(m_numBuffers == m_freeBuffers.size());
for (auto& pair : m_freeBuffers) VL_DO_CLEAR(delete[] pair.first, pair.first = nullptr);
}
#endif
}
void VerilatedVcd::closePrev() {
@ -574,7 +572,6 @@ void VerilatedVcd::declDouble(uint32_t code, const char* name, bool array, int a
VerilatedVcd::Buffer* VerilatedVcd::getTraceBuffer() {
VerilatedVcd::Buffer* const bufp = new Buffer{*this};
#ifdef VL_THREADED
if (parallel()) {
// Note: This is called from VeriltedVcd::dump, which already holds the lock
// If no buffer available, allocate a new one
@ -593,14 +590,12 @@ VerilatedVcd::Buffer* VerilatedVcd::getTraceBuffer() {
bufp->m_size = pair.second;
bufp->adjustGrowp();
}
#endif
// Return the buffer
return bufp;
}
void VerilatedVcd::commitTraceBuffer(VerilatedVcd::Buffer* bufp) {
if (parallel()) {
#if VL_THREADED
// Note: This is called from VeriltedVcd::dump, which already holds the lock
// Resize output buffer. Note, we use the full size of the trace buffer, as
// this is a lot more stable than the actual occupancy of the trace buffer.
@ -616,9 +611,6 @@ void VerilatedVcd::commitTraceBuffer(VerilatedVcd::Buffer* bufp) {
bufferCheck();
// Put buffer back on free list
m_freeBuffers.emplace_back(bufp->m_bufp, bufp->m_size);
#else
VL_FATAL_MT(__FILE__, __LINE__, "", "Unreachable");
#endif
} else {
// Needs adjusting for emitTimeChange
m_writep = bufp->m_writep;
@ -665,7 +657,6 @@ void VerilatedVcdBuffer::finishLine(uint32_t code, char* writep) {
m_writep = writep + suffixp[VL_TRACE_SUFFIX_ENTRY_SIZE - 1];
if (m_owner.parallel()) {
#ifdef VL_THREADED
// Double the size of the buffer if necessary
if (VL_UNLIKELY(m_writep >= m_growp)) {
// Compute occupied size of current buffer
@ -685,9 +676,6 @@ void VerilatedVcdBuffer::finishLine(uint32_t code, char* writep) {
// Adjust resize limit
adjustGrowp();
}
#else
VL_FATAL_MT(__FILE__, __LINE__, "", "Unreachable");
#endif
} else {
// Flush the write buffer if there's not enough space left for new information
// We only call this once per vector, so we need enough slop for a very wide "b###" line

View File

@ -65,11 +65,9 @@ private:
using NameMap = std::map<const std::string, const std::string>;
NameMap* m_namemapp = nullptr; // List of names for the header
#ifdef VL_THREADED
// Vector of free trace buffers as (pointer, size) pairs.
std::vector<std::pair<char*, size_t>> m_freeBuffers;
size_t m_numBuffers = 0; // Number of trace buffers allocated
#endif
void bufferResize(size_t minsize);
void bufferFlush() VL_MT_UNSAFE_ONE;
@ -187,7 +185,6 @@ class VerilatedVcdBuffer VL_NOT_FINAL {
// The maximum number of bytes a single signal can emit
const size_t m_maxSignalBytes = m_owner.m_maxSignalBytes;
#ifdef VL_THREADED
// Additional data for parallel tracing only
char* m_bufp = nullptr; // The beginning of the trace buffer
size_t m_size = 0; // The size of the buffer at m_bufp
@ -197,7 +194,6 @@ class VerilatedVcdBuffer VL_NOT_FINAL {
m_growp = (m_bufp + m_size) - (2 * m_maxSignalBytes);
assert(m_growp >= m_bufp + m_maxSignalBytes);
}
#endif
void finishLine(uint32_t code, char* writep);

View File

@ -71,7 +71,7 @@ class VerilatedVpio VL_NOT_FINAL {
// MEM MANGLEMENT
// Internal note: Globals may multi-construct, see verilated.cpp top.
static VL_THREAD_LOCAL uint8_t* t_freeHead;
static thread_local uint8_t* t_freeHead;
public:
// CONSTRUCTORS
@ -205,7 +205,7 @@ public:
const VerilatedRange* rangep() const override { return &get_range(); }
const char* name() const override { return m_varp->name(); }
const char* fullname() const override {
static VL_THREAD_LOCAL std::string t_out;
static thread_local std::string t_out;
t_out = std::string{m_scopep->name()} + "." + name();
return t_out.c_str();
}
@ -348,7 +348,7 @@ public:
uint32_t size() const override { return varp()->packed().elements(); }
const VerilatedRange* rangep() const override { return &(varp()->packed()); }
const char* fullname() const override {
static VL_THREAD_LOCAL std::string t_out;
static thread_local std::string t_out;
constexpr size_t LEN_MAX_INDEX = 25;
char num[LEN_MAX_INDEX];
VL_SNPRINTF(num, LEN_MAX_INDEX, "%d", m_index);
@ -666,7 +666,7 @@ public:
// Statics
// Internal note: Globals may multi-construct, see verilated.cpp top.
VL_THREAD_LOCAL uint8_t* VerilatedVpio::t_freeHead = nullptr;
thread_local uint8_t* VerilatedVpio::t_freeHead = nullptr;
//======================================================================
// VerilatedVpiError
@ -708,7 +708,7 @@ public:
}
void setMessage(const 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 t_filehold;
static thread_local std::string t_filehold;
va_list args;
va_start(args, message);
VL_VSNPRINTF(m_buff, sizeof(m_buff), message, args);
@ -1701,15 +1701,15 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep,
const char* fullname) {
if (!vl_check_format(varp, valuep, fullname, true)) return;
// Maximum required size is for binary string, one byte per bit plus null termination
static VL_THREAD_LOCAL char t_outStr[VL_VALUE_STRING_MAX_WORDS * VL_EDATASIZE + 1];
static thread_local char t_outStr[VL_VALUE_STRING_MAX_WORDS * VL_EDATASIZE + 1];
// cppcheck-suppress variableScope
static const VL_THREAD_LOCAL int t_outStrSz = sizeof(t_outStr) - 1;
static const thread_local int t_outStrSz = sizeof(t_outStr) - 1;
// We used to presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal
// This may cause backward compatibility issues with older code.
if (valuep->format == vpiVectorVal) {
// Vector pointer must come from our memory pool
// It only needs to persist until the next vpi_get_value
static VL_THREAD_LOCAL t_vpi_vecval t_out[VL_VALUE_STRING_MAX_WORDS * 2];
static thread_local t_vpi_vecval t_out[VL_VALUE_STRING_MAX_WORDS * 2];
valuep->value.vector = t_out;
if (varp->vltype() == VLVT_UINT8) {
t_out[0].aval = *(reinterpret_cast<CData*>(varDatap));

View File

@ -56,7 +56,7 @@
# if !defined(_WIN32) && !defined(__MINGW32__)
# define VL_ATTR_WEAK __attribute__((weak))
# endif
# if defined(__clang__) && defined(VL_THREADED)
# if defined(__clang__)
# define VL_ACQUIRE(...) __attribute__((acquire_capability(__VA_ARGS__)))
# define VL_ACQUIRE_SHARED(...) __attribute__((acquire_shared_capability(__VA_ARGS__)))
# define VL_RELEASE(...) __attribute__((release_capability(__VA_ARGS__)))
@ -139,47 +139,34 @@
# define VL_PREFETCH_RW(p) ///< Prefetch pointer argument with read/write intent
#endif
#if defined(VL_THREADED) && !defined(VL_CPPCHECK)
# if defined(_MSC_VER) && _MSC_VER >= 1900
# define VL_THREAD_LOCAL thread_local
# elif defined(__GNUC__)
# if (__cplusplus < 201103L)
# error "VL_THREADED/--threads support requires C++-11 or newer only; use newer compiler"
# endif
# else
# error "Unsupported compiler for VL_THREADED: No thread-local declarator"
# endif
# define VL_THREAD_LOCAL thread_local // "thread_local" when supported
#else
# define VL_THREAD_LOCAL // "thread_local" when supported
#endif
#ifndef VL_NO_LEGACY
# define VL_FUNC __func__ // Deprecated
# define VL_THREAD // Deprecated
# define VL_THREAD_LOCAL thread_local // Deprecated
# define VL_STATIC_OR_THREAD static // Deprecated
#endif
// Comment tag that Function is pure (and thus also VL_MT_SAFE)
#define VL_PURE
// Comment tag that function is threadsafe when VL_THREADED
// Comment tag that function is threadsafe
#if defined(__clang__)
# define VL_MT_SAFE __attribute__((annotate("MT_SAFE")))
#else
# define VL_MT_SAFE
#endif
// Comment tag that function is threadsafe when VL_THREADED, only
// Comment tag that function is threadsafe, only
// during normal operation (post-init)
#define VL_MT_SAFE_POSTINIT
// Attribute that function is clang threadsafe and uses given mutex
#define VL_MT_SAFE_EXCLUDES(mutex) VL_EXCLUDES(mutex)
// Comment tag that function is not threadsafe when VL_THREADED
// Comment tag that function is not threadsafe
#if defined(__clang__)
# define VL_MT_UNSAFE __attribute__((annotate("MT_UNSAFE")))
#else
# define VL_MT_UNSAFE
#endif
// Comment tag that function is not threadsafe when VL_THREADED,
// Comment tag that function is not threadsafe
// protected to make sure single-caller
#define VL_MT_UNSAFE_ONE
@ -482,28 +469,26 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read()
//=========================================================================
// Threading related OS-specific functions
#if VL_THREADED
# ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include "Windows.h"
# define VL_CPU_RELAX() YieldProcessor()
# elif defined(__i386__) || defined(__x86_64__) || defined(VL_CPPCHECK)
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include "Windows.h"
# define VL_CPU_RELAX() YieldProcessor()
#elif defined(__i386__) || defined(__x86_64__) || defined(VL_CPPCHECK)
// 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")
# elif defined(__loongarch__)
// LoongArch does not currently have a yield/pause instruction
# define VL_CPU_RELAX() asm volatile("nop" ::: "memory")
# else
# error "Missing VL_CPU_RELAX() definition. Or, don't use VL_THREADED"
# endif
# 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")
#elif defined(__loongarch__)
/ LoongArch does not currently have a yield/pause instruction
# define VL_CPU_RELAX() asm volatile("nop" ::: "memory")
#else
# error "Missing VL_CPU_RELAX() definition."
#endif
//=========================================================================

View File

@ -210,7 +210,7 @@ void EmitCBaseVisitor::emitVarDecl(const AstVar* nodep, bool asRef) {
// Issue 2622.
const bool beStatic = name.size() >= suffix.size()
&& name.substr(name.size() - suffix.size()) == suffix;
if (beStatic) puts("static VL_THREAD_LOCAL ");
if (beStatic) puts("static thread_local ");
}
puts(nodep->vlArgType(true, false, false, "", asRef));
puts(";\n");

View File

@ -116,7 +116,7 @@ class CMakeEmitter final {
cmake_set_raw(*of, name + "_COVERAGE", v3Global.opt.coverage() ? "1" : "0");
*of << "# Timing mode? 0/1\n";
cmake_set_raw(*of, name + "_TIMING", v3Global.usesTiming() ? "1" : "0");
*of << "# Threaded output mode? 0/1/N threads (from --threads)\n";
*of << "# Threaded output mode? 1/N threads (from --threads)\n";
cmake_set_raw(*of, name + "_THREADS", cvtToStr(v3Global.opt.threads()));
*of << "# VCD Tracing output mode? 0/1 (from --trace)\n";
cmake_set_raw(*of, name + "_TRACE_VCD",

View File

@ -63,10 +63,6 @@ public:
of.puts("VM_PARALLEL_BUILDS = ");
of.puts(v3Global.useParallelBuild() ? "1" : "0");
of.puts("\n");
of.puts("# Threaded output mode? 0/1/N threads (from --threads)\n");
of.puts("VM_THREADS = ");
of.puts(cvtToStr(v3Global.opt.threads()));
of.puts("\n");
of.puts("# Tracing output mode? 0/1 (from --trace/--trace-fst)\n");
of.puts("VM_TRACE = ");
of.puts(v3Global.opt.trace() ? "1" : "0");

View File

@ -1388,10 +1388,17 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
DECL_OPTION("-sv", CbCall, [this]() { m_defaultLanguage = V3LangCode::L1800_2017; });
DECL_OPTION("-threads-coarsen", OnOff, &m_threadsCoarsen).undocumented(); // Debug
DECL_OPTION("-no-threads", CbCall, [this]() { m_threads = 0; });
DECL_OPTION("-no-threads", CbCall, [this, fl]() {
fl->v3warn(DEPRECATED, "Option --no-threads is deprecated, use '--threads 1' instead");
m_threads = 1;
});
DECL_OPTION("-threads", CbVal, [this, fl](const char* valp) {
m_threads = std::atoi(valp);
if (m_threads < 0) fl->v3fatal("--threads must be >= 0: " << valp);
if (m_threads == 0) {
fl->v3warn(DEPRECATED, "Option --threads 0 is deprecated, use '--threads 1' instead");
m_threads = 1;
}
});
DECL_OPTION("-threads-dpi", CbVal, [this, fl](const char* valp) {
if (!std::strcmp(valp, "all")) {

View File

@ -304,7 +304,7 @@ private:
int m_pinsBv = 65; // main switch: --pins-bv
int m_reloopLimit = 40; // main switch: --reloop-limit
VOptionBool m_skipIdentical; // main switch: --skip-identical
int m_threads = 0; // main switch: --threads (0 == --no-threads)
int m_threads = 1; // main switch: --threads
int m_threadsMaxMTasks = 0; // main switch: --threads-max-mtasks
VTimescale m_timeDefaultPrec; // main switch: --timescale
VTimescale m_timeDefaultUnit; // main switch: --timescale

View File

@ -904,7 +904,7 @@ sub compile_vlt_flags {
@{$param{verilator_flags}},
@{$param{verilator_flags2}},
@{$param{verilator_flags3}});
die "%Error: specify threads via 'threads =>' argument, not as a command line option" unless ($checkflags !~ /(^|\s)-?-threads\s/ && $checkflags !~ /(^|\s)-?-no-threads($|\s)/);
die "%Error: specify threads via 'threads =>' argument, not as a command line option" unless ($checkflags !~ /(^|\s)-?-threads\s/);
$self->{sc} = 1 if ($checkflags =~ /-sc\b/);
$self->{trace} = ($opt_trace || $checkflags =~ /-trace\b/
|| $checkflags =~ /-trace-fst\b/);

View File

@ -23,7 +23,7 @@ mkdir $child_dir;
top_filename => "$Self->{name}_child.v",
verilator_flags => ["-cc", "-Mdir", "${child_dir}", "--debug-check"],
# Can't use multi threading (like hier blocks), but needs to be thread safe
threads => $Self->{vltmt} ? 1 : 0,
threads => 1,
);
run(logfile => "${child_dir}/vlt_compile.log",

View File

@ -0,0 +1,5 @@
%Warning-DEPRECATED: Option --threads 0 is deprecated, use '--threads 1' instead
... For warning description see https://verilator.org/warn/DEPRECATED?v=latest
... Use "/* verilator lint_off DEPRECATED */" and lint_on around source to disable this message.
%Error-DEPRECATED: Option --no-threads is deprecated, use '--threads 1' instead
%Error: Exiting due to

View File

@ -0,0 +1,21 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2022 by Antmicro. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(vlt => 1);
lint(
verilator_flags2 => ["-Werror-DEPRECATED", "--no-threads"],
fails => 1,
threads => 0,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -20,7 +20,7 @@ top_filename("t/t_gen_alw.v");
compile(
v_flags2 => ["--prof-exec"],
# Checks below care about thread count, so use 2 (minimum reasonable)
threads => $Self->{vltmt} ? 2 : 0
threads => $Self->{vltmt} ? 2 : 1
);
execute(

View File

@ -16,9 +16,8 @@ int main(int argc, char** argv, char** env) {
srand48(5);
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
#ifdef VL_THREADED
contextp->threads(2);
#endif
// VL_USE_THREADS define is set in t_gantt_two.pl
contextp->threads(TEST_USE_THREADS);
contextp->commandArgs(argc, argv);
contextp->debug(0);

View File

@ -17,13 +17,15 @@ scenarios(vlt_all => 1);
# enough for the profiling to happen:
top_filename("t/t_gen_alw.v");
my $threads_num = $Self->{vltmt} ? 2 : 1;
compile(
make_top_shell => 0,
make_main => 0,
v_flags2 => ["--prof-exec --exe $Self->{t_dir}/$Self->{name}.cpp"],
# Checks below care about thread count, so use 2 (minimum reasonable)
threads => $Self->{vltmt} ? 2 : 0,
make_flags => 'CPPFLAGS_ADD=-DVL_NO_LEGACY',
threads => $threads_num,
make_flags => "CPPFLAGS_ADD=\"-DVL_NO_LEGACY -DTEST_USE_THREADS=$threads_num\"",
);
execute(

View File

@ -23,7 +23,7 @@ compile(
'--Wno-TIMESCALEMOD',
'--CFLAGS', '"-pipe -DCPP_MACRO=cplusplus"'
],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -13,17 +13,19 @@ clean_objs();
scenarios(simulator => 1);
top_filename("t/t_hier_block.v");
my $threads = ($Self->{vltmt} ? '-DTEST_THREADS=6' : '-DTEST_THREADS=1');
if (!$Self->have_cmake) {
$Self->skip("Test requires CMake; ignore error since not available or version too old\n");
} else {
run(logfile => "$Self->{obj_dir}/cmake.log",
cmd => ['cd "' . $Self->{obj_dir} . '" && cmake ' . $Self->{t_dir} . '/t_hier_block_cmake',
"-DCMAKE_PREFIX_PATH=$ENV{VERILATOR_ROOT}",
($Self->{vltmt} ? '-DTEST_THREADS=6' : '')
$threads
]);
run(logfile => "$Self->{obj_dir}/build.log",
cmd => ['cd "' . $Self->{obj_dir} . '" && cmake --build', '.']
cmd => ['cd "' . $Self->{obj_dir} . '" && cmake --build', '.', '--', "CXX_FLAGS=$threads"]
);
run(logfile => "$Self->{obj_dir}/run.log",

View File

@ -14,9 +14,8 @@
int main(int argc, char *argv[]) {
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
#if VL_THREADED
contextp->threads(6);
#endif
// TEST_THREADS is set in t_hier_block_cmake.pl
contextp->threads(TEST_THREADS);
contextp->commandArgs(argc, argv);
std::unique_ptr<Vt_hier_block> top{new Vt_hier_block{contextp.get(), "top"}};
for (int i = 0; i < 100 && !contextp->gotFinish(); ++i) {

View File

@ -24,7 +24,7 @@ compile(
verilator_flags2 => ['--stats',
'+define+USE_VLT', 't/t_hier_block_vlt.vlt',
'--CFLAGS', '"-pipe -DCPP_MACRO=cplusplus"'],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -24,7 +24,7 @@ compile(
'--hierarchical',
'--CFLAGS', '"-pipe -DCPP_MACRO=cplusplus"'
],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -26,7 +26,7 @@ compile(
"--CFLAGS", '"-O0 -ggdb"',
"--trace-fst"
],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -26,7 +26,7 @@ compile(
"--CFLAGS", '"-O0 -ggdb"',
"--trace"
],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -22,7 +22,7 @@ compile(
'--trace-fst',
'--no-trace-underscore', # To avoid handle mismatches
],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -22,7 +22,7 @@ compile(
'--trace',
'--no-trace-underscore', # To avoid handle mismatches
],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -23,7 +23,7 @@ compile(
'+define+SHOW_TIMESCALE',
'+define+USE_VLT', 't/t_hier_block_vlt.vlt',
'--CFLAGS', '"-pipe -DCPP_MACRO=cplusplus"'],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -16,7 +16,7 @@ my $default_vltmt_threads = $Self->get_default_vltmt_threads();
compile(
verilator_flags2 => ['--stats', "$Self->{t_dir}/$Self->{name}.vlt"],
# Force 3 threads even if we have fewer cores
threads => $Self->{vltmt} ? $default_vltmt_threads : 0
threads => $Self->{vltmt} ? $default_vltmt_threads : 1
);
sub checkRelativeRefs {

View File

@ -61,7 +61,7 @@ while (1) {
"-LDFLAGS",
"'-Wl,-rpath,$abs_secret_dir -L$abs_secret_dir -l$secret_prefix'"],
xsim_flags2 => ["$secret_dir/secret.sv"],
threads => $Self->{vltmt} ? 1 : 0,
threads => 1,
context_threads => $Self->{vltmt} ? 6 : 1
);

View File

@ -15,7 +15,7 @@ scenarios(simulator => 1);
# So use 6 threads here though it's not optimal in performace wise, but ok.
compile(
verilator_flags2 => ['--stats', "$Self->{t_dir}/t_split_var_0.vlt"],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -16,7 +16,7 @@ top_filename("t/t_split_var_0.v");
# So use 6 threads here though it's not optimal in performace wise, but ok.
compile(
verilator_flags2 => ['--cc --trace --stats +define+TEST_ATTRIBUTES'],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -14,7 +14,7 @@ top_filename("t/t_threads_counter.v");
compile(
verilator_flags2 => ['--cc'],
threads => 0,
threads => 1,
);
execute(

View File

@ -18,7 +18,7 @@ top_filename("t/t_threads_crazy.v");
compile(
verilator_flags2 => ['--cc'],
threads => $Self->{vltmt} ? 2 : 0,
threads => $Self->{vltmt} ? 2 : 1,
context_threads => 1024
);
@ -28,8 +28,6 @@ execute(
if ($Self->{vltmt}) {
file_grep($Self->{run_log_filename}, qr/System has \d+ hardware threads but simulation thread count set to 1024\. This will likely cause significant slowdown\./);
} else {
file_grep($Self->{run_log_filename}, qr/Verilator run-time library built without VL_THREADS\. Ignoring call to 'VerilatedContext::threads' with argument 1024\./);
}
ok(1);

View File

@ -32,6 +32,7 @@
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__stl
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__stl
-V{t#,#} No triggers active
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -61,8 +62,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -119,8 +122,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -156,8 +161,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -188,8 +195,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -238,8 +247,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -301,8 +312,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -342,8 +355,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -373,8 +388,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -428,8 +445,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -464,8 +483,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -495,8 +516,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -544,8 +567,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -580,8 +605,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -616,8 +643,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -647,8 +676,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -696,8 +727,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -732,8 +765,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -763,8 +798,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -834,8 +871,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -866,8 +905,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -902,8 +943,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -933,8 +976,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -988,8 +1033,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1024,8 +1071,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1055,8 +1104,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1090,8 +1141,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1139,8 +1192,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1175,8 +1230,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1206,8 +1263,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1255,8 +1314,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1291,8 +1352,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1356,8 +1419,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1387,8 +1452,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1442,8 +1509,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1478,8 +1547,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1509,8 +1580,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1558,8 +1631,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1598,8 +1673,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1629,8 +1706,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1678,8 +1757,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1714,8 +1795,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1745,8 +1828,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1794,8 +1879,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1855,8 +1942,10 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug1::eval_step
-V{t#,#}+ Vt_timing_debug1___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug1___024root___eval
-V{t#,#}+ Vt_timing_debug1___024root___eval_triggers__act
@ -1898,4 +1987,5 @@
-V{t#,#}+ Vt_timing_debug1___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug1___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+ Vt_timing_debug1___024root___eval_final

View File

@ -60,6 +60,7 @@
-V{t#,#} Awaiting join of fork at: t/t_timing_class.v:209
-V{t#,#}+ Vt_timing_debug2_t___eval_initial__TOP__t__7
-V{t#,#}+ Vt_timing_debug2___024root___eval_settle
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -69,8 +70,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#} Committing processes waiting for @([event] t.ec.e):
-V{t#,#} - Process waiting at t/t_timing_class.v:80
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -107,8 +110,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -174,8 +179,10 @@
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:29
-V{t#,#} Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -230,8 +237,10 @@
-V{t#,#} Resuming: Process waiting at t/t_timing_class.v:29
-V{t#,#} Suspending process waiting for @([event] t::EventClass.e) at t/t_timing_class.v:29
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -305,8 +314,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -344,8 +355,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -401,8 +414,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -459,10 +474,12 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkDelayClass::~
-V{t#,#}+ Vt_timing_debug2_t__03a__03aForkClass::~
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -490,8 +507,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -521,8 +540,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -549,8 +570,10 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -577,9 +600,11 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_timing_debug2::eval_step
-V{t#,#}+ Vt_timing_debug2___024root___eval_debug_assertions
-V{t#,#}+ Vt_timing_debug2_t__03a__03aAssignDelayClass::~
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_timing_debug2___024root___eval
-V{t#,#}+ Vt_timing_debug2___024root___eval_triggers__act
@ -606,6 +631,7 @@
-V{t#,#}+ Vt_timing_debug2___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}+ Vt_timing_debug2___024root___timing_commit
-V{t#,#}End-of-eval cleanup
-V{t#,#}+ Vt_timing_debug2___024root___eval_final
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelay40::~
-V{t#,#}+ Vt_timing_debug2_t__03a__03aDelayClass::~

View File

@ -15,7 +15,7 @@ scenarios(simulator => 1);
# Strangely, asking for more threads makes it go away.
compile(
verilator_flags2 => ['--cc --trace --trace-params -Wno-LITENDIAN'],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -17,7 +17,7 @@ top_filename("t/t_trace_litendian.v");
# Strangely, asking for more threads makes it go away.
compile(
verilator_flags2 => ['--cc --trace-fst --trace-params -Wno-LITENDIAN'],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -21,7 +21,7 @@ else {
# Strangely, asking for more threads makes it go away.
compile(
verilator_flags2 => ['--sc --trace-fst --trace-params -Wno-LITENDIAN'],
threads => $Self->{vltmt} ? 6 : 0
threads => $Self->{vltmt} ? 6 : 1
);
execute(

View File

@ -13,13 +13,16 @@ internalsDump:
-V{t#,#}+ Vt_verilated_debug___024root___eval_initial__TOP
Data: w96: 000000aa 000000bb 000000cc
-V{t#,#}+ Vt_verilated_debug___024root___eval_settle
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_verilated_debug___024root___eval
-V{t#,#}+ Vt_verilated_debug___024root___eval_triggers__act
-V{t#,#}+ Vt_verilated_debug___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}End-of-eval cleanup
-V{t#,#}+++++TOP Evaluate Vt_verilated_debug::eval_step
-V{t#,#}+ Vt_verilated_debug___024root___eval_debug_assertions
-V{t#,#}MTask0 starting
-V{t#,#}+ Eval
-V{t#,#}+ Vt_verilated_debug___024root___eval
-V{t#,#}+ Vt_verilated_debug___024root___eval_triggers__act
@ -35,4 +38,5 @@ internalsDump:
-V{t#,#}+ Vt_verilated_debug___024root___eval_triggers__act
-V{t#,#}+ Vt_verilated_debug___024root___dump_triggers__act
-V{t#,#} No triggers active
-V{t#,#}End-of-eval cleanup
-V{t#,#}+ Vt_verilated_debug___024root___eval_final

View File

@ -79,8 +79,8 @@ endif()
define_property(TARGET
PROPERTY VERILATOR_THREADED
BRIEF_DOCS "Verilator multithreading enabled"
FULL_DOCS "Verilator multithreading enabled"
BRIEF_DOCS "Deprecated and has no effect (ignored)"
FULL_DOCS "Deprecated and has no effect (ignored)"
)
define_property(TARGET
@ -262,11 +262,6 @@ function(verilate TARGET)
"${VCMAKE}" "${VCMAKE_COPY}"
DEPENDS "${VCMAKE}" VERBATIM)
if (${VERILATE_PREFIX}_THREADS)
# If any verilate() call specifies THREADS, define VL_THREADED in the final build
set_property(TARGET ${TARGET} PROPERTY VERILATOR_THREADED ON)
endif()
if (${VERILATE_PREFIX}_COVERAGE)
# If any verilate() call specifies COVERAGE, define VM_COVERAGE in the final build
set_property(TARGET ${TARGET} PROPERTY VERILATOR_COVERAGE ON)
@ -326,7 +321,6 @@ function(verilate TARGET)
target_compile_definitions(${TARGET} PRIVATE
VM_COVERAGE=$<BOOL:$<TARGET_PROPERTY:VERILATOR_COVERAGE>>
VM_SC=$<BOOL:$<TARGET_PROPERTY:VERILATOR_SYSTEMC>>
$<$<BOOL:$<TARGET_PROPERTY:VERILATOR_THREADED>>:VL_THREADED>
VM_TRACE=$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE>>
VM_TRACE_VCD=$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE_VCD>>
VM_TRACE_FST=$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE_FST>>
@ -336,11 +330,9 @@ function(verilate TARGET)
${${VERILATE_PREFIX}_USER_LDLIBS}
)
if (${VERILATE_PREFIX}_THREADS OR ${VERILATE_PREFIX}_TRACE_THREADS)
target_link_libraries(${TARGET} PUBLIC
${VERILATOR_MT_CFLAGS}
)
endif()
target_link_libraries(${TARGET} PUBLIC
${VERILATOR_MT_CFLAGS}
)
target_compile_features(${TARGET} PRIVATE cxx_std_11)