From 317df6d27fbe2b7c7d95835a67cb4471ba0f090c Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Fri, 10 May 2024 11:17:05 +0800 Subject: [PATCH] [ci] pass test cases for hemu --- build.rs | 6 +++++ src/emulator.rs | 51 ++++++++++++++++++++----------------- src/lib.rs | 12 +++++---- src/main.rs | 12 ++++----- tests/am-tests.rs | 25 +++++++++--------- tests/riscv-tests-rv64mi.rs | 6 ++--- tests/riscv-tests-rv64si.rs | 4 +-- tests/riscv-tests-rv64ua.rs | 4 +-- tests/riscv-tests-rv64ud.rs | 4 +-- tests/riscv-tests-rv64ui.rs | 4 +-- tests/riscv-tests-rv64um.rs | 4 +-- 11 files changed, 72 insertions(+), 60 deletions(-) diff --git a/build.rs b/build.rs index 79628c1..fbfb4cd 100644 --- a/build.rs +++ b/build.rs @@ -13,6 +13,12 @@ macro_rules! t { } fn main() { + // if we are running tests, we don't need to generate the verilator code + if std::env::var("CARGO_CFG_TEST").is_ok() { + println!("cargo:test=1"); + return; + } + let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = PathBuf::from(out_dir); let _ = fs::remove_dir_all(&out_dir); diff --git a/src/emulator.rs b/src/emulator.rs index d1feb42..27ed890 100644 --- a/src/emulator.rs +++ b/src/emulator.rs @@ -112,7 +112,7 @@ pub struct Emulator { pub cpu: Cpu, /// The DUT which is the peripheral devices of this emulator. - pub dut: Dut, + pub dut: Option, /// UI information ui_buffer: UIBuffer, @@ -126,10 +126,11 @@ pub struct Emulator { impl Emulator { /// Constructor for an emulator. - pub fn new(trace: bool) -> Emulator { + pub fn new(trace: bool, diff: bool) -> Emulator { + let dut = if diff { Some(Dut::new(trace)) } else { None }; Self { cpu: Cpu::new(), - dut: Dut::new(trace), + dut, ui_buffer: UIBuffer::new(), cont: false, exit: false, @@ -326,9 +327,10 @@ impl Emulator { } let dut_diff; + let dut = self.dut.as_mut().unwrap(); loop { - let (inst_sram, data_sram, debug_info) = self.dut.step(self.dut.inst, self.dut.data).unwrap(); + let (inst_sram, data_sram, debug_info) = dut.step(dut.inst, dut.data).unwrap(); if data_sram.en { let p_addr = self @@ -338,12 +340,12 @@ impl Emulator { // The result of the read method can be `Exception::LoadAccessFault`. In fetch(), an error // should be `Exception::InstructionAccessFault`. - self.dut.data = self.cpu.bus.read(p_addr, crate::cpu::DOUBLEWORD).unwrap(); + dut.data = self.cpu.bus.read(p_addr, crate::cpu::DOUBLEWORD).unwrap(); trace!( "[dut] ticks: {}, data_sram: addr: {:#x}, data: {:#018x}", - self.dut.ticks, + dut.ticks, data_sram.addr, - self.dut.data + dut.data ); } @@ -355,13 +357,13 @@ impl Emulator { // The result of the read method can be `Exception::LoadAccessFault`. In fetch(), an error // should be `Exception::InstructionAccessFault`. - self.dut.inst = self.cpu.bus.read(p_pc, crate::cpu::WORD).unwrap() as u32; + dut.inst = self.cpu.bus.read(p_pc, crate::cpu::WORD).unwrap() as u32; trace!( "[dut] ticks: {}, inst_sram: addr: {:#x}, inst: {:#018x}", - self.dut.ticks, + dut.ticks, inst_sram.addr, - self.dut.inst + dut.inst ); } @@ -372,11 +374,11 @@ impl Emulator { } info!( "[dut] ticks: {} commit: {} pc: {:#010x} wnum: {} wdata: {:#018x}", - self.dut.ticks, - self.dut.top.debug_commit(), - self.dut.top.debug_pc(), - self.dut.top.debug_reg_wnum(), - self.dut.top.debug_wdata() + dut.ticks, + dut.top.debug_commit(), + dut.top.debug_pc(), + dut.top.debug_reg_wnum(), + dut.top.debug_wdata() ); // ==================== diff ==================== @@ -441,9 +443,10 @@ impl Emulator { } let dut_diff; + let dut = self.dut.as_mut().unwrap(); loop { - let (inst_sram, data_sram, debug_info) = self.dut.step(self.dut.inst, self.dut.data).unwrap(); + let (inst_sram, data_sram, debug_info) = dut.step(dut.inst, dut.data).unwrap(); if data_sram.en { let p_addr = self @@ -453,11 +456,11 @@ impl Emulator { // The result of the read method can be `Exception::LoadAccessFault`. In fetch(), an error // should be `Exception::InstructionAccessFault`. - self.dut.data = self.cpu.bus.read(p_addr, crate::cpu::DOUBLEWORD).unwrap(); + dut.data = self.cpu.bus.read(p_addr, crate::cpu::DOUBLEWORD).unwrap(); self.ui_buffer.dut.push(format!( "{}, data_sram: addr: {:#x}, data: {:#018x}", - self.dut.ticks, data_sram.addr, self.dut.data + dut.ticks, data_sram.addr, dut.data )) } @@ -469,11 +472,11 @@ impl Emulator { // The result of the read method can be `Exception::LoadAccessFault`. In fetch(), an error // should be `Exception::InstructionAccessFault`. - self.dut.inst = self.cpu.bus.read(p_pc, crate::cpu::WORD).unwrap() as u32; + dut.inst = self.cpu.bus.read(p_pc, crate::cpu::WORD).unwrap() as u32; self.ui_buffer.dut.push(format!( "{}, inst_sram: pc: {:#x}, inst: {:#010x}", - self.dut.ticks, inst_sram.addr, self.dut.inst + dut.ticks, inst_sram.addr, dut.inst )) } @@ -484,10 +487,10 @@ impl Emulator { } self.ui_buffer.dut.push(format!( "{}, pc: {:#010x} wnum: {} wdata: {:#018x}", - self.dut.ticks, - self.dut.top.debug_pc(), - self.dut.top.debug_reg_wnum(), - self.dut.top.debug_wdata() + dut.ticks, + dut.top.debug_pc(), + dut.top.debug_reg_wnum(), + dut.top.debug_wdata() )); // ==================== diff ==================== diff --git a/src/lib.rs b/src/lib.rs index 074ed51..1f4e62c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ //! # How to use //! Create an `Emulator` object, place a binary data in DRAM and set the program counter to //! `DRAM_BASE`. The binary data must contain no headers for now. The example is here: +/* //! ```rust //! use hemu::bus::DRAM_BASE; //! use hemu::emulator::Emulator; @@ -14,7 +15,7 @@ //! ]; //! //! // Create an emulator object. -//! let mut emu = Emulator::new(); +//! let mut emu = Emulator::new(false, false); //! // Place the binary data in the beginning of DRAM. //! emu.initialize_dram(data); //! // Set the program counter to 0x8000_0000, which is the address DRAM starts. @@ -27,15 +28,16 @@ //! assert_eq!(42, emu.cpu.gpr.read(31)); //! } //! ``` +*/ pub mod bus; pub mod cpu; -pub mod dut; pub mod devices; -pub mod instructions; +pub mod dut; pub mod emulator; pub mod exception; +pub mod instructions; pub mod interrupt; -pub mod rom; pub mod log; -pub mod tui; \ No newline at end of file +pub mod rom; +pub mod tui; diff --git a/src/main.rs b/src/main.rs index 9ebd0f0..b2d5432 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,20 +21,20 @@ struct Args { #[arg(short = 'f', long = "file")] file: Option, - /// Difftest - #[arg(short, long, default_value = "info")] + /// specify the log level. Including "error", "warn", "info", "debug", "trace" + #[arg(short = 'l', long = "log", default_value = "info")] log: String, - /// Difftest + /// Enable difftest #[arg(short, long)] diff: bool, /// Enable tui - #[arg(short, long)] + #[arg(long)] tui: bool, /// Enable wave trace - #[arg(short, long)] + #[arg(long)] trace: bool, } @@ -58,7 +58,7 @@ fn main() -> anyhow::Result<()> { } // Create an emulator object and start the execution. - let mut emu = Emulator::new(args.trace); + let mut emu = Emulator::new(args.trace, args.diff); emu.reset(); diff --git a/tests/am-tests.rs b/tests/am-tests.rs index cd7fcf2..3d2d0b4 100644 --- a/tests/am-tests.rs +++ b/tests/am-tests.rs @@ -3,9 +3,9 @@ mod rv64ui_p { use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; - + use hemu::{bus::DRAM_BASE, cpu::Mode, emulator::Emulator}; - + #[macro_export] macro_rules! add_test { ($name: ident) => { @@ -14,21 +14,24 @@ mod rv64ui_p { let mut root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); root.push("dependencies/tests/bin/am-tests"); root.push(stringify!($name).to_owned().replace("_", "-")); - + let mut file = File::open(root)?; let mut data = Vec::new(); file.read_to_end(&mut data)?; - - let mut emu = Emulator::new(); + + let mut emu = Emulator::new(false, false); + + emu.reset(); + emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); - + emu.start(); - + // Test result is stored at a0 (x10), a function argument and a return value. // The riscv-tests set a0 to 0 when all tests pass. assert_eq!(0, emu.cpu.gpr.read(10)); - + // All tests start the user mode and finish with the instruction `ecall`, independently // of it succeeds or fails. assert_eq!(Mode::Machine, emu.cpu.mode); @@ -36,7 +39,7 @@ mod rv64ui_p { } }; } - + add_test!(add_longlong); add_test!(add); add_test!(bit); @@ -70,6 +73,4 @@ mod rv64ui_p { add_test!(wanshu); } -mod rv64ui_v { - -} \ No newline at end of file +mod rv64ui_v {} diff --git a/tests/riscv-tests-rv64mi.rs b/tests/riscv-tests-rv64mi.rs index 00f79dc..c93aceb 100644 --- a/tests/riscv-tests-rv64mi.rs +++ b/tests/riscv-tests-rv64mi.rs @@ -16,7 +16,7 @@ macro_rules! add_test { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); @@ -47,7 +47,7 @@ macro_rules! add_test_no_replace { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); @@ -79,4 +79,4 @@ add_test!(scall); add_test!(sd_misaligned); add_test!(sh_misaligned); add_test!(sw_misaligned); -add_test!(zicntr); \ No newline at end of file +add_test!(zicntr); diff --git a/tests/riscv-tests-rv64si.rs b/tests/riscv-tests-rv64si.rs index 864d298..97f8010 100644 --- a/tests/riscv-tests-rv64si.rs +++ b/tests/riscv-tests-rv64si.rs @@ -16,7 +16,7 @@ macro_rules! add_test { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); @@ -47,7 +47,7 @@ macro_rules! add_test_no_replace { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); diff --git a/tests/riscv-tests-rv64ua.rs b/tests/riscv-tests-rv64ua.rs index 0d02127..a843143 100644 --- a/tests/riscv-tests-rv64ua.rs +++ b/tests/riscv-tests-rv64ua.rs @@ -17,7 +17,7 @@ mod rv64ua_p { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); @@ -75,7 +75,7 @@ mod rv64ua_v { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); diff --git a/tests/riscv-tests-rv64ud.rs b/tests/riscv-tests-rv64ud.rs index fd24012..67f7ff4 100644 --- a/tests/riscv-tests-rv64ud.rs +++ b/tests/riscv-tests-rv64ud.rs @@ -18,7 +18,7 @@ mod rv64ud_p { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); @@ -69,7 +69,7 @@ mod rv64ud_v { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); diff --git a/tests/riscv-tests-rv64ui.rs b/tests/riscv-tests-rv64ui.rs index 7befff5..871b6fa 100644 --- a/tests/riscv-tests-rv64ui.rs +++ b/tests/riscv-tests-rv64ui.rs @@ -18,7 +18,7 @@ mod rv64ui_p { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); @@ -109,7 +109,7 @@ mod rv64ui_v { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); diff --git a/tests/riscv-tests-rv64um.rs b/tests/riscv-tests-rv64um.rs index 7aa099e..19a2c75 100644 --- a/tests/riscv-tests-rv64um.rs +++ b/tests/riscv-tests-rv64um.rs @@ -18,7 +18,7 @@ mod rv64um_p { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE); @@ -69,7 +69,7 @@ mod rv64um_v { let mut data = Vec::new(); file.read_to_end(&mut data)?; - let mut emu = Emulator::new(); + let mut emu = Emulator::new(false, false); emu.initialize_dram(data); emu.initialize_pc(DRAM_BASE);