add a procedural implementation of rename_execute_retire #12
4 changed files with 149283 additions and 135206 deletions
75105
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
75105
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
File diff suppressed because it is too large
Load diff
129874
crates/cpu/tests/expected/rename_execute_retire_head_n1.vcd
generated
129874
crates/cpu/tests/expected/rename_execute_retire_head_n1.vcd
generated
File diff suppressed because it is too large
Load diff
79443
crates/cpu/tests/expected/rename_execute_retire_slow_loop.vcd
generated
79443
crates/cpu/tests/expected/rename_execute_retire_slow_loop.vcd
generated
File diff suppressed because it is too large
Load diff
|
|
@ -3219,6 +3219,7 @@ struct MockLoadStoreOpDebugState<C: PhantomConstGet<CpuConfig>> {
|
|||
is_speculative: Bool,
|
||||
src_values: HdlOption<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
|
||||
dest_value: HdlOption<TraceAsString<PRegValue>>,
|
||||
cycles_left: UInt<8>,
|
||||
ran_nonspeculatively: Bool,
|
||||
sent_cant_cause_cancel: Bool,
|
||||
sent_output_ready: Bool,
|
||||
|
|
@ -3231,6 +3232,7 @@ struct MockLoadStoreOp<C: PhantomConstCpuConfig> {
|
|||
is_speculative: bool,
|
||||
src_values: Option<[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN]>,
|
||||
dest_value: Option<SimValue<TraceAsString<PRegValue>>>,
|
||||
cycles_left: u8,
|
||||
ran_nonspeculatively: bool,
|
||||
sent_cant_cause_cancel: bool,
|
||||
sent_output_ready: bool,
|
||||
|
|
@ -3245,6 +3247,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreOp<C> {
|
|||
is_speculative,
|
||||
src_values,
|
||||
dest_value,
|
||||
cycles_left,
|
||||
ran_nonspeculatively,
|
||||
sent_cant_cause_cancel,
|
||||
sent_output_ready,
|
||||
|
|
@ -3256,6 +3259,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreOp<C> {
|
|||
is_speculative,
|
||||
src_values,
|
||||
dest_value,
|
||||
cycles_left,
|
||||
ran_nonspeculatively,
|
||||
sent_cant_cause_cancel,
|
||||
sent_output_ready,
|
||||
|
|
@ -3275,7 +3279,8 @@ struct MockLoadStoreUnitDebugState<C: PhantomConstGet<CpuConfig>> {
|
|||
config: C,
|
||||
}
|
||||
|
||||
struct MockLoadStoreUnitState<C: PhantomConstCpuConfig> {
|
||||
struct MockLoadStoreUnitState<'a, C: PhantomConstCpuConfig> {
|
||||
random_state: &'a RandomState,
|
||||
ops: VecDeque<MockLoadStoreOp<C>>,
|
||||
memory: MockMemory,
|
||||
speculative_memory: MockMemory,
|
||||
|
|
@ -3283,9 +3288,15 @@ struct MockLoadStoreUnitState<C: PhantomConstCpuConfig> {
|
|||
unit_index: usize,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
||||
fn new(config: C, unit_index: usize, memory: MockMemory) -> Self {
|
||||
impl<'a, C: PhantomConstCpuConfig> MockLoadStoreUnitState<'a, C> {
|
||||
fn new(
|
||||
config: C,
|
||||
unit_index: usize,
|
||||
memory: MockMemory,
|
||||
random_state: &'a RandomState,
|
||||
) -> Self {
|
||||
Self {
|
||||
random_state,
|
||||
ops: VecDeque::new(),
|
||||
memory: memory.clone(),
|
||||
speculative_memory: memory,
|
||||
|
|
@ -3296,6 +3307,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
#[hdl]
|
||||
fn debug_state(&self) -> SimValue<MockLoadStoreUnitDebugState<C>> {
|
||||
let Self {
|
||||
random_state: _,
|
||||
ops,
|
||||
memory,
|
||||
speculative_memory,
|
||||
|
|
@ -3346,6 +3358,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
is_speculative,
|
||||
src_values,
|
||||
dest_value,
|
||||
cycles_left: _,
|
||||
ran_nonspeculatively: _,
|
||||
sent_cant_cause_cancel: _,
|
||||
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 {
|
||||
let MockLoadStoreOp {
|
||||
mop,
|
||||
is_speculative,
|
||||
src_values,
|
||||
dest_value,
|
||||
cycles_left: _,
|
||||
ran_nonspeculatively,
|
||||
sent_cant_cause_cancel: _,
|
||||
sent_output_ready: _,
|
||||
|
|
@ -3453,11 +3483,16 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
is_last_mop_in_insn,
|
||||
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 {
|
||||
mop,
|
||||
is_speculative: true,
|
||||
src_values: None,
|
||||
dest_value: None,
|
||||
cycles_left,
|
||||
ran_nonspeculatively: false,
|
||||
sent_cant_cause_cancel: false,
|
||||
sent_output_ready: false,
|
||||
|
|
@ -3477,6 +3512,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
is_speculative: _,
|
||||
src_values: op_src_values,
|
||||
dest_value: _,
|
||||
cycles_left: _,
|
||||
ran_nonspeculatively: _,
|
||||
sent_cant_cause_cancel: _,
|
||||
sent_output_ready: _,
|
||||
|
|
@ -3497,6 +3533,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
is_speculative,
|
||||
src_values: _,
|
||||
dest_value: _,
|
||||
cycles_left: _,
|
||||
ran_nonspeculatively: _,
|
||||
sent_cant_cause_cancel: _,
|
||||
sent_output_ready: _,
|
||||
|
|
@ -3513,6 +3550,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
is_speculative: _,
|
||||
src_values: _,
|
||||
dest_value,
|
||||
cycles_left,
|
||||
ran_nonspeculatively: _,
|
||||
sent_cant_cause_cancel,
|
||||
sent_output_ready: _,
|
||||
|
|
@ -3522,7 +3560,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
if *sent_cant_cause_cancel {
|
||||
continue;
|
||||
}
|
||||
if dest_value.is_some() {
|
||||
if dest_value.is_some() && *cycles_left == 0 {
|
||||
return #[hdl(sim)]
|
||||
ret_ty.HdlSome(
|
||||
#[hdl(sim)]
|
||||
|
|
@ -3555,6 +3593,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
is_speculative: _,
|
||||
src_values: _,
|
||||
dest_value,
|
||||
cycles_left,
|
||||
ran_nonspeculatively: _,
|
||||
sent_cant_cause_cancel: _,
|
||||
sent_output_ready,
|
||||
|
|
@ -3564,7 +3603,9 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
if *sent_output_ready {
|
||||
continue;
|
||||
}
|
||||
if let Some(dest_value) = dest_value {
|
||||
if let Some(dest_value) = dest_value
|
||||
&& *cycles_left == 0
|
||||
{
|
||||
return #[hdl(sim)]
|
||||
ret_ty.HdlSome(
|
||||
#[hdl(sim)]
|
||||
|
|
@ -3606,13 +3647,14 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
is_speculative: _,
|
||||
src_values: _,
|
||||
dest_value: _,
|
||||
cycles_left,
|
||||
ran_nonspeculatively,
|
||||
sent_cant_cause_cancel: _,
|
||||
sent_output_ready: _,
|
||||
config: _,
|
||||
}) = self.ops.front()
|
||||
{
|
||||
if *ran_nonspeculatively {
|
||||
if *ran_nonspeculatively && *cycles_left == 0 {
|
||||
return #[hdl(sim)]
|
||||
ret_ty.HdlSome(
|
||||
#[hdl(sim)]
|
||||
|
|
@ -3646,6 +3688,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
|
|||
}
|
||||
fn cancel_all(&mut self) {
|
||||
let Self {
|
||||
random_state: _,
|
||||
ops,
|
||||
memory,
|
||||
speculative_memory,
|
||||
|
|
@ -3699,6 +3742,10 @@ fn mock_load_store_unit<#[hdl(skip)] MI: MakeInsns>(
|
|||
),
|
||||
async |args, mut sim| {
|
||||
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(
|
||||
cd,
|
||||
async |mut sim| {
|
||||
|
|
@ -3758,6 +3805,7 @@ fn mock_load_store_unit<#[hdl(skip)] MI: MakeInsns>(
|
|||
state,
|
||||
config,
|
||||
unit_index,
|
||||
&random_state,
|
||||
sim,
|
||||
)
|
||||
},
|
||||
|
|
@ -3774,9 +3822,10 @@ fn mock_load_store_unit<#[hdl(skip)] MI: MakeInsns>(
|
|||
memory: MockMemory,
|
||||
config: PhantomConst<CpuConfig>,
|
||||
unit_index: usize,
|
||||
random_state: &RandomState,
|
||||
mut sim: ExternModuleSimulationState,
|
||||
) {
|
||||
let mut state = MockLoadStoreUnitState::new(config, unit_index, memory);
|
||||
let mut state = MockLoadStoreUnitState::new(config, unit_index, memory, random_state);
|
||||
loop {
|
||||
{
|
||||
#[hdl]
|
||||
|
|
@ -4142,7 +4191,7 @@ fn test_rename_execute_retire_slow_loop() {
|
|||
};
|
||||
sim.write_clock(sim.io().cd.clk, false);
|
||||
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));
|
||||
println!("clock tick: {cycle}");
|
||||
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_reset(sim.io().cd.rst, true);
|
||||
for cycle in 0..200 {
|
||||
for cycle in 0..300 {
|
||||
sim.advance_time(SimDuration::from_nanos(500));
|
||||
println!("clock tick: {cycle}");
|
||||
sim.write_clock(sim.io().cd.clk, true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue