Add trace dumpvars() call for selective runtime tracing (#3322).

This commit is contained in:
Wilson Snyder 2022-03-05 15:44:32 -05:00
parent 3737d209f6
commit 321880f5a6
20 changed files with 1033 additions and 35 deletions

View File

@ -16,6 +16,7 @@ Verilator 4.219 devel
* Removed the deprecated lint_off flag -msg; use -rule instead.
* Removed the deprecated "fl" attribute in XML output; use "loc" attribute instead.
* Suppress WIDTH warning on negate using carry bit (#3295). [Peter Monsson]
* Add trace dumpvars() call for selective runtime tracing (#3322). [Shunyao CAD]
* Fix skipping public enum values with four-state values (#3303).
* Fix $readmem file not found to be warning not error (#3310). [Alexander Grobman]
* Fix compile error with --trace-fst --sc (#3332). [leavinel]

View File

@ -134,7 +134,8 @@ B. Or, for finer-grained control, or C++ files with multiple Verilated
...
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
topp->trace(tfp, 99); // Trace 99 levels of hierarchy
topp->trace(tfp, 99); // Trace 99 levels of hierarchy (or see below)
// tfp->dumpvars(1, "t"); // trace 1 level under "t"
tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
...
while (contextp->time() < sim_time && !contextp->gotFinish()) {

View File

@ -122,7 +122,7 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
// convert m_code2symbol into an array for fast lookup
if (!m_symbolp) {
m_symbolp = new fstHandle[nextCode()];
m_symbolp = new fstHandle[nextCode()]{0};
for (const auto& i : m_code2symbol) m_symbolp[i.first] = i.second;
}
m_code2symbol.clear();
@ -162,7 +162,8 @@ void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstV
int lsb) {
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
VerilatedTrace<VerilatedFst>::declCode(code, bits, false);
const bool enabled = VerilatedTrace<VerilatedFst>::declCode(code, name, bits, false);
if (!enabled) return;
std::string nameasstr = namePrefix() + name;
std::istringstream nameiss{nameasstr};
@ -250,12 +251,14 @@ void VerilatedFst::declDouble(vluint32_t code, const char* name, int dtypenum, f
VL_ATTR_ALWINLINE
void VerilatedFst::emitBit(vluint32_t code, CData newval) {
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
fstWriterEmitValueChange(m_fst, m_symbolp[code], newval ? "1" : "0");
}
VL_ATTR_ALWINLINE
void VerilatedFst::emitCData(vluint32_t code, CData newval, int bits) {
char buf[VL_BYTESIZE];
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
cvtCDataToStr(buf, newval << (VL_BYTESIZE - bits));
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
}
@ -263,6 +266,7 @@ void VerilatedFst::emitCData(vluint32_t code, CData newval, int bits) {
VL_ATTR_ALWINLINE
void VerilatedFst::emitSData(vluint32_t code, SData newval, int bits) {
char buf[VL_SHORTSIZE];
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
cvtSDataToStr(buf, newval << (VL_SHORTSIZE - bits));
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
}
@ -270,6 +274,7 @@ void VerilatedFst::emitSData(vluint32_t code, SData newval, int bits) {
VL_ATTR_ALWINLINE
void VerilatedFst::emitIData(vluint32_t code, IData newval, int bits) {
char buf[VL_IDATASIZE];
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
cvtIDataToStr(buf, newval << (VL_IDATASIZE - bits));
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
}
@ -277,6 +282,7 @@ void VerilatedFst::emitIData(vluint32_t code, IData newval, int bits) {
VL_ATTR_ALWINLINE
void VerilatedFst::emitQData(vluint32_t code, QData newval, int bits) {
char buf[VL_QUADSIZE];
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
cvtQDataToStr(buf, newval << (VL_QUADSIZE - bits));
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
}

View File

@ -121,6 +121,7 @@ template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const char* unitp);
template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const std::string& unit);
template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const char* unitp);
template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const std::string& unit);
template <> void VerilatedTrace<VerilatedFst>::dumpvars(int level, const std::string& hier);
#endif
//=============================================================================
@ -178,6 +179,11 @@ public:
void set_time_resolution(const std::string& unit) VL_MT_SAFE {
m_sptrace.set_time_resolution(unit);
}
// Set variables to dump, using $dumpvars format
// If level = 0, dump everything and hier is then ignored
void dumpvars(int level, const std::string& hier) VL_MT_SAFE {
m_sptrace.dumpvars(level, hier);
}
// Internal class access
inline VerilatedFst* spTrace() { return &m_sptrace; }

View File

@ -162,10 +162,6 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
// Base macros
// Return true if data[bit] set; not 0/1 return, but 0/non-zero return.
#define VL_BITISSET_I(data, bit) ((data) & (VL_UL(1) << VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data, bit) ((data) & (1ULL << VL_BITBIT_Q(bit)))
#define VL_BITISSET_E(data, bit) ((data) & (VL_EUL(1) << VL_BITBIT_E(bit)))
#define VL_BITISSET_W(data, bit) ((data)[VL_BITWORD_E(bit)] & (VL_EUL(1) << VL_BITBIT_E(bit)))
#define VL_BITISSETLIMIT_W(data, width, bit) (((bit) < (width)) && VL_BITISSET_W(data, bit))
// Shift appropriate word by bit. Does not account for wrapping between two words
@ -343,13 +339,19 @@ double vl_time_multiplier(int scale) VL_PURE;
vluint64_t vl_time_pow10(int n) VL_PURE;
#ifdef VL_DEBUG
/// Evaluate statement if Verilated::debug() enabled
/// Evaluate statement if VL_DEBUG defined
# define VL_DEBUG_IFDEF(stmt) \
do { \
stmt \
} while (false)
/// Evaluate statement if VL_DEBUG defined and Verilated::debug() enabled
# define VL_DEBUG_IF(stmt) \
do { \
if (VL_UNLIKELY(Verilated::debug())) {stmt} \
} while (false)
#else
// We intentionally do not compile the stmt to improve compile speed
# define VL_DEBUG_IFDEF(stmt) do {} while (false)
# define VL_DEBUG_IF(stmt) do {} while (false)
#endif

View File

@ -27,6 +27,7 @@
#include "verilated.h"
#include "verilated_trace_defs.h"
#include <bitset>
#include <memory>
#include <string>
#include <vector>
@ -142,7 +143,9 @@ private:
};
vluint32_t* m_sigs_oldvalp; // Old value store
EData* m_sigs_enabledp; // Bit vector of enabled codes (nullptr = all on)
vluint64_t m_timeLastDump; // Last time we did a dump
std::vector<bool> m_sigs_enabledVec; // Staging for m_sigs_enabledp
std::vector<CallbackRecord> m_initCbs; // Routines to initialize traciong
std::vector<CallbackRecord> m_fullCbs; // Routines to perform full dump
std::vector<CallbackRecord> m_chgCbs; // Routines to perform incremental dump
@ -152,6 +155,7 @@ private:
vluint32_t m_numSignals; // Number of distinct signals
vluint32_t m_maxBits; // Number of bits in the widest signal
std::vector<std::string> m_namePrefixStack{""}; // Path prefixes to add to signal names
std::vector<std::pair<int, std::string>> m_dumpvars; // dumpvar() entries
char m_scopeEscape;
double m_timeRes; // Time resolution (ns/ms etc)
double m_timeUnit; // Time units (ns/ms etc)
@ -171,27 +175,22 @@ private:
#ifdef VL_TRACE_THREADED
// Number of total trace buffers that have been allocated
vluint32_t m_numTraceBuffers;
// Size of trace buffers
size_t m_traceBufferSize;
// Buffers handed to worker for processing
VerilatedThreadQueue<vluint32_t*> m_buffersToWorker;
// Buffers returned from worker after processing
VerilatedThreadQueue<vluint32_t*> m_buffersFromWorker;
// Write pointer into current buffer
vluint32_t* m_traceBufferWritep;
// End of trace buffer
vluint32_t* m_traceBufferEndp;
// The worker thread itself
std::unique_ptr<std::thread> m_workerThread;
// Get a new trace buffer that can be populated. May block if none available
vluint32_t* getTraceBuffer();
// Write pointer into current buffer
vluint32_t* m_traceBufferWritep;
// End of trace buffer
vluint32_t* m_traceBufferEndp;
// The worker thread itself
std::unique_ptr<std::thread> m_workerThread;
// The function executed by the worker thread
void workerThreadMain();
@ -223,7 +222,8 @@ protected:
void traceInit() VL_MT_UNSAFE;
void declCode(vluint32_t code, vluint32_t bits, bool tri);
// Declare new signal and return true if enabled
bool declCode(vluint32_t code, const char* namep, vluint32_t bits, bool tri);
// Is this an escape?
bool isScopeEscape(char c) { return std::isspace(c) || c == m_scopeEscape; }
@ -259,6 +259,9 @@ public:
// Set time resolution (s/ms, defaults to ns)
void set_time_resolution(const char* unitp) VL_MT_SAFE;
void set_time_resolution(const std::string& unit) VL_MT_SAFE;
// Set variables to dump, using $dumpvars format
// If level = 0, dump everything and hier is then ignored
void dumpvars(int level, const std::string& hier) VL_MT_SAFE;
// Call
void dump(vluint64_t timeui) VL_MT_SAFE_EXCLUDES(m_mutex);

View File

@ -282,6 +282,7 @@ template <> void VerilatedTrace<VL_DERIVED_T>::onExit(void* selfp) {
template <>
VerilatedTrace<VL_DERIVED_T>::VerilatedTrace()
: m_sigs_oldvalp{nullptr}
, m_sigs_enabledp{nullptr}
, m_timeLastDump{0}
, m_fullDump{true}
, m_nextCode{0}
@ -302,6 +303,7 @@ VerilatedTrace<VL_DERIVED_T>::VerilatedTrace()
template <> VerilatedTrace<VL_DERIVED_T>::~VerilatedTrace() {
if (m_sigs_oldvalp) VL_DO_CLEAR(delete[] m_sigs_oldvalp, m_sigs_oldvalp = nullptr);
if (m_sigs_enabledp) VL_DO_CLEAR(delete[] m_sigs_enabledp, m_sigs_enabledp = nullptr);
Verilated::removeFlushCb(VerilatedTrace<VL_DERIVED_T>::onFlush, this);
Verilated::removeExitCb(VerilatedTrace<VL_DERIVED_T>::onExit, this);
#ifdef VL_TRACE_THREADED
@ -320,9 +322,10 @@ template <> void VerilatedTrace<VL_DERIVED_T>::traceInit() VL_MT_UNSAFE {
m_nextCode = 1;
m_numSignals = 0;
m_maxBits = 0;
m_sigs_enabledVec.clear();
// Call all initialize callbacks, which will:
// - Call decl* for each signal
// - Call decl* for each signal (these eventually call ::declCode)
// - Store the base code
for (vluint32_t i = 0; i < m_initCbs.size(); ++i) {
const CallbackRecord& cbr = m_initCbs[i];
@ -338,6 +341,23 @@ template <> void VerilatedTrace<VL_DERIVED_T>::traceInit() VL_MT_UNSAFE {
// holding previous signal values.
if (!m_sigs_oldvalp) m_sigs_oldvalp = new vluint32_t[nextCode()];
// Apply enables
if (m_sigs_enabledp) VL_DO_CLEAR(delete[] m_sigs_enabledp, m_sigs_enabledp = nullptr);
if (!m_sigs_enabledVec.empty()) {
// Else if was empty, m_sigs_enabledp = nullptr to short circuit tests
// But it isn't, so alloc one bit for each code to indicate enablement
// We don't want to still use m_signs_enabledVec as std::vector<bool> is not
// guarenteed to be fast
m_sigs_enabledp = new vluint32_t[1 + VL_WORDS_I(nextCode())]{0};
m_sigs_enabledVec.reserve(nextCode());
for (size_t code = 0; code < nextCode(); ++code) {
if (m_sigs_enabledVec[code]) {
m_sigs_enabledp[VL_BITWORD_I(code)] |= 1U << VL_BITBIT_I(code);
}
}
m_sigs_enabledVec.clear();
}
// Set callback so flush/abort will flush this file
Verilated::addFlushCb(VerilatedTrace<VL_DERIVED_T>::onFlush, this);
Verilated::addExitCb(VerilatedTrace<VL_DERIVED_T>::onExit, this);
@ -356,10 +376,38 @@ template <> void VerilatedTrace<VL_DERIVED_T>::traceInit() VL_MT_UNSAFE {
}
template <>
void VerilatedTrace<VL_DERIVED_T>::declCode(vluint32_t code, vluint32_t bits, bool tri) {
bool VerilatedTrace<VL_DERIVED_T>::declCode(vluint32_t code, const char* namep, vluint32_t bits,
bool tri) {
if (VL_UNCOVERABLE(!code)) {
VL_FATAL_MT(__FILE__, __LINE__, "", "Internal: internal trace problem, code 0 is illegal");
}
// To keep it simple, this is O(enables * signals), but we expect few enables
std::string declName = namePrefix() + namep;
bool enabled = false;
if (m_dumpvars.empty()) enabled = true;
for (const auto& item : m_dumpvars) {
const int dumpvarsLevel = item.first;
const char* dvp = item.second.c_str();
const char* np = declName.c_str();
while (*dvp && *dvp == *np) {
++dvp;
++np;
}
if (*dvp) continue; // Didn't match dumpvar item
if (*np && *np != ' ') continue; // e.g. "t" isn't a match for "top"
int levels = 0;
while (*np) {
if (*np++ == ' ') ++levels;
}
if (levels > dumpvarsLevel) continue; // Too deep
// We only need to set first code word if it's a multicode signal
// as that's all we'll check for later
if (m_sigs_enabledVec.size() <= code) m_sigs_enabledVec.resize((code + 1024) * 2);
m_sigs_enabledVec[code] = true;
enabled = true;
break;
}
// Note: The tri-state flag is not used by Verilator, but is here for
// compatibility with some foreign code.
int codesNeeded = VL_WORDS_I(bits);
@ -367,6 +415,7 @@ void VerilatedTrace<VL_DERIVED_T>::declCode(vluint32_t code, vluint32_t bits, bo
m_nextCode = std::max(m_nextCode, code + codesNeeded);
++m_numSignals;
m_maxBits = std::max(m_maxBits, bits);
return enabled;
}
//=========================================================================
@ -392,6 +441,19 @@ template <>
void VerilatedTrace<VL_DERIVED_T>::set_time_resolution(const std::string& unit) VL_MT_SAFE {
set_time_resolution(unit.c_str());
}
template <>
void VerilatedTrace<VL_DERIVED_T>::dumpvars(int level, const std::string& hier) VL_MT_SAFE {
if (level == 0) {
m_dumpvars.clear(); // empty = everything on
} else {
// Convert Verilog . separators to trace space separators
std::string hierSpaced = hier;
for (auto& i : hierSpaced) {
if (i == '.') i = ' ';
}
m_dumpvars.push_back(std::make_pair(level, hierSpaced));
}
}
template <>
void VerilatedTrace<VL_DERIVED_T>::dump(vluint64_t timeui) VL_MT_SAFE_EXCLUDES(m_mutex) {
@ -523,44 +585,58 @@ template <> void VerilatedTrace<VL_DERIVED_T>::popNamePrefix(unsigned count) {
// the emit* functions can be inlined for performance.
template <> void VerilatedTrace<VL_DERIVED_T>::fullBit(vluint32_t* oldp, CData newval) {
*oldp = newval;
self()->emitBit(oldp - m_sigs_oldvalp, newval);
const uint32_t code = oldp - m_sigs_oldvalp;
*oldp = newval; // Still copy even if not tracing so chg doesn't call full
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
self()->emitBit(code, newval);
}
template <>
void VerilatedTrace<VL_DERIVED_T>::fullCData(vluint32_t* oldp, CData newval, int bits) {
*oldp = newval;
self()->emitCData(oldp - m_sigs_oldvalp, newval, bits);
const uint32_t code = oldp - m_sigs_oldvalp;
*oldp = newval; // Still copy even if not tracing so chg doesn't call full
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
self()->emitCData(code, newval, bits);
}
template <>
void VerilatedTrace<VL_DERIVED_T>::fullSData(vluint32_t* oldp, SData newval, int bits) {
*oldp = newval;
self()->emitSData(oldp - m_sigs_oldvalp, newval, bits);
const uint32_t code = oldp - m_sigs_oldvalp;
*oldp = newval; // Still copy even if not tracing so chg doesn't call full
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
self()->emitSData(code, newval, bits);
}
template <>
void VerilatedTrace<VL_DERIVED_T>::fullIData(vluint32_t* oldp, IData newval, int bits) {
*oldp = newval;
self()->emitIData(oldp - m_sigs_oldvalp, newval, bits);
const uint32_t code = oldp - m_sigs_oldvalp;
*oldp = newval; // Still copy even if not tracing so chg doesn't call full
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
self()->emitIData(code, newval, bits);
}
template <>
void VerilatedTrace<VL_DERIVED_T>::fullQData(vluint32_t* oldp, QData newval, int bits) {
const uint32_t code = oldp - m_sigs_oldvalp;
*reinterpret_cast<QData*>(oldp) = newval;
self()->emitQData(oldp - m_sigs_oldvalp, newval, bits);
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
self()->emitQData(code, newval, bits);
}
template <>
void VerilatedTrace<VL_DERIVED_T>::fullWData(vluint32_t* oldp, const WData* newvalp, int bits) {
const uint32_t code = oldp - m_sigs_oldvalp;
for (int i = 0; i < VL_WORDS_I(bits); ++i) oldp[i] = newvalp[i];
self()->emitWData(oldp - m_sigs_oldvalp, newvalp, bits);
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
self()->emitWData(code, newvalp, bits);
}
template <> void VerilatedTrace<VL_DERIVED_T>::fullDouble(vluint32_t* oldp, double newval) {
// cppcheck-suppress invalidPointerCast
const uint32_t code = oldp - m_sigs_oldvalp;
*reinterpret_cast<double*>(oldp) = newval;
self()->emitDouble(oldp - m_sigs_oldvalp, newval);
if (VL_UNLIKELY(m_sigs_enabledp && !(VL_BITISSET_W(m_sigs_enabledp, code)))) return;
// cppcheck-suppress invalidPointerCast
self()->emitDouble(code, newval);
}
//=========================================================================

View File

@ -463,7 +463,7 @@ void VerilatedVcd::declare(vluint32_t code, const char* name, const char* wirep,
int arraynum, bool tri, bool bussed, int msb, int lsb) {
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
VerilatedTrace<VerilatedVcd>::declCode(code, bits, tri);
const bool enabled = VerilatedTrace<VerilatedVcd>::declCode(code, name, bits, tri);
if (m_suffixes.size() <= nextCode() * VL_TRACE_SUFFIX_ENTRY_SIZE) {
m_suffixes.resize(nextCode() * VL_TRACE_SUFFIX_ENTRY_SIZE * 2, 0);
@ -472,6 +472,8 @@ void VerilatedVcd::declare(vluint32_t code, const char* name, const char* wirep,
// Make sure write buffer is large enough (one character per bit), plus header
bufferResize(bits + 1024);
if (!enabled) return;
// Split name into basename
// Spaces and tabs aren't legal in VCD signal names, so:
// Space separates each level of scope
@ -606,6 +608,7 @@ static inline void VerilatedVcdCCopyAndAppendNewLine(char* writep, const char* s
void VerilatedVcd::finishLine(vluint32_t code, char* writep) {
const char* const suffixp = m_suffixes.data() + code * VL_TRACE_SUFFIX_ENTRY_SIZE;
VL_DEBUG_IFDEF(assert(suffixp[0]););
VerilatedVcdCCopyAndAppendNewLine(writep, suffixp);
// Now write back the write pointer incremented by the actual size of the

View File

@ -328,6 +328,7 @@ template <> void VerilatedTrace<VerilatedVcd>::set_time_unit(const char* unitp);
template <> void VerilatedTrace<VerilatedVcd>::set_time_unit(const std::string& unit);
template <> void VerilatedTrace<VerilatedVcd>::set_time_resolution(const char* unitp);
template <> void VerilatedTrace<VerilatedVcd>::set_time_resolution(const std::string& unit);
template <> void VerilatedTrace<VerilatedVcd>::dumpvars(int level, const std::string& hier);
#endif // DOXYGEN
//=============================================================================
@ -392,6 +393,11 @@ public:
void set_time_resolution(const std::string& unit) VL_MT_SAFE {
m_sptrace.set_time_resolution(unit);
}
// Set variables to dump, using $dumpvars format
// If level = 0, dump everything and hier is then ignored
void dumpvars(int level, const std::string& hier) VL_MT_SAFE {
m_sptrace.dumpvars(level, hier);
}
// Internal class access
inline VerilatedVcd* spTrace() { return &m_sptrace; }

View File

@ -414,6 +414,12 @@ using ssize_t = uint32_t; ///< signed size_t; returned from read()
#define VL_BITBIT_Q(bit) ((bit) & VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
#define VL_BITBIT_E(bit) ((bit) & VL_SIZEBITS_E) ///< Bit number for a bit in a EData
// Return true if data[bit] set; not 0/1 return, but 0/non-zero return.
#define VL_BITISSET_I(data, bit) ((data) & (VL_UL(1) << VL_BITBIT_I(bit)))
#define VL_BITISSET_Q(data, bit) ((data) & (1ULL << VL_BITBIT_Q(bit)))
#define VL_BITISSET_E(data, bit) ((data) & (VL_EUL(1) << VL_BITBIT_E(bit)))
#define VL_BITISSET_W(data, bit) ((data)[VL_BITWORD_E(bit)] & (VL_EUL(1) << VL_BITBIT_E(bit)))
//=========================================================================
// Floating point
// #defines, to avoid requiring math.h on all compile runs

View File

@ -0,0 +1,62 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
#include <memory>
#include <verilated.h>
#include <verilated_fst_c.h>
#include <verilated_vcd_c.h>
#include VM_PREFIX_INCLUDE
unsigned long long main_time = 0;
double sc_time_stamp() { return (double)main_time; }
const unsigned long long dt_2 = 3;
int main(int argc, char** argv, char** env) {
std::unique_ptr<VM_PREFIX> top{new VM_PREFIX("top")};
Verilated::debug(0);
Verilated::traceEverOn(true);
#if defined(T_TRACE_DUMPVARS_DYN_VCD_0) || defined(T_TRACE_DUMPVARS_DYN_VCD_1)
std::unique_ptr<VerilatedVcdC> tfp{new VerilatedVcdC};
#elif defined(T_TRACE_DUMPVARS_DYN_FST_0) || defined(T_TRACE_DUMPVARS_DYN_FST_1)
std::unique_ptr<VerilatedFstC> tfp{new VerilatedFstC};
#else
#error "Bad test"
#endif
#if defined(T_TRACE_DUMPVARS_DYN_VCD_0) || defined(T_TRACE_DUMPVARS_DYN_FST_0)
tfp->dumpvars(0, "");
#elif defined(T_TRACE_DUMPVARS_DYN_VCD_1) || defined(T_TRACE_DUMPVARS_DYN_FST_1)
tfp->dumpvars(99, "t"); // This should not match "top."
tfp->dumpvars(1, "top.t.cyc"); // A signal
tfp->dumpvars(1, "top.t.sub1a"); // Scope
tfp->dumpvars(2, "top.t.sub1b"); // Scope
#else
#error "Bad test"
#endif
top->trace(tfp.get(), 99);
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
top->clk = 0;
while (main_time <= 20) {
top->eval();
tfp->dump((unsigned int)(main_time));
++main_time;
top->clk = !top->clk;
}
tfp->close();
top->final();
tfp.reset();
top.reset();
printf("*-* All Finished *-*\n");
return 0;
}

View File

@ -0,0 +1,42 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
int cyc;
sub1 #(10) sub1a (.*);
sub1 #(20) sub1b (.*);
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc == 10) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module sub1 #(parameter int ADD)
(input int cyc);
wire int value = cyc + ADD;
sub2 #(ADD + 1) sub2a(.*);
sub2 #(ADD + 2) sub2b(.*);
sub2 #(ADD + 3) sub2c(.*);
endmodule
module sub2 #(parameter int ADD)
(input int cyc);
wire int value = cyc + ADD;
endmodule

View File

@ -0,0 +1,209 @@
$date
Sat Mar 5 14:06:13 2022
$end
$version
fstWriter
$end
$timescale
1ps
$end
$scope module top $end
$var wire 1 ! clk $end
$scope module t $end
$var wire 1 ! clk $end
$var int 32 " cyc [31:0] $end
$scope module sub1a $end
$var parameter 32 # ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 $ value [31:0] $end
$scope module sub2a $end
$var parameter 32 % ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 & value [31:0] $end
$upscope $end
$scope module sub2b $end
$var parameter 32 ' ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 ( value [31:0] $end
$upscope $end
$scope module sub2c $end
$var parameter 32 ) ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 * value [31:0] $end
$upscope $end
$upscope $end
$scope module sub1b $end
$var parameter 32 + ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 , value [31:0] $end
$scope module sub2a $end
$var parameter 32 - ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 . value [31:0] $end
$upscope $end
$scope module sub2b $end
$var parameter 32 / ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 0 value [31:0] $end
$upscope $end
$scope module sub2c $end
$var parameter 32 1 ADD [31:0] $end
$var wire 32 " cyc [31:0] $end
$var wire 32 2 value [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
b00000000000000000000000000010111 2
b00000000000000000000000000010111 1
b00000000000000000000000000010110 0
b00000000000000000000000000010110 /
b00000000000000000000000000010101 .
b00000000000000000000000000010101 -
b00000000000000000000000000010100 ,
b00000000000000000000000000010100 +
b00000000000000000000000000001101 *
b00000000000000000000000000001101 )
b00000000000000000000000000001100 (
b00000000000000000000000000001100 '
b00000000000000000000000000001011 &
b00000000000000000000000000001011 %
b00000000000000000000000000001010 $
b00000000000000000000000000001010 #
b00000000000000000000000000000000 "
0!
$end
#1
1!
b00000000000000000000000000000001 "
b00000000000000000000000000001011 $
b00000000000000000000000000001100 &
b00000000000000000000000000001101 (
b00000000000000000000000000001110 *
b00000000000000000000000000010101 ,
b00000000000000000000000000010110 .
b00000000000000000000000000010111 0
b00000000000000000000000000011000 2
#2
0!
#3
1!
b00000000000000000000000000011001 2
b00000000000000000000000000011000 0
b00000000000000000000000000010111 .
b00000000000000000000000000010110 ,
b00000000000000000000000000001111 *
b00000000000000000000000000001110 (
b00000000000000000000000000001101 &
b00000000000000000000000000001100 $
b00000000000000000000000000000010 "
#4
0!
#5
1!
b00000000000000000000000000000011 "
b00000000000000000000000000001101 $
b00000000000000000000000000001110 &
b00000000000000000000000000001111 (
b00000000000000000000000000010000 *
b00000000000000000000000000010111 ,
b00000000000000000000000000011000 .
b00000000000000000000000000011001 0
b00000000000000000000000000011010 2
#6
0!
#7
1!
b00000000000000000000000000011011 2
b00000000000000000000000000011010 0
b00000000000000000000000000011001 .
b00000000000000000000000000011000 ,
b00000000000000000000000000010001 *
b00000000000000000000000000010000 (
b00000000000000000000000000001111 &
b00000000000000000000000000001110 $
b00000000000000000000000000000100 "
#8
0!
#9
1!
b00000000000000000000000000000101 "
b00000000000000000000000000001111 $
b00000000000000000000000000010000 &
b00000000000000000000000000010001 (
b00000000000000000000000000010010 *
b00000000000000000000000000011001 ,
b00000000000000000000000000011010 .
b00000000000000000000000000011011 0
b00000000000000000000000000011100 2
#10
0!
#11
1!
b00000000000000000000000000011101 2
b00000000000000000000000000011100 0
b00000000000000000000000000011011 .
b00000000000000000000000000011010 ,
b00000000000000000000000000010011 *
b00000000000000000000000000010010 (
b00000000000000000000000000010001 &
b00000000000000000000000000010000 $
b00000000000000000000000000000110 "
#12
0!
#13
1!
b00000000000000000000000000000111 "
b00000000000000000000000000010001 $
b00000000000000000000000000010010 &
b00000000000000000000000000010011 (
b00000000000000000000000000010100 *
b00000000000000000000000000011011 ,
b00000000000000000000000000011100 .
b00000000000000000000000000011101 0
b00000000000000000000000000011110 2
#14
0!
#15
1!
b00000000000000000000000000011111 2
b00000000000000000000000000011110 0
b00000000000000000000000000011101 .
b00000000000000000000000000011100 ,
b00000000000000000000000000010101 *
b00000000000000000000000000010100 (
b00000000000000000000000000010011 &
b00000000000000000000000000010010 $
b00000000000000000000000000001000 "
#16
0!
#17
1!
b00000000000000000000000000001001 "
b00000000000000000000000000010011 $
b00000000000000000000000000010100 &
b00000000000000000000000000010101 (
b00000000000000000000000000010110 *
b00000000000000000000000000011101 ,
b00000000000000000000000000011110 .
b00000000000000000000000000011111 0
b00000000000000000000000000100000 2
#18
0!
#19
1!
b00000000000000000000000000100001 2
b00000000000000000000000000100000 0
b00000000000000000000000000011111 .
b00000000000000000000000000011110 ,
b00000000000000000000000000010111 *
b00000000000000000000000000010110 (
b00000000000000000000000000010101 &
b00000000000000000000000000010100 $
b00000000000000000000000000001010 "
#20
0!

View File

@ -0,0 +1,27 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. 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_all => 1);
top_filename("t_trace_dumpvars_dyn.v");
compile(
make_main => 0,
verilator_flags2 => ["--trace-fst --exe $Self->{t_dir}/t_trace_dumpvars_dyn.cpp"],
);
execute(
check_finished => 1,
);
fst_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
ok(1);
1;

View File

@ -0,0 +1,135 @@
$date
Sat Mar 5 14:05:37 2022
$end
$version
fstWriter
$end
$timescale
1ps
$end
$scope module top $end
$scope module t $end
$var int 32 ! cyc [31:0] $end
$scope module sub1a $end
$var parameter 32 " ADD [31:0] $end
$var wire 32 ! cyc [31:0] $end
$var wire 32 # value [31:0] $end
$upscope $end
$scope module sub1b $end
$var parameter 32 $ ADD [31:0] $end
$var wire 32 ! cyc [31:0] $end
$var wire 32 % value [31:0] $end
$scope module sub2a $end
$var parameter 32 & ADD [31:0] $end
$var wire 32 ! cyc [31:0] $end
$var wire 32 ' value [31:0] $end
$upscope $end
$scope module sub2b $end
$var parameter 32 ( ADD [31:0] $end
$var wire 32 ! cyc [31:0] $end
$var wire 32 ) value [31:0] $end
$upscope $end
$scope module sub2c $end
$var parameter 32 * ADD [31:0] $end
$var wire 32 ! cyc [31:0] $end
$var wire 32 + value [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
$dumpvars
b00000000000000000000000000010111 +
b00000000000000000000000000010111 *
b00000000000000000000000000010110 )
b00000000000000000000000000010110 (
b00000000000000000000000000010101 '
b00000000000000000000000000010101 &
b00000000000000000000000000010100 %
b00000000000000000000000000010100 $
b00000000000000000000000000001010 #
b00000000000000000000000000001010 "
b00000000000000000000000000000000 !
$end
#1
b00000000000000000000000000000001 !
b00000000000000000000000000001011 #
b00000000000000000000000000010101 %
b00000000000000000000000000010110 '
b00000000000000000000000000010111 )
b00000000000000000000000000011000 +
#2
#3
b00000000000000000000000000011001 +
b00000000000000000000000000011000 )
b00000000000000000000000000010111 '
b00000000000000000000000000010110 %
b00000000000000000000000000001100 #
b00000000000000000000000000000010 !
#4
#5
b00000000000000000000000000000011 !
b00000000000000000000000000001101 #
b00000000000000000000000000010111 %
b00000000000000000000000000011000 '
b00000000000000000000000000011001 )
b00000000000000000000000000011010 +
#6
#7
b00000000000000000000000000011011 +
b00000000000000000000000000011010 )
b00000000000000000000000000011001 '
b00000000000000000000000000011000 %
b00000000000000000000000000001110 #
b00000000000000000000000000000100 !
#8
#9
b00000000000000000000000000000101 !
b00000000000000000000000000001111 #
b00000000000000000000000000011001 %
b00000000000000000000000000011010 '
b00000000000000000000000000011011 )
b00000000000000000000000000011100 +
#10
#11
b00000000000000000000000000011101 +
b00000000000000000000000000011100 )
b00000000000000000000000000011011 '
b00000000000000000000000000011010 %
b00000000000000000000000000010000 #
b00000000000000000000000000000110 !
#12
#13
b00000000000000000000000000000111 !
b00000000000000000000000000010001 #
b00000000000000000000000000011011 %
b00000000000000000000000000011100 '
b00000000000000000000000000011101 )
b00000000000000000000000000011110 +
#14
#15
b00000000000000000000000000011111 +
b00000000000000000000000000011110 )
b00000000000000000000000000011101 '
b00000000000000000000000000011100 %
b00000000000000000000000000010010 #
b00000000000000000000000000001000 !
#16
#17
b00000000000000000000000000001001 !
b00000000000000000000000000010011 #
b00000000000000000000000000011101 %
b00000000000000000000000000011110 '
b00000000000000000000000000011111 )
b00000000000000000000000000100000 +
#18
#19
b00000000000000000000000000100001 +
b00000000000000000000000000100000 )
b00000000000000000000000000011111 '
b00000000000000000000000000011110 %
b00000000000000000000000000010100 #
b00000000000000000000000000001010 !
#20

View File

@ -0,0 +1,27 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. 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_all => 1);
top_filename("t_trace_dumpvars_dyn.v");
compile(
make_main => 0,
verilator_flags2 => ["--trace-fst --exe $Self->{t_dir}/t_trace_dumpvars_dyn.cpp"],
);
execute(
check_finished => 1,
);
fst_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
ok(1);
1;

View File

@ -0,0 +1,203 @@
$version Generated by VerilatedVcd $end
$date Sat Mar 5 13:48:47 2022 $end
$timescale 1ps $end
$scope module top $end
$var wire 1 , clk $end
$scope module t $end
$var wire 1 , clk $end
$var wire 32 # cyc [31:0] $end
$scope module sub1a $end
$var wire 32 - ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 $ value [31:0] $end
$scope module sub2a $end
$var wire 32 . ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 % value [31:0] $end
$upscope $end
$scope module sub2b $end
$var wire 32 / ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 & value [31:0] $end
$upscope $end
$scope module sub2c $end
$var wire 32 0 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 ' value [31:0] $end
$upscope $end
$upscope $end
$scope module sub1b $end
$var wire 32 1 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 ( value [31:0] $end
$scope module sub2a $end
$var wire 32 2 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 ) value [31:0] $end
$upscope $end
$scope module sub2b $end
$var wire 32 3 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 * value [31:0] $end
$upscope $end
$scope module sub2c $end
$var wire 32 4 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 + value [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 #
b00000000000000000000000000001010 $
b00000000000000000000000000001011 %
b00000000000000000000000000001100 &
b00000000000000000000000000001101 '
b00000000000000000000000000010100 (
b00000000000000000000000000010101 )
b00000000000000000000000000010110 *
b00000000000000000000000000010111 +
0,
b00000000000000000000000000001010 -
b00000000000000000000000000001011 .
b00000000000000000000000000001100 /
b00000000000000000000000000001101 0
b00000000000000000000000000010100 1
b00000000000000000000000000010101 2
b00000000000000000000000000010110 3
b00000000000000000000000000010111 4
#1
b00000000000000000000000000000001 #
b00000000000000000000000000001011 $
b00000000000000000000000000001100 %
b00000000000000000000000000001101 &
b00000000000000000000000000001110 '
b00000000000000000000000000010101 (
b00000000000000000000000000010110 )
b00000000000000000000000000010111 *
b00000000000000000000000000011000 +
1,
#2
0,
#3
b00000000000000000000000000000010 #
b00000000000000000000000000001100 $
b00000000000000000000000000001101 %
b00000000000000000000000000001110 &
b00000000000000000000000000001111 '
b00000000000000000000000000010110 (
b00000000000000000000000000010111 )
b00000000000000000000000000011000 *
b00000000000000000000000000011001 +
1,
#4
0,
#5
b00000000000000000000000000000011 #
b00000000000000000000000000001101 $
b00000000000000000000000000001110 %
b00000000000000000000000000001111 &
b00000000000000000000000000010000 '
b00000000000000000000000000010111 (
b00000000000000000000000000011000 )
b00000000000000000000000000011001 *
b00000000000000000000000000011010 +
1,
#6
0,
#7
b00000000000000000000000000000100 #
b00000000000000000000000000001110 $
b00000000000000000000000000001111 %
b00000000000000000000000000010000 &
b00000000000000000000000000010001 '
b00000000000000000000000000011000 (
b00000000000000000000000000011001 )
b00000000000000000000000000011010 *
b00000000000000000000000000011011 +
1,
#8
0,
#9
b00000000000000000000000000000101 #
b00000000000000000000000000001111 $
b00000000000000000000000000010000 %
b00000000000000000000000000010001 &
b00000000000000000000000000010010 '
b00000000000000000000000000011001 (
b00000000000000000000000000011010 )
b00000000000000000000000000011011 *
b00000000000000000000000000011100 +
1,
#10
0,
#11
b00000000000000000000000000000110 #
b00000000000000000000000000010000 $
b00000000000000000000000000010001 %
b00000000000000000000000000010010 &
b00000000000000000000000000010011 '
b00000000000000000000000000011010 (
b00000000000000000000000000011011 )
b00000000000000000000000000011100 *
b00000000000000000000000000011101 +
1,
#12
0,
#13
b00000000000000000000000000000111 #
b00000000000000000000000000010001 $
b00000000000000000000000000010010 %
b00000000000000000000000000010011 &
b00000000000000000000000000010100 '
b00000000000000000000000000011011 (
b00000000000000000000000000011100 )
b00000000000000000000000000011101 *
b00000000000000000000000000011110 +
1,
#14
0,
#15
b00000000000000000000000000001000 #
b00000000000000000000000000010010 $
b00000000000000000000000000010011 %
b00000000000000000000000000010100 &
b00000000000000000000000000010101 '
b00000000000000000000000000011100 (
b00000000000000000000000000011101 )
b00000000000000000000000000011110 *
b00000000000000000000000000011111 +
1,
#16
0,
#17
b00000000000000000000000000001001 #
b00000000000000000000000000010011 $
b00000000000000000000000000010100 %
b00000000000000000000000000010101 &
b00000000000000000000000000010110 '
b00000000000000000000000000011101 (
b00000000000000000000000000011110 )
b00000000000000000000000000011111 *
b00000000000000000000000000100000 +
1,
#18
0,
#19
b00000000000000000000000000001010 #
b00000000000000000000000000010100 $
b00000000000000000000000000010101 %
b00000000000000000000000000010110 &
b00000000000000000000000000010111 '
b00000000000000000000000000011110 (
b00000000000000000000000000011111 )
b00000000000000000000000000100000 *
b00000000000000000000000000100001 +
1,
#20
0,

View File

@ -0,0 +1,27 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. 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_all => 1);
top_filename("t_trace_dumpvars_dyn.v");
compile(
make_main => 0,
verilator_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_dumpvars_dyn.cpp"],
);
execute(
check_finished => 1,
);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
ok(1);
1;

View File

@ -0,0 +1,129 @@
$version Generated by VerilatedVcd $end
$date Sat Mar 5 13:47:52 2022 $end
$timescale 1ps $end
$scope module top $end
$scope module t $end
$var wire 32 # cyc [31:0] $end
$scope module sub1a $end
$var wire 32 - ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 $ value [31:0] $end
$upscope $end
$scope module sub1b $end
$var wire 32 1 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 ( value [31:0] $end
$scope module sub2a $end
$var wire 32 2 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 ) value [31:0] $end
$upscope $end
$scope module sub2b $end
$var wire 32 3 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 * value [31:0] $end
$upscope $end
$scope module sub2c $end
$var wire 32 4 ADD [31:0] $end
$var wire 32 # cyc [31:0] $end
$var wire 32 + value [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000000 #
b00000000000000000000000000001010 $
b00000000000000000000000000010100 (
b00000000000000000000000000010101 )
b00000000000000000000000000010110 *
b00000000000000000000000000010111 +
b00000000000000000000000000001010 -
b00000000000000000000000000010100 1
b00000000000000000000000000010101 2
b00000000000000000000000000010110 3
b00000000000000000000000000010111 4
#1
b00000000000000000000000000000001 #
b00000000000000000000000000001011 $
b00000000000000000000000000010101 (
b00000000000000000000000000010110 )
b00000000000000000000000000010111 *
b00000000000000000000000000011000 +
#2
#3
b00000000000000000000000000000010 #
b00000000000000000000000000001100 $
b00000000000000000000000000010110 (
b00000000000000000000000000010111 )
b00000000000000000000000000011000 *
b00000000000000000000000000011001 +
#4
#5
b00000000000000000000000000000011 #
b00000000000000000000000000001101 $
b00000000000000000000000000010111 (
b00000000000000000000000000011000 )
b00000000000000000000000000011001 *
b00000000000000000000000000011010 +
#6
#7
b00000000000000000000000000000100 #
b00000000000000000000000000001110 $
b00000000000000000000000000011000 (
b00000000000000000000000000011001 )
b00000000000000000000000000011010 *
b00000000000000000000000000011011 +
#8
#9
b00000000000000000000000000000101 #
b00000000000000000000000000001111 $
b00000000000000000000000000011001 (
b00000000000000000000000000011010 )
b00000000000000000000000000011011 *
b00000000000000000000000000011100 +
#10
#11
b00000000000000000000000000000110 #
b00000000000000000000000000010000 $
b00000000000000000000000000011010 (
b00000000000000000000000000011011 )
b00000000000000000000000000011100 *
b00000000000000000000000000011101 +
#12
#13
b00000000000000000000000000000111 #
b00000000000000000000000000010001 $
b00000000000000000000000000011011 (
b00000000000000000000000000011100 )
b00000000000000000000000000011101 *
b00000000000000000000000000011110 +
#14
#15
b00000000000000000000000000001000 #
b00000000000000000000000000010010 $
b00000000000000000000000000011100 (
b00000000000000000000000000011101 )
b00000000000000000000000000011110 *
b00000000000000000000000000011111 +
#16
#17
b00000000000000000000000000001001 #
b00000000000000000000000000010011 $
b00000000000000000000000000011101 (
b00000000000000000000000000011110 )
b00000000000000000000000000011111 *
b00000000000000000000000000100000 +
#18
#19
b00000000000000000000000000001010 #
b00000000000000000000000000010100 $
b00000000000000000000000000011110 (
b00000000000000000000000000011111 )
b00000000000000000000000000100000 *
b00000000000000000000000000100001 +
#20

View File

@ -0,0 +1,27 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 by Wilson Snyder. 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_all => 1);
top_filename("t_trace_dumpvars_dyn.v");
compile(
make_main => 0,
verilator_flags2 => ["--trace --exe $Self->{t_dir}/t_trace_dumpvars_dyn.cpp -CFLAGS -DVL_DEBUG"],
);
execute(
check_finished => 1,
);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
ok(1);
1;