From b66aeeae94bef3de5c2b595ff1fc594a6667dff1 Mon Sep 17 00:00:00 2001 From: Porterlu <1258210724@qq.com> Date: Sat, 17 Aug 2024 03:02:50 +0800 Subject: [PATCH] [difftest] update SpikeEvent after func --- difftest/spike_interfaces/spike_interfaces.cc | 30 ++++++++++++++++++- .../spike_interfaces/spike_interfaces_c.h | 5 ++++ rocketemu/driver/src/sim.rs | 2 +- rocketemu/offline/src/difftest.rs | 2 +- rocketemu/spike_rs/src/lib.rs | 27 +++++++++++++++++ rocketemu/spike_rs/src/spike_event.rs | 24 ++++++++++++++- rocketemu/test_common/src/spike_runner.rs | 15 ++++++---- 7 files changed, 96 insertions(+), 9 deletions(-) diff --git a/difftest/spike_interfaces/spike_interfaces.cc b/difftest/spike_interfaces/spike_interfaces.cc index 33f565a46..fa2ed66f2 100644 --- a/difftest/spike_interfaces/spike_interfaces.cc +++ b/difftest/spike_interfaces/spike_interfaces.cc @@ -56,6 +56,13 @@ const char *proc_disassemble(spike_processor_t *proc) { return strdup(disasm->disassemble(fetch.insn).c_str()); } +const char *proc_disassemble_with_pc(spike_processor_t *proc, reg_t pc) { + auto mmu = proc->p->get_mmu(); + auto disasm = proc->p->get_disassembler(); + auto fetch = mmu->load_insn(pc); + return strdup(disasm->disassemble(fetch.insn).c_str()); +} + spike_processor_t *spike_get_proc(spike_t *spike) { return new spike_processor_t{spike->s->get_proc()}; } @@ -76,7 +83,7 @@ reg_t proc_func(spike_processor_t *proc) { fetch = mmu->load_insn(pc); res = fetch.func(proc->p, fetch.insn, pc); } catch (trap_t &trap) { - printf("catch exception\n"); + //printf("catch exception\n"); unsigned max_xlen = proc->p->get_const_xlen(); state_t* state = proc->p->get_state(); reg_t hsdeleg = (state->prv <= PRV_S) ? state->medeleg->read() : 0; @@ -148,6 +155,12 @@ reg_t proc_get_insn(spike_processor_t *proc) { return fetch.insn.bits(); } +reg_t proc_get_insn_with_pc(spike_processor_t *proc, reg_t pc) { + auto mmu = proc->p->get_mmu(); + auto fetch = mmu->load_insn(pc); + return fetch.insn.bits(); +} + uint8_t proc_get_vreg_data(spike_processor_t *proc, uint32_t vreg_idx, uint32_t vreg_offset) { return proc->p->VU.elt(vreg_idx, vreg_offset); @@ -167,18 +180,33 @@ uint32_t proc_get_rs1(spike_processor_t *proc) { return (uint32_t)fetch.insn.rs1(); } +uint32_t proc_get_rs1_with_pc(spike_processor_t *proc, reg_t pc) { + auto fetch = proc->p->get_mmu()->load_insn(pc); + return (uint32_t)fetch.insn.rs1(); +} + uint32_t proc_get_rs2(spike_processor_t *proc) { auto pc = proc->p->get_state()->pc; auto fetch = proc->p->get_mmu()->load_insn(pc); return (uint32_t)fetch.insn.rs2(); } +uint32_t proc_get_rs2_with_pc(spike_processor_t *proc, reg_t pc) { + auto fetch = proc->p->get_mmu()->load_insn(pc); + return (uint32_t)fetch.insn.rs2(); +} + uint32_t proc_get_rd(spike_processor_t *proc) { auto pc = proc->p->get_state()->pc; auto fetch = proc->p->get_mmu()->load_insn(pc); return fetch.insn.rd(); } +uint32_t proc_get_rd_with_pc(spike_processor_t *proc, reg_t pc) { + auto fetch = proc->p->get_mmu()->load_insn(pc); + return fetch.insn.rd(); +} + uint64_t proc_vu_get_vtype(spike_processor_t *proc) { return proc->p->VU.vtype->read(); } diff --git a/difftest/spike_interfaces/spike_interfaces_c.h b/difftest/spike_interfaces/spike_interfaces_c.h index 6c43acaf0..bbbed864a 100644 --- a/difftest/spike_interfaces/spike_interfaces_c.h +++ b/difftest/spike_interfaces/spike_interfaces_c.h @@ -17,17 +17,22 @@ void spike_register_callback(void *ffi_target, ffi_callback callback); spike_t *spike_new(const char *set, const char *lvl, size_t lane_number); const char *proc_disassemble(spike_processor_t *proc); +const char *proc_disassemble_with_pc(spike_processor_t *proc, reg_t pc); void proc_reset(spike_processor_t *proc); spike_processor_t *spike_get_proc(spike_t *spike); spike_state_t *proc_get_state(spike_processor_t *proc); uint64_t proc_func(spike_processor_t *proc); uint64_t proc_get_insn(spike_processor_t *proc); +uint64_t proc_get_insn_with_pc(spike_processor_t *proc, reg_t pc); uint8_t proc_get_vreg_data(spike_processor_t *proc, uint32_t vreg_idx, uint32_t vreg_offset); uint32_t proc_get_rs1(spike_processor_t *proc); +uint32_t proc_get_rs1_with_pc(spike_processor_t *proc, reg_t pc); uint32_t proc_get_rs2(spike_processor_t *proc); +uint32_t proc_get_rs2_with_pc(spike_processor_t *proc, reg_t pc); uint32_t proc_get_rd(spike_processor_t *proc); +uint32_t proc_get_rd_with_pc(spike_processor_t *proc, reg_t pc); uint64_t proc_vu_get_vtype(spike_processor_t *proc); uint32_t proc_vu_get_vxrm(spike_processor_t *proc); diff --git a/rocketemu/driver/src/sim.rs b/rocketemu/driver/src/sim.rs index 0420a7f8c..b685c2f1a 100644 --- a/rocketemu/driver/src/sim.rs +++ b/rocketemu/driver/src/sim.rs @@ -43,7 +43,7 @@ pub struct SimulationArgs { pub log_level: String, /// The timeout value - #[arg(long, default_value_t = 1_0000)] + #[arg(long, default_value_t = 1_00000)] pub timeout: u64, #[cfg(feature = "trace")] diff --git a/rocketemu/offline/src/difftest.rs b/rocketemu/offline/src/difftest.rs index eaf755497..b16dadb94 100644 --- a/rocketemu/offline/src/difftest.rs +++ b/rocketemu/offline/src/difftest.rs @@ -35,7 +35,7 @@ impl Difftest { } if se.is_rd_written() && se.rd_idx != 0 { let event = self.dut.step()?; - + match event { JsonEvents::RegWrite { addr, data, cycle } => { self.runner.cycle = *cycle; diff --git a/rocketemu/spike_rs/src/lib.rs b/rocketemu/spike_rs/src/lib.rs index 0d64e6d24..67e87515e 100644 --- a/rocketemu/spike_rs/src/lib.rs +++ b/rocketemu/spike_rs/src/lib.rs @@ -97,6 +97,12 @@ impl Processor { format!("{}", c_str.to_string_lossy()) } + pub fn disassemble_with_pc(&self, pc: u64) -> String { + let bytes = unsafe { proc_disassemble_with_pc(self.processor, pc) }; + let c_str = unsafe { CStr::from_ptr(bytes as *mut c_char) }; + format!("{}", c_str.to_string_lossy()) + } + pub fn reset(&self) { unsafe { proc_reset(self.processor) } } @@ -114,6 +120,10 @@ impl Processor { unsafe { proc_get_insn(self.processor) as u32 } } + pub fn get_insn_with_pc(&self, pc: u64) -> u32 { + unsafe { proc_get_insn_with_pc(self.processor, pc) as u32 } + } + pub fn get_vreg_data(&self, idx: u32, offset: u32) -> u8 { unsafe { proc_get_vreg_data(self.processor, idx, offset) } } @@ -122,14 +132,26 @@ impl Processor { unsafe { proc_get_rs1(self.processor) } } + pub fn get_rs1_with_pc(&self, pc: u64) -> u32 { + unsafe { proc_get_rs1_with_pc(self.processor, pc) } + } + pub fn get_rs2(&self) -> u32 { unsafe { proc_get_rs2(self.processor) } } + pub fn get_rs2_with_pc(&self, pc: u64) -> u32 { + unsafe { proc_get_rs2_with_pc(self.processor, pc) } + } + pub fn get_rd(&self) -> u32 { unsafe { proc_get_rd(self.processor) } } + pub fn get_rd_with_pc(&self, pc: u64) -> u32 { + unsafe { proc_get_rd_with_pc(self.processor, pc) } + } + // vu pub fn vu_get_vtype(&self) -> u32 { unsafe { proc_vu_get_vtype(self.processor) as u32 } @@ -249,14 +271,19 @@ extern "C" { fn spike_get_proc(spike: *mut ()) -> *mut (); fn spike_destruct(spike: *mut ()); fn proc_disassemble(proc: *mut ()) -> *mut c_char; + fn proc_disassemble_with_pc(proc: *mut(), pc: u64) -> *mut c_char; fn proc_reset(proc: *mut ()); fn proc_get_state(proc: *mut ()) -> *mut (); fn proc_func(proc: *mut ()) -> u64; fn proc_get_insn(proc: *mut ()) -> u64; + fn proc_get_insn_with_pc(proc: *mut(), pc: u64) -> u64; fn proc_get_vreg_data(proc: *mut (), vreg_idx: u32, vreg_offset: u32) -> u8; fn proc_get_rs1(proc: *mut ()) -> u32; + fn proc_get_rs1_with_pc(proc: *mut(), pc: u64) -> u32; fn proc_get_rs2(proc: *mut ()) -> u32; + fn proc_get_rs2_with_pc(proc: *mut(), pc: u64) -> u32; fn proc_get_rd(proc: *mut ()) -> u32; + fn proc_get_rd_with_pc(proc: *mut(), pc: u64) -> u32; fn proc_vu_get_vtype(proc: *mut ()) -> u64; fn proc_vu_get_vxrm(proc: *mut ()) -> u32; diff --git a/rocketemu/spike_rs/src/spike_event.rs b/rocketemu/spike_rs/src/spike_event.rs index db00432d3..5d6267822 100644 --- a/rocketemu/spike_rs/src/spike_event.rs +++ b/rocketemu/spike_rs/src/spike_event.rs @@ -100,7 +100,6 @@ pub struct SpikeEvent { } impl SpikeEvent { - pub fn new_with_pc(pc: u64, do_log_vrf: bool) -> Self { SpikeEvent { do_log_vrf, @@ -188,6 +187,29 @@ impl SpikeEvent { } } + pub fn fill_event(&mut self, spike: &Spike) { + let pc = self.pc; + let proc = spike.get_proc(); + let state = proc.get_state(); + + let insn_bits = proc.get_insn_with_pc(pc); + let opcode = clip(insn_bits, 0, 6); + let width = clip(insn_bits, 12, 14); + + let is_rs_fp = opcode == 0b1010111 && width == 0b101/* OPFVF */; + + let rs1 = proc.get_rs1_with_pc(pc); + let rs2 = proc.get_rs2_with_pc(pc); + + self.disasm = proc.disassemble_with_pc(pc); + self.inst_bits = insn_bits; + self.rs1 = rs1; + self.rs2 = rs2; + self.rs1_bits = state.get_reg(rs1, is_rs_fp); + self.rs2_bits = state.get_reg(rs2, is_rs_fp); + self.rd_idx = proc.get_rd_with_pc(pc); + } + pub fn opcode(&self) -> u32 { clip(self.inst_bits, 0, 6) } diff --git a/rocketemu/test_common/src/spike_runner.rs b/rocketemu/test_common/src/spike_runner.rs index b85fadc7c..7fe2281f1 100644 --- a/rocketemu/test_common/src/spike_runner.rs +++ b/rocketemu/test_common/src/spike_runner.rs @@ -78,15 +78,20 @@ impl SpikeRunner { let state = proc.get_state(); state.set_mcycle((self.cycle + self.spike_cycle) as usize); - + let mut event = SpikeEvent::new_with_pc(state.get_pc(), self.do_log_vrf); - state.clear(); + //state.clear(); + + let new_pc = proc.func(); + + // fill the SpikeEvent + //event.fill_event(spike); // inst is scalar debug!("SpikeStep: spike run scalar insn ({})", event.describe_insn()); - let new_pc = proc.func(); - event.log_mem_write(spike).unwrap(); - event.log_reg_write(spike).unwrap(); + + //event.log_mem_write(spike).unwrap(); + //event.log_reg_write(spike).unwrap(); state.handle_pc(new_pc).unwrap();