diff --git a/Cargo.lock b/Cargo.lock index ad43a3c..90538a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,7 +305,7 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fayalite" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#fbe4585578a043829bfb4d5af087fc7f4bf010b8" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#9e803223d0f08c3398182cbabbff28cda7853b0f" dependencies = [ "base64", "bitvec", @@ -332,7 +332,7 @@ dependencies = [ [[package]] name = "fayalite-proc-macros" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#fbe4585578a043829bfb4d5af087fc7f4bf010b8" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#9e803223d0f08c3398182cbabbff28cda7853b0f" dependencies = [ "fayalite-proc-macros-impl", ] @@ -340,7 +340,7 @@ dependencies = [ [[package]] name = "fayalite-proc-macros-impl" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#fbe4585578a043829bfb4d5af087fc7f4bf010b8" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#9e803223d0f08c3398182cbabbff28cda7853b0f" dependencies = [ "base16ct", "num-bigint", @@ -355,7 +355,7 @@ dependencies = [ [[package]] name = "fayalite-visit-gen" version = "0.3.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#fbe4585578a043829bfb4d5af087fc7f4bf010b8" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#9e803223d0f08c3398182cbabbff28cda7853b0f" dependencies = [ "indexmap", "prettyplease", diff --git a/crates/cpu/src/config.rs b/crates/cpu/src/config.rs index cf2fd08..acbec47 100644 --- a/crates/cpu/src/config.rs +++ b/crates/cpu/src/config.rs @@ -160,18 +160,3 @@ pub type CpuConfigLog2FetchWidthInBytes> = DynSize #[hdl(get(|c| c.fetch_width_in_bytes()))] pub type CpuConfigFetchWidthInBytes> = DynSize; - -#[hdl(get(|c| c.rob_size.get()))] -pub type CpuConfigRobSize> = DynSize; - -pub trait PhantomConstCpuConfig: - PhantomConstGet - + Into> - + From> - + Type - + ToSimValue - + ToExpr -{ -} - -impl PhantomConstCpuConfig for PhantomConst {} diff --git a/crates/cpu/src/next_pc.rs b/crates/cpu/src/next_pc.rs index e76fa6a..97d2f33 100644 --- a/crates/cpu/src/next_pc.rs +++ b/crates/cpu/src/next_pc.rs @@ -12,10 +12,7 @@ #![doc = simple_mermaid::mermaid!("next_pc/next_pc.mermaid")] use crate::{ - config::{ - CpuConfig, CpuConfigFetchWidth, CpuConfigMaxFetchesInFlight, CpuConfigRobSize, - PhantomConstCpuConfig, TwiceCpuConfigFetchWidth, - }, + config::{CpuConfig, CpuConfigFetchWidth, CpuConfigMaxFetchesInFlight}, util::array_vec::ArrayVec, }; use fayalite::{ @@ -115,7 +112,7 @@ pub struct RetireToNextPcInterfacePerInsn> { pub config: C, } -impl SimValueDefault for RetireToNextPcInterfacePerInsn { +impl SimValueDefault for RetireToNextPcInterfacePerInsn> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -159,7 +156,7 @@ pub struct DecodeToPostDecodeInterfaceInner> { pub config: C, } -impl SimValueDefault for DecodeToPostDecodeInterfaceInner { +impl SimValueDefault for DecodeToPostDecodeInterfaceInner> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { insns, config } = self; @@ -184,9 +181,6 @@ pub struct PostDecodeOutputInterface> { pub config: C, } -const BRANCH_PREDICTOR_LOG2_SIZE: usize = 8; -const BRANCH_PREDICTOR_SIZE: usize = 1 << BRANCH_PREDICTOR_LOG2_SIZE; - #[hdl] struct TrainBranchPredictor { branch_predictor_index: UIntInRange<0, { BRANCH_PREDICTOR_SIZE }>, @@ -204,231 +198,38 @@ struct Cancel> { } /// the output of [`Stage::run`]. -/// when cancelling operations, the returned [`StageRunOutput.cancel`] should be the state after -/// running all operations returned in [`StageRunOutput.output`]. +/// when cancelling operations, the returned [`StageOutput.cancel`] should be the state after +/// running all operations returned in [`StageOutput.output`]. #[hdl(no_static)] -struct StageRunOutput + PhantomConstCpuConfig, S: Type + Stage> { - outputs: ArrayVec, StageMaxOutputsPerStep>, +struct StageOutput> { + outputs: ArrayVec, /// when set to [`HdlSome`], [`Stage::cancel`] is called on all previous stages cancel: HdlOption>, } -trait Stages: Type { - fn visit_sim_value_ref>(this: &SimValue, visitor: &mut V); -} - -impl Stages for () { - #[hdl] - fn visit_sim_value_ref>(this: &SimValue, _visitor: &mut V) { - #[hdl(sim)] - let () = this; - } -} - -impl> Stages for (S1,) { - #[hdl] - fn visit_sim_value_ref>(this: &SimValue, visitor: &mut V) { - #[hdl(sim)] - let (s1,) = this; - visitor.visit(s1); - } -} - -impl, S2: Stage> Stages for (S1, S2) { - #[hdl] - fn visit_sim_value_ref>(this: &SimValue, visitor: &mut V) { - #[hdl(sim)] - let (s1, s2) = this; - visitor.visit(s1); - visitor.visit(s2); - } -} - -trait StagesVisitSimValueRef { - fn visit>(&mut self, stage: &SimValue); -} - -trait Stage: Type + SimValueDefault + ResetSteps { - type InputStages: Stages; - type Input: Type + SimValueDefault; +trait Stage: Type + SimValueDefault + ResetSteps { type Inputs: Type; type Output: Type; - type ToExternalPipeInputInterface: Type; - type FromExternalPipeOutputInterface: Type; - type FromExternalPipeOutputItem: Type; - type MaxOutputsPerStep: Size; - type ToExternalPipeInputInputLen: Size; - type InputQueueSize: Size; - type OutputQueueSize: Size; + type MaxOutputCount: Size; - fn input_ty(config: C) -> Self::Input; - fn inputs_ty(config: C) -> Self::Inputs; - fn output_ty(config: C) -> Self::Output; - fn to_external_pipe_input_interface_ty(config: C) -> Self::ToExternalPipeInputInterface; - fn from_external_pipe_output_interface_ty(config: C) -> Self::FromExternalPipeOutputInterface; - fn from_external_pipe_output_item_ty(config: C) -> Self::FromExternalPipeOutputItem; - - fn max_outputs_per_step(config: C) -> ::SizeType; - fn to_external_pipe_input_input_len( - config: C, - ) -> ::SizeType; - fn input_queue_size(config: C) -> ::SizeType; - fn output_queue_size(config: C) -> ::SizeType; - - fn cancel_in_progress_for_stage_mut( - cancel: &mut SimValue>, - ) -> &mut SimValue>; - - /// see [`StageRunOutput`] for docs on output + fn output_ty(config: PhantomConst) -> Self::Output; + fn max_output_count( + config: PhantomConst, + ) -> ::SizeType; + fn stage_output_ty( + config: PhantomConst, + ) -> StageOutput> { + StageOutput[Self::output_ty(config)][Self::max_output_count(config)][config] + } + /// see [`StageOutput`] for docs on output fn run( state: &mut SimValue, inputs: &SimValue, - ) -> SimValue>; + ) -> SimValue>>; /// changes state to match `cancel` - fn cancel(state: &mut SimValue, cancel: &SimValue>); + fn cancel(state: &mut SimValue, cancel: &SimValue>>); } -macro_rules! hdl_type_alias_with_generics { - ( - #[without_generics = $WithoutGenerics:ident, $OneGeneric:ident] - #[ty = $ty:expr] - $vis:vis type $Type:ident<$C:ident: $PhantomConstCpuConfig:ident, $Arg:ident: $Trait:ident<$TraitC:ident>> = $Target:ty; - ) => { - $vis type $Type<$C, $Arg> = <$Target as fayalite::phantom_const::ReturnSelfUnchanged<$C>>::Type; - - $vis struct $WithoutGenerics {} - - #[allow(non_upper_case_globals)] - $vis const $Type: $WithoutGenerics = $WithoutGenerics {}; - - const _: () = { - #[derive(Clone, PartialEq, Eq, Hash, Debug)] - $vis struct $OneGeneric<$C: $PhantomConstCpuConfig>($C); - - impl<$C: $PhantomConstCpuConfig> std::ops::Index<$C> for $WithoutGenerics { - type Output = $OneGeneric<$C>; - - fn index(&self, config: $C) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($OneGeneric(config))) - } - } - - impl<$C: $PhantomConstCpuConfig, $Arg: $Trait<$TraitC>> std::ops::Index<$Arg> for $OneGeneric<$C> { - type Output = $Type<$C, $Arg>; - - fn index(&self, arg: $Arg) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($ty(self.0, arg))) - } - } - }; - }; - ( - #[without_generics = $WithoutGenerics:ident, $OneGeneric:ident] - #[size = $size:expr] - $vis:vis type $Type:ident<$C:ident: $PhantomConstCpuConfig:ident, $Arg:ident: $Trait:ident<$TraitC:ident>> = $Target:ty; - ) => { - $vis type $Type<$C, $Arg> = <$Target as fayalite::phantom_const::ReturnSelfUnchanged<$C>>::Type; - - $vis struct $WithoutGenerics {} - - #[allow(non_upper_case_globals)] - $vis const $Type: $WithoutGenerics = $WithoutGenerics {}; - - const _: () = { - #[derive(Clone, PartialEq, Eq, Hash, Debug)] - $vis struct $OneGeneric<$C: $PhantomConstCpuConfig>($C); - - impl<$C: $PhantomConstCpuConfig> std::ops::Index<$C> for $WithoutGenerics { - type Output = $OneGeneric<$C>; - - fn index(&self, config: $C) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($OneGeneric(config))) - } - } - - impl<$C: $PhantomConstCpuConfig, $Arg: $Trait<$TraitC>> std::ops::Index<$Arg> for $OneGeneric<$C> { - type Output = <$Type<$C, $Arg> as Size>::SizeType; - - fn index(&self, arg: $Arg) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($size(self.0, arg))) - } - } - }; - }; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageInputWithoutGenerics, StageInputWithStage] - #[ty = |config: C, _stage| T::input_ty(config)] - type StageInput> = >::Input; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageInputsWithoutGenerics, StageInputsWithStage] - #[ty = |config: C, _stage| T::inputs_ty(config)] - type StageInputs> = >::Inputs; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageOutputWithoutGenerics, StageOutputWithStage] - #[ty = |config: C, _stage| T::output_ty(config)] - type StageOutput> = >::Output; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageToExternalPipeInputInterfaceWithoutGenerics, StageToExternalPipeInputInterfaceWithStage] - #[ty = |config: C, _stage| T::to_external_pipe_input_interface_ty(config)] - type StageToExternalPipeInputInterface> = >::ToExternalPipeInputInterface; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageFromExternalPipeOutputInterfaceWithoutGenerics, StageFromExternalPipeOutputInterfaceWithStage] - #[ty = |config: C, _stage| T::from_external_pipe_output_interface_ty(config)] - type StageFromExternalPipeOutputInterface> = >::FromExternalPipeOutputInterface; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageMaxOutputsPerStepWithoutGenerics, StageMaxOutputsPerStepWithStage] - #[size = |config: C, _stage| T::max_outputs_per_step(config)] - type StageMaxOutputsPerStep> = >::MaxOutputsPerStep; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageInputQueueSizeWithoutGenerics, StageInputQueueSizeWithStage] - #[size = |config: C, _stage| T::input_queue_size(config)] - type StageInputQueueSize> = >::InputQueueSize; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageToExternalPipeInputInputLenWithoutGenerics, StageToExternalPipeInputInputLenWithStage] - #[size = |config: C, _stage| T::to_external_pipe_input_input_len(config)] - type StageToExternalPipeInputInputLen> = >::ToExternalPipeInputInputLen; -} - -hdl_type_alias_with_generics! { - #[without_generics = StageOutputQueueSizeWithoutGenerics, StageOutputQueueSizeWithStage] - #[size = |config: C, _stage| T::output_queue_size(config)] - type StageOutputQueueSize> = >::OutputQueueSize; -} - -#[hdl] -type StageToExternalPipeInputInput< - C: PhantomConstGet + PhantomConstCpuConfig, - S: Type + Stage, -> = ArrayVec, StageToExternalPipeInputInputLen>; - -#[hdl] -type StageToExternalPipeInputCancel< - C: PhantomConstGet + PhantomConstCpuConfig, - S: Type + Stage, -> = UIntInRangeInclusiveType, StageInputQueueSize>; - -#[hdl] -type StageToExternalPipeInputInput< - C: PhantomConstGet + PhantomConstCpuConfig, - S: Type + Stage, -> = ArrayVec, StageToExternalPipeInputInputLen>; - #[hdl(no_static)] struct NextPcStageOutput> { start_pc: UInt<64>, @@ -442,7 +243,7 @@ struct NextPcStageOutput> { config: C, } -impl SimValueDefault for NextPcStageOutput { +impl SimValueDefault for NextPcStageOutput> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -467,7 +268,7 @@ impl SimValueDefault for NextPcStageOutput { } #[hdl(no_static)] -struct NextPcStageState + PhantomConstCpuConfig> { +struct NextPcStageState> { call_stack: CallStack, branch_target_buffer: BranchTargetBuffer, next_pc: UInt<64>, @@ -475,7 +276,7 @@ struct NextPcStageState + PhantomConstCpuConfig> { config: C, } -impl SimValueDefault for NextPcStageState { +impl SimValueDefault for NextPcStageState> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -498,7 +299,7 @@ impl SimValueDefault for NextPcStageState { } } -impl ResetSteps for NextPcStageState { +impl ResetSteps for NextPcStageState> { #[hdl] fn reset_step(this: &mut SimValue, step: usize) -> ResetStatus { #[hdl(sim)] @@ -517,60 +318,26 @@ impl ResetSteps for NextPcStageState { } } -impl Stage for NextPcStageState { - type Input = (); +impl Stage for NextPcStageState> { type Inputs = (); - type Output = NextPcStageOutput; - type ToExternalPipeInputInterface = (); - type FromExternalPipeOutputInterface = (); - type MaxOutputsPerStep = ConstUsize<1>; - type InputQueueSize = ConstUsize<1>; - type OutputQueueSize = ConstUsize<1>; + type Output = NextPcStageOutput>; + type MaxOutputCount = ConstUsize<1>; - fn input_ty(_config: C) -> Self::Input { - () - } - - fn inputs_ty(_config: C) -> Self::Inputs { - () - } - - fn output_ty(config: C) -> Self::Output { + fn output_ty(config: PhantomConst) -> Self::Output { NextPcStageOutput[config] } - fn to_external_pipe_input_interface_ty(_config: C) -> Self::ToExternalPipeInputInterface { - () - } - - fn from_external_pipe_output_interface_ty(_config: C) -> Self::FromExternalPipeOutputInterface { - () - } - - fn max_outputs_per_step(_config: C) -> ::SizeType { + fn max_output_count( + _config: PhantomConst, + ) -> ::SizeType { ConstUsize } - fn input_queue_size(_config: C) -> ::SizeType { - ConstUsize - } - - fn output_queue_size(_config: C) -> ::SizeType { - ConstUsize - } - - fn cancel_in_progress_for_stage_mut( - cancel: &mut SimValue>, - ) -> &mut SimValue> { - &mut cancel.next_pc - } - #[hdl] fn run( state: &mut SimValue, _inputs: &SimValue, - ) -> SimValue> { - let this_ty = state.ty(); + ) -> SimValue>> { let config = state.config.ty(); let start_call_stack = state.call_stack.clone(); let fetch_block_id = state.next_fetch_block_id.as_int(); @@ -649,17 +416,15 @@ impl Stage for NextPcStageState { config, }; #[hdl(sim)] - StageRunOutput::<_, _> { - outputs: StageRunOutput[config][this_ty] - .outputs - .new_full_sim([output]), + StageOutput::<_, _, _> { + outputs: Self::stage_output_ty(config).outputs.new_full_sim([output]), cancel: #[hdl(sim)] (HdlOption[Cancel[config]]).HdlNone(), } } #[hdl] - fn cancel(state: &mut SimValue, cancel: &SimValue>) { + fn cancel(state: &mut SimValue, cancel: &SimValue>>) { #[hdl(sim)] let Self { call_stack, @@ -739,7 +504,7 @@ struct BrPredStageOutput> { config: C, } -impl SimValueDefault for BrPredStageOutput { +impl SimValueDefault for BrPredStageOutput> { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -753,7 +518,7 @@ impl SimValueDefault for BrPredStageOutput { } #[hdl(no_static)] -struct BrPredStageState + PhantomConstCpuConfig> { +struct BrPredStageState> { branch_history: UInt<6>, branch_predictor: Array, config: C, @@ -764,7 +529,7 @@ fn step_branch_history(branch_history: &mut SimValue>, taken: bool) { ((&**branch_history << 1) | taken.cast_to_static::>()).cast_to_static::>(); } -impl BrPredStageState { +impl BrPredStageState> { fn branch_predictor_index(this: &SimValue, branch_pc: u64) -> usize { let mut t = this.branch_history.cast_to_static::>().as_int(); t ^= t.rotate_left(5) & !branch_pc.rotate_right(3); @@ -778,7 +543,7 @@ impl BrPredStageState { } } -impl SimValueDefault for BrPredStageState { +impl SimValueDefault for BrPredStageState> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -799,7 +564,7 @@ impl SimValueDefault for BrPredStageState { } } -impl ResetSteps for BrPredStageState { +impl ResetSteps for BrPredStageState> { #[hdl] fn reset_step(this: &mut SimValue, step: usize) -> ResetStatus { #[hdl(sim)] @@ -813,60 +578,26 @@ impl ResetSteps for BrPredStageState { } } -impl Stage for BrPredStageState { - type Input = NextPcStageOutput; - type Inputs = NextPcStageOutput; - type Output = BrPredStageOutput; - type ToExternalPipeInputInterface = (); - type FromExternalPipeOutputInterface = (); - type MaxOutputsPerStep = ConstUsize<1>; - type InputQueueSize = ConstUsize<1>; - type OutputQueueSize = CpuConfigMaxFetchesInFlight; +impl Stage for BrPredStageState> { + type Inputs = NextPcStageOutput>; + type Output = BrPredStageOutput>; + type MaxOutputCount = ConstUsize<1>; - fn input_ty(config: C) -> Self::Input { - NextPcStageOutput[config] - } - - fn inputs_ty(config: C) -> Self::Inputs { - NextPcStageOutput[config] - } - - fn output_ty(config: C) -> Self::Output { + fn output_ty(config: PhantomConst) -> Self::Output { BrPredStageOutput[config] } - fn to_external_pipe_input_interface_ty(_config: C) -> Self::ToExternalPipeInputInterface { - () - } - - fn from_external_pipe_output_interface_ty(_config: C) -> Self::FromExternalPipeOutputInterface { - () - } - - fn max_outputs_per_step(_config: C) -> ::SizeType { + fn max_output_count( + _config: PhantomConst, + ) -> ::SizeType { ConstUsize } - fn input_queue_size(_config: C) -> ::SizeType { - ConstUsize - } - - fn output_queue_size(config: C) -> ::SizeType { - CpuConfigMaxFetchesInFlight[config] - } - - fn cancel_in_progress_for_stage_mut( - cancel: &mut SimValue>, - ) -> &mut SimValue> { - &mut cancel.br_pred - } - #[hdl] fn run( state: &mut SimValue, inputs: &SimValue, - ) -> SimValue> { - let this_ty = state.ty(); + ) -> SimValue>> { let config = state.config.ty(); #[hdl(sim)] let NextPcStageOutput::<_> { @@ -911,9 +642,9 @@ impl Stage for BrPredStageState { let btb_entry_index = &btb_entry.0; let mut btb_entry = btb_entry.1.clone(); btb_entry.addr_kind = opposite_addr_kind; - let StageRunOutput { outputs, cancel } = StageRunOutput[config][this_ty]; + let StageOutput { outputs, cancel } = Self::stage_output_ty(config); let retval = #[hdl(sim)] - StageRunOutput::<_, _> { + StageOutput::<_, _, _> { outputs: outputs.sim_value_default(), cancel: #[hdl(sim)] cancel.HdlSome( @@ -944,17 +675,15 @@ impl Stage for BrPredStageState { config, }; #[hdl(sim)] - StageRunOutput::<_, _> { - outputs: StageRunOutput[config][this_ty] - .outputs - .new_full_sim([output]), + StageOutput::<_, _, _> { + outputs: Self::stage_output_ty(config).outputs.new_full_sim([output]), cancel: #[hdl(sim)] (HdlOption[Cancel[config]]).HdlNone(), } } #[hdl] - fn cancel(state: &mut SimValue, cancel: &SimValue>) { + fn cancel(state: &mut SimValue, cancel: &SimValue>>) { #[hdl(sim)] let Cancel::<_> { call_stack: _, @@ -968,7 +697,7 @@ impl Stage for BrPredStageState { } } -impl BrPredStageState { +impl BrPredStageState> { #[hdl] fn train_branch_predictor( this: &mut SimValue, @@ -991,11 +720,11 @@ impl BrPredStageState { } #[hdl(no_static)] -struct FetchDecodeStageState + PhantomConstCpuConfig> { +struct FetchDecodeStageState> { config: C, } -impl SimValueDefault for FetchDecodeStageState { +impl SimValueDefault for FetchDecodeStageState> { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -1005,7 +734,7 @@ impl SimValueDefault for FetchDecodeStageState { } } -impl ResetSteps for FetchDecodeStageState { +impl ResetSteps for FetchDecodeStageState> { #[hdl] fn reset_step(this: &mut SimValue, _step: usize) -> ResetStatus { #[hdl(sim)] @@ -1020,7 +749,7 @@ struct FetchDecodeStageOutput> { decode_output: DecodeToPostDecodeInterfaceInner, } -impl SimValueDefault for FetchDecodeStageOutput { +impl SimValueDefault for FetchDecodeStageOutput> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -1035,66 +764,32 @@ impl SimValueDefault for FetchDecodeStageOutput { } } -impl Stage for FetchDecodeStageState { - type Input = NextPcStageOutput; - type Inputs = FetchDecodeStageOutput; - type Output = FetchDecodeStageOutput; - type ToExternalPipeInputInterface = NextPcToFetchInterface; - type FromExternalPipeOutputInterface = DecodeToPostDecodeInterface; - type MaxOutputsPerStep = ConstUsize<1>; - type InputQueueSize = CpuConfigMaxFetchesInFlight; - type OutputQueueSize = ConstUsize<1>; +impl Stage for FetchDecodeStageState> { + type Inputs = FetchDecodeStageOutput>; + type Output = FetchDecodeStageOutput>; + type MaxOutputCount = ConstUsize<1>; - fn input_ty(config: C) -> Self::Input { - NextPcStageOutput[config] - } - - fn inputs_ty(config: C) -> Self::Inputs { + fn output_ty(config: PhantomConst) -> Self::Output { FetchDecodeStageOutput[config] } - fn output_ty(config: C) -> Self::Output { - FetchDecodeStageOutput[config] - } - - fn to_external_pipe_input_interface_ty(config: C) -> Self::ToExternalPipeInputInterface { - NextPcToFetchInterface[config] - } - - fn from_external_pipe_output_interface_ty(config: C) -> Self::FromExternalPipeOutputInterface { - DecodeToPostDecodeInterface[config] - } - - fn max_outputs_per_step(_config: C) -> ::SizeType { + fn max_output_count( + _config: PhantomConst, + ) -> ::SizeType { ConstUsize } - fn input_queue_size(config: C) -> ::SizeType { - CpuConfigMaxFetchesInFlight[config] - } - - fn output_queue_size(_config: C) -> ::SizeType { - ConstUsize - } - - fn cancel_in_progress_for_stage_mut( - cancel: &mut SimValue>, - ) -> &mut SimValue> { - &mut cancel.fetch_decode - } - #[hdl] fn run( state: &mut SimValue, inputs: &SimValue, - ) -> SimValue> { - let this_ty = state.ty(); + ) -> SimValue>> { #[hdl(sim)] let Self { config } = state; let config = config.ty(); - let StageRunOutput { outputs, cancel } = StageRunOutput[config][this_ty]; + let StageOutput { outputs, cancel } = Self::stage_output_ty(config); #[hdl(sim)] - StageRunOutput::<_, _> { + StageOutput::<_, _, _> { outputs: outputs.new_full_sim([inputs]), cancel: #[hdl(sim)] cancel.HdlNone(), @@ -1102,14 +797,14 @@ impl Stage for FetchDecodeStageState { } #[hdl] - fn cancel(state: &mut SimValue, _cancel: &SimValue>) { + fn cancel(state: &mut SimValue, _cancel: &SimValue>>) { #[hdl(sim)] let Self { config: _ } = state; } } #[hdl(no_static)] -struct PostDecodeStageState + PhantomConstCpuConfig> { +struct PostDecodeStageState> { config: C, } @@ -1119,7 +814,7 @@ struct PostDecodeStageInput> { br_pred_stage_output: BrPredStageOutput, } -impl SimValueDefault for PostDecodeStageInput { +impl SimValueDefault for PostDecodeStageInput> { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -1141,7 +836,7 @@ struct PostDecodeStageOutput> { config: C, } -impl SimValueDefault for PostDecodeStageOutput { +impl SimValueDefault for PostDecodeStageOutput> { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -1159,7 +854,7 @@ impl SimValueDefault for PostDecodeStageOutput { } } -impl SimValueDefault for PostDecodeStageState { +impl SimValueDefault for PostDecodeStageState> { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -1169,7 +864,7 @@ impl SimValueDefault for PostDecodeStageState { } } -impl ResetSteps for PostDecodeStageState { +impl ResetSteps for PostDecodeStageState> { #[hdl] fn reset_step(this: &mut SimValue, _step: usize) -> ResetStatus { #[hdl(sim)] @@ -1178,60 +873,26 @@ impl ResetSteps for PostDecodeStageState { } } -impl Stage for PostDecodeStageState { - type Input = PostDecodeStageInput; - type Inputs = PostDecodeStageInput; - type Output = PostDecodeStageOutput; - type ToExternalPipeInputInterface = (); - type FromExternalPipeOutputInterface = (); - type MaxOutputsPerStep = CpuConfigFetchWidth; - type InputQueueSize = ConstUsize<1>; - type OutputQueueSize = TwiceCpuConfigFetchWidth; +impl Stage for PostDecodeStageState> { + type Inputs = PostDecodeStageInput>; + type Output = PostDecodeStageOutput>; + type MaxOutputCount = CpuConfigFetchWidth>; - fn input_ty(config: C) -> Self::Input { - PostDecodeStageInput[config] - } - - fn inputs_ty(config: C) -> Self::Inputs { - PostDecodeStageInput[config] - } - - fn output_ty(config: C) -> Self::Output { + fn output_ty(config: PhantomConst) -> Self::Output { PostDecodeStageOutput[config] } - fn to_external_pipe_input_interface_ty(_config: C) -> Self::ToExternalPipeInputInterface { - () - } - - fn from_external_pipe_output_interface_ty(_config: C) -> Self::FromExternalPipeOutputInterface { - () - } - - fn max_outputs_per_step(config: C) -> ::SizeType { + fn max_output_count( + config: PhantomConst, + ) -> ::SizeType { CpuConfigFetchWidth[config] } - fn input_queue_size(_config: C) -> ::SizeType { - ConstUsize - } - - fn output_queue_size(config: C) -> ::SizeType { - TwiceCpuConfigFetchWidth[config] - } - - fn cancel_in_progress_for_stage_mut( - cancel: &mut SimValue>, - ) -> &mut SimValue> { - &mut cancel.post_decode - } - #[hdl] fn run( state: &mut SimValue, inputs: &SimValue, - ) -> SimValue> { - let this_ty = state.ty(); + ) -> SimValue>> { #[hdl(sim)] let Self { config } = state; let config = config.ty(); @@ -1269,10 +930,10 @@ impl Stage for PostDecodeStageState { -- either the decoded instructions or a WipDecodedInsnKind::Interrupt", ); let insns = ArrayVec::elements_sim_ref(&insns); - let StageRunOutput { + let StageOutput { outputs: outputs_ty, cancel: cancel_ty, - } = StageRunOutput[config][this_ty]; + } = Self::stage_output_ty(config); assert_eq!(outputs_ty.capacity(), decode_output.insns.ty().capacity()); let mut outputs = outputs_ty.sim_value_default(); let mut add_output_insn = |insn: &SimValue, @@ -1321,7 +982,7 @@ impl Stage for PostDecodeStageState { let mut call_stack = start_call_stack.clone(); CallStack::push(&mut call_stack, start_pc); let retval = #[hdl(sim)] - StageRunOutput::<_, _> { + StageOutput::<_, _, _> { outputs, cancel: #[hdl(sim)] cancel_ty.HdlSome( @@ -1518,7 +1179,7 @@ impl Stage for PostDecodeStageState { }; if *new_btb_entry.cmp_ne(predicted_btb_entry) { #[hdl(sim)] - StageRunOutput::<_, _> { + StageOutput::<_, _, _> { outputs: outputs_ty.sim_value_default(), cancel: #[hdl(sim)] cancel_ty.HdlSome( @@ -1535,7 +1196,7 @@ impl Stage for PostDecodeStageState { } } else { #[hdl(sim)] - StageRunOutput::<_, _> { + StageOutput::<_, _, _> { outputs, cancel: #[hdl(sim)] cancel_ty.HdlNone(), @@ -1544,45 +1205,36 @@ impl Stage for PostDecodeStageState { } #[hdl] - fn cancel(state: &mut SimValue, _cancel: &SimValue>) { + fn cancel(state: &mut SimValue, _cancel: &SimValue>>) { #[hdl(sim)] let Self { config: _ } = state; } } #[hdl(no_static)] -struct ExecuteRetireStageInput> { - post_decode_stage_output: PostDecodeStageOutput, - retire_interface_per_insn: RetireToNextPcInterfacePerInsn, +struct RenameDispatchExecuteStageState> { + config: C, } -impl SimValueDefault for ExecuteRetireStageInput { +#[hdl(no_static)] +struct RenameDispatchExecuteStageOutput> { + post_decode_stage_output: PostDecodeStageOutput, +} + +impl SimValueDefault for RenameDispatchExecuteStageOutput> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { post_decode_stage_output, - retire_interface_per_insn, } = self; #[hdl(sim)] Self { post_decode_stage_output: post_decode_stage_output.sim_value_default(), - retire_interface_per_insn: retire_interface_per_insn.sim_value_default(), } } } -#[hdl(no_static)] -struct ExecuteRetireStageState + PhantomConstCpuConfig> { - config: C, -} - -#[hdl(no_static)] -struct ExecuteRetireStageOutput> { - train_branch_predictor: HdlOption, - config: C, -} - -impl SimValueDefault for ExecuteRetireStageState { +impl SimValueDefault for RenameDispatchExecuteStageState> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { config } = self; @@ -1591,7 +1243,7 @@ impl SimValueDefault for ExecuteRetireStageState { } } -impl ResetSteps for ExecuteRetireStageState { +impl ResetSteps for RenameDispatchExecuteStageState> { #[hdl] fn reset_step(this: &mut SimValue, _step: usize) -> ResetStatus { #[hdl(sim)] @@ -1600,66 +1252,122 @@ impl ResetSteps for ExecuteRetireStageState { } } -impl Stage for ExecuteRetireStageState { - type Input = PostDecodeStageOutput; - type Inputs = ExecuteRetireStageInput; - type Output = ExecuteRetireStageOutput; - type ToExternalPipeInputInterface = PostDecodeOutputInterface; - type FromExternalPipeOutputInterface = RetireToNextPcInterface; - type MaxOutputsPerStep = ConstUsize<1>; - type InputQueueSize = CpuConfigRobSize; - type OutputQueueSize = ConstUsize<1>; +impl Stage for RenameDispatchExecuteStageState> { + type Inputs = RenameDispatchExecuteStageOutput>; + type Output = RenameDispatchExecuteStageOutput>; + type MaxOutputCount = ConstUsize<1>; - fn input_ty(config: C) -> Self::Input { - PostDecodeStageOutput[config] + fn output_ty(config: PhantomConst) -> Self::Output { + RenameDispatchExecuteStageOutput[config] } - fn inputs_ty(config: C) -> Self::Inputs { - ExecuteRetireStageInput[config] - } - - fn output_ty(config: C) -> Self::Output { - ExecuteRetireStageOutput[config] - } - - fn to_external_pipe_input_interface_ty(config: C) -> Self::ToExternalPipeInputInterface { - PostDecodeOutputInterface[config] - } - - fn from_external_pipe_output_interface_ty(config: C) -> Self::FromExternalPipeOutputInterface { - RetireToNextPcInterface[config] - } - - fn max_outputs_per_step(_config: C) -> ::SizeType { + fn max_output_count( + _config: PhantomConst, + ) -> ::SizeType { ConstUsize } - fn input_queue_size(config: C) -> ::SizeType { - CpuConfigRobSize[config] - } - - fn output_queue_size(_config: C) -> ::SizeType { - ConstUsize - } - - fn cancel_in_progress_for_stage_mut( - cancel: &mut SimValue>, - ) -> &mut SimValue> { - &mut cancel.execute_retire - } - #[hdl] fn run( state: &mut SimValue, inputs: &SimValue, - ) -> SimValue> { - let this_ty = state.ty(); + ) -> SimValue>> { + #[hdl(sim)] + let Self { config } = state; + let config = config.ty(); + let StageOutput { outputs, cancel } = Self::stage_output_ty(config); + #[hdl(sim)] + StageOutput::<_, _, _> { + outputs: outputs.new_full_sim([inputs]), + cancel: #[hdl(sim)] + cancel.HdlNone(), + } + } + + #[hdl] + fn cancel(state: &mut SimValue, _cancel: &SimValue>>) { + #[hdl(sim)] + let Self { config: _ } = state; + } +} + +#[hdl(no_static)] +struct RetireStageInput> { + rename_dispatch_execute_stage_output: RenameDispatchExecuteStageOutput, + retire_interface_per_insn: RetireToNextPcInterfacePerInsn, +} + +impl SimValueDefault for RetireStageInput> { + #[hdl] + fn sim_value_default(self) -> SimValue { + let Self { + rename_dispatch_execute_stage_output, + retire_interface_per_insn, + } = self; + #[hdl(sim)] + Self { + rename_dispatch_execute_stage_output: rename_dispatch_execute_stage_output + .sim_value_default(), + retire_interface_per_insn: retire_interface_per_insn.sim_value_default(), + } + } +} + +#[hdl(no_static)] +struct RetireStageState> { + config: C, +} + +#[hdl(no_static)] +struct RetireStageOutput> { + train_branch_predictor: HdlOption, + config: C, +} + +impl SimValueDefault for RetireStageState> { + #[hdl] + fn sim_value_default(self) -> SimValue { + let Self { config } = self; + #[hdl(sim)] + Self { config } + } +} + +impl ResetSteps for RetireStageState> { + #[hdl] + fn reset_step(this: &mut SimValue, _step: usize) -> ResetStatus { + #[hdl(sim)] + let Self { config: _ } = this; + ResetStatus::Done + } +} + +impl Stage for RetireStageState> { + type Inputs = RetireStageInput>; + type Output = RetireStageOutput>; + type MaxOutputCount = ConstUsize<1>; + + fn output_ty(config: PhantomConst) -> Self::Output { + RetireStageOutput[config] + } + + fn max_output_count( + _config: PhantomConst, + ) -> ::SizeType { + ConstUsize + } + + #[hdl] + fn run( + state: &mut SimValue, + inputs: &SimValue, + ) -> SimValue>> { #[hdl(sim)] let Self { config } = state; let config = config.ty(); #[hdl(sim)] - let ExecuteRetireStageInput::<_> { - post_decode_stage_output, + let RetireStageInput::<_> { + rename_dispatch_execute_stage_output, retire_interface_per_insn, } = inputs; #[hdl(sim)] @@ -1671,6 +1379,10 @@ impl Stage for ExecuteRetireStageState { config: _, } = retire_interface_per_insn; #[hdl(sim)] + let RenameDispatchExecuteStageOutput::<_> { + post_decode_stage_output, + } = rename_dispatch_execute_stage_output; + #[hdl(sim)] let PostDecodeStageOutput::<_> { insn, next_pc: predicted_next_pc, @@ -1681,10 +1393,10 @@ impl Stage for ExecuteRetireStageState { config: _, } = post_decode_stage_output; assert_eq!(*id, insn.id, "instruction queuing out of sync"); - let StageRunOutput { + let StageOutput { outputs: outputs_ty, cancel: cancel_ty, - } = StageRunOutput[config][this_ty]; + } = Self::stage_output_ty(config); let mut branch_history = start_branch_history.clone(); let train_branch_predictor = #[hdl(sim)] if let HdlSome(taken) = cond_br_taken { @@ -1811,10 +1523,10 @@ impl Stage for ExecuteRetireStageState { CallStackOp::Unknown => unreachable!(), } #[hdl(sim)] - StageRunOutput::<_, _> { + StageOutput::<_, _, _> { outputs: outputs_ty.new_sim( #[hdl(sim)] - ExecuteRetireStageOutput::<_> { + RetireStageOutput::<_> { train_branch_predictor, config, }, @@ -1834,10 +1546,10 @@ impl Stage for ExecuteRetireStageState { } } else { #[hdl(sim)] - StageRunOutput::<_, _> { + StageOutput::<_, _, _> { outputs: outputs_ty.new_full_sim([ #[hdl(sim)] - ExecuteRetireStageOutput::<_> { + RetireStageOutput::<_> { train_branch_predictor, config, }, @@ -1849,7 +1561,7 @@ impl Stage for ExecuteRetireStageState { } #[hdl] - fn cancel(state: &mut SimValue, _cancel: &SimValue>) { + fn cancel(state: &mut SimValue, _cancel: &SimValue>>) { #[hdl(sim)] let Self { config: _ } = state; } @@ -1934,18 +1646,6 @@ impl SimValueDefault for SimOnly { } } -impl SimValueDefault for PhantomConst { - fn sim_value_default(self) -> SimValue { - self.to_sim_value() - } -} - -impl SimValueDefault for () { - fn sim_value_default(self) -> SimValue { - self.to_sim_value() - } -} - impl SimValueDefault for ArrayVec { fn sim_value_default(self) -> SimValue { self.new_sim(self.element().sim_value_default()) @@ -2383,8 +2083,6 @@ struct Queue { head: UIntInRangeType, Capacity>, /// exclusive tail: UIntInRangeType, Capacity>, - /// used to disambiguate between a full and an empty queue - eq_head_tail_means_full: Bool, } impl Queue { @@ -2395,27 +2093,21 @@ impl Queue { assert_ne!(self.capacity(), 0); (pos + 1) % self.capacity() } - fn nth_pos_after(self, pos: usize, nth: usize) -> usize { - assert_ne!(self.capacity(), 0); - (pos + nth) % self.capacity() - } fn prev_pos(self, pos: usize) -> usize { assert_ne!(self.capacity(), 0); (pos + self.capacity() - 1) % self.capacity() } fn is_empty(this: &SimValue) -> bool { - this.head == this.tail && !*this.eq_head_tail_means_full + this.head == this.tail } fn is_full(this: &SimValue) -> bool { - this.head == this.tail && *this.eq_head_tail_means_full + let head = *this.head; + let tail = *this.tail; + this.ty().next_pos(head) == tail } fn len(this: &SimValue) -> usize { let capacity = this.ty().capacity(); - if Self::is_full(this) { - capacity - } else { - (*this.tail + capacity - *this.head) % capacity - } + (*this.tail + capacity - *this.head) % capacity } fn space_left(this: &SimValue) -> usize { this.ty().capacity() - Self::len(this) @@ -2423,7 +2115,6 @@ impl Queue { fn clear(this: &mut SimValue) { *this.head = 0; *this.tail = 0; - *this.eq_head_tail_means_full = false; } fn try_push(this: &mut SimValue, value: impl ToSimValueWithType) -> Result<(), ()> { if Self::is_full(this) { @@ -2432,7 +2123,6 @@ impl Queue { let head = *this.head; let head = this.ty().next_pos(head); *this.head = head; - *this.eq_head_tail_means_full = true; let data = &mut this.data[head]; *data = value.to_sim_value_with_type(data.ty()); Ok(()) @@ -2446,7 +2136,6 @@ impl Queue { let data = this.data[head].clone(); let head = this.ty().prev_pos(head); *this.head = head; - *this.eq_head_tail_means_full = false; Some(data) } } @@ -2457,11 +2146,6 @@ impl Queue { Some(this.data[*this.tail].clone()) } } - fn peek_iter( - this: &SimValue, - ) -> impl Clone + DoubleEndedIterator> + ExactSizeIterator { - (0..Self::len(this)).map(|nth| this.data[this.ty().nth_pos_after(*this.tail, nth)].clone()) - } fn pop(this: &mut SimValue) -> Option> { if Self::is_empty(this) { None @@ -2469,7 +2153,6 @@ impl Queue { let tail = *this.tail; let data = this.data[tail].clone(); *this.tail = this.ty().next_pos(tail); - *this.eq_head_tail_means_full = false; Some(data) } } @@ -2478,12 +2161,7 @@ impl Queue { impl SimValueDefault for Queue { #[hdl] fn sim_value_default(self) -> SimValue { - let Self { - data, - head, - tail, - eq_head_tail_means_full: _, - } = self; + let Self { data, head, tail } = self; #[hdl(sim)] Queue:: { data: repeat( @@ -2492,7 +2170,6 @@ impl SimValueDefault for Queue ), head: 0usize.to_sim_value_with_type(head), tail: 0usize.to_sim_value_with_type(tail), - eq_head_tail_means_full: false, } } } @@ -2501,148 +2178,66 @@ impl ResetSteps for Queue { #[hdl] fn reset_step(this: &mut SimValue, step: usize) -> ResetStatus { #[hdl(sim)] - let Queue:: { - data, - head, - tail, - eq_head_tail_means_full, - } = this; + let Queue:: { data, head, tail } = this; **head = 0; **tail = 0; - **eq_head_tail_means_full = false; ResetSteps::reset_step(data, step) } } -#[hdl(no_static)] -struct CancelInProgressForStageWithQueues< - C: PhantomConstGet + PhantomConstCpuConfig, - S: Type + Stage, -> { - cancel_state: Bool, - input_queue_to_cancel: UIntInRangeInclusiveType, StageInputQueueSize>, - output_queue_to_cancel: UIntInRangeInclusiveType, StageOutputQueueSize>, +#[hdl] +struct FetchQueueEntry { + fetch_block_id: UInt<{ FETCH_BLOCK_ID_WIDTH }>, + btb_entry: HdlOption, + btb_entry_index: UIntInRange<0, { BranchTargetBuffer::SIZE }>, + next_pc: UInt<64>, } -#[hdl(no_static)] -struct StageWithQueues + PhantomConstCpuConfig, S: Type + Stage> { - input_queue: Queue, StageInputQueueSize>, - state: S, - output_queue: Queue, StageOutputQueueSize>, - config: C, -} - -impl> StageWithQueues { +impl SimValueDefault for FetchQueueEntry { #[hdl] - fn to_external_pipe_input_input( - this: &SimValue, - cancel: &SimValue>>, - prev_stage_output_queue: &SimValue, PrevLen>>, - ) -> SimValue> { + fn sim_value_default(self) -> SimValue { #[hdl(sim)] - let Self { - input_queue, - state, - output_queue, - config, - } = this; - let config = config.ty(); - let state_ty = state.ty(); - let mut retval = StageToExternalPipeInputInput[config][state_ty].sim_value_default(); - #[hdl(sim)] - if let HdlNone = cancel { - for input in - Queue::peek_iter(prev_stage_output_queue).take(Queue::space_left(&this.input_queue)) - { - let Ok(_) = ArrayVec::try_push_sim(&mut retval, input) else { - break; - }; - } + FetchQueueEntry { + fetch_block_id: 0 as FetchBlockIdInt, + btb_entry: #[hdl(sim)] + HdlNone(), + btb_entry_index: 0usize.to_sim_value_with_type(FetchQueueEntry.btb_entry_index), + next_pc: 0u64, } - retval - } - #[hdl] - fn to_external_pipe_input_cancel( - this: &mut SimValue, - cancel: &mut SimValue>>, - ) -> SimValue> { - #[hdl(sim)] - let Self { - input_queue, - state, - output_queue, - config, - } = this; - let config = config.ty(); - let state_ty = state.ty(); - #[hdl(sim)] - if let HdlSome(cancel) = cancel { - S::cancel_in_progress_for_stage_mut(cancel) - .input_queue_to_cancel - .clone() - } else { - 0usize.to_sim_value_with_type(StageToExternalPipeInputCancel[config][state_ty]) - } - } - #[hdl] - fn to_external_pipe_input_cancel( - this: &mut SimValue, - cancel: &mut SimValue>>, - ) -> SimValue> { - #[hdl(sim)] - let Self { - input_queue, - state, - output_queue, - config, - } = this; - let config = config.ty(); - let state_ty = state.ty(); - #[hdl(sim)] - if let HdlSome(cancel) = cancel { - S::cancel_in_progress_for_stage_mut(cancel) - .input_queue_to_cancel - .clone() - } else { - 0usize.to_sim_value_with_type(StageToExternalPipeInputCancel[config][state_ty]) - } - } - #[hdl] - fn run( - this: &mut SimValue, - cancel: &mut SimValue>>, - to_external_pipe_input_input_ready: usize, - prev_stage_output_queue: &mut SimValue, PrevLen>>, - ) { - #[hdl(sim)] - let Self { - input_queue, - state, - output_queue, - config, - } = this; - let config = config.ty(); - todo!() } } +const BRANCH_PREDICTOR_LOG2_SIZE: usize = 8; +const BRANCH_PREDICTOR_SIZE: usize = 1 << BRANCH_PREDICTOR_LOG2_SIZE; + #[hdl(no_static)] -struct CancelInProgress + PhantomConstCpuConfig> { +struct CancelInProgress> { cancel: Cancel, - next_pc: CancelInProgressForStageWithQueues>, - br_pred: CancelInProgressForStageWithQueues>, - fetch_decode: CancelInProgressForStageWithQueues>, - post_decode: CancelInProgressForStageWithQueues>, - execute_retire: CancelInProgressForStageWithQueues>, + br_pred_stage_inputs_to_cancel: UIntInRangeInclusive<0, 32>, + br_pred_stage_cancel: Bool, + fetch_decode_stage_inputs_to_cancel: + UIntInRangeInclusiveType, CpuConfigMaxFetchesInFlight>, + fetch_decode_stage_cancel: Bool, + post_decode_stage_inputs_to_cancel: UIntInRangeInclusive<0, 1>, + post_decode_stage_cancel: Bool, + post_decode_stage_outputs_to_cancel: + UIntInRangeInclusiveType, TwiceCpuConfigFetchWidth>, + rename_dispatch_execute_stage_inputs_to_cancel: UIntInRangeInclusive<0, 256>, + rename_dispatch_execute_stage_cancel: Bool, + retire_stage_inputs_to_cancel: UIntInRangeInclusive<0, 1>, + retire_stage_cancel: Bool, config: C, } -impl CancelInProgress { +impl CancelInProgress> { #[hdl] fn to_fetch_cancel_data( this: &SimValue, - ) -> SimValue, CpuConfigMaxFetchesInFlight>>> - { + ) -> SimValue< + HdlOption< + UIntInRangeInclusiveType, CpuConfigMaxFetchesInFlight>>, + >, + > { let NextPcStateOutputs { to_fetch_cancel_data, .. @@ -2669,12 +2264,12 @@ pub struct StatesAndQueues> { post_decode_stage_outputs: Queue, CpuConfigFetchWidth>, rename_dispatch_execute_stage_inputs: Queue, ConstUsize<256>>, rename_dispatch_execute_stage_state: RenameDispatchExecuteStageState, - retire_stage_inputs: Queue, ConstUsize<1>>, - retire_stage_state: ExecuteRetireStageState, + retire_stage_inputs: Queue, ConstUsize<1>>, + retire_stage_state: RetireStageState, config: C, } -impl SimValueDefault for StatesAndQueues { +impl SimValueDefault for StatesAndQueues> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -2713,7 +2308,7 @@ impl SimValueDefault for StatesAndQueues { } } -impl ResetSteps for StatesAndQueues { +impl ResetSteps for StatesAndQueues> { #[hdl] fn reset_step(this: &mut SimValue, step: usize) -> ResetStatus { #[hdl(sim)] @@ -2761,12 +2356,12 @@ impl ResetSteps for StatesAndQueues { } } -impl StatesAndQueues { +impl StatesAndQueues> { #[hdl] fn step_no_cancel( this: &mut SimValue, - inputs: SimValue>, - ) -> SimValue>> { + inputs: SimValue>>, + ) -> SimValue>>> { #[hdl(sim)] let NextPcStateStepInputs::<_> { to_fetch_fetch_triggered, @@ -2796,20 +2391,18 @@ impl StatesAndQueues { let retval_ty = HdlOption[CancelInProgress[config]]; let mut retval = #[hdl(sim)] retval_ty.HdlNone(); - if Queue::capacity(br_pred_stage_inputs) - Queue::len(br_pred_stage_inputs) { - todo!() - } + if Queue::capacity(br_pred_stage_inputs) - Queue::len(br_pred_stage_inputs) #[hdl(sim)] - let StageRunOutput::<_, _> { outputs, cancel } = + let StageOutput::<_, _, _> { outputs, cancel } = Stage::run(next_pc_stage_state, &().to_sim_value()); - + retval } #[hdl] fn step_cancel( this: &mut SimValue, - cancel_opt: &mut SimValue>>, - inputs: SimValue>, + cancel_opt: &mut SimValue>>>, + inputs: SimValue>>, ) { #[hdl(sim)] let NextPcStateStepInputs::<_> { @@ -2917,7 +2510,7 @@ pub struct NextPcState> { cancel: HdlOption>, } -impl SimValueDefault for NextPcState { +impl SimValueDefault for NextPcState> { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -2932,7 +2525,7 @@ impl SimValueDefault for NextPcState { } } -impl ResetSteps for NextPcState { +impl ResetSteps for NextPcState> { #[hdl] fn reset_step(this: &mut SimValue, step: usize) -> ResetStatus { #[hdl(sim)] @@ -2966,9 +2559,9 @@ struct NextPcStateStepInputs> { from_retire_inner_triggered: HdlOption>, } -impl NextPcState { +impl NextPcState> { #[hdl] - fn outputs(this: &SimValue) -> SimValue> { + fn outputs(this: &SimValue) -> SimValue>> { #[hdl(sim)] let Self { states_and_queues, @@ -3053,7 +2646,10 @@ impl NextPcState { } } #[hdl] - fn step(this: &mut SimValue, inputs: SimValue>) { + fn step( + this: &mut SimValue, + inputs: SimValue>>, + ) { #[hdl(sim)] let Self { states_and_queues, diff --git a/crates/cpu/src/next_pc/next_pc.mermaid b/crates/cpu/src/next_pc/next_pc.mermaid index 613e4b3..05ac31c 100644 --- a/crates/cpu/src/next_pc/next_pc.mermaid +++ b/crates/cpu/src/next_pc/next_pc.mermaid @@ -16,7 +16,10 @@ stateDiagram-v2 br_pred --> post_decode post_decode --> next_pc: cancel following - state "Execute/Retire" as execute_retire - post_decode --> execute_retire - execute_retire --> [*] - execute_retire --> next_pc: cancel following \ No newline at end of file + state "Rename\nDispatch\nExecute" as execute + post_decode --> execute + + state "Retire" as retire + execute --> retire + retire --> [*] + retire --> next_pc: cancel following \ No newline at end of file