Skip to content

Commit

Permalink
[difftest] move wave dump logic to 'dpi_common'
Browse files Browse the repository at this point in the history
  • Loading branch information
FanShupei committed Aug 27, 2024
1 parent b895010 commit 3b30253
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 92 deletions.
109 changes: 109 additions & 0 deletions difftest/dpi_common/src/dump.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use svdpi::SvScope;
use tracing::error;

mod dpi_export {
use std::ffi::c_char;
extern "C" {
/// `export "DPI-C" function dump_wave(input string file)`
pub fn dump_wave(path: *const c_char);
}
}

fn dump_wave(scope: svdpi::SvScope, path: &str) {
use std::ffi::CString;
let path_cstring = CString::new(path).unwrap();

svdpi::set_scope(scope);
unsafe {
dpi_export::dump_wave(path_cstring.as_ptr());
}
}

pub struct DumpEndError;

pub struct RealDumpControl {
svscope: svdpi::SvScope,
wave_path: String,
dump_start: u64,
dump_end: u64,

started: bool,
}

impl RealDumpControl {
pub fn new(svscope: SvScope, wave_path: &str, dump_range: &str) -> Self {
let (dump_start, dump_end) = parse_range(dump_range);
Self {
svscope,
wave_path: wave_path.to_owned(),
dump_start,
dump_end,

started: false,
}
}

pub fn start(&mut self) {
if !self.started {
dump_wave(self.svscope, &self.wave_path);
self.started = true;
}
}

pub fn trigger_watchdog(&mut self, tick: u64) -> Result<(), DumpEndError> {
if self.dump_end != 0 && tick > self.dump_end {
return Err(DumpEndError);
}

if tick >= self.dump_start {
self.start();
}

Ok(())
}
}

pub struct EmptyDumpControl {}
impl EmptyDumpControl {
pub fn new() -> Self {
Self {}
}
pub fn start(&mut self) {
// do nothing
}
pub fn trigger_watchdog(&mut self, _tick: u64) -> Result<(), DumpEndError> {
// do nothing
Ok(())
}
}

fn parse_range(input: &str) -> (u64, u64) {
if input.is_empty() {
return (0, 0);
}

let parts: Vec<&str> = input.split(",").collect();

if parts.len() != 1 && parts.len() != 2 {
error!("invalid dump wave range: `{input}` was given");
return (0, 0);
}

const INVALID_NUMBER: &'static str = "invalid number";

if parts.len() == 1 {
return (parts[0].parse().expect(INVALID_NUMBER), 0);
}

if parts[0].is_empty() {
return (0, parts[1].parse().expect(INVALID_NUMBER));
}

let start = parts[0].parse().expect(INVALID_NUMBER);
let end = parts[1].parse().expect(INVALID_NUMBER);
if start > end {
panic!("dump start is larger than end: `{input}`");
}

(start, end)
}
2 changes: 2 additions & 0 deletions difftest/dpi_common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod dump;

use tracing_subscriber::{EnvFilter, FmtSubscriber};

pub fn setup_logger() {
Expand Down
20 changes: 0 additions & 20 deletions difftest/dpi_t1/src/dpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,23 +274,3 @@ unsafe extern "C" fn retire_vector_mem(dummy: *const SvBitVecVal) {
//--------------------------------
// import functions and wrappers
//--------------------------------

#[cfg(feature = "trace")]
mod dpi_export {
use std::ffi::c_char;
extern "C" {
/// `export "DPI-C" function dump_wave(input string file)`
pub fn dump_wave(path: *const c_char);
}
}

#[cfg(feature = "trace")]
pub(crate) fn dump_wave(scope: svdpi::SvScope, path: &str) {
use std::ffi::CString;
let path_cstring = CString::new(path).unwrap();

svdpi::set_scope(scope);
unsafe {
dpi_export::dump_wave(path_cstring.as_ptr());
}
}
90 changes: 21 additions & 69 deletions difftest/dpi_t1/src/drive.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use dpi_common::dump;
use spike_rs::runner::SpikeRunner;
use spike_rs::runner::{SpikeArgs, MEM_SIZE};
use spike_rs::spike_event::MemAccessRecord;
Expand Down Expand Up @@ -95,21 +96,18 @@ impl ShadowMem {
}
}

#[cfg(feature = "trace")]
type DumpControl = dump::RealDumpControl;
#[cfg(not(feature = "trace"))]
type DumpControl = dump::EmptyDumpControl;

pub(crate) struct Driver {
spike_runner: SpikeRunner,

// SvScope from t1_cosim_init
#[cfg(feature = "trace")]
scope: SvScope,

#[cfg(feature = "trace")]
wave_path: String,
#[cfg(feature = "trace")]
dump_start: u64,
#[cfg(feature = "trace")]
dump_end: u64,
#[cfg(feature = "trace")]
dump_started: bool,
dump_control: DumpControl,

pub(crate) dlen: u32,

Expand All @@ -123,42 +121,13 @@ pub(crate) struct Driver {
shadow_mem: ShadowMem,
}

#[cfg(feature = "trace")]
fn parse_range(input: &str) -> (u64, u64) {
if input.is_empty() {
return (0, 0);
}

let parts: Vec<&str> = input.split(",").collect();

if parts.len() != 1 && parts.len() != 2 {
error!("invalid dump wave range: `{input}` was given");
return (0, 0);
}

const INVALID_NUMBER: &'static str = "invalid number";

if parts.len() == 1 {
return (parts[0].parse().expect(INVALID_NUMBER), 0);
}

if parts[0].is_empty() {
return (0, parts[1].parse().expect(INVALID_NUMBER));
}

let start = parts[0].parse().expect(INVALID_NUMBER);
let end = parts[1].parse().expect(INVALID_NUMBER);
if start > end {
panic!("dump start is larger than end: `{input}`");
}

(start, end)
}

impl Driver {
pub(crate) fn new(scope: SvScope, args: &OnlineArgs) -> Self {
#[cfg(feature = "trace")]
let (dump_start, dump_end) = parse_range(&args.dump_range);
let dump_control = DumpControl::new(scope, &args.wave_path, &args.dump_range);

#[cfg(not(feature = "trace"))]
let dump_control = DumpControl::new();

let mut self_ = Self {
spike_runner: SpikeRunner::new(
Expand All @@ -172,16 +141,8 @@ impl Driver {
false,
),

#[cfg(feature = "trace")]
scope,
#[cfg(feature = "trace")]
wave_path: args.wave_path.to_owned(),
#[cfg(feature = "trace")]
dump_start,
#[cfg(feature = "trace")]
dump_end,
#[cfg(feature = "trace")]
dump_started: false,
dump_control,

dlen: args.dlen,
timeout: args.timeout,
Expand Down Expand Up @@ -263,31 +224,22 @@ impl Driver {
);
WATCHDOG_TIMEOUT
} else {
#[cfg(feature = "trace")]
if self.dump_end != 0 && tick > self.dump_end {
info!(
"[{tick}] run to dump end, exiting (last_commit_cycle={})",
self.last_commit_cycle
);
return WATCHDOG_TIMEOUT;
}

#[cfg(feature = "trace")]
if !self.dump_started && tick >= self.dump_start {
self.start_dump_wave();
self.dump_started = true;
match self.dump_control.trigger_watchdog(tick) {
Ok(()) => {}
Err(dump::DumpEndError) => {
info!(
"[{tick}] run to dump end, exiting (last_commit_cycle={})",
self.last_commit_cycle
);
return WATCHDOG_TIMEOUT;
}
}

trace!("[{}] watchdog continue", get_t());
WATCHDOG_CONTINUE
}
}

#[cfg(feature = "trace")]
fn start_dump_wave(&mut self) {
dump_wave(self.scope, &self.wave_path);
}

pub(crate) fn step(&mut self) -> SpikeEvent {
// there will be a vfence / scalar load / scalar store in the commit queue's front
if let Some(se) = self.spike_runner.commit_queue.front() {
Expand Down
5 changes: 2 additions & 3 deletions difftest/offline/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,8 @@ fn main() -> anyhow::Result<()> {

fn setup_logger() {
// default to WARN level
let env_filer = EnvFilter::builder()
.with_default_directive(LevelFilter::WARN.into())
.from_env_lossy();
let env_filer =
EnvFilter::builder().with_default_directive(LevelFilter::WARN.into()).from_env_lossy();

let global_logger = FmtSubscriber::builder()
.with_env_filter(env_filer)
Expand Down

0 comments on commit 3b30253

Please sign in to comment.