Compare commits

..

1 commit

Author SHA1 Message Date
9fbb517cf4
WIP adding support for speculative loads/stores
Some checks failed
/ test (pull_request) Failing after 6m26s
2026-04-28 00:52:46 -07:00
3 changed files with 186690 additions and 241509 deletions

View file

@ -166,20 +166,15 @@ pub struct UnitMOpCantCauseCancel<C: PhantomConstGet<CpuConfig>> {
pub struct ExecuteToUnitInterface<C: PhantomConstGet<CpuConfig>> {
/// Enqueues happen in program order, they are not re-ordered by out-of-order execution.
pub enqueue: ReadyValid<UnitEnqueue<C>>,
pub inputs_ready: HdlOption<UnitInputsReady<C>>,
pub is_no_longer_speculative: HdlOption<UnitMOpIsNoLongerSpeculative<C>>,
/// this uses [`Self::unit_outputs_ready`] as a shared ready flag
#[hdl(flip)]
pub cant_cause_cancel: HdlOption<UnitMOpCantCauseCancel<C>>,
/// this uses [`Self::unit_outputs_ready`] as a shared ready flag
#[hdl(flip)]
pub output_ready: HdlOption<UnitOutputReady<C>>,
/// this uses [`Self::unit_outputs_ready`] as a shared ready flag
#[hdl(flip)]
pub finish_cause_cancel: HdlOption<UnitFinishCauseCancel<C>>,
/// ready flag for [`Self::cant_cause_cancel`], [`Self::output_ready`], and [`Self::finish_cause_cancel`]
pub unit_outputs_ready: Bool,
pub inputs_ready: ReadyValid<UnitInputsReady<C>>,
pub cancel_all: ReadyValid<()>,
pub is_no_longer_speculative: ReadyValid<UnitMOpIsNoLongerSpeculative<C>>,
#[hdl(flip)]
pub cant_cause_cancel: ReadyValid<UnitMOpCantCauseCancel<C>>,
#[hdl(flip)]
pub output_ready: ReadyValid<UnitOutputReady<C>>,
#[hdl(flip)]
pub finish_cause_cancel: ReadyValid<UnitFinishCauseCancel<C>>,
pub config: C,
}
@ -209,7 +204,7 @@ impl<C: PhantomConstCpuConfig> SimValueDefault for RenameExecuteRetireDebugState
rename_delayed: zeroed(rename_delayed),
rename_table: zeroed(rename_table),
retire_rename_table: zeroed(retire_rename_table),
rob: rob.sim_value_default(),
rob: zeroed(rob),
next_pc_canceling: zeroed(next_pc_canceling),
unit_canceling: zeroed(unit_canceling),
l1_reg_file: zeroed(l1_reg_file),
@ -660,21 +655,6 @@ struct RobEntriesDebugState {
renamed_entries_len: UInt<8>,
}
impl SimValueDefault for RobEntriesDebugState {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> {
let Self {
unrenamed,
renamed_entries_len,
} = self;
#[hdl(sim)]
Self {
unrenamed: zeroed(unrenamed),
renamed_entries_len: renamed_entries_len.sim_value_default(),
}
}
}
#[derive(Debug)]
struct RobEntries<C: PhantomConstCpuConfig> {
unrenamed: SimValue<MOpInstance<MOp>>,
@ -756,27 +736,6 @@ pub struct ReorderBufferDebugState<C: PhantomConstGet<CpuConfig>> {
config: C,
}
impl<C: PhantomConstCpuConfig> SimValueDefault for ReorderBufferDebugState<C> {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> {
let Self {
next_renamed_mop_id,
entries,
incomplete_back_entry,
renamed,
config,
} = self;
#[hdl(sim)]
Self {
next_renamed_mop_id: next_renamed_mop_id.sim_value_default(),
entries: entries.sim_value_default(),
incomplete_back_entry: incomplete_back_entry.sim_value_default(),
renamed: renamed.sim_value_default(),
config,
}
}
}
#[derive(Debug)]
struct ReorderBuffer<C: PhantomConstCpuConfig> {
next_renamed_mop_id: SimValue<MOpId>,
@ -1898,17 +1857,16 @@ async fn rename_execute_retire_run(
let ExecuteToUnitInterface::<_> {
enqueue,
inputs_ready,
is_no_longer_speculative,
cant_cause_cancel: _,
output_ready: _,
finish_cause_cancel: _,
unit_outputs_ready,
cancel_all,
is_no_longer_speculative,
cant_cause_cancel,
output_ready,
finish_cause_cancel,
config: _,
} = to_unit;
sim.write(enqueue.data, state.get_unit_enqueue(unit_index))
.await;
sim.write(inputs_ready, state.get_unit_inputs_ready(unit_index))
sim.write(inputs_ready.data, state.get_unit_inputs_ready(unit_index))
.await;
sim.write(
cancel_all.data,
@ -1922,11 +1880,13 @@ async fn rename_execute_retire_run(
)
.await;
sim.write(
is_no_longer_speculative,
is_no_longer_speculative.data,
state.get_unit_mop_is_no_longer_speculative(unit_index),
)
.await;
sim.write(unit_outputs_ready, !is_canceling).await;
sim.write(cant_cause_cancel.ready, !is_canceling).await;
sim.write(output_ready.ready, !is_canceling).await;
sim.write(finish_cause_cancel.ready, !is_canceling).await;
}
sim.wait_for_clock_edge(cd.clk).await;
let from_post_decode_insns = sim.read_past(from_post_decode.insns, cd.clk).await;
@ -1944,12 +1904,11 @@ async fn rename_execute_retire_run(
let ExecuteToUnitInterface::<_> {
enqueue,
inputs_ready,
cancel_all,
is_no_longer_speculative,
cant_cause_cancel,
output_ready,
finish_cause_cancel,
unit_outputs_ready,
cancel_all,
config: _,
} = to_unit;
if sim.read_past_bool(enqueue.ready, cd.clk).await {
@ -1970,43 +1929,60 @@ async fn rename_execute_retire_run(
.expect("UnitEnqueue is known to be valid");
}
}
#[hdl(sim)]
if let HdlSome(inputs_ready) = sim.read_past(inputs_ready, cd.clk).await {
assert!(!state.is_canceling());
let RobEntry {
mop: _,
mop_in_unit_state,
is_speculative: _,
finished,
caused_cancel,
} = state.rob.renamed_by_id_mut(&inputs_ready.mop.id);
assert!(finished.is_none());
assert!(caused_cancel.is_none());
*mop_in_unit_state = mop_in_unit_state
.with_inputs_ready()
.expect("UnitInputsReady is known to be valid");
}
#[hdl(sim)]
if let HdlSome(is_no_longer_speculative) =
sim.read_past(is_no_longer_speculative, cd.clk).await
{
assert!(!state.is_canceling());
let RobEntry {
mop: _,
mop_in_unit_state,
is_speculative: _,
finished,
caused_cancel,
} = state.rob.renamed_by_id_mut(&is_no_longer_speculative.id);
assert!(finished.is_none());
assert!(caused_cancel.is_none());
*mop_in_unit_state = mop_in_unit_state
.without_speculative()
.expect("UnitMOpIsNoLongerSpeculative is known to be valid");
}
if sim.read_past_bool(unit_outputs_ready, cd.clk).await {
if sim.read_past_bool(inputs_ready.ready, cd.clk).await {
#[hdl(sim)]
if let HdlSome(cant_cause_cancel) = sim.read_past(cant_cause_cancel, cd.clk).await {
if let HdlSome(inputs_ready) = sim.read_past(inputs_ready.data, cd.clk).await {
assert!(!state.is_canceling());
let RobEntry {
mop: _,
mop_in_unit_state,
is_speculative: _,
finished,
caused_cancel,
} = state.rob.renamed_by_id_mut(&inputs_ready.mop.id);
assert!(finished.is_none());
assert!(caused_cancel.is_none());
*mop_in_unit_state = mop_in_unit_state
.with_inputs_ready()
.expect("UnitInputsReady is known to be valid");
}
}
if sim.read_past_bool(cancel_all.ready, cd.clk).await {
#[hdl(sim)]
if let HdlSome(v) = sim.read_past(cancel_all.data, cd.clk).await {
let () = *v;
assert!(state.unit_canceling[unit_index]);
state.unit_canceling[unit_index] = false;
}
}
if sim
.read_past_bool(is_no_longer_speculative.ready, cd.clk)
.await
{
#[hdl(sim)]
if let HdlSome(is_no_longer_speculative) =
sim.read_past(is_no_longer_speculative.data, cd.clk).await
{
assert!(!state.is_canceling());
let RobEntry {
mop: _,
mop_in_unit_state,
is_speculative: _,
finished,
caused_cancel,
} = state.rob.renamed_by_id_mut(&is_no_longer_speculative.id);
assert!(finished.is_none());
assert!(caused_cancel.is_none());
*mop_in_unit_state = mop_in_unit_state
.with_inputs_ready()
.expect("UnitMOpIsNoLongerSpeculative is known to be valid");
}
}
if sim.read_past_bool(cant_cause_cancel.ready, cd.clk).await {
#[hdl(sim)]
if let HdlSome(cant_cause_cancel) =
sim.read_past(cant_cause_cancel.data, cd.clk).await
{
#[hdl(sim)]
let UnitMOpCantCauseCancel::<_> { id, config: _ } = cant_cause_cancel;
assert!(!state.is_canceling());
@ -2020,28 +1996,24 @@ async fn rename_execute_retire_run(
assert!(finished.is_none());
assert!(caused_cancel.is_none());
*mop_in_unit_state = mop_in_unit_state
.with_cant_cause_cancel()
.with_inputs_ready()
.expect("UnitMOpCantCauseCancel should be valid");
}
}
if sim.read_past_bool(output_ready.ready, cd.clk).await {
#[hdl(sim)]
if let HdlSome(output_ready) = sim.read_past(output_ready, cd.clk).await {
if let HdlSome(output_ready) = sim.read_past(output_ready.data, cd.clk).await {
state.unit_output_ready(output_ready);
}
}
if sim.read_past_bool(finish_cause_cancel.ready, cd.clk).await {
#[hdl(sim)]
if let HdlSome(finish_cause_cancel) =
sim.read_past(finish_cause_cancel, cd.clk).await
sim.read_past(finish_cause_cancel.data, cd.clk).await
{
state.unit_finish_cause_cancel(finish_cause_cancel);
}
}
if sim.read_past_bool(cancel_all.ready, cd.clk).await {
#[hdl(sim)]
if let HdlSome(v) = sim.read_past(cancel_all.data, cd.clk).await {
let () = *v;
assert!(state.unit_canceling[unit_index]);
state.unit_canceling[unit_index] = false;
}
}
}
match &mut state.next_pc_canceling {
Some(NextPcCancelingState::NeedReceiveCancel) => {
@ -2116,19 +2088,18 @@ pub fn rename_execute_retire(config: PhantomConst<CpuConfig>) {
.await;
sim.write(to_next_pc.next_insns, to_next_pc.ty().next_insns.HdlNone())
.await;
for to_unit in ExecuteToUnitInterfaces::unit_fields(to_units) {
for unit_field in ExecuteToUnitInterfaces::unit_fields(to_units) {
#[hdl]
let ExecuteToUnitInterface::<_> {
enqueue,
inputs_ready,
is_no_longer_speculative,
cant_cause_cancel: _,
output_ready: _,
finish_cause_cancel: _,
unit_outputs_ready,
cancel_all,
is_no_longer_speculative,
cant_cause_cancel,
output_ready,
finish_cause_cancel,
config: _,
} = to_unit;
} = unit_field;
sim.write(
enqueue.data,
#[hdl(sim)]
@ -2136,9 +2107,9 @@ pub fn rename_execute_retire(config: PhantomConst<CpuConfig>) {
)
.await;
sim.write(
inputs_ready,
inputs_ready.data,
#[hdl(sim)]
(inputs_ready.ty()).HdlNone(),
(inputs_ready.ty().data).HdlNone(),
)
.await;
sim.write(
@ -2148,12 +2119,14 @@ pub fn rename_execute_retire(config: PhantomConst<CpuConfig>) {
)
.await;
sim.write(
is_no_longer_speculative,
is_no_longer_speculative.data,
#[hdl(sim)]
(is_no_longer_speculative.ty()).HdlNone(),
(is_no_longer_speculative.ty().data).HdlNone(),
)
.await;
sim.write(unit_outputs_ready, false).await;
sim.write(cant_cause_cancel.ready, false).await;
sim.write(output_ready.ready, false).await;
sim.write(finish_cause_cancel.ready, false).await;
}
},
|sim, ()| {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff