diff --git a/t1rocketemu/online_dpi/src/dpi.rs b/t1rocketemu/online_dpi/src/dpi.rs index 82c33ebe37..5d2599942a 100644 --- a/t1rocketemu/online_dpi/src/dpi.rs +++ b/t1rocketemu/online_dpi/src/dpi.rs @@ -313,6 +313,9 @@ mod dpi_export { #[cfg(feature = "trace")] /// `export "DPI-C" function dump_wave(input string file)` pub fn dump_wave(path: *const c_char); + + /// 'export "DPI-C" function quit()' + pub fn quit(); } } @@ -326,3 +329,9 @@ pub(crate) fn dump_wave(scope: crate::svdpi::SvScope, path: &str) { dpi_export::dump_wave(path_cstring.as_ptr()); } } + +pub(crate) fn quit() { + unsafe { + dpi_export::quit(); + } +} \ No newline at end of file diff --git a/t1rocketemu/online_dpi/src/drive.rs b/t1rocketemu/online_dpi/src/drive.rs index 2b89fdca4b..6a4ff08f6c 100644 --- a/t1rocketemu/online_dpi/src/drive.rs +++ b/t1rocketemu/online_dpi/src/drive.rs @@ -1,5 +1,5 @@ use crate::dpi::*; -use crate::get_t; +use crate::{ get_t, EXIT_CODE, EXIT_POS }; use crate::svdpi::SvScope; use crate::OfflineArgs; @@ -335,6 +335,14 @@ impl Driver { self.shadow_mem.write_mem_axi(addr, size, 32, strobe, data); let data_hex = hex::encode(data); self.last_commit_cycle = get_t(); + + // exit with code + if addr == EXIT_POS && data.len() == 4 && data == &EXIT_CODE.to_le_bytes() { + info!("exit successfully"); + quit(); + return; + } + trace!( "[{}] axi_write_load_store (addr={addr:#x}, size={size}, data={data_hex})", get_t() diff --git a/t1rocketemu/online_dpi/src/lib.rs b/t1rocketemu/online_dpi/src/lib.rs index bafe6db0d5..35a72ec339 100644 --- a/t1rocketemu/online_dpi/src/lib.rs +++ b/t1rocketemu/online_dpi/src/lib.rs @@ -24,6 +24,10 @@ pub(crate) struct OfflineArgs { pub timeout: u64, } +// quit signal +const EXIT_POS: u32 = 0x4000_0000; +const EXIT_CODE: u32 = 0xdead_beef; + // keep in sync with TestBench.ClockGen pub const CYCLE_PERIOD: u64 = 20; diff --git a/t1rocketemu/src/TestBench.scala b/t1rocketemu/src/TestBench.scala index d49abc0c1f..aa72472c5e 100644 --- a/t1rocketemu/src/TestBench.scala +++ b/t1rocketemu/src/TestBench.scala @@ -34,6 +34,11 @@ class TestBench(generator: SerializableModuleGenerator[T1RocketTile, T1RocketTil |`endif | endfunction; | + | export "DPI-C" function quit; + | function quit(); + | $$finish; + | endfunction; + | | import "DPI-C" context function void t1rocket_cosim_init(); | initial begin | t1rocket_cosim_init(); diff --git a/tests/emurt/emurt.c b/tests/emurt/emurt.c index f52a57d369..77ebc6fad6 100644 --- a/tests/emurt/emurt.c +++ b/tests/emurt/emurt.c @@ -54,7 +54,9 @@ int _write(int file, char* ptr, int len) { } void _exit(int code) { - __asm__("csrwi 0x7cc, 0"); + __asm__("li x1, 0x40000000"); + __asm__("li x2, 0xdeadbeef"); + __asm__("sw x2, 0(x1)"); __builtin_unreachable(); } diff --git a/tests/t1_main.S b/tests/t1_main.S index 85ed6ac321..426e90a1bf 100644 --- a/tests/t1_main.S +++ b/tests/t1_main.S @@ -10,6 +10,8 @@ _start: call test // exit - csrwi 0x7cc, 0 + li x1, 0x40000000 + li x2, 0xdeadbeef + sw x2, 0(x1) .p2align 2