forked from libre-chip/cpu
Compare commits
No commits in common. "rename-execute-retire" and "master" have entirely different histories.
rename-exe
...
master
8 changed files with 156 additions and 420 deletions
|
|
@ -33,6 +33,3 @@ hex-literal.workspace = true
|
|||
regex = "1.12.2"
|
||||
sha2.workspace = true
|
||||
which.workspace = true
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(todo)'] }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
use crate::{instruction::CONST_ZERO_UNIT_NUM, unit::UnitKind};
|
||||
use crate::{
|
||||
instruction::{CONST_ZERO_UNIT_NUM, MOpTrait, PRegNum, RenamedMOp, UnitNum, UnitOutRegNum},
|
||||
unit::{
|
||||
UnitCancelInput, UnitKind, UnitOutputWrite,
|
||||
unit_base::{UnitForwardingInfo, UnitToRegAlloc},
|
||||
},
|
||||
};
|
||||
use fayalite::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::num::NonZeroUsize;
|
||||
|
|
@ -95,14 +101,55 @@ impl CpuConfig {
|
|||
pub fn unit_num_width(&self) -> usize {
|
||||
UInt::range(CONST_ZERO_UNIT_NUM..self.non_const_unit_nums().end).width()
|
||||
}
|
||||
pub fn unit_num(&self) -> UnitNum<DynSize> {
|
||||
UnitNum[self.unit_num_width()]
|
||||
}
|
||||
pub fn unit_out_reg_num(&self) -> UnitOutRegNum<DynSize> {
|
||||
UnitOutRegNum[self.out_reg_num_width]
|
||||
}
|
||||
pub fn p_reg_num(&self) -> PRegNum<DynSize, DynSize> {
|
||||
PRegNum[self.unit_num_width()][self.out_reg_num_width]
|
||||
}
|
||||
pub fn p_reg_num_width(&self) -> usize {
|
||||
self.unit_num_width() + self.out_reg_num_width
|
||||
}
|
||||
pub fn renamed_mop_in_unit(&self) -> RenamedMOp<UnitOutRegNum<DynSize>, DynSize> {
|
||||
RenamedMOp[self.unit_out_reg_num()][self.p_reg_num_width()]
|
||||
}
|
||||
pub fn unit_output_write(&self) -> UnitOutputWrite<DynSize> {
|
||||
UnitOutputWrite[self.out_reg_num_width]
|
||||
}
|
||||
pub fn unit_output_writes(&self) -> Array<HdlOption<UnitOutputWrite<DynSize>>> {
|
||||
Array[HdlOption[self.unit_output_write()]][self.non_const_unit_nums().len()]
|
||||
}
|
||||
pub fn unit_cancel_input(&self) -> UnitCancelInput<DynSize> {
|
||||
UnitCancelInput[self.out_reg_num_width]
|
||||
}
|
||||
pub fn unit_forwarding_info(&self) -> UnitForwardingInfo<DynSize, DynSize, DynSize> {
|
||||
UnitForwardingInfo[self.unit_num_width()][self.out_reg_num_width]
|
||||
[self.non_const_unit_nums().len()]
|
||||
}
|
||||
pub fn unit_max_in_flight(&self, unit_index: usize) -> NonZeroUsize {
|
||||
self.units[unit_index]
|
||||
.max_in_flight
|
||||
.unwrap_or(self.default_unit_max_in_flight)
|
||||
}
|
||||
pub fn unit_to_reg_alloc<
|
||||
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>, SrcRegWidth = DynSize>,
|
||||
ExtraOut: Type,
|
||||
>(
|
||||
&self,
|
||||
mop_ty: MOp,
|
||||
extra_out_ty: ExtraOut,
|
||||
) -> UnitToRegAlloc<MOp, ExtraOut, DynSize, DynSize, DynSize> {
|
||||
assert_eq!(
|
||||
mop_ty.dest_reg_ty(),
|
||||
self.unit_out_reg_num(),
|
||||
"inconsistent types",
|
||||
);
|
||||
UnitToRegAlloc[mop_ty][extra_out_ty][self.unit_num_width()][self.out_reg_num_width]
|
||||
[self.non_const_unit_nums().len()]
|
||||
}
|
||||
pub fn fetch_width_in_bytes(&self) -> usize {
|
||||
1usize
|
||||
.checked_shl(self.log2_fetch_width_in_bytes.into())
|
||||
|
|
@ -141,18 +188,6 @@ impl CpuConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[hdl(get(|c| c.out_reg_num_width))]
|
||||
pub type CpuConfigOutRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||
|
||||
#[hdl(get(|c| c.unit_num_width()))]
|
||||
pub type CpuConfigUnitNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||
|
||||
#[hdl(get(|c| c.p_reg_num_width()))]
|
||||
pub type CpuConfigPRegNumWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||
|
||||
#[hdl(get(|c| c.non_const_unit_nums().len()))]
|
||||
pub type CpuConfigUnitCount<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||
|
||||
#[hdl(get(|c| c.fetch_width.get()))]
|
||||
pub type CpuConfigFetchWidth<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
use crate::{
|
||||
config::{CpuConfig, CpuConfigOutRegNumWidth, CpuConfigUnitNumWidth, PhantomConstCpuConfig},
|
||||
register::{PRegFlags, PRegFlagsViewTrait, PRegValue, ViewUnused},
|
||||
unit::UnitMOp,
|
||||
util::{Rotate, range_u32_len},
|
||||
|
|
@ -2596,21 +2595,19 @@ impl<DestReg: Type, SrcRegWidth: Size> MoveRegMOp<DestReg, SrcRegWidth> {
|
|||
}
|
||||
}
|
||||
|
||||
#[hdl(cmp_eq, no_static)]
|
||||
#[hdl(cmp_eq)]
|
||||
/// there may be more than one unit of a given kind, so UnitNum is not the same as UnitKind.
|
||||
/// zero is used for built-in constants, such as the zero register
|
||||
pub struct UnitNum<C: PhantomConstGet<CpuConfig>> {
|
||||
pub adj_value: UIntType<CpuConfigUnitNumWidth<C>>,
|
||||
pub config: C,
|
||||
pub struct UnitNum<Width: Size> {
|
||||
pub adj_value: UIntType<Width>,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig> UnitNum<C> {
|
||||
impl<Width: Size> UnitNum<Width> {
|
||||
#[hdl]
|
||||
pub fn const_zero(self) -> Expr<Self> {
|
||||
#[hdl]
|
||||
UnitNum {
|
||||
adj_value: CONST_ZERO_UNIT_NUM.cast_to(self.adj_value),
|
||||
config: self.config,
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
|
|
@ -2618,7 +2615,6 @@ impl<C: PhantomConstCpuConfig> UnitNum<C> {
|
|||
#[hdl]
|
||||
UnitNum {
|
||||
adj_value: (index + 1).cast_to(self.adj_value),
|
||||
config: self.config,
|
||||
}
|
||||
}
|
||||
pub fn is_index(expr: impl ToExpr<Type = Self>, index: usize) -> Expr<Bool> {
|
||||
|
|
@ -2626,9 +2622,7 @@ impl<C: PhantomConstCpuConfig> UnitNum<C> {
|
|||
expr.ty().from_index(index).adj_value.cmp_eq(expr.adj_value)
|
||||
}
|
||||
#[hdl]
|
||||
pub fn as_index(
|
||||
expr: impl ToExpr<Type = Self>,
|
||||
) -> Expr<HdlOption<UIntType<CpuConfigUnitNumWidth<C>>>> {
|
||||
pub fn as_index(expr: impl ToExpr<Type = Self>) -> Expr<HdlOption<UIntType<Width>>> {
|
||||
let expr = expr.to_expr();
|
||||
#[hdl]
|
||||
let unit_index = wire(HdlOption[expr.ty().adj_value]);
|
||||
|
|
@ -2646,20 +2640,19 @@ impl<C: PhantomConstCpuConfig> UnitNum<C> {
|
|||
|
||||
pub const CONST_ZERO_UNIT_NUM: usize = 0;
|
||||
|
||||
#[hdl(cmp_eq, no_static)]
|
||||
pub struct UnitOutRegNum<C: PhantomConstGet<CpuConfig>> {
|
||||
pub value: UIntType<CpuConfigOutRegNumWidth<C>>,
|
||||
pub config: C,
|
||||
#[hdl(cmp_eq)]
|
||||
pub struct UnitOutRegNum<Width: Size> {
|
||||
pub value: UIntType<Width>,
|
||||
}
|
||||
|
||||
#[hdl(cmp_eq, no_static)]
|
||||
#[hdl(cmp_eq)]
|
||||
/// Physical Register Number -- registers in the CPU's backend
|
||||
pub struct PRegNum<C: PhantomConstGet<CpuConfig>> {
|
||||
pub unit_num: UnitNum<C>,
|
||||
pub unit_out_reg: UnitOutRegNum<C>,
|
||||
pub struct PRegNum<UnitNumWidth: Size, OutRegNumWidth: Size> {
|
||||
pub unit_num: UnitNum<UnitNumWidth>,
|
||||
pub unit_out_reg: UnitOutRegNum<OutRegNumWidth>,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig> PRegNum<C> {
|
||||
impl<UnitNumWidth: Size, OutRegNumWidth: Size> PRegNum<UnitNumWidth, OutRegNumWidth> {
|
||||
#[hdl]
|
||||
pub fn const_zero(self) -> Expr<Self> {
|
||||
#[hdl]
|
||||
|
|
@ -2668,7 +2661,6 @@ impl<C: PhantomConstCpuConfig> PRegNum<C> {
|
|||
unit_out_reg: #[hdl]
|
||||
UnitOutRegNum {
|
||||
value: 0u8.cast_to(self.unit_out_reg.value),
|
||||
config: self.unit_out_reg.config,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,7 @@ pub mod instruction;
|
|||
pub mod main_memory_and_io;
|
||||
pub mod next_pc;
|
||||
pub mod powerisa_instructions_xml;
|
||||
#[cfg(todo)]
|
||||
pub mod reg_alloc;
|
||||
pub mod register;
|
||||
pub mod rename_execute_retire;
|
||||
pub mod unit;
|
||||
pub mod util;
|
||||
|
|
|
|||
|
|
@ -1,295 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
config::{
|
||||
CpuConfig, CpuConfigFetchWidth, CpuConfigPRegNumWidth, CpuConfigRobSize,
|
||||
PhantomConstCpuConfig,
|
||||
},
|
||||
instruction::{MOp, MOpRegNum, PRegNum, RenamedMOp},
|
||||
next_pc::{RetireToNextPcInterfaceInner, SimValueDefault},
|
||||
util::array_vec::ArrayVec,
|
||||
};
|
||||
use fayalite::{
|
||||
int::UIntInRangeInclusiveType, prelude::*, ty::OpaqueSimValue, util::ready_valid::ReadyValid,
|
||||
};
|
||||
use std::collections::VecDeque;
|
||||
|
||||
#[hdl]
|
||||
/// A µOp along with the state needed for this instance of the µOp.
|
||||
pub struct MOpInstance<MOp> {
|
||||
pub fetch_block_id: UInt<8>,
|
||||
pub id: UInt<12>,
|
||||
pub pc: UInt<64>,
|
||||
/// initialized to 0 by decoder, overwritten by `next_pc()`
|
||||
pub predicted_next_pc: UInt<64>,
|
||||
pub size_in_bytes: UInt<4>,
|
||||
/// `true` if this µOp is the first µOp in the ISA-level instruction.
|
||||
/// In general, a single µOp can't be cancelled by itself,
|
||||
/// it needs to be cancelled along with all other µOps that
|
||||
/// come from the same ISA-level instruction.
|
||||
pub is_first_mop_in_insn: Bool,
|
||||
pub mop: MOp,
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
/// TODO: merge with [`crate::next_pc::PostDecodeOutputInterface`]
|
||||
pub struct PostDecodeOutputInterface<C: PhantomConstGet<CpuConfig>> {
|
||||
pub insns: ArrayVec<MOpInstance<MOp>, CpuConfigFetchWidth<C>>,
|
||||
#[hdl(flip)]
|
||||
pub ready: UIntInRangeInclusiveType<ConstUsize<0>, CpuConfigFetchWidth<C>>,
|
||||
/// tells the rename/execute/retire circuit to cancel all non-retired instructions
|
||||
pub cancel: ReadyValid<()>,
|
||||
pub config: C,
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
/// handles updating speculative branch predictor state (e.g. branch histories)
|
||||
/// when instructions retire, as well as updating state when a
|
||||
/// branch instruction is mis-speculated.
|
||||
pub struct RetireToNextPcInterface<C: PhantomConstGet<CpuConfig>> {
|
||||
pub inner: ReadyValid<RetireToNextPcInterfaceInner<C>>,
|
||||
/// only for debugging
|
||||
pub next_insns: HdlOption<ArrayVec<MOpInstance<MOp>, CpuConfigRobSize<C>>>,
|
||||
}
|
||||
|
||||
fn zeroed<T: Type>(ty: T) -> SimValue<T> {
|
||||
SimValue::from_opaque(
|
||||
ty,
|
||||
OpaqueSimValue::from_bits(UInt::new(ty.canonical().bit_width()).zero()),
|
||||
)
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig> SimValueDefault for RenameExecuteRetireDebugState<C> {
|
||||
fn sim_value_default(self) -> SimValue<Self> {
|
||||
zeroed(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct RenameTable<C: PhantomConstCpuConfig> {
|
||||
entries: Box<[SimValue<PRegNum<C>>; 1 << MOpRegNum::WIDTH]>,
|
||||
config: C,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig> RenameTable<C> {
|
||||
fn new(config: C) -> Self {
|
||||
Self {
|
||||
entries: vec![PRegNum[config].const_zero().into_sim_value(); 1 << MOpRegNum::WIDTH]
|
||||
.try_into()
|
||||
.expect("size is known to match"),
|
||||
config,
|
||||
}
|
||||
}
|
||||
fn to_debug_state(&self) -> SimValue<Array<PRegNum<C>, { 1 << MOpRegNum::WIDTH }>> {
|
||||
self.entries
|
||||
.to_sim_value_with_type(Array[PRegNum[self.config]][ConstUsize])
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
struct RobEntryDebugState<C: PhantomConstGet<CpuConfig>> {
|
||||
mop: MOpInstance<RenamedMOp<PRegNum<C>, CpuConfigPRegNumWidth<C>>>,
|
||||
config: C,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig> SimValueDefault for RobEntryDebugState<C> {
|
||||
fn sim_value_default(self) -> SimValue<Self> {
|
||||
zeroed(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RobEntry<C: PhantomConstCpuConfig> {
|
||||
mop: SimValue<MOpInstance<RenamedMOp<PRegNum<C>, CpuConfigPRegNumWidth<C>>>>,
|
||||
config: C,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
struct OrigMOpQueueEntryDebugState {
|
||||
mop: MOpInstance<MOp>,
|
||||
/// number of renamed µOps that this non-renamed µOp corresponds to
|
||||
renamed_mop_count: UInt<8>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct OrigMOpQueueEntry {
|
||||
mop: SimValue<MOpInstance<MOp>>,
|
||||
/// number of renamed µOps that this non-renamed µOp corresponds to
|
||||
renamed_mop_count: u8,
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
pub struct RenameExecuteRetireDebugState<C: PhantomConstGet<CpuConfig>> {
|
||||
rename_table: Array<PRegNum<C>, { 1 << MOpRegNum::WIDTH }>,
|
||||
retire_rename_table: Array<PRegNum<C>, { 1 << MOpRegNum::WIDTH }>,
|
||||
rob: ArrayVec<RobEntryDebugState<C>, CpuConfigRobSize<C>>,
|
||||
orig_mop_queue: ArrayVec<OrigMOpQueueEntryDebugState, CpuConfigRobSize<C>>,
|
||||
cancelling: Bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RenameExecuteRetireState<C: PhantomConstCpuConfig> {
|
||||
rename_table: RenameTable<C>,
|
||||
retire_rename_table: RenameTable<C>,
|
||||
rob: VecDeque<RobEntry<C>>,
|
||||
orig_mop_queue: VecDeque<OrigMOpQueueEntry>,
|
||||
cancelling: bool,
|
||||
config: C,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
|
||||
fn new(config: C) -> Self {
|
||||
let rename_table = RenameTable::new(config);
|
||||
Self {
|
||||
rename_table: rename_table.clone(),
|
||||
retire_rename_table: rename_table,
|
||||
rob: VecDeque::with_capacity(CpuConfigRobSize[config]),
|
||||
orig_mop_queue: VecDeque::with_capacity(CpuConfigRobSize[config]),
|
||||
cancelling: false,
|
||||
config,
|
||||
}
|
||||
}
|
||||
#[hdl]
|
||||
async fn write_for_debug(
|
||||
&self,
|
||||
sim: &mut ExternModuleSimulationState,
|
||||
state_for_debug: Expr<RenameExecuteRetireDebugState<C>>,
|
||||
) {
|
||||
let Self {
|
||||
ref rename_table,
|
||||
ref retire_rename_table,
|
||||
ref rob,
|
||||
ref orig_mop_queue,
|
||||
cancelling,
|
||||
config,
|
||||
} = *self;
|
||||
sim.write(
|
||||
state_for_debug,
|
||||
#[hdl(sim)]
|
||||
RenameExecuteRetireDebugState::<_> {
|
||||
rename_table: rename_table.to_debug_state(),
|
||||
retire_rename_table: retire_rename_table.to_debug_state(),
|
||||
rob: state_for_debug
|
||||
.ty()
|
||||
.rob
|
||||
.from_iter_sim(
|
||||
zeroed(RobEntryDebugState[config]),
|
||||
rob.iter().map(|entry| {
|
||||
let RobEntry { mop, config: _ } = entry;
|
||||
#[hdl(sim)]
|
||||
RobEntryDebugState::<_> { mop, config }
|
||||
}),
|
||||
)
|
||||
.expect("known to fit"),
|
||||
orig_mop_queue: state_for_debug
|
||||
.ty()
|
||||
.orig_mop_queue
|
||||
.from_iter_sim(
|
||||
zeroed(OrigMOpQueueEntryDebugState),
|
||||
orig_mop_queue.iter().map(|entry| {
|
||||
let OrigMOpQueueEntry {
|
||||
mop,
|
||||
renamed_mop_count,
|
||||
} = entry;
|
||||
#[hdl(sim)]
|
||||
OrigMOpQueueEntryDebugState {
|
||||
mop,
|
||||
renamed_mop_count,
|
||||
}
|
||||
}),
|
||||
)
|
||||
.expect("known to fit"),
|
||||
cancelling,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
#[hdl]
|
||||
async fn write_to_next_pc_next_insns(
|
||||
&self,
|
||||
sim: &mut ExternModuleSimulationState,
|
||||
next_insns: Expr<HdlOption<ArrayVec<MOpInstance<MOp>, CpuConfigRobSize<C>>>>,
|
||||
) {
|
||||
sim.write(
|
||||
next_insns,
|
||||
#[hdl(sim)]
|
||||
(next_insns.ty()).HdlSome(
|
||||
next_insns
|
||||
.ty()
|
||||
.HdlSome
|
||||
.from_iter_sim(
|
||||
zeroed(MOpInstance[MOp]),
|
||||
self.orig_mop_queue.iter().map(|entry| &entry.mop),
|
||||
)
|
||||
.expect("known to fit"),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
async fn rename_execute_retire_run(
|
||||
mut sim: ExternModuleSimulationState,
|
||||
cd: Expr<ClockDomain>,
|
||||
from_post_decode: Expr<PostDecodeOutputInterface<PhantomConst<CpuConfig>>>,
|
||||
to_next_pc: Expr<RetireToNextPcInterface<PhantomConst<CpuConfig>>>,
|
||||
state_for_debug: Expr<RenameExecuteRetireDebugState<PhantomConst<CpuConfig>>>,
|
||||
config: PhantomConst<CpuConfig>,
|
||||
) {
|
||||
let mut state = RenameExecuteRetireState::new(config);
|
||||
loop {
|
||||
state
|
||||
.write_to_next_pc_next_insns(&mut sim, to_next_pc.next_insns)
|
||||
.await;
|
||||
state.write_for_debug(&mut sim, state_for_debug).await;
|
||||
sim.wait_for_clock_edge(cd.clk).await;
|
||||
todo!("step state based on I/O");
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl_module(extern)]
|
||||
pub fn rename_execute_retire(config: PhantomConst<CpuConfig>) {
|
||||
#[hdl]
|
||||
let cd: ClockDomain = m.input();
|
||||
#[hdl]
|
||||
let from_post_decode: PostDecodeOutputInterface<PhantomConst<CpuConfig>> =
|
||||
m.input(PostDecodeOutputInterface[config]);
|
||||
#[hdl]
|
||||
let to_next_pc: RetireToNextPcInterface<PhantomConst<CpuConfig>> =
|
||||
m.output(RetireToNextPcInterface[config]);
|
||||
#[hdl]
|
||||
let state_for_debug: RenameExecuteRetireDebugState<PhantomConst<CpuConfig>> =
|
||||
m.output(RenameExecuteRetireDebugState[config]);
|
||||
m.register_clock_for_past(cd.clk);
|
||||
m.extern_module_simulation_fn(
|
||||
(cd, from_post_decode, to_next_pc, state_for_debug, config),
|
||||
|(cd, from_post_decode, to_next_pc, state_for_debug, config), mut sim| async move {
|
||||
sim.write(state_for_debug, state_for_debug.ty().sim_value_default())
|
||||
.await;
|
||||
sim.resettable(
|
||||
cd,
|
||||
|mut sim: ExternModuleSimulationState| async move {
|
||||
sim.write(from_post_decode.ready, 0usize).await;
|
||||
sim.write(from_post_decode.cancel.ready, false).await;
|
||||
sim.write(to_next_pc.inner.data, to_next_pc.ty().inner.data.HdlNone())
|
||||
.await;
|
||||
sim.write(to_next_pc.next_insns, to_next_pc.ty().next_insns.HdlNone())
|
||||
.await;
|
||||
},
|
||||
|sim, ()| {
|
||||
rename_execute_retire_run(
|
||||
sim,
|
||||
cd,
|
||||
from_post_decode,
|
||||
to_next_pc,
|
||||
state_for_debug,
|
||||
config,
|
||||
)
|
||||
},
|
||||
)
|
||||
.await;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
config::{CpuConfig, PhantomConstCpuConfig},
|
||||
config::CpuConfig,
|
||||
instruction::{
|
||||
AluBranchMOp, LoadStoreMOp, MOp, MOpDestReg, MOpInto, MOpRegNum, MOpTrait,
|
||||
MOpVariantVisitOps, MOpVariantVisitor, MOpVisitVariants, RenamedMOp, UnitOutRegNum,
|
||||
|
|
@ -48,7 +48,7 @@ macro_rules! all_units {
|
|||
}
|
||||
|
||||
impl $UnitKind {
|
||||
pub fn unit(self, config: PhantomConst<CpuConfig>, unit_index: usize) -> DynUnit {
|
||||
pub fn unit(self, config: &CpuConfig, unit_index: usize) -> DynUnit {
|
||||
match self {
|
||||
$($UnitKind::$Unit => $create_dyn_unit_fn(config, unit_index),)*
|
||||
}
|
||||
|
|
@ -277,9 +277,9 @@ pub struct UnitResultCompleted<ExtraOut> {
|
|||
pub extra_out: ExtraOut,
|
||||
}
|
||||
|
||||
#[hdl(cmp_eq, no_static)]
|
||||
pub struct UnitOutputWrite<C: PhantomConstGet<CpuConfig>> {
|
||||
pub which: UnitOutRegNum<C>,
|
||||
#[hdl(cmp_eq)]
|
||||
pub struct UnitOutputWrite<OutRegNumWidth: Size> {
|
||||
pub which: UnitOutRegNum<OutRegNumWidth>,
|
||||
pub value: PRegValue,
|
||||
}
|
||||
|
||||
|
|
@ -300,21 +300,21 @@ impl<ExtraOut: Type> UnitResult<ExtraOut> {
|
|||
}
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
pub struct UnitOutput<C: PhantomConstGet<CpuConfig>, ExtraOut> {
|
||||
pub which: UnitOutRegNum<C>,
|
||||
#[hdl]
|
||||
pub struct UnitOutput<OutRegNumWidth: Size, ExtraOut> {
|
||||
pub which: UnitOutRegNum<OutRegNumWidth>,
|
||||
pub result: UnitResult<ExtraOut>,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig, ExtraOut: Type> UnitOutput<C, ExtraOut> {
|
||||
impl<OutRegNumWidth: Size, ExtraOut: Type> UnitOutput<OutRegNumWidth, ExtraOut> {
|
||||
pub fn extra_out_ty(self) -> ExtraOut {
|
||||
self.result.extra_out_ty()
|
||||
}
|
||||
}
|
||||
|
||||
#[hdl(cmp_eq, no_static)]
|
||||
pub struct UnitCancelInput<C: PhantomConstGet<CpuConfig>> {
|
||||
pub which: UnitOutRegNum<C>,
|
||||
#[hdl(cmp_eq)]
|
||||
pub struct UnitCancelInput<OutRegNumWidth: Size> {
|
||||
pub which: UnitOutRegNum<OutRegNumWidth>,
|
||||
}
|
||||
|
||||
pub trait UnitTrait:
|
||||
|
|
@ -332,7 +332,7 @@ pub trait UnitTrait:
|
|||
|
||||
fn extract_mop(
|
||||
&self,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>>,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
||||
) -> Expr<HdlOption<Self::MOp>>;
|
||||
|
||||
fn module(&self) -> Interned<Module<Self::Type>>;
|
||||
|
|
@ -340,7 +340,7 @@ pub trait UnitTrait:
|
|||
fn unit_to_reg_alloc(
|
||||
&self,
|
||||
this: Expr<Self::Type>,
|
||||
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>>;
|
||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>>;
|
||||
|
||||
fn cd(&self, this: Expr<Self::Type>) -> Expr<ClockDomain>;
|
||||
|
||||
|
|
@ -390,7 +390,7 @@ impl UnitTrait for DynUnit {
|
|||
|
||||
fn extract_mop(
|
||||
&self,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>>,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
||||
) -> Expr<HdlOption<Self::MOp>> {
|
||||
self.unit.extract_mop(mop)
|
||||
}
|
||||
|
|
@ -402,7 +402,7 @@ impl UnitTrait for DynUnit {
|
|||
fn unit_to_reg_alloc(
|
||||
&self,
|
||||
this: Expr<Self::Type>,
|
||||
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
|
||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> {
|
||||
self.unit.unit_to_reg_alloc(this)
|
||||
}
|
||||
|
||||
|
|
@ -445,7 +445,7 @@ impl<T: UnitTrait + Clone + std::hash::Hash + Eq> UnitTrait for DynUnitWrapper<T
|
|||
|
||||
fn extract_mop(
|
||||
&self,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>>,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
||||
) -> Expr<HdlOption<Self::MOp>> {
|
||||
Expr::from_enum(Expr::as_enum(self.0.extract_mop(mop)))
|
||||
}
|
||||
|
|
@ -457,7 +457,7 @@ impl<T: UnitTrait + Clone + std::hash::Hash + Eq> UnitTrait for DynUnitWrapper<T
|
|||
fn unit_to_reg_alloc(
|
||||
&self,
|
||||
this: Expr<Self::Type>,
|
||||
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
|
||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> {
|
||||
Expr::from_bundle(Expr::as_bundle(
|
||||
self.0.unit_to_reg_alloc(Expr::from_bundle(this)),
|
||||
))
|
||||
|
|
|
|||
|
|
@ -19,13 +19,16 @@ use crate::{
|
|||
},
|
||||
};
|
||||
use fayalite::{
|
||||
intern::Interned, module::wire_with_loc, prelude::*, util::ready_valid::ReadyValid,
|
||||
intern::{Intern, Interned},
|
||||
module::wire_with_loc,
|
||||
prelude::*,
|
||||
util::ready_valid::ReadyValid,
|
||||
};
|
||||
use std::{collections::HashMap, ops::RangeTo};
|
||||
|
||||
#[hdl]
|
||||
fn add_sub<SrcCount: KnownSize>(
|
||||
mop: Expr<AddSubMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize, SrcCount>>,
|
||||
mop: Expr<AddSubMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>,
|
||||
pc: Expr<UInt<64>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
|
|
@ -242,7 +245,7 @@ fn add_sub<SrcCount: KnownSize>(
|
|||
|
||||
#[hdl]
|
||||
fn logical_flags(
|
||||
mop: Expr<LogicalFlagsMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>>,
|
||||
mop: Expr<LogicalFlagsMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<UnitResultCompleted<()>> {
|
||||
|
|
@ -256,7 +259,7 @@ fn logical_flags(
|
|||
|
||||
#[hdl]
|
||||
fn logical(
|
||||
mop: Expr<LogicalMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize, ConstUsize<2>>>,
|
||||
mop: Expr<LogicalMOp<UnitOutRegNum<DynSize>, DynSize, ConstUsize<2>>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<UnitResultCompleted<()>> {
|
||||
|
|
@ -270,7 +273,7 @@ fn logical(
|
|||
|
||||
#[hdl]
|
||||
fn logical_i(
|
||||
mop: Expr<LogicalMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize, ConstUsize<1>>>,
|
||||
mop: Expr<LogicalMOp<UnitOutRegNum<DynSize>, DynSize, ConstUsize<1>>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<UnitResultCompleted<()>> {
|
||||
|
|
@ -284,7 +287,7 @@ fn logical_i(
|
|||
|
||||
#[hdl]
|
||||
fn shift_rotate(
|
||||
mop: Expr<ShiftRotateMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>>,
|
||||
mop: Expr<ShiftRotateMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<UnitResultCompleted<()>> {
|
||||
|
|
@ -298,7 +301,7 @@ fn shift_rotate(
|
|||
|
||||
#[hdl]
|
||||
fn compare<SrcCount: KnownSize>(
|
||||
mop: Expr<CompareMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize, SrcCount>>,
|
||||
mop: Expr<CompareMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
) -> Expr<UnitResultCompleted<()>> {
|
||||
|
|
@ -312,7 +315,7 @@ fn compare<SrcCount: KnownSize>(
|
|||
|
||||
#[hdl]
|
||||
fn branch<SrcCount: KnownSize>(
|
||||
mop: Expr<BranchMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize, SrcCount>>,
|
||||
mop: Expr<BranchMOp<UnitOutRegNum<DynSize>, DynSize, SrcCount>>,
|
||||
pc: Expr<UInt<64>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
|
|
@ -327,7 +330,7 @@ fn branch<SrcCount: KnownSize>(
|
|||
|
||||
#[hdl]
|
||||
fn read_special(
|
||||
mop: Expr<ReadSpecialMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>>,
|
||||
mop: Expr<ReadSpecialMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
||||
pc: Expr<UInt<64>>,
|
||||
flags_mode: Expr<FlagsMode>,
|
||||
src_values: Expr<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
|
||||
|
|
@ -341,18 +344,20 @@ fn read_special(
|
|||
}
|
||||
|
||||
#[hdl_module]
|
||||
pub fn alu_branch(config: PhantomConst<CpuConfig>, unit_index: usize) {
|
||||
pub fn alu_branch(config: &CpuConfig, unit_index: usize) {
|
||||
#[hdl]
|
||||
let cd: ClockDomain = m.input();
|
||||
#[hdl]
|
||||
let unit_to_reg_alloc: UnitToRegAlloc<
|
||||
PhantomConst<CpuConfig>,
|
||||
AluBranchMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>,
|
||||
AluBranchMOp<UnitOutRegNum<DynSize>, DynSize>,
|
||||
(),
|
||||
> = m.output(
|
||||
UnitToRegAlloc[config][AluBranchMOp[UnitOutRegNum[config]][config.get().p_reg_num_width()]]
|
||||
[()],
|
||||
);
|
||||
DynSize,
|
||||
DynSize,
|
||||
DynSize,
|
||||
> = m.output(config.unit_to_reg_alloc(
|
||||
AluBranchMOp[config.unit_out_reg_num()][config.p_reg_num_width()],
|
||||
(),
|
||||
));
|
||||
#[hdl]
|
||||
let global_state: GlobalState = m.input();
|
||||
|
||||
|
|
@ -370,11 +375,10 @@ pub fn alu_branch(config: PhantomConst<CpuConfig>, unit_index: usize) {
|
|||
#[hdl]
|
||||
if let HdlSome(execute_start) = ReadyValid::firing_data(unit_base.execute_start) {
|
||||
#[hdl]
|
||||
let ExecuteStart::<_, _> {
|
||||
let ExecuteStart::<_> {
|
||||
mop,
|
||||
pc,
|
||||
src_values,
|
||||
config: _,
|
||||
} = execute_start;
|
||||
#[hdl]
|
||||
match mop {
|
||||
|
|
@ -576,14 +580,14 @@ pub fn alu_branch(config: PhantomConst<CpuConfig>, unit_index: usize) {
|
|||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct AluBranch {
|
||||
config: PhantomConst<CpuConfig>,
|
||||
config: Interned<CpuConfig>,
|
||||
module: Interned<Module<alu_branch>>,
|
||||
}
|
||||
|
||||
impl AluBranch {
|
||||
pub fn new(config: PhantomConst<CpuConfig>, unit_index: usize) -> Self {
|
||||
pub fn new(config: &CpuConfig, unit_index: usize) -> Self {
|
||||
Self {
|
||||
config,
|
||||
config: config.intern(),
|
||||
module: alu_branch(config, unit_index),
|
||||
}
|
||||
}
|
||||
|
|
@ -592,7 +596,7 @@ impl AluBranch {
|
|||
impl UnitTrait for AluBranch {
|
||||
type Type = alu_branch;
|
||||
type ExtraOut = ();
|
||||
type MOp = AluBranchMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>;
|
||||
type MOp = AluBranchMOp<UnitOutRegNum<DynSize>, DynSize>;
|
||||
|
||||
fn ty(&self) -> Self::Type {
|
||||
self.module.io_ty()
|
||||
|
|
@ -612,7 +616,7 @@ impl UnitTrait for AluBranch {
|
|||
|
||||
fn extract_mop(
|
||||
&self,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<PhantomConst<CpuConfig>>, DynSize>>,
|
||||
mop: Expr<RenamedMOp<UnitOutRegNum<DynSize>, DynSize>>,
|
||||
) -> Expr<HdlOption<Self::MOp>> {
|
||||
UnitMOp::alu_branch_mop(mop)
|
||||
}
|
||||
|
|
@ -624,7 +628,7 @@ impl UnitTrait for AluBranch {
|
|||
fn unit_to_reg_alloc(
|
||||
&self,
|
||||
this: Expr<Self::Type>,
|
||||
) -> Expr<UnitToRegAlloc<PhantomConst<CpuConfig>, Self::MOp, Self::ExtraOut>> {
|
||||
) -> Expr<UnitToRegAlloc<Self::MOp, Self::ExtraOut, DynSize, DynSize, DynSize>> {
|
||||
this.unit_to_reg_alloc
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
config::{CpuConfig, CpuConfigUnitCount, PhantomConstCpuConfig},
|
||||
config::CpuConfig,
|
||||
instruction::{COMMON_MOP_SRC_LEN, MOpTrait, PRegNum, UnitNum, UnitOutRegNum},
|
||||
register::PRegValue,
|
||||
unit::{UnitCancelInput, UnitOutput, UnitOutputWrite},
|
||||
|
|
@ -15,11 +15,13 @@ use fayalite::{
|
|||
ty::StaticType,
|
||||
util::ready_valid::ReadyValid,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[hdl(no_static)]
|
||||
pub struct UnitForwardingInfo<C: PhantomConstGet<CpuConfig>> {
|
||||
pub unit_output_writes: ArrayType<HdlOption<UnitOutputWrite<C>>, CpuConfigUnitCount<C>>,
|
||||
pub unit_reg_frees: ArrayType<HdlOption<UnitOutRegNum<C>>, CpuConfigUnitCount<C>>,
|
||||
#[hdl]
|
||||
pub struct UnitForwardingInfo<UnitNumWidth: Size, OutRegNumWidth: Size, UnitCount: Size> {
|
||||
pub unit_output_writes: ArrayType<HdlOption<UnitOutputWrite<OutRegNumWidth>>, UnitCount>,
|
||||
pub unit_reg_frees: ArrayType<HdlOption<UnitOutRegNum<OutRegNumWidth>>, UnitCount>,
|
||||
pub _phantom: PhantomData<UnitNumWidth>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
|
|
@ -28,18 +30,26 @@ pub struct UnitInput<MOp: Type> {
|
|||
pub pc: UInt<64>,
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
pub struct UnitToRegAlloc<C: PhantomConstGet<CpuConfig>, MOp: Type, ExtraOut: Type> {
|
||||
#[hdl]
|
||||
pub struct UnitToRegAlloc<
|
||||
MOp: Type,
|
||||
ExtraOut: Type,
|
||||
UnitNumWidth: Size,
|
||||
OutRegNumWidth: Size,
|
||||
UnitCount: Size,
|
||||
> {
|
||||
#[hdl(flip)]
|
||||
pub unit_forwarding_info: UnitForwardingInfo<C>,
|
||||
pub unit_forwarding_info: UnitForwardingInfo<UnitNumWidth, OutRegNumWidth, UnitCount>,
|
||||
#[hdl(flip)]
|
||||
pub input: ReadyValid<UnitInput<MOp>>,
|
||||
#[hdl(flip)]
|
||||
pub cancel_input: HdlOption<UnitCancelInput<C>>,
|
||||
pub output: HdlOption<UnitOutput<C, ExtraOut>>,
|
||||
pub cancel_input: HdlOption<UnitCancelInput<OutRegNumWidth>>,
|
||||
pub output: HdlOption<UnitOutput<OutRegNumWidth, ExtraOut>>,
|
||||
}
|
||||
|
||||
impl<C: PhantomConstCpuConfig, MOp: Type, ExtraOut: Type> UnitToRegAlloc<C, MOp, ExtraOut> {
|
||||
impl<MOp: Type, ExtraOut: Type, UnitNumWidth: Size, OutRegNumWidth: Size, UnitCount: Size>
|
||||
UnitToRegAlloc<MOp, ExtraOut, UnitNumWidth, OutRegNumWidth, UnitCount>
|
||||
{
|
||||
pub fn mop_ty(self) -> MOp {
|
||||
self.input.data.HdlSome.mop
|
||||
}
|
||||
|
|
@ -48,20 +58,16 @@ impl<C: PhantomConstCpuConfig, MOp: Type, ExtraOut: Type> UnitToRegAlloc<C, MOp,
|
|||
}
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
pub struct ExecuteStart<
|
||||
C: PhantomConstGet<CpuConfig>,
|
||||
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<C>>,
|
||||
> {
|
||||
#[hdl]
|
||||
pub struct ExecuteStart<MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>>> {
|
||||
pub mop: MOp,
|
||||
pub pc: UInt<64>,
|
||||
pub src_values: Array<PRegValue, { COMMON_MOP_SRC_LEN }>,
|
||||
pub config: C,
|
||||
}
|
||||
|
||||
#[hdl(no_static)]
|
||||
pub struct ExecuteEnd<C: PhantomConstGet<CpuConfig>, ExtraOut> {
|
||||
pub unit_output: UnitOutput<C, ExtraOut>,
|
||||
#[hdl]
|
||||
pub struct ExecuteEnd<OutRegNumWidth: Size, ExtraOut> {
|
||||
pub unit_output: UnitOutput<OutRegNumWidth, ExtraOut>,
|
||||
}
|
||||
|
||||
#[hdl]
|
||||
|
|
@ -234,10 +240,10 @@ impl InFlightOpsSummary<DynSize> {
|
|||
|
||||
#[hdl_module]
|
||||
pub fn unit_base<
|
||||
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<PhantomConst<CpuConfig>>, SrcRegWidth = DynSize>,
|
||||
MOp: Type + MOpTrait<DestReg = UnitOutRegNum<DynSize>, SrcRegWidth = DynSize>,
|
||||
ExtraOut: Type,
|
||||
>(
|
||||
config: PhantomConst<CpuConfig>,
|
||||
config: &CpuConfig,
|
||||
unit_index: usize,
|
||||
mop_ty: MOp,
|
||||
extra_out_ty: ExtraOut,
|
||||
|
|
@ -245,18 +251,17 @@ pub fn unit_base<
|
|||
#[hdl]
|
||||
let cd: ClockDomain = m.input();
|
||||
#[hdl]
|
||||
let unit_to_reg_alloc: UnitToRegAlloc<PhantomConst<CpuConfig>, MOp, ExtraOut> =
|
||||
m.output(UnitToRegAlloc[config][mop_ty][extra_out_ty]);
|
||||
let unit_to_reg_alloc: UnitToRegAlloc<MOp, ExtraOut, DynSize, DynSize, DynSize> =
|
||||
m.output(config.unit_to_reg_alloc(mop_ty, extra_out_ty));
|
||||
#[hdl]
|
||||
let execute_start: ReadyValid<ExecuteStart<PhantomConst<CpuConfig>, MOp>> =
|
||||
m.output(ReadyValid[ExecuteStart[config][mop_ty]]);
|
||||
let execute_start: ReadyValid<ExecuteStart<MOp>> = m.output(ReadyValid[ExecuteStart[mop_ty]]);
|
||||
#[hdl]
|
||||
let execute_end: HdlOption<ExecuteEnd<PhantomConst<CpuConfig>, ExtraOut>> =
|
||||
m.input(HdlOption[ExecuteEnd[config][extra_out_ty]]);
|
||||
let execute_end: HdlOption<ExecuteEnd<DynSize, ExtraOut>> =
|
||||
m.input(HdlOption[ExecuteEnd[config.out_reg_num_width][extra_out_ty]]);
|
||||
|
||||
connect(execute_start.data, execute_start.ty().data.HdlNone());
|
||||
|
||||
let max_in_flight = config.get().unit_max_in_flight(unit_index).get();
|
||||
let max_in_flight = config.unit_max_in_flight(unit_index).get();
|
||||
let in_flight_op_ty = InFlightOp[mop_ty];
|
||||
#[hdl]
|
||||
let in_flight_ops = reg_builder()
|
||||
|
|
@ -274,15 +279,16 @@ pub fn unit_base<
|
|||
);
|
||||
|
||||
#[hdl]
|
||||
let UnitForwardingInfo::<_> {
|
||||
let UnitForwardingInfo::<_, _, _> {
|
||||
unit_output_writes,
|
||||
unit_reg_frees,
|
||||
_phantom: _,
|
||||
} = unit_to_reg_alloc.unit_forwarding_info;
|
||||
#[hdl]
|
||||
let read_src_regs = wire(mop_ty.src_regs_ty());
|
||||
connect(
|
||||
read_src_regs,
|
||||
repeat(PRegNum[config].const_zero().cast_to_bits(), ConstUsize),
|
||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
||||
);
|
||||
#[hdl]
|
||||
let read_src_values = wire();
|
||||
|
|
@ -291,7 +297,7 @@ pub fn unit_base<
|
|||
let input_src_regs = wire(mop_ty.src_regs_ty());
|
||||
connect(
|
||||
input_src_regs,
|
||||
repeat(PRegNum[config].const_zero().cast_to_bits(), ConstUsize),
|
||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
||||
);
|
||||
#[hdl]
|
||||
let input_src_regs_valid = wire();
|
||||
|
|
@ -303,7 +309,7 @@ pub fn unit_base<
|
|||
Bool,
|
||||
SourceLocation::caller(),
|
||||
);
|
||||
mem.depth(1 << config.get().out_reg_num_width);
|
||||
mem.depth(1 << config.out_reg_num_width);
|
||||
mem
|
||||
})
|
||||
.collect();
|
||||
|
|
@ -313,11 +319,11 @@ pub fn unit_base<
|
|||
PRegValue,
|
||||
SourceLocation::caller(),
|
||||
);
|
||||
unit_output_regs.depth(1 << config.get().out_reg_num_width);
|
||||
unit_output_regs.depth(1 << config.out_reg_num_width);
|
||||
|
||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||
let read_port = unit_output_regs.new_read_port();
|
||||
let p_reg_num = read_src_regs[src_index].cast_bits_to(PRegNum[config]);
|
||||
let p_reg_num = read_src_regs[src_index].cast_bits_to(config.p_reg_num());
|
||||
connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
|
||||
connect(read_port.en, false);
|
||||
connect(read_port.clk, cd.clk);
|
||||
|
|
@ -330,7 +336,7 @@ pub fn unit_base<
|
|||
|
||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||
let read_port = unit_output_regs_valid[unit_index].new_read_port();
|
||||
let p_reg_num = input_src_regs[src_index].cast_bits_to(PRegNum[config]);
|
||||
let p_reg_num = input_src_regs[src_index].cast_bits_to(config.p_reg_num());
|
||||
connect_any(read_port.addr, p_reg_num.unit_out_reg.value);
|
||||
connect(read_port.en, false);
|
||||
connect(read_port.clk, cd.clk);
|
||||
|
|
@ -361,8 +367,8 @@ pub fn unit_base<
|
|||
connect_any(ready_write_port.addr, unit_output_write.which.value);
|
||||
connect(ready_write_port.en, true);
|
||||
let p_reg_num = #[hdl]
|
||||
PRegNum::<_> {
|
||||
unit_num: UnitNum[config].from_index(unit_index),
|
||||
PRegNum::<_, _> {
|
||||
unit_num: config.unit_num().from_index(unit_index),
|
||||
unit_out_reg: unit_output_write.which,
|
||||
};
|
||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||
|
|
@ -393,11 +399,10 @@ pub fn unit_base<
|
|||
execute_start.data,
|
||||
HdlSome(
|
||||
#[hdl]
|
||||
ExecuteStart::<_, _> {
|
||||
ExecuteStart::<_> {
|
||||
mop: in_flight_op.mop,
|
||||
pc: in_flight_op.pc,
|
||||
src_values: read_src_values,
|
||||
config,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
@ -420,7 +425,7 @@ pub fn unit_base<
|
|||
let input_mop_src_regs = wire(mop_ty.src_regs_ty());
|
||||
connect(
|
||||
input_mop_src_regs,
|
||||
repeat(PRegNum[config].const_zero().cast_to_bits(), ConstUsize),
|
||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
||||
);
|
||||
MOp::connect_src_regs(mop, input_mop_src_regs);
|
||||
let src_ready_flags = wire_with_loc(
|
||||
|
|
@ -492,7 +497,7 @@ pub fn unit_base<
|
|||
);
|
||||
connect(
|
||||
src_regs,
|
||||
repeat(PRegNum[config].const_zero().cast_to_bits(), ConstUsize),
|
||||
repeat(config.p_reg_num().const_zero().cast_to_bits(), ConstUsize),
|
||||
);
|
||||
MOp::connect_src_regs(mop, src_regs);
|
||||
|
||||
|
|
@ -516,8 +521,8 @@ pub fn unit_base<
|
|||
value: _,
|
||||
} = unit_output_write;
|
||||
let p_reg_num = #[hdl]
|
||||
PRegNum::<_> {
|
||||
unit_num: UnitNum[config].from_index(unit_index),
|
||||
PRegNum::<_, _> {
|
||||
unit_num: config.unit_num().from_index(unit_index),
|
||||
unit_out_reg,
|
||||
};
|
||||
for src_index in 0..COMMON_MOP_SRC_LEN {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue