Add support for and , #2126.

This commit is contained in:
Wilson Snyder
2020-03-01 21:39:23 -05:00
parent 0ca0e07354
commit 30a33a6104
51 changed files with 1378 additions and 137 deletions
+2
View File
@@ -7,6 +7,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
** Add split_var metacomment to assist UNOPTFLAT fixes, #2066. [Yutetsu TAKATSUKASA]
** Add support for $dumpfile and $dumpvars, #2126. [Alexander Grobman]
*** Add +verilator+noassert flag to disable assertion checking. [Tobias Wölfel]
*** Add check for assertOn for asserts, #2162. [Tobias Wölfel]
+50 -31
View File
@@ -3782,17 +3782,29 @@ $unsigned, $warning.
Generally supported.
=item $display, $write, $fdisplay, $fwrite, $swrite
$display and friends must have a constant format string as the first
argument (as with C's printf). The rare usage which lists variables
standalone without a format is not supported.
=item $displayb, $displayh, $displayo, $writeb, $writeh, $writeo, etc
The sized display functions are rarely used and so not supported. Replace
them with a $write with the appropriate format specifier.
=item $dump/$dumpports and related
$dumpfile or $dumpports will create a VCD or FST file (which is based on
the --trace argument given when the model was Verilated). This will take
effect starting at the next eval() call. If you have multiple Verilated
designs under the same C model, then this will dump signals only from the
design containing the $dumpvar.
$dumpvars and $dumpports module identifier is ignored; the traced instances
will always start at the top of the design. The levels argument is also
ignored, use tracing_on/tracing_off pragmas instead.
$dumpportson/$dumpportsoff/$dumpportsall/$dumpportslimit filename argument
is ignored, only a single trace file may be active at once.
$dumpall/$dumpportsall, $dumpon/$dumpportson, $dumpoff/$dumpportsoff, and
$dumplimit/$dumpportlimit are currently ignored.
=item $finish, $stop
The rarely used optional parameter to $finish and $stop is ignored.
@@ -4835,19 +4847,20 @@ designs have topped 16GB.
See the next question for tracing in SystemC mode.
Add the --trace switch to Verilator, and in your top level C code, call
Verilated::traceEverOn(true). Then create a VerilatedVcdC object, and
in your main loop call "trace_object->dump(time)" every time step, and
finally call "trace_object->close()". For an example, see below and the
examples/make_tracing_c/sim_main.cpp file of the distribution.
A. Add the --trace switch to Verilator, and in your top level C code, call
Verilated::traceEverOn(true). Then you may use $dumpfile and $dumpvars to
enable traces, same as with any Verilog simulator. See
C<examples/make_tracing_c>.
You also need to compile verilated_vcd_c.cpp and add it to your link,
preferably by adding the dependencies in $(VK_GLOBAL_OBJS) to your
Makefile's link rule. This is done for you if using the Verilator --exe
flag.
Note you can also call ->trace on multiple Verilated objects with the same
trace file if you want all data to land in the same output file.
B. Or, for finer-grained control, or C++ files with multiple Verilated
modules you may also create the trace purely from C++. Create a
VerilatedVcdC object, and in your main loop call "trace_object->dump(time)"
every time step, and finally call "trace_object->close()". You also need
to compile verilated_vcd_c.cpp and add it to your link, preferably by
adding the dependencies in $(VK_GLOBAL_OBJS) to your Makefile's link rule.
This is done for you if using the Verilator --exe flag. Note you can also
call ->trace on multiple Verilated objects with the same trace file if you
want all data to land in the same output file.
#include "verilated_vcd_c.h"
...
@@ -4867,11 +4880,17 @@ trace file if you want all data to land in the same output file.
=item How do I generate waveforms (traces) in SystemC?
Add the --trace switch to Verilator, and in your top level C sc_main code,
include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then
create a VerilatedVcdSc object as you would create a normal SystemC trace
file. For an example, see the call to VerilatedVcdSc in the
examples/make_tracing_sc/sc_main.cpp file of the distribution, and below.
A. Add the --trace switch to Verilator, and in your top level sc_main, call
Verilated::traceEverOn(true). Then you may use $dumpfile and $dumpvars to
enable traces, same as with any Verilog simulator, see the non-SystemC
example in C<examples/make_tracing_c>. This will trace only the module
containing the $dumpvar.
B. Or, you may create a trace purely from SystemC, which may trace all
Verilated designs in the SystemC model. Create a VerilatedVcdSc object as
you would create a normal SystemC trace file. For an example, see the call
to VerilatedVcdSc in the examples/make_tracing_sc/sc_main.cpp file of the
distribution, and below.
Alternatively you may use the C++ trace mechanism described in the previous
question, however the timescale and timeprecision will not inherited from
@@ -4901,23 +4920,23 @@ trace file if you want all data to land in the same output file.
=item How do I generate FST waveforms (traces) in C++?
FST a format by GTKWave.
This version provides a basic FST support.
To dump FST format, add the --trace-fst switch to Verilator and change the include
path in the testbench to:
FST a format by GTKWave. This version provides a basic FST support. To
dump FST format, add the --trace-fst switch to Verilator and either A. use
$dumpfile/$dumpvars in Verilog as described in the VCD example above, or
B. in C++ change the include described in the VCD example above:
#include "verilated_fst_c.h"
VerilatedFstC* tfp = new VerilatedFstC;
Note that currently supporting both FST and VCD in a single simulation is impossible,
but such requirement could be rare.
Note that currently supporting both FST and VCD in a single simulation is
impossible, but such requirement should be rare.
=item How do I generate FST waveforms (traces) in SystemC?
=item How do I generate FST waveforms (aka dumps or traces) in SystemC?
The FST library from GTKWave does not currently support SystemC; use VCD
format instead.
=item How do I view waveforms (traces)?
=item How do I view waveforms (aka dumps or traces)?
Verilator makes standard VCD (Value Change Dump) and FST files. VCD files are viewable
with the public domain GTKWave (recommended) or Dinotrace (legacy)
+9 -30
View File
@@ -10,11 +10,6 @@
// Include model header, generated from Verilating "top.v"
#include "Vtop.h"
// If "verilator --trace" is used, include the tracing class
#if VM_TRACE
# include <verilated_vcd_c.h>
#endif
// Current simulation time (64-bit unsigned)
vluint64_t main_time = 0;
// Called by $time in Verilog
@@ -36,28 +31,19 @@ int main(int argc, char** argv, char** env) {
// May be overridden by commandArgs
Verilated::randReset(2);
// Verilator must compute traced signals
Verilated::traceEverOn(true);
// 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");
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
#if VM_TRACE
// If verilator was invoked with --trace argument,
// and if at run time passed the +trace argument, turn on tracing
VerilatedVcdC* tfp = NULL;
const char* flag = Verilated::commandArgsPlusMatch("trace");
if (flag && 0==strcmp(flag, "+trace")) {
Verilated::traceEverOn(true); // Verilator must compute traced signals
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
tfp = new VerilatedVcdC;
top->trace(tfp, 99); // Trace 99 levels of hierarchy
Verilated::mkdir("logs");
tfp->open("logs/vlt_dump.vcd"); // Open the dump file
}
#endif
// Set some inputs
top->reset_l = !0;
top->fastclk = 0;
@@ -90,13 +76,11 @@ int main(int argc, char** argv, char** env) {
top->in_quad += 0x12;
// 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.)
top->eval();
#if VM_TRACE
// Dump trace data for this cycle
if (tfp) tfp->dump(main_time);
#endif
// Read outputs
VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
@@ -107,11 +91,6 @@ int main(int argc, char** argv, char** env) {
// Final model cleanup
top->final();
// Close trace if opened
#if VM_TRACE
if (tfp) { tfp->close(); tfp = NULL; }
#endif
// Coverage analysis (since test passed)
#if VM_COVERAGE
Verilated::mkdir("logs");
+5
View File
@@ -36,6 +36,11 @@ module top
// Print some stuff as an example
initial begin
if ($test$plusargs("trace") != 0) begin
$display("[%0t] Tracing to logs/vlt_dump.vcd...\n", $time);
$dumpfile("logs/vlt_dump.vcd");
$dumpvars();
end
$display("[%0t] Model running...\n", $time);
end
+3
View File
@@ -37,6 +37,9 @@ int sc_main(int argc, char* argv[]) {
// 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();
+19
View File
@@ -1602,6 +1602,25 @@ IData VL_ATOI_N(const std::string& str, int base) VL_PURE {
return static_cast<IData>(v);
}
//===========================================================================
// Dumping
const char* vl_dumpctl_filenamep(bool setit, const std::string& filename) VL_MT_SAFE {
// This function performs both accessing and setting so it's easy to make an in-function static
static VL_THREAD_LOCAL std::string t_filename;
if (setit) {
t_filename = filename;
} else {
static VL_THREAD_LOCAL bool t_warned = false;
if (VL_UNLIKELY(t_filename.empty() && !t_warned)) {
t_warned = true;
VL_PRINTF_MT("%%Warning: $dumpvar ignored as not proceeded by $dumpfile\n");
return "";
}
}
return t_filename.c_str();
}
//===========================================================================
// Readmem/writemem
+1
View File
@@ -83,6 +83,7 @@ class VerilatedVar;
class VerilatedVarNameMap;
class VerilatedVcd;
class VerilatedVcdC;
class VerilatedVcdSc;
class VerilatedFst;
class VerilatedFstC;
+13 -11
View File
@@ -64,9 +64,12 @@ protected:
vluint32_t m_code; ///< Starting code number
// CONSTRUCTORS
VerilatedFstCallInfo(VerilatedFstCallback_t icb, VerilatedFstCallback_t fcb,
VerilatedFstCallback_t changecb,
void* ut, vluint32_t code)
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {}
VerilatedFstCallback_t changecb, void* ut)
: m_initcb(icb)
, m_fullcb(fcb)
, m_changecb(changecb)
, m_userthis(ut)
, m_code(1) {}
~VerilatedFstCallInfo() {}
};
@@ -173,17 +176,16 @@ void VerilatedFst::declSymbol(vluint32_t code, const char* name,
//=============================================================================
// Callbacks
void VerilatedFst::addCallback(
VerilatedFstCallback_t initcb, VerilatedFstCallback_t fullcb,
VerilatedFstCallback_t changecb, void* userthis) VL_MT_UNSAFE_ONE {
void VerilatedFst::addCallback(VerilatedFstCallback_t initcb, VerilatedFstCallback_t fullcb,
VerilatedFstCallback_t changecb, void* userthis) VL_MT_UNSAFE_ONE {
m_assertOne.check();
if (VL_UNLIKELY(isOpen())) {
std::string msg = (std::string("Internal: ")+__FILE__+"::"+__FUNCTION__
+" called with already open file");
std::string msg = (std::string("Internal: ") + __FILE__ + "::" + __FUNCTION__
+ " called with already open file");
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
}
VerilatedFstCallInfo* vci = new VerilatedFstCallInfo(initcb, fullcb, changecb, userthis, 1);
m_callbacks.push_back(vci);
VerilatedFstCallInfo* cip = new VerilatedFstCallInfo(initcb, fullcb, changecb, userthis);
m_callbacks.push_back(cip);
}
//=============================================================================
@@ -192,7 +194,7 @@ void VerilatedFst::addCallback(
void VerilatedFst::dump(vluint64_t timeui) {
if (!isOpen()) return;
if (VL_UNLIKELY(m_fullDump)) {
m_fullDump = false; // No need for more full dumps
m_fullDump = false; // No more need for next dump to be full
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
VerilatedFstCallInfo* cip = m_callbacks[ent];
(cip->m_fullcb)(this, cip->m_userthis, cip->m_code);
+1 -1
View File
@@ -198,7 +198,7 @@ class VerilatedFstC {
VL_UNCOPYABLE(VerilatedFstC);
public:
explicit VerilatedFstC(void* filep=NULL) : m_sptrace(filep) {}
~VerilatedFstC() {}
~VerilatedFstC() { close(); }
public:
// ACCESSORS
/// Is file open?
+6
View File
@@ -441,4 +441,10 @@ inline IData VL_CMP_NN(const std::string& lhs, const std::string& rhs, bool igno
extern IData VL_ATOI_N(const std::string& str, int base) VL_PURE;
//======================================================================
// Dumping
extern const char* vl_dumpctl_filenamep(bool setit = false,
const std::string& filename = "") VL_MT_SAFE;
#endif // Guard
+7 -4
View File
@@ -119,7 +119,7 @@ protected:
bool VerilatedVcdFile::open(const std::string& name) VL_MT_UNSAFE {
m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC, 0666);
return (m_fd>=0);
return m_fd >= 0;
}
void VerilatedVcdFile::close() VL_MT_UNSAFE {
@@ -136,7 +136,10 @@ ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) VL_MT_UNSAFE {
// Opening/Closing
VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep)
: m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) {
: m_isOpen(false)
, m_rolloverMB(0)
, m_modDepth(0)
, m_nextCode(1) {
// Not in header to avoid link issue if header is included without this .cpp file
m_fileNewed = (filep == NULL);
m_filep = m_fileNewed ? new VerilatedVcdFile : filep;
@@ -156,7 +159,7 @@ VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep)
void VerilatedVcd::open(const char* filename) {
m_assertOne.check();
if (isOpen()) return;
if (isOpen() || !filename || !*filename) return;
// Set member variables
m_filename = filename;
@@ -690,7 +693,7 @@ void VerilatedVcd::dump(vluint64_t timeui) {
m_assertOne.check();
if (!isOpen()) return;
if (VL_UNLIKELY(m_fullDump)) {
m_fullDump = false; // No need for more full dumps
m_fullDump = false; // No more need for next dump to be full
dumpFull(timeui);
return;
}
+3 -3
View File
@@ -103,9 +103,9 @@ private:
typedef std::vector<VerilatedVcdSig> SigVec;
SigVec m_sigs; ///< Pointer to signal information
typedef std::vector<VerilatedVcdCallInfo*> CallbackVec;
CallbackVec m_callbacks; ///< Routines to perform dumping
CallbackVec m_callbacks; ///< Routines to perform dumping
typedef std::map<std::string,std::string> NameMap;
NameMap* m_namemapp; ///< List of names for the header
NameMap* m_namemapp; ///< List of names for the header
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
@@ -445,7 +445,7 @@ class VerilatedVcdC {
public:
explicit VerilatedVcdC(VerilatedVcdFile* filep = NULL)
: m_sptrace(filep) {}
~VerilatedVcdC() {}
~VerilatedVcdC() { close(); }
public:
// ACCESSORS
/// Is file open?
+1 -1
View File
@@ -62,7 +62,7 @@ public:
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
# endif
}
virtual ~VerilatedVcdSc() {}
virtual ~VerilatedVcdSc() { close(); }
// METHODS
/// Called by SystemC simulate()
+26
View File
@@ -815,6 +815,32 @@ inline bool operator==(AstDisplayType::en lhs, const AstDisplayType& rhs) {
//######################################################################
class VDumpCtlType {
public:
enum en { FILE, VARS, ALL, FLUSH, LIMIT, OFF, ON };
enum en m_e;
inline VDumpCtlType()
: m_e(ON) {}
// cppcheck-suppress noExplicitConstructor
inline VDumpCtlType(en _e)
: m_e(_e) {}
explicit inline VDumpCtlType(int _e)
: m_e(static_cast<en>(_e)) {}
operator en() const { return m_e; }
const char* ascii() const {
static const char* const names[] = {"$dumpfile", "$dumpvars", "$dumpall", "$dumpflush",
"$dumplimit", "$dumpoff", "$dumpon"};
return names[m_e];
}
};
inline bool operator==(const VDumpCtlType& lhs, const VDumpCtlType& rhs) {
return lhs.m_e == rhs.m_e;
}
inline bool operator==(const VDumpCtlType& lhs, VDumpCtlType::en rhs) { return lhs.m_e == rhs; }
inline bool operator==(VDumpCtlType::en lhs, const VDumpCtlType& rhs) { return lhs == rhs.m_e; }
//######################################################################
class VParseRefExp {
public:
enum en {
+25
View File
@@ -3033,6 +3033,31 @@ public:
void filep(AstNodeVarRef* nodep) { setNOp3p(nodep); }
};
class AstDumpCtl : public AstNodeStmt {
// $dumpon etc
// Parents: expr
// Child: expr based on type of control statement
VDumpCtlType m_ctlType; // Type of operation
public:
AstDumpCtl(FileLine* fl, VDumpCtlType ctlType, AstNode* exprp = NULL)
: ASTGEN_SUPER(fl), m_ctlType(ctlType) {
setNOp1p(exprp);
}
ASTNODE_NODE_FUNCS(DumpCtl)
virtual string verilogKwd() const { return ctlType().ascii(); }
virtual string emitVerilog() { return "%f" + verilogKwd() + "(%l)"; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
virtual bool isOutputter() const { return true; }
virtual bool cleanOut() const { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
VDumpCtlType ctlType() const { return m_ctlType; }
AstNode* exprp() const { return op1p(); } // op2 = Expressions to output
void exprp(AstNode* nodep) { setOp1p(nodep); }
};
class AstElabDisplay : public AstNode {
// Parents: stmtlist
// Children: SFORMATF to generate print string
+127 -13
View File
@@ -402,6 +402,44 @@ public:
if (nodep->addNewline()) text += "\n";
displayNode(nodep, nodep->fmtp()->scopeNamep(), text, nodep->fmtp()->exprsp(), false);
}
virtual void visit(AstDumpCtl* nodep) VL_OVERRIDE {
switch (nodep->ctlType()) {
case VDumpCtlType::FILE:
puts("vl_dumpctl_filenamep(true, ");
emitCvtPackStr(nodep->exprp());
puts(");\n");
break;
case VDumpCtlType::VARS:
// We ignore number of levels to dump in exprp()
if (v3Global.opt.trace()) {
puts("vlSymsp->TOPp->_traceDumpOpen();\n");
} else {
puts("VL_PRINTF_MT(\"-Info: ");
puts(protect(nodep->fileline()->filename()));
puts(":");
puts(cvtToStr(nodep->fileline()->lineno()));
puts(": $dumpvar ignored, as Verilated without --trace");
puts("\\n\");\n");
}
break;
case VDumpCtlType::ALL:
// $dumpall currently ignored
break;
case VDumpCtlType::FLUSH:
puts("Verilated::flushCall();\n"); // Also flush stdio, as need lock
break;
case VDumpCtlType::LIMIT:
// $dumplimit currently ignored
break;
case VDumpCtlType::OFF:
// Currently ignored as both Vcd and Fst do not support them, as would need "X" dump
break;
case VDumpCtlType::ON:
// Currently ignored as $dumpoff is also ignored
break;
default: nodep->v3fatalSrc("Bad case, unexpected " << nodep->ctlType().ascii());
}
}
virtual void visit(AstScopeName* nodep) VL_OVERRIDE {
// For use under AstCCalls for dpiImports. ScopeNames under
// displays are handled in AstDisplay
@@ -2110,8 +2148,16 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) {
void EmitCImp::emitDestructorImp(AstNodeModule* modp) {
puts("\n");
puts(prefixNameProtect(modp) + "::~" + prefixNameProtect(modp) + "() {\n");
if (modp->isTop() && v3Global.opt.mtasks()) {
puts("delete __Vm_threadPoolp; __Vm_threadPoolp = NULL;\n");
if (modp->isTop()) {
if (v3Global.opt.mtasks()) {
puts("delete __Vm_threadPoolp; __Vm_threadPoolp = NULL;\n");
}
// Call via function in __Trace.cpp as this .cpp file does not have trace header
if (v3Global.needTraceDumper()) {
puts("#ifdef VM_TRACE\n");
puts("if (VL_UNLIKELY(__VlSymsp->__Vm_dumperp)) _traceDumpClose();\n");
puts("#endif // VM_TRACE\n");
}
}
emitTextSection(AstType::atScDtor);
if (modp->isTop()) puts("delete __VlSymsp; __VlSymsp=NULL;\n");
@@ -2304,7 +2350,7 @@ void EmitCImp::emitSettleLoop(const std::string& eval_call, bool initial) {
}
void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("\nvoid " + prefixNameProtect(modp) + "::eval() {\n");
puts("\nvoid " + prefixNameProtect(modp) + "::eval_step() {\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+++++TOP Evaluate " + prefixNameProtect(modp)
+ "::eval\\n\"); );\n");
puts(EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp; // Setup global symbol table\n");
@@ -2316,6 +2362,15 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
putsDecoration("// Initialize\n");
puts("if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) "
+protect("_eval_initial_loop")+"(vlSymsp);\n");
if (v3Global.opt.trace()) {
puts("#ifdef VM_TRACE\n");
putsDecoration("// Tracing\n");
// SystemC's eval loop deals with calling trace, not us
if (v3Global.needTraceDumper() && !optSystemC()) {
puts("if (VL_UNLIKELY(vlSymsp->__Vm_dumperp)) _traceDump();\n");
}
puts("#endif // VM_TRACE\n");
}
if (v3Global.opt.inhibitSim()) {
puts("if (VL_UNLIKELY(__Vm_inhibitSim)) return;\n");
}
@@ -2377,6 +2432,21 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("}\n");
splitSizeInc(10);
//
if (v3Global.needTraceDumper() && !optSystemC()) {
puts("\nvoid " + prefixNameProtect(modp) + "::eval_end_step() {\n");
puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+eval_end_step " + prefixNameProtect(modp)
+ "::eval_end_step\\n\"); );\n");
puts("#ifdef VM_TRACE\n");
puts(EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symTopAssign()+"\n");
putsDecoration("// Tracing\n");
// SystemC's eval loop deals with calling trace, not us
puts("if (VL_UNLIKELY(vlSymsp->__Vm_dumperp)) _traceDump();\n");
puts("#endif // VM_TRACE\n");
puts("}\n");
}
//
puts("\nvoid " + prefixNameProtect(modp) + "::" + protect("_eval_initial_loop") + "("
+ EmitCBaseVisitor::symClassVar() + ") {\n");
@@ -2693,11 +2763,11 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
ofp()->putsPrivate(!modp->isTop()); // private: unless top
puts(symClassName()+"* __VlSymsp; // Symbol table\n");
ofp()->putsPrivate(false); // public:
if (modp->isTop() && v3Global.opt.inhibitSim()) {
puts("bool __Vm_inhibitSim; ///< Set true to disable evaluation of module\n");
}
if (modp->isTop() && v3Global.opt.mtasks()) {
emitMTaskState();
if (modp->isTop()) {
if (v3Global.opt.inhibitSim()) {
puts("bool __Vm_inhibitSim; ///< Set true to disable evaluation of module\n");
}
if (v3Global.opt.mtasks()) emitMTaskState();
}
emitCoverageDecl(modp); // may flip public/private
@@ -2775,14 +2845,26 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
if (modp->isTop()) {
puts("\n// API METHODS\n");
string callEvalEndStep
= (v3Global.needTraceDumper() && !optSystemC()) ? "eval_end_step(); " : "";
if (optSystemC()) ofp()->putsPrivate(true); ///< eval() is invoked by our sensitive() calls.
else puts("/// Evaluate the model. Application must call when inputs change.\n");
puts("void eval();\n");
if (!optSystemC()) puts("/// Evaluate the model. Application must call when inputs change.\n");
puts("void eval() { eval_step(); " + callEvalEndStep + "}\n");
if (!optSystemC()) puts("/// Evaluate when calling multiple units/models per time step.\n");
puts("void eval_step();\n");
if (!optSystemC()) {
puts("/// Evaluate at end of a timestep for tracing, when using eval_step().\n");
puts("/// Application must call after all eval() and before time changes.\n");
puts("void eval_end_step()");
if (callEvalEndStep == "") puts(" {}\n");
else puts(";\n");
}
ofp()->putsPrivate(false); // public:
if (!optSystemC()) puts("/// Simulation complete, run final blocks. Application must call on completion.\n");
puts("void final();\n");
if (v3Global.opt.inhibitSim()) {
puts("void inhibitSim(bool flag) { __Vm_inhibitSim=flag; } ///< Set true to disable evaluation of module\n");
puts("/// Disable evaluation of module (e.g. turn off)\n");
puts("void inhibitSim(bool flag) { __Vm_inhibitSim = flag; }\n");
}
}
@@ -2791,6 +2873,9 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
ofp()->putsPrivate(true); // private:
puts("static void "+protect("_eval_initial_loop")
+"("+EmitCBaseVisitor::symClassVar()+");\n");
if (v3Global.needTraceDumper() && !optSystemC()) puts("void _traceDump();");
if (v3Global.needTraceDumper()) puts("void _traceDumpOpen();");
if (v3Global.needTraceDumper()) puts("void _traceDumpClose();");
}
if (!VN_IS(modp, Class)) {
@@ -2978,14 +3063,43 @@ class EmitCTrace : EmitCStmts {
void emitTraceHeader() {
// Includes
puts("#include \""+v3Global.opt.traceSourceName()+"_c.h\"\n");
puts("#include \""+ symClassName() +".h\"\n");
puts("#include \"" + v3Global.opt.traceSourceLang() + ".h\"\n");
puts("#include \"" + symClassName() + ".h\"\n");
puts("\n");
}
void emitTraceSlow() {
puts("\n//======================\n\n");
if (v3Global.needTraceDumper() && !optSystemC()) {
puts("void " + topClassName() + "::_traceDump() {\n");
// Caller checked for __Vm_dumperp non-NULL
puts( "VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n");
puts( "__VlSymsp->__Vm_dumperp->dump(VL_TIME_Q());\n");
puts("}\n");
splitSizeInc(10);
}
if (v3Global.needTraceDumper()) {
puts("void " + topClassName() + "::_traceDumpOpen() {\n");
puts( "if (VL_UNLIKELY(!__VlSymsp->__Vm_dumperp)) {\n");
puts( "VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n");
puts( "__VlSymsp->__Vm_dumperp = new " + v3Global.opt.traceClassLang() + "();\n");
puts( "const char* cp = vl_dumpctl_filenamep();\n");
puts( "trace(__VlSymsp->__Vm_dumperp, 0, 0);\n");
puts( "__VlSymsp->__Vm_dumperp->open(vl_dumpctl_filenamep());\n");
puts( "}\n");
puts("}\n");
splitSizeInc(10);
puts("void " + topClassName() + "::_traceDumpClose() {\n");
// Caller checked for __Vm_dumperp non-NULL
puts( "VerilatedLockGuard lock(__VlSymsp->__Vm_dumperMutex);\n");
puts( "delete __VlSymsp->__Vm_dumperp; __VlSymsp->__Vm_dumperp = NULL;\n");
puts("}\n");
splitSizeInc(10);
}
puts("void "+topClassName()+"::trace(");
puts(v3Global.opt.traceClassBase()+"C* tfp, int, int) {\n");
puts( "tfp->spTrace()->addCallback("
+5
View File
@@ -66,6 +66,11 @@ class EmitCInlines : EmitCBaseVisitor {
v3Global.needHeavy(true);
iterateChildren(nodep);
}
virtual void visit(AstDumpCtl* nodep) VL_OVERRIDE {
if (v3Global.opt.trace()) v3Global.needTraceDumper(true);
v3Global.needHeavy(true);
iterateChildren(nodep);
}
virtual void visit(AstPutcN* nodep) VL_OVERRIDE {
v3Global.needHeavy(true);
iterateChildren(nodep);
+2 -2
View File
@@ -160,13 +160,13 @@ class CMakeEmitter {
}
if (v3Global.opt.trace()) {
global.push_back("${VERILATOR_ROOT}/include/"
+ v3Global.opt.traceSourceName()+"_c.cpp");
+ v3Global.opt.traceSourceBase() + "_c.cpp");
if (v3Global.opt.systemC()) {
if (v3Global.opt.traceFormat() != TraceFormat::VCD) {
v3error("Unsupported: This trace format is not supported in SystemC, use VCD format.");
}
global.push_back("${VERILATOR_ROOT}/include/"
+ v3Global.opt.traceSourceName()+"_sc.cpp");
+ v3Global.opt.traceSourceLang() + ".cpp");
}
}
if (v3Global.opt.mtasks()) {
+10 -4
View File
@@ -417,6 +417,13 @@ void EmitCSyms::emitSymHdr() {
puts("\n// LOCAL STATE\n");
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
if (v3Global.needTraceDumper()) {
// __Vm_dumperp is local, otherwise we wouldn't know what design's eval()
// should call a global dumpperp
puts("VerilatedMutex __Vm_dumperMutex; // Protect __Vm_dumperp\n");
puts(v3Global.opt.traceClassLang()
+ "* __Vm_dumperp VL_GUARDED_BY(__Vm_dumperMutex); /// Trace class for $dump*\n");
}
if (v3Global.opt.trace()) {
puts("bool __Vm_activity; ///< Used by trace routines to determine change occurred\n");
}
@@ -582,10 +589,9 @@ void EmitCSyms::emitSymImp() {
puts("\n// FUNCTIONS\n");
puts(symClassName()+"::"+symClassName()+"("+topClassName()+"* topp, const char* namep)\n");
puts(" // Setup locals\n");
puts(" : __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
if (v3Global.opt.trace()) {
puts(" , __Vm_activity(false)\n");
}
puts(" : __Vm_namep(namep)\n"); // No leak, as gets destroyed when the top is destroyed
if (v3Global.needTraceDumper()) puts(" , __Vm_dumperp(NULL)\n");
if (v3Global.opt.trace()) puts(" , __Vm_activity(false)\n");
puts(" , __Vm_didInit(false)\n");
puts(" // Setup submodule names\n");
char comma = ',';
+2 -2
View File
@@ -85,12 +85,12 @@ public:
putMakeClassEntry(of, "verilated_cov.cpp");
}
if (v3Global.opt.trace()) {
putMakeClassEntry(of, v3Global.opt.traceSourceName()+"_c.cpp");
putMakeClassEntry(of, v3Global.opt.traceSourceBase() + "_c.cpp");
if (v3Global.opt.systemC()) {
if (v3Global.opt.traceFormat() != TraceFormat::VCD) {
v3error("Unsupported: This trace format is not supported in SystemC, use VCD format.");
} else {
putMakeClassEntry(of, v3Global.opt.traceSourceName()+"_sc.cpp");
putMakeClassEntry(of, v3Global.opt.traceSourceLang() + ".cpp");
}
}
}
+14 -10
View File
@@ -71,15 +71,16 @@ inline bool operator==(VWidthMinUsage::en lhs, const VWidthMinUsage& rhs) {
class V3Global {
// Globals
AstNetlist* m_rootp; // Root of entire netlist
VWidthMinUsage m_widthMinUsage; // What AstNode::widthMin() is used for
AstNetlist* m_rootp; // Root of entire netlist
VWidthMinUsage m_widthMinUsage; // What AstNode::widthMin() is used for
int m_debugFileNumber; // Number to append to debug files created
bool m_assertDTypesResolved; // Tree should have dtypep()'s
bool m_constRemoveXs; // Const needs to strip any Xs
bool m_needHInlines; // Need __Inlines file
bool m_needHeavy; // Need verilated_heavy.h include
bool m_dpi; // Need __Dpi include files
int m_debugFileNumber; // Number to append to debug files created
bool m_assertDTypesResolved; // Tree should have dtypep()'s
bool m_constRemoveXs; // Const needs to strip any Xs
bool m_needTraceDumper; // Need __Vm_dumperp in symbols
bool m_needHInlines; // Need __Inlines file
bool m_needHeavy; // Need verilated_heavy.h include
bool m_dpi; // Need __Dpi include files
public:
// Options
@@ -92,6 +93,7 @@ public:
m_widthMinUsage = VWidthMinUsage::LINT_WIDTH;
m_assertDTypesResolved = false;
m_constRemoveXs = false;
m_needTraceDumper = false;
m_needHInlines = false;
m_needHeavy = false;
m_dpi = false;
@@ -119,10 +121,12 @@ public:
char digits[100]; sprintf(digits, "%03d", m_debugFileNumber);
return opt.makeDir()+"/"+opt.prefix()+"_"+digits+"_"+nameComment;
}
bool needTraceDumper() const { return m_needTraceDumper; }
void needTraceDumper(bool flag) { m_needTraceDumper = flag; }
bool needHInlines() const { return m_needHInlines; }
void needHInlines(bool flag) { m_needHInlines=flag; }
void needHInlines(bool flag) { m_needHInlines = flag; }
bool needHeavy() const { return m_needHeavy; }
void needHeavy(bool flag) { m_needHeavy=flag; }
void needHeavy(bool flag) { m_needHeavy = flag; }
bool dpi() const { return m_dpi; }
void dpi(bool flag) { m_dpi = flag; }
};
+5 -1
View File
@@ -467,7 +467,11 @@ class V3Options {
bool oTable() const { return m_oTable; }
string traceClassBase() const { return m_traceFormat.classBase(); }
string traceSourceName() const { return m_traceFormat.sourceName(); }
string traceClassLang() const { return m_traceFormat.classBase() + (systemC() ? "Sc" : "C"); }
string traceSourceBase() const { return m_traceFormat.sourceName(); }
string traceSourceLang() const {
return m_traceFormat.sourceName() + (systemC() ? "_sc" : "_c");
}
// METHODS (from main)
static string version();
+5
View File
@@ -2872,6 +2872,11 @@ private:
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
}
}
virtual void visit(AstDumpCtl* nodep) VL_OVERRIDE {
assertAtStatement(nodep);
// Just let all arguments seek their natural sizes
userIterateChildren(nodep, WidthVP(SELF, BOTH).p());
}
virtual void visit(AstFOpen* nodep) VL_OVERRIDE {
// Although a system function in IEEE, here a statement which sets the file pointer (MCD)
assertAtStatement(nodep);
+14 -1
View File
@@ -197,6 +197,19 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$cos" { FL; return yD_COS; }
"$cosh" { FL; return yD_COSH; }
"$display" { FL; return yD_DISPLAY; }
"$dumpall" { FL; return yD_DUMPALL; }
"$dumpfile" { FL; return yD_DUMPFILE; }
"$dumpflush" { FL; return yD_DUMPFLUSH; }
"$dumplimit" { FL; return yD_DUMPLIMIT; }
"$dumpoff" { FL; return yD_DUMPOFF; }
"$dumpon" { FL; return yD_DUMPON; }
"$dumpports" { FL; return yD_DUMPPORTS; }
"$dumpportsall" { FL; return yD_DUMPALL; }
"$dumpportsflush" { FL; return yD_DUMPFLUSH; }
"$dumpportslimit" { FL; return yD_DUMPLIMIT; }
"$dumpportsoff" { FL; return yD_DUMPOFF; }
"$dumpportson" { FL; return yD_DUMPON; }
"$dumpvars" { FL; return yD_DUMPVARS; }
"$exp" { FL; return yD_EXP; }
"$fclose" { FL; return yD_FCLOSE; }
"$fdisplay" { FL; return yD_FDISPLAY; }
@@ -208,10 +221,10 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"$floor" { FL; return yD_FLOOR; }
"$fopen" { FL; return yD_FOPEN; }
"$fread" { FL; return yD_FREAD; }
"$frewind" { FL; return yD_FREWIND; }
"$fscanf" { FL; return yD_FSCANF; }
"$fseek" { FL; return yD_FSEEK; }
"$ftell" { FL; return yD_FTELL; }
"$frewind" { FL; return yD_FREWIND; }
"$fullskew" { FL; return yaTIMINGSPEC; }
"$fwrite" { FL; return yD_FWRITE; }
"$hold" { FL; return yaTIMINGSPEC; }
+31 -1
View File
@@ -553,6 +553,14 @@ class AstSenTree;
%token<fl> yD_COUNTONES "$countones"
%token<fl> yD_DIMENSIONS "$dimensions"
%token<fl> yD_DISPLAY "$display"
%token<fl> yD_DUMPALL "$dumpall"
%token<fl> yD_DUMPFILE "$dumpfile"
%token<fl> yD_DUMPFLUSH "$dumpflush"
%token<fl> yD_DUMPLIMIT "$dumplimit"
%token<fl> yD_DUMPOFF "$dumpoff"
%token<fl> yD_DUMPON "$dumpon"
%token<fl> yD_DUMPPORTS "$dumpports"
%token<fl> yD_DUMPVARS "$dumpvars"
%token<fl> yD_ERROR "$error"
%token<fl> yD_EXP "$exp"
%token<fl> yD_FATAL "$fatal"
@@ -3154,8 +3162,30 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yaD_DPI '(' exprList ')' { $$ = new AstTaskRef($<fl>1, *$1, $3);
GRAMMARP->argWrapList(VN_CAST($$, TaskRef)); }
//
| yD_DUMPPORTS '(' idDotted ',' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FILE, $5); DEL($3);
$$->addNext(new AstDumpCtl($<fl>1, VDumpCtlType::VARS,
new AstConst($<fl>1, 1))); }
| yD_DUMPPORTS '(' ',' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FILE, $4);
$$->addNext(new AstDumpCtl($<fl>1, VDumpCtlType::VARS,
new AstConst($<fl>1, 1))); }
| yD_DUMPFILE '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FILE, $3); }
| yD_DUMPVARS parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::VARS,
new AstConst($<fl>1, 0)); }
| yD_DUMPVARS '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::VARS, $3); }
| yD_DUMPVARS '(' expr ',' idDotted ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::VARS, $3); DEL($5); }
| yD_DUMPALL parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ALL); }
| yD_DUMPALL '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ALL); DEL($3); }
| yD_DUMPFLUSH parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FLUSH); }
| yD_DUMPFLUSH '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::FLUSH); DEL($3); }
| yD_DUMPLIMIT '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::LIMIT, $3); }
| yD_DUMPLIMIT '(' expr ',' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::LIMIT, $3); DEL($5); }
| yD_DUMPOFF parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::OFF); }
| yD_DUMPOFF '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::OFF); DEL($3); }
| yD_DUMPON parenE { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ON); }
| yD_DUMPON '(' expr ')' { $$ = new AstDumpCtl($<fl>1, VDumpCtlType::ON); DEL($3); }
//
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1, $3); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1, $3); }
//
| yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
| yD_FFLUSH parenE { $$ = NULL; BBUNSUP($1, "Unsupported: $fflush of all handles does not map to C++."); }
+3 -3
View File
@@ -64,15 +64,15 @@ int main(int argc, char* argv[]) {
vluint64_t firstUsage = get_memory_usage();
// Warmup phase
for (int i = 0; i < 1000; i++) {
for (int i = 0; i < 10; i++) {
make_and_destroy();
}
firstUsage = get_memory_usage();
printf("Memory size %" VL_PRI64 "d bytes\n", firstUsage);
int loops = 100*1000;
int loops = 10;
for (int left = loops; left > 0;) {
for (int j = 0; j < 1000; ++j, --left) {
for (int j = 0; j < 1; ++j, --left) {
make_and_destroy();
}
}
+2
View File
@@ -0,0 +1,2 @@
%Warning: $dumpvar ignored as not proceeded by $dumpfile
*-* All Finished *-*
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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.
scenarios(vlt => 1);
compile(
verilator_flags2 => ["-trace"],
);
execute(
check_finished => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;
+13
View File
@@ -0,0 +1,13 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2020 by Wilson Snyder.
module t(/*AUTOARG*/);
initial begin
// Check error when this missing: $dumpfile("/should/not/be/opened");
$dumpvars;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+2
View File
@@ -0,0 +1,2 @@
-Info: t/t_trace_flag_off.v:9: $dumpvar ignored, as Verilated without --trace
*-* All Finished *-*
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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.
# Test that without --trace we get a message when turning on traces
scenarios(vlt => 1);
compile(
);
execute(
expect_filename => $Self->{golden_filename},
fails => 0,
);
ok(1);
1;
+13
View File
@@ -0,0 +1,13 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2020 by Wilson Snyder.
module t(/*AUTOARG*/);
initial begin
$dumpfile("/should/not/be/opened");
$dumpvars();
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
+48 -1
View File
@@ -3,6 +3,9 @@
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2020 by Wilson Snyder.
`define CONCAT(a, b) a``b
`define STRINGIFY(x) `"x`"
module t (/*AUTOARG*/
// Inputs
clk
@@ -15,11 +18,55 @@ module t (/*AUTOARG*/
sub sub ();
// verilator tracing_off
string filename;
// verilator tracing_on
initial begin
`ifdef TEST_FST
filename = {`STRINGIFY(`TEST_OBJ_DIR), "/simx.fst"};
`else
filename = {`STRINGIFY(`TEST_OBJ_DIR), "/simx.vcd"};
`endif
`ifdef TEST_DUMP
$dumpfile(filename);
$dumpvars(0, top);
$dumplimit(10 * 1024 * 1024);
`elsif TEST_DUMPPORTS
$dumpports(top, filename);
$dumpportslimit(10 * 1024 * 1024, filename);
`endif
end
always @ (posedge clk) begin
if (cyc != 0) begin
cyc <= cyc + 1;
c_trace_on <= cyc + 2;
if (cyc == 10) begin
if (cyc == 3) begin
`ifdef TEST_DUMP
$dumpoff;
`elsif TEST_DUMPPORTS
$dumpportsoff(filename);
`endif
end
else if (cyc == 5) begin
`ifdef TEST_DUMP
$dumpall;
$dumpflush;
`elsif TEST_DUMPPORTS
$dumpportsall(filename);
$dumpportsflush(filename);
`endif
end
else if (cyc == 7) begin
`ifdef TEST_DUMP
$dumpon;
`elsif TEST_DUMPPORTS
$dumpportson(filename);
`endif
end
else if (cyc == 10) begin
$write("*-* All Finished *-*\n");
$finish;
end
@@ -9,7 +9,13 @@
#include VM_PREFIX_INCLUDE
#include "Vt_trace_two_b.h"
#include "verilated.h"
#include "verilated_vcd_c.h"
#ifdef TEST_HDR_TRACE
# ifdef TEST_FST
# include "verilated_fst_c.h"
# else
# include "verilated_vcd_c.h"
# endif
#endif
// Compile in place
#include "Vt_trace_two_b.cpp"
@@ -26,18 +32,28 @@ int main(int argc, char** argv, char** env) {
double sim_time = 1100;
Verilated::commandArgs(argc, argv);
Verilated::debug(0);
Verilated::traceEverOn(true);
srand48(5);
ap = new VM_PREFIX("topa");
bp = new Vt_trace_two_b("topb");
ap->eval();
bp->eval();
ap->eval_step();
bp->eval_step();
ap->eval_end_step();
bp->eval_end_step();
#if VM_TRACE
#ifdef TEST_HDR_TRACE
Verilated::traceEverOn(true);
# ifdef TEST_FST
VerilatedFstC* tfp = new VerilatedFstC;
ap->trace(tfp, 99);
bp->trace(tfp, 99);
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.fst");
# else
VerilatedVcdC* tfp = new VerilatedVcdC;
ap->trace(tfp, 99);
bp->trace(tfp, 99);
tfp->open(VL_STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
# endif
if (tfp) tfp->dump(main_time);
#endif
{
@@ -48,11 +64,13 @@ int main(int argc, char** argv, char** env) {
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
ap->clk = !ap->clk;
bp->clk = ap->clk;
ap->eval();
bp->eval();
#if VM_TRACE
ap->eval_step();
bp->eval_step();
ap->eval_end_step();
bp->eval_end_step();
#ifdef TEST_HDR_TRACE
if (tfp) tfp->dump(main_time);
#endif // VM_TRACE
#endif
main_time += 5;
}
if (!Verilated::gotFinish()) {
@@ -60,9 +78,9 @@ int main(int argc, char** argv, char** env) {
}
ap->final();
bp->final();
#if VM_TRACE
#ifdef TEST_HDR_TRACE
if (tfp) tfp->close();
#endif // VM_TRACE
#endif
VL_DO_DANGLING(delete ap, ap);
VL_DO_DANGLING(delete bp, bp);
+102
View File
@@ -0,0 +1,102 @@
$version Generated by VerilatedVcd $end
$date Sun Mar 1 20:48:56 2020
$end
$timescale 1ns $end
$scope module topa $end
$var wire 1 3 clk $end
$scope module t $end
$var wire 32 + c_trace_on [31:0] $end
$var wire 1 3 clk $end
$var wire 32 # cyc [31:0] $end
$scope module sub $end
$var wire 32 ; inside_sub_a [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000001 #
b00000000000000000000000000000000 +
03
b00000000000000000000000000000001 ;
#0
#10
#10
b00000000000000000000000000000010 #
b00000000000000000000000000000011 +
13
#15
#15
03
#20
#20
b00000000000000000000000000000011 #
b00000000000000000000000000000100 +
13
#25
#25
03
#30
#30
b00000000000000000000000000000100 #
b00000000000000000000000000000101 +
13
#35
#35
03
#40
#40
b00000000000000000000000000000101 #
b00000000000000000000000000000110 +
13
#45
#45
03
#50
#50
b00000000000000000000000000000110 #
b00000000000000000000000000000111 +
13
#55
#55
03
#60
#60
b00000000000000000000000000000111 #
b00000000000000000000000000001000 +
13
#65
#65
03
#70
#70
b00000000000000000000000000001000 #
b00000000000000000000000000001001 +
13
#75
#75
03
#80
#80
b00000000000000000000000000001001 #
b00000000000000000000000000001010 +
13
#85
#85
03
#90
#90
b00000000000000000000000000001010 #
b00000000000000000000000000001011 +
13
#95
#95
03
#100
#100
b00000000000000000000000000001011 #
b00000000000000000000000000001100 +
13
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2020 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.
# Test tracing with two models instanced
scenarios(vlt_all => 1);
top_filename("t_trace_two_a.v");
compile(
make_main => 0,
verilator_make_gmake => 0,
top_filename => 't_trace_two_b.v',
VM_PREFIX => 'Vt_trace_two_b',
verilator_flags2 => ['-trace'],
);
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
verilator_flags2 => ['-exe', '-trace', "$Self->{t_dir}/t_trace_two_cc.cpp"],
v_flags2 => ['+define+TEST_DUMP'],
);
execute(
check_finished => 1,
);
if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
}
ok(1);
1;
+81
View File
@@ -0,0 +1,81 @@
$version Generated by VerilatedVcd $end
$date Sun Mar 1 20:49:13 2020
$end
$timescale 1ps $end
$scope module topa $end
$scope module t $end
$var wire 32 3 c_trace_on [31:0] $end
$var wire 1 # clk $end
$var wire 32 + cyc [31:0] $end
$scope module sub $end
$var wire 32 ; inside_sub_a [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
0#
b00000000000000000000000000000001 +
b00000000000000000000000000000000 3
b00000000000000000000000000000001 ;
#10000
1#
b00000000000000000000000000000010 +
b00000000000000000000000000000011 3
#15000
0#
#20000
1#
b00000000000000000000000000000011 +
b00000000000000000000000000000100 3
#25000
0#
#30000
1#
b00000000000000000000000000000100 +
b00000000000000000000000000000101 3
#35000
0#
#40000
1#
b00000000000000000000000000000101 +
b00000000000000000000000000000110 3
#45000
0#
#50000
1#
b00000000000000000000000000000110 +
b00000000000000000000000000000111 3
#55000
0#
#60000
1#
b00000000000000000000000000000111 +
b00000000000000000000000000001000 3
#65000
0#
#70000
1#
b00000000000000000000000000001000 +
b00000000000000000000000000001001 3
#75000
0#
#80000
1#
b00000000000000000000000000001001 +
b00000000000000000000000000001010 3
#85000
0#
#90000
1#
b00000000000000000000000000001010 +
b00000000000000000000000000001011 3
#95000
0#
#100000
1#
b00000000000000000000000000001011 +
b00000000000000000000000000001100 3
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2020 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.
scenarios(simulator => 1);
if (!$Self->have_sc) {
skip("No SystemC installed");
}
else {
top_filename("t_trace_two_a.v");
compile(
make_main => 0,
verilator_make_gmake => 0,
top_filename => 't_trace_two_b.v',
VM_PREFIX => 'Vt_trace_two_b',
verilator_flags2 => ['-sc -trace'],
);
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
verilator_flags2 => ['-sc', '-exe', '-trace',
"$Self->{t_dir}/t_trace_two_sc.cpp"],
v_flags2 => ['+define+TEST_DUMP'],
);
execute(
check_finished => 1,
);
if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
}
}
ok(1);
1;
+83
View File
@@ -0,0 +1,83 @@
$date
Sun Mar 1 21:31:56 2020
$end
$version
fstWriter
$end
$timescale
1ns
$end
$scope module topa $end
$var wire 1 ! clk $end
$scope module t $end
$var wire 1 ! clk $end
$var integer 32 " cyc $end
$var integer 32 # c_trace_on $end
$scope module sub $end
$var integer 32 $ inside_sub_a $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
$dumpvars
#0
0!
#10
1!
b00000000000000000000000000000011 #
b00000000000000000000000000000010 "
#15
0!
#20
1!
b00000000000000000000000000000011 "
b00000000000000000000000000000100 #
#25
0!
#30
1!
b00000000000000000000000000000101 #
b00000000000000000000000000000100 "
#35
0!
#40
1!
b00000000000000000000000000000101 "
b00000000000000000000000000000110 #
#45
0!
#50
1!
b00000000000000000000000000000111 #
b00000000000000000000000000000110 "
#55
0!
#60
1!
b00000000000000000000000000000111 "
b00000000000000000000000000001000 #
#65
0!
#70
1!
b00000000000000000000000000001001 #
b00000000000000000000000000001000 "
#75
0!
#80
1!
b00000000000000000000000000001001 "
b00000000000000000000000000001010 #
#85
0!
#90
1!
b00000000000000000000000000001011 #
b00000000000000000000000000001010 "
#95
0!
#100
1!
b00000000000000000000000000001011 "
b00000000000000000000000000001100 #
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2020 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.
# Test tracing with two models instanced
scenarios(vlt_all => 1);
top_filename("t_trace_two_a.v");
compile(
make_main => 0,
verilator_make_gmake => 0,
top_filename => 't_trace_two_b.v',
VM_PREFIX => 'Vt_trace_two_b',
verilator_flags2 => ['--trace-fst-thread -DTEST_FST'],
);
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
verilator_flags2 => ['-exe', '--trace-fst-thread',
'-DTEST_FST',
"$Self->{t_dir}/t_trace_two_cc.cpp"],
v_flags2 => ['+define+TEST_DUMP'],
);
execute(
check_finished => 1,
);
if ($Self->{vlt_all}) {
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", $Self->{golden_filename});
}
ok(1);
1;
+2 -1
View File
@@ -23,7 +23,8 @@ compile(
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
verilator_flags2 => ['-exe', '-trace', "$Self->{t_dir}/t_trace_two_hdr_cc.cpp"],
make_flags => 'CPPFLAGS_ADD=-DTEST_HDR_TRACE=1',
verilator_flags2 => ['-exe', '-trace', "$Self->{t_dir}/t_trace_two_cc.cpp"],
);
execute(
+2 -1
View File
@@ -26,8 +26,9 @@ else {
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
make_flags => 'CPPFLAGS_ADD=-DTEST_HDR_TRACE',
verilator_flags2 => ['-sc', '-exe', '-trace',
"$Self->{t_dir}/t_trace_two_hdr_sc.cpp"],
"$Self->{t_dir}/t_trace_two_sc.cpp"],
);
execute(
Binary file not shown.
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2020 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.
# Test tracing with two models instanced
scenarios(vlt_all => 1);
top_filename("t_trace_two_a.v");
compile(
make_main => 0,
verilator_make_gmake => 0,
top_filename => 't_trace_two_b.v',
VM_PREFIX => 'Vt_trace_two_b',
verilator_flags2 => ['--trace-fst-thread'],
);
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
make_flags => 'CPPFLAGS_ADD="-DTEST_HDR_TRACE=1 -DTEST_FST=1"',
verilator_flags2 => ['-exe', '--trace-fst-thread',
'-DTEST_FST',
"$Self->{t_dir}/t_trace_two_cc.cpp"],
);
execute(
check_finished => 1,
);
if ($Self->{vlt_all}) {
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", $Self->{golden_filename});
}
ok(1);
1;
+102
View File
@@ -0,0 +1,102 @@
$version Generated by VerilatedVcd $end
$date Sun Mar 1 21:32:13 2020
$end
$timescale 1ns $end
$scope module topa $end
$var wire 1 3 clk $end
$scope module t $end
$var wire 32 + c_trace_on [31:0] $end
$var wire 1 3 clk $end
$var wire 32 # cyc [31:0] $end
$scope module sub $end
$var wire 32 ; inside_sub_a [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
b00000000000000000000000000000001 #
b00000000000000000000000000000000 +
03
b00000000000000000000000000000001 ;
#0
#10
#10
b00000000000000000000000000000010 #
b00000000000000000000000000000011 +
13
#15
#15
03
#20
#20
b00000000000000000000000000000011 #
b00000000000000000000000000000100 +
13
#25
#25
03
#30
#30
b00000000000000000000000000000100 #
b00000000000000000000000000000101 +
13
#35
#35
03
#40
#40
b00000000000000000000000000000101 #
b00000000000000000000000000000110 +
13
#45
#45
03
#50
#50
b00000000000000000000000000000110 #
b00000000000000000000000000000111 +
13
#55
#55
03
#60
#60
b00000000000000000000000000000111 #
b00000000000000000000000000001000 +
13
#65
#65
03
#70
#70
b00000000000000000000000000001000 #
b00000000000000000000000000001001 +
13
#75
#75
03
#80
#80
b00000000000000000000000000001001 #
b00000000000000000000000000001010 +
13
#85
#85
03
#90
#90
b00000000000000000000000000001010 #
b00000000000000000000000000001011 +
13
#95
#95
03
#100
#100
b00000000000000000000000000001011 #
b00000000000000000000000000001100 +
13
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2020 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.
# Test tracing with two models instanced
scenarios(vlt_all => 1);
top_filename("t_trace_two_a.v");
compile(
make_main => 0,
verilator_make_gmake => 0,
top_filename => 't_trace_two_b.v',
VM_PREFIX => 'Vt_trace_two_b',
verilator_flags2 => ['-trace'],
);
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
verilator_flags2 => ['-exe', '-trace', "$Self->{t_dir}/t_trace_two_cc.cpp"],
v_flags2 => ['+define+TEST_DUMPPORTS'],
);
execute(
check_finished => 1,
);
if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
}
ok(1);
1;
+81
View File
@@ -0,0 +1,81 @@
$version Generated by VerilatedVcd $end
$date Sun Mar 1 21:32:22 2020
$end
$timescale 1ps $end
$scope module topa $end
$scope module t $end
$var wire 32 3 c_trace_on [31:0] $end
$var wire 1 # clk $end
$var wire 32 + cyc [31:0] $end
$scope module sub $end
$var wire 32 ; inside_sub_a [31:0] $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
#0
0#
b00000000000000000000000000000001 +
b00000000000000000000000000000000 3
b00000000000000000000000000000001 ;
#10000
1#
b00000000000000000000000000000010 +
b00000000000000000000000000000011 3
#15000
0#
#20000
1#
b00000000000000000000000000000011 +
b00000000000000000000000000000100 3
#25000
0#
#30000
1#
b00000000000000000000000000000100 +
b00000000000000000000000000000101 3
#35000
0#
#40000
1#
b00000000000000000000000000000101 +
b00000000000000000000000000000110 3
#45000
0#
#50000
1#
b00000000000000000000000000000110 +
b00000000000000000000000000000111 3
#55000
0#
#60000
1#
b00000000000000000000000000000111 +
b00000000000000000000000000001000 3
#65000
0#
#70000
1#
b00000000000000000000000000001000 +
b00000000000000000000000000001001 3
#75000
0#
#80000
1#
b00000000000000000000000000001001 +
b00000000000000000000000000001010 3
#85000
0#
#90000
1#
b00000000000000000000000000001010 +
b00000000000000000000000000001011 3
#95000
0#
#100000
1#
b00000000000000000000000000001011 +
b00000000000000000000000000001100 3
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2020 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.
scenarios(simulator => 1);
if (!$Self->have_sc) {
skip("No SystemC installed");
}
else {
top_filename("t_trace_two_a.v");
compile(
make_main => 0,
verilator_make_gmake => 0,
top_filename => 't_trace_two_b.v',
VM_PREFIX => 'Vt_trace_two_b',
verilator_flags2 => ['-sc -trace'],
);
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
verilator_flags2 => ['-sc', '-exe', '-trace',
"$Self->{t_dir}/t_trace_two_sc.cpp"],
v_flags2 => ['+define+TEST_DUMPPORTS'],
);
execute(
check_finished => 1,
);
if ($Self->{vlt_all}) {
file_grep("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
}
}
ok(1);
1;
+83
View File
@@ -0,0 +1,83 @@
$date
Sun Mar 1 21:32:04 2020
$end
$version
fstWriter
$end
$timescale
1ns
$end
$scope module topa $end
$var wire 1 ! clk $end
$scope module t $end
$var wire 1 ! clk $end
$var integer 32 " cyc $end
$var integer 32 # c_trace_on $end
$scope module sub $end
$var integer 32 $ inside_sub_a $end
$upscope $end
$upscope $end
$upscope $end
$enddefinitions $end
$dumpvars
#0
0!
#10
1!
b00000000000000000000000000000011 #
b00000000000000000000000000000010 "
#15
0!
#20
1!
b00000000000000000000000000000011 "
b00000000000000000000000000000100 #
#25
0!
#30
1!
b00000000000000000000000000000101 #
b00000000000000000000000000000100 "
#35
0!
#40
1!
b00000000000000000000000000000101 "
b00000000000000000000000000000110 #
#45
0!
#50
1!
b00000000000000000000000000000111 #
b00000000000000000000000000000110 "
#55
0!
#60
1!
b00000000000000000000000000000111 "
b00000000000000000000000000001000 #
#65
0!
#70
1!
b00000000000000000000000000001001 #
b00000000000000000000000000001000 "
#75
0!
#80
1!
b00000000000000000000000000001001 "
b00000000000000000000000000001010 #
#85
0!
#90
1!
b00000000000000000000000000001011 #
b00000000000000000000000000001010 "
#95
0!
#100
1!
b00000000000000000000000000001011 "
b00000000000000000000000000001100 #
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2020 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.
# Test tracing with two models instanced
scenarios(vlt_all => 1);
top_filename("t_trace_two_a.v");
compile(
make_main => 0,
verilator_make_gmake => 0,
top_filename => 't_trace_two_b.v',
VM_PREFIX => 'Vt_trace_two_b',
verilator_flags2 => ['--trace-fst-thread'],
);
compile(
make_main => 0,
top_filename => 't_trace_two_a.v',
verilator_flags2 => ['-exe', '--trace-fst-thread',
'-DTEST_FST',
"$Self->{t_dir}/t_trace_two_cc.cpp"],
v_flags2 => ['+define+TEST_DUMPPORTS'],
);
execute(
check_finished => 1,
);
if ($Self->{vlt_all}) {
fst2vcd($Self->trace_filename, "$Self->{obj_dir}/simx-fst2vcd.vcd");
vcd_identical("$Self->{obj_dir}/simx-fst2vcd.vcd", $Self->{golden_filename});
}
ok(1);
1;
@@ -9,7 +9,9 @@
#include VM_PREFIX_INCLUDE
#include "Vt_trace_two_b.h"
#include "verilated.h"
#include "verilated_vcd_c.h"
#ifdef TEST_HDR_TRACE
# include "verilated_vcd_sc.h"
#endif
// Compile in place
#include "Vt_trace_two_b.cpp"
@@ -20,7 +22,6 @@
// General headers
#include "verilated.h"
#include "systemc.h"
#include "verilated_vcd_sc.h"
VM_PREFIX* ap;
Vt_trace_two_b* bp;
@@ -29,6 +30,7 @@ int sc_main(int argc, char** argv) {
sc_signal<bool> clk;
sc_time sim_time(1100, SC_NS);
Verilated::commandArgs(argc, argv);
Verilated::traceEverOn(true);
Verilated::debug(0);
srand48(5);
ap = new VM_PREFIX("topa");
@@ -36,8 +38,7 @@ int sc_main(int argc, char** argv) {
ap->clk(clk);
bp->clk(clk);
#if VM_TRACE
Verilated::traceEverOn(true);
#ifdef TEST_HDR_TRACE
VerilatedVcdSc* tfp = new VerilatedVcdSc;
ap->trace(tfp, 99);
bp->trace(tfp, 99);
@@ -64,9 +65,9 @@ int sc_main(int argc, char** argv) {
}
ap->final();
bp->final();
#if VM_TRACE
#ifdef TEST_HDR_TRACE
if (tfp) tfp->close();
#endif // VM_TRACE
#endif
VL_DO_DANGLING(delete ap, ap);
VL_DO_DANGLING(delete bp, bp);