mirror of
https://github.com/verilator/verilator.git
synced 2026-09-07 10:01:11 +02:00
Associate trace codes with function indices (#4610)
For each traced variable, also register the trace function index that will write it.
This commit is contained in:
+16
-13
@@ -222,35 +222,38 @@ void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum, fstVar
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedFst::declEvent(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
void VerilatedFst::declEvent(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
fstVarDir vardir, fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 0, 0);
|
||||
}
|
||||
void VerilatedFst::declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
void VerilatedFst::declBit(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
fstVarDir vardir, fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 0, 0);
|
||||
}
|
||||
void VerilatedFst::declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
void VerilatedFst::declBus(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
fstVarDir vardir, fstVarType vartype, bool array, int arraynum, int msb,
|
||||
int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
void VerilatedFst::declQuad(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
fstVarDir vardir, fstVarType vartype, bool array, int arraynum,
|
||||
int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
void VerilatedFst::declArray(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
fstVarDir vardir, fstVarType vartype, bool array, int arraynum,
|
||||
int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
void VerilatedFst::declDouble(uint32_t code, uint32_t fidx, const char* name, int dtypenum,
|
||||
fstVarDir vardir, fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 63, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Get/commit trace buffer
|
||||
|
||||
VerilatedFst::Buffer* VerilatedFst::getTraceBuffer() {
|
||||
VerilatedFst::Buffer* VerilatedFst::getTraceBuffer(uint32_t fidx) {
|
||||
if (offload()) return new OffloadBuffer{*this};
|
||||
return new Buffer{*this};
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ protected:
|
||||
bool preChangeDump() override { return isOpen(); }
|
||||
|
||||
// Trace buffer management
|
||||
Buffer* getTraceBuffer() override;
|
||||
Buffer* getTraceBuffer(uint32_t fidx) override;
|
||||
void commitTraceBuffer(Buffer*) override;
|
||||
|
||||
// Configure sub-class
|
||||
@@ -101,17 +101,17 @@ public:
|
||||
//=========================================================================
|
||||
// Internal interface to Verilator generated code
|
||||
|
||||
void declEvent(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declEvent(uint32_t code, uint32_t fidx, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
void declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declBit(uint32_t code, uint32_t fidx, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
void declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declBus(uint32_t code, uint32_t fidx, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declQuad(uint32_t code, uint32_t fidx, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declArray(uint32_t code, uint32_t fidx, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declDouble(uint32_t code, uint32_t fidx, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
|
||||
void declDTypeEnum(int dtypenum, const char* name, uint32_t elements, unsigned int minValbits,
|
||||
|
||||
+16
-11
@@ -162,24 +162,29 @@ private:
|
||||
// (the one in Ubuntu 14.04 with GCC 4.8.4 in particular) use the
|
||||
// assignment operator on inserting into collections, so they don't work
|
||||
// with const fields...
|
||||
union { // The callback
|
||||
const union { // The callback
|
||||
initCb_t m_initCb;
|
||||
dumpCb_t m_dumpCb;
|
||||
dumpOffloadCb_t m_dumpOffloadCb;
|
||||
cleanupCb_t m_cleanupCb;
|
||||
};
|
||||
void* m_userp; // The user pointer to pass to the callback (the symbol table)
|
||||
const uint32_t m_fidx; // The index of the tracing function
|
||||
void* const m_userp; // The user pointer to pass to the callback (the symbol table)
|
||||
CallbackRecord(initCb_t cb, void* userp)
|
||||
: m_initCb{cb}
|
||||
, m_fidx{0}
|
||||
, m_userp{userp} {}
|
||||
CallbackRecord(dumpCb_t cb, void* userp)
|
||||
CallbackRecord(dumpCb_t cb, uint32_t fidx, void* userp)
|
||||
: m_dumpCb{cb}
|
||||
, m_fidx{fidx}
|
||||
, m_userp{userp} {}
|
||||
CallbackRecord(dumpOffloadCb_t cb, void* userp)
|
||||
CallbackRecord(dumpOffloadCb_t cb, uint32_t fidx, void* userp)
|
||||
: m_dumpOffloadCb{cb}
|
||||
, m_fidx{fidx}
|
||||
, m_userp{userp} {}
|
||||
CallbackRecord(cleanupCb_t cb, void* userp)
|
||||
: m_cleanupCb{cb}
|
||||
, m_fidx{0}
|
||||
, m_userp{userp} {}
|
||||
};
|
||||
|
||||
@@ -329,7 +334,7 @@ protected:
|
||||
virtual bool preChangeDump() = 0;
|
||||
|
||||
// Trace buffer management
|
||||
virtual Buffer* getTraceBuffer() = 0;
|
||||
virtual Buffer* getTraceBuffer(uint32_t fidx) = 0;
|
||||
virtual void commitTraceBuffer(Buffer*) = 0;
|
||||
|
||||
// Configure sub-class
|
||||
@@ -363,12 +368,12 @@ public:
|
||||
|
||||
void addModel(VerilatedModel*) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
void addInitCb(initCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addConstCb(dumpCb_t cb, void* userp) VL_MT_SAFE;
|
||||
void addConstCb(dumpOffloadCb_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 addConstCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addConstCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addFullCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addChgCb(dumpOffloadCb_t cb, uint32_t fidx, void* userp) VL_MT_SAFE;
|
||||
void addCleanupCb(cleanupCb_t cb, void* userp) VL_MT_SAFE;
|
||||
|
||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||
|
||||
@@ -498,16 +498,15 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runCallbacks(const std::vector<Callback
|
||||
// Main thread executes all jobs with index % threads == 0
|
||||
std::vector<ParallelWorkerData*> mainThreadWorkerData;
|
||||
// Enqueue all the jobs
|
||||
for (unsigned i = 0; i < cbVec.size(); ++i) {
|
||||
const CallbackRecord& cbr = cbVec[i];
|
||||
for (const CallbackRecord& cbr : cbVec) {
|
||||
// Always get the trace buffer on the main thread
|
||||
Buffer* const bufp = getTraceBuffer();
|
||||
Buffer* const bufp = getTraceBuffer(cbr.m_fidx);
|
||||
// Create new work item
|
||||
workerData.emplace_back(cbr.m_dumpCb, cbr.m_userp, bufp);
|
||||
// Grab the new work item
|
||||
ParallelWorkerData* const itemp = &workerData.back();
|
||||
// Enqueue task to thread pool, or main thread
|
||||
if (unsigned rem = i % threads) {
|
||||
if (unsigned rem = cbr.m_fidx % threads) {
|
||||
threadPoolp->workerp(rem - 1)->addTask(parallelWorkerTask, itemp);
|
||||
} else {
|
||||
mainThreadWorkerData.push_back(itemp);
|
||||
@@ -530,7 +529,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runCallbacks(const std::vector<Callback
|
||||
}
|
||||
// Fall back on sequential execution
|
||||
for (const CallbackRecord& cbr : cbVec) {
|
||||
Buffer* const traceBufferp = getTraceBuffer();
|
||||
Buffer* const traceBufferp = getTraceBuffer(cbr.m_fidx);
|
||||
cbr.m_dumpCb(cbr.m_userp, traceBufferp);
|
||||
commitTraceBuffer(traceBufferp);
|
||||
}
|
||||
@@ -541,7 +540,7 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::runOffloadedCallbacks(
|
||||
const std::vector<CallbackRecord>& cbVec) {
|
||||
// Fall back on sequential execution
|
||||
for (const CallbackRecord& cbr : cbVec) {
|
||||
Buffer* traceBufferp = getTraceBuffer();
|
||||
Buffer* traceBufferp = getTraceBuffer(cbr.m_fidx);
|
||||
cbr.m_dumpOffloadCb(cbr.m_userp, static_cast<OffloadBuffer*>(traceBufferp));
|
||||
commitTraceBuffer(traceBufferp);
|
||||
}
|
||||
@@ -704,28 +703,34 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addInitCb(initCb_t cb, void* userp) VL_
|
||||
addCallbackRecord(m_initCbs, CallbackRecord{cb, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_constCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_constCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_constOffloadCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpOffloadCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_constOffloadCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullOffloadCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addFullCb(dumpOffloadCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_fullOffloadCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgOffloadCbs, CallbackRecord{cb, userp});
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addChgCb(dumpOffloadCb_t cb, uint32_t fidx,
|
||||
void* userp) VL_MT_SAFE {
|
||||
addCallbackRecord(m_chgOffloadCbs, CallbackRecord{cb, fidx, userp});
|
||||
}
|
||||
template <>
|
||||
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addCleanupCb(cleanupCb_t cb, void* userp) VL_MT_SAFE {
|
||||
|
||||
+13
-10
@@ -520,32 +520,35 @@ void VerilatedVcd::declare(uint32_t code, const char* name, const char* wirep, b
|
||||
m_namemapp->emplace(hiername, decl);
|
||||
}
|
||||
|
||||
void VerilatedVcd::declEvent(uint32_t code, const char* name, bool array, int arraynum) {
|
||||
void VerilatedVcd::declEvent(uint32_t code, uint32_t fidx, const char* name, bool array,
|
||||
int arraynum) {
|
||||
declare(code, name, "event", array, arraynum, false, false, 0, 0);
|
||||
}
|
||||
void VerilatedVcd::declBit(uint32_t code, const char* name, bool array, int arraynum) {
|
||||
void VerilatedVcd::declBit(uint32_t code, uint32_t fidx, const char* name, bool array,
|
||||
int arraynum) {
|
||||
declare(code, name, "wire", array, arraynum, false, false, 0, 0);
|
||||
}
|
||||
void VerilatedVcd::declBus(uint32_t code, const char* name, bool array, int arraynum, int msb,
|
||||
int lsb) {
|
||||
void VerilatedVcd::declBus(uint32_t code, uint32_t fidx, const char* name, bool array,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declare(code, name, "wire", array, arraynum, false, true, msb, lsb);
|
||||
}
|
||||
void VerilatedVcd::declQuad(uint32_t code, const char* name, bool array, int arraynum, int msb,
|
||||
int lsb) {
|
||||
void VerilatedVcd::declQuad(uint32_t code, uint32_t fidx, const char* name, bool array,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declare(code, name, "wire", array, arraynum, false, true, msb, lsb);
|
||||
}
|
||||
void VerilatedVcd::declArray(uint32_t code, const char* name, bool array, int arraynum, int msb,
|
||||
int lsb) {
|
||||
void VerilatedVcd::declArray(uint32_t code, uint32_t fidx, const char* name, bool array,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declare(code, name, "wire", array, arraynum, false, true, msb, lsb);
|
||||
}
|
||||
void VerilatedVcd::declDouble(uint32_t code, const char* name, bool array, int arraynum) {
|
||||
void VerilatedVcd::declDouble(uint32_t code, uint32_t fidx, const char* name, bool array,
|
||||
int arraynum) {
|
||||
declare(code, name, "real", array, arraynum, false, false, 63, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Get/commit trace buffer
|
||||
|
||||
VerilatedVcd::Buffer* VerilatedVcd::getTraceBuffer() {
|
||||
VerilatedVcd::Buffer* VerilatedVcd::getTraceBuffer(uint32_t fidx) {
|
||||
VerilatedVcd::Buffer* const bufp = new Buffer{*this};
|
||||
if (parallel()) {
|
||||
// Note: This is called from VerilatedVcd::dump, which already holds the lock
|
||||
|
||||
@@ -107,7 +107,7 @@ protected:
|
||||
bool preChangeDump() override;
|
||||
|
||||
// Trace buffer management
|
||||
Buffer* getTraceBuffer() override;
|
||||
Buffer* getTraceBuffer(uint32_t fidx) override;
|
||||
void commitTraceBuffer(Buffer*) override;
|
||||
|
||||
// Configure sub-class
|
||||
@@ -140,12 +140,15 @@ public:
|
||||
//=========================================================================
|
||||
// Internal interface to Verilator generated code
|
||||
|
||||
void declEvent(uint32_t code, const char* name, bool array, int arraynum);
|
||||
void declBit(uint32_t code, const char* name, bool array, int arraynum);
|
||||
void declBus(uint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
|
||||
void declQuad(uint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
|
||||
void declArray(uint32_t code, const char* name, bool array, int arraynum, int msb, int lsb);
|
||||
void declDouble(uint32_t code, const char* name, bool array, int arraynum);
|
||||
void declEvent(uint32_t code, uint32_t fidx, const char* name, bool array, int arraynum);
|
||||
void declBit(uint32_t code, uint32_t fidx, const char* name, bool array, int arraynum);
|
||||
void declBus(uint32_t code, uint32_t fidx, const char* name, bool array, int arraynum, int msb,
|
||||
int lsb);
|
||||
void declQuad(uint32_t code, uint32_t fidx, const char* name, bool array, int arraynum,
|
||||
int msb, int lsb);
|
||||
void declArray(uint32_t code, uint32_t fidx, const char* name, bool array, int arraynum,
|
||||
int msb, int lsb);
|
||||
void declDouble(uint32_t code, uint32_t fidx, const char* name, bool array, int arraynum);
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
Reference in New Issue
Block a user