diff --git a/rocketemu/dpi/dpi_pre_link.cc b/rocketemu/dpi/dpi_pre_link.cc index be7293350..e35b4dccd 100644 --- a/rocketemu/dpi/dpi_pre_link.cc +++ b/rocketemu/dpi/dpi_pre_link.cc @@ -8,6 +8,12 @@ class VTestBench; VerilatedContext *contextp; VTestBench *topp; +bool quit; + +void quit_c() { + quit = true; +} + int verilator_main_c(int argc, char **argv) { // Setup context, defaults, and parse command line Verilated::debug(0); @@ -15,11 +21,14 @@ int verilator_main_c(int argc, char **argv) { contextp->fatalOnError(false); contextp->commandArgs(argc, argv); + // Set quit flag, true means quit + quit = false; + // Construct the Verilated model, from Vtop.h generated from Verilating topp = new VTestBench(contextp); // Simulate until $finish - while (!contextp->gotFinish()) { + while (!contextp->gotFinish() && !quit) { // Evaluate model topp->eval(); // Advance time diff --git a/rocketemu/dpi/dpi_pre_link.h b/rocketemu/dpi/dpi_pre_link.h index cf2752e97..94d8bd51a 100644 --- a/rocketemu/dpi/dpi_pre_link.h +++ b/rocketemu/dpi/dpi_pre_link.h @@ -13,6 +13,8 @@ extern "C" { int verilator_main_c(int argc, char **argv); +void quit_c(); + #ifdef VM_TRACE void dump_wave_c(char *path); #endif diff --git a/rocketemu/driver/src/dpi.rs b/rocketemu/driver/src/dpi.rs index 65633f63d..945b545be 100644 --- a/rocketemu/driver/src/dpi.rs +++ b/rocketemu/driver/src/dpi.rs @@ -178,6 +178,8 @@ unsafe extern "C" fn cosim_watchdog_rs(target: *mut (), reason: *mut c_char) { extern "C" { fn verilator_main_c(argc: c_int, argv: *mut *mut c_char) -> c_int; + fn quit_c(); + #[cfg(feature = "trace")] fn dump_wave_c(path: *const c_char); @@ -190,6 +192,12 @@ pub(crate) fn get_t() -> u64 { unsafe { get_t_c() / 20 } } +pub(crate) fn quit() { + unsafe { + quit_c(); + } +} + pub(crate) fn verilator_main() { let mut c_args_ptr: Vec<*mut c_char> = std::env::args() .collect::>() diff --git a/rocketemu/driver/src/sim.rs b/rocketemu/driver/src/sim.rs index cea85af2c..bd5b2f3c5 100644 --- a/rocketemu/driver/src/sim.rs +++ b/rocketemu/driver/src/sim.rs @@ -1,6 +1,7 @@ #[cfg(feature = "trace")] use crate::dpi::dump_wave; use crate::dpi::get_t; +use crate::dpi::quit; use clap::{arg, Parser}; use std::collections::HashMap; @@ -23,6 +24,8 @@ pub(crate) struct AxiReadPayload { pub(crate) data: Vec, } +const EXIT_POS: u32 = 0x4000_0000; + #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] pub struct SimulationArgs { @@ -265,6 +268,12 @@ impl Simulator { get_t() ); + if addr == EXIT_POS { + info!("exit with code: {:x?}", data); + quit(); + return; + } + self.write_mem(addr, self.dlen / 8, strobe, data); }