Compare commits
	
		
			No commits in common. "1084278f34fa202e86d7d6e5c9834c698bcc10c6" and "294e9798480aa637221192345650ef8c5e93b44d" have entirely different histories.
		
	
	
		
			1084278f34
			...
			294e979848
		
	
		
					 5 changed files with 8383 additions and 10864 deletions
				
			
		
							
								
								
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -300,7 +300,7 @@ checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" | |||
| [[package]] | ||||
| name = "fayalite" | ||||
| version = "0.3.0" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#86a1bb46be4690e854470cf4a1a6e90c92268391" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d4ea8260512e54c5187c1c59bd9bac47a319f86d" | ||||
| dependencies = [ | ||||
|  "bitvec", | ||||
|  "blake3", | ||||
|  | @ -325,7 +325,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "fayalite-proc-macros" | ||||
| version = "0.3.0" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#86a1bb46be4690e854470cf4a1a6e90c92268391" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d4ea8260512e54c5187c1c59bd9bac47a319f86d" | ||||
| dependencies = [ | ||||
|  "fayalite-proc-macros-impl", | ||||
| ] | ||||
|  | @ -333,7 +333,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "fayalite-proc-macros-impl" | ||||
| version = "0.3.0" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#86a1bb46be4690e854470cf4a1a6e90c92268391" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d4ea8260512e54c5187c1c59bd9bac47a319f86d" | ||||
| dependencies = [ | ||||
|  "base16ct", | ||||
|  "num-bigint", | ||||
|  | @ -348,7 +348,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "fayalite-visit-gen" | ||||
| version = "0.3.0" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#86a1bb46be4690e854470cf4a1a6e90c92268391" | ||||
| source = "git+https://git.libre-chip.org/libre-chip/fayalite.git?branch=master#d4ea8260512e54c5187c1c59bd9bac47a319f86d" | ||||
| dependencies = [ | ||||
|  "indexmap", | ||||
|  "prettyplease", | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| // See Notices.txt for copyright information
 | ||||
| use crate::{unit::UnitMOp, util::range_u32_len}; | ||||
| use fayalite::{expr::ops::ArrayLiteral, intern::Interned, prelude::*}; | ||||
| use std::{fmt, marker::PhantomData, ops::Range}; | ||||
| use std::{marker::PhantomData, ops::Range}; | ||||
| 
 | ||||
| pub mod power_isa; | ||||
| 
 | ||||
|  | @ -668,29 +668,6 @@ pub struct MOpDestReg { | |||
|     pub flag_regs: Array<HdlOption<()>, { range_u32_len(&MOpRegNum::FLAG_REG_NUMS) }>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] | ||||
| pub enum RenameTableName { | ||||
|     /// the large rename table for normal registers (has less read/write ports)
 | ||||
|     Normal, | ||||
|     /// a special small rename table (for flags and stuff, since it has more read/write ports)
 | ||||
|     Special, | ||||
| } | ||||
| 
 | ||||
| impl RenameTableName { | ||||
|     pub const fn reg_range(self) -> std::ops::Range<u32> { | ||||
|         match self { | ||||
|             Self::Normal => MOpRegNum::NORMAL_REG_NUMS, | ||||
|             Self::Special => MOpRegNum::SPECIAL_REG_NUMS, | ||||
|         } | ||||
|     } | ||||
|     pub const fn as_str(self) -> &'static str { | ||||
|         match self { | ||||
|             Self::Normal => "rename_table_normal", | ||||
|             Self::Special => "rename_table_special", | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] | ||||
| pub enum MOpDestRegKind { | ||||
|     NormalReg { | ||||
|  | @ -705,69 +682,6 @@ pub enum MOpDestRegKind { | |||
|     }, | ||||
| } | ||||
| 
 | ||||
| #[derive(Copy, Clone, Debug)] | ||||
| pub struct MOpDestRegName { | ||||
|     base_name: &'static str, | ||||
|     index: usize, | ||||
|     reg_num: Option<u32>, | ||||
| } | ||||
| 
 | ||||
| impl fmt::Display for MOpDestRegName { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|         let Self { | ||||
|             base_name, | ||||
|             index, | ||||
|             reg_num, | ||||
|         } = self; | ||||
|         write!(f, "{base_name}{index}")?; | ||||
|         if let Some(reg_num) = reg_num { | ||||
|             write!(f, "_r{reg_num:02X}")?; | ||||
|         } | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl MOpDestRegKind { | ||||
|     pub const fn reg_range(self) -> std::ops::Range<u32> { | ||||
|         match self { | ||||
|             Self::NormalReg { .. } => MOpRegNum::NORMAL_REG_NUMS, | ||||
|             Self::FlagReg { .. } => MOpRegNum::FLAG_REG_NUMS, | ||||
|         } | ||||
|     } | ||||
|     pub const fn rename_table_names(self) -> &'static [RenameTableName] { | ||||
|         match self { | ||||
|             Self::NormalReg { .. } => &[RenameTableName::Normal, RenameTableName::Special], | ||||
|             Self::FlagReg { .. } => &[RenameTableName::Special], | ||||
|         } | ||||
|     } | ||||
|     pub fn fixed_reg_num(self) -> Option<u32> { | ||||
|         match self { | ||||
|             Self::NormalReg { dest_reg_index: _ } => None, | ||||
|             Self::FlagReg { | ||||
|                 flag_reg_index: _, | ||||
|                 reg_num, | ||||
|             } => Some(reg_num), | ||||
|         } | ||||
|     } | ||||
|     pub fn reg_name(self) -> MOpDestRegName { | ||||
|         match self { | ||||
|             Self::NormalReg { dest_reg_index } => MOpDestRegName { | ||||
|                 base_name: "dest", | ||||
|                 index: dest_reg_index, | ||||
|                 reg_num: None, | ||||
|             }, | ||||
|             Self::FlagReg { | ||||
|                 flag_reg_index, | ||||
|                 reg_num, | ||||
|             } => MOpDestRegName { | ||||
|                 base_name: "flag", | ||||
|                 index: flag_reg_index, | ||||
|                 reg_num: Some(reg_num), | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl MOpDestReg { | ||||
|     pub const NORMAL_REG_COUNT: usize = 2; | ||||
|     pub const REG_COUNT: usize = Self::NORMAL_REG_COUNT + range_u32_len(&MOpRegNum::FLAG_REG_NUMS); | ||||
|  |  | |||
|  | @ -3,22 +3,17 @@ | |||
| use crate::{ | ||||
|     config::CpuConfig, | ||||
|     instruction::{ | ||||
|         MOp, MOpDestReg, MOpRegNum, MOpTrait, PRegNum, RenameTableName, UnitOutRegNum, | ||||
|         COMMON_MOP_SRC_LEN, | ||||
|         MOp, MOpDestReg, MOpRegNum, MOpTrait, PRegNum, UnitOutRegNum, COMMON_MOP_SRC_LEN, | ||||
|     }, | ||||
|     unit::{TrapData, UnitTrait}, | ||||
|     util::tree_reduce::tree_reduce_with_state, | ||||
| }; | ||||
| use fayalite::{ | ||||
|     memory::{splat_mask, WriteStruct}, | ||||
|     module::{instance_with_loc, memory_with_loc, wire_with_loc}, | ||||
|     module::{instance_with_loc, wire_with_loc}, | ||||
|     prelude::*, | ||||
|     util::ready_valid::ReadyValid, | ||||
| }; | ||||
| use std::{ | ||||
|     collections::{BTreeMap, VecDeque}, | ||||
|     num::NonZeroUsize, | ||||
| }; | ||||
| use std::num::NonZeroUsize; | ||||
| 
 | ||||
| pub mod unit_free_regs_tracker; | ||||
| 
 | ||||
|  | @ -60,23 +55,15 @@ pub fn reg_alloc(config: &CpuConfig) { | |||
|     ); | ||||
|     // TODO: finish
 | ||||
| 
 | ||||
|     let mut rename_table_mems = BTreeMap::<RenameTableName, MemBuilder<_>>::new(); | ||||
|     // the large rename table for normal registers (has less read/write ports)
 | ||||
|     #[hdl] | ||||
|     let mut rename_table_normal_mem = memory(config.p_reg_num()); | ||||
|     rename_table_normal_mem.depth(MOpRegNum::NORMAL_REG_NUMS.len()); | ||||
| 
 | ||||
|     for reg_kind in MOpDestReg::REG_KINDS { | ||||
|         for &rename_table_name in reg_kind.rename_table_names() { | ||||
|             rename_table_mems | ||||
|                 .entry(rename_table_name) | ||||
|                 .or_insert_with(|| { | ||||
|                     let mut mem = memory_with_loc( | ||||
|                         &format!("{}_mem", rename_table_name.as_str()), | ||||
|                         config.p_reg_num(), | ||||
|                         SourceLocation::caller(), | ||||
|                     ); | ||||
|                     mem.depth(rename_table_name.reg_range().len()); | ||||
|                     mem | ||||
|                 }); | ||||
|         } | ||||
|     } | ||||
|     // a special small rename table (for flags and stuff, since it has more read/write ports)
 | ||||
|     #[hdl] | ||||
|     let mut rename_table_special_mem = memory(config.p_reg_num()); | ||||
|     rename_table_special_mem.depth(MOpRegNum::SPECIAL_REG_NUMS.len()); | ||||
| 
 | ||||
|     #[hdl] | ||||
|     let available_units = | ||||
|  | @ -105,28 +92,29 @@ pub fn reg_alloc(config: &CpuConfig) { | |||
|         struct RenameTableReadPort<T> { | ||||
|             addr: MOpRegNum, | ||||
|             #[hdl(flip)] | ||||
|             data: T, | ||||
|             data: HdlOption<T>, | ||||
|         } | ||||
|         let rename_table_read_ports: [_; COMMON_MOP_SRC_LEN] = std::array::from_fn(|src_index| { | ||||
|             let wire = wire_with_loc( | ||||
|                 &format!("rename_{fetch_index}_src_{src_index}"), | ||||
|                 SourceLocation::caller(), | ||||
|                 RenameTableReadPort[config.p_reg_num()], | ||||
|             ); | ||||
|             connect(wire.addr, MOpRegNum::const_zero()); | ||||
|             connect(wire.data, config.p_reg_num().const_zero()); | ||||
|             for (&rename_table_name, mem) in &mut rename_table_mems { | ||||
|                 let table_name = rename_table_name.as_str(); | ||||
|         let make_rename_table_read_port = | ||||
|             |mem: &mut MemBuilder<_>, | ||||
|              reg_range: std::ops::Range<u32>, | ||||
|              src_index: usize, | ||||
|              table_name: &str| { | ||||
|                 let read_port = mem.new_read_port(); | ||||
|                 connect(read_port.clk, cd.clk); | ||||
|                 connect_any(read_port.addr, 0u8); | ||||
|                 connect(read_port.en, false); | ||||
|                 let reg_range = rename_table_name.reg_range(); | ||||
|                 let wire = wire_with_loc( | ||||
|                     &format!("{table_name}_{fetch_index}_src_{src_index}"), | ||||
|                     SourceLocation::caller(), | ||||
|                     RenameTableReadPort[config.p_reg_num()], | ||||
|                 ); | ||||
|                 connect(wire.addr, MOpRegNum::const_zero()); | ||||
|                 connect(wire.data, Expr::ty(wire.data).HdlNone()); | ||||
|                 #[hdl] | ||||
|                 if wire.addr.value.cmp_ge(reg_range.start) & wire.addr.value.cmp_lt(reg_range.end) { | ||||
|                     connect_any(read_port.addr, wire.addr.value - reg_range.start); | ||||
|                     connect(read_port.en, true); | ||||
|                     connect(wire.data, read_port.data); | ||||
|                     connect(wire.data, HdlSome(read_port.data)); | ||||
|                     for prev_fetch_index in 0..fetch_index { | ||||
|                         #[hdl] | ||||
|                         if let HdlSome(decoded_insn) = | ||||
|  | @ -137,55 +125,36 @@ pub fn reg_alloc(config: &CpuConfig) { | |||
|                                 renamed_mops_out_reg[prev_fetch_index] | ||||
|                             { | ||||
|                                 let dest_reg = MOpTrait::dest_reg(decoded_insn.mop); | ||||
|                                 for (dest_reg, reg_kind) in MOpDestReg::regs(dest_reg) | ||||
|                                     .into_iter() | ||||
|                                     .zip(MOpDestReg::REG_KINDS) | ||||
|                                 { | ||||
|                                     if reg_kind.rename_table_names().contains(&rename_table_name) { | ||||
|                                         #[hdl] | ||||
|                                         if dest_reg.value.cmp_eq(wire.addr.value) { | ||||
|                                             connect(wire.data, renamed_mop_out_reg); | ||||
|                                         } | ||||
|                                 for dest_reg in MOpDestReg::regs(dest_reg) { | ||||
|                                     #[hdl] | ||||
|                                     if dest_reg.value.cmp_eq(wire.addr.value) { | ||||
|                                         connect(wire.data, HdlSome(renamed_mop_out_reg)); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             wire | ||||
|         }); | ||||
|         let mut rename_table_write_ports = BTreeMap::<RenameTableName, VecDeque<_>>::new(); | ||||
|         for reg_kind in MOpDestReg::REG_KINDS { | ||||
|             for &rename_table_name in reg_kind.rename_table_names() { | ||||
|                 let mem = rename_table_mems | ||||
|                     .get_mut(&rename_table_name) | ||||
|                     .expect("already added all RenameTableName values"); | ||||
|                 let write_ports = rename_table_write_ports | ||||
|                     .entry(rename_table_name) | ||||
|                     .or_default(); | ||||
|                 let write_port_ = mem.new_write_port(); | ||||
|                 let table_name = rename_table_name.as_str(); | ||||
|                 let write_port = wire_with_loc( | ||||
|                     &format!("{table_name}_{fetch_index}_{}", reg_kind.reg_name()), | ||||
|                     SourceLocation::caller(), | ||||
|                     Expr::ty(write_port_), | ||||
|                 ); | ||||
|                 connect(write_port_, write_port); | ||||
|                 write_ports.push_back(write_port); | ||||
|                 connect_any( | ||||
|                     write_port, | ||||
|                     #[hdl] | ||||
|                     WriteStruct::<_, _> { | ||||
|                         addr: 0_hdl_u0, | ||||
|                         en: false, | ||||
|                         clk: cd.clk, | ||||
|                         data: Expr::ty(write_port.data).uninit(), | ||||
|                         mask: splat_mask(config.p_reg_num(), true.to_expr()), | ||||
|                     }, | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|                 wire | ||||
|             }; | ||||
|         let rename_table_normal_read_ports: [_; COMMON_MOP_SRC_LEN] = | ||||
|             std::array::from_fn(|src_index| { | ||||
|                 make_rename_table_read_port( | ||||
|                     &mut rename_table_normal_mem, | ||||
|                     MOpRegNum::NORMAL_REG_NUMS, | ||||
|                     src_index, | ||||
|                     "rename_table_normal", | ||||
|                 ) | ||||
|             }); | ||||
|         let rename_table_special_read_ports: [_; COMMON_MOP_SRC_LEN] = | ||||
|             std::array::from_fn(|src_index| { | ||||
|                 make_rename_table_read_port( | ||||
|                     &mut rename_table_special_mem, | ||||
|                     MOpRegNum::FLAG_REG_NUMS, | ||||
|                     src_index, | ||||
|                     "rename_table_special", | ||||
|                 ) | ||||
|             }); | ||||
|         #[hdl] | ||||
|         if let HdlSome(decoded_insn) = fetch_decode_interface.decoded_insns[fetch_index].data { | ||||
|             connect( | ||||
|  | @ -202,41 +171,31 @@ pub fn reg_alloc(config: &CpuConfig) { | |||
|                         renamed_mop_out_reg.unit_out_reg, | ||||
|                         config.p_reg_num_width(), | ||||
|                         &mut |src_reg, src_index| { | ||||
|                             connect( | ||||
|                                 rename_table_read_ports[src_index].addr, | ||||
|                                 #[hdl] | ||||
|                                 MOpRegNum { value: src_reg }, | ||||
|                             let src_reg = #[hdl] | ||||
|                             MOpRegNum { value: src_reg }; | ||||
|                             let renamed_src_reg = wire_with_loc( | ||||
|                                 &format!("renamed_src_reg_{fetch_index}_{src_index}"), | ||||
|                                 SourceLocation::caller(), | ||||
|                                 config.p_reg_num(), | ||||
|                             ); | ||||
|                             rename_table_read_ports[src_index].data.cast_to_bits() | ||||
|                             connect(rename_table_normal_read_ports[src_index].addr, src_reg); | ||||
|                             connect(rename_table_special_read_ports[src_index].addr, src_reg); | ||||
|                             #[hdl] | ||||
|                             if let HdlSome(v) = rename_table_normal_read_ports[src_index].data { | ||||
|                                 connect(renamed_src_reg, v); | ||||
|                             } else if let HdlSome(v) = | ||||
|                                 rename_table_special_read_ports[src_index].data | ||||
|                             { | ||||
|                                 connect(renamed_src_reg, v); | ||||
|                             } else { | ||||
|                                 connect(renamed_src_reg, config.p_reg_num().const_zero()); | ||||
|                             } | ||||
|                             renamed_src_reg.cast_to_bits() | ||||
|                         }, | ||||
|                     )), | ||||
|                 ); | ||||
|                 for (reg, reg_kind) in MOpDestReg::regs(dest_reg) | ||||
|                     .into_iter() | ||||
|                     .zip(MOpDestReg::REG_KINDS) | ||||
|                 { | ||||
|                     for &rename_table_name in reg_kind.rename_table_names() { | ||||
|                         let Some(write_ports) = | ||||
|                             rename_table_write_ports.get_mut(&rename_table_name) | ||||
|                         else { | ||||
|                             unreachable!(); | ||||
|                         }; | ||||
|                         let Some(write_port) = write_ports.pop_front() else { | ||||
|                             unreachable!(); | ||||
|                         }; | ||||
|                         let reg_range = rename_table_name.reg_range(); | ||||
|                         #[hdl] | ||||
|                         if reg.value.cmp_ge(reg_range.start) & reg.value.cmp_lt(reg_range.end) { | ||||
|                             connect(write_port.data, renamed_mop_out_reg); | ||||
|                             if let Some(fixed_reg_num) = reg_kind.fixed_reg_num() { | ||||
|                                 connect_any(write_port.addr, fixed_reg_num - reg_range.start); | ||||
|                             } else { | ||||
|                                 connect_any(write_port.addr, reg.value - reg_range.start); | ||||
|                             } | ||||
|                             connect(write_port.en, true); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 // TODO: write dest_reg to rename table
 | ||||
|                 // rename_table_mem.new_write_port()
 | ||||
|             } | ||||
|         } | ||||
|         connect( | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue