forked from libre-chip/cpu
		
	WIP: adding micro ops
This commit is contained in:
		
							parent
							
								
									0f4f067996
								
							
						
					
					
						commit
						4c3dd128a3
					
				
					 5 changed files with 149 additions and 39 deletions
				
			
		
							
								
								
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -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#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#1a2149b0406fd29fa2032532dfba3b371cf74a26" | ||||
| 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#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#1a2149b0406fd29fa2032532dfba3b371cf74a26" | ||||
| 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#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#1a2149b0406fd29fa2032532dfba3b371cf74a26" | ||||
| 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#bf907c38721ebc804d6aaf0bf5ed6798d8604dab" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#1a2149b0406fd29fa2032532dfba3b371cf74a26" | ||||
| dependencies = [ | ||||
|  "indexmap", | ||||
|  "prettyplease", | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| use fayalite::prelude::*; | ||||
| use crate::config::CpuConfig; | ||||
| use fayalite::prelude::*; | ||||
| use std::marker::PhantomData; | ||||
| 
 | ||||
| pub mod power_isa; | ||||
| 
 | ||||
|  | @ -9,7 +10,7 @@ macro_rules! all_units { | |||
|         #[unit_kind = $UnitKind:ident] | ||||
|         #[hdl] | ||||
|         $(#[$enum_meta:meta])* | ||||
|         $vis:vis enum $UnitMOpEnum:ident { | ||||
|         $vis:vis enum $UnitMOpEnum:ident<$RegWidth:ident: Size> { | ||||
|             $( | ||||
|                 $(#[$variant_meta:meta])* | ||||
|                 $Unit:ident($Op:ty), | ||||
|  | @ -46,21 +47,21 @@ macro_rules! all_units { | |||
| 
 | ||||
|         #[hdl] | ||||
|         $(#[$enum_meta])* | ||||
|         $vis enum $UnitMOpEnum { | ||||
|         $vis enum $UnitMOpEnum<$RegWidth: Size> { | ||||
|             $( | ||||
|                 $(#[$variant_meta])* | ||||
|                 $Unit($Op), | ||||
|             )* | ||||
|         } | ||||
| 
 | ||||
|         impl $UnitMOpEnum { | ||||
|         impl<$RegWidth: Size> $UnitMOpEnum<$RegWidth> { | ||||
|             #[hdl] | ||||
|             $vis fn kind(expr: impl ToExpr<Type = Self>) -> Expr<$HdlUnitKind> { | ||||
|                 #[hdl] | ||||
|                 let unit_kind = wire(); | ||||
|                 #[hdl] | ||||
|                 match expr { | ||||
|                     $($UnitMOpEnum::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* | ||||
|                     $($UnitMOpEnum::<$RegWidth>::$Unit(_) => connect(unit_kind, $HdlUnitKind.$Unit()),)* | ||||
|                 } | ||||
|                 unit_kind | ||||
|             } | ||||
|  | @ -87,32 +88,152 @@ all_units! { | |||
|     #[hdl_unit_kind = HdlUnitKind] | ||||
|     #[unit_kind = UnitKind] | ||||
|     #[hdl] | ||||
|     pub enum UnitMOp { | ||||
|         AluBranch(AluBranchMOp), | ||||
|         L2RegisterFile(L2RegisterFileMOp), | ||||
|         LoadStore(LoadStoreMOp), | ||||
|     pub enum UnitMOp<RegWidth: Size> { | ||||
|         AluBranch(AluBranchMOp<RegWidth>), | ||||
|         L2RegisterFile(L2RegisterFileMOp<RegWidth>), | ||||
|         LoadStore(LoadStoreMOp<RegWidth>), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub enum AluBranchMOp { | ||||
|     Add64, | ||||
|     Sub64, | ||||
|     And64, | ||||
|     Or64, | ||||
|     Xor64, | ||||
| 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<PrefixPad: KnownSize, RegWidth: Size, SrcCount: KnownSize> { | ||||
|     pub prefix_pad: UIntType<PrefixPad>, | ||||
|     pub dest: UIntType<RegWidth>, | ||||
|     pub src: Array<UIntType<RegWidth>, { COMMON_MOP_SRC_REG_COUNT }>, | ||||
|     pub other: UInt<{ COMMON_MOP_OTHER_WIDTH }>, | ||||
|     pub _phantom: PhantomData<SrcCount>, | ||||
| } | ||||
| 
 | ||||
| impl<PrefixPad: KnownSize, RegWidth: Size, SrcCount: KnownSize> | ||||
|     CommonMOp<PrefixPad, RegWidth, SrcCount> | ||||
| { | ||||
|     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<Type = Self>) -> Expr<SInt> { | ||||
|         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<Type = Self>, imm: impl ToExpr<Type = SInt>) { | ||||
|         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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub enum L2RegisterFileMOp { | ||||
|     Read, | ||||
|     Write, | ||||
| pub struct AluCommonMOp<RegWidth: Size, SrcCount: KnownSize> { | ||||
|     pub common: CommonMOp<ConstUsize<0>, RegWidth, SrcCount>, | ||||
|     pub output_integer_mode: OutputIntegerMode, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub enum LoadStoreMOp { | ||||
|     Load, | ||||
|     Store, | ||||
| pub struct AddSubMOp<RegWidth: Size, SrcCount: KnownSize> { | ||||
|     pub alu_common: AluCommonMOp<RegWidth, SrcCount>, | ||||
|     pub invert_src0: Bool, | ||||
|     pub invert_carry_in: Bool, | ||||
|     pub invert_carry_out: Bool, | ||||
|     pub add_pc: Bool, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub struct LogicalMOp<RegWidth: Size> { | ||||
|     pub alu_common: AluCommonMOp<RegWidth, ConstUsize<2>>, | ||||
|     pub lut: UInt<4>, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub struct BranchMOp<RegWidth: Size> { | ||||
|     pub alu_common: AluCommonMOp<RegWidth, ConstUsize<2>>, | ||||
|     pub lut: UInt<4>, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub enum AluBranchMOp<RegWidth: Size> { | ||||
|     AddSub(AddSubMOp<RegWidth, ConstUsize<3>>), | ||||
|     AddSubI(AddSubMOp<RegWidth, ConstUsize<2>>), | ||||
|     Logical(LogicalMOp<RegWidth>), | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub struct ReadL2RegMOp<RegWidth: Size> { | ||||
|     pub common: CommonMOp<ConstUsize<1>, RegWidth, ConstUsize<0>>, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub struct WriteL2RegMOp<RegWidth: Size> { | ||||
|     pub common: CommonMOp<ConstUsize<1>, RegWidth, ConstUsize<1>>, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub enum L2RegisterFileMOp<RegWidth: Size> { | ||||
|     ReadL2Reg(ReadL2RegMOp<RegWidth>), | ||||
|     WriteL2Reg(WriteL2RegMOp<RegWidth>), | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub struct LoadStoreCommonMOp<RegWidth: Size, SrcCount: KnownSize> { | ||||
|     pub common: CommonMOp<ConstUsize<1>, RegWidth, SrcCount>, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub struct LoadMOp<RegWidth: Size> { | ||||
|     pub load_store_common: LoadStoreCommonMOp<RegWidth, ConstUsize<1>>, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub struct StoreMOp<RegWidth: Size> { | ||||
|     pub load_store_common: LoadStoreCommonMOp<RegWidth, ConstUsize<2>>, | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
| pub enum LoadStoreMOp<RegWidth: Size> { | ||||
|     Load(CommonMOp<ConstUsize<1>, RegWidth, ConstUsize<0>>), | ||||
|     Store(CommonMOp<ConstUsize<1>, RegWidth, ConstUsize<1>>), | ||||
| } | ||||
| 
 | ||||
| #[hdl] | ||||
|  | @ -142,14 +263,3 @@ pub struct PRegNum<UnitNumWidth: Size, OutRegNumWidth: Size> { | |||
| 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>, | ||||
| } | ||||
|  |  | |||
|  | @ -1,2 +1,2 @@ | |||
| pub mod instruction; | ||||
| pub mod config; | ||||
| pub mod instruction; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue