diff --git a/crates/cpu/src/config.rs b/crates/cpu/src/config.rs index a7dd7d9..cf2fd08 100644 --- a/crates/cpu/src/config.rs +++ b/crates/cpu/src/config.rs @@ -163,3 +163,15 @@ 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 45c3db5..e76fa6a 100644 --- a/crates/cpu/src/next_pc.rs +++ b/crates/cpu/src/next_pc.rs @@ -14,7 +14,7 @@ use crate::{ config::{ CpuConfig, CpuConfigFetchWidth, CpuConfigMaxFetchesInFlight, CpuConfigRobSize, - TwiceCpuConfigFetchWidth, + PhantomConstCpuConfig, TwiceCpuConfigFetchWidth, }, util::array_vec::ArrayVec, }; @@ -115,7 +115,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 +159,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; @@ -204,150 +204,231 @@ struct Cancel> { } /// the output of [`Stage::run`]. -/// when cancelling operations, the returned [`StageOutput.cancel`] should be the state after -/// running all operations returned in [`StageOutput.output`]. +/// when cancelling operations, the returned [`StageRunOutput.cancel`] should be the state after +/// running all operations returned in [`StageRunOutput.output`]. #[hdl(no_static)] -struct StageOutput> { - outputs: ArrayVec, +struct StageRunOutput + PhantomConstCpuConfig, S: Type + Stage> { + outputs: ArrayVec, StageMaxOutputsPerStep>, /// when set to [`HdlSome`], [`Stage::cancel`] is called on all previous stages cancel: HdlOption>, } -trait Stage: Type + SimValueDefault + ResetSteps { - type Input: Type; +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; 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; - fn input_ty(config: PhantomConst) -> Self::Input; - fn inputs_ty(config: PhantomConst) -> Self::Inputs; - fn output_ty(config: PhantomConst) -> Self::Output; - fn max_outputs_per_step( - config: PhantomConst, - ) -> ::SizeType; - fn input_queue_size( - config: PhantomConst, - ) -> ::SizeType; - fn output_queue_size( - config: PhantomConst, - ) -> ::SizeType; - fn stage_output_ty( - config: PhantomConst, - ) -> StageOutput> { - StageOutput[Self::output_ty(config)][Self::max_outputs_per_step(config)][config] - } - /// see [`StageOutput`] for docs on output + 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 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<$Arg:ident: $Trait:ident, $C:ident: PhantomConstGet> = $Target:ty; + $vis:vis type $Type:ident<$C:ident: $PhantomConstCpuConfig:ident, $Arg:ident: $Trait:ident<$TraitC:ident>> = $Target:ty; ) => { - $vis type $Type<$Arg, $C> = <$Target as fayalite::phantom_const::ReturnSelfUnchanged<$C>>::Type; + $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 {}; - #[derive(Clone, PartialEq, Eq, Hash, Debug)] - $vis struct $OneGeneric<$Arg: $Trait>($Arg); + const _: () = { + #[derive(Clone, PartialEq, Eq, Hash, Debug)] + $vis struct $OneGeneric<$C: $PhantomConstCpuConfig>($C); - impl<$Arg: $Trait> std::ops::Index<$Arg> for $WithoutGenerics { - type Output = $OneGeneric<$Arg>; + impl<$C: $PhantomConstCpuConfig> std::ops::Index<$C> for $WithoutGenerics { + type Output = $OneGeneric<$C>; - fn index(&self, arg: $Arg) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($OneGeneric(arg))) + fn index(&self, config: $C) -> &Self::Output { + fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($OneGeneric(config))) + } } - } - impl<$Arg: $Trait, $C: PhantomConstGet> std::ops::Index<$C> for $OneGeneric<$Arg> { - type Output = $Type<$Arg, $C>; + impl<$C: $PhantomConstCpuConfig, $Arg: $Trait<$TraitC>> std::ops::Index<$Arg> for $OneGeneric<$C> { + type Output = $Type<$C, $Arg>; - fn index(&self, config: $C) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($ty(self.0, config))) + 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<$Arg:ident: $Trait:ident, $C:ident: PhantomConstGet> = $Target:ty; + $vis:vis type $Type:ident<$C:ident: $PhantomConstCpuConfig:ident, $Arg:ident: $Trait:ident<$TraitC:ident>> = $Target:ty; ) => { - $vis type $Type<$Arg, $C> = <$Target as fayalite::phantom_const::ReturnSelfUnchanged<$C>>::Type; + $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 {}; - #[derive(Clone, PartialEq, Eq, Hash, Debug)] - $vis struct $OneGeneric<$Arg: $Trait>($Arg); + const _: () = { + #[derive(Clone, PartialEq, Eq, Hash, Debug)] + $vis struct $OneGeneric<$C: $PhantomConstCpuConfig>($C); - impl<$Arg: $Trait> std::ops::Index<$Arg> for $WithoutGenerics { - type Output = $OneGeneric<$Arg>; + impl<$C: $PhantomConstCpuConfig> std::ops::Index<$C> for $WithoutGenerics { + type Output = $OneGeneric<$C>; - fn index(&self, arg: $Arg) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($OneGeneric(arg))) + fn index(&self, config: $C) -> &Self::Output { + fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($OneGeneric(config))) + } } - } - impl<$Arg: $Trait, $C: PhantomConstGet> std::ops::Index<$C> for $OneGeneric<$Arg> { - type Output = <$Type<$Arg, $C> as Size>::SizeType; + impl<$C: $PhantomConstCpuConfig, $Arg: $Trait<$TraitC>> std::ops::Index<$Arg> for $OneGeneric<$C> { + type Output = <$Type<$C, $Arg> as Size>::SizeType; - fn index(&self, config: $C) -> &Self::Output { - fayalite::intern::Interned::into_inner(fayalite::intern::Intern::intern_sized($size(self.0, config))) + 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 = StageTraitInputWithoutGenerics, StageTraitInputWithStage] - #[ty = |_stage, config: C| T::input_ty(PhantomConst::new_interned(config.get()))] - type StageTraitInput> = ::Input; + #[without_generics = StageInputWithoutGenerics, StageInputWithStage] + #[ty = |config: C, _stage| T::input_ty(config)] + type StageInput> = >::Input; } hdl_type_alias_with_generics! { - #[without_generics = StageTraitInputsWithoutGenerics, StageTraitInputsWithStage] - #[ty = |_stage, config: C| T::inputs_ty(PhantomConst::new_interned(config.get()))] - type StageTraitInputs> = ::Inputs; + #[without_generics = StageInputsWithoutGenerics, StageInputsWithStage] + #[ty = |config: C, _stage| T::inputs_ty(config)] + type StageInputs> = >::Inputs; } hdl_type_alias_with_generics! { - #[without_generics = StageTraitOutputWithoutGenerics, StageTraitOutputWithStage] - #[ty = |_stage, config: C| T::output_ty(PhantomConst::new_interned(config.get()))] - type StageTraitOutput> = ::Output; + #[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 = |_stage, config: C| T::max_outputs_per_step(PhantomConst::new_interned(config.get()))] - type StageMaxOutputsPerStep> = ::MaxOutputsPerStep; + #[size = |config: C, _stage| T::max_outputs_per_step(config)] + type StageMaxOutputsPerStep> = >::MaxOutputsPerStep; } hdl_type_alias_with_generics! { #[without_generics = StageInputQueueSizeWithoutGenerics, StageInputQueueSizeWithStage] - #[size = |_stage, config: C| T::input_queue_size(PhantomConst::new_interned(config.get()))] - type StageInputQueueSize> = ::InputQueueSize; + #[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 = |_stage, config: C| T::output_queue_size(PhantomConst::new_interned(config.get()))] - type StageOutputQueueSize> = ::OutputQueueSize; + #[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>, @@ -361,7 +442,7 @@ struct NextPcStageOutput> { config: C, } -impl SimValueDefault for NextPcStageOutput> { +impl SimValueDefault for NextPcStageOutput { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -386,7 +467,7 @@ impl SimValueDefault for NextPcStageOutput> { } #[hdl(no_static)] -struct NextPcStageState> { +struct NextPcStageState + PhantomConstCpuConfig> { call_stack: CallStack, branch_target_buffer: BranchTargetBuffer, next_pc: UInt<64>, @@ -394,7 +475,7 @@ struct NextPcStageState> { config: C, } -impl SimValueDefault for NextPcStageState> { +impl SimValueDefault for NextPcStageState { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -417,7 +498,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)] @@ -436,49 +517,60 @@ impl ResetSteps for NextPcStageState> { } } -impl Stage for NextPcStageState> { +impl Stage for NextPcStageState { type Input = (); type Inputs = (); - type Output = NextPcStageOutput>; + type Output = NextPcStageOutput; + type ToExternalPipeInputInterface = (); + type FromExternalPipeOutputInterface = (); type MaxOutputsPerStep = ConstUsize<1>; type InputQueueSize = ConstUsize<1>; type OutputQueueSize = ConstUsize<1>; - fn input_ty(_config: PhantomConst) -> Self::Input { + fn input_ty(_config: C) -> Self::Input { () } - fn inputs_ty(_config: PhantomConst) -> Self::Inputs { + fn inputs_ty(_config: C) -> Self::Inputs { () } - fn output_ty(config: PhantomConst) -> Self::Output { + fn output_ty(config: C) -> Self::Output { NextPcStageOutput[config] } - fn max_outputs_per_step( - _config: PhantomConst, - ) -> ::SizeType { + 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 { ConstUsize } - fn input_queue_size( - _config: PhantomConst, - ) -> ::SizeType { + fn input_queue_size(_config: C) -> ::SizeType { ConstUsize } - fn output_queue_size( - _config: PhantomConst, - ) -> ::SizeType { + 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>> { + ) -> SimValue> { + let this_ty = state.ty(); let config = state.config.ty(); let start_call_stack = state.call_stack.clone(); let fetch_block_id = state.next_fetch_block_id.as_int(); @@ -557,15 +649,17 @@ impl Stage for NextPcStageState> { config, }; #[hdl(sim)] - StageOutput::<_, _, _> { - outputs: Self::stage_output_ty(config).outputs.new_full_sim([output]), + StageRunOutput::<_, _> { + outputs: StageRunOutput[config][this_ty] + .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, @@ -645,7 +739,7 @@ struct BrPredStageOutput> { config: C, } -impl SimValueDefault for BrPredStageOutput> { +impl SimValueDefault for BrPredStageOutput { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -659,7 +753,7 @@ impl SimValueDefault for BrPredStageOutput> { } #[hdl(no_static)] -struct BrPredStageState> { +struct BrPredStageState + PhantomConstCpuConfig> { branch_history: UInt<6>, branch_predictor: Array, config: C, @@ -670,7 +764,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); @@ -684,7 +778,7 @@ impl BrPredStageState> { } } -impl SimValueDefault for BrPredStageState> { +impl SimValueDefault for BrPredStageState { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -705,7 +799,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)] @@ -719,49 +813,60 @@ impl ResetSteps for BrPredStageState> { } } -impl Stage for BrPredStageState> { - type Input = NextPcStageOutput>; - type Inputs = NextPcStageOutput>; - type Output = BrPredStageOutput>; +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>; + type OutputQueueSize = CpuConfigMaxFetchesInFlight; - fn input_ty(config: PhantomConst) -> Self::Input { + fn input_ty(config: C) -> Self::Input { NextPcStageOutput[config] } - fn inputs_ty(config: PhantomConst) -> Self::Inputs { + fn inputs_ty(config: C) -> Self::Inputs { NextPcStageOutput[config] } - fn output_ty(config: PhantomConst) -> Self::Output { + fn output_ty(config: C) -> Self::Output { BrPredStageOutput[config] } - fn max_outputs_per_step( - _config: PhantomConst, - ) -> ::SizeType { + 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 { ConstUsize } - fn input_queue_size( - _config: PhantomConst, - ) -> ::SizeType { + fn input_queue_size(_config: C) -> ::SizeType { ConstUsize } - fn output_queue_size( - config: PhantomConst, - ) -> ::SizeType { + 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>> { + ) -> SimValue> { + let this_ty = state.ty(); let config = state.config.ty(); #[hdl(sim)] let NextPcStageOutput::<_> { @@ -806,9 +911,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 StageOutput { outputs, cancel } = Self::stage_output_ty(config); + let StageRunOutput { outputs, cancel } = StageRunOutput[config][this_ty]; let retval = #[hdl(sim)] - StageOutput::<_, _, _> { + StageRunOutput::<_, _> { outputs: outputs.sim_value_default(), cancel: #[hdl(sim)] cancel.HdlSome( @@ -839,15 +944,17 @@ impl Stage for BrPredStageState> { config, }; #[hdl(sim)] - StageOutput::<_, _, _> { - outputs: Self::stage_output_ty(config).outputs.new_full_sim([output]), + StageRunOutput::<_, _> { + outputs: StageRunOutput[config][this_ty] + .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: _, @@ -861,7 +968,7 @@ impl Stage for BrPredStageState> { } } -impl BrPredStageState> { +impl BrPredStageState { #[hdl] fn train_branch_predictor( this: &mut SimValue, @@ -884,11 +991,11 @@ impl BrPredStageState> { } #[hdl(no_static)] -struct FetchDecodeStageState> { +struct FetchDecodeStageState + PhantomConstCpuConfig> { config: C, } -impl SimValueDefault for FetchDecodeStageState> { +impl SimValueDefault for FetchDecodeStageState { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -898,7 +1005,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)] @@ -913,7 +1020,7 @@ struct FetchDecodeStageOutput> { decode_output: DecodeToPostDecodeInterfaceInner, } -impl SimValueDefault for FetchDecodeStageOutput> { +impl SimValueDefault for FetchDecodeStageOutput { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -928,55 +1035,66 @@ impl SimValueDefault for FetchDecodeStageOutput> { } } -impl Stage for FetchDecodeStageState> { - type Input = NextPcStageOutput>; - type Inputs = FetchDecodeStageOutput>; - type Output = 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 InputQueueSize = CpuConfigMaxFetchesInFlight; type OutputQueueSize = ConstUsize<1>; - fn input_ty(config: PhantomConst) -> Self::Input { + fn input_ty(config: C) -> Self::Input { NextPcStageOutput[config] } - fn inputs_ty(config: PhantomConst) -> Self::Inputs { + fn inputs_ty(config: C) -> Self::Inputs { FetchDecodeStageOutput[config] } - fn output_ty(config: PhantomConst) -> Self::Output { + fn output_ty(config: C) -> Self::Output { FetchDecodeStageOutput[config] } - fn max_outputs_per_step( - _config: PhantomConst, - ) -> ::SizeType { + 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 { ConstUsize } - fn input_queue_size( - config: PhantomConst, - ) -> ::SizeType { + fn input_queue_size(config: C) -> ::SizeType { CpuConfigMaxFetchesInFlight[config] } - fn output_queue_size( - _config: PhantomConst, - ) -> ::SizeType { + 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>> { + ) -> SimValue> { + let this_ty = state.ty(); #[hdl(sim)] let Self { config } = state; let config = config.ty(); - let StageOutput { outputs, cancel } = Self::stage_output_ty(config); + let StageRunOutput { outputs, cancel } = StageRunOutput[config][this_ty]; #[hdl(sim)] - StageOutput::<_, _, _> { + StageRunOutput::<_, _> { outputs: outputs.new_full_sim([inputs]), cancel: #[hdl(sim)] cancel.HdlNone(), @@ -984,14 +1102,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> { +struct PostDecodeStageState + PhantomConstCpuConfig> { config: C, } @@ -1001,7 +1119,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)] @@ -1023,7 +1141,7 @@ struct PostDecodeStageOutput> { config: C, } -impl SimValueDefault for PostDecodeStageOutput> { +impl SimValueDefault for PostDecodeStageOutput { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -1041,7 +1159,7 @@ impl SimValueDefault for PostDecodeStageOutput> { } } -impl SimValueDefault for PostDecodeStageState> { +impl SimValueDefault for PostDecodeStageState { #[hdl] fn sim_value_default(self) -> SimValue { #[hdl(sim)] @@ -1051,7 +1169,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)] @@ -1060,49 +1178,60 @@ impl ResetSteps for PostDecodeStageState> { } } -impl Stage for PostDecodeStageState> { - type Input = PostDecodeStageInput>; - type Inputs = PostDecodeStageInput>; - type Output = PostDecodeStageOutput>; - type MaxOutputsPerStep = CpuConfigFetchWidth>; +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>; + type OutputQueueSize = TwiceCpuConfigFetchWidth; - fn input_ty(config: PhantomConst) -> Self::Input { + fn input_ty(config: C) -> Self::Input { PostDecodeStageInput[config] } - fn inputs_ty(config: PhantomConst) -> Self::Inputs { + fn inputs_ty(config: C) -> Self::Inputs { PostDecodeStageInput[config] } - fn output_ty(config: PhantomConst) -> Self::Output { + fn output_ty(config: C) -> Self::Output { PostDecodeStageOutput[config] } - fn max_outputs_per_step( - config: PhantomConst, - ) -> ::SizeType { + 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 { CpuConfigFetchWidth[config] } - fn input_queue_size( - _config: PhantomConst, - ) -> ::SizeType { + fn input_queue_size(_config: C) -> ::SizeType { ConstUsize } - fn output_queue_size( - config: PhantomConst, - ) -> ::SizeType { + 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>> { + ) -> SimValue> { + let this_ty = state.ty(); #[hdl(sim)] let Self { config } = state; let config = config.ty(); @@ -1140,10 +1269,10 @@ impl Stage for PostDecodeStageState> { -- either the decoded instructions or a WipDecodedInsnKind::Interrupt", ); let insns = ArrayVec::elements_sim_ref(&insns); - let StageOutput { + let StageRunOutput { outputs: outputs_ty, cancel: cancel_ty, - } = Self::stage_output_ty(config); + } = StageRunOutput[config][this_ty]; 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, @@ -1192,7 +1321,7 @@ impl Stage for PostDecodeStageState> { let mut call_stack = start_call_stack.clone(); CallStack::push(&mut call_stack, start_pc); let retval = #[hdl(sim)] - StageOutput::<_, _, _> { + StageRunOutput::<_, _> { outputs, cancel: #[hdl(sim)] cancel_ty.HdlSome( @@ -1389,7 +1518,7 @@ impl Stage for PostDecodeStageState> { }; if *new_btb_entry.cmp_ne(predicted_btb_entry) { #[hdl(sim)] - StageOutput::<_, _, _> { + StageRunOutput::<_, _> { outputs: outputs_ty.sim_value_default(), cancel: #[hdl(sim)] cancel_ty.HdlSome( @@ -1406,7 +1535,7 @@ impl Stage for PostDecodeStageState> { } } else { #[hdl(sim)] - StageOutput::<_, _, _> { + StageRunOutput::<_, _> { outputs, cancel: #[hdl(sim)] cancel_ty.HdlNone(), @@ -1415,7 +1544,7 @@ 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; } @@ -1427,7 +1556,7 @@ struct ExecuteRetireStageInput> { retire_interface_per_insn: RetireToNextPcInterfacePerInsn, } -impl SimValueDefault for ExecuteRetireStageInput> { +impl SimValueDefault for ExecuteRetireStageInput { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -1443,7 +1572,7 @@ impl SimValueDefault for ExecuteRetireStageInput> { } #[hdl(no_static)] -struct ExecuteRetireStageState> { +struct ExecuteRetireStageState + PhantomConstCpuConfig> { config: C, } @@ -1453,7 +1582,7 @@ struct ExecuteRetireStageOutput> { config: C, } -impl SimValueDefault for ExecuteRetireStageState> { +impl SimValueDefault for ExecuteRetireStageState { #[hdl] fn sim_value_default(self) -> SimValue { let Self { config } = self; @@ -1462,7 +1591,7 @@ impl SimValueDefault for ExecuteRetireStageState> { } } -impl ResetSteps for ExecuteRetireStageState> { +impl ResetSteps for ExecuteRetireStageState { #[hdl] fn reset_step(this: &mut SimValue, _step: usize) -> ResetStatus { #[hdl(sim)] @@ -1471,49 +1600,60 @@ impl ResetSteps for ExecuteRetireStageState> { } } -impl Stage for ExecuteRetireStageState> { - type Input = PostDecodeStageOutput>; - type Inputs = ExecuteRetireStageInput>; - type Output = ExecuteRetireStageOutput>; +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 InputQueueSize = CpuConfigRobSize; type OutputQueueSize = ConstUsize<1>; - fn input_ty(config: PhantomConst) -> Self::Input { + fn input_ty(config: C) -> Self::Input { PostDecodeStageOutput[config] } - fn inputs_ty(config: PhantomConst) -> Self::Inputs { + fn inputs_ty(config: C) -> Self::Inputs { ExecuteRetireStageInput[config] } - fn output_ty(config: PhantomConst) -> Self::Output { + fn output_ty(config: C) -> Self::Output { ExecuteRetireStageOutput[config] } - fn max_outputs_per_step( - _config: PhantomConst, - ) -> ::SizeType { + 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 { ConstUsize } - fn input_queue_size( - config: PhantomConst, - ) -> ::SizeType { + fn input_queue_size(config: C) -> ::SizeType { CpuConfigRobSize[config] } - fn output_queue_size( - _config: PhantomConst, - ) -> ::SizeType { + 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>> { + ) -> SimValue> { + let this_ty = state.ty(); #[hdl(sim)] let Self { config } = state; let config = config.ty(); @@ -1541,10 +1681,10 @@ impl Stage for ExecuteRetireStageState> { config: _, } = post_decode_stage_output; assert_eq!(*id, insn.id, "instruction queuing out of sync"); - let StageOutput { + let StageRunOutput { outputs: outputs_ty, cancel: cancel_ty, - } = Self::stage_output_ty(config); + } = StageRunOutput[config][this_ty]; let mut branch_history = start_branch_history.clone(); let train_branch_predictor = #[hdl(sim)] if let HdlSome(taken) = cond_br_taken { @@ -1671,7 +1811,7 @@ impl Stage for ExecuteRetireStageState> { CallStackOp::Unknown => unreachable!(), } #[hdl(sim)] - StageOutput::<_, _, _> { + StageRunOutput::<_, _> { outputs: outputs_ty.new_sim( #[hdl(sim)] ExecuteRetireStageOutput::<_> { @@ -1694,7 +1834,7 @@ impl Stage for ExecuteRetireStageState> { } } else { #[hdl(sim)] - StageOutput::<_, _, _> { + StageRunOutput::<_, _> { outputs: outputs_ty.new_full_sim([ #[hdl(sim)] ExecuteRetireStageOutput::<_> { @@ -1709,7 +1849,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; } @@ -1794,6 +1934,18 @@ 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()) @@ -2231,6 +2383,8 @@ 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 { @@ -2241,21 +2395,27 @@ 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.head == this.tail && !*this.eq_head_tail_means_full } fn is_full(this: &SimValue) -> bool { - let head = *this.head; - let tail = *this.tail; - this.ty().next_pos(head) == tail + this.head == this.tail && *this.eq_head_tail_means_full } fn len(this: &SimValue) -> usize { let capacity = this.ty().capacity(); - (*this.tail + capacity - *this.head) % capacity + if Self::is_full(this) { + capacity + } else { + (*this.tail + capacity - *this.head) % capacity + } } fn space_left(this: &SimValue) -> usize { this.ty().capacity() - Self::len(this) @@ -2263,6 +2423,7 @@ 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) { @@ -2271,6 +2432,7 @@ 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(()) @@ -2284,6 +2446,7 @@ 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) } } @@ -2294,6 +2457,11 @@ 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 @@ -2301,6 +2469,7 @@ 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) } } @@ -2309,7 +2478,12 @@ impl Queue { impl SimValueDefault for Queue { #[hdl] fn sim_value_default(self) -> SimValue { - let Self { data, head, tail } = self; + let Self { + data, + head, + tail, + eq_head_tail_means_full: _, + } = self; #[hdl(sim)] Queue:: { data: repeat( @@ -2318,6 +2492,7 @@ 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, } } } @@ -2326,55 +2501,148 @@ impl ResetSteps for Queue { #[hdl] fn reset_step(this: &mut SimValue, step: usize) -> ResetStatus { #[hdl(sim)] - let Queue:: { data, head, tail } = this; + let Queue:: { + data, + head, + tail, + eq_head_tail_means_full, + } = this; **head = 0; **tail = 0; + **eq_head_tail_means_full = false; ResetSteps::reset_step(data, step) } } #[hdl(no_static)] -struct StageWithQueues> { - state: S, - input_queue: Queue, StageInputQueueSize>, - output_queue: Queue, StageOutputQueueSize>, -} - -impl StageWithQueues> { - FIXME +struct CancelInProgressForStageWithQueues< + C: PhantomConstGet + PhantomConstCpuConfig, + S: Type + Stage, +> { + cancel_state: Bool, + input_queue_to_cancel: UIntInRangeInclusiveType, StageInputQueueSize>, + output_queue_to_cancel: UIntInRangeInclusiveType, StageOutputQueueSize>, } #[hdl(no_static)] -struct CancelInProgress> { - cancel: Cancel, - 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, +struct StageWithQueues + PhantomConstCpuConfig, S: Type + Stage> { + input_queue: Queue, StageInputQueueSize>, + state: S, + output_queue: Queue, StageOutputQueueSize>, config: C, } -impl CancelInProgress> { +impl> StageWithQueues { + #[hdl] + fn to_external_pipe_input_input( + this: &SimValue, + cancel: &SimValue>>, + prev_stage_output_queue: &SimValue, PrevLen>>, + ) -> 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; + }; + } + } + 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!() + } +} + +#[hdl(no_static)] +struct CancelInProgress + PhantomConstCpuConfig> { + cancel: Cancel, + next_pc: CancelInProgressForStageWithQueues>, + br_pred: CancelInProgressForStageWithQueues>, + fetch_decode: CancelInProgressForStageWithQueues>, + post_decode: CancelInProgressForStageWithQueues>, + execute_retire: CancelInProgressForStageWithQueues>, + config: C, +} + +impl CancelInProgress { #[hdl] fn to_fetch_cancel_data( this: &SimValue, - ) -> SimValue< - HdlOption< - UIntInRangeInclusiveType< - ConstUsize<1>, - CpuConfigMaxFetchesInFlight>, - >, - >, - > { + ) -> SimValue, CpuConfigMaxFetchesInFlight>>> + { let NextPcStateOutputs { to_fetch_cancel_data, .. @@ -2406,7 +2674,7 @@ pub struct StatesAndQueues> { config: C, } -impl SimValueDefault for StatesAndQueues> { +impl SimValueDefault for StatesAndQueues { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -2445,7 +2713,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)] @@ -2493,12 +2761,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, @@ -2532,7 +2800,7 @@ impl StatesAndQueues> { todo!() } #[hdl(sim)] - let StageOutput::<_, _, _> { outputs, cancel } = + let StageRunOutput::<_, _> { outputs, cancel } = Stage::run(next_pc_stage_state, &().to_sim_value()); retval @@ -2540,8 +2808,8 @@ impl StatesAndQueues> { #[hdl] fn step_cancel( this: &mut SimValue, - cancel_opt: &mut SimValue>>>, - inputs: SimValue>>, + cancel_opt: &mut SimValue>>, + inputs: SimValue>, ) { #[hdl(sim)] let NextPcStateStepInputs::<_> { @@ -2649,7 +2917,7 @@ pub struct NextPcState> { cancel: HdlOption>, } -impl SimValueDefault for NextPcState> { +impl SimValueDefault for NextPcState { #[hdl] fn sim_value_default(self) -> SimValue { let Self { @@ -2664,7 +2932,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)] @@ -2698,9 +2966,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, @@ -2785,10 +3053,7 @@ impl NextPcState> { } } #[hdl] - fn step( - this: &mut SimValue, - inputs: SimValue>>, - ) { + fn step(this: &mut SimValue, inputs: SimValue>) { #[hdl(sim)] let Self { states_and_queues,