Commentary

This commit is contained in:
Wilson Snyder 2021-03-07 08:28:13 -05:00
parent 8c3ad591ae
commit caa9c99837
16 changed files with 133 additions and 117 deletions

View File

@ -2037,9 +2037,8 @@ This is an example similar to the above, but using SystemC.
#include "Vour.h" #include "Vour.h"
int sc_main(int argc, char** argv) { int sc_main(int argc, char** argv) {
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
sc_clock clk("clk", 10, SC_NS, 0.5, 3, SC_NS, true); sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true};
Vour* top; Vour* top = new Vour{"top"};
top = new Vour("top");
top->clk(clk); top->clk(clk);
while (!Verilated::gotFinish()) { sc_start(1, SC_NS); } while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
delete top; delete top;

View File

@ -395,23 +395,19 @@ but is maintained to build successfully with C++14/C++17/C++20.
We will work with contributors to fix up indentation style issues, but it We will work with contributors to fix up indentation style issues, but it
is appreciated if you could match our style: is appreciated if you could match our style:
* All files should contain the magic header to ensure standard indentation:
+
// -*- mode: C++; c-file-style: "cc-mode" -*-
+
This sets indentation to the `cc-mode` defaults. (Verilator predates a
CC-mode change of several years ago which overrides the defaults with GNU
style indentation; the `c-set-style` undoes that.)
* Use "mixedCapsSymbols" instead of "underlined_symbols". * Use "mixedCapsSymbols" instead of "underlined_symbols".
* Uas a "p" suffix on variables that are pointers, e.g. "nodep". * Uas a "p" suffix on variables that are pointers, e.g. "nodep".
* Comment every member variable. * Comment every member variable.
Indentation is automatically maintained with "make format" using * In the include directory, use /// to document functions the user calls.
clang-format version 10.0.0, and yapf for python, and is automatically (This convention has not been applied retroactively.)
corrected in the CI actions. For those manually formatting C++ code:
C++ and Python indentation is automatically maintained with "make format"
using clang-format version 10.0.0, and yapf for python, and is
automatically corrected in the CI actions. For those manually formatting
C++ code:
* Use 4 spaces per level, and no tabs. * Use 4 spaces per level, and no tabs.

View File

@ -26,7 +26,7 @@ int sc_main(int argc, char* argv[]) {
if (false && argc && argv) {} if (false && argc && argv) {}
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v" // Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop("top"); Vtop* top = new Vtop{"top"};
// Initialize SC model // Initialize SC model
sc_start(1, SC_NS); sc_start(1, SC_NS);

View File

@ -27,12 +27,15 @@ int main(int argc, char** argv, char** env) {
// Prevent unused variable warnings // Prevent unused variable warnings
if (false && argc && argv && env) {} if (false && argc && argv && env) {}
// Create logs/ directory in case we have traces to put under it
Verilated::mkdir("logs");
// Set debug level, 0 is off, 9 is highest presently used // Set debug level, 0 is off, 9 is highest presently used
// May be overridden by commandArgs // May be overridden by commandArgs argument parsing
Verilated::debug(0); Verilated::debug(0);
// Randomization reset policy // Randomization reset policy
// May be overridden by commandArgs // May be overridden by commandArgs argument parsing
Verilated::randReset(2); Verilated::randReset(2);
// Verilator must compute traced signals // Verilator must compute traced signals
@ -42,14 +45,12 @@ int main(int argc, char** argv, char** env) {
// This needs to be called before you create any model // This needs to be called before you create any model
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
// Create logs/ directory in case we have traces to put under it // Construct the Verilated model, from Vtop.h generated from Verilating "top.v".
Verilated::mkdir("logs"); // Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end.
// "TOP" will be the hierarchical name of the module.
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
// Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end
const std::unique_ptr<Vtop> top{new Vtop}; const std::unique_ptr<Vtop> top{new Vtop};
// Set some inputs // Set Vtop's input signals
top->reset_l = !0; top->reset_l = !0;
top->clk = 0; top->clk = 0;
top->in_small = 1; top->in_small = 1;
@ -82,7 +83,7 @@ int main(int argc, char** argv, char** env) {
// Evaluate model // Evaluate model
// (If you have multiple models being simulated in the same // (If you have multiple models being simulated in the same
// timestep then instead of eval(), call eval_step() on each, then // timestep then instead of eval(), call eval_step() on each, then
// eval_end_step() on each.) // eval_end_step() on each. See the manual.)
top->eval(); top->eval();
// Read outputs // Read outputs
@ -95,7 +96,7 @@ int main(int argc, char** argv, char** env) {
// Final model cleanup // Final model cleanup
top->final(); top->final();
// Coverage analysis (since test passed) // Coverage analysis (calling write only after the test is known to pass)
#if VM_COVERAGE #if VM_COVERAGE
Verilated::mkdir("logs"); Verilated::mkdir("logs");
VerilatedCov::write("logs/coverage.dat"); VerilatedCov::write("logs/coverage.dat");

View File

@ -29,21 +29,26 @@ int sc_main(int argc, char* argv[]) {
// Prevent unused variable warnings // Prevent unused variable warnings
if (false && argc && argv) {} if (false && argc && argv) {}
// Create logs/ directory in case we have traces to put under it
Verilated::mkdir("logs");
// Set debug level, 0 is off, 9 is highest presently used // Set debug level, 0 is off, 9 is highest presently used
// May be overridden by commandArgs // May be overridden by commandArgs argument parsing
Verilated::debug(0); Verilated::debug(0);
// Randomization reset policy // Randomization reset policy
// May be overridden by commandArgs // May be overridden by commandArgs argument parsing
Verilated::randReset(2); Verilated::randReset(2);
#if VM_TRACE
// Before any evaluation, need to know to calculate those signals only used for tracing
Verilated::traceEverOn(true);
#endif
// Pass arguments so Verilated code can see them, e.g. $value$plusargs // Pass arguments so Verilated code can see them, e.g. $value$plusargs
// This needs to be called before you create any model // This needs to be called before you create any model
Verilated::commandArgs(argc, argv); Verilated::commandArgs(argc, argv);
// Create logs/ directory in case we have traces to put under it
Verilated::mkdir("logs");
// General logfile // General logfile
ios::sync_with_stdio(); ios::sync_with_stdio();
@ -64,7 +69,7 @@ int sc_main(int argc, char* argv[]) {
// Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end // Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end
const std::unique_ptr<Vtop> top{new Vtop{"top"}}; const std::unique_ptr<Vtop> top{new Vtop{"top"}};
// Attach signals to the model // Attach Vtop's signals to this upper model
top->clk(clk); top->clk(clk);
top->fastclk(fastclk); top->fastclk(fastclk);
top->reset_l(reset_l); top->reset_l(reset_l);
@ -75,11 +80,6 @@ int sc_main(int argc, char* argv[]) {
top->out_quad(out_quad); top->out_quad(out_quad);
top->out_wide(out_wide); top->out_wide(out_wide);
#if VM_TRACE
// Before any evaluation, need to know to calculate those signals only used for tracing
Verilated::traceEverOn(true);
#endif
// You must do one evaluation before enabling waves, in order to allow // You must do one evaluation before enabling waves, in order to allow
// SystemC to interconnect everything for testing. // SystemC to interconnect everything for testing.
sc_start(1, SC_NS); sc_start(1, SC_NS);
@ -128,7 +128,7 @@ int sc_main(int argc, char* argv[]) {
} }
#endif #endif
// Coverage analysis (since test passed) // Coverage analysis (calling write only after the test is known to pass)
#if VM_COVERAGE #if VM_COVERAGE
Verilated::mkdir("logs"); Verilated::mkdir("logs");
VerilatedCov::write("logs/coverage.dat"); VerilatedCov::write("logs/coverage.dat");

View File

@ -122,7 +122,7 @@ enum VerilatedVarFlags {
}; };
//========================================================================= //=========================================================================
/// Mutex and threading support // Mutex and threading support
/// Return current thread ID (or 0), not super fast, cache if needed /// Return current thread ID (or 0), not super fast, cache if needed
extern vluint32_t VL_THREAD_ID() VL_MT_SAFE; extern vluint32_t VL_THREAD_ID() VL_MT_SAFE;
@ -135,7 +135,9 @@ extern vluint32_t VL_THREAD_ID() VL_MT_SAFE;
class VL_CAPABILITY("mutex") VerilatedMutex final { class VL_CAPABILITY("mutex") VerilatedMutex final {
private: private:
std::mutex m_mutex; // Mutex std::mutex m_mutex; // Mutex
public: public:
/// Construct mutex (without locking it)
VerilatedMutex() = default; VerilatedMutex() = default;
~VerilatedMutex() = default; ~VerilatedMutex() = default;
const VerilatedMutex& operator!() const { return *this; } // For -fthread_safety const VerilatedMutex& operator!() const { return *this; } // For -fthread_safety
@ -165,25 +167,29 @@ private:
VerilatedMutex& m_mutexr; VerilatedMutex& m_mutexr;
public: public:
/// Construct and hold given mutex lock until destruction or unlock()
explicit VerilatedLockGuard(VerilatedMutex& mutexr) VL_ACQUIRE(mutexr) explicit VerilatedLockGuard(VerilatedMutex& mutexr) VL_ACQUIRE(mutexr)
: m_mutexr(mutexr) { // Need () or GCC 4.8 false warning : m_mutexr(mutexr) { // Need () or GCC 4.8 false warning
m_mutexr.lock(); m_mutexr.lock();
} }
/// Destruct and unlock the mutex
~VerilatedLockGuard() VL_RELEASE() { m_mutexr.unlock(); } ~VerilatedLockGuard() VL_RELEASE() { m_mutexr.unlock(); }
/// Unlock the mutex
void lock() VL_ACQUIRE() { m_mutexr.lock(); } void lock() VL_ACQUIRE() { m_mutexr.lock(); }
/// Lock the mutex
void unlock() VL_RELEASE() { m_mutexr.unlock(); } void unlock() VL_RELEASE() { m_mutexr.unlock(); }
}; };
#else // !VL_THREADED #else // !VL_THREADED
/// Empty non-threaded mutex to avoid #ifdefs in consuming code // Empty non-threaded mutex to avoid #ifdefs in consuming code
class VerilatedMutex final { class VerilatedMutex final {
public: public:
void lock() {} void lock() {}
void unlock() {} void unlock() {}
}; };
/// Empty non-threaded lock guard to avoid #ifdefs in consuming code // Empty non-threaded lock guard to avoid #ifdefs in consuming code
class VerilatedLockGuard final { class VerilatedLockGuard final {
VL_UNCOPYABLE(VerilatedLockGuard); VL_UNCOPYABLE(VerilatedLockGuard);
@ -196,20 +202,22 @@ public:
#endif // VL_THREADED #endif // VL_THREADED
/// Remember the calling thread at construction time, and make sure later calls use same thread // Internals: Remember the calling thread at construction time, and make
// sure later calls use same thread
class VerilatedAssertOneThread final { class VerilatedAssertOneThread final {
// MEMBERS // MEMBERS
#if defined(VL_THREADED) && defined(VL_DEBUG) #if defined(VL_THREADED) && defined(VL_DEBUG)
vluint32_t m_threadid; /// Thread that is legal vluint32_t m_threadid; /// Thread that is legal
public: public:
// CONSTRUCTORS // CONSTRUCTORS
/// The constructor establishes the thread id for all later calls. // The constructor establishes the thread id for all later calls.
/// If necessary, a different class could be made that inits it otherwise. // If necessary, a different class could be made that inits it otherwise.
VerilatedAssertOneThread() VerilatedAssertOneThread()
: m_threadid{VL_THREAD_ID()} {} : m_threadid{VL_THREAD_ID()} {}
~VerilatedAssertOneThread() { check(); } ~VerilatedAssertOneThread() { check(); }
// METHODS // METHODS
/// Check that the current thread ID is the same as the construction thread ID // Check that the current thread ID is the same as the construction thread ID
void check() VL_MT_UNSAFE_ONE { void check() VL_MT_UNSAFE_ONE {
if (VL_UNCOVERABLE(m_threadid != VL_THREAD_ID())) { if (VL_UNCOVERABLE(m_threadid != VL_THREAD_ID())) {
if (m_threadid == 0) { if (m_threadid == 0) {
@ -495,16 +503,20 @@ public:
static const char* profThreadsFilenamep() VL_MT_SAFE { return s_ns.s_profThreadsFilenamep; } static const char* profThreadsFilenamep() VL_MT_SAFE { return s_ns.s_profThreadsFilenamep; }
typedef void (*VoidPCb)(void*); // Callback type for below typedef void (*VoidPCb)(void*); // Callback type for below
/// Callbacks to run on global flush /// Add callback to run on global flush
static void addFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE; static void addFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE;
/// Remove callback to run on global flush
static void removeFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE; static void removeFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE;
/// Run flush callbacks registered with addFlushCb
static void runFlushCallbacks() VL_MT_SAFE; static void runFlushCallbacks() VL_MT_SAFE;
#ifndef VL_NO_LEGACY #ifndef VL_NO_LEGACY
static void flushCall() VL_MT_SAFE { runFlushCallbacks(); } // Deprecated static void flushCall() VL_MT_SAFE { runFlushCallbacks(); } // Deprecated
#endif #endif
/// Callbacks to run prior to termination /// Add callback to run prior to exit termination
static void addExitCb(VoidPCb cb, void* datap) VL_MT_SAFE; static void addExitCb(VoidPCb cb, void* datap) VL_MT_SAFE;
/// Remove callback to run prior to exit termination
static void removeExitCb(VoidPCb cb, void* datap) VL_MT_SAFE; static void removeExitCb(VoidPCb cb, void* datap) VL_MT_SAFE;
/// Run exit callbacks registered with addExitCb
static void runExitCallbacks() VL_MT_SAFE; static void runExitCallbacks() VL_MT_SAFE;
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs, /// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs,
@ -519,11 +531,12 @@ public:
/// Match plusargs with a given prefix. Returns static char* valid only for a single call /// Match plusargs with a given prefix. Returns static char* valid only for a single call
static const char* commandArgsPlusMatch(const char* prefixp) VL_MT_SAFE; static const char* commandArgsPlusMatch(const char* prefixp) VL_MT_SAFE;
/// Produce name & version for (at least) VPI /// Return product name for (at least) VPI
static const char* productName() VL_PURE; static const char* productName() VL_PURE;
/// Return product version for (at least) VPI
static const char* productVersion() VL_PURE; static const char* productVersion() VL_PURE;
/// Convenience OS utilities /// Call OS to make a directory
static void mkdir(const char* dirname) VL_MT_UNSAFE; static void mkdir(const char* dirname) VL_MT_UNSAFE;
/// When multithreaded, quiesce the model to prepare for trace/saves/coverage /// When multithreaded, quiesce the model to prepare for trace/saves/coverage
@ -575,17 +588,17 @@ public:
static size_t serialized2Size() VL_PURE; static size_t serialized2Size() VL_PURE;
static void* serialized2Ptr() VL_MT_UNSAFE; static void* serialized2Ptr() VL_MT_UNSAFE;
#ifdef VL_THREADED #ifdef VL_THREADED
/// Internal: Set the mtaskId, called when an mtask starts // Internal: Set the mtaskId, called when an mtask starts
static void mtaskId(vluint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; } static void mtaskId(vluint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
static vluint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; } static vluint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; } static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; }
static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; } static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; }
/// Internal: Called at end of each thread mtask, before finishing eval // Internal: Called at end of each thread mtask, before finishing eval
static void endOfThreadMTask(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE { static void endOfThreadMTask(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) endOfThreadMTaskGuts(evalMsgQp); if (VL_UNLIKELY(t_s.t_endOfEvalReqd)) endOfThreadMTaskGuts(evalMsgQp);
} }
/// Internal: Called at end of eval loop // Internal: Called at end of eval loop
static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE; static void endOfEval(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE;
#endif #endif
@ -604,7 +617,7 @@ private:
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
extern void vl_finish(const char* filename, int linenum, const char* hier); extern void vl_finish(const char* filename, int linenum, const char* hier);
/// Routine to call for $stop /// Routine to call for $stop and non-fatal error
/// User code may wish to replace this function, to do so, define VL_USER_STOP. /// User code may wish to replace this function, to do so, define VL_USER_STOP.
/// This code does not have to be thread safe. /// This code does not have to be thread safe.
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this. /// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.

View File

@ -32,7 +32,7 @@
//=================================================================== //===================================================================
// SETTING OPERATORS // SETTING OPERATORS
/// Convert svBitVecVal to Verilator internal data // Convert svBitVecVal to Verilator internal data
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, const svBitVecVal* lwp) VL_MT_SAFE { static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, const svBitVecVal* lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits); int words = VL_WORDS_I(obits);
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i]; for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i];
@ -43,7 +43,7 @@ static inline QData VL_SET_Q_SVBV(const svBitVecVal* lwp) VL_MT_SAFE {
} }
static inline IData VL_SET_I_SVBV(const svBitVecVal* lwp) VL_MT_SAFE { return lwp[0]; } static inline IData VL_SET_I_SVBV(const svBitVecVal* lwp) VL_MT_SAFE { return lwp[0]; }
/// Convert Verilator internal data to svBitVecVal // Convert Verilator internal data to svBitVecVal
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) VL_MT_SAFE { static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits); int words = VL_WORDS_I(obits);
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i]; for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i];
@ -54,8 +54,8 @@ static inline void VL_SET_SVBV_Q(int, svBitVecVal* owp, QData ld) VL_MT_SAFE {
VL_SET_WQ(owp, ld); VL_SET_WQ(owp, ld);
} }
/// Convert svLogicVecVal to Verilator internal data // Convert svLogicVecVal to Verilator internal data
/// Note these functions ignore X/Z in svLogicVecVal // Note these functions ignore X/Z in svLogicVecVal
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, const svLogicVecVal* lwp) VL_MT_SAFE { static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, const svLogicVecVal* lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits); int words = VL_WORDS_I(obits);
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i].aval; for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i].aval;
@ -66,8 +66,8 @@ static inline QData VL_SET_Q_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
} }
static inline IData VL_SET_I_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE { return lwp[0].aval; } static inline IData VL_SET_I_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE { return lwp[0].aval; }
/// Convert Verilator internal data to svLogicVecVal // Convert Verilator internal data to svLogicVecVal
/// Note these functions never create X/Z in svLogicVecVal // Note these functions never create X/Z in svLogicVecVal
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) VL_MT_SAFE { static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits); int words = VL_WORDS_I(obits);
for (int i = 0; i < words; ++i) owp[i].bval = 0; for (int i = 0; i < words; ++i) owp[i].bval = 0;

View File

@ -15,7 +15,6 @@
/// \brief C++ Tracing in FST Format /// \brief C++ Tracing in FST Format
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
// clang-format off // clang-format off

View File

@ -15,7 +15,6 @@
/// \brief C++ Tracing in FST Format /// \brief C++ Tracing in FST Format
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
#ifndef VERILATOR_VERILATED_FST_C_H_ #ifndef VERILATOR_VERILATED_FST_C_H_
#define VERILATOR_VERILATED_FST_C_H_ #define VERILATOR_VERILATED_FST_C_H_
@ -32,8 +31,8 @@
//============================================================================= //=============================================================================
// VerilatedFst // VerilatedFst
/// Base class to create a Verilator FST dump // Base class to create a Verilator FST dump
/// This is an internally used class - see VerilatedFstC for what to call from applications // This is an internally used class - see VerilatedFstC for what to call from applications
class VerilatedFst final : public VerilatedTrace<VerilatedFst> { class VerilatedFst final : public VerilatedTrace<VerilatedFst> {
private: private:
@ -86,23 +85,23 @@ public:
explicit VerilatedFst(void* fst = nullptr); explicit VerilatedFst(void* fst = nullptr);
~VerilatedFst(); ~VerilatedFst();
/// Open the file; call isOpen() to see if errors // Open the file; call isOpen() to see if errors
void open(const char* filename) VL_MT_UNSAFE; void open(const char* filename) VL_MT_UNSAFE;
/// Close the file // Close the file
void close() VL_MT_UNSAFE; void close() VL_MT_UNSAFE;
/// Flush any remaining data to this file // Flush any remaining data to this file
void flush() VL_MT_UNSAFE; void flush() VL_MT_UNSAFE;
/// Is file open? // Return if file is open
bool isOpen() const { return m_fst != nullptr; } bool isOpen() const { return m_fst != nullptr; }
//========================================================================= //=========================================================================
// Internal interface to Verilator generated code // Internal interface to Verilator generated code
/// Inside dumping routines, declare a data type // Inside dumping routines, declare a data type
void declDTypeEnum(int dtypenum, const char* name, vluint32_t elements, void declDTypeEnum(int dtypenum, const char* name, vluint32_t elements,
unsigned int minValbits, const char** itemNamesp, const char** itemValuesp); unsigned int minValbits, const char** itemNamesp, const char** itemValuesp);
/// Inside dumping routines, declare a signal // Inside dumping routines, declare a signal
void declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, void declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
fstVarType vartype, bool array, int arraynum); fstVarType vartype, bool array, int arraynum);
void declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir, void declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
@ -135,16 +134,18 @@ class VerilatedFstC final {
VL_UNCOPYABLE(VerilatedFstC); VL_UNCOPYABLE(VerilatedFstC);
public: public:
/// Construct the dump. Optional argument is ignored.
explicit VerilatedFstC(void* filep = nullptr) explicit VerilatedFstC(void* filep = nullptr)
: m_sptrace{filep} {} : m_sptrace{filep} {}
/// Destruct, flush, and close the dump
~VerilatedFstC() { close(); } ~VerilatedFstC() { close(); }
/// Routines can only be called from one thread; allow next call from different thread /// Routines can only be called from one thread; allow next call from different thread
void changeThread() { spTrace()->changeThread(); } void changeThread() { spTrace()->changeThread(); }
// ACCESSORS // METHODS - User called
/// Is file open?
/// Return if file is open
bool isOpen() const { return m_sptrace.isOpen(); } bool isOpen() const { return m_sptrace.isOpen(); }
// METHODS
/// Open a new FST file /// Open a new FST file
void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); } void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); }
/// Close dump /// Close dump
@ -158,16 +159,22 @@ public:
void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); } void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); } void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); } void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
/// Set time units (s/ms, defaults to ns)
/// For Verilated models, these propage from the Verilated default --timeunit // METHODS - Internal/backward compatible
// \protectedsection
// Set time units (s/ms, defaults to ns)
// Users should not need to call this, as for Verilated models, these
// propage from the Verilated default timeunit
void set_time_unit(const char* unitp) { m_sptrace.set_time_unit(unitp); } void set_time_unit(const char* unitp) { m_sptrace.set_time_unit(unitp); }
void set_time_unit(const std::string& unit) { m_sptrace.set_time_unit(unit); } void set_time_unit(const std::string& unit) { m_sptrace.set_time_unit(unit); }
/// Set time resolution (s/ms, defaults to ns) // Set time resolution (s/ms, defaults to ns)
/// For Verilated models, these propage from the Verilated default --timeunit // Users should not need to call this, as for Verilated models, these
// propage from the Verilated default timeprecision
void set_time_resolution(const char* unitp) { m_sptrace.set_time_resolution(unitp); } void set_time_resolution(const char* unitp) { m_sptrace.set_time_resolution(unitp); }
void set_time_resolution(const std::string& unit) { m_sptrace.set_time_resolution(unit); } void set_time_resolution(const std::string& unit) { m_sptrace.set_time_resolution(unit); }
/// Internal class access // Internal class access
inline VerilatedFst* spTrace() { return &m_sptrace; }; inline VerilatedFst* spTrace() { return &m_sptrace; };
}; };

View File

@ -12,10 +12,9 @@
//============================================================================= //=============================================================================
/// ///
/// \file /// \file
/// \brief Tracing functionality common to all formats /// \brief Internal tracing functionality common to all formats
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
#ifndef VERILATOR_VERILATED_TRACE_H_ #ifndef VERILATOR_VERILATED_TRACE_H_
#define VERILATOR_VERILATED_TRACE_H_ #define VERILATOR_VERILATED_TRACE_H_
@ -221,9 +220,9 @@ protected:
void declCode(vluint32_t code, vluint32_t bits, bool tri); void declCode(vluint32_t code, vluint32_t bits, bool tri);
/// Is this an escape? // Is this an escape?
bool isScopeEscape(char c) { return c != '\f' && (isspace(c) || c == m_scopeEscape); } bool isScopeEscape(char c) { return c != '\f' && (isspace(c) || c == m_scopeEscape); }
/// Character that splits scopes. Note whitespace are ALWAYS escapes. // Character that splits scopes. Note whitespace are ALWAYS escapes.
char scopeEscape() { return m_scopeEscape; } char scopeEscape() { return m_scopeEscape; }
void close(); void close();

View File

@ -15,7 +15,6 @@
/// \brief Implementation of tracing functionality common to all trace formats /// \brief Implementation of tracing functionality common to all trace formats
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
// clang-format off // clang-format off

View File

@ -15,7 +15,6 @@
/// \brief C++ Tracing in VCD Format /// \brief C++ Tracing in VCD Format
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
// clang-format off // clang-format off
@ -34,8 +33,6 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
// SPDIFF_ON
#ifndef O_LARGEFILE // For example on WIN32 #ifndef O_LARGEFILE // For example on WIN32
# define O_LARGEFILE 0 # define O_LARGEFILE 0
#endif #endif

View File

@ -15,7 +15,6 @@
/// \brief C++ Tracing in VCD Format /// \brief C++ Tracing in VCD Format
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
#ifndef VERILATOR_VERILATED_VCD_C_H_ #ifndef VERILATOR_VERILATED_VCD_C_H_
#define VERILATOR_VERILATED_VCD_C_H_ #define VERILATOR_VERILATED_VCD_C_H_
@ -29,7 +28,6 @@
class VerilatedVcd; class VerilatedVcd;
// SPDIFF_ON
//============================================================================= //=============================================================================
// VerilatedFile // VerilatedFile
/// File handling routines, which can be overrode for e.g. socket I/O /// File handling routines, which can be overrode for e.g. socket I/O
@ -48,8 +46,8 @@ public:
//============================================================================= //=============================================================================
// VerilatedVcd // VerilatedVcd
/// Base class to create a Verilator VCD dump // Base class to create a Verilator VCD dump
/// This is an internally used class - see VerilatedVcdC for what to call from applications // This is an internally used class - see VerilatedVcdC for what to call from applications
class VerilatedVcd VL_NOT_FINAL : public VerilatedTrace<VerilatedVcd> { class VerilatedVcd VL_NOT_FINAL : public VerilatedTrace<VerilatedVcd> {
private: private:
@ -136,19 +134,19 @@ public:
~VerilatedVcd(); ~VerilatedVcd();
// ACCESSORS // ACCESSORS
/// Set size in megabytes after which new file should be created // Set size in megabytes after which new file should be created
void rolloverMB(vluint64_t rolloverMB) { m_rolloverMB = rolloverMB; } void rolloverMB(vluint64_t rolloverMB) { m_rolloverMB = rolloverMB; }
// METHODS // METHODS
/// Open the file; call isOpen() to see if errors // Open the file; call isOpen() to see if errors
void open(const char* filename) VL_MT_UNSAFE_ONE; void open(const char* filename) VL_MT_UNSAFE_ONE;
/// Open next data-only file // Open next data-only file
void openNext(bool incFilename) VL_MT_UNSAFE_ONE; void openNext(bool incFilename) VL_MT_UNSAFE_ONE;
/// Close the file // Close the file
void close() VL_MT_UNSAFE_ONE; void close() VL_MT_UNSAFE_ONE;
/// Flush any remaining data to this file // Flush any remaining data to this file
void flush() VL_MT_UNSAFE_ONE; void flush() VL_MT_UNSAFE_ONE;
/// Is file open? // Return if file is open
bool isOpen() const { return m_isOpen; } bool isOpen() const { return m_isOpen; }
//========================================================================= //=========================================================================
@ -211,8 +209,8 @@ public:
chgDouble(oldp - this->oldp(0), newval); chgDouble(oldp - this->oldp(0), newval);
} }
/// Inside dumping routines, dump one signal, faster when not inlined // Inside dumping routines, dump one signal, faster when not inlined
/// due to code size reduction. // due to code size reduction.
void fullBit(vluint32_t code, const vluint32_t newval); void fullBit(vluint32_t code, const vluint32_t newval);
void fullBus(vluint32_t code, const vluint32_t newval, int bits); void fullBus(vluint32_t code, const vluint32_t newval, int bits);
void fullQuad(vluint32_t code, const vluint64_t newval, int bits); void fullQuad(vluint32_t code, const vluint64_t newval, int bits);
@ -225,8 +223,8 @@ public:
int bits); int bits);
void fullDouble(vluint32_t code, const double newval); void fullDouble(vluint32_t code, const double newval);
/// Inside dumping routines, dump one signal if it has changed. // Inside dumping routines, dump one signal if it has changed.
/// We do want to inline these to avoid calls when the value did not change. // We do want to inline these to avoid calls when the value did not change.
inline void chgBit(vluint32_t code, const vluint32_t newval) { inline void chgBit(vluint32_t code, const vluint32_t newval) {
vluint32_t diff = oldp(code)[0] ^ newval; vluint32_t diff = oldp(code)[0] ^ newval;
if (VL_UNLIKELY(diff)) fullBit(code, newval); if (VL_UNLIKELY(diff)) fullBit(code, newval);
@ -336,17 +334,19 @@ class VerilatedVcdC VL_NOT_FINAL {
VL_UNCOPYABLE(VerilatedVcdC); VL_UNCOPYABLE(VerilatedVcdC);
public: public:
/// Construct the dump. Optional argument is a preconstructed file.
explicit VerilatedVcdC(VerilatedVcdFile* filep = nullptr) explicit VerilatedVcdC(VerilatedVcdFile* filep = nullptr)
: m_sptrace{filep} {} : m_sptrace{filep} {}
/// Destruct, flush, and close the dump
~VerilatedVcdC() { close(); } ~VerilatedVcdC() { close(); }
/// Routines can only be called from one thread; allow next call from different thread /// Routines can only be called from one thread; allow next call from different thread
void changeThread() { spTrace()->changeThread(); } void changeThread() { spTrace()->changeThread(); }
public: public:
// ACCESSORS // METHODS - User called
/// Is file open?
/// Return if file is open
bool isOpen() const { return m_sptrace.isOpen(); } bool isOpen() const { return m_sptrace.isOpen(); }
// METHODS
/// Open a new VCD file /// Open a new VCD file
/// This includes a complete header dump each time it is called, /// This includes a complete header dump each time it is called,
/// just as if this object was deleted and reconstructed. /// just as if this object was deleted and reconstructed.
@ -368,16 +368,22 @@ public:
void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); } void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); } void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); } void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
/// Set time units (s/ms, defaults to ns)
/// For Verilated models, these propage from the Verilated default --timeunit // METHODS - Internal/backward compatible
// \protectedsection
// Set time units (s/ms, defaults to ns)
// Users should not need to call this, as for Verilated models, these
// propage from the Verilated default timeunit
void set_time_unit(const char* unit) { m_sptrace.set_time_unit(unit); } void set_time_unit(const char* unit) { m_sptrace.set_time_unit(unit); }
void set_time_unit(const std::string& unit) { m_sptrace.set_time_unit(unit); } void set_time_unit(const std::string& unit) { m_sptrace.set_time_unit(unit); }
/// Set time resolution (s/ms, defaults to ns) // Set time resolution (s/ms, defaults to ns)
/// For Verilated models, these propage from the Verilated default --timeunit // Users should not need to call this, as for Verilated models, these
// propage from the Verilated default timeprecision
void set_time_resolution(const char* unit) { m_sptrace.set_time_resolution(unit); } void set_time_resolution(const char* unit) { m_sptrace.set_time_resolution(unit); }
void set_time_resolution(const std::string& unit) { m_sptrace.set_time_resolution(unit); } void set_time_resolution(const std::string& unit) { m_sptrace.set_time_resolution(unit); }
/// Internal class access // Internal class access
inline VerilatedVcd* spTrace() { return &m_sptrace; } inline VerilatedVcd* spTrace() { return &m_sptrace; }
#ifdef VL_TRACE_VCD_OLD_API #ifdef VL_TRACE_VCD_OLD_API
@ -385,7 +391,8 @@ public:
// Note: These are only for testing for backward compatibility with foreign // Note: These are only for testing for backward compatibility with foreign
// code and is not used by Verilator. Do not use these as there is no // code and is not used by Verilator. Do not use these as there is no
// guarantee of functionality. // guarantee of functionality.
/// Use evcd format
// Use evcd format
void evcd(bool flag) VL_MT_UNSAFE_ONE { m_sptrace.evcd(flag); } void evcd(bool flag) VL_MT_UNSAFE_ONE { m_sptrace.evcd(flag); }
#endif #endif
}; };

View File

@ -15,12 +15,10 @@
/// \brief Verilator tracing in VCD Format /// \brief Verilator tracing in VCD Format
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
#include "verilatedos.h" #include "verilatedos.h"
#include "verilated_vcd_sc.h" #include "verilated_vcd_sc.h"
// SPDIFF_ON
//====================================================================== //======================================================================
//====================================================================== //======================================================================

View File

@ -15,7 +15,6 @@
/// This class is not threadsafe, as the SystemC kernel is not threadsafe. /// This class is not threadsafe, as the SystemC kernel is not threadsafe.
/// ///
//============================================================================= //=============================================================================
// SPDIFF_OFF
#ifndef VERILATOR_VERILATED_VCD_SC_H_ #ifndef VERILATOR_VERILATED_VCD_SC_H_
#define VERILATOR_VERILATED_VCD_SC_H_ #define VERILATOR_VERILATED_VCD_SC_H_
@ -24,18 +23,18 @@
#include "verilated_sc.h" #include "verilated_sc.h"
#include "verilated_vcd_c.h" #include "verilated_vcd_c.h"
// SPDIFF_ON
//============================================================================= //=============================================================================
// VerilatedVcdSc // VerilatedVcdSc
/// ///
/// This class is passed to the SystemC simulation kernel, just like a /// This class creates a Verilator-friendly VCD trace format with the
/// documented SystemC trace format. /// SystemC simulation kernel, just like a SystemC-documented trace format.
class VerilatedVcdSc final : sc_trace_file, public VerilatedVcdC { class VerilatedVcdSc final : sc_trace_file, public VerilatedVcdC {
// CONSTRUCTORS // CONSTRUCTORS
VL_UNCOPYABLE(VerilatedVcdSc); VL_UNCOPYABLE(VerilatedVcdSc);
public: public:
/// Construct a SC trace object, and register with the SystemC kernel
VerilatedVcdSc() { VerilatedVcdSc() {
sc_get_curr_simcontext()->add_trace_file(this); sc_get_curr_simcontext()->add_trace_file(this);
// We want to avoid a depreciated warning, but still be back compatible. // We want to avoid a depreciated warning, but still be back compatible.
@ -48,16 +47,17 @@ public:
} }
spTrace()->set_time_resolution(sc_get_time_resolution().to_string()); spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
} }
/// Destruct, flush, and close the dump
virtual ~VerilatedVcdSc() { close(); } virtual ~VerilatedVcdSc() { close(); }
// METHODS // METHODS - for SC kernel
/// Called by SystemC simulate() // Called by SystemC simulate()
virtual void cycle(bool delta_cycle) { virtual void cycle(bool delta_cycle) {
if (!delta_cycle) this->dump(sc_time_stamp().to_double()); if (!delta_cycle) this->dump(sc_time_stamp().to_double());
} }
private: private:
/// Fake outs for linker // METHODS - Fake outs for linker
#ifdef NC_SYSTEMC #ifdef NC_SYSTEMC
// Cadence Incisive has these as abstract functions so we must create them // Cadence Incisive has these as abstract functions so we must create them

View File

@ -47,7 +47,8 @@ public:
/// Returns time of the next registered VPI callback, or /// Returns time of the next registered VPI callback, or
/// ~(0) if none are registered /// ~(0) if none are registered
static QData cbNextDeadline() VL_MT_UNSAFE_ONE; static QData cbNextDeadline() VL_MT_UNSAFE_ONE;
/// Self test, for internal use only
// Self test, for internal use only
static void selfTest() VL_MT_UNSAFE_ONE; static void selfTest() VL_MT_UNSAFE_ONE;
}; };