forked from github/verilator
Commentary
This commit is contained in:
parent
8c3ad591ae
commit
caa9c99837
@ -2037,9 +2037,8 @@ This is an example similar to the above, but using SystemC.
|
||||
#include "Vour.h"
|
||||
int sc_main(int argc, char** argv) {
|
||||
Verilated::commandArgs(argc, argv);
|
||||
sc_clock clk("clk", 10, SC_NS, 0.5, 3, SC_NS, true);
|
||||
Vour* top;
|
||||
top = new Vour("top");
|
||||
sc_clock clk{"clk", 10, SC_NS, 0.5, 3, SC_NS, true};
|
||||
Vour* top = new Vour{"top"};
|
||||
top->clk(clk);
|
||||
while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
|
||||
delete top;
|
||||
|
@ -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
|
||||
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".
|
||||
|
||||
* Uas a "p" suffix on variables that are pointers, e.g. "nodep".
|
||||
|
||||
* Comment every member variable.
|
||||
|
||||
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:
|
||||
* In the include directory, use /// to document functions the user calls.
|
||||
(This convention has not been applied retroactively.)
|
||||
|
||||
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.
|
||||
|
||||
|
@ -26,7 +26,7 @@ int sc_main(int argc, char* argv[]) {
|
||||
if (false && argc && argv) {}
|
||||
|
||||
// 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
|
||||
sc_start(1, SC_NS);
|
||||
|
@ -27,12 +27,15 @@ int main(int argc, char** argv, char** env) {
|
||||
// Prevent unused variable warnings
|
||||
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
|
||||
// May be overridden by commandArgs
|
||||
// May be overridden by commandArgs argument parsing
|
||||
Verilated::debug(0);
|
||||
|
||||
// Randomization reset policy
|
||||
// May be overridden by commandArgs
|
||||
// May be overridden by commandArgs argument parsing
|
||||
Verilated::randReset(2);
|
||||
|
||||
// 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
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// Create logs/ directory in case we have traces to put under it
|
||||
Verilated::mkdir("logs");
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
// "TOP" will be the hierarchical name of the module.
|
||||
const std::unique_ptr<Vtop> top{new Vtop};
|
||||
|
||||
// Set some inputs
|
||||
// Set Vtop's input signals
|
||||
top->reset_l = !0;
|
||||
top->clk = 0;
|
||||
top->in_small = 1;
|
||||
@ -82,7 +83,7 @@ int main(int argc, char** argv, char** env) {
|
||||
// Evaluate model
|
||||
// (If you have multiple models being simulated in the same
|
||||
// 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();
|
||||
|
||||
// Read outputs
|
||||
@ -95,7 +96,7 @@ int main(int argc, char** argv, char** env) {
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Coverage analysis (since test passed)
|
||||
// Coverage analysis (calling write only after the test is known to pass)
|
||||
#if VM_COVERAGE
|
||||
Verilated::mkdir("logs");
|
||||
VerilatedCov::write("logs/coverage.dat");
|
||||
|
@ -29,21 +29,26 @@ int sc_main(int argc, char* argv[]) {
|
||||
// Prevent unused variable warnings
|
||||
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
|
||||
// May be overridden by commandArgs
|
||||
// May be overridden by commandArgs argument parsing
|
||||
Verilated::debug(0);
|
||||
|
||||
// Randomization reset policy
|
||||
// May be overridden by commandArgs
|
||||
// May be overridden by commandArgs argument parsing
|
||||
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
|
||||
// This needs to be called before you create any model
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// Create logs/ directory in case we have traces to put under it
|
||||
Verilated::mkdir("logs");
|
||||
|
||||
// General logfile
|
||||
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
|
||||
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->fastclk(fastclk);
|
||||
top->reset_l(reset_l);
|
||||
@ -75,11 +80,6 @@ int sc_main(int argc, char* argv[]) {
|
||||
top->out_quad(out_quad);
|
||||
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
|
||||
// SystemC to interconnect everything for testing.
|
||||
sc_start(1, SC_NS);
|
||||
@ -128,7 +128,7 @@ int sc_main(int argc, char* argv[]) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Coverage analysis (since test passed)
|
||||
// Coverage analysis (calling write only after the test is known to pass)
|
||||
#if VM_COVERAGE
|
||||
Verilated::mkdir("logs");
|
||||
VerilatedCov::write("logs/coverage.dat");
|
||||
|
@ -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
|
||||
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 {
|
||||
private:
|
||||
std::mutex m_mutex; // Mutex
|
||||
|
||||
public:
|
||||
/// Construct mutex (without locking it)
|
||||
VerilatedMutex() = default;
|
||||
~VerilatedMutex() = default;
|
||||
const VerilatedMutex& operator!() const { return *this; } // For -fthread_safety
|
||||
@ -165,25 +167,29 @@ private:
|
||||
VerilatedMutex& m_mutexr;
|
||||
|
||||
public:
|
||||
/// Construct and hold given mutex lock until destruction or unlock()
|
||||
explicit VerilatedLockGuard(VerilatedMutex& mutexr) VL_ACQUIRE(mutexr)
|
||||
: m_mutexr(mutexr) { // Need () or GCC 4.8 false warning
|
||||
m_mutexr.lock();
|
||||
}
|
||||
/// Destruct and unlock the mutex
|
||||
~VerilatedLockGuard() VL_RELEASE() { m_mutexr.unlock(); }
|
||||
/// Unlock the mutex
|
||||
void lock() VL_ACQUIRE() { m_mutexr.lock(); }
|
||||
/// Lock the mutex
|
||||
void unlock() VL_RELEASE() { m_mutexr.unlock(); }
|
||||
};
|
||||
|
||||
#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 {
|
||||
public:
|
||||
void lock() {}
|
||||
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 {
|
||||
VL_UNCOPYABLE(VerilatedLockGuard);
|
||||
|
||||
@ -196,20 +202,22 @@ public:
|
||||
|
||||
#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 {
|
||||
// MEMBERS
|
||||
#if defined(VL_THREADED) && defined(VL_DEBUG)
|
||||
vluint32_t m_threadid; /// Thread that is legal
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
/// The constructor establishes the thread id for all later calls.
|
||||
/// If necessary, a different class could be made that inits it otherwise.
|
||||
// The constructor establishes the thread id for all later calls.
|
||||
// If necessary, a different class could be made that inits it otherwise.
|
||||
VerilatedAssertOneThread()
|
||||
: m_threadid{VL_THREAD_ID()} {}
|
||||
~VerilatedAssertOneThread() { check(); }
|
||||
// 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 {
|
||||
if (VL_UNCOVERABLE(m_threadid != VL_THREAD_ID())) {
|
||||
if (m_threadid == 0) {
|
||||
@ -495,16 +503,20 @@ public:
|
||||
static const char* profThreadsFilenamep() VL_MT_SAFE { return s_ns.s_profThreadsFilenamep; }
|
||||
|
||||
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;
|
||||
/// Remove callback to run on global flush
|
||||
static void removeFlushCb(VoidPCb cb, void* datap) VL_MT_SAFE;
|
||||
/// Run flush callbacks registered with addFlushCb
|
||||
static void runFlushCallbacks() VL_MT_SAFE;
|
||||
#ifndef VL_NO_LEGACY
|
||||
static void flushCall() VL_MT_SAFE { runFlushCallbacks(); } // Deprecated
|
||||
#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;
|
||||
/// Remove callback to run prior to exit termination
|
||||
static void removeExitCb(VoidPCb cb, void* datap) VL_MT_SAFE;
|
||||
/// Run exit callbacks registered with addExitCb
|
||||
static void runExitCallbacks() VL_MT_SAFE;
|
||||
|
||||
/// 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
|
||||
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;
|
||||
/// Return product version for (at least) VPI
|
||||
static const char* productVersion() VL_PURE;
|
||||
|
||||
/// Convenience OS utilities
|
||||
/// Call OS to make a directory
|
||||
static void mkdir(const char* dirname) VL_MT_UNSAFE;
|
||||
|
||||
/// When multithreaded, quiesce the model to prepare for trace/saves/coverage
|
||||
@ -575,17 +588,17 @@ public:
|
||||
static size_t serialized2Size() VL_PURE;
|
||||
static void* serialized2Ptr() VL_MT_UNSAFE;
|
||||
#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 vluint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
|
||||
static void endOfEvalReqdInc() 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 {
|
||||
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;
|
||||
#endif
|
||||
|
||||
@ -604,7 +617,7 @@ private:
|
||||
/// 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);
|
||||
|
||||
/// 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.
|
||||
/// This code does not have to be thread safe.
|
||||
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
||||
|
@ -32,7 +32,7 @@
|
||||
//===================================================================
|
||||
// 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 {
|
||||
int words = VL_WORDS_I(obits);
|
||||
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]; }
|
||||
|
||||
/// 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 {
|
||||
int words = VL_WORDS_I(obits);
|
||||
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);
|
||||
}
|
||||
|
||||
/// Convert svLogicVecVal to Verilator internal data
|
||||
/// Note these functions ignore X/Z in svLogicVecVal
|
||||
// Convert svLogicVecVal to Verilator internal data
|
||||
// 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 {
|
||||
int words = VL_WORDS_I(obits);
|
||||
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; }
|
||||
|
||||
/// Convert Verilator internal data to svLogicVecVal
|
||||
/// Note these functions never create X/Z in svLogicVecVal
|
||||
// Convert Verilator internal data to 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 {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i = 0; i < words; ++i) owp[i].bval = 0;
|
||||
|
@ -15,7 +15,6 @@
|
||||
/// \brief C++ Tracing in FST Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
// clang-format off
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
/// \brief C++ Tracing in FST Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef VERILATOR_VERILATED_FST_C_H_
|
||||
#define VERILATOR_VERILATED_FST_C_H_
|
||||
@ -32,8 +31,8 @@
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFst
|
||||
/// Base class to create a Verilator FST dump
|
||||
/// This is an internally used class - see VerilatedFstC for what to call from applications
|
||||
// Base class to create a Verilator FST dump
|
||||
// This is an internally used class - see VerilatedFstC for what to call from applications
|
||||
|
||||
class VerilatedFst final : public VerilatedTrace<VerilatedFst> {
|
||||
private:
|
||||
@ -86,23 +85,23 @@ public:
|
||||
explicit VerilatedFst(void* fst = nullptr);
|
||||
~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;
|
||||
/// Close the file
|
||||
// Close the file
|
||||
void close() VL_MT_UNSAFE;
|
||||
/// Flush any remaining data to this file
|
||||
// Flush any remaining data to this file
|
||||
void flush() VL_MT_UNSAFE;
|
||||
/// Is file open?
|
||||
// Return if file is open
|
||||
bool isOpen() const { return m_fst != nullptr; }
|
||||
|
||||
//=========================================================================
|
||||
// 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,
|
||||
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,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
void declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
@ -135,16 +134,18 @@ class VerilatedFstC final {
|
||||
VL_UNCOPYABLE(VerilatedFstC);
|
||||
|
||||
public:
|
||||
/// Construct the dump. Optional argument is ignored.
|
||||
explicit VerilatedFstC(void* filep = nullptr)
|
||||
: m_sptrace{filep} {}
|
||||
/// Destruct, flush, and close the dump
|
||||
~VerilatedFstC() { close(); }
|
||||
/// Routines can only be called from one thread; allow next call from different thread
|
||||
void changeThread() { spTrace()->changeThread(); }
|
||||
|
||||
// ACCESSORS
|
||||
/// Is file open?
|
||||
// METHODS - User called
|
||||
|
||||
/// Return if file is open
|
||||
bool isOpen() const { return m_sptrace.isOpen(); }
|
||||
// METHODS
|
||||
/// Open a new FST file
|
||||
void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); }
|
||||
/// Close dump
|
||||
@ -158,16 +159,22 @@ public:
|
||||
void dump(double 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)); }
|
||||
/// 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 std::string& unit) { m_sptrace.set_time_unit(unit); }
|
||||
/// Set time resolution (s/ms, defaults to ns)
|
||||
/// For Verilated models, these propage from the Verilated default --timeunit
|
||||
// Set time resolution (s/ms, defaults to ns)
|
||||
// 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 std::string& unit) { m_sptrace.set_time_resolution(unit); }
|
||||
|
||||
/// Internal class access
|
||||
// Internal class access
|
||||
inline VerilatedFst* spTrace() { return &m_sptrace; };
|
||||
};
|
||||
|
||||
|
@ -12,10 +12,9 @@
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Tracing functionality common to all formats
|
||||
/// \brief Internal tracing functionality common to all formats
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef VERILATOR_VERILATED_TRACE_H_
|
||||
#define VERILATOR_VERILATED_TRACE_H_
|
||||
@ -221,9 +220,9 @@ protected:
|
||||
|
||||
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); }
|
||||
/// Character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||
// Character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||
char scopeEscape() { return m_scopeEscape; }
|
||||
|
||||
void close();
|
||||
|
@ -15,7 +15,6 @@
|
||||
/// \brief Implementation of tracing functionality common to all trace formats
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
// clang-format off
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
/// \brief C++ Tracing in VCD Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
// clang-format off
|
||||
|
||||
@ -34,8 +33,6 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
// SPDIFF_ON
|
||||
|
||||
#ifndef O_LARGEFILE // For example on WIN32
|
||||
# define O_LARGEFILE 0
|
||||
#endif
|
||||
|
@ -15,7 +15,6 @@
|
||||
/// \brief C++ Tracing in VCD Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef VERILATOR_VERILATED_VCD_C_H_
|
||||
#define VERILATOR_VERILATED_VCD_C_H_
|
||||
@ -29,7 +28,6 @@
|
||||
|
||||
class VerilatedVcd;
|
||||
|
||||
// SPDIFF_ON
|
||||
//=============================================================================
|
||||
// VerilatedFile
|
||||
/// File handling routines, which can be overrode for e.g. socket I/O
|
||||
@ -48,8 +46,8 @@ public:
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcd
|
||||
/// Base class to create a Verilator VCD dump
|
||||
/// This is an internally used class - see VerilatedVcdC for what to call from applications
|
||||
// Base class to create a Verilator VCD dump
|
||||
// This is an internally used class - see VerilatedVcdC for what to call from applications
|
||||
|
||||
class VerilatedVcd VL_NOT_FINAL : public VerilatedTrace<VerilatedVcd> {
|
||||
private:
|
||||
@ -136,19 +134,19 @@ public:
|
||||
~VerilatedVcd();
|
||||
|
||||
// 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; }
|
||||
|
||||
// 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;
|
||||
/// Open next data-only file
|
||||
// Open next data-only file
|
||||
void openNext(bool incFilename) VL_MT_UNSAFE_ONE;
|
||||
/// Close the file
|
||||
// Close the file
|
||||
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;
|
||||
/// Is file open?
|
||||
// Return if file is open
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
|
||||
//=========================================================================
|
||||
@ -211,8 +209,8 @@ public:
|
||||
chgDouble(oldp - this->oldp(0), newval);
|
||||
}
|
||||
|
||||
/// Inside dumping routines, dump one signal, faster when not inlined
|
||||
/// due to code size reduction.
|
||||
// Inside dumping routines, dump one signal, faster when not inlined
|
||||
// due to code size reduction.
|
||||
void fullBit(vluint32_t code, const vluint32_t newval);
|
||||
void fullBus(vluint32_t code, const vluint32_t newval, int bits);
|
||||
void fullQuad(vluint32_t code, const vluint64_t newval, int bits);
|
||||
@ -225,8 +223,8 @@ public:
|
||||
int bits);
|
||||
void fullDouble(vluint32_t code, const double newval);
|
||||
|
||||
/// 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.
|
||||
// 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.
|
||||
inline void chgBit(vluint32_t code, const vluint32_t newval) {
|
||||
vluint32_t diff = oldp(code)[0] ^ newval;
|
||||
if (VL_UNLIKELY(diff)) fullBit(code, newval);
|
||||
@ -336,17 +334,19 @@ class VerilatedVcdC VL_NOT_FINAL {
|
||||
VL_UNCOPYABLE(VerilatedVcdC);
|
||||
|
||||
public:
|
||||
/// Construct the dump. Optional argument is a preconstructed file.
|
||||
explicit VerilatedVcdC(VerilatedVcdFile* filep = nullptr)
|
||||
: m_sptrace{filep} {}
|
||||
/// Destruct, flush, and close the dump
|
||||
~VerilatedVcdC() { close(); }
|
||||
/// Routines can only be called from one thread; allow next call from different thread
|
||||
void changeThread() { spTrace()->changeThread(); }
|
||||
|
||||
public:
|
||||
// ACCESSORS
|
||||
/// Is file open?
|
||||
// METHODS - User called
|
||||
|
||||
/// Return if file is open
|
||||
bool isOpen() const { return m_sptrace.isOpen(); }
|
||||
// METHODS
|
||||
/// Open a new VCD file
|
||||
/// This includes a complete header dump each time it is called,
|
||||
/// 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(vluint32_t 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 std::string& unit) { m_sptrace.set_time_unit(unit); }
|
||||
/// Set time resolution (s/ms, defaults to ns)
|
||||
/// For Verilated models, these propage from the Verilated default --timeunit
|
||||
// Set time resolution (s/ms, defaults to ns)
|
||||
// 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 std::string& unit) { m_sptrace.set_time_resolution(unit); }
|
||||
|
||||
/// Internal class access
|
||||
// Internal class access
|
||||
inline VerilatedVcd* spTrace() { return &m_sptrace; }
|
||||
|
||||
#ifdef VL_TRACE_VCD_OLD_API
|
||||
@ -385,7 +391,8 @@ public:
|
||||
// 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
|
||||
// guarantee of functionality.
|
||||
/// Use evcd format
|
||||
|
||||
// Use evcd format
|
||||
void evcd(bool flag) VL_MT_UNSAFE_ONE { m_sptrace.evcd(flag); }
|
||||
#endif
|
||||
};
|
||||
|
@ -15,12 +15,10 @@
|
||||
/// \brief Verilator tracing in VCD Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated_vcd_sc.h"
|
||||
|
||||
// SPDIFF_ON
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
/// This class is not threadsafe, as the SystemC kernel is not threadsafe.
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef VERILATOR_VERILATED_VCD_SC_H_
|
||||
#define VERILATOR_VERILATED_VCD_SC_H_
|
||||
@ -24,18 +23,18 @@
|
||||
#include "verilated_sc.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
|
||||
// SPDIFF_ON
|
||||
//=============================================================================
|
||||
// VerilatedVcdSc
|
||||
///
|
||||
/// This class is passed to the SystemC simulation kernel, just like a
|
||||
/// documented SystemC trace format.
|
||||
/// This class creates a Verilator-friendly VCD trace format with the
|
||||
/// SystemC simulation kernel, just like a SystemC-documented trace format.
|
||||
|
||||
class VerilatedVcdSc final : sc_trace_file, public VerilatedVcdC {
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedVcdSc);
|
||||
|
||||
public:
|
||||
/// Construct a SC trace object, and register with the SystemC kernel
|
||||
VerilatedVcdSc() {
|
||||
sc_get_curr_simcontext()->add_trace_file(this);
|
||||
// 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());
|
||||
}
|
||||
/// Destruct, flush, and close the dump
|
||||
virtual ~VerilatedVcdSc() { close(); }
|
||||
|
||||
// METHODS
|
||||
/// Called by SystemC simulate()
|
||||
// METHODS - for SC kernel
|
||||
// Called by SystemC simulate()
|
||||
virtual void cycle(bool delta_cycle) {
|
||||
if (!delta_cycle) this->dump(sc_time_stamp().to_double());
|
||||
}
|
||||
|
||||
private:
|
||||
/// Fake outs for linker
|
||||
// METHODS - Fake outs for linker
|
||||
|
||||
#ifdef NC_SYSTEMC
|
||||
// Cadence Incisive has these as abstract functions so we must create them
|
||||
|
@ -47,7 +47,8 @@ public:
|
||||
/// Returns time of the next registered VPI callback, or
|
||||
/// ~(0) if none are registered
|
||||
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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user