Skip to content

Commit

Permalink
[difftest] add t1 simulator
Browse files Browse the repository at this point in the history
[ipemu] implement chisel printf

Signed-off-by: Avimitin <[email protected]>

[nix] fix incorrect devShell

Signed-off-by: Avimitin <[email protected]>

[tests] remove mmio store on exit

Signed-off-by: Avimitin <[email protected]>

[nix] add rtl-event.log derivation

Signed-off-by: Avimitin <[email protected]>

[script] add new difftest main target

Signed-off-by: Avimitin <[email protected]>
  • Loading branch information
Clo91eaf committed Jun 10, 2024
1 parent c3e307f commit 067f71b
Show file tree
Hide file tree
Showing 20 changed files with 1,697 additions and 293 deletions.
18 changes: 14 additions & 4 deletions difftest/libspike_interfaces/spike_interfaces.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,6 @@ void state_set_pc(spike_state_t* state, uint64_t pc) {
state->s->pc = pc;
}

uint32_t state_get_reg_write_size(spike_state_t* state) {
return state->s->log_reg_write.size();
}

uint32_t state_get_reg(spike_state_t* state, uint32_t index, bool is_fp) {
if (is_fp) {
auto &fr = state->s->FPR;
Expand All @@ -185,6 +181,20 @@ uint32_t state_get_reg(spike_state_t* state, uint32_t index, bool is_fp) {
return (uint32_t)xr[index];
}

uint32_t state_get_reg_write_size(spike_state_t* state) {
return state->s->log_reg_write.size();
}

uint32_t state_get_reg_write_index(spike_state_t* state) {
int vec_idx = 0;
int i = 0;
for (auto [idx, data] : state->s->log_reg_write) {
vec_idx |= (idx & 0xf) << (i * 4);
i++;
}
return vec_idx;
}

uint32_t state_get_mem_write_size(spike_state_t* state) {
return state->s->log_mem_write.size();
}
Expand Down
1 change: 1 addition & 0 deletions difftest/libspike_interfaces/spike_interfaces_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ uint64_t state_handle_pc(spike_state_t* state, uint64_t new_pc);
void state_set_pc(spike_state_t* state, uint64_t pc);
uint32_t state_get_reg(spike_state_t* state, uint32_t index, bool is_fp);
uint32_t state_get_reg_write_size(spike_state_t* state);
uint32_t state_get_reg_write_index(spike_state_t* state);
uint32_t state_get_mem_write_size(spike_state_t* state);
uint32_t state_get_mem_write_addr(spike_state_t* state, uint32_t index);
uint64_t state_get_mem_write_value(spike_state_t* state, uint32_t index);
Expand Down
30 changes: 19 additions & 11 deletions difftest/t1-simulator/default.nix
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
{ lib
, libspike
, rustPlatform
, rust-analyzer
, libspike_interfaces
, rtl
}:

rustPlatform.buildRustPackage {
name = "t1-simulator";
src = with lib.fileset; toSource {
root = ./.;
fileset = fileFilter (file: file.name != "default.nix") ./.;
let
self = rustPlatform.buildRustPackage {
name = "t1-simulator";
src = with lib.fileset; toSource {
root = ./.;
fileset = fileFilter (file: file.name != "default.nix") ./.;
};
passthru.devShell = self.overrideAttrs (old: {
nativeBuildInputs = old.nativeBuildInputs ++ [
rust-analyzer
];
});
buildInputs = [ libspike libspike_interfaces ];
cargoLock = {
lockFile = ./Cargo.lock;
};
};
buildInputs = [ libspike libspike_interfaces ];
cargoLock = {
lockFile = ./Cargo.lock;
};
}
in
self
11 changes: 11 additions & 0 deletions difftest/t1-simulator/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Build

```bash
nix build ".#t1-simulator"
```

## Develop

```bash
nix develop '.#t1-simulator.devShell'
```
203 changes: 203 additions & 0 deletions difftest/t1-simulator/src/difftest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
mod dut;
mod spike;

use dut::*;
pub use spike::SpikeHandle;
use std::path::Path;
use tracing::{error, trace};

pub struct Difftest {
spike: SpikeHandle,
dut: Dut,
}

impl Difftest {
pub fn new(
size: usize,
elf_file: String,
log_file: String,
vlen: u32,
dlen: u32,
set: String,
) -> Self {
Self {
spike: SpikeHandle::new(size, Path::new(&elf_file), vlen, dlen, set),
dut: Dut::new(Path::new(&log_file)),
}
}

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

Ok(())
}

fn update_lsu_idx(&mut self, lsu_enq: LsuEnqEvent) -> anyhow::Result<()> {
self.spike.update_lsu_idx(lsu_enq).unwrap();

Ok(())
}

fn poke_inst(&mut self) -> anyhow::Result<()> {
loop {
let se = self.spike.find_se_to_issue();
if (se.is_vfence_insn || se.is_exit_insn) && self.spike.to_rtl_queue.len() == 1 {
if se.is_exit_insn {
error!("Simulation quit graceful");
return Err(anyhow::anyhow!("graceful exit"));
}

self.spike.to_rtl_queue.pop_back();
} else {
break;
}
}

// TODO: remove these, now just for aligning online difftest
if let Some(se) = self.spike.to_rtl_queue.front() {
// it is ensured there are some other instruction not committed, thus
// se_to_issue should not be issued
if se.is_vfence_insn || se.is_exit_insn {
assert!(
self.spike.to_rtl_queue.len() > 1,
"to_rtl_queue are smaller than expected"
);
if se.is_exit_insn {
trace!("DPIPokeInst: exit waiting for fence");
} else {
trace!("DPIPokeInst: waiting for fence, no issuing new instruction");
}
} else {
trace!(
"DPIPokeInst: poke instruction: pc={:#x}, inst={}",
se.pc,
se.disasm
);
}
}
Ok(())
}

pub fn diff(&mut self) -> anyhow::Result<()> {
self.poke_inst().unwrap();

let event = self.dut.step()?;

match &*event.event {
"peekTL" => {
let idx = event.parameter.idx.unwrap();
// assert!(idx < self.spike.config.dlen / 32);
let opcode = event.parameter.opcode.unwrap();
let param = event.parameter.param.unwrap();
let source = event.parameter.source.unwrap();
let mask = event.parameter.mask.unwrap();
let data = event.parameter.data.unwrap();
let corrupt = event.parameter.corrupt.unwrap();
let dready = event.parameter.dready.unwrap() != 0;
let cycle = event.parameter.cycle.unwrap();
// check align
let addr = event.parameter.address.unwrap();
let size = (1 << event.parameter.size.unwrap()) as usize;
assert_eq!(
addr as usize % size,
0,
"[{cycle}] unaligned access (addr={addr:08X}, size={size}"
);

let opcode = Opcode::from_u32(opcode);
self
.spike
.peek_tl(&PeekTLEvent {
idx,
opcode,
param,
size,
source,
addr,
mask,
data,
corrupt,
dready,
cycle,
})
.unwrap();
}
"issue" => {
let idx = event.parameter.idx.unwrap();
let cycle = event.parameter.cycle.unwrap();
self.peek_issue(IssueEvent { idx, cycle }).unwrap();
}
"lsuEnq" => {
let enq = event.parameter.enq.unwrap();
let cycle = event.parameter.cycle.unwrap();
self.update_lsu_idx(LsuEnqEvent { enq, cycle }).unwrap();
}
"vrfWriteFromLsu" => {
let idx = event.parameter.idx.unwrap();
let vd = event.parameter.vd.unwrap();
let offset = event.parameter.offset.unwrap();
let mask = event.parameter.mask.unwrap();
let data = event.parameter.data.unwrap();
let instruction = event.parameter.instruction.unwrap();
let lane = event.parameter.lane.unwrap();
let cycle = event.parameter.cycle.unwrap();
assert!(idx < self.spike.config.dlen / 32);

self
.spike
.peek_vrf_write_from_lsu(VrfWriteEvent {
idx: lane.trailing_zeros(),
vd,
offset,
mask,
data,
instruction,
cycle,
})
.unwrap();
}
"vrfWriteFromLane" => {
let idx = event.parameter.idx.unwrap();
let vd = event.parameter.vd.unwrap();
let offset = event.parameter.offset.unwrap();
let mask = event.parameter.mask.unwrap();
let data = event.parameter.data.unwrap();
let instruction = event.parameter.instruction.unwrap();
let cycle = event.parameter.cycle.unwrap();
assert!(idx < self.spike.config.dlen / 32);
self
.spike
.peek_vrf_write_from_lane(VrfWriteEvent {
idx,
vd,
offset,
mask,
data,
instruction,
cycle,
})
.unwrap();
}
"inst" => {
let data = event.parameter.data.unwrap() as u32;
let cycle = event.parameter.cycle.unwrap();
// let vxsat = event.parameter.vxsat.unwrap();
// let rd_valid = event.parameter.rd_valid.unwrap();
// let rd = event.parameter.rd.unwrap();
// let mem = event.parameter.mem.unwrap();

let se = self.spike.to_rtl_queue.back().unwrap();
se.record_rd_write(data).unwrap();
se.check_is_ready_for_commit(cycle).unwrap();

self.spike.to_rtl_queue.pop_back();
}
"skip" => {}
_ => {
panic!("unknown event: {}", event.event)
}
}

Ok(())
}
}
Loading

0 comments on commit 067f71b

Please sign in to comment.