Introduced a unique main to the simulation. (#1368)
The main method centralizes more of the lifecycle of a simulation.
This commit is contained in:
parent
0c2e8dd6bc
commit
4d1876334e
|
@ -61,7 +61,6 @@ serial_t::serial_t(simif_t &simif,
|
|||
printf("\n");
|
||||
|
||||
tsi_argc = argc_count + 1;
|
||||
fesvr = new firesim_tsi_t(tsi_argc, tsi_argv, has_mem);
|
||||
}
|
||||
|
||||
serial_t::~serial_t() {
|
||||
|
@ -75,6 +74,11 @@ serial_t::~serial_t() {
|
|||
}
|
||||
|
||||
void serial_t::init() {
|
||||
// `ucontext` used by tsi cannot be created in one thread and resumed in
|
||||
// another. To ensure that the tsi process is on the correct thread, it is
|
||||
// built here, as the bridge constructor may be invoked from a thread other
|
||||
// than the one it will run on later in meta-simulations.
|
||||
fesvr = new firesim_tsi_t(tsi_argc, tsi_argv, has_mem);
|
||||
write(mmio_addrs.step_size, step_size);
|
||||
go();
|
||||
}
|
||||
|
|
|
@ -11,16 +11,14 @@ clang_tidy_files := $(shell \
|
|||
find $(firesim_base_dir) -name '*.cc' -or -name '*.h' \
|
||||
| grep -v generic_vharness.cc \
|
||||
| grep -v TestPointerChaser.cc \
|
||||
| grep -v simif.cc \
|
||||
| grep -v simif_ \
|
||||
| grep -v tracerv \
|
||||
| grep -v dromajo \
|
||||
| grep -v serial \
|
||||
| grep -v fesvr \
|
||||
| grep -v firesim_top \
|
||||
| grep -v generated-src \
|
||||
| grep -v output \
|
||||
| grep -v constructor.h \
|
||||
| grep -v -F 'main.cc' \
|
||||
)
|
||||
|
||||
clang_tidy_flags :=\
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <string_view>
|
||||
|
||||
#include "core/simif.h"
|
||||
#include "core/timing.h"
|
||||
|
||||
struct PEEKPOKEBRIDGEMODULE_struct {
|
||||
uint64_t STEP;
|
||||
|
|
|
@ -76,7 +76,7 @@ UARTBRIDGEMODULE_checks;
|
|||
#ifdef LOADMEMWIDGET_0_PRESENT
|
||||
registry.add_widget(new loadmem_t(simif,
|
||||
LOADMEMWIDGET_0_substruct_create,
|
||||
config.mem,
|
||||
conf_target.mem,
|
||||
LOADMEMWIDGET_0_mem_data_chunk));
|
||||
#endif // LOADMEMWIDGET_0_PRESENT
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
// See LICENSE for license details.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "core/config.h"
|
||||
#include "core/simif.h"
|
||||
#include "core/simulation.h"
|
||||
|
||||
#include "bridges/autocounter.h"
|
||||
#include "bridges/clock.h"
|
||||
#include "bridges/cpu_managed_stream.h"
|
||||
#include "bridges/fased_memory_timing_model.h"
|
||||
#include "bridges/fpga_managed_stream.h"
|
||||
#include "bridges/fpga_model.h"
|
||||
#include "bridges/loadmem.h"
|
||||
#include "bridges/master.h"
|
||||
#include "bridges/plusargs.h"
|
||||
#include "bridges/reset_pulse.h"
|
||||
#include "bridges/synthesized_assertions.h"
|
||||
#include "bridges/synthesized_prints.h"
|
||||
#include "bridges/termination.h"
|
||||
|
||||
#ifdef PEEKPOKEBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/peek_poke.h"
|
||||
#endif
|
||||
#ifdef BLOCKDEVBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/blockdev.h"
|
||||
#endif
|
||||
#ifdef DROMAJOBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/dromajo.h"
|
||||
#endif
|
||||
#ifdef GROUNDTESTBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/groundtest.h"
|
||||
#endif
|
||||
#ifdef SERIALBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/serial.h"
|
||||
#endif
|
||||
#ifdef SIMPLENICBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/simplenic.h"
|
||||
#endif
|
||||
#ifdef TRACERVBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/tracerv.h"
|
||||
#endif
|
||||
#ifdef UARTBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/uart.h"
|
||||
#endif
|
||||
|
||||
// The user-defined part of the driver implements this method to return
|
||||
// a simulation instance implementing all simulation-specific logic.
|
||||
extern std::unique_ptr<simulation_t>
|
||||
create_simulation(const std::vector<std::string> &args, simif_t &simif);
|
||||
|
||||
// The platform-specific component of the driver implements this method
|
||||
// to return a handle to the simulation.
|
||||
extern std::unique_ptr<simif_t>
|
||||
create_simif(const TargetConfig &config, int argc, char **argv);
|
||||
|
||||
// clang-format off
|
||||
|
||||
// Entry point of the driver.
|
||||
int main(int argc, char **argv) {
|
||||
std::vector<std::string> args(argv + 1, argv + argc);
|
||||
auto simif_ptr = create_simif(conf_target, argc, argv);
|
||||
|
||||
{
|
||||
auto &simif = *simif_ptr;
|
||||
auto ®istry = simif_ptr->get_registry();
|
||||
|
||||
// DOC include start: Bridge Driver Registration
|
||||
// Here we instantiate our driver once for each bridge in the target
|
||||
// Golden Gate emits a <BridgeModuleClassName>_<id>_PRESENT macro for each
|
||||
// instance which you may use to conditionally instantiate your driver.
|
||||
// This file can be included in the setup method of any top-level to pass
|
||||
// an instance of each driver to the `add_bridge_driver` method. Drivers can
|
||||
// be distinguished by overloading the method with the appropriate type.
|
||||
#include "constructor.h"
|
||||
// DOC include end: Bridge Driver Registration
|
||||
}
|
||||
|
||||
auto sim = create_simulation(args, *simif_ptr);
|
||||
return simif_ptr->run(*sim);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
// See LICENSE for license details.
|
||||
|
||||
#include "simif.h"
|
||||
#include "core/config.h"
|
||||
#include "core/simulation.h"
|
||||
#include "core/stream_engine.h"
|
||||
|
||||
|
@ -8,7 +9,7 @@
|
|||
|
||||
simif_t::simif_t(const TargetConfig &config,
|
||||
const std::vector<std::string> &args)
|
||||
: config(config), args(args) {
|
||||
: config(config), args(args), registry() {
|
||||
for (auto &arg : args) {
|
||||
if (arg.find("+fastloadmem") == 0) {
|
||||
fastloadmem = true;
|
||||
|
@ -22,7 +23,7 @@ simif_t::simif_t(const TargetConfig &config,
|
|||
}
|
||||
}
|
||||
|
||||
simif_t::~simif_t() {}
|
||||
simif_t::~simif_t() = default;
|
||||
|
||||
CPUManagedStreamIO &simif_t::get_cpu_managed_stream_io() {
|
||||
std::cerr << "CPU-managed streams are not supported" << std::endl;
|
||||
|
@ -35,14 +36,14 @@ FPGAManagedStreamIO &simif_t::get_fpga_managed_stream_io() {
|
|||
}
|
||||
|
||||
void simif_t::target_init() {
|
||||
auto &master = registry->get_widget<master_t>();
|
||||
auto &loadmem = registry->get_widget<loadmem_t>();
|
||||
auto &master = registry.get_widget<master_t>();
|
||||
auto &loadmem = registry.get_widget<loadmem_t>();
|
||||
|
||||
// Do any post-constructor initialization required before requesting MMIO
|
||||
while (!master.is_init_done())
|
||||
;
|
||||
|
||||
if (auto *stream = registry->get_stream_engine()) {
|
||||
if (auto *stream = registry.get_stream_engine()) {
|
||||
stream->init();
|
||||
}
|
||||
|
||||
|
@ -56,12 +57,9 @@ void simif_t::target_init() {
|
|||
}
|
||||
}
|
||||
|
||||
extern std::unique_ptr<simulation_t>
|
||||
create_simulation(const std::vector<std::string> &args, simif_t &simif);
|
||||
std::string_view simif_t::get_target_name() const { return config.target_name; }
|
||||
|
||||
int simif_t::simulation_run() {
|
||||
registry.reset(new widget_registry_t(config, *this, args));
|
||||
sim = create_simulation(args, *this);
|
||||
int simif_t::run(simulation_t &sim) {
|
||||
target_init();
|
||||
return sim->execute_simulation_flow();
|
||||
return sim.execute_simulation_flow();
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ class StreamEngine;
|
|||
class simulation_t;
|
||||
class CPUManagedStreamIO;
|
||||
class FPGAManagedStreamIO;
|
||||
class TargetConfig;
|
||||
|
||||
/** \class simif_t
|
||||
*
|
||||
|
@ -95,45 +96,45 @@ public:
|
|||
* (will report a larger number).
|
||||
*/
|
||||
uint64_t actual_tcycle() {
|
||||
return registry->get_widget<clockmodule_t>().tcycle();
|
||||
return registry.get_widget<clockmodule_t>().tcycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the current host cycle.
|
||||
*/
|
||||
uint64_t actual_hcycle() {
|
||||
return registry->get_widget<clockmodule_t>().hcycle();
|
||||
return registry.get_widget<clockmodule_t>().hcycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the simulated target.
|
||||
*/
|
||||
std::string_view get_target_name() const { return config.target_name; }
|
||||
std::string_view get_target_name() const;
|
||||
|
||||
/**
|
||||
* Return a reference to the registry which owns all widgets.
|
||||
*/
|
||||
widget_registry_t &get_registry() { return *registry; }
|
||||
widget_registry_t &get_registry() { return registry; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Waits for the target to be initialised.
|
||||
* Runs the simulation in the context of the driver.
|
||||
*
|
||||
* The default implementation initialises the target and hands control to
|
||||
* the driver routines, suitable for actual FPGA implementations.
|
||||
*/
|
||||
void target_init();
|
||||
|
||||
void load_mem(std::string filename);
|
||||
virtual int run(simulation_t &sim);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Simulation main loop.
|
||||
* Sets up the target and blocks until it is initialized.
|
||||
*/
|
||||
int simulation_run();
|
||||
void target_init();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Target configuration.
|
||||
*/
|
||||
const TargetConfig config;
|
||||
const TargetConfig &config;
|
||||
|
||||
/**
|
||||
* Saved command-line arguments.
|
||||
|
@ -143,12 +144,7 @@ protected:
|
|||
/**
|
||||
* Helper holding references to all bridges.
|
||||
*/
|
||||
std::unique_ptr<widget_registry_t> registry;
|
||||
|
||||
/**
|
||||
* Reference to the user-defined bits of the simulation.
|
||||
*/
|
||||
std::unique_ptr<simulation_t> sim;
|
||||
widget_registry_t registry;
|
||||
|
||||
/**
|
||||
* Path to load DRAM contents from.
|
||||
|
|
|
@ -2,55 +2,11 @@
|
|||
|
||||
#include "widget_registry.h"
|
||||
|
||||
#include "core/bridge_driver.h"
|
||||
|
||||
#include "bridges/autocounter.h"
|
||||
#include "bridges/clock.h"
|
||||
#include "bridges/cpu_managed_stream.h"
|
||||
#include "bridges/fased_memory_timing_model.h"
|
||||
#include "bridges/fpga_managed_stream.h"
|
||||
#include "bridges/fpga_model.h"
|
||||
#include "bridges/loadmem.h"
|
||||
#include "bridges/master.h"
|
||||
#include "bridges/plusargs.h"
|
||||
#include "bridges/reset_pulse.h"
|
||||
#include "bridges/synthesized_assertions.h"
|
||||
#include "bridges/synthesized_prints.h"
|
||||
#include "bridges/termination.h"
|
||||
#include "core/bridge_driver.h"
|
||||
#include "core/stream_engine.h"
|
||||
|
||||
#ifdef PEEKPOKEBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/peek_poke.h"
|
||||
#endif
|
||||
#ifdef BLOCKDEVBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/blockdev.h"
|
||||
#endif
|
||||
#ifdef DROMAJOBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/dromajo.h"
|
||||
#endif
|
||||
#ifdef GROUNDTESTBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/groundtest.h"
|
||||
#endif
|
||||
#ifdef SERIALBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/serial.h"
|
||||
#endif
|
||||
#ifdef SIMPLENICBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/simplenic.h"
|
||||
#endif
|
||||
#ifdef TRACERVBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/tracerv.h"
|
||||
#endif
|
||||
#ifdef UARTBRIDGEMODULE_0_PRESENT
|
||||
#include "bridges/uart.h"
|
||||
#endif
|
||||
|
||||
widget_registry_t::widget_registry_t(const TargetConfig &config,
|
||||
simif_t &simif,
|
||||
const std::vector<std::string> &args)
|
||||
: config(config) {
|
||||
|
||||
widget_registry_t ®istry = *this;
|
||||
#include "constructor.h"
|
||||
}
|
||||
widget_registry_t::widget_registry_t() = default;
|
||||
|
||||
widget_registry_t::~widget_registry_t() = default;
|
||||
|
||||
|
|
|
@ -26,10 +26,7 @@ class StreamEngine;
|
|||
*/
|
||||
class widget_registry_t final {
|
||||
public:
|
||||
widget_registry_t(const TargetConfig &config,
|
||||
simif_t &simif,
|
||||
const std::vector<std::string> &args);
|
||||
|
||||
widget_registry_t();
|
||||
~widget_registry_t();
|
||||
|
||||
/**
|
||||
|
@ -94,9 +91,6 @@ public:
|
|||
void add_widget(StreamEngine *widget);
|
||||
|
||||
private:
|
||||
// Target-specific configuration.
|
||||
const TargetConfig config;
|
||||
|
||||
// Mapping from bridge kinds to the list of bridges of that kind.
|
||||
using widget_list_t = std::vector<std::unique_ptr<widget_t>>;
|
||||
std::unordered_map<const void *, widget_list_t> widgets;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "bridges/cpu_managed_stream.h"
|
||||
#include "bridges/fpga_managed_stream.h"
|
||||
#include "core/simulation.h"
|
||||
#include "emul/mm.h"
|
||||
#include "emul/mmio.h"
|
||||
|
||||
|
@ -49,7 +50,11 @@ simif_emul_t::simif_emul_t(const TargetConfig &config,
|
|||
assert(!config.cpu_managed && "stream should be CPU or FPGA managed");
|
||||
fpga_managed_stream_io.reset(new FPGAManagedStreamIOImpl(*this, *conf));
|
||||
}
|
||||
}
|
||||
|
||||
simif_emul_t::~simif_emul_t() {}
|
||||
|
||||
void simif_emul_t::start_driver(simulation_t &sim) {
|
||||
// Set up the simulation thread.
|
||||
finished = false;
|
||||
exit_code = EXIT_FAILURE;
|
||||
|
@ -57,13 +62,36 @@ simif_emul_t::simif_emul_t(const TargetConfig &config,
|
|||
std::unique_lock<std::mutex> lock(rtlsim_mutex);
|
||||
driver_flag = false;
|
||||
rtlsim_flag = false;
|
||||
thread = std::thread([&] { thread_main(); });
|
||||
|
||||
// Spawn the target thread.
|
||||
thread = std::thread([&] {
|
||||
do_tick();
|
||||
|
||||
// Load memories before initialising the simulation.
|
||||
if (fastloadmem && !load_mem_path.empty()) {
|
||||
fprintf(stdout, "[fast loadmem] %s\n", load_mem_path.c_str());
|
||||
load_mems(load_mem_path.c_str());
|
||||
}
|
||||
|
||||
// Run the simulation flow.
|
||||
target_init();
|
||||
exit_code = sim.execute_simulation_flow();
|
||||
|
||||
// Wake the target thread before returning from the simulation thread.
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(rtlsim_mutex);
|
||||
finished = true;
|
||||
rtlsim_cond.notify_one();
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for the target thread to yield and enter the RTL simulator.
|
||||
// The target thread is waken up when the DPI tick function is
|
||||
// ready to transfer data to it.
|
||||
rtlsim_cond.wait(lock, [&] { return rtlsim_flag; });
|
||||
}
|
||||
}
|
||||
|
||||
simif_emul_t::~simif_emul_t() {}
|
||||
|
||||
void simif_emul_t::wait_write(mmio_t &mmio) {
|
||||
while (!mmio.write_resp())
|
||||
advance_target();
|
||||
|
@ -190,24 +218,3 @@ bool simif_emul_t::to_sim() {
|
|||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
void simif_emul_t::thread_main() {
|
||||
// Switch over to the target thread and wait for the first tick.
|
||||
do_tick();
|
||||
|
||||
// Load memories before initialising the simulation.
|
||||
if (fastloadmem && !load_mem_path.empty()) {
|
||||
fprintf(stdout, "[fast loadmem] %s\n", load_mem_path.c_str());
|
||||
load_mems(load_mem_path.c_str());
|
||||
}
|
||||
|
||||
// Run the simulation flow.
|
||||
exit_code = simulation_run();
|
||||
|
||||
// Wake the target thread before returning from the simulation thread.
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(rtlsim_mutex);
|
||||
finished = true;
|
||||
rtlsim_cond.notify_one();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
int end();
|
||||
|
||||
/**
|
||||
* Simulation thread implementation.
|
||||
* Start the driver thread.
|
||||
*
|
||||
* This thread is synchronized by the main thread driven by Verilator/VCS
|
||||
* which simulates the RTL and invokes the tick function through DPI. At
|
||||
|
@ -53,7 +53,7 @@ public:
|
|||
* runs for one cycle, handling the AXI transactions, before switching control
|
||||
* back to the target thread that reads outputs into the RTL.
|
||||
*/
|
||||
void thread_main();
|
||||
void start_driver(simulation_t &sim);
|
||||
|
||||
/**
|
||||
* Transfers control to the simulator on a tick.
|
||||
|
|
|
@ -8,25 +8,38 @@
|
|||
*/
|
||||
class simif_emul_vcs_t final : public simif_emul_t {
|
||||
public:
|
||||
simif_emul_vcs_t(const TargetConfig &config,
|
||||
const std::vector<std::string> &args)
|
||||
: simif_emul_t(config, args) {}
|
||||
simif_emul_vcs_t(const TargetConfig &config, int argc, char **argv);
|
||||
|
||||
~simif_emul_vcs_t() {}
|
||||
|
||||
int run(simulation_t &sim);
|
||||
|
||||
private:
|
||||
int argc;
|
||||
char **argv;
|
||||
};
|
||||
|
||||
/// Simulator instance used by DPI.
|
||||
simif_emul_t *simulator = nullptr;
|
||||
|
||||
simif_emul_vcs_t::simif_emul_vcs_t(const TargetConfig &config,
|
||||
int argc,
|
||||
char **argv)
|
||||
: simif_emul_t(config, std::vector<std::string>(argv + 1, argv + argc)),
|
||||
argc(argc), argv(argv) {
|
||||
simulator = this;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int vcs_main(int argc, char **argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point to the VCS meta-simulation hijacked from VCS itself.
|
||||
*/
|
||||
int main(int argc, char **argv) {
|
||||
std::vector<std::string> args{argv + 1, argv + argc};
|
||||
simulator = new simif_emul_vcs_t(conf_target, args);
|
||||
return vcs_main(argc, argv);
|
||||
int simif_emul_vcs_t::run(simulation_t &sim) {
|
||||
start_driver(sim);
|
||||
vcs_main(argc, argv);
|
||||
}
|
||||
|
||||
std::unique_ptr<simif_t>
|
||||
create_simif(const TargetConfig &config, int argc, char **argv) {
|
||||
return std::make_unique<simif_emul_vcs_t>(config, argc, argv);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
|
||||
~simif_emul_verilator_t();
|
||||
|
||||
int run();
|
||||
int run(simulation_t &sim);
|
||||
|
||||
uint64_t get_time() const { return main_time; }
|
||||
|
||||
|
@ -62,7 +62,9 @@ simif_emul_verilator_t::~simif_emul_verilator_t() {
|
|||
#endif
|
||||
}
|
||||
|
||||
int simif_emul_verilator_t::run() {
|
||||
int simif_emul_verilator_t::run(simulation_t &sim) {
|
||||
start_driver(sim);
|
||||
|
||||
top->clock = 0;
|
||||
|
||||
top->reset = 1;
|
||||
|
@ -98,8 +100,9 @@ void simif_emul_verilator_t::tick() {
|
|||
top->eval();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::unique_ptr<simif_t>
|
||||
create_simif(const TargetConfig &config, int argc, char **argv) {
|
||||
Verilated::commandArgs(argc, argv);
|
||||
std::vector<std::string> args(argv + 1, argv + argc);
|
||||
return simif_emul_verilator_t(conf_target, args).run();
|
||||
return std::make_unique<simif_emul_verilator_t>(config, args);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@ public:
|
|||
simif_f1_t(const TargetConfig &config, const std::vector<std::string> &args);
|
||||
~simif_f1_t();
|
||||
|
||||
int run() { return simulation_run(); }
|
||||
|
||||
void write(size_t addr, uint32_t data) override;
|
||||
uint32_t read(size_t addr) override;
|
||||
|
||||
|
@ -204,7 +202,8 @@ uint32_t simif_f1_t::is_write_ready() {
|
|||
return value & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::unique_ptr<simif_t>
|
||||
create_simif(const TargetConfig &config, int argc, char **argv) {
|
||||
std::vector<std::string> args(argv + 1, argv + argc);
|
||||
return simif_f1_t(conf_target, args).run();
|
||||
return std::make_unique<simif_f1_t>(config, args);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ public:
|
|||
const std::vector<std::string> &args);
|
||||
~simif_f1_xsim_t();
|
||||
|
||||
int run() { return simulation_run(); }
|
||||
|
||||
void write(size_t addr, uint32_t data) override;
|
||||
uint32_t read(size_t addr) override;
|
||||
|
||||
|
@ -107,7 +105,8 @@ uint32_t simif_f1_xsim_t::is_write_ready() {
|
|||
return *((uint64_t *)buf);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::unique_ptr<simif_t>
|
||||
create_simif(const TargetConfig &config, int argc, char **argv) {
|
||||
std::vector<std::string> args(argv + 1, argv + argc);
|
||||
return simif_f1_xsim_t(conf_target, args).run();
|
||||
return std::make_unique<simif_f1_xsim_t>(config, args);
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ public:
|
|||
const std::vector<std::string> &args);
|
||||
~simif_vitis_t() {}
|
||||
|
||||
int run() { return simulation_run(); }
|
||||
|
||||
void write(size_t addr, uint32_t data) override;
|
||||
uint32_t read(size_t addr) override;
|
||||
|
||||
|
@ -138,7 +136,8 @@ char *simif_vitis_t::get_memory_base() {
|
|||
abort();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::unique_ptr<simif_t>
|
||||
create_simif(const TargetConfig &config, int argc, char **argv) {
|
||||
std::vector<std::string> args(argv + 1, argv + argc);
|
||||
return simif_vitis_t(conf_target, args).run();
|
||||
return std::make_unique<simif_vitis_t>(config, args);
|
||||
}
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
class firesim_top_t : public systematic_scheduler_t, public simulation_t {
|
||||
public:
|
||||
firesim_top_t(const std::vector<std::string> &args, simif_t &sim);
|
||||
~firesim_top_t() {}
|
||||
~firesim_top_t() override = default;
|
||||
|
||||
void simulation_init();
|
||||
void simulation_finish();
|
||||
int simulation_run();
|
||||
void simulation_init() override;
|
||||
void simulation_finish() override;
|
||||
int simulation_run() override;
|
||||
|
||||
private:
|
||||
// profile interval: # of cycles to advance before profiling instrumentation
|
||||
|
|
Loading…
Reference in New Issue