tests/rename_execute_retire: make loads/stores take more than one cycle to execute

This commit is contained in:
Jacob Lifshay 2026-05-19 18:08:07 -07:00
parent 79ac190093
commit 2363e65564
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
4 changed files with 149283 additions and 135206 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -3219,6 +3219,7 @@ struct MockLoadStoreOpDebugState<C: PhantomConstGet<CpuConfig>> {
is_speculative: Bool, is_speculative: Bool,
src_values: HdlOption<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>, src_values: HdlOption<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
dest_value: HdlOption<TraceAsString<PRegValue>>, dest_value: HdlOption<TraceAsString<PRegValue>>,
cycles_left: UInt<8>,
ran_nonspeculatively: Bool, ran_nonspeculatively: Bool,
sent_cant_cause_cancel: Bool, sent_cant_cause_cancel: Bool,
sent_output_ready: Bool, sent_output_ready: Bool,
@ -3231,6 +3232,7 @@ struct MockLoadStoreOp<C: PhantomConstCpuConfig> {
is_speculative: bool, is_speculative: bool,
src_values: Option<[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN]>, src_values: Option<[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN]>,
dest_value: Option<SimValue<TraceAsString<PRegValue>>>, dest_value: Option<SimValue<TraceAsString<PRegValue>>>,
cycles_left: u8,
ran_nonspeculatively: bool, ran_nonspeculatively: bool,
sent_cant_cause_cancel: bool, sent_cant_cause_cancel: bool,
sent_output_ready: bool, sent_output_ready: bool,
@ -3245,6 +3247,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreOp<C> {
is_speculative, is_speculative,
src_values, src_values,
dest_value, dest_value,
cycles_left,
ran_nonspeculatively, ran_nonspeculatively,
sent_cant_cause_cancel, sent_cant_cause_cancel,
sent_output_ready, sent_output_ready,
@ -3256,6 +3259,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreOp<C> {
is_speculative, is_speculative,
src_values, src_values,
dest_value, dest_value,
cycles_left,
ran_nonspeculatively, ran_nonspeculatively,
sent_cant_cause_cancel, sent_cant_cause_cancel,
sent_output_ready, sent_output_ready,
@ -3275,7 +3279,8 @@ struct MockLoadStoreUnitDebugState<C: PhantomConstGet<CpuConfig>> {
config: C, config: C,
} }
struct MockLoadStoreUnitState<C: PhantomConstCpuConfig> { struct MockLoadStoreUnitState<'a, C: PhantomConstCpuConfig> {
random_state: &'a RandomState,
ops: VecDeque<MockLoadStoreOp<C>>, ops: VecDeque<MockLoadStoreOp<C>>,
memory: MockMemory, memory: MockMemory,
speculative_memory: MockMemory, speculative_memory: MockMemory,
@ -3283,9 +3288,15 @@ struct MockLoadStoreUnitState<C: PhantomConstCpuConfig> {
unit_index: usize, unit_index: usize,
} }
impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> { impl<'a, C: PhantomConstCpuConfig> MockLoadStoreUnitState<'a, C> {
fn new(config: C, unit_index: usize, memory: MockMemory) -> Self { fn new(
config: C,
unit_index: usize,
memory: MockMemory,
random_state: &'a RandomState,
) -> Self {
Self { Self {
random_state,
ops: VecDeque::new(), ops: VecDeque::new(),
memory: memory.clone(), memory: memory.clone(),
speculative_memory: memory, speculative_memory: memory,
@ -3296,6 +3307,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
#[hdl] #[hdl]
fn debug_state(&self) -> SimValue<MockLoadStoreUnitDebugState<C>> { fn debug_state(&self) -> SimValue<MockLoadStoreUnitDebugState<C>> {
let Self { let Self {
random_state: _,
ops, ops,
memory, memory,
speculative_memory, speculative_memory,
@ -3346,6 +3358,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
is_speculative, is_speculative,
src_values, src_values,
dest_value, dest_value,
cycles_left: _,
ran_nonspeculatively: _, ran_nonspeculatively: _,
sent_cant_cause_cancel: _, sent_cant_cause_cancel: _,
sent_output_ready: _, sent_output_ready: _,
@ -3394,12 +3407,29 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
} }
} }
} }
for op in &mut self.ops {
let MockLoadStoreOp {
mop: _,
is_speculative: _,
src_values: _,
dest_value,
cycles_left,
ran_nonspeculatively: _,
sent_cant_cause_cancel: _,
sent_output_ready: _,
config: _,
} = op;
if dest_value.is_some() {
*cycles_left = cycles_left.saturating_sub(1);
}
}
for op in &mut self.ops { for op in &mut self.ops {
let MockLoadStoreOp { let MockLoadStoreOp {
mop, mop,
is_speculative, is_speculative,
src_values, src_values,
dest_value, dest_value,
cycles_left: _,
ran_nonspeculatively, ran_nonspeculatively,
sent_cant_cause_cancel: _, sent_cant_cause_cancel: _,
sent_output_ready: _, sent_output_ready: _,
@ -3453,11 +3483,16 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
is_last_mop_in_insn, is_last_mop_in_insn,
mop: mop.into_trace_as_string(), mop: mop.into_trace_as_string(),
}; };
const CYCLE_COUNTS: &[u8; 16] = &[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 10];
let cycles_left = CYCLE_COUNTS[self.random_state.random_u64(u32::from_le_bytes(*b"lshe"))
as usize
% CYCLE_COUNTS.len()];
self.ops.push_back(MockLoadStoreOp { self.ops.push_back(MockLoadStoreOp {
mop, mop,
is_speculative: true, is_speculative: true,
src_values: None, src_values: None,
dest_value: None, dest_value: None,
cycles_left,
ran_nonspeculatively: false, ran_nonspeculatively: false,
sent_cant_cause_cancel: false, sent_cant_cause_cancel: false,
sent_output_ready: false, sent_output_ready: false,
@ -3477,6 +3512,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
is_speculative: _, is_speculative: _,
src_values: op_src_values, src_values: op_src_values,
dest_value: _, dest_value: _,
cycles_left: _,
ran_nonspeculatively: _, ran_nonspeculatively: _,
sent_cant_cause_cancel: _, sent_cant_cause_cancel: _,
sent_output_ready: _, sent_output_ready: _,
@ -3497,6 +3533,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
is_speculative, is_speculative,
src_values: _, src_values: _,
dest_value: _, dest_value: _,
cycles_left: _,
ran_nonspeculatively: _, ran_nonspeculatively: _,
sent_cant_cause_cancel: _, sent_cant_cause_cancel: _,
sent_output_ready: _, sent_output_ready: _,
@ -3513,6 +3550,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
is_speculative: _, is_speculative: _,
src_values: _, src_values: _,
dest_value, dest_value,
cycles_left,
ran_nonspeculatively: _, ran_nonspeculatively: _,
sent_cant_cause_cancel, sent_cant_cause_cancel,
sent_output_ready: _, sent_output_ready: _,
@ -3522,7 +3560,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
if *sent_cant_cause_cancel { if *sent_cant_cause_cancel {
continue; continue;
} }
if dest_value.is_some() { if dest_value.is_some() && *cycles_left == 0 {
return #[hdl(sim)] return #[hdl(sim)]
ret_ty.HdlSome( ret_ty.HdlSome(
#[hdl(sim)] #[hdl(sim)]
@ -3555,6 +3593,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
is_speculative: _, is_speculative: _,
src_values: _, src_values: _,
dest_value, dest_value,
cycles_left,
ran_nonspeculatively: _, ran_nonspeculatively: _,
sent_cant_cause_cancel: _, sent_cant_cause_cancel: _,
sent_output_ready, sent_output_ready,
@ -3564,7 +3603,9 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
if *sent_output_ready { if *sent_output_ready {
continue; continue;
} }
if let Some(dest_value) = dest_value { if let Some(dest_value) = dest_value
&& *cycles_left == 0
{
return #[hdl(sim)] return #[hdl(sim)]
ret_ty.HdlSome( ret_ty.HdlSome(
#[hdl(sim)] #[hdl(sim)]
@ -3606,13 +3647,14 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
is_speculative: _, is_speculative: _,
src_values: _, src_values: _,
dest_value: _, dest_value: _,
cycles_left,
ran_nonspeculatively, ran_nonspeculatively,
sent_cant_cause_cancel: _, sent_cant_cause_cancel: _,
sent_output_ready: _, sent_output_ready: _,
config: _, config: _,
}) = self.ops.front() }) = self.ops.front()
{ {
if *ran_nonspeculatively { if *ran_nonspeculatively && *cycles_left == 0 {
return #[hdl(sim)] return #[hdl(sim)]
ret_ty.HdlSome( ret_ty.HdlSome(
#[hdl(sim)] #[hdl(sim)]
@ -3646,6 +3688,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
} }
fn cancel_all(&mut self) { fn cancel_all(&mut self) {
let Self { let Self {
random_state: _,
ops, ops,
memory, memory,
speculative_memory, speculative_memory,
@ -3699,6 +3742,10 @@ fn mock_load_store_unit<#[hdl(skip)] MI: MakeInsns>(
), ),
async |args, mut sim| { async |args, mut sim| {
let (cd, from_execute, debug_state, all_outputs_written, config, unit_index) = args; let (cd, from_execute, debug_state, all_outputs_written, config, unit_index) = args;
// intentionally have a different sequence each time we're reset
let random_state = RandomState {
state: Cell::new(0),
};
sim.resettable( sim.resettable(
cd, cd,
async |mut sim| { async |mut sim| {
@ -3758,6 +3805,7 @@ fn mock_load_store_unit<#[hdl(skip)] MI: MakeInsns>(
state, state,
config, config,
unit_index, unit_index,
&random_state,
sim, sim,
) )
}, },
@ -3774,9 +3822,10 @@ fn mock_load_store_unit<#[hdl(skip)] MI: MakeInsns>(
memory: MockMemory, memory: MockMemory,
config: PhantomConst<CpuConfig>, config: PhantomConst<CpuConfig>,
unit_index: usize, unit_index: usize,
random_state: &RandomState,
mut sim: ExternModuleSimulationState, mut sim: ExternModuleSimulationState,
) { ) {
let mut state = MockLoadStoreUnitState::new(config, unit_index, memory); let mut state = MockLoadStoreUnitState::new(config, unit_index, memory, random_state);
loop { loop {
{ {
#[hdl] #[hdl]
@ -4142,7 +4191,7 @@ fn test_rename_execute_retire_slow_loop() {
}; };
sim.write_clock(sim.io().cd.clk, false); sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true); sim.write_reset(sim.io().cd.rst, true);
for cycle in 0..500 { for cycle in 0..600 {
sim.advance_time(SimDuration::from_nanos(500)); sim.advance_time(SimDuration::from_nanos(500));
println!("clock tick: {cycle}"); println!("clock tick: {cycle}");
sim.write_clock(sim.io().cd.clk, true); sim.write_clock(sim.io().cd.clk, true);
@ -4280,7 +4329,7 @@ fn test_rename_execute_retire_head_n1() {
}; };
sim.write_clock(sim.io().cd.clk, false); sim.write_clock(sim.io().cd.clk, false);
sim.write_reset(sim.io().cd.rst, true); sim.write_reset(sim.io().cd.rst, true);
for cycle in 0..200 { for cycle in 0..300 {
sim.advance_time(SimDuration::from_nanos(500)); sim.advance_time(SimDuration::from_nanos(500));
println!("clock tick: {cycle}"); println!("clock tick: {cycle}");
sim.write_clock(sim.io().cd.clk, true); sim.write_clock(sim.io().cd.clk, true);