diff --git a/Changes b/Changes index 682450cc4..d6c2cdff4 100644 --- a/Changes +++ b/Changes @@ -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] diff --git a/docs/guide/faq.rst b/docs/guide/faq.rst index 7ecbdb8a9..14f4281ea 100644 --- a/docs/guide/faq.rst +++ b/docs/guide/faq.rst @@ -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()) { diff --git a/include/verilated_fst_c.cpp b/include/verilated_fst_c.cpp index a5491cab7..365834b88 100644 --- a/include/verilated_fst_c.cpp +++ b/include/verilated_fst_c.cpp @@ -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::declCode(code, bits, false); + const bool enabled = VerilatedTrace::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); } diff --git a/include/verilated_fst_c.h b/include/verilated_fst_c.h index 1d0637887..3e48daf92 100644 --- a/include/verilated_fst_c.h +++ b/include/verilated_fst_c.h @@ -121,6 +121,7 @@ template <> void VerilatedTrace::set_time_unit(const char* unitp); template <> void VerilatedTrace::set_time_unit(const std::string& unit); template <> void VerilatedTrace::set_time_resolution(const char* unitp); template <> void VerilatedTrace::set_time_resolution(const std::string& unit); +template <> void VerilatedTrace::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; } diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index ac241fd34..988b5d807 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -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 diff --git a/include/verilated_trace.h b/include/verilated_trace.h index 3b1426dd6..6caeb5d03 100644 --- a/include/verilated_trace.h +++ b/include/verilated_trace.h @@ -27,6 +27,7 @@ #include "verilated.h" #include "verilated_trace_defs.h" +#include #include #include #include @@ -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 m_sigs_enabledVec; // Staging for m_sigs_enabledp std::vector m_initCbs; // Routines to initialize traciong std::vector m_fullCbs; // Routines to perform full dump std::vector 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 m_namePrefixStack{""}; // Path prefixes to add to signal names + std::vector> 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 m_buffersToWorker; // Buffers returned from worker after processing VerilatedThreadQueue 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 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 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); diff --git a/include/verilated_trace_imp.cpp b/include/verilated_trace_imp.cpp index acbf0d4e9..26e0bf63a 100644 --- a/include/verilated_trace_imp.cpp +++ b/include/verilated_trace_imp.cpp @@ -282,6 +282,7 @@ template <> void VerilatedTrace::onExit(void* selfp) { template <> VerilatedTrace::VerilatedTrace() : m_sigs_oldvalp{nullptr} + , m_sigs_enabledp{nullptr} , m_timeLastDump{0} , m_fullDump{true} , m_nextCode{0} @@ -302,6 +303,7 @@ VerilatedTrace::VerilatedTrace() template <> VerilatedTrace::~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::onFlush, this); Verilated::removeExitCb(VerilatedTrace::onExit, this); #ifdef VL_TRACE_THREADED @@ -320,9 +322,10 @@ template <> void VerilatedTrace::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::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 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::onFlush, this); Verilated::addExitCb(VerilatedTrace::onExit, this); @@ -356,10 +376,38 @@ template <> void VerilatedTrace::traceInit() VL_MT_UNSAFE { } template <> -void VerilatedTrace::declCode(vluint32_t code, vluint32_t bits, bool tri) { +bool VerilatedTrace::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::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::set_time_resolution(const std::string& unit) VL_MT_SAFE { set_time_resolution(unit.c_str()); } +template <> +void VerilatedTrace::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::dump(vluint64_t timeui) VL_MT_SAFE_EXCLUDES(m_mutex) { @@ -523,44 +585,58 @@ template <> void VerilatedTrace::popNamePrefix(unsigned count) { // the emit* functions can be inlined for performance. template <> void VerilatedTrace::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::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::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::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::fullQData(vluint32_t* oldp, QData newval, int bits) { + const uint32_t code = oldp - m_sigs_oldvalp; *reinterpret_cast(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::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::fullDouble(vluint32_t* oldp, double newval) { - // cppcheck-suppress invalidPointerCast + const uint32_t code = oldp - m_sigs_oldvalp; *reinterpret_cast(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); } //========================================================================= diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index d299f2001..cba693d3b 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -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::declCode(code, bits, tri); + const bool enabled = VerilatedTrace::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 diff --git a/include/verilated_vcd_c.h b/include/verilated_vcd_c.h index 1cf9601de..8595baba3 100644 --- a/include/verilated_vcd_c.h +++ b/include/verilated_vcd_c.h @@ -328,6 +328,7 @@ template <> void VerilatedTrace::set_time_unit(const char* unitp); template <> void VerilatedTrace::set_time_unit(const std::string& unit); template <> void VerilatedTrace::set_time_resolution(const char* unitp); template <> void VerilatedTrace::set_time_resolution(const std::string& unit); +template <> void VerilatedTrace::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; } diff --git a/include/verilatedos.h b/include/verilatedos.h index bf1731a34..af7742388 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -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 diff --git a/test_regress/t/t_trace_dumpvars_dyn.cpp b/test_regress/t/t_trace_dumpvars_dyn.cpp new file mode 100644 index 000000000..f5d5f986e --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn.cpp @@ -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 +#include +#include +#include + +#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 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 tfp{new VerilatedVcdC}; +#elif defined(T_TRACE_DUMPVARS_DYN_FST_0) || defined(T_TRACE_DUMPVARS_DYN_FST_1) + std::unique_ptr 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; +} diff --git a/test_regress/t/t_trace_dumpvars_dyn.v b/test_regress/t/t_trace_dumpvars_dyn.v new file mode 100644 index 000000000..dfeaa16dd --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn.v @@ -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 diff --git a/test_regress/t/t_trace_dumpvars_dyn_fst_0.out b/test_regress/t/t_trace_dumpvars_dyn_fst_0.out new file mode 100644 index 000000000..e3d5eaaf3 --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_fst_0.out @@ -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! diff --git a/test_regress/t/t_trace_dumpvars_dyn_fst_0.pl b/test_regress/t/t_trace_dumpvars_dyn_fst_0.pl new file mode 100755 index 000000000..2e62f1f44 --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_fst_0.pl @@ -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; diff --git a/test_regress/t/t_trace_dumpvars_dyn_fst_1.out b/test_regress/t/t_trace_dumpvars_dyn_fst_1.out new file mode 100644 index 000000000..1a5eae60b --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_fst_1.out @@ -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 diff --git a/test_regress/t/t_trace_dumpvars_dyn_fst_1.pl b/test_regress/t/t_trace_dumpvars_dyn_fst_1.pl new file mode 100755 index 000000000..2e62f1f44 --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_fst_1.pl @@ -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; diff --git a/test_regress/t/t_trace_dumpvars_dyn_vcd_0.out b/test_regress/t/t_trace_dumpvars_dyn_vcd_0.out new file mode 100644 index 000000000..c19393619 --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_vcd_0.out @@ -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, diff --git a/test_regress/t/t_trace_dumpvars_dyn_vcd_0.pl b/test_regress/t/t_trace_dumpvars_dyn_vcd_0.pl new file mode 100755 index 000000000..31354ab6a --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_vcd_0.pl @@ -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; diff --git a/test_regress/t/t_trace_dumpvars_dyn_vcd_1.out b/test_regress/t/t_trace_dumpvars_dyn_vcd_1.out new file mode 100644 index 000000000..dd46b59b0 --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_vcd_1.out @@ -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 diff --git a/test_regress/t/t_trace_dumpvars_dyn_vcd_1.pl b/test_regress/t/t_trace_dumpvars_dyn_vcd_1.pl new file mode 100755 index 000000000..70ccefe3c --- /dev/null +++ b/test_regress/t/t_trace_dumpvars_dyn_vcd_1.pl @@ -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;