diff --git a/Cargo.lock b/Cargo.lock index 18e40cd..1247f56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -279,7 +279,7 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fayalite" version = "0.2.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d0229fbcfb11666b5abf7ae487ffe335866f9326" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" dependencies = [ "bitvec", "blake3", @@ -300,7 +300,7 @@ dependencies = [ [[package]] name = "fayalite-proc-macros" version = "0.2.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d0229fbcfb11666b5abf7ae487ffe335866f9326" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" dependencies = [ "fayalite-proc-macros-impl", ] @@ -308,7 +308,7 @@ dependencies = [ [[package]] name = "fayalite-proc-macros-impl" version = "0.2.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d0229fbcfb11666b5abf7ae487ffe335866f9326" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" dependencies = [ "base16ct", "num-bigint", @@ -323,7 +323,7 @@ dependencies = [ [[package]] name = "fayalite-visit-gen" version = "0.2.0" -source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d0229fbcfb11666b5abf7ae487ffe335866f9326" +source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" dependencies = [ "indexmap", "prettyplease", diff --git a/crates/cpu/src/config.rs b/crates/cpu/src/config.rs index 61907f4..03d93df 100644 --- a/crates/cpu/src/config.rs +++ b/crates/cpu/src/config.rs @@ -11,4 +11,4 @@ impl CpuConfig { pub fn unit_num(&self) -> UnitNum { UnitNum[UInt::range(0..self.units.len()).width()] } -} +} \ No newline at end of file diff --git a/crates/cpu/src/instruction.rs b/crates/cpu/src/instruction.rs index 8d3144b..ff4ebcb 100644 --- a/crates/cpu/src/instruction.rs +++ b/crates/cpu/src/instruction.rs @@ -1,6 +1,5 @@ -use crate::config::CpuConfig; use fayalite::prelude::*; -use std::marker::PhantomData; +use crate::config::CpuConfig; pub mod power_isa; @@ -10,7 +9,7 @@ macro_rules! all_units { #[unit_kind = $UnitKind:ident] #[hdl] $(#[$enum_meta:meta])* - $vis:vis enum $UnitMOpEnum:ident<$RegWidth:ident: Size> { + $vis:vis enum $UnitMOpEnum:ident { $( $(#[$variant_meta:meta])* $Unit:ident($Op:ty), @@ -47,21 +46,21 @@ macro_rules! all_units { #[hdl] $(#[$enum_meta])* - $vis enum $UnitMOpEnum<$RegWidth: Size> { + $vis enum $UnitMOpEnum { $( $(#[$variant_meta])* $Unit($Op), )* } - impl<$RegWidth: Size> $UnitMOpEnum<$RegWidth> { + impl $UnitMOpEnum { #[hdl] $vis fn kind(expr: impl ToExpr) -> Expr<$HdlUnitKind> { #[hdl] let unit_kind = wire(); #[hdl] match expr { - $($UnitMOpEnum::<$RegWidth>::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* + $($UnitMOpEnum::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* } unit_kind } @@ -88,152 +87,32 @@ all_units! { #[hdl_unit_kind = HdlUnitKind] #[unit_kind = UnitKind] #[hdl] - pub enum UnitMOp { - AluBranch(AluBranchMOp), - L2RegisterFile(L2RegisterFileMOp), - LoadStore(LoadStoreMOp), + pub enum UnitMOp { + AluBranch(AluBranchMOp), + L2RegisterFile(L2RegisterFileMOp), + LoadStore(LoadStoreMOp), } } #[hdl] -pub enum OutputIntegerMode { - Full64, - DupLow32, - ZeroExt32, - SignExt32, - ZeroExt16, - SignExt16, - ZeroExt8, - SignExt8, -} - -pub const MOP_IMM_WIDTH: usize = 34; -pub const MOP_MIN_REG_WIDTH: usize = 8; -pub const COMMON_MOP_OTHER_WIDTH: usize = - MOP_IMM_WIDTH - (COMMON_MOP_SRC_REG_COUNT - COMMON_MOP_IMM_SRC_REG_COUNT) * MOP_MIN_REG_WIDTH; -pub const COMMON_MOP_SRC_REG_COUNT: usize = 3; -pub const COMMON_MOP_IMM_SRC_REG_COUNT: usize = 2; - -#[hdl] -pub struct CommonMOp { - pub prefix_pad: UIntType, - pub dest: UIntType, - pub src: Array, { COMMON_MOP_SRC_REG_COUNT }>, - pub other: UInt<{ COMMON_MOP_OTHER_WIDTH }>, - pub _phantom: PhantomData, -} - -impl - CommonMOp -{ - pub fn imm_ty(self) -> SInt { - assert!(self.src.element().width() >= MOP_MIN_REG_WIDTH); - assert!(SrcCount::VALUE <= COMMON_MOP_SRC_REG_COUNT); - SInt[(COMMON_MOP_SRC_REG_COUNT - SrcCount::VALUE) * MOP_MIN_REG_WIDTH - + COMMON_MOP_OTHER_WIDTH] - } - #[hdl] - pub fn imm(expr: impl ToExpr) -> Expr { - let expr = expr.to_expr(); - assert!(Expr::ty(expr).src.element().width() >= MOP_MIN_REG_WIDTH); - let mut acc = expr.other[..COMMON_MOP_OTHER_WIDTH - 1]; - for i in SrcCount::VALUE..COMMON_MOP_SRC_REG_COUNT { - acc = (acc, expr.src[i][..MOP_MIN_REG_WIDTH]).cast_to_bits(); - } - acc = (acc, expr.other[COMMON_MOP_OTHER_WIDTH - 1]).cast_to_bits(); - #[hdl] - let imm = wire(Expr::ty(expr).imm_ty()); - debug_assert_eq!(Expr::ty(acc).width(), Expr::ty(imm).width()); - connect(imm, acc.cast_to(Expr::ty(imm))); - imm - } - #[hdl] - pub fn connect_to_imm(expr: impl ToExpr, imm: impl ToExpr) { - let expr = expr.to_expr(); - let imm = imm.to_expr(); - let imm_ty = Expr::ty(expr).imm_ty(); - assert_eq!(Expr::ty(imm), imm_ty); - let mut pos = COMMON_MOP_OTHER_WIDTH - 1; - connect_any( - expr.other, - (imm[..pos], imm[imm_ty.width() - 1]).cast_to_bits(), - ); - for i in SrcCount::VALUE..COMMON_MOP_SRC_REG_COUNT { - connect_any(expr.src[i], imm[pos..pos + MOP_MIN_REG_WIDTH]); - pos += MOP_MIN_REG_WIDTH; - } - } +pub enum AluBranchMOp { + Add64, + Sub64, + And64, + Or64, + Xor64, } #[hdl] -pub struct AluCommonMOp { - pub common: CommonMOp, RegWidth, SrcCount>, - pub output_integer_mode: OutputIntegerMode, +pub enum L2RegisterFileMOp { + Read, + Write, } #[hdl] -pub struct AddSubMOp { - pub alu_common: AluCommonMOp, - pub invert_src0: Bool, - pub invert_carry_in: Bool, - pub invert_carry_out: Bool, - pub add_pc: Bool, -} - -#[hdl] -pub struct LogicalMOp { - pub alu_common: AluCommonMOp>, - pub lut: UInt<4>, -} - -#[hdl] -pub struct BranchMOp { - pub alu_common: AluCommonMOp>, - pub lut: UInt<4>, -} - -#[hdl] -pub enum AluBranchMOp { - AddSub(AddSubMOp>), - AddSubI(AddSubMOp>), - Logical(LogicalMOp), -} - -#[hdl] -pub struct ReadL2RegMOp { - pub common: CommonMOp, RegWidth, ConstUsize<0>>, -} - -#[hdl] -pub struct WriteL2RegMOp { - pub common: CommonMOp, RegWidth, ConstUsize<1>>, -} - -#[hdl] -pub enum L2RegisterFileMOp { - ReadL2Reg(ReadL2RegMOp), - WriteL2Reg(WriteL2RegMOp), -} - -#[hdl] -pub struct LoadStoreCommonMOp { - pub common: CommonMOp, RegWidth, SrcCount>, -} - -#[hdl] -pub struct LoadMOp { - pub load_store_common: LoadStoreCommonMOp>, -} - -#[hdl] -pub struct StoreMOp { - pub load_store_common: LoadStoreCommonMOp>, -} - -#[hdl] -pub enum LoadStoreMOp { - Load(CommonMOp, RegWidth, ConstUsize<0>>), - Store(CommonMOp, RegWidth, ConstUsize<1>>), +pub enum LoadStoreMOp { + Load, + Store, } #[hdl] @@ -263,3 +142,14 @@ pub struct PRegNum { pub struct MOpRegNum { pub value: UInt<8>, } + +#[hdl] +/// µOp -- a micro-operation +#[doc(alias = "UOp")] // help you find it in the docs if you mis-spell it +#[doc(alias = "\u{B5}Op")] // micro sign +#[doc(alias = "\u{39C}Op")] // greek capital letter mu +#[doc(alias = "\u{3BC}Op")] // greek small letter mu +pub struct MOp { + pub op: UnitMOp, + pub value: UInt<8>, +} diff --git a/crates/cpu/src/instruction/power_isa.rs b/crates/cpu/src/instruction/power_isa.rs index a242303..89dc832 100644 --- a/crates/cpu/src/instruction/power_isa.rs +++ b/crates/cpu/src/instruction/power_isa.rs @@ -19,4 +19,4 @@ pub struct PowerIsaCrFieldNum { pub struct PowerIsaCrBitNum { pub cr_field: PowerIsaCrFieldNum, pub bit_in_field: UInt<2>, -} +} \ No newline at end of file diff --git a/crates/cpu/src/lib.rs b/crates/cpu/src/lib.rs index eab7c3e..1ff8b46 100644 --- a/crates/cpu/src/lib.rs +++ b/crates/cpu/src/lib.rs @@ -1,2 +1,2 @@ -pub mod config; pub mod instruction; +pub mod config; \ No newline at end of file