forked from github/verilator
Configure tracing at run-time, instead of compile time (#3504)
All remaining use of conditional compilation in the tracing implementation of the run-time library are replaced with the use of VerilatedModel::traceConfig, and is now done at run-time.
This commit is contained in:
parent
a4ed3c2086
commit
1d400dd98c
@ -72,6 +72,8 @@
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#include "verilated_trace.h"
|
||||
|
||||
// Max characters in static char string for VL_VALUE_STRING
|
||||
constexpr unsigned VL_VALUE_STRING_MAX_WIDTH = 8192;
|
||||
|
||||
@ -2914,6 +2916,8 @@ void VerilatedImp::versionDump() VL_MT_SAFE {
|
||||
VerilatedModel::VerilatedModel(VerilatedContext& context)
|
||||
: m_context{context} {}
|
||||
|
||||
std::unique_ptr<VerilatedTraceConfig> VerilatedModel::traceConfig() const { return nullptr; }
|
||||
|
||||
//===========================================================================
|
||||
// VerilatedModule:: Methods
|
||||
|
||||
|
@ -91,6 +91,8 @@ class VerilatedFstC;
|
||||
class VerilatedFstSc;
|
||||
class VerilatedScope;
|
||||
class VerilatedScopeNameMap;
|
||||
template <class, class> class VerilatedTrace;
|
||||
class VerilatedTraceConfig;
|
||||
class VerilatedVar;
|
||||
class VerilatedVarNameMap;
|
||||
class VerilatedVcd;
|
||||
@ -278,6 +280,12 @@ public:
|
||||
virtual const char* modelName() const = 0;
|
||||
/// Returns the thread level parallelism, this model was Verilated with. Always 1 or higher.
|
||||
virtual unsigned threads() const = 0;
|
||||
|
||||
private:
|
||||
// The following are for use by Verilator internals only
|
||||
template <class, class> friend class VerilatedTrace;
|
||||
// Run-time trace configuration requested by this model
|
||||
virtual std::unique_ptr<VerilatedTraceConfig> traceConfig() const;
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
|
@ -142,26 +142,6 @@ ifneq ($(VM_THREADS),0)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(VM_TRACE_THREADS),0)
|
||||
ifneq ($(VM_TRACE_THREADS),)
|
||||
ifeq ($(findstring -DVL_THREADED,$(CPPFLAGS)),)
|
||||
$(error VM_TRACE_THREADS requires VM_THREADS)
|
||||
endif
|
||||
CPPFLAGS += -DVL_TRACE_THREADED
|
||||
VK_C11=1
|
||||
VK_LIBS_THREADED=1
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifneq ($(VM_TRACE_FST_WRITER_THREAD),0)
|
||||
ifneq ($(VM_TRACE_FST_WRITER_THREAD),)
|
||||
CPPFLAGS += -DVL_TRACE_FST_WRITER_THREAD
|
||||
VK_C11=1
|
||||
VK_LIBS_THREADED=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(VK_C11),0)
|
||||
ifneq ($(VK_C11),)
|
||||
# Need C++11 at least, so always default to newest
|
||||
|
@ -93,17 +93,7 @@ static_assert(static_cast<int>(FST_ST_VCD_PROGRAM) == static_cast<int>(VLT_TRACE
|
||||
// VerilatedFst
|
||||
|
||||
VerilatedFst::VerilatedFst(void* fst)
|
||||
:
|
||||
#ifdef VL_TRACE_OFFLOAD
|
||||
VerilatedTrace {
|
||||
true
|
||||
}
|
||||
#else
|
||||
VerilatedTrace {
|
||||
false
|
||||
}
|
||||
#endif
|
||||
, m_fst{fst} {}
|
||||
: m_fst{fst} {}
|
||||
|
||||
VerilatedFst::~VerilatedFst() {
|
||||
if (m_fst) fstWriterClose(m_fst);
|
||||
@ -116,7 +106,7 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
m_fst = fstWriterCreate(filename, 1);
|
||||
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
|
||||
fstWriterSetTimescaleFromString(m_fst, timeResStr().c_str()); // lintok-begin-on-ref
|
||||
if (useFstWriterThread()) fstWriterSetParallelMode(m_fst, 1);
|
||||
if (m_useFstWriterThread) fstWriterSetParallelMode(m_fst, 1);
|
||||
fullDump(true); // First dump must be full for fst
|
||||
|
||||
m_curScope.clear();
|
||||
@ -278,6 +268,14 @@ void VerilatedFst::commitTraceBuffer(VerilatedFst::Buffer* bufp) {
|
||||
delete bufp;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Configure
|
||||
|
||||
void VerilatedFst::configure(const VerilatedTraceConfig& config) {
|
||||
// If at least one model requests the FST writer thread, then use it
|
||||
m_useFstWriterThread |= config.m_useFstWriterThread;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstBuffer implementation
|
||||
|
||||
|
@ -55,19 +55,13 @@ private:
|
||||
fstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
|
||||
char* m_strbuf = nullptr; // String buffer long enough to hold maxBits() chars
|
||||
|
||||
bool m_useFstWriterThread = false; // Whether to use the separate FST writer thread
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFst);
|
||||
void declare(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, bool bussed, int msb, int lsb);
|
||||
|
||||
static constexpr bool useFstWriterThread() {
|
||||
#ifdef VL_TRACE_FST_WRITER_THREAD
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
//=========================================================================
|
||||
// Implementation of VerilatedTrace interface
|
||||
@ -83,6 +77,9 @@ protected:
|
||||
virtual Buffer* getTraceBuffer() override;
|
||||
virtual void commitTraceBuffer(Buffer*) override;
|
||||
|
||||
// Configure sub-class
|
||||
virtual void configure(const VerilatedTraceConfig&) override;
|
||||
|
||||
public:
|
||||
//=========================================================================
|
||||
// External interface to client code
|
||||
|
@ -24,21 +24,6 @@
|
||||
|
||||
// clang-format off
|
||||
|
||||
// In FST mode, VL_TRACE_THREADED enables offloading, but only if we also have
|
||||
// the FST writer thread. This means with --trace-threads 1, we get the FST
|
||||
// writer thread only, and with --trace-threads 2 we get offloading as well
|
||||
#if defined(VL_TRACE_FST_WRITER_THREAD) && defined(VL_TRACE_THREADED)
|
||||
# define VL_TRACE_OFFLOAD
|
||||
#endif
|
||||
// VCD tracing can happen fully in parallel
|
||||
#if defined(VM_TRACE_VCD) && VM_TRACE_VCD && defined(VL_TRACE_THREADED)
|
||||
# define VL_TRACE_PARALLEL
|
||||
#endif
|
||||
|
||||
#if defined(VL_TRACE_PARALLEL) && defined(VL_TRACE_OFFLOAD)
|
||||
# error "Cannot have VL_TRACE_PARALLEL and VL_TRACE_OFFLOAD together"
|
||||
#endif
|
||||
|
||||
#include "verilated.h"
|
||||
#include "verilated_trace_defs.h"
|
||||
|
||||
@ -47,6 +32,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#ifdef VL_THREADED
|
||||
@ -130,6 +116,22 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedTraceConfig
|
||||
|
||||
// Simple data representing trace configuration required by generated models.
|
||||
class VerilatedTraceConfig final {
|
||||
public:
|
||||
const bool m_useParallel; // Use parallel tracing
|
||||
const bool m_useOffloading; // Offloading trace rendering
|
||||
const bool m_useFstWriterThread; // Use the separate FST writer thread
|
||||
|
||||
VerilatedTraceConfig(bool useParallel, bool useOffloading, bool useFstWriterThread)
|
||||
: m_useParallel{useParallel}
|
||||
, m_useOffloading{useOffloading}
|
||||
, m_useFstWriterThread{useFstWriterThread} {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedTrace
|
||||
|
||||
@ -180,7 +182,8 @@ private:
|
||||
, m_userp{userp} {}
|
||||
};
|
||||
|
||||
const bool m_offload; // Whether to use the offload thread (ignored if !VL_THREADED)
|
||||
bool m_offload = false; // Use the offload thread (ignored if !VL_THREADED)
|
||||
bool m_parallel = false; // Use parallel tracing (ignored if !VL_THREADED)
|
||||
|
||||
#ifdef VL_THREADED
|
||||
struct ParallelWorkerData {
|
||||
@ -215,7 +218,6 @@ private:
|
||||
std::vector<CallbackRecord> m_chgCbs; // Routines to perform incremental dump
|
||||
std::vector<CallbackRecord> m_chgOffloadCbs; // Routines to perform offloaded incremental dump
|
||||
std::vector<CallbackRecord> m_cleanupCbs; // Routines to call at the end of dump
|
||||
VerilatedContext* m_contextp = nullptr; // The context used by the traced models
|
||||
bool m_fullDump = true; // Whether a full dump is required on the next call to 'dump'
|
||||
uint32_t m_nextCode = 0; // Next code number to assign
|
||||
uint32_t m_numSignals = 0; // Number of distinct signals
|
||||
@ -227,8 +229,8 @@ private:
|
||||
double m_timeUnit = 1e-0; // Time units (ns/ms etc)
|
||||
uint64_t m_timeLastDump = 0; // Last time we did a dump
|
||||
bool m_didSomeDump = false; // Did at least one dump (i.e.: m_timeLastDump is valid)
|
||||
|
||||
void addModel(VerilatedModel*) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
VerilatedContext* m_contextp = nullptr; // The context used by the traced models
|
||||
std::unordered_set<const VerilatedModel*> m_models; // The collection of models being traced
|
||||
|
||||
void addCallbackRecord(std::vector<CallbackRecord>& cbVec, CallbackRecord&& cbRec)
|
||||
VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
@ -313,18 +315,12 @@ protected:
|
||||
|
||||
#ifdef VL_THREADED
|
||||
inline bool offload() const { return m_offload; }
|
||||
inline bool parallel() const { return m_parallel; }
|
||||
#else
|
||||
static constexpr bool offload() { return false; }
|
||||
static constexpr bool parallel() { return false; }
|
||||
#endif
|
||||
|
||||
inline bool parallel() const {
|
||||
#ifdef VL_TRACE_PARALLEL
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Virtual functions to be provided by the format specific implementation
|
||||
|
||||
@ -340,11 +336,14 @@ protected:
|
||||
virtual Buffer* getTraceBuffer() = 0;
|
||||
virtual void commitTraceBuffer(Buffer*) = 0;
|
||||
|
||||
// Configure sub-class
|
||||
virtual void configure(const VerilatedTraceConfig&) = 0;
|
||||
|
||||
public:
|
||||
//=========================================================================
|
||||
// External interface to client code
|
||||
|
||||
explicit VerilatedTrace(bool offload);
|
||||
explicit VerilatedTrace();
|
||||
~VerilatedTrace();
|
||||
|
||||
// Set time units (s/ms, defaults to ns)
|
||||
@ -366,12 +365,13 @@ public:
|
||||
//=========================================================================
|
||||
// Non-hot path internal interface to Verilator generated code
|
||||
|
||||
void addInitCb(initCb_t cb, void* userp, VerilatedModel*) VL_MT_SAFE;
|
||||
void addFullCb(dumpCb_t cb, void* userp, VerilatedModel*) VL_MT_SAFE;
|
||||
void addFullCb(dumpOffloadCb_t cb, void* userp, VerilatedModel*) VL_MT_SAFE;
|
||||
void addChgCb(dumpCb_t cb, void* userp, VerilatedModel*) VL_MT_SAFE;
|
||||
void addChgCb(dumpOffloadCb_t cb, void* userp, VerilatedModel*) VL_MT_SAFE;
|
||||
void addCleanupCb(cleanupCb_t cb, void* userp, VerilatedModel*) VL_MT_SAFE;
|
||||
void addModel(VerilatedModel*) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
void addInitCb(initCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addCleanupCb(cleanupCb_t cb, void* userp) VL_MT_SAFE;
|
||||
|
||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||
|
||||
|
@ -293,14 +293,7 @@ template <> void VerilatedTrace<VL_SUB_T, VL_BUF_T>::onExit(void* selfp) {
|
||||
//=============================================================================
|
||||
// VerilatedTrace
|
||||
|
||||
template <>
|
||||
VerilatedTrace<VL_SUB_T, VL_BUF_T>::VerilatedTrace(bool offload)
|
||||
: m_offload{offload} {
|
||||
#ifndef VL_THREADED
|
||||
if (m_offload) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", "Cannot use trace offloading without VL_THREADED");
|
||||
}
|
||||
#endif
|
||||
template <> VerilatedTrace<VL_SUB_T, VL_BUF_T>::VerilatedTrace() {
|
||||
set_time_unit(Verilated::threadContextp()->timeunitString());
|
||||
set_time_resolution(Verilated::threadContextp()->timeprecisionString());
|
||||
}
|
||||
@ -648,8 +641,17 @@ template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addModel(VerilatedModel* modelp)
|
||||
VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
|
||||
const bool firstModel = m_models.empty();
|
||||
const bool newModel = m_models.insert(modelp).second;
|
||||
VerilatedContext* const contextp = modelp->contextp();
|
||||
if (VL_UNCOVERABLE(m_contextp && contextp != m_contextp)) { // LCOV_EXCL_START
|
||||
|
||||
// Validate
|
||||
if (!newModel) { // LCOV_EXCL_START
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"The same model has already been added to this trace file");
|
||||
}
|
||||
if (VL_UNCOVERABLE(m_contextp && contextp != m_contextp)) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"A trace file instance can only handle models from the same context");
|
||||
}
|
||||
@ -657,7 +659,35 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addModel(VerilatedModel* modelp)
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"Cannot add models to a trace file if 'dump' has already been called");
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
// Keep hold of the context
|
||||
m_contextp = contextp;
|
||||
|
||||
// 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) {
|
||||
if (m_offload != configp->m_useOffloading) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"Either all or no models using the same trace file must use offloading");
|
||||
}
|
||||
}
|
||||
m_offload = configp->m_useOffloading;
|
||||
// If at least one model requests parallel tracing, then use it
|
||||
m_parallel |= configp->m_useParallel;
|
||||
|
||||
if (VL_UNCOVERABLE(m_parallel && m_offload)) { // LCOV_EXCL_START
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", "Cannot use parallel tracing with offloading");
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
// Configure format specific sub class
|
||||
configure(*(configp.get()));
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -669,43 +699,27 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addCallbackRecord(std::vector<CallbackR
|
||||
}
|
||||
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addInitCb(initCb_t cb, void* userp,
|
||||
VerilatedModel* modelp) VL_MT_SAFE {
|
||||
addModel(modelp);
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addInitCb(initCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_initCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpCb_t cb, void* userp,
|
||||
VerilatedModel* modelp) VL_MT_SAFE {
|
||||
addModel(modelp);
|
||||
assert(!offload());
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpOffloadCb_t cb, void* userp,
|
||||
VerilatedModel* modelp) VL_MT_SAFE {
|
||||
addModel(modelp);
|
||||
assert(offload());
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullOffloadCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpCb_t cb, void* userp,
|
||||
VerilatedModel* modelp) VL_MT_SAFE {
|
||||
addModel(modelp);
|
||||
assert(!offload());
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpOffloadCb_t cb, void* userp,
|
||||
VerilatedModel* modelp) VL_MT_SAFE {
|
||||
addModel(modelp);
|
||||
assert(offload());
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgOffloadCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addCleanupCb(cleanupCb_t cb, void* userp,
|
||||
VerilatedModel* modelp) VL_MT_SAFE {
|
||||
addModel(modelp);
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addCleanupCb(cleanupCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_cleanupCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,7 @@ ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) VL_MT_UNSAFE {
|
||||
//=============================================================================
|
||||
// Opening/Closing
|
||||
|
||||
VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep)
|
||||
: VerilatedTrace{false} {
|
||||
VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep) {
|
||||
// Not in header to avoid link issue if header is included without this .cpp file
|
||||
m_fileNewed = (filep == nullptr);
|
||||
m_filep = m_fileNewed ? new VerilatedVcdFile : filep;
|
||||
|
@ -112,6 +112,9 @@ protected:
|
||||
virtual Buffer* getTraceBuffer() override;
|
||||
virtual void commitTraceBuffer(Buffer*) override;
|
||||
|
||||
// Configure sub-class
|
||||
virtual void configure(const VerilatedTraceConfig&) override { return; };
|
||||
|
||||
public:
|
||||
//=========================================================================
|
||||
// External interface to client code
|
||||
|
@ -113,12 +113,6 @@ class CMakeEmitter final {
|
||||
cmake_set_raw(*of, name + "_COVERAGE", v3Global.opt.coverage() ? "1" : "0");
|
||||
*of << "# Threaded output mode? 0/1/N threads (from --threads)\n";
|
||||
cmake_set_raw(*of, name + "_THREADS", cvtToStr(v3Global.opt.threads()));
|
||||
*of << "# Threaded tracing output mode? 0/1/N threads (from --threads/--trace-threads)\n";
|
||||
cmake_set_raw(*of, name + "_TRACE_THREADS", cvtToStr(v3Global.opt.vmTraceThreads()));
|
||||
cmake_set_raw(*of, name + "_TRACE_FST_WRITER_THREAD",
|
||||
v3Global.opt.traceThreads() && v3Global.opt.traceFormat().fst() ? "1" : "0");
|
||||
*of << "# Struct output mode? 0/1 (from --trace-structs)\n";
|
||||
cmake_set_raw(*of, name + "_TRACE_STRUCTS", cvtToStr(v3Global.opt.traceStructs()));
|
||||
*of << "# VCD Tracing output mode? 0/1 (from --trace)\n";
|
||||
cmake_set_raw(*of, name + "_TRACE_VCD",
|
||||
(v3Global.opt.trace() && v3Global.opt.traceFormat().vcd()) ? "1" : "0");
|
||||
|
@ -223,6 +223,9 @@ class EmitCModel final : public EmitCFunc {
|
||||
puts("const char* hierName() const override final;\n");
|
||||
puts("const char* modelName() const override final;\n");
|
||||
puts("unsigned threads() const override final;\n");
|
||||
if (v3Global.opt.trace()) {
|
||||
puts("std::unique_ptr<VerilatedTraceConfig> traceConfig() const override final;\n");
|
||||
}
|
||||
|
||||
puts("} VL_ATTR_ALIGNED(VL_CACHE_LINE_BYTES);\n");
|
||||
|
||||
@ -487,6 +490,17 @@ class EmitCModel final : public EmitCFunc {
|
||||
+ "\"; }\n");
|
||||
puts("unsigned " + topClassName() + "::threads() const { return "
|
||||
+ cvtToStr(std::max(1, v3Global.opt.threads())) + "; }\n");
|
||||
|
||||
if (v3Global.opt.trace()) {
|
||||
puts("std::unique_ptr<VerilatedTraceConfig> " + topClassName()
|
||||
+ "::traceConfig() const {\n");
|
||||
puts("return std::unique_ptr<VerilatedTraceConfig>{new VerilatedTraceConfig{");
|
||||
puts(v3Global.opt.useTraceParallel() ? "true" : "false");
|
||||
puts(v3Global.opt.useTraceOffload() ? ", true" : ", false");
|
||||
puts(v3Global.opt.useFstWriterThread() ? ", true" : ", false");
|
||||
puts("}};\n");
|
||||
puts("};\n");
|
||||
}
|
||||
}
|
||||
|
||||
void emitTraceMethods(AstNodeModule* modp) {
|
||||
@ -539,8 +553,8 @@ class EmitCModel final : public EmitCFunc {
|
||||
puts(/**/ "}");
|
||||
}
|
||||
puts(/**/ "if (false && levels && options) {} // Prevent unused\n");
|
||||
puts(/**/ "tfp->spTrace()->addInitCb(&" + protect("trace_init")
|
||||
+ ", &(vlSymsp->TOP), this);\n");
|
||||
puts(/**/ "tfp->spTrace()->addModel(this);\n");
|
||||
puts(/**/ "tfp->spTrace()->addInitCb(&" + protect("trace_init") + ", &(vlSymsp->TOP));\n");
|
||||
puts(/**/ topModNameProtected + "__" + protect("trace_register")
|
||||
+ "(&(vlSymsp->TOP), tfp->spTrace());\n");
|
||||
|
||||
|
@ -73,15 +73,6 @@ public:
|
||||
of.puts("VM_TRACE_FST = ");
|
||||
of.puts(v3Global.opt.trace() && v3Global.opt.traceFormat().fst() ? "1" : "0");
|
||||
of.puts("\n");
|
||||
of.puts(
|
||||
"# Tracing threaded output mode? 0/1/N threads (from --threads/--trace-thread)\n");
|
||||
of.puts("VM_TRACE_THREADS = ");
|
||||
of.puts(cvtToStr(v3Global.opt.vmTraceThreads()));
|
||||
of.puts("\n");
|
||||
of.puts("# Separate FST writer thread? 0/1 (from --trace-fst with --trace-thread > 0)\n");
|
||||
of.puts("VM_TRACE_FST_WRITER_THREAD = ");
|
||||
of.puts(v3Global.opt.traceThreads() && v3Global.opt.traceFormat().fst() ? "1" : "0");
|
||||
of.puts("\n");
|
||||
|
||||
of.puts("\n### Object file lists...\n");
|
||||
for (int support = 0; support < 3; ++support) {
|
||||
|
@ -521,6 +521,7 @@ public:
|
||||
bool useTraceParallel() const {
|
||||
return trace() && traceFormat().vcd() && threads() && (threads() > 1 || hierChild() > 1);
|
||||
}
|
||||
bool useFstWriterThread() const { return traceThreads() && traceFormat().fst(); }
|
||||
unsigned vmTraceThreads() const {
|
||||
return useTraceParallel() ? threads() : useTraceOffload() ? 1 : 0;
|
||||
}
|
||||
|
@ -515,7 +515,6 @@ private:
|
||||
}
|
||||
m_regFuncp->addStmtsp(new AstAddrOfCFunc(flp, funcp));
|
||||
m_regFuncp->addStmtsp(new AstText(flp, ", vlSelf", true));
|
||||
m_regFuncp->addStmtsp(new AstText(flp, ", vlSelf->vlSymsp->__Vm_modelp", true));
|
||||
m_regFuncp->addStmtsp(new AstText(flp, ");\n", true));
|
||||
} else {
|
||||
// Sub functions
|
||||
@ -705,7 +704,7 @@ private:
|
||||
// Register it
|
||||
m_regFuncp->addStmtsp(new AstText(fl, "tracep->addCleanupCb(", true));
|
||||
m_regFuncp->addStmtsp(new AstAddrOfCFunc(fl, cleanupFuncp));
|
||||
m_regFuncp->addStmtsp(new AstText(fl, ", vlSelf, vlSelf->vlSymsp->__Vm_modelp);\n", true));
|
||||
m_regFuncp->addStmtsp(new AstText(fl, ", vlSelf);\n", true));
|
||||
|
||||
// Clear global activity flag
|
||||
cleanupFuncp->addStmtsp(
|
||||
|
@ -261,15 +261,6 @@ function(verilate TARGET)
|
||||
set_property(TARGET ${TARGET} PROPERTY VERILATOR_THREADED ON)
|
||||
endif()
|
||||
|
||||
if (${VERILATE_PREFIX}_TRACE_THREADS)
|
||||
# If any verilate() call specifies TRACE_THREADS, define VL_TRACE_THREADED in the final build
|
||||
set_property(TARGET ${TARGET} PROPERTY VERILATOR_TRACE_THREADED ON)
|
||||
endif()
|
||||
|
||||
if (${VERILATE_PREFIX}_TRACE_FST_WRITER_THREAD)
|
||||
set_property(TARGET ${TARGET} PROPERTY VERILATOR_TRACE_FST_WRITER_TRHEAD 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)
|
||||
@ -330,8 +321,6 @@ function(verilate TARGET)
|
||||
VM_COVERAGE=$<BOOL:$<TARGET_PROPERTY:VERILATOR_COVERAGE>>
|
||||
VM_SC=$<BOOL:$<TARGET_PROPERTY:VERILATOR_SYSTEMC>>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:VERILATOR_THREADED>>:VL_THREADED>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE_THREADED>>:VL_TRACE_THREADED>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE_FST_WRITER_TRHEAD>>:VL_TRACE_FST_WRITER_THREAD>
|
||||
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>>
|
||||
|
Loading…
Reference in New Issue
Block a user