Skip to content

Commit

Permalink
[difftest] revert offline changes temporally
Browse files Browse the repository at this point in the history
  • Loading branch information
FanShupei committed Aug 28, 2024
1 parent aec68df commit 58fce44
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 69 deletions.
9 changes: 5 additions & 4 deletions difftest/offline/src/difftest.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use spike_rs::runner::{SpikeArgs, SpikeRunner};
use common::spike_runner::SpikeRunner;
use std::path::Path;
use tracing::info;

use common::rtl_config::RTLConfig;
use common::CommonArgs;

use crate::dut::Dut;
use crate::json_events::*;
Expand All @@ -16,12 +17,12 @@ pub struct Difftest {
}

impl Difftest {
pub fn new(args: &SpikeArgs) -> Self {
pub fn new(args: CommonArgs) -> Self {
let config = RTLConfig { vlen: args.vlen, dlen: args.dlen };
Self {
runner: SpikeRunner::new(args, true),
runner: SpikeRunner::new(&args, true),
dut: Dut::new(Path::new(
args.log_file.as_ref().expect("difftest must be run with a log file"),
&args.log_file.expect("difftest must be run with a log file"),
)),
config,
}
Expand Down
3 changes: 2 additions & 1 deletion difftest/offline/src/json_events.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use common::spike_runner::SpikeRunner;
use num_bigint::BigUint;
use serde::{Deserialize, Deserializer};
use spike_rs::{runner::SpikeRunner, spike_event::LSU_IDX_DEFAULT};
use spike_rs::spike_event::LSU_IDX_DEFAULT;
use tracing::{debug, info};

#[derive(Deserialize, Debug, PartialEq, Clone)]
Expand Down
72 changes: 8 additions & 64 deletions difftest/offline/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,15 @@ mod difftest;
mod dut;
mod json_events;

use std::path::PathBuf;

use clap::Parser;
use spike_rs::runner::{SpikeArgs, SpikeRunner};
use tracing::{error, info, level_filters::LevelFilter};
use tracing_subscriber::{EnvFilter, FmtSubscriber};

use crate::difftest::Difftest;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Args {
/// Path to the ELF file
#[arg(long)]
pub elf_file: PathBuf,
use tracing::info;

/// Path to the log file
#[arg(long)]
pub log_file: Option<PathBuf>,
use common::spike_runner::SpikeRunner;
use common::CommonArgs;

/// deprecated, use 'RUST_LOG' instead
#[arg(long)]
pub log_level: Option<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,
}
use crate::difftest::Difftest;

fn run_spike(args: &SpikeArgs) -> anyhow::Result<()> {
fn run_spike(args: &CommonArgs) -> anyhow::Result<()> {
let mut count: u64 = 0;

let spike = SpikeRunner::new(args, true);
Expand All @@ -61,21 +32,9 @@ fn run_spike(args: &SpikeArgs) -> anyhow::Result<()> {

fn main() -> anyhow::Result<()> {
// parse args
let args = Args::parse();

setup_logger();

if args.log_level.is_some() {
error!("'--log-level' is deprecated, use 'RUST_LOG' env instead");
}
let args = CommonArgs::parse();

let args = SpikeArgs {
elf_file: args.elf_file,
log_file: args.log_file,
vlen: args.vlen,
dlen: args.dlen,
set: args.set,
};
args.setup_logger()?;

// if there is no log file, just run spike and quit
if args.log_file.is_none() {
Expand All @@ -84,7 +43,7 @@ fn main() -> anyhow::Result<()> {
}

// if there is a log file, run difftest
let mut diff = Difftest::new(&args);
let mut diff = Difftest::new(args);

loop {
match diff.diff() {
Expand All @@ -96,18 +55,3 @@ 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 global_logger = FmtSubscriber::builder()
.with_env_filter(env_filer)
.without_time()
.with_target(false)
.compact()
.finish();
tracing::subscriber::set_global_default(global_logger)
.expect("internal error: fail to setup log subscriber");
}
1 change: 1 addition & 0 deletions difftest/test_common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use tracing::Level;
use tracing_subscriber::{EnvFilter, FmtSubscriber};

pub mod rtl_config;
pub mod spike_runner;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
Expand Down
135 changes: 135 additions & 0 deletions difftest/test_common/src/spike_runner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use std::collections::VecDeque;
use std::path::Path;
use tracing::debug;

use spike_rs::spike_event::SpikeEvent;
use spike_rs::util::load_elf;
use spike_rs::Spike;

use crate::CommonArgs;

pub struct SpikeRunner {
spike: Box<Spike>,

/// commit queue
/// in the spike thread, spike should detech if this queue is full, if not
/// full, execute until a vector instruction, record the behavior of this
/// instruction, and send to commit queue.
/// Note:
/// - The event issued earliest is at the back of the queue
/// - The queue may contain at most one unissued event. If so, the unissued event must be at the
/// front of the queue, and it must be a fence
pub commit_queue: VecDeque<SpikeEvent>,

/// config for v extension
pub vlen: u32,
pub dlen: u32,

/// implement the get_t() for mcycle csr update
pub cycle: u64,

/// for mcycle csr update
pub spike_cycle: u64,

pub do_log_vrf: bool,
}

impl SpikeRunner {
pub fn new(args: &CommonArgs, do_log_vrf: bool) -> Self {
// load the elf file
// initialize spike
let mut spike = args.to_spike_c_handler();

let entry_addr = load_elf(&mut spike, Path::new(&args.elf_file)).unwrap();

// initialize processor
let proc = spike.get_proc();
let state = proc.get_state();
proc.reset();
state.set_pc(entry_addr);

SpikeRunner {
spike,
commit_queue: VecDeque::new(),
vlen: args.vlen,
dlen: args.dlen,
cycle: 0,
spike_cycle: 0,
do_log_vrf,
}
}

pub fn load_elf(&mut self, fname: &Path) -> anyhow::Result<u64> {
load_elf(&mut *self.spike, fname)
}

// just execute one instruction for non-difftest
pub fn exec(&self) -> anyhow::Result<()> {
let spike = &self.spike;
let proc = spike.get_proc();
let state = proc.get_state();

let new_pc = proc.func();

state.handle_pc(new_pc).unwrap();

Ok(())
}

// execute the spike processor for one instruction and record
// the spike event for difftest
pub fn spike_step(&mut self) -> SpikeEvent {
let spike = &self.spike;
let proc = self.spike.get_proc();
let state = proc.get_state();

let mcycle = (self.cycle + self.spike_cycle) as usize;
state.set_mcycle(0);

let mut event = SpikeEvent::new(spike, self.do_log_vrf);
state.clear();

let new_pc = if event.is_v() || event.is_exit() {
// inst is v / quit
debug!(
"SpikeStep: spike run vector insn ({}), mcycle={mcycle}",
event.describe_insn(),
);
event.pre_log_arch_changes(spike, self.vlen).unwrap();
let new_pc_ = proc.func();
event.log_arch_changes(spike, self.vlen).unwrap();
new_pc_
} else {
// inst is scalar
debug!(
"SpikeStep: spike run scalar insn ({}), mcycle={mcycle}",
event.describe_insn(),
);
let new_pc_ = proc.func();
event.log_mem_write(spike).unwrap();
new_pc_
};

state.handle_pc(new_pc).unwrap();

self.spike_cycle += 1;

event
}

pub fn find_v_se_to_issue(&mut self) -> SpikeEvent {
if !self.commit_queue.is_empty() && self.commit_queue.front().unwrap().is_vfence() {
// if the front (latest) se is a vfence, return the vfence
self.commit_queue.front().unwrap().clone()
} else {
// else, loop until find a se, and push the se to the front
loop {
let se = self.spike_step();
if se.is_v() {
self.commit_queue.push_front(se.clone());
break se.clone();
}
}
}
}
}

0 comments on commit 58fce44

Please sign in to comment.