From 1c65e3b62d4116ffe5a40ed7e47908a7ca429d95 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Fri, 27 Dec 2024 15:38:05 +0800 Subject: [PATCH 1/2] [difftest] refactor t1 offline difftest and some log message Signed-off-by: Clo91eaf --- difftest/offline_t1emu/src/difftest.rs | 4 +- difftest/offline_t1emu/src/json_events.rs | 58 +++++++++---------- .../offline_t1rocketemu/src/json_events.rs | 22 +++---- t1emu/src/TestBench.scala | 2 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/difftest/offline_t1emu/src/difftest.rs b/difftest/offline_t1emu/src/difftest.rs index 12c1a6473..2df586533 100644 --- a/difftest/offline_t1emu/src/difftest.rs +++ b/difftest/offline_t1emu/src/difftest.rs @@ -40,9 +40,9 @@ pub fn diff(runner: &mut SpikeRunner, event: &JsonEvents) -> anyhow::Result<()> runner.cycle = *cycle; runner.check_rd(&CheckRdEvent { data: *data, issue_idx: *issue_idx, cycle: *cycle }) } - JsonEvents::VrfScoreboardReport { count, issue_idx, cycle } => { + JsonEvents::VrfScoreboard { count, issue_idx, cycle } => { runner.cycle = *cycle; - runner.vrf_scoreboard_report(&VrfScoreboardReportEvent { + runner.vrf_scoreboard(&VrfScoreboardEvent { count: *count, issue_idx: *issue_idx, cycle: *cycle, diff --git a/difftest/offline_t1emu/src/json_events.rs b/difftest/offline_t1emu/src/json_events.rs index 9f8c3d4cd..5a1542013 100644 --- a/difftest/offline_t1emu/src/json_events.rs +++ b/difftest/offline_t1emu/src/json_events.rs @@ -4,7 +4,7 @@ use spike_rs::runner::SpikeRunner; use spike_rs::spike_event::LSU_IDX_DEFAULT; use tracing::{debug, info}; -fn bigint_to_vec_u8<'de, D>(deserializer: D) -> Result, D::Error> +fn str_to_vec_u8<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { @@ -14,7 +14,7 @@ where Ok(bigint.to_bytes_le()) } -fn bigint_to_vec_bool<'de, D>(deserializer: D) -> Result, D::Error> +fn str_to_vec_bool<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { @@ -27,7 +27,7 @@ where Ok(bools) } -fn hex_to_u32<'de, D>(deserializer: D) -> Result +fn str_to_u32<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { @@ -57,30 +57,30 @@ pub(crate) enum JsonEvents { issue_idx: u8, vd: u32, offset: u32, - #[serde(deserialize_with = "bigint_to_vec_bool", default)] + #[serde(deserialize_with = "str_to_vec_bool", default)] mask: Vec, - #[serde(deserialize_with = "bigint_to_vec_u8", default)] + #[serde(deserialize_with = "str_to_vec_u8", default)] data: Vec, lane: u32, cycle: u64, }, MemoryWrite { - #[serde(deserialize_with = "bigint_to_vec_bool", default)] + #[serde(deserialize_with = "str_to_vec_bool", default)] mask: Vec, - #[serde(deserialize_with = "bigint_to_vec_u8", default)] + #[serde(deserialize_with = "str_to_vec_u8", default)] data: Vec, lsu_idx: u8, - #[serde(deserialize_with = "hex_to_u32", default)] + #[serde(deserialize_with = "str_to_u32", default)] address: u32, cycle: u64, }, CheckRd { - #[serde(deserialize_with = "hex_to_u32", default)] + #[serde(deserialize_with = "str_to_u32", default)] data: u32, issue_idx: u8, cycle: u64, }, - VrfScoreboardReport { + VrfScoreboard { count: u32, issue_idx: u8, cycle: u64, @@ -115,7 +115,7 @@ pub struct MemoryWriteEvent { pub cycle: u64, } -pub struct VrfScoreboardReportEvent { +pub struct VrfScoreboardEvent { pub count: u32, pub issue_idx: u8, pub cycle: u64, @@ -134,7 +134,7 @@ pub(crate) trait JsonEventRunner { fn peek_vrf_write(&mut self, vrf_write: &VrfWriteEvent) -> anyhow::Result<()>; - fn vrf_scoreboard_report(&mut self, report: &VrfScoreboardReportEvent) -> anyhow::Result<()>; + fn vrf_scoreboard(&mut self, vrf_scoreboard: &VrfScoreboardEvent) -> anyhow::Result<()>; fn peek_memory_write(&mut self, memory_write: &MemoryWriteEvent) -> anyhow::Result<()>; @@ -212,7 +212,7 @@ impl JsonEventRunner for SpikeRunner { if let Some(unretired_writes) = se.vrf_access_record.unretired_writes { assert!( unretired_writes > 0, - "[{}] unretired_writes should be greater than 0, issue_idx={} ({})", + "[{}] VrfWrite: unretired_writes should be greater than 0, issue_idx={} ({})", vrf_write.cycle, vrf_write.issue_idx, se.describe_insn() @@ -232,8 +232,8 @@ impl JsonEventRunner for SpikeRunner { assert_eq!( record.byte, written_byte, - "[{}] {offset}th byte incorrect ({:02x} record != {written_byte:02x} written) \ - for vrf write (lane={}, vd={}, offset={}, mask={}, data={:x?}) \ + "[{}] VrfWrite: {offset}th byte incorrect ({:#02x} record != {written_byte:#02x} written) \ + (lane={}, vd={}, offset={}, mask={}, data={:x?}) \ issue_idx={} [vrf_idx={}] (disasm: {}, pc: {:#x}, bits: {:#x})", vrf_write.cycle, record.byte, @@ -251,7 +251,7 @@ impl JsonEventRunner for SpikeRunner { record.executed = true; } else { debug!( - "[{}] cannot find vrf write record, maybe not changed (lane={}, vd={}, idx={}, offset={}, mask={}, data={:x?})", + "[{}] VrfWrite: cannot find vrf write record, maybe not changed (lane={}, vd={}, idx={}, offset={}, mask={}, data={:x?})", vrf_write.cycle, vrf_write.lane, vrf_write.vd, @@ -264,7 +264,7 @@ impl JsonEventRunner for SpikeRunner { }) } else { info!( - "[{cycle}] RecordRFAccess: rtl detect vrf write on lane={}, vd={} \ + "[{cycle}] VrfWrite: rtl detect vrf write on lane={}, vd={} \ with no matched se (issue_idx={}), \ maybe from committed load insn", vrf_write.lane, vrf_write.vd, vrf_write.issue_idx @@ -286,7 +286,7 @@ impl JsonEventRunner for SpikeRunner { let lsu_idx = memory_write.lsu_idx; if let Some(se) = self.commit_queue.iter_mut().find(|se| se.lsu_idx == lsu_idx) { - info!("[{cycle}] MemoryWrite: address={base_addr:08x}, size={}, data={data:x?}, mask={}, pc = {:#x}, disasm = {}", data.len(), mask_display(&mask), se.pc, se.disasm); + info!("[{cycle}] MemoryWrite: address={base_addr:#x}, size={}, data={data:x?}, mask={}, pc = {:#x}, disasm = {}", data.len(), mask_display(&mask), se.pc, se.disasm); // compare with spike event record mask.iter().enumerate() .filter(|(_, &mask)| mask) @@ -295,29 +295,29 @@ impl JsonEventRunner for SpikeRunner { let data_byte = *data.get(offset).unwrap_or(&0); let mem_write = se.mem_access_record.all_writes.get_mut(&byte_addr).unwrap_or_else(|| { - panic!("[{cycle}] cannot find mem write of byte_addr {byte_addr:08x}") + panic!("[{cycle}] MemoryWrite: cannot find mem write of byte_addr {byte_addr:#x}") }); let single_mem_write_val = mem_write.writes[mem_write.num_completed_writes].val; mem_write.num_completed_writes += 1; - assert_eq!(single_mem_write_val, data_byte, "[{cycle}] expect mem write of byte {single_mem_write_val:02X}, actual byte {data_byte:02X} (byte_addr={byte_addr:08X}, pc = {:#x}, disasm = {})", se.pc, se.disasm); + assert_eq!(single_mem_write_val, data_byte, "[{cycle}] expect mem write of byte {single_mem_write_val:#02x}, actual byte {data_byte:#02x} (byte_addr={byte_addr:#x}, pc = {:#x}, disasm = {})", se.pc, se.disasm); }); return Ok(()); } - panic!("[{cycle}] cannot find se with instruction lsu_idx={lsu_idx}") + panic!("[{cycle}] MemoryWrite: cannot find se with instruction lsu_idx={lsu_idx}") } - fn vrf_scoreboard_report(&mut self, report: &VrfScoreboardReportEvent) -> anyhow::Result<()> { - let count = report.count; - let issue_idx = report.issue_idx; - let cycle = report.cycle; + fn vrf_scoreboard(&mut self, vrf_scoreboard: &VrfScoreboardEvent) -> anyhow::Result<()> { + let count = vrf_scoreboard.count; + let issue_idx = vrf_scoreboard.issue_idx; + let cycle = vrf_scoreboard.cycle; let mut should_retire: Option = None; if let Some(se) = self.commit_queue.iter_mut().rev().find(|se| se.issue_idx == issue_idx) { assert!( se.vrf_access_record.retired_writes <= count, - "[{cycle}] retired_writes({}) should be less than count({count}), issue_idx={issue_idx} ({})", + "[{cycle}] VrfScoreboard: retired_writes({}) should be less than count({count}), issue_idx={issue_idx} ({})", se.vrf_access_record.retired_writes, se.describe_insn() ); @@ -329,12 +329,12 @@ impl JsonEventRunner for SpikeRunner { se.vrf_access_record.unretired_writes = Some(count - se.vrf_access_record.retired_writes); info!( - "[{cycle}] VrfScoreboardReport: count={count}, issue_idx={issue_idx}, retired={} ({})", + "[{cycle}] VrfScoreboard: count={count}, issue_idx={issue_idx}, retired={} ({})", se.vrf_access_record.retired_writes, se.describe_insn() ); } else { - panic!("[{cycle}] cannot find se with instruction issue_idx={issue_idx}"); + panic!("[{cycle}] VrfScoreboard: cannot find se with instruction issue_idx={issue_idx}"); } if let Some(issue_idx) = should_retire { @@ -362,7 +362,7 @@ impl JsonEventRunner for SpikeRunner { let se = self.commit_queue.iter_mut().find(|se| se.issue_idx == issue_idx).unwrap_or_else(|| { - panic!("[{cycle}] cannot find se with instruction issue_idx={issue_idx}") + panic!("[{cycle}] CheckRd: cannot find se with instruction issue_idx={issue_idx}") }); info!("[{cycle}] CheckRd: issue_idx={issue_idx}, data={data:x?}"); diff --git a/difftest/offline_t1rocketemu/src/json_events.rs b/difftest/offline_t1rocketemu/src/json_events.rs index bf25390c6..9c003d671 100644 --- a/difftest/offline_t1rocketemu/src/json_events.rs +++ b/difftest/offline_t1rocketemu/src/json_events.rs @@ -383,7 +383,7 @@ impl JsonEventRunner for SpikeRunner { if let Some(unretired_writes) = se.vrf_access_record.unretired_writes { assert!( unretired_writes > 0, - "[{}] unretired_writes should be greater than 0, issue_idx={} ({})", + "[{}] VrfWrite: unretired_writes should be greater than 0, issue_idx={} ({})", vrf_write.cycle, vrf_write.issue_idx, se.describe_insn() @@ -403,8 +403,8 @@ impl JsonEventRunner for SpikeRunner { assert_eq!( record.byte, written_byte, - "[{}] {offset}th byte incorrect ({:#02x} record != {written_byte:#02x} written) \ - for vrf write (lane={}, vd={}, offset={}, mask={}, data={:x?}) \ + "[{}] VrfWrite: {offset}th byte incorrect ({:#02x} record != {written_byte:#02x} written) \ + (lane={}, vd={}, offset={}, mask={}, data={:x?}) \ issue_idx={} [vrf_idx={}] (disasm: {}, pc: {:#x}, bits: {:#x})", vrf_write.cycle, record.byte, @@ -422,7 +422,7 @@ impl JsonEventRunner for SpikeRunner { record.executed = true; } else { debug!( - "[{}] cannot find vrf write record, maybe not changed (lane={}, vd={}, idx={}, offset={}, mask={}, data={:x?})", + "[{}] VrfWrite: cannot find vrf write record, maybe not changed (lane={}, vd={}, idx={}, offset={}, mask={}, data={:x?})", vrf_write.cycle, vrf_write.lane, vrf_write.vd, @@ -435,7 +435,7 @@ impl JsonEventRunner for SpikeRunner { }) } else { info!( - "[{cycle}] RecordRFAccess: rtl detect vrf write on lane={}, vd={} \ + "[{cycle}] VrfWrite: rtl detect vrf write on lane={}, vd={} \ with no matched se (issue_idx={}), \ maybe from committed load insn", vrf_write.lane, vrf_write.vd, vrf_write.issue_idx @@ -466,7 +466,7 @@ impl JsonEventRunner for SpikeRunner { let data_byte = *data.get(offset).unwrap_or(&0); let mem_write = se.mem_access_record.all_writes.get_mut(&byte_addr).unwrap_or_else(|| { - panic!("[{cycle}] cannot find mem write of byte_addr {byte_addr:#x}") + panic!("[{cycle}] MemoryWrite: cannot find mem write of byte_addr {byte_addr:#x}") }); let single_mem_write_val = mem_write.writes[mem_write.num_completed_writes].val; mem_write.num_completed_writes += 1; @@ -475,7 +475,7 @@ impl JsonEventRunner for SpikeRunner { return Ok(()); } - panic!("[{cycle}] cannot find se with instruction lsu_idx={lsu_idx}") + panic!("[{cycle}] MemoryWrite: cannot find se with instruction lsu_idx={lsu_idx}") } fn vrf_scoreboard(&mut self, vrf_scoreboard: &VrfScoreboardEvent) -> anyhow::Result<()> { @@ -488,7 +488,7 @@ impl JsonEventRunner for SpikeRunner { if let Some(se) = self.commit_queue.iter_mut().rev().find(|se| se.issue_idx == issue_idx) { assert!( se.vrf_access_record.retired_writes <= count, - "[{cycle}] retired_writes({}) should be less than count({count}), issue_idx={issue_idx} ({})", + "[{cycle}] VrfScoreboard: retired_writes({}) should be less than count({count}), issue_idx={issue_idx} ({})", se.vrf_access_record.retired_writes, se.describe_insn() ); @@ -500,12 +500,12 @@ impl JsonEventRunner for SpikeRunner { se.vrf_access_record.unretired_writes = Some(count - se.vrf_access_record.retired_writes); info!( - "[{cycle}] VrfScoreboardReport: count={count}, issue_idx={issue_idx}, retired={} ({})", + "[{cycle}] VrfScoreboard: count={count}, issue_idx={issue_idx}, retired={} ({})", se.vrf_access_record.retired_writes, se.describe_insn() ); } else { - panic!("[{cycle}] cannot find se with instruction issue_idx={issue_idx}"); + panic!("[{cycle}] VrfScoreboard: cannot find se with instruction issue_idx={issue_idx}"); } if let Some(issue_idx) = should_retire { @@ -533,7 +533,7 @@ impl JsonEventRunner for SpikeRunner { let se = self.commit_queue.iter_mut().find(|se| se.issue_idx == issue_idx).unwrap_or_else(|| { - panic!("[{cycle}] cannot find se with instruction issue_idx={issue_idx}") + panic!("[{cycle}] CheckRd: cannot find se with instruction issue_idx={issue_idx}") }); info!("[{cycle}] CheckRd: issue_idx={issue_idx}, data={data:x?}"); diff --git a/t1emu/src/TestBench.scala b/t1emu/src/TestBench.scala index ae1e6f648..79619d758 100644 --- a/t1emu/src/TestBench.scala +++ b/t1emu/src/TestBench.scala @@ -234,7 +234,7 @@ class TestBench(val parameter: T1Parameter) scoreboard.bits := scoreboard.bits + PopCount(writeEnq) when(scoreboard.valid && !instructionValid(tag)) { printf( - cf"""{"event":"VrfScoreboardReport","count":${scoreboard.bits},"issue_idx":${tag},"cycle":${simulationTime}}\n""" + cf"""{"event":"VrfScoreboard","count":${scoreboard.bits},"issue_idx":${tag},"cycle":${simulationTime}}\n""" ) scoreboard.valid := false.B } From 36f6476eff0d0b93ea6100434dbb62e7e426ef30 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Fri, 27 Dec 2024 15:43:06 +0800 Subject: [PATCH 2/2] [difftest] fixed the issue in the VrfScoreboard where count=0 caused a conflict with writing rd Signed-off-by: Clo91eaf --- difftest/offline_t1emu/src/json_events.rs | 4 ++-- difftest/offline_t1rocketemu/src/json_events.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/difftest/offline_t1emu/src/json_events.rs b/difftest/offline_t1emu/src/json_events.rs index 5a1542013..3c5cb2c1d 100644 --- a/difftest/offline_t1emu/src/json_events.rs +++ b/difftest/offline_t1emu/src/json_events.rs @@ -333,8 +333,8 @@ impl JsonEventRunner for SpikeRunner { se.vrf_access_record.retired_writes, se.describe_insn() ); - } else { - panic!("[{cycle}] VrfScoreboard: cannot find se with instruction issue_idx={issue_idx}"); + } else if count != 0 { + panic!("[{cycle}] VrfScoreboard: cannot find se with instruction issue_idx={issue_idx}, count={count}"); } if let Some(issue_idx) = should_retire { diff --git a/difftest/offline_t1rocketemu/src/json_events.rs b/difftest/offline_t1rocketemu/src/json_events.rs index 9c003d671..b38ba618a 100644 --- a/difftest/offline_t1rocketemu/src/json_events.rs +++ b/difftest/offline_t1rocketemu/src/json_events.rs @@ -504,8 +504,8 @@ impl JsonEventRunner for SpikeRunner { se.vrf_access_record.retired_writes, se.describe_insn() ); - } else { - panic!("[{cycle}] VrfScoreboard: cannot find se with instruction issue_idx={issue_idx}"); + } else if count != 0 { + panic!("[{cycle}] VrfScoreboard: cannot find se with instruction issue_idx={issue_idx}, count={count}"); } if let Some(issue_idx) = should_retire {