From 61729907ad64ab1d40adb9445c1e79b35c933ef4 Mon Sep 17 00:00:00 2001 From: Shupei Fan Date: Sat, 7 Dec 2024 13:42:06 +0000 Subject: [PATCH] [difftest & t1emu & nix] pass dlen/vlen/isa to online by verilog paramters --- difftest/Cargo.lock | 18 ++++++- difftest/Cargo.toml | 1 + difftest/default.nix | 4 +- difftest/dpi_t1emu/src/dpi.rs | 27 +++++++--- difftest/dpi_t1emu/src/drive.rs | 40 +++++++++++---- difftest/dpi_t1emu/src/lib.rs | 43 ---------------- difftest/dpi_t1rocketemu/src/dpi.rs | 25 +++++++--- difftest/dpi_t1rocketemu/src/drive.rs | 19 +++++-- difftest/dpi_t1rocketemu/src/lib.rs | 30 ----------- difftest/offline_common/Cargo.toml | 15 ++++++ difftest/offline_common/src/lib.rs | 63 ++++++++++++++++++++++++ difftest/offline_t1emu/Cargo.toml | 1 + difftest/offline_t1emu/src/main.rs | 5 +- difftest/offline_t1rocketemu/Cargo.toml | 1 + difftest/offline_t1rocketemu/src/main.rs | 5 +- difftest/spike_rs/Cargo.toml | 2 - difftest/spike_rs/src/runner.rs | 32 +----------- profiler/default.nix | 2 +- t1/src/T1.scala | 4 +- t1emu/src/TestBench.scala | 19 ++++--- t1emu/vsrc/VerbatimModule.sv | 30 +++++++++-- t1rocketemu/src/TestBench.scala | 22 ++++++--- t1rocketemu/vsrc/VerbatimModule.sv | 30 ++++++++--- 23 files changed, 270 insertions(+), 168 deletions(-) create mode 100644 difftest/offline_common/Cargo.toml create mode 100644 difftest/offline_common/src/lib.rs diff --git a/difftest/Cargo.lock b/difftest/Cargo.lock index b65312e95..81c78a44f 100644 --- a/difftest/Cargo.lock +++ b/difftest/Cargo.lock @@ -319,6 +319,20 @@ dependencies = [ "autocfg", ] +[[package]] +name = "offline_common" +version = "0.1.0" +dependencies = [ + "anyhow", + "clap", + "num-bigint", + "serde", + "serde_json", + "spike_rs", + "tracing", + "tracing-subscriber", +] + [[package]] name = "offline_t1emu" version = "0.1.0" @@ -327,6 +341,7 @@ dependencies = [ "clap", "libloading", "num-bigint", + "offline_common", "serde", "serde_json", "spike_rs", @@ -343,6 +358,7 @@ dependencies = [ "clap", "libloading", "num-bigint", + "offline_common", "serde", "serde_json", "spike_rs", @@ -507,10 +523,8 @@ name = "spike_rs" version = "0.1.0" dependencies = [ "anyhow", - "clap", "libc", "tracing", - "tracing-subscriber", "xmas-elf", ] diff --git a/difftest/Cargo.toml b/difftest/Cargo.toml index c8b285876..a575cd8f4 100644 --- a/difftest/Cargo.toml +++ b/difftest/Cargo.toml @@ -4,6 +4,7 @@ members = [ "spike_rs", "offline_t1emu", "offline_t1rocketemu", + "offline_common", "dpi_t1emu", "dpi_t1rocketemu", "dpi_common", diff --git a/difftest/default.nix b/difftest/default.nix index 9eaa19e9d..366717ab6 100644 --- a/difftest/default.nix +++ b/difftest/default.nix @@ -23,6 +23,7 @@ let ./dpi_common ./dpi_t1emu ./dpi_t1rocketemu + ./offline_common ./offline_t1emu ./offline_t1rocketemu ./Cargo.lock @@ -43,9 +44,6 @@ if (lib.hasPrefix "dpi" moduleType) then env = { SPIKE_LIB_DIR = "${libspike}/lib"; SPIKE_INTERFACES_LIB_DIR = "${libspike_interfaces}/lib"; - DESIGN_VLEN = rtlDesignMetadata.vlen; - DESIGN_DLEN = rtlDesignMetadata.dlen; - SPIKE_ISA_STRING = rtlDesignMetadata.march; }; cargoLock = { diff --git a/difftest/dpi_t1emu/src/dpi.rs b/difftest/dpi_t1emu/src/dpi.rs index cf89f7ba3..d3f193579 100644 --- a/difftest/dpi_t1emu/src/dpi.rs +++ b/difftest/dpi_t1emu/src/dpi.rs @@ -1,13 +1,12 @@ #![allow(non_snake_case)] #![allow(unused_variables)] -use dpi_common::plusarg::PlusArgMatcher; use dpi_common::DpiTarget; use std::ffi::c_longlong; +use svdpi::dpi::param::InStr; use tracing::debug; -use crate::drive::Driver; -use crate::OnlineArgs; +use crate::drive::{Driver, OnlineArgs}; use svdpi::SvScope; pub type SvBitVecVal = u32; @@ -217,17 +216,31 @@ unsafe extern "C" fn axi_write_indexedAccessPort( } #[no_mangle] -unsafe extern "C" fn t1_cosim_init() { - let plusargs = PlusArgMatcher::from_args(); - let args = OnlineArgs::from_plusargs(&plusargs); - +unsafe extern "C" fn t1_cosim_init( + elf_file: InStr<'_>, + dlen: i32, + vlen: i32, + spike_isa: InStr<'_>, +) { dpi_common::setup_logger(); let scope = SvScope::get_current().expect("failed to get scope in t1_cosim_init"); + let args = OnlineArgs { + elf_file: elf_file.get().to_str().unwrap().into(), + log_file: None, + dlen: dlen as u32, + vlen: vlen as u32, + spike_isa: spike_isa.get().to_str().unwrap().into(), + }; TARGET.init(|| Driver::new(scope, &args)); } +#[no_mangle] +unsafe extern "C" fn t1_cosim_set_timeout(timeout: u64) { + TARGET.with(|driver| driver.set_timeout(timeout)); +} + #[no_mangle] unsafe extern "C" fn t1_cosim_final() { TARGET.with(|driver| { diff --git a/difftest/dpi_t1emu/src/drive.rs b/difftest/dpi_t1emu/src/drive.rs index 45ac99794..ca4f96097 100644 --- a/difftest/dpi_t1emu/src/drive.rs +++ b/difftest/dpi_t1emu/src/drive.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use spike_rs::runner::SpikeRunner; use spike_rs::runner::{SpikeArgs, MEM_SIZE}; use spike_rs::spike_event::MemAccessRecord; @@ -7,7 +9,6 @@ use tracing::{debug, error, info, trace}; use crate::dpi::*; use crate::get_t; -use crate::OnlineArgs; use svdpi::SvScope; struct ShadowMem { @@ -95,6 +96,23 @@ impl ShadowMem { } } +pub(crate) struct OnlineArgs { + /// Path to the ELF file + pub elf_file: String, + + /// Path to the log file + pub log_file: Option, + + /// vlen config + pub vlen: u32, + + /// dlen config + pub dlen: u32, + + /// ISA config + pub spike_isa: String, +} + pub(crate) struct Driver { spike_runner: SpikeRunner, @@ -118,15 +136,15 @@ pub(crate) struct Driver { impl Driver { pub(crate) fn new(scope: SvScope, args: &OnlineArgs) -> Self { + let elf_file = Path::new(&args.elf_file); let mut self_ = Self { spike_runner: SpikeRunner::new( &SpikeArgs { - elf_file: args.elf_file.clone(), - log_file: args.log_file.clone(), - log_level: "info".to_string(), + elf_file: elf_file.to_owned(), + log_file: args.log_file.as_ref().map(From::from), vlen: args.vlen, dlen: args.dlen, - set: args.set.clone(), + set: args.spike_isa.clone(), }, false, ), @@ -135,16 +153,16 @@ impl Driver { success: false, dlen: args.dlen, - timeout: args.timeout, + timeout: 0, last_commit_cycle: 0, issued: 0, vector_lsu_count: 0, shadow_mem: ShadowMem::new(), }; - self_.spike_runner.load_elf(&args.elf_file).unwrap(); + self_.spike_runner.load_elf(elf_file).unwrap(); - load_elf_to_buffer(&mut self_.shadow_mem.mem, &args.elf_file).unwrap(); + load_elf_to_buffer(&mut self_.shadow_mem.mem, elf_file).unwrap(); self_ } @@ -204,6 +222,10 @@ impl Driver { ); } + pub(crate) fn set_timeout(&mut self, timeout: u64) { + self.timeout = timeout; + } + pub(crate) fn watchdog(&mut self) -> u8 { let tick = get_t(); @@ -212,7 +234,7 @@ impl Driver { return WATCHDOG_QUIT; } - if tick - self.last_commit_cycle > self.timeout { + if self.timeout > 0 && tick - self.last_commit_cycle > self.timeout { error!( "[{tick}] watchdog timeout (last_commit_cycle={})", self.last_commit_cycle diff --git a/difftest/dpi_t1emu/src/lib.rs b/difftest/dpi_t1emu/src/lib.rs index ac7ec54bb..a3cd17528 100644 --- a/difftest/dpi_t1emu/src/lib.rs +++ b/difftest/dpi_t1emu/src/lib.rs @@ -1,49 +1,6 @@ -use std::path::PathBuf; - -use dpi_common::plusarg::PlusArgMatcher; - pub mod dpi; pub mod drive; -pub(crate) struct OnlineArgs { - /// Path to the ELF file - pub elf_file: PathBuf, - - /// Path to the log file - pub log_file: Option, - - /// vlen config - pub vlen: u32, - - /// dlen config - pub dlen: u32, - - /// ISA config - pub set: String, - - // default to TIMEOUT_DEFAULT - pub timeout: u64, -} - -const TIMEOUT_DEFAULT: u64 = 1000000; - -impl OnlineArgs { - pub fn from_plusargs(matcher: &PlusArgMatcher) -> Self { - Self { - elf_file: matcher.match_("t1_elf_file").into(), - log_file: matcher.try_match("t1_log_file").map(|x| x.into()), - - vlen: env!("DESIGN_VLEN").parse().unwrap(), - dlen: env!("DESIGN_DLEN").parse().unwrap(), - set: env!("SPIKE_ISA_STRING").parse().unwrap(), - timeout: matcher - .try_match("t1_timeout") - .map(|x| x.parse().unwrap()) - .unwrap_or(TIMEOUT_DEFAULT), - } - } -} - // keep in sync with TestBench.verbatimModule // the value is measured in simulation time unit pub const CYCLE_PERIOD: u64 = 20000; diff --git a/difftest/dpi_t1rocketemu/src/dpi.rs b/difftest/dpi_t1rocketemu/src/dpi.rs index 9c6f40956..96405ec30 100644 --- a/difftest/dpi_t1rocketemu/src/dpi.rs +++ b/difftest/dpi_t1rocketemu/src/dpi.rs @@ -1,14 +1,13 @@ #![allow(non_snake_case)] #![allow(unused_variables)] -use dpi_common::plusarg::PlusArgMatcher; use dpi_common::DpiTarget; use std::ffi::c_longlong; +use svdpi::dpi::param::InStr; use svdpi::SvScope; use tracing::debug; -use crate::drive::Driver; -use crate::OnlineArgs; +use crate::drive::{Driver, OnlineArgs}; pub type SvBitVecVal = u32; @@ -317,14 +316,21 @@ unsafe extern "C" fn axi_read_instructionFetchAXI( } #[no_mangle] -unsafe extern "C" fn t1_cosim_init() { - let plusargs = PlusArgMatcher::from_args(); - let args = OnlineArgs::from_plusargs(&plusargs); - +unsafe extern "C" fn t1_cosim_init( + elf_file: InStr<'_>, + dlen: i32, + vlen: i32, + spike_isa: InStr<'_>, +) { dpi_common::setup_logger(); let scope = SvScope::get_current().expect("failed to get scope in t1_cosim_init"); + let args = OnlineArgs { + elf_file: elf_file.get().to_str().unwrap().into(), + dlen: dlen as u32, + }; + TARGET.init(|| Driver::new(scope, &args)); } @@ -336,6 +342,11 @@ unsafe extern "C" fn t1_cosim_final() { }); } +#[no_mangle] +unsafe extern "C" fn t1_cosim_set_timeout(timeout: u64) { + TARGET.with(|driver| driver.set_timeout(timeout)); +} + /// evaluate at every cycle /// return value: /// 0 : continue diff --git a/difftest/dpi_t1rocketemu/src/drive.rs b/difftest/dpi_t1rocketemu/src/drive.rs index c42e2e1cc..fc460eeb5 100644 --- a/difftest/dpi_t1rocketemu/src/drive.rs +++ b/difftest/dpi_t1rocketemu/src/drive.rs @@ -1,7 +1,6 @@ use crate::get_t; use crate::interconnect::simctrl::ExitFlagRef; use crate::interconnect::{create_emu_addrspace, AddressSpace}; -use crate::OnlineArgs; use svdpi::SvScope; use anyhow::Context; @@ -25,6 +24,14 @@ pub struct FunctionSym { } pub type FunctionSymTab = HashMap; +pub struct OnlineArgs { + /// Path to the ELF file + pub elf_file: String, + + /// dlen config + pub dlen: u32, +} + pub(crate) struct Driver { // SvScope from t1rocket_cosim_init #[allow(unused)] @@ -46,7 +53,7 @@ impl Driver { let (mut addr_space, exit_flag) = create_emu_addrspace(); // pass e_entry to rocket let (e_entry, _fn_sym_tab) = - Self::load_elf(&args.elf_file, &mut addr_space).expect("fail creating simulator"); + Self::load_elf(Path::new(&args.elf_file), &mut addr_space).expect("fail creating simulator"); Self { scope, @@ -54,7 +61,7 @@ impl Driver { dlen: args.dlen, e_entry, - timeout: args.timeout, + timeout: 0, last_commit_cycle: 0, addr_space, @@ -204,6 +211,10 @@ impl Driver { } } + pub(crate) fn set_timeout(&mut self, timeout: u64) { + self.timeout = timeout; + } + pub(crate) fn watchdog(&mut self) -> u8 { const WATCHDOG_CONTINUE: u8 = 0; const WATCHDOG_TIMEOUT: u8 = 1; @@ -216,7 +227,7 @@ impl Driver { return WATCHDOG_QUIT; } - if tick - self.last_commit_cycle > self.timeout { + if self.timeout > 0 && tick - self.last_commit_cycle > self.timeout { error!( "[{tick}] watchdog timeout (last_commit_cycle={})", self.last_commit_cycle diff --git a/difftest/dpi_t1rocketemu/src/lib.rs b/difftest/dpi_t1rocketemu/src/lib.rs index d21fd1595..9ce1dea36 100644 --- a/difftest/dpi_t1rocketemu/src/lib.rs +++ b/difftest/dpi_t1rocketemu/src/lib.rs @@ -1,37 +1,7 @@ -use std::path::PathBuf; - -use dpi_common::plusarg::PlusArgMatcher; - mod dpi; mod drive; mod interconnect; -pub(crate) struct OnlineArgs { - /// Path to the ELF file - pub elf_file: PathBuf, - - /// dlen config - pub dlen: u32, - - // default to TIMEOUT_DEFAULT - pub timeout: u64, -} - -const TIMEOUT_DEFAULT: u64 = 1000000; - -impl OnlineArgs { - pub fn from_plusargs(matcher: &PlusArgMatcher) -> Self { - Self { - elf_file: matcher.match_("t1_elf_file").into(), - dlen: env!("DESIGN_DLEN").parse().unwrap(), - timeout: matcher - .try_match("t1_timeout") - .map(|x| x.parse().unwrap()) - .unwrap_or(TIMEOUT_DEFAULT), - } - } -} - // keep in sync with TestBench.verbatimModule // the value is measured in simulation time unit pub const CYCLE_PERIOD: u64 = 20000; diff --git a/difftest/offline_common/Cargo.toml b/difftest/offline_common/Cargo.toml new file mode 100644 index 000000000..efc9cd546 --- /dev/null +++ b/difftest/offline_common/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "offline_common" +version = "0.1.0" +edition = "2021" + +[dependencies] +clap = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +anyhow = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +num-bigint = { workspace = true } + +spike_rs = { path = "../spike_rs" } diff --git a/difftest/offline_common/src/lib.rs b/difftest/offline_common/src/lib.rs new file mode 100644 index 000000000..44b629236 --- /dev/null +++ b/difftest/offline_common/src/lib.rs @@ -0,0 +1,63 @@ +use std::path::PathBuf; + +use clap::Parser; +use spike_rs::runner::SpikeArgs; +use tracing::Level; +use tracing_subscriber::{EnvFilter, FmtSubscriber}; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +pub struct OfflineArgs { + /// Path to the ELF file + #[arg(long)] + pub elf_file: PathBuf, + + /// Path to the log file + #[arg(long)] + pub log_file: Option, + + /// Log level: trace, debug, info, warn, error + #[arg(long, default_value = "info")] + pub log_level: String, + + /// vlen config + #[arg(long, default_value = env!("DESIGN_VLEN"))] + pub vlen: u32, + + /// dlen config + #[arg(long, default_value = env!("DESIGN_DLEN"))] + pub dlen: u32, + + /// ISA config + #[arg(long, default_value = env!("SPIKE_ISA_STRING"))] + pub set: String, +} + +impl OfflineArgs { + pub fn to_spike_args(self) -> SpikeArgs { + SpikeArgs { + elf_file: self.elf_file, + log_file: self.log_file, + vlen: self.vlen, + dlen: self.dlen, + set: self.set, + } + } + + pub fn setup_logger(&self) -> anyhow::Result<()> { + // setup log + let log_level: Level = self.log_level.parse()?; + let global_logger = FmtSubscriber::builder() + .with_env_filter(EnvFilter::from_default_env()) + .with_max_level(log_level) + .without_time() + .with_target(false) + .with_ansi(true) + .compact() + .finish(); + tracing::subscriber::set_global_default(global_logger) + .expect("internal error: fail to setup log subscriber"); + + Ok(()) + } +} diff --git a/difftest/offline_t1emu/Cargo.toml b/difftest/offline_t1emu/Cargo.toml index 8013827fa..503d4f649 100644 --- a/difftest/offline_t1emu/Cargo.toml +++ b/difftest/offline_t1emu/Cargo.toml @@ -16,3 +16,4 @@ libloading = "0.8.1" xmas-elf = "0.9.1" spike_rs = { path = "../spike_rs" } +offline_common = { path = "../offline_common" } diff --git a/difftest/offline_t1emu/src/main.rs b/difftest/offline_t1emu/src/main.rs index 01ba1eff0..45abdbd63 100644 --- a/difftest/offline_t1emu/src/main.rs +++ b/difftest/offline_t1emu/src/main.rs @@ -9,6 +9,7 @@ use std::{ use anyhow::Context as _; use clap::Parser; use json_events::JsonEvents; +use offline_common::OfflineArgs; use tracing::info; use spike_rs::runner::*; @@ -35,10 +36,12 @@ fn run_spike(args: &SpikeArgs) -> anyhow::Result<()> { fn main() -> anyhow::Result<()> { // parse args - let args = SpikeArgs::parse(); + let args = OfflineArgs::parse(); args.setup_logger()?; + let args = args.to_spike_args(); + match &args.log_file { None => { // if there is no log file, just run spike and quit diff --git a/difftest/offline_t1rocketemu/Cargo.toml b/difftest/offline_t1rocketemu/Cargo.toml index 37c749d35..0e86b04f9 100644 --- a/difftest/offline_t1rocketemu/Cargo.toml +++ b/difftest/offline_t1rocketemu/Cargo.toml @@ -16,3 +16,4 @@ libloading = "0.8.1" xmas-elf = "0.9.1" spike_rs = { path = "../spike_rs" } +offline_common = { path = "../offline_common" } diff --git a/difftest/offline_t1rocketemu/src/main.rs b/difftest/offline_t1rocketemu/src/main.rs index 8018b3d3c..b90ba1893 100644 --- a/difftest/offline_t1rocketemu/src/main.rs +++ b/difftest/offline_t1rocketemu/src/main.rs @@ -9,6 +9,7 @@ use std::{ use anyhow::Context as _; use clap::Parser; use json_events::JsonEvents; +use offline_common::OfflineArgs; use tracing::info; use spike_rs::runner::{SpikeArgs, SpikeRunner}; @@ -35,10 +36,12 @@ fn run_spike(args: &SpikeArgs) -> anyhow::Result<()> { fn main() -> anyhow::Result<()> { // parse args - let args = SpikeArgs::parse(); + let args = OfflineArgs::parse(); args.setup_logger()?; + let args = args.to_spike_args(); + match &args.log_file { None => { // if there is no log file, just run spike and quit diff --git a/difftest/spike_rs/Cargo.toml b/difftest/spike_rs/Cargo.toml index b1dee9f83..a6f085855 100644 --- a/difftest/spike_rs/Cargo.toml +++ b/difftest/spike_rs/Cargo.toml @@ -5,9 +5,7 @@ edition = "2021" [dependencies] anyhow = { workspace = true } -clap = { workspace = true } tracing = { workspace = true } -tracing-subscriber = { workspace = true } libc = "0.2.155" xmas-elf = "0.9.1" diff --git a/difftest/spike_rs/src/runner.rs b/difftest/spike_rs/src/runner.rs index e96722307..9e85b58ef 100644 --- a/difftest/spike_rs/src/runner.rs +++ b/difftest/spike_rs/src/runner.rs @@ -1,8 +1,6 @@ -use clap::Parser; use std::collections::VecDeque; use std::path::{Path, PathBuf}; -use tracing::{debug, Level}; -use tracing_subscriber::{EnvFilter, FmtSubscriber}; +use tracing::debug; use crate::spike_event::SpikeEvent; use crate::util::load_elf; @@ -49,31 +47,20 @@ pub struct SpikeRunner { pub frf_board: Vec>, } -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] pub struct SpikeArgs { /// Path to the ELF file - #[arg(long)] pub elf_file: PathBuf, /// Path to the log file - #[arg(long)] pub log_file: Option, - /// Log level: trace, debug, info, warn, error - #[arg(long, default_value = "info")] - pub log_level: String, - /// vlen config - #[arg(long, default_value = env!("DESIGN_VLEN"))] pub vlen: u32, /// dlen config - #[arg(long, default_value = env!("DESIGN_DLEN"))] pub dlen: u32, /// ISA config - #[arg(long, default_value = env!("SPIKE_ISA_STRING"))] pub set: String, } @@ -82,23 +69,6 @@ impl SpikeArgs { let lvl = "M"; Spike::new(&self.set, lvl, (self.dlen / 32) as usize, MEM_SIZE) } - - pub fn setup_logger(&self) -> anyhow::Result<()> { - // setup log - let log_level: Level = self.log_level.parse()?; - let global_logger = FmtSubscriber::builder() - .with_env_filter(EnvFilter::from_default_env()) - .with_max_level(log_level) - .without_time() - .with_target(false) - .with_ansi(true) - .compact() - .finish(); - tracing::subscriber::set_global_default(global_logger) - .expect("internal error: fail to setup log subscriber"); - - Ok(()) - } } pub const MEM_SIZE: usize = 1usize << 32; diff --git a/profiler/default.nix b/profiler/default.nix index 417596e82..9cd6af948 100644 --- a/profiler/default.nix +++ b/profiler/default.nix @@ -6,7 +6,7 @@ rustPlatform.buildRustPackage { src = ./.; name = "profiler"; - + cargoLock = { lockFile = ./Cargo.lock; }; diff --git a/t1/src/T1.scala b/t1/src/T1.scala index 142aa67e5..dc08f788f 100644 --- a/t1/src/T1.scala +++ b/t1/src/T1.scala @@ -143,6 +143,8 @@ case class T1Parameter( vlen.toInt }.get + def spikeMarch: String = s"rv32gc_${extensions.mkString("_").toLowerCase}" + val allInstructions: Seq[Instruction] = { org.chipsalliance.rvdecoderdb .instructions(org.chipsalliance.rvdecoderdb.extractResource(getClass.getClassLoader)) @@ -392,7 +394,7 @@ class T1(val parameter: T1Parameter) omInstance.vlenIn := Property(parameter.vLen) omInstance.dlenIn := Property(parameter.dLen) omInstance.extensionsIn := Property(parameter.extensions) - omInstance.marchIn := Property(s"rv32gc_${parameter.extensions.mkString("_").toLowerCase}") + omInstance.marchIn := Property(parameter.spikeMarch) /** the LSU Module */ diff --git a/t1emu/src/TestBench.scala b/t1emu/src/TestBench.scala index cfe02fdc3..ae1e6f648 100644 --- a/t1emu/src/TestBench.scala +++ b/t1emu/src/TestBench.scala @@ -39,12 +39,19 @@ class TestBench(val parameter: T1Parameter) val om: Property[ClassType] = IO(Output(Property[omType.Type]())) om := omInstance.getPropertyReference - val verbatimModule = Module(new ExtModule { - - override def desiredName = "VerbatimModule" - val clock = IO(Output(Bool())) - val reset = IO(Output(Bool())) - }) + val verbatimModule = Module( + new ExtModule( + Map( + "T1_VLEN" -> parameter.vLen, + "T1_DLEN" -> parameter.dLen, + "T1_SPIKE_ISA" -> parameter.spikeMarch + ) + ) { + override def desiredName = "VerbatimModule" + val clock = IO(Output(Bool())) + val reset = IO(Output(Bool())) + } + ) def clock = verbatimModule.clock.asClock def reset = verbatimModule.reset override def implicitClock = verbatimModule.clock.asClock diff --git a/t1emu/vsrc/VerbatimModule.sv b/t1emu/vsrc/VerbatimModule.sv index 3d1dfb3f2..ae2d16161 100644 --- a/t1emu/vsrc/VerbatimModule.sv +++ b/t1emu/vsrc/VerbatimModule.sv @@ -1,18 +1,27 @@ -module VerbatimModule(output reg clock, output reg reset); +module VerbatimModule #( + parameter integer T1_DLEN, + parameter integer T1_VLEN, + parameter string T1_SPIKE_ISA +)( + output reg clock, + output reg reset +); // This module contains everything we can not represent in Chisel currently, // including clock gen, plusarg parsing, sim control, etc // // plusargs: "T" denotes being present only if trace is enabled - // +t1_elf_file (required) path to elf file, parsed in DPI side + // +t1_elf_file (required) path to elf file // +t1_wave_path (required T) path to wave dump file - // +t1_timeout (optional) max cycle between two V inst retire, parsed in DPI side + // +t1_timeout (optional) max cycle between two V inst retire // +t1_global_timeout (optional) max cycle for whole simulation, for debug only // +t1_dump_start (optional T) cycle when dump starts, by default it's simulation start, for debug only // +t1_dump_end (optional T) cycle when dump ends, by default is's simulation end, for debug only longint unsigned cycle = 0; longint unsigned global_timeout = 0; + longint unsigned dpi_timeout = 1000000; + string elf_file; `ifdef T1_ENABLE_TRACE longint unsigned dump_start = 0; longint unsigned dump_end = 0; @@ -44,7 +53,13 @@ module VerbatimModule(output reg clock, output reg reset); endfunction `endif - import "DPI-C" context function void t1_cosim_init(); + import "DPI-C" context function void t1_cosim_init( + string elf_file, + int dlen, + int vlen, + string spike_isa + ); + import "DPI-C" context function void t1_cosim_set_timeout(longint unsigned timeout); import "DPI-C" context function void t1_cosim_final(); import "DPI-C" context function byte unsigned t1_cosim_watchdog(); @@ -57,9 +72,14 @@ module VerbatimModule(output reg clock, output reg reset); $value$plusargs("t1_dump_end=%d", dump_end); $value$plusargs("t1_wave_path=%s", wave_path); `endif + $value$plusargs("t1_elf_file=%s", elf_file); + $value$plusargs("t1_timeout=%d", dpi_timeout); $value$plusargs("t1_global_timeout=%d", global_timeout); - t1_cosim_init(); + if (elf_file.len() == 0) $fatal(1, "+t1_elf_file must be set"); + + t1_cosim_init(elf_file, T1_DLEN, T1_VLEN, T1_SPIKE_ISA); + t1_cosim_set_timeout(dpi_timeout); `ifdef T1_ENABLE_TRACE if (dump_start == 0) begin diff --git a/t1rocketemu/src/TestBench.scala b/t1rocketemu/src/TestBench.scala index 032ae3c12..9e55ffa5a 100644 --- a/t1rocketemu/src/TestBench.scala +++ b/t1rocketemu/src/TestBench.scala @@ -39,13 +39,21 @@ class TestBench(val parameter: T1RocketTileParameter) val om: Property[ClassType] = IO(Output(Property[omType.Type]())) om := omInstance.getPropertyReference - val verbatimModule = Module(new ExtModule { - override def desiredName = "VerbatimModule" - val clock = IO(Output(Bool())) - val reset = IO(Output(Bool())) - val initFlag = IO(Output(Bool())) - val idle = IO(Input(Bool())) - }) + val verbatimModule = Module( + new ExtModule( + Map( + "T1_VLEN" -> parameter.vLen, + "T1_DLEN" -> parameter.dLen, + "T1_SPIKE_ISA" -> parameter.t1Parameter.spikeMarch + ) + ) { + override def desiredName = "VerbatimModule" + val clock = IO(Output(Bool())) + val reset = IO(Output(Bool())) + val initFlag = IO(Output(Bool())) + val idle = IO(Input(Bool())) + } + ) def clock = verbatimModule.clock.asClock def reset = verbatimModule.reset def initFlag = verbatimModule.initFlag diff --git a/t1rocketemu/vsrc/VerbatimModule.sv b/t1rocketemu/vsrc/VerbatimModule.sv index 6f4b2dd50..2cf3d542e 100644 --- a/t1rocketemu/vsrc/VerbatimModule.sv +++ b/t1rocketemu/vsrc/VerbatimModule.sv @@ -1,4 +1,8 @@ -module VerbatimModule( +module VerbatimModule #( + parameter integer T1_DLEN, + parameter integer T1_VLEN, + parameter string T1_SPIKE_ISA +)( output reg clock, output reg reset, output reg initFlag, @@ -9,9 +13,9 @@ module VerbatimModule( // including clock gen, plusarg parsing, sim control, etc // // plusargs: "T" denotes being present only if trace is enabled - // +t1_elf_file (required) path to elf file, parsed in DPI side + // +t1_elf_file (required) path to elf file // +t1_wave_path (required T) path to wave dump file - // +t1_timeout (optional) max cycle between two AXI DPI call, parsed in DPI side + // +t1_timeout (optional) max cycle between two AXI DPI call // +t1_global_timeout (optional) max cycle for whole simulation, for debug only // +t1_timeout_after_quit (optional) // +t1_dump_start (optional T) cycle when dump starts, by default it's simulation start, for debug only @@ -21,6 +25,8 @@ module VerbatimModule( longint unsigned quit_cycle = 0; longint unsigned global_timeout = 0; longint unsigned timeout_after_quit = 10000; + longint unsigned dpi_timeout = 1000000; + string elf_file; `ifdef T1_ENABLE_TRACE longint unsigned dump_start = 0; longint unsigned dump_end = 0; @@ -52,7 +58,13 @@ module VerbatimModule( endfunction `endif - import "DPI-C" context function void t1_cosim_init(); + import "DPI-C" context function void t1_cosim_init( + string elf_file, + int dlen, + int vlen, + string spike_isa + ); + import "DPI-C" context function void t1_cosim_set_timeout(longint unsigned timeout); import "DPI-C" context function void t1_cosim_final(); import "DPI-C" context function byte unsigned t1_cosim_watchdog(); @@ -66,13 +78,15 @@ module VerbatimModule( $value$plusargs("t1_dump_end=%d", dump_end); $value$plusargs("t1_wave_path=%s", wave_path); `endif + $value$plusargs("t1_elf_file=%s", elf_file); + $value$plusargs("t1_timeout=%d", dpi_timeout); $value$plusargs("t1_global_timeout=%d", global_timeout); $value$plusargs("t1_timeout_after_quit=%d", timeout_after_quit); - // Args: - // +t1_elf_file=... : path of elf file - // +t1_timeout=... : (optional) max interval of inst commit, counted in cycle - t1_cosim_init(); + if (elf_file.len() == 0) $fatal(1, "+t1_elf_file must be set"); + + t1_cosim_init(elf_file, T1_DLEN, T1_VLEN, T1_SPIKE_ISA); + t1_cosim_set_timeout(dpi_timeout); `ifdef T1_ENABLE_TRACE if (dump_start == 0) begin