Skip to content

Commit

Permalink
[t1rocket] wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Clo91eaf committed Aug 23, 2024
1 parent b526047 commit 0cc0fae
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 29 deletions.
2 changes: 1 addition & 1 deletion rocketemu/src/TestBench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class TestBench(generator: SerializableModuleGenerator[RocketTile, RocketTilePar

// output probes
val rocketProbe = probe.read(dut.io.rocketProbe)
when(rocketProbe.rob.trace.rfWen && rocketProbe.rob.trace.rfWaddr =/= 0.U)(printf(cf"""{"event":"RegWrite","addr":${rocketProbe.rob.trace.rfWaddr},"data":${rocketProbe.rob.trace.rfWdata},"cycle":${simulationTime}}\n"""))
when(rocketProbe.rfWen && rocketProbe.rfWaddr =/= 0.U)(printf(cf"""{"event":"RegWrite","addr":${rocketProbe.rfWaddr},"data":${rocketProbe.rfWdata},"cycle":${simulationTime}}\n"""))

// Memory Drivers
val instFetchAXI = dut.io.instructionFetchAXI.viewAs[AXI4ROIrrevocableVerilog]
Expand Down
4 changes: 2 additions & 2 deletions rocketv/src/RocketCore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1096,8 +1096,8 @@ class Rocket(val parameter: RocketParameter)
probeWire.rfWdata := rfWdata

// TODO: add wait enable
// probeWire.waitEn :=
// probeWire.waitAddr :=
probeWire.waitWen := wbSetSboard && wbWen
probeWire.waitWaddr := wbWaddr

// FIXME: vectorCSR
probeWire.isVector := io.t1.map { t1 =>
Expand Down
2 changes: 1 addition & 1 deletion t1rocketemu/.rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
hard_tabs = false
tab_spaces = 2
chain_width = 100
struct_lit_width = 50
struct_lit_width = 50
9 changes: 8 additions & 1 deletion t1rocketemu/offline/src/difftest.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use common::spike_runner::SpikeRunner;
use std::path::Path;
use tracing::info;

use common::rtl_config::RTLConfig;
use common::CommonArgs;
Expand Down Expand Up @@ -48,6 +47,14 @@ impl Difftest {
self.runner.cycle = *cycle;
self.runner.peek_reg_write(&RegWriteEvent { idx: *idx, data: *data, cycle: *cycle })
}
JsonEvents::RegWriteWait { idx, cycle } => {
self.runner.cycle = *cycle;
self.runner.peek_reg_write_wait(&RegWriteWaitEvent { idx: *idx, cycle: *cycle })
}
JsonEvents::FregWrite { idx, data, cycle } => {
self.runner.cycle = *cycle;
self.runner.peek_freg_write(&RegWriteEvent { idx: *idx, data: *data, cycle: *cycle })
}
JsonEvents::Issue { idx, cycle } => {
self.runner.cycle = *cycle;
self.runner.peek_issue(&IssueEvent { idx: *idx, cycle: *cycle })
Expand Down
87 changes: 86 additions & 1 deletion t1rocketemu/offline/src/json_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ pub(crate) enum JsonEvents {
data: u32,
cycle: u64,
},
RegWriteWait {
idx: u8,
cycle: u64,
},
FregWrite {
idx: u8,
#[serde(deserialize_with = "str_to_u32", default)]
data: u32,
cycle: u64,
},

Issue {
idx: u8,
cycle: u64,
Expand Down Expand Up @@ -109,6 +120,11 @@ pub struct RegWriteEvent {
pub cycle: u64,
}

pub struct RegWriteWaitEvent {
pub idx: u8,
pub cycle: u64,
}

pub struct IssueEvent {
pub idx: u8,
pub cycle: u64,
Expand Down Expand Up @@ -152,6 +168,10 @@ pub struct CheckRdEvent {
pub(crate) trait JsonEventRunner {
fn peek_reg_write(&mut self, reg_write: &RegWriteEvent) -> anyhow::Result<()>;

fn peek_reg_write_wait(&mut self, reg_write: &RegWriteWaitEvent) -> anyhow::Result<()>;

fn peek_freg_write(&mut self, reg_write: &RegWriteEvent) -> anyhow::Result<()>;

fn peek_issue(&mut self, issue: &IssueEvent) -> anyhow::Result<()>;

fn update_lsu_idx(&mut self, lsu_enq: &LsuEnqEvent) -> anyhow::Result<()>;
Expand All @@ -175,7 +195,20 @@ impl JsonEventRunner for SpikeRunner {
let idx = reg_write.idx;
let data = reg_write.data;

let se = self.find_rf_se();
if let Some(board_data) = self.rf_board[idx as usize] {
info!(
"[{cycle}] RegWrite: Hit board! idx={idx}, rtl data={data:#08x}, board data={board_data:#08x}",
);

assert!(
data == board_data,
"rtl data({data:#x}) should be equal to board data({board_data:#x})"
);

return Ok(());
}

let se = self.find_reg_se();

info!(
"[{cycle}] RegWrite: rtl idx={idx}, data={data:#08x}; se idx={}, data={:#08x} ({})",
Expand All @@ -198,6 +231,58 @@ impl JsonEventRunner for SpikeRunner {
Ok(())
}

fn peek_reg_write_wait(&mut self, reg_write: &RegWriteWaitEvent) -> anyhow::Result<()> {
let cycle = reg_write.cycle;
let idx = reg_write.idx;

let se = self.find_reg_se();

info!(
"[{cycle}] RegWriteWait: rtl idx={idx}; se idx={}, data={:#08x} ({})",
se.rd_idx,
se.rd_bits,
se.describe_insn()
);

assert!(
idx as u32 == se.rd_idx,
"rtl idx({idx:#x}) should be equal to spike idx({:#x})",
se.rd_idx
);

self.rf_board[idx as usize] = Some(se.rd_bits);

Ok(())
}

fn peek_freg_write(&mut self, reg_write: &RegWriteEvent) -> anyhow::Result<()> {
let cycle = reg_write.cycle;
let idx = reg_write.idx;
let data = reg_write.data;

let se = self.find_freg_se();

info!(
"[{cycle}] FregWrite: rtl idx={idx}, data={data:#08x}; se idx={}, data={:#08x} ({})",
se.rd_idx,
se.rd_bits,
se.describe_insn()
);

assert!(
idx as u32 == se.rd_idx,
"rtl idx({idx:#x}) should be equal to spike idx({:#x})",
se.rd_idx
);
assert!(
data == se.rd_bits,
"rtl data({data:#x}) should be equal to spike data({:#x})",
se.rd_bits
);

Ok(())
}

fn peek_issue(&mut self, issue: &IssueEvent) -> anyhow::Result<()> {
let mut se = self.find_v_se(); // ensure the front of queue is a new un-issued se

Expand Down
4 changes: 3 additions & 1 deletion t1rocketemu/spike_rs/src/spike_event.rs
Original file line number Diff line number Diff line change
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 @@ -142,6 +143,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 @@ -418,7 +420,7 @@ impl SpikeEvent {
0b0001 => {
self.rd_idx = rd_idx_type >> 4;
let data = state.get_reg(self.rd_idx, true);
self.is_rd_written = true;
self.is_fd_written = true;
self.rd_bits = data;
trace!(
"FloatRFChange: idx={:#02x}, data={:08x}",
Expand Down
30 changes: 13 additions & 17 deletions t1rocketemu/src/TestBench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import chisel3.experimental.dataview.DataViewable
import chisel3.util.circt.dpi.{RawClockedNonVoidFunctionCall, RawUnclockedNonVoidFunctionCall}
import chisel3.util.{HasExtModuleInline, Mux1H, PopCount, Queue, UIntToOH, Valid}
import org.chipsalliance.amba.axi4.bundle._
import org.chipsalliance.rocketv.RocketROB
import org.chipsalliance.t1.t1rocketemu.dpi._
import org.chipsalliance.t1.tile.{T1RocketTile, T1RocketTileParameter}

Expand Down Expand Up @@ -177,33 +176,30 @@ class TestBench(generator: SerializableModuleGenerator[T1RocketTile, T1RocketTil

// output the probes
// rocket reg write
when(rocketProbe.rfWen && !rocketProbe.isVector)(
when(rocketProbe.rfWen && !rocketProbe.isVector && rocketProbe.rfWaddr =/= 0.U)(
printf(
cf"""{"event":"RegWrite","idx":${rocketProbe.rfWaddr},"data":"${rocketProbe.rfWdata}%x","cycle":${simulationTime}}\n"""
)
)

// TODO: refactor this wait logic
// when(rocketProbe.waitWen && !rocketProbe.isVector)( // should this judge vector?
// printf(
// cf"""{"event":"RegWriteWait","idx":${rocketProbe.waitWaddr},"cycle":${simulationTime}}\n"""
// )
// )
when(rocketProbe.waitWen && !rocketProbe.isVector && rocketProbe.waitWaddr =/= 0.U)( // should this judge vector?
printf(
cf"""{"event":"RegWriteWait","idx":${rocketProbe.waitWaddr},"cycle":${simulationTime}}\n"""
)
)

// [[option]] rocket fpu reg write
t1RocketProbe.fpuProbe.foreach { fpu =>
when(fpu.rfWen)(
when(fpu.pipeWrite.rfWen)(
printf(
cf"""{"event":"FregWrite","idx":${fpu.rfWaddr},"data":"${fpu.rfWdata}%x","cycle":${simulationTime}}\n"""
cf"""{"event":"FregWrite","idx":${fpu.pipeWrite.rfWaddr},"data":"${fpu.pipeWrite.rfWdata}%x","cycle":${simulationTime}}\n"""
)
)
when(fpu.loadOrVectorWrite.rfWen && !rocketProbe.isVector)(
printf(
cf"""{"event":"FregWrite","idx":${fpu.loadOrVectorWrite.rfWaddr},"data":"${fpu.loadOrVectorWrite.rfWdata}%x","cycle":${simulationTime}}\n"""
)
)

// TODO: refactor this wait logic
// when(fpu.waitWen && !fpu.isVector)( // should this judge vector?
// printf(
// cf"""{"event":"FregWriteWait","idx":${fpu.waitWaddr},"cycle":${simulationTime}}\n"""
// )
// )
}

// t1 vrf write
Expand Down
39 changes: 34 additions & 5 deletions t1rocketemu/test_common/src/spike_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ pub struct SpikeRunner {
/// dependency, the vector instruction should be issued in order.
pub vector_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.
/// scalar queue to arrange the order of scalar reg / freg write instructions
pub scalar_queue: VecDeque<SpikeEvent>,

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

/// config for v extension
pub vlen: u32,
pub dlen: u32,
Expand All @@ -37,6 +39,8 @@ pub struct SpikeRunner {
pub cycle: u64,

pub do_log_vrf: bool,

pub rf_board: Vec<Option<u32>>,
}

impl SpikeRunner {
Expand All @@ -58,10 +62,12 @@ impl SpikeRunner {
commit_queue: VecDeque::new(),
vector_queue: VecDeque::new(),
scalar_queue: VecDeque::new(),
float_queue: VecDeque::new(),
vlen: args.vlen,
dlen: args.dlen,
cycle: 0,
do_log_vrf,
rf_board: vec![None; 32],
}
}

Expand Down Expand Up @@ -122,15 +128,36 @@ impl SpikeRunner {
event
}

pub fn find_rf_se(&mut self) -> SpikeEvent {
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 && se.rd_idx != 0 {
if se.is_scalar() && se.is_rd_written {
return se;
} else if 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_fd_written {
return se;
} else if se.is_v() {
self.vector_queue.push_front(se.clone());
Expand All @@ -147,8 +174,10 @@ impl SpikeRunner {
// 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 && se.rd_idx != 0 {
if se.is_scalar() && se.is_rd_written {
self.scalar_queue.push_front(se.clone());
} else if se.is_fd_written {
self.float_queue.push_front(se.clone());
} else if se.is_v() {
return se;
}
Expand Down

0 comments on commit 0cc0fae

Please sign in to comment.