WIP adding unit input/output values and insn tracking

This commit is contained in:
Jacob Lifshay 2025-02-13 20:55:43 -08:00
parent d7818d889c
commit 2b7e7e4946
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
9 changed files with 11507 additions and 6399 deletions

View file

@ -6,7 +6,7 @@ use crate::{
MOp, MOpDestReg, MOpRegNum, MOpTrait, PRegNum, RenameTableName, UnitOutRegNum,
COMMON_MOP_SRC_LEN,
},
unit::{TrapData, UnitTrait},
unit::{unit_base::UnitForwardingInfo, TrapData, UnitTrait},
util::tree_reduce::tree_reduce_with_state,
};
use fayalite::{
@ -17,6 +17,7 @@ use fayalite::{
};
use std::{
collections::{BTreeMap, VecDeque},
marker::PhantomData,
num::NonZeroUsize,
};
@ -79,8 +80,7 @@ pub fn reg_alloc(config: &CpuConfig) {
}
#[hdl]
let available_units =
wire(Array[Array[Bool][config.unit_kinds.len()]][config.fetch_width.get()]);
let available_units = wire(Array[Array[Bool][config.units.len()]][config.fetch_width.get()]);
#[hdl]
let selected_unit_indexes =
wire(Array[HdlOption[UInt[config.unit_num_width()]]][config.fetch_width.get()]);
@ -95,7 +95,7 @@ pub fn reg_alloc(config: &CpuConfig) {
);
connect(
available_units[fetch_index],
repeat(false, config.unit_kinds.len()),
repeat(false, config.units.len()),
);
connect(
renamed_mops[fetch_index],
@ -116,7 +116,6 @@ pub fn reg_alloc(config: &CpuConfig) {
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 read_port = mem.new_read_port();
connect(read_port.clk, cd.clk);
connect_any(read_port.addr, 0u8);
@ -242,7 +241,7 @@ pub fn reg_alloc(config: &CpuConfig) {
connect(
selected_unit_indexes[fetch_index],
tree_reduce_with_state(
0..config.unit_kinds.len(),
0..config.units.len(),
&mut 0usize,
|_state, unit_index| {
let selected_unit_index_leaf = wire_with_loc(
@ -304,15 +303,15 @@ pub fn reg_alloc(config: &CpuConfig) {
config.fetch_width.get(),
),
);
for (unit_index, &unit_kind) in config.unit_kinds.iter().enumerate() {
let dyn_unit = unit_kind.unit(config);
for (unit_index, unit_config) in config.units.iter().enumerate() {
let dyn_unit = unit_config.kind.unit(config, unit_index);
let unit = instance_with_loc(
&format!("unit_{unit_index}"),
dyn_unit.make_module(),
dyn_unit.module(),
SourceLocation::caller(),
);
connect(dyn_unit.cd(unit), cd);
let unit_input = dyn_unit.input(unit);
let unit_input_insn = dyn_unit.input_insn(unit);
// TODO: handle assigning multiple instructions to a unit at a time
let assign_to_unit_at_once = NonZeroUsize::new(1).unwrap();
// TODO: handle retiring multiple instructions from a unit at a time
@ -333,7 +332,10 @@ pub fn reg_alloc(config: &CpuConfig) {
HdlOption[UInt[config.out_reg_num_width]].uninit(), // FIXME: just for debugging
);
connect(unit_free_regs_tracker.alloc_out[0].ready, false);
connect(unit_input.data, Expr::ty(unit_input).data.HdlNone());
connect(
unit_input_insn.data,
Expr::ty(unit_input_insn).data.HdlNone(),
);
for fetch_index in 0..config.fetch_width.get() {
#[hdl]
if let HdlNone = unit_free_regs_tracker.alloc_out[0].data {
@ -341,7 +343,7 @@ pub fn reg_alloc(config: &CpuConfig) {
connect(available_units[fetch_index][unit_index], false);
}
#[hdl]
if !unit_input.ready {
if !unit_input_insn.ready {
// must come after to override connects in loops above
connect(available_units[fetch_index][unit_index], false);
}
@ -354,11 +356,11 @@ pub fn reg_alloc(config: &CpuConfig) {
if let HdlSome(renamed_mop) =
HdlOption::and_then(renamed_mops[fetch_index], |v| dyn_unit.extract_mop(v))
{
connect(unit_input.data, HdlSome(renamed_mop));
connect(unit_input_insn.data, HdlSome(renamed_mop));
} else {
connect(
unit_input.data,
HdlSome(Expr::ty(unit_input).data.HdlSome.uninit()),
unit_input_insn.data,
HdlSome(Expr::ty(unit_input_insn).data.HdlSome.uninit()),
);
// FIXME: add hdl_assert(cd.clk, false.to_expr(), "");
}
@ -383,5 +385,23 @@ pub fn reg_alloc(config: &CpuConfig) {
}
}
}
// TODO: connect outputs to other units
connect(
dyn_unit.unit_forwarding_info(unit),
#[hdl]
UnitForwardingInfo::<_, _, _> {
unit_output_writes: repeat(
HdlOption[config.unit_output_write()].HdlNone(),
config.units.len(),
),
_phantom: PhantomData,
},
);
connect(dyn_unit.output(unit).ready, false);
// TODO: handle cancellation
connect(
dyn_unit.cancel_input(unit).data,
HdlOption[config.unit_cancel_input()].HdlNone(),
);
}
}