Skip to content

Commit

Permalink
[difftest] refactor offline_t1rocket in difftest
Browse files Browse the repository at this point in the history
  • Loading branch information
Clo91eaf committed Sep 8, 2024
1 parent e0446a2 commit 518d6ba
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 35 deletions.
2 changes: 1 addition & 1 deletion difftest/offline_t1rocket/src/difftest.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use spike_rs::spike_runner::{SpikeArgs, SpikeRunner};
use spike_rs::runner::{SpikeArgs, SpikeRunner};
use std::path::Path;

use crate::dut::Dut;
Expand Down
1 change: 1 addition & 0 deletions difftest/offline_t1rocket/src/dut.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Context;
use std::io::BufRead;
use std::path::Path;

Expand Down
78 changes: 78 additions & 0 deletions difftest/spike_rs/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ pub struct SpikeRunner {
/// front of the queue, and it must be a fence
pub commit_queue: VecDeque<SpikeEvent>,

/// vector queue to arrange the order of vector instructions, because of the register write
/// dependency, the vector instruction should be issued in order.
pub vector_queue: VecDeque<SpikeEvent>,

/// scalar queue to arrange the order of scalar reg write instructions
pub scalar_queue: VecDeque<SpikeEvent>,

/// float queue to arrange the order of scalar freg write instructions
pub float_queue: VecDeque<SpikeEvent>,

/// config for v extension
pub vlen: u32,
pub dlen: u32,
Expand All @@ -32,6 +42,11 @@ pub struct SpikeRunner {
pub spike_cycle: u64,

pub do_log_vrf: bool,

// register file scoreboard
pub rf_board: Vec<Option<u32>>,
// float reg file scoreboard
pub frf_board: Vec<Option<u32>>,
}

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -105,11 +120,16 @@ impl SpikeRunner {
SpikeRunner {
spike,
commit_queue: VecDeque::new(),
vector_queue: VecDeque::new(),
scalar_queue: VecDeque::new(),
float_queue: VecDeque::new(),
vlen: args.vlen,
dlen: args.dlen,
cycle: 0,
spike_cycle: 0,
do_log_vrf,
rf_board: vec![None; 32],
frf_board: vec![None; 32],
}
}

Expand Down Expand Up @@ -161,6 +181,7 @@ impl SpikeRunner {
);
let new_pc_ = proc.func();
event.log_mem_write(spike).unwrap();
event.log_reg_write(spike).unwrap();
new_pc_
};

Expand All @@ -186,4 +207,61 @@ impl SpikeRunner {
}
}
}

pub fn find_reg_se(&mut self) -> SpikeEvent {
if !self.scalar_queue.is_empty() {
// return the back (oldest) scalar insn
self.scalar_queue.pop_back().unwrap()
} else {
// else, loop until find a se, and push the se to the front
loop {
let se = self.spike_step();
if se.is_scalar() && se.is_rd_written {
return se;
} else if se.is_scalar() && se.is_fd_written {
self.float_queue.push_front(se.clone());
} else if se.is_v() {
self.vector_queue.push_front(se.clone());
}
}
}
}

pub fn find_freg_se(&mut self) -> SpikeEvent {
if !self.float_queue.is_empty() {
// return the back (oldest) float insn
self.float_queue.pop_back().unwrap()
} else {
// else, loop until find a se, and push the se to the front
loop {
let se = self.spike_step();
if se.is_scalar() && se.is_rd_written {
self.scalar_queue.push_front(se.clone());
} else if se.is_scalar() && se.is_fd_written {
return se;
} else if se.is_v() {
self.vector_queue.push_front(se.clone());
}
}
}
}

pub fn find_v_se(&mut self) -> SpikeEvent {
if !self.vector_queue.is_empty() {
// return the back (oldest) vector insn
self.vector_queue.pop_back().unwrap()
} else {
// else, loop until find a se, and push the se to the front
loop {
let se = self.spike_step();
if se.is_scalar() && se.is_rd_written {
self.scalar_queue.push_front(se.clone());
} else if se.is_scalar() && se.is_fd_written {
self.float_queue.push_front(se.clone());
} else if se.is_v() {
return se;
}
}
}
}
}
68 changes: 35 additions & 33 deletions difftest/spike_rs/src/spike_event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::collections::HashMap;
use tracing::{info, trace};
use tracing::trace;
use Default;

use crate::clip;
Expand Down Expand Up @@ -92,6 +92,7 @@ pub struct SpikeEvent {

// mutable states
pub is_rd_written: bool,
pub is_fd_written: bool,
pub vd_write_record: VdWriteRecord,
pub mem_access_record: MemAccessRecord,
pub vrf_access_record: VrfAccessRecord,
Expand Down Expand Up @@ -143,6 +144,7 @@ impl SpikeEvent {
rd_bits: Default::default(),

is_rd_written: false,
is_fd_written: false,
vd_write_record: Default::default(),
mem_access_record: Default::default(),
vrf_access_record: Default::default(),
Expand Down Expand Up @@ -326,18 +328,15 @@ impl SpikeEvent {

pub fn pre_log_arch_changes(&mut self, spike: &Spike, vlen: u32) -> anyhow::Result<()> {
if self.do_log_vrf {
self.rd_bits = spike.get_proc().get_rd();

// record the vrf writes before executing the insn
let vlen_in_bytes = vlen;

let proc = spike.get_proc();
let (start, len) = self.get_vrf_write_range(vlen_in_bytes).unwrap();
self.rd_bits = proc.get_state().get_reg(self.rd_idx, false);
let (start, len) = self.get_vrf_write_range(vlen).unwrap();
self.vd_write_record.vd_bytes.resize(len as usize, 0u8);
for i in 0..len {
let offset = start + i;
let vreg_index = offset / vlen_in_bytes;
let vreg_offset = offset % vlen_in_bytes;
let vreg_index = offset / vlen;
let vreg_offset = offset % vlen;
let cur_byte = proc.get_vreg_data(vreg_index, vreg_offset);
self.vd_write_record.vd_bytes[i as usize] = cur_byte;
}
Expand Down Expand Up @@ -391,7 +390,7 @@ impl SpikeEvent {
Ok(())
}

fn log_reg_write(&mut self, spike: &Spike) -> anyhow::Result<()> {
pub fn log_reg_write(&mut self, spike: &Spike) -> anyhow::Result<()> {
let proc = spike.get_proc();
let state = proc.get_state();
// in spike, log_reg_write is arrange:
Expand All @@ -402,36 +401,39 @@ impl SpikeEvent {
// xx0100 <- csr
let reg_write_size = state.get_reg_write_size();
// TODO: refactor it.
(0..reg_write_size).for_each(|idx| match state.get_reg_write_index(idx) & 0xf {
0b0000 => {
// scalar rf
let data = state.get_reg(self.rd_idx, false);
self.is_rd_written = true;
if data != self.rd_bits {
trace!(
"ScalarRFChange: idx={}, change_from={}, change_to={data}",
self.rd_idx,
self.rd_bits
);
self.rd_bits = data;
(0..reg_write_size).for_each(|idx| {
let rd_idx_type = state.get_reg_write_index(idx);
match rd_idx_type & 0xf {
0b0000 => {
// scalar rf
self.rd_idx = rd_idx_type >> 4;
if self.rd_idx != 0 {
let data = state.get_reg(self.rd_idx, false);
self.is_rd_written = true;
self.rd_bits = data;
trace!(
"ScalarRFChange: idx={:#02x}, data={:08x}",
self.rd_idx,
self.rd_bits
);
}
}
}
0b0001 => {
let data = state.get_reg(self.rd_idx, true);
self.is_rd_written = true;
if data != self.rd_bits {
0b0001 => {
self.rd_idx = rd_idx_type >> 4;
let data = state.get_reg(self.rd_idx, true);
self.is_fd_written = true;
self.rd_bits = data;
trace!(
"FloatRFChange: idx={}, change_from={}, change_to={data}",
"FloatRFChange: idx={:#02x}, data={:08x}",
self.rd_idx,
self.rd_bits
);
self.rd_bits = data;
}
_ => trace!(
"UnknownRegChange, idx={:#02x}, spike detect unknown reg change",
self.rd_idx
),
}
_ => trace!(
"UnknownRegChange, idx={}, spike detect unknown reg change",
state.get_reg_write_index(idx)
),
});

Ok(())
Expand Down Expand Up @@ -459,7 +461,7 @@ impl SpikeEvent {
trace!("SpikeMemWrite: addr={addr:x}, value={value:x}, size={size}");

if addr == 0x4000_0000 && value == 0xdead_beef {
info!("SpikeExit: exit by writing 0xdeadbeef to 0x40000000");
trace!("SpikeExit: exit by writing 0xdeadbeef to 0x40000000");
self.is_exit = true;

return;
Expand Down
2 changes: 1 addition & 1 deletion script/emu/src/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ object Main:

val offlineChecker = os.Path(
resolveNixPath(s".#t1.${finalConfig}.ip.offline-checker")
) / "bin" / "offline_t1"
) / "bin" / (if finalConfig == "t1rocket" then "offline_t1rocket" else "offline_t1")

val elfFile =
if caseAttr.isDefined then resolveTestElfPath(finalConfig, caseAttr.get).toString
Expand Down

0 comments on commit 518d6ba

Please sign in to comment.