Compare commits
1 commit
9fbb517cf4
...
52b1b625d1
| Author | SHA1 | Date | |
|---|---|---|---|
| 52b1b625d1 |
3 changed files with 242030 additions and 187211 deletions
|
|
@ -166,15 +166,20 @@ 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: ReadyValid<UnitInputsReady<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 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,
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +209,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: zeroed(rob),
|
||||
rob: rob.sim_value_default(),
|
||||
next_pc_canceling: zeroed(next_pc_canceling),
|
||||
unit_canceling: zeroed(unit_canceling),
|
||||
l1_reg_file: zeroed(l1_reg_file),
|
||||
|
|
@ -655,6 +660,21 @@ 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>>,
|
||||
|
|
@ -736,6 +756,27 @@ 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>,
|
||||
|
|
@ -1857,16 +1898,17 @@ 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,
|
||||
cant_cause_cancel: _,
|
||||
output_ready: _,
|
||||
finish_cause_cancel: _,
|
||||
unit_outputs_ready,
|
||||
cancel_all,
|
||||
config: _,
|
||||
} = to_unit;
|
||||
sim.write(enqueue.data, state.get_unit_enqueue(unit_index))
|
||||
.await;
|
||||
sim.write(inputs_ready.data, state.get_unit_inputs_ready(unit_index))
|
||||
sim.write(inputs_ready, state.get_unit_inputs_ready(unit_index))
|
||||
.await;
|
||||
sim.write(
|
||||
cancel_all.data,
|
||||
|
|
@ -1880,13 +1922,11 @@ async fn rename_execute_retire_run(
|
|||
)
|
||||
.await;
|
||||
sim.write(
|
||||
is_no_longer_speculative.data,
|
||||
is_no_longer_speculative,
|
||||
state.get_unit_mop_is_no_longer_speculative(unit_index),
|
||||
)
|
||||
.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.write(unit_outputs_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;
|
||||
|
|
@ -1904,11 +1944,12 @@ 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 {
|
||||
|
|
@ -1929,60 +1970,43 @@ async fn rename_execute_retire_run(
|
|||
.expect("UnitEnqueue is known to be valid");
|
||||
}
|
||||
}
|
||||
if sim.read_past_bool(inputs_ready.ready, cd.clk).await {
|
||||
#[hdl(sim)]
|
||||
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");
|
||||
}
|
||||
#[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");
|
||||
}
|
||||
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, 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");
|
||||
}
|
||||
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(cant_cause_cancel.ready, cd.clk).await {
|
||||
if sim.read_past_bool(unit_outputs_ready, cd.clk).await {
|
||||
#[hdl(sim)]
|
||||
if let HdlSome(cant_cause_cancel) =
|
||||
sim.read_past(cant_cause_cancel.data, cd.clk).await
|
||||
{
|
||||
if let HdlSome(cant_cause_cancel) = sim.read_past(cant_cause_cancel, cd.clk).await {
|
||||
#[hdl(sim)]
|
||||
let UnitMOpCantCauseCancel::<_> { id, config: _ } = cant_cause_cancel;
|
||||
assert!(!state.is_canceling());
|
||||
|
|
@ -1996,24 +2020,28 @@ async fn rename_execute_retire_run(
|
|||
assert!(finished.is_none());
|
||||
assert!(caused_cancel.is_none());
|
||||
*mop_in_unit_state = mop_in_unit_state
|
||||
.with_inputs_ready()
|
||||
.with_cant_cause_cancel()
|
||||
.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.data, cd.clk).await {
|
||||
if let HdlSome(output_ready) = sim.read_past(output_ready, 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.data, cd.clk).await
|
||||
sim.read_past(finish_cause_cancel, 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) => {
|
||||
|
|
@ -2088,18 +2116,19 @@ 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 unit_field in ExecuteToUnitInterfaces::unit_fields(to_units) {
|
||||
for to_unit in ExecuteToUnitInterfaces::unit_fields(to_units) {
|
||||
#[hdl]
|
||||
let ExecuteToUnitInterface::<_> {
|
||||
enqueue,
|
||||
inputs_ready,
|
||||
cancel_all,
|
||||
is_no_longer_speculative,
|
||||
cant_cause_cancel,
|
||||
output_ready,
|
||||
finish_cause_cancel,
|
||||
cant_cause_cancel: _,
|
||||
output_ready: _,
|
||||
finish_cause_cancel: _,
|
||||
unit_outputs_ready,
|
||||
cancel_all,
|
||||
config: _,
|
||||
} = unit_field;
|
||||
} = to_unit;
|
||||
sim.write(
|
||||
enqueue.data,
|
||||
#[hdl(sim)]
|
||||
|
|
@ -2107,9 +2136,9 @@ pub fn rename_execute_retire(config: PhantomConst<CpuConfig>) {
|
|||
)
|
||||
.await;
|
||||
sim.write(
|
||||
inputs_ready.data,
|
||||
inputs_ready,
|
||||
#[hdl(sim)]
|
||||
(inputs_ready.ty().data).HdlNone(),
|
||||
(inputs_ready.ty()).HdlNone(),
|
||||
)
|
||||
.await;
|
||||
sim.write(
|
||||
|
|
@ -2119,14 +2148,12 @@ pub fn rename_execute_retire(config: PhantomConst<CpuConfig>) {
|
|||
)
|
||||
.await;
|
||||
sim.write(
|
||||
is_no_longer_speculative.data,
|
||||
is_no_longer_speculative,
|
||||
#[hdl(sim)]
|
||||
(is_no_longer_speculative.ty().data).HdlNone(),
|
||||
(is_no_longer_speculative.ty()).HdlNone(),
|
||||
)
|
||||
.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.write(unit_outputs_ready, false).await;
|
||||
}
|
||||
},
|
||||
|sim, ()| {
|
||||
|
|
|
|||
427499
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
427499
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue