From 95c5064b809332bd5d8392ce348b304e6ac4911c Mon Sep 17 00:00:00 2001 From: Porterlu <1258210724@qq.com> Date: Thu, 25 Jul 2024 00:35:18 +0800 Subject: [PATCH] [rocketemu] set the resetvector using information from an ELF file --- rocketemu/dpi/dpi.cc | 3 +++ rocketemu/dpi/dpi.h | 3 +++ rocketemu/driver/src/dpi.rs | 6 ++++++ rocketemu/driver/src/sim.rs | 6 ++++-- rocketemu/src/TestBench.scala | 4 ++-- 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/rocketemu/dpi/dpi.cc b/rocketemu/dpi/dpi.cc index fcf59050f4..372b42c4ef 100644 --- a/rocketemu/dpi/dpi.cc +++ b/rocketemu/dpi/dpi.cc @@ -50,6 +50,9 @@ void axi_read_instructionFetchAXI( /// true. void cosim_init() { dpi_call_target = cosim_init_rs(); } +/// dynamically set resetvector according to the payload +void get_resetvector() { get_resetvector_rs(dpi_call_target); } + /// evaluate at every 1024 cycles, return reason = 0 to continue simulation, /// other value is used as error code. void cosim_watchdog(char *reason) { diff --git a/rocketemu/dpi/dpi.h b/rocketemu/dpi/dpi.h index 46f6224e95..c4369f96da 100644 --- a/rocketemu/dpi/dpi.h +++ b/rocketemu/dpi/dpi.h @@ -43,6 +43,9 @@ extern void axi_read_instructionFetchAXI_rs( /// true. returns dpi call target extern void *cosim_init_rs(); +/// evaluate after reset, return the reset vector +extern void *get_resetvector_rs(void *dpi_call_target); + /// evaluate at every 1024 cycles, return reason = 0 to continue simulation, /// other value is used as error code. extern void cosim_watchdog_rs(void *dpi_call_target, char *reason); diff --git a/rocketemu/driver/src/dpi.rs b/rocketemu/driver/src/dpi.rs index 8103ebb1cd..9341c61f74 100644 --- a/rocketemu/driver/src/dpi.rs +++ b/rocketemu/driver/src/dpi.rs @@ -163,6 +163,12 @@ unsafe extern "C" fn cosim_init_rs(call_init: *mut SvBit) -> *mut () { Box::into_raw(sim) as *mut () } +#[no_mangle] +unsafe extern "C" fn get_resetvector_rs(target: *mut ()) -> u64 { + let sim = &mut *(target as *mut Simulator); + sim.e_entry +} + #[no_mangle] unsafe extern "C" fn cosim_watchdog_rs(target: *mut (), reason: *mut c_char) { // watchdog dpi call would be called before initialization, guard on null target diff --git a/rocketemu/driver/src/sim.rs b/rocketemu/driver/src/sim.rs index 2c9eb45f59..d7e92ed2d7 100644 --- a/rocketemu/driver/src/sim.rs +++ b/rocketemu/driver/src/sim.rs @@ -112,6 +112,7 @@ pub struct Simulator { pub(crate) fn_sym_tab: FunctionSymTab, pub(crate) dlen: u32, pub(crate) timeout: u64, + pub(crate) e_entry: u64 #[cfg(feature = "trace")] wave_path: String, @@ -140,8 +141,8 @@ impl Simulator { tracing::subscriber::set_global_default(global_logger) .expect("internal error: fail to setup log subscriber"); - // FIXME: pass e_entry to rocket - let (_FIXME_e_entry, mem, fn_sym_tab) = + // pass e_entry to rocket + let (e_entry, mem, fn_sym_tab) = Self::load_elf(&args.elf_file).expect("fail creating simulator"); #[cfg(feature = "trace")] @@ -154,6 +155,7 @@ impl Simulator { dlen: option_env!("DESIGN_DLEN") .map(|dlen| dlen.parse().expect("fail to parse dlen into u32 digit")) .unwrap_or(256), + e_entry: e_entry, #[cfg(feature = "trace")] wave_path: args.wave_path.to_owned(), diff --git a/rocketemu/src/TestBench.scala b/rocketemu/src/TestBench.scala index c139bf4d8a..b0bc50bcd6 100644 --- a/rocketemu/src/TestBench.scala +++ b/rocketemu/src/TestBench.scala @@ -68,8 +68,8 @@ class TestBench(generator: SerializableModuleGenerator[RocketTile, RocketTilePar dut.io.msip := 0.U dut.io.buserror := 0.U - // FIXME: get resetVector from simulator instead of hard code here - dut.io.resetVector := (BigInt(1) << 31).U + // get resetVector from simulator + dut.io.resetVector := RawUnclockedNonVoidFunctionCall("get_resetvector", Const(UInt(generator.parameter.resetVectorBits.W)))(simulationTime === 0.U) // Memory Drivers val instFetchAXI = dut.io.instructionFetchAXI.viewAs[AXI4ROIrrevocableVerilog]