mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 04:57:25 -04:00
DV: Add verilator simulation utility
This commit is contained in:
parent
677153f549
commit
b72f5db6bd
4 changed files with 690 additions and 0 deletions
133
dv/verilator/simutil_verilator/cpp/verilated_toplevel.h
Normal file
133
dv/verilator/simutil_verilator/cpp/verilated_toplevel.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef VERILATED_TOPLEVEL_H_
|
||||
#define VERILATED_TOPLEVEL_H_
|
||||
|
||||
#include <verilated.h>
|
||||
|
||||
// VM_TRACE_FMT_FST must be set by the user when calling Verilator with
|
||||
// --trace-fst. VM_TRACE is set by Verilator itself.
|
||||
#if VM_TRACE == 1
|
||||
# ifdef VM_TRACE_FMT_FST
|
||||
# include "verilated_fst_c.h"
|
||||
# define VM_TRACE_CLASS_NAME VerilatedFstC
|
||||
# else
|
||||
# include "verilated_vcd_c.h"
|
||||
# define VM_TRACE_CLASS_NAME VerilatedVcdC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if VM_TRACE == 1
|
||||
/**
|
||||
* "Base" for all tracers in Verilator with common functionality
|
||||
*
|
||||
* This class is (like the VerilatedToplevel class) a workaround for the
|
||||
* insufficient class hierarchy in Verilator-generated C++ code.
|
||||
*
|
||||
* Once Verilator is improved to support this functionality natively this class
|
||||
* should go away.
|
||||
*/
|
||||
class VerilatedTracer {
|
||||
public:
|
||||
VerilatedTracer() : impl_(nullptr) {
|
||||
impl_ = new VM_TRACE_CLASS_NAME();
|
||||
};
|
||||
|
||||
~VerilatedTracer() {
|
||||
delete impl_;
|
||||
}
|
||||
|
||||
|
||||
bool isOpen() const {
|
||||
return impl_->isOpen();
|
||||
};
|
||||
|
||||
void open(const char* filename) {
|
||||
impl_->open(filename);
|
||||
};
|
||||
|
||||
void close() {
|
||||
impl_->close();
|
||||
};
|
||||
|
||||
void dump(vluint64_t timeui) {
|
||||
impl_->dump(timeui);
|
||||
}
|
||||
|
||||
operator VM_TRACE_CLASS_NAME*() const { assert(impl_); return impl_; }
|
||||
|
||||
private:
|
||||
VM_TRACE_CLASS_NAME* impl_;
|
||||
};
|
||||
#else
|
||||
/**
|
||||
* No-op tracer interface
|
||||
*/
|
||||
class VerilatedTracer {
|
||||
public:
|
||||
VerilatedTracer() {};
|
||||
~VerilatedTracer() {}
|
||||
bool isOpen() const { return false; };
|
||||
void open(const char* filename) {};
|
||||
void close() {};
|
||||
void dump(vluint64_t timeui) {}
|
||||
};
|
||||
#endif // VM_TRACE == 1
|
||||
|
||||
/**
|
||||
* Pure abstract class (interface) for verilated toplevel modules
|
||||
*
|
||||
* Verilator-produced toplevel modules do not have a common base class defining
|
||||
* the methods such as eval(); instead, they are only inheriting from the
|
||||
* generic VerilatedModule class, which doesn't have toplevel-specific
|
||||
* functionality. This makes it impossible to write code which accepts any
|
||||
* toplevel module as input by specifying the common "toplevel base class".
|
||||
*
|
||||
* This class, VerilatedToplevel, fills this gap by defining an abstract base
|
||||
* class for verilated toplevel modules. This class should be used together with
|
||||
* the VERILATED_TOPLEVEL macro.
|
||||
*
|
||||
* Note that this function is a workaround until Verilator gains this
|
||||
* functionality natively.
|
||||
*
|
||||
* To support the different tracing implementations (VCD, FST or no tracing),
|
||||
* the trace() function is modified to take a VerilatedTracer argument instead
|
||||
* of the tracer-specific class.
|
||||
*/
|
||||
class VerilatedToplevel {
|
||||
public:
|
||||
VerilatedToplevel() {};
|
||||
virtual ~VerilatedToplevel() {};
|
||||
|
||||
virtual void eval() = 0;
|
||||
virtual void final() = 0;
|
||||
virtual const char* name() const = 0;
|
||||
virtual void trace(VerilatedTracer& tfp, int levels, int options) = 0;
|
||||
};
|
||||
|
||||
#define STR(s) #s
|
||||
|
||||
#if VM_TRACE == 1
|
||||
#define VERILATED_TOPLEVEL_TRACE_CALL(topname) \
|
||||
V##topname::trace(static_cast<VM_TRACE_CLASS_NAME*>(tfp), levels, options);
|
||||
#else
|
||||
#define VERILATED_TOPLEVEL_TRACE_CALL(topname) \
|
||||
assert(0 && "Tracing not enabled.");
|
||||
#endif
|
||||
|
||||
|
||||
#define VERILATED_TOPLEVEL(topname) \
|
||||
class topname : public V##topname, public VerilatedToplevel { \
|
||||
public: \
|
||||
topname(const char* name="TOP") : V##topname(name), VerilatedToplevel() {} \
|
||||
const char* name() const { return STR(topname); } \
|
||||
void eval() { V##topname::eval(); } \
|
||||
void final() { V##topname::final(); } \
|
||||
void trace(VerilatedTracer& tfp, int levels, int options=0) { \
|
||||
VERILATED_TOPLEVEL_TRACE_CALL(topname) \
|
||||
} \
|
||||
};
|
||||
|
||||
#endif // VERILATED_TOPLEVEL_H_
|
381
dv/verilator/simutil_verilator/cpp/verilator_sim_ctrl.cc
Normal file
381
dv/verilator/simutil_verilator/cpp/verilator_sim_ctrl.cc
Normal file
|
@ -0,0 +1,381 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "verilator_sim_ctrl.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <vltstd/svdpi.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// This is defined by Verilator and passed through the command line
|
||||
#ifndef VM_TRACE
|
||||
#define VM_TRACE 0
|
||||
#endif
|
||||
|
||||
// DPI Exports
|
||||
extern "C" {
|
||||
extern void simutil_verilator_memload(const char* file);
|
||||
}
|
||||
|
||||
VerilatorSimCtrl::VerilatorSimCtrl(VerilatedToplevel* top, CData& sig_clk,
|
||||
CData& sig_rst, VerilatorSimCtrlFlags flags)
|
||||
: top_(top),
|
||||
sig_clk_(sig_clk),
|
||||
sig_rst_(sig_rst),
|
||||
flags_(flags),
|
||||
time_(0),
|
||||
init_rom_(false),
|
||||
init_ram_(false),
|
||||
init_flash_(false),
|
||||
tracing_enabled_(false),
|
||||
tracing_enabled_changed_(false),
|
||||
tracing_ever_enabled_(false),
|
||||
tracing_possible_(VM_TRACE),
|
||||
initial_reset_delay_cycles_(2),
|
||||
reset_duration_cycles_(2),
|
||||
request_stop_(false),
|
||||
tracer_(VerilatedTracer()),
|
||||
term_after_cycles_(0) {}
|
||||
|
||||
void VerilatorSimCtrl::RequestStop() { request_stop_ = true; }
|
||||
|
||||
bool VerilatorSimCtrl::TraceOn() {
|
||||
bool old_tracing_enabled = tracing_enabled_;
|
||||
|
||||
tracing_enabled_ = tracing_possible_;
|
||||
tracing_ever_enabled_ = tracing_enabled_;
|
||||
|
||||
if (old_tracing_enabled != tracing_enabled_) {
|
||||
tracing_enabled_changed_ = true;
|
||||
}
|
||||
return tracing_enabled_;
|
||||
}
|
||||
|
||||
bool VerilatorSimCtrl::TraceOff() {
|
||||
if (tracing_enabled_) {
|
||||
tracing_enabled_changed_ = true;
|
||||
}
|
||||
tracing_enabled_ = false;
|
||||
return tracing_enabled_;
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::PrintHelp() const {
|
||||
std::cout << "Execute a simulation model for " << top_->name()
|
||||
<< "\n"
|
||||
"\n";
|
||||
if (tracing_possible_) {
|
||||
std::cout << "-t|--trace Write a trace file from the start\n";
|
||||
}
|
||||
std::cout << "-r|--rominit=VMEMFILE Initialize the ROM with VMEMFILE\n"
|
||||
"-m|--raminit=VMEMFILE Initialize the RAM with VMEMFILE\n"
|
||||
"-f|--flashinit=VMEMFILE Initialize the FLASH with VMEMFILE\n"
|
||||
"-h|--help Show help\n"
|
||||
"\n"
|
||||
"All further arguments are passed to the design and can be used "
|
||||
"in the \n"
|
||||
"design, e.g. by DPI modules.\n";
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::InitRom(std::string rom) {
|
||||
if (!init_rom_) {
|
||||
return;
|
||||
}
|
||||
|
||||
svScope scope;
|
||||
|
||||
scope = svGetScopeFromName(rom.data());
|
||||
if (!scope) {
|
||||
std::cerr << "ERROR: No ROM found at " << rom << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
svSetScope(scope);
|
||||
|
||||
simutil_verilator_memload(rom_init_file_.data());
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Rom initialized with program at " << rom_init_file_
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::InitRam(std::string ram) {
|
||||
if (!init_ram_) {
|
||||
return;
|
||||
}
|
||||
|
||||
svScope scope;
|
||||
|
||||
scope = svGetScopeFromName(ram.data());
|
||||
if (!scope) {
|
||||
std::cerr << "ERROR: No RAM found at " << ram << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
svSetScope(scope);
|
||||
|
||||
simutil_verilator_memload(ram_init_file_.data());
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Ram initialized with program at " << ram_init_file_
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::InitFlash(std::string flash) {
|
||||
if (!init_flash_) {
|
||||
return;
|
||||
}
|
||||
|
||||
svScope scope;
|
||||
|
||||
scope = svGetScopeFromName(flash.data());
|
||||
if (!scope) {
|
||||
std::cerr << "ERROR: No FLASH found at " << flash << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
svSetScope(scope);
|
||||
|
||||
simutil_verilator_memload(flash_init_file_.data());
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Flash initialized with program at " << flash_init_file_
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
bool VerilatorSimCtrl::ParseCommandArgs(int argc, char** argv, int& retcode) {
|
||||
const struct option long_options[] = {
|
||||
{"rominit", required_argument, nullptr, 'r'},
|
||||
{"raminit", required_argument, nullptr, 'm'},
|
||||
{"flashinit", required_argument, nullptr, 'f'},
|
||||
{"term-after-cycles", required_argument, nullptr, 'c'},
|
||||
{"trace", no_argument, nullptr, 't'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{nullptr, no_argument, nullptr, 0}};
|
||||
|
||||
while (1) {
|
||||
int c = getopt_long(argc, argv, ":r:m:f:th", long_options, nullptr);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable error reporting by getopt
|
||||
opterr = 0;
|
||||
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case 'r':
|
||||
rom_init_file_ = optarg;
|
||||
init_rom_ = true;
|
||||
if (!IsFileReadable(rom_init_file_)) {
|
||||
std::cerr << "ERROR: ROM initialization file "
|
||||
<< "'" << rom_init_file_ << "'"
|
||||
<< " is not readable." << std::endl;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
ram_init_file_ = optarg;
|
||||
init_ram_ = true;
|
||||
if (!IsFileReadable(ram_init_file_)) {
|
||||
std::cerr << "ERROR: Memory initialization file "
|
||||
<< "'" << ram_init_file_ << "'"
|
||||
<< " is not readable." << std::endl;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
flash_init_file_ = optarg;
|
||||
init_flash_ = true;
|
||||
if (!IsFileReadable(flash_init_file_)) {
|
||||
std::cerr << "ERROR: FLASH initialization file "
|
||||
<< "'" << flash_init_file_ << "'"
|
||||
<< " is not readable." << std::endl;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (!tracing_possible_) {
|
||||
std::cerr << "ERROR: Tracing has not been enabled at compile time."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
TraceOn();
|
||||
break;
|
||||
case 'c':
|
||||
term_after_cycles_ = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
PrintHelp();
|
||||
return false;
|
||||
case ':': // missing argument
|
||||
std::cerr << "ERROR: Missing argument." << std::endl;
|
||||
PrintHelp();
|
||||
return false;
|
||||
case '?':
|
||||
default:;
|
||||
// Ignore unrecognized options since they might be consumed by
|
||||
// Verilator's built-in parsing below.
|
||||
}
|
||||
}
|
||||
|
||||
Verilated::commandArgs(argc, argv);
|
||||
return true;
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::Trace() {
|
||||
// We cannot output a message when calling TraceOn()/TraceOff() as these
|
||||
// functions can be called from a signal handler. Instead we print the message
|
||||
// here from the main loop.
|
||||
if (tracing_enabled_changed_) {
|
||||
if (TracingEnabled()) {
|
||||
std::cout << "Tracing enabled." << std::endl;
|
||||
} else {
|
||||
std::cout << "Tracing disabled." << std::endl;
|
||||
}
|
||||
tracing_enabled_changed_ = false;
|
||||
}
|
||||
|
||||
if (!TracingEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tracer_.isOpen()) {
|
||||
tracer_.open(GetSimulationFileName());
|
||||
std::cout << "Writing simulation traces to " << GetSimulationFileName()
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
tracer_.dump(GetTime());
|
||||
}
|
||||
|
||||
const char* VerilatorSimCtrl::GetSimulationFileName() const {
|
||||
#ifdef VM_TRACE_FMT_FST
|
||||
return "sim.fst";
|
||||
#else
|
||||
return "sim.vcd";
|
||||
#endif
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::Run() {
|
||||
// We always need to enable this as tracing can be enabled at runtime
|
||||
if (tracing_possible_) {
|
||||
Verilated::traceEverOn(true);
|
||||
top_->trace(tracer_, 99, 0);
|
||||
}
|
||||
|
||||
// Evaluate all initial blocks, including the DPI setup routines
|
||||
top_->eval();
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Simulation running, end by pressing CTRL-c." << std::endl;
|
||||
|
||||
time_begin_ = std::chrono::steady_clock::now();
|
||||
UnsetReset();
|
||||
Trace();
|
||||
while (1) {
|
||||
if (time_ >= initial_reset_delay_cycles_ * 2) {
|
||||
SetReset();
|
||||
}
|
||||
if (time_ >= reset_duration_cycles_ * 2 + initial_reset_delay_cycles_ * 2) {
|
||||
UnsetReset();
|
||||
}
|
||||
|
||||
sig_clk_ = !sig_clk_;
|
||||
|
||||
top_->eval();
|
||||
time_++;
|
||||
|
||||
Trace();
|
||||
|
||||
if (request_stop_) {
|
||||
std::cout << "Received stop request, shutting down simulation."
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
if (Verilated::gotFinish()) {
|
||||
std::cout << "Received $finish() from Verilog, shutting down simulation."
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
if (term_after_cycles_ && time_ > term_after_cycles_) {
|
||||
std::cout << "Simulation timeout of " << term_after_cycles_
|
||||
<< " cycles reached, shutting down simulation."
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
top_->final();
|
||||
time_end_ = std::chrono::steady_clock::now();
|
||||
|
||||
if (TracingEverEnabled()) {
|
||||
tracer_.close();
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::SetReset() {
|
||||
if (flags_ & ResetPolarityNegative) {
|
||||
sig_rst_ = 0;
|
||||
} else {
|
||||
sig_rst_ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::UnsetReset() {
|
||||
if (flags_ & ResetPolarityNegative) {
|
||||
sig_rst_ = 1;
|
||||
} else {
|
||||
sig_rst_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::SetInitialResetDelay(unsigned int cycles) {
|
||||
initial_reset_delay_cycles_ = cycles;
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::SetResetDuration(unsigned int cycles) {
|
||||
reset_duration_cycles_ = cycles;
|
||||
}
|
||||
|
||||
bool VerilatorSimCtrl::IsFileReadable(std::string filepath) {
|
||||
struct stat statbuf;
|
||||
return stat(filepath.data(), &statbuf) == 0;
|
||||
}
|
||||
|
||||
bool VerilatorSimCtrl::FileSize(std::string filepath, int& size_byte) {
|
||||
struct stat statbuf;
|
||||
if (stat(filepath.data(), &statbuf) != 0) {
|
||||
size_byte = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
size_byte = statbuf.st_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int VerilatorSimCtrl::GetExecutionTimeMs() {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(time_end_ -
|
||||
time_begin_)
|
||||
.count();
|
||||
}
|
||||
|
||||
void VerilatorSimCtrl::PrintStatistics() {
|
||||
double speed_hz = time_ / 2 / (GetExecutionTimeMs() / 1000.0);
|
||||
double speed_khz = speed_hz / 1000.0;
|
||||
|
||||
std::cout << std::endl
|
||||
<< "Simulation statistics" << std::endl
|
||||
<< "=====================" << std::endl
|
||||
<< "Executed cycles: " << time_ / 2 << std::endl
|
||||
<< "Wallclock time: " << GetExecutionTimeMs() / 1000.0 << " s"
|
||||
<< std::endl
|
||||
<< "Simulation speed: " << speed_hz << " cycles/s "
|
||||
<< "(" << speed_khz << " kHz)" << std::endl;
|
||||
|
||||
int trace_size_byte;
|
||||
if (tracing_enabled_ && FileSize(GetSimulationFileName(), trace_size_byte)) {
|
||||
std::cout << "Trace file size: " << trace_size_byte << " B" << std::endl;
|
||||
}
|
||||
}
|
157
dv/verilator/simutil_verilator/cpp/verilator_sim_ctrl.h
Normal file
157
dv/verilator/simutil_verilator/cpp/verilator_sim_ctrl.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef VERILATOR_SIM_CTRL_H_
|
||||
#define VERILATOR_SIM_CTRL_H_
|
||||
|
||||
#include <verilated.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
#include "verilated_toplevel.h"
|
||||
|
||||
enum VerilatorSimCtrlFlags {
|
||||
Defaults = 0,
|
||||
ResetPolarityNegative = 1,
|
||||
};
|
||||
|
||||
class VerilatorSimCtrl {
|
||||
public:
|
||||
VerilatorSimCtrl(VerilatedToplevel* top, CData& clk, CData& rst_n,
|
||||
VerilatorSimCtrlFlags flags = Defaults);
|
||||
|
||||
/**
|
||||
* Print help how to use this tool
|
||||
*/
|
||||
void PrintHelp() const;
|
||||
|
||||
/**
|
||||
* Parse command line arguments
|
||||
*
|
||||
* This removes all recognized command-line arguments from argc/argv.
|
||||
*
|
||||
* The return value of this method indicates if the program should exit with
|
||||
* retcode: if this method returns true, do *not* exit; if it returns *false*,
|
||||
* do exit.
|
||||
*/
|
||||
bool ParseCommandArgs(int argc, char** argv, int& retcode);
|
||||
|
||||
/**
|
||||
* Run the main loop of the simulation
|
||||
*
|
||||
* This function blocks until the simulation finishes.
|
||||
*/
|
||||
void Run();
|
||||
|
||||
/**
|
||||
* Initialize Rom
|
||||
*/
|
||||
void InitRom(const std::string mem);
|
||||
|
||||
/**
|
||||
* Initialize Ram
|
||||
*/
|
||||
void InitRam(const std::string mem);
|
||||
|
||||
/**
|
||||
* Initialize Flash
|
||||
*/
|
||||
void InitFlash(const std::string mem);
|
||||
|
||||
/**
|
||||
* Get the current time in ticks
|
||||
*/
|
||||
unsigned long GetTime() { return time_; }
|
||||
|
||||
/**
|
||||
* Set the number of clock cycles (periods) before the reset signal is
|
||||
* activated
|
||||
*/
|
||||
void SetInitialResetDelay(unsigned int cycles);
|
||||
|
||||
/**
|
||||
* Set the number of clock cycles (periods) the reset signal is activated
|
||||
*/
|
||||
void SetResetDuration(unsigned int cycles);
|
||||
|
||||
/**
|
||||
* Request the simulation to stop
|
||||
*/
|
||||
void RequestStop();
|
||||
|
||||
/**
|
||||
* Enable tracing (if possible)
|
||||
*
|
||||
* Enabling tracing can fail if no tracing support has been compiled into the
|
||||
* simulation.
|
||||
*
|
||||
* @return Is tracing enabled?
|
||||
*/
|
||||
bool TraceOn();
|
||||
|
||||
/**
|
||||
* Disable tracing
|
||||
*
|
||||
* @return Is tracing enabled?
|
||||
*/
|
||||
bool TraceOff();
|
||||
|
||||
/**
|
||||
* Is tracing currently enabled?
|
||||
*/
|
||||
bool TracingEnabled() { return tracing_enabled_; }
|
||||
|
||||
/**
|
||||
* Has tracing been ever enabled during the run?
|
||||
*
|
||||
* Tracing can be enabled and disabled at runtime.
|
||||
*/
|
||||
bool TracingEverEnabled() { return tracing_ever_enabled_; }
|
||||
|
||||
/**
|
||||
* Is tracing support compiled into the simulation?
|
||||
*/
|
||||
bool TracingPossible() { return tracing_possible_; }
|
||||
|
||||
/**
|
||||
* Print statistics about the simulation run
|
||||
*/
|
||||
void PrintStatistics();
|
||||
|
||||
const char* GetSimulationFileName() const;
|
||||
|
||||
private:
|
||||
VerilatedToplevel* top_;
|
||||
CData& sig_clk_;
|
||||
CData& sig_rst_;
|
||||
VerilatorSimCtrlFlags flags_;
|
||||
unsigned long time_;
|
||||
bool init_rom_;
|
||||
bool init_ram_;
|
||||
bool init_flash_;
|
||||
std::string rom_init_file_;
|
||||
std::string ram_init_file_;
|
||||
std::string flash_init_file_;
|
||||
bool tracing_enabled_;
|
||||
bool tracing_enabled_changed_;
|
||||
bool tracing_ever_enabled_;
|
||||
bool tracing_possible_;
|
||||
unsigned int initial_reset_delay_cycles_;
|
||||
unsigned int reset_duration_cycles_;
|
||||
volatile unsigned int request_stop_;
|
||||
std::chrono::steady_clock::time_point time_begin_;
|
||||
std::chrono::steady_clock::time_point time_end_;
|
||||
VerilatedTracer tracer_;
|
||||
int term_after_cycles_;
|
||||
|
||||
unsigned int GetExecutionTimeMs();
|
||||
void SetReset();
|
||||
void UnsetReset();
|
||||
bool IsFileReadable(std::string filepath);
|
||||
bool FileSize(std::string filepath, int& size_byte);
|
||||
void Trace();
|
||||
};
|
||||
|
||||
#endif // VERILATOR_SIM_CTRL_H_
|
19
dv/verilator/simutil_verilator/simutil_verilator.core
Normal file
19
dv/verilator/simutil_verilator/simutil_verilator.core
Normal file
|
@ -0,0 +1,19 @@
|
|||
CAPI=2:
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: "lowrisc:dv_verilator:simutil_verilator"
|
||||
description: "Verilator simulator support"
|
||||
filesets:
|
||||
files_cpp:
|
||||
files:
|
||||
- cpp/verilator_sim_ctrl.cc
|
||||
- cpp/verilator_sim_ctrl.h: { is_include_file: true }
|
||||
- cpp/verilated_toplevel.h: { is_include_file: true }
|
||||
file_type: cppSource
|
||||
|
||||
targets:
|
||||
default:
|
||||
filesets:
|
||||
- files_cpp
|
Loading…
Add table
Add a link
Reference in a new issue