Skip to content

Commit

Permalink
Separate tracing of const values from non-const values
Browse files Browse the repository at this point in the history
Some values emitted to the trace files are constant (e.g.: actual
parameter values), and never change. Previously we used to trace these
in the 'full' dumps, which also included all other truly variable
signals. This patch introduces a new generated trace function 'const',
to complement the 'full' and 'chg' flavour, and 'const' now only
contains the constant signals, while 'full' and 'chg' contain only the
truly variable signals. The generate 'full' and 'chg' trace functions
now have exactly the same shape. Note that 'const' signals are still
traced using the 'full*' dump methods of the trace buffers, so there is
no need for a third flavour of those.
  • Loading branch information
gezalore committed Oct 23, 2023
1 parent 33c5b5f commit a86f1fb
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 122 deletions.
1 change: 1 addition & 0 deletions include/verilated_fst_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
fstWriterSetTimescaleFromString(m_fst, timeResStr().c_str()); // lintok-begin-on-ref
if (m_useFstWriterThread) fstWriterSetParallelMode(m_fst, 1);
constDump(true); // First dump must contain the const signals
fullDump(true); // First dump must be full for fst

m_curScope.clear();
Expand Down
6 changes: 6 additions & 0 deletions include/verilated_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,14 @@ class VerilatedTrace VL_NOT_FINAL {
private:
std::vector<bool> m_sigs_enabledVec; // Staging for m_sigs_enabledp
std::vector<CallbackRecord> m_initCbs; // Routines to initialize tracing
std::vector<CallbackRecord> m_constCbs; // Routines to perform const dump
std::vector<CallbackRecord> m_constOffloadCbs; // Routines to perform offloaded const dump
std::vector<CallbackRecord> m_fullCbs; // Routines to perform full dump
std::vector<CallbackRecord> m_fullOffloadCbs; // Routines to perform offloaded full dump
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
bool m_constDump = true; // Whether a const dump is required on the next call to 'dump'
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
Expand Down Expand Up @@ -289,6 +292,7 @@ class VerilatedTrace VL_NOT_FINAL {
uint32_t nextCode() const { return m_nextCode; }
uint32_t numSignals() const { return m_numSignals; }
uint32_t maxBits() const { return m_maxBits; }
void constDump(bool value) { m_constDump = value; }
void fullDump(bool value) { m_fullDump = value; }

double timeRes() const { return m_timeRes; }
Expand Down Expand Up @@ -359,6 +363,8 @@ class VerilatedTrace VL_NOT_FINAL {

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;
Expand Down
17 changes: 17 additions & 0 deletions include/verilated_trace_imp.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,15 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
}
}

if (VL_UNLIKELY(m_constDump)) {
m_constDump = false;
if (offload()) {
runOffloadedCallbacks(m_constOffloadCbs);
} else {
runCallbacks(m_constCbs);
}
}

for (uint32_t i = 0; i < m_cleanupCbs.size(); ++i) {
const CallbackRecord& cbr = m_cleanupCbs[i];
cbr.m_cleanupCb(cbr.m_userp, self());
Expand Down Expand Up @@ -695,6 +704,14 @@ 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});
}
template <>
void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addConstCb(dumpOffloadCb_t cb, void* userp) VL_MT_SAFE {
addCallbackRecord(m_constOffloadCbs, CallbackRecord{cb, 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});
}
Expand Down
1 change: 1 addition & 0 deletions include/verilated_vcd_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ void VerilatedVcd::openNextImp(bool incFilename) {
}
}
m_isOpen = true;
constDump(true); // First dump must containt the const signals
fullDump(true); // First dump must be full
m_wroteBytes = 0;
}
Expand Down
32 changes: 32 additions & 0 deletions src/V3Ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,38 @@ inline std::ostream& operator<<(std::ostream& os, const VUseType& rhs) {
return os << rhs.ascii();
}

//######################################################################

class VTraceType final {
public:
enum en : uint8_t {
CONST, // Const value dump (once at the beginning)
FULL, // Full value dump (always emitted)
CHANGE // Incremental value dump (emitted only if the value changed)
};
enum en m_e;
VTraceType()
: m_e{CONST} {}
// cppcheck-suppress noExplicitConstructor
constexpr VTraceType(en _e)
: m_e{_e} {}
explicit VTraceType(int _e)
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
constexpr operator en() const { return m_e; }
const char* ascii() const {
static const char* const names[] = {"CONST", "FULL", "CHANGE"};
return names[m_e];
}
};
constexpr bool operator==(const VTraceType& lhs, const VTraceType& rhs) {
return lhs.m_e == rhs.m_e;
}
constexpr bool operator==(const VTraceType& lhs, VTraceType::en rhs) { return lhs.m_e == rhs; }
constexpr bool operator==(VTraceType::en lhs, const VTraceType& rhs) { return lhs == rhs.m_e; }
inline std::ostream& operator<<(std::ostream& os, const VTraceType& rhs) {
return os << rhs.ascii();
}

// ######################################################################

class VCastable final {
Expand Down
8 changes: 4 additions & 4 deletions src/V3AstNodeOther.h
Original file line number Diff line number Diff line change
Expand Up @@ -3243,14 +3243,14 @@ class AstTraceInc final : public AstNodeStmt {
private:
AstTraceDecl* m_declp; // Pointer to declaration
const uint32_t m_baseCode; // Trace code base value in function containing this AstTraceInc
const bool m_full; // Is this a full vs incremental dump
const VTraceType m_traceType; // Is this a const/full/incremental dump

public:
AstTraceInc(FileLine* fl, AstTraceDecl* declp, bool full, uint32_t baseCode = 0)
AstTraceInc(FileLine* fl, AstTraceDecl* declp, VTraceType traceType, uint32_t baseCode = 0)
: ASTGEN_SUPER_TraceInc(fl)
, m_declp{declp}
, m_baseCode{baseCode}
, m_full{full} {
, m_traceType{traceType} {
dtypeFrom(declp);
this->valuep(
declp->valuep()->cloneTree(true)); // TODO: maybe use reference to TraceDecl instead?
Expand All @@ -3274,7 +3274,7 @@ class AstTraceInc final : public AstNodeStmt {
bool isOutputter() override { return true; }
// but isPure() true
AstTraceDecl* declp() const { return m_declp; }
bool full() const { return m_full; }
VTraceType traceType() const { return m_traceType; }
uint32_t baseCode() const { return m_baseCode; }
};
class AstTracePopNamePrefix final : public AstNodeStmt {
Expand Down
6 changes: 4 additions & 2 deletions src/V3EmitCImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ class EmitCTrace final : EmitCFunc {

void emitTraceChangeOne(AstTraceInc* nodep, int arrayindex) {
iterateAndNextConstNull(nodep->precondsp());
const string func = nodep->full() ? "full" : "chg";
const std::string func = nodep->traceType() == VTraceType::CHANGE ? "chg" : "full";
bool emitWidth = true;
if (nodep->dtypep()->basicp()->isDouble()) {
puts("bufp->" + func + "Double");
Expand All @@ -794,7 +794,9 @@ class EmitCTrace final : EmitCFunc {

const uint32_t offset = (arrayindex < 0) ? 0 : (arrayindex * nodep->declp()->widthWords());
const uint32_t code = nodep->declp()->code() + offset;
puts(v3Global.opt.useTraceOffload() && !nodep->full() ? "(base+" : "(oldp+");
puts(v3Global.opt.useTraceOffload() && nodep->traceType() == VTraceType::CHANGE
? "(base+"
: "(oldp+");
puts(cvtToStr(code - nodep->baseCode()));
puts(",");
emitTraceValue(nodep, arrayindex);
Expand Down
Loading

0 comments on commit a86f1fb

Please sign in to comment.