From fb3d95efa6608527a52ac25c1cce6b880cee7c7e Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Tue, 14 May 2024 11:02:41 +0800 Subject: [PATCH] [dut] add bus for dut --- src/dut.rs | 39 +++++++++++++++++++++++++++++++++++++-- src/emulator.rs | 28 +++++++++------------------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/dut.rs b/src/dut.rs index a247b90..319e17f 100644 --- a/src/dut.rs +++ b/src/dut.rs @@ -1,4 +1,6 @@ mod top; +use crate::bus::Bus; +use crate::cpu::{BYTE, WORD, HALFWORD, DOUBLEWORD}; use crate::emulator::{DebugInfo, GprInfo, MemInfo}; use std::time::Duration; use top::Top; @@ -25,8 +27,8 @@ impl SramRequest { // sram interface pub struct Dut { pub top: Top, + pub bus: Bus, pub ticks: u64, - pub prepare_for_difftest: bool, pub inst: u32, pub data: u64, pub trace: bool, @@ -43,7 +45,7 @@ impl Dut { Dut { top, ticks: 0, - prepare_for_difftest: false, + bus: Bus::new(), inst: 0, data: 0, trace, @@ -79,6 +81,26 @@ impl Dut { self.ticks += 1; + // write data sram + if self.top.data_sram_wen() != 0 { + let data_sram_mask = extend_to_64(self.top.data_sram_wen()); + let data_sram_align = data_sram_mask.trailing_zeros(); + let data_sram_aligned = if data_sram_align == 0 { + 0 + } else { + (self.top.data_sram_wdata() & data_sram_mask) >> data_sram_align + }; + let data_sram_size = match data_sram_mask >> data_sram_align { + 0b0000_0001 => BYTE, + 0b0000_0011 => HALFWORD, + 0b0000_1111 => WORD, + 0b1111_1111 => DOUBLEWORD, + _ => panic!("Invalid data sram size"), + }; + let _ = self.bus.write(self.top.data_sram_addr() as u64, data_sram_aligned, data_sram_size); + } + + Ok({ ( SramRequest::new(self.top.inst_sram_en() != 0, self.top.inst_sram_addr()), @@ -118,3 +140,16 @@ impl Drop for Dut { println!("Simulation complete"); } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_extend_to_64() { + assert_eq!(extend_to_64(0b1111_1111), 0xffffffff_ffffffff); + assert_eq!(extend_to_64(0b0000_1111), 0x00000000_ffffffff); + assert_eq!(extend_to_64(0b0000_0001), 0x00000000_000000ff); + assert_eq!(extend_to_64(0b0001_0001), 0x000000ff_000000ff); + } +} diff --git a/src/emulator.rs b/src/emulator.rs index 31fd2a3..1b2bcbe 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -139,12 +139,18 @@ impl Emulator { /// Set binary data to the beginning of the DRAM from the emulator console. pub fn initialize_dram(&mut self, data: Vec) { - self.cpu.bus.initialize_dram(data); + self.cpu.bus.initialize_dram(data.clone()); + if let Some(ref mut dut) = self.dut { + dut.bus.initialize_dram(data); + } } /// Set binary data to the virtio disk from the emulator console. pub fn initialize_disk(&mut self, data: Vec) { - self.cpu.bus.initialize_disk(data); + self.cpu.bus.initialize_disk(data.clone()); + if let Some(ref mut dut) = self.dut { + dut.bus.initialize_dram(data); + } } /// Set the program counter to the CPU field. @@ -238,7 +244,7 @@ impl Emulator { // The result of the read method can be `Exception::LoadAccessFault`. In fetch(), an error // should be `Exception::InstructionAccessFault`. - dut.data = self.cpu.bus.read(p_addr, crate::cpu::DOUBLEWORD).unwrap(); + dut.data = dut.bus.read(p_addr, crate::cpu::DOUBLEWORD).unwrap(); trace!( "[dut] ticks: {}, data_sram: addr: {:#x}, data: {:#018x}", dut.ticks, @@ -327,22 +333,6 @@ impl Emulator { false => {} } - // difftest ui cpu inst - self - .ui - .selected_tab - .diff - .cpu - .push(format!("pc: {:#x}, inst: {}", self.cpu.pc, self.cpu.inst)); - - // trace ui itrace - self - .ui - .selected_tab - .trace - .itrace - .push(format!("pc: {:#x}, inst: {}", self.cpu.pc, self.cpu.inst)); - // difftest ui dut inst if let Some(ref dut) = self.dut { let pc = dut.top.debug_pc();