WIP: adding load/store unit

This commit is contained in:
Jacob Lifshay 2026-07-10 19:16:13 -07:00
parent bc2bcf4434
commit 304100b492
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
6 changed files with 1392 additions and 3 deletions

View file

@ -19,6 +19,7 @@ use std::{
borrow::Cow, borrow::Cow,
fmt, fmt,
marker::PhantomData, marker::PhantomData,
num::NonZeroU64,
ops::{ControlFlow, Range}, ops::{ControlFlow, Range},
}; };
@ -2983,6 +2984,19 @@ pub enum LoadStoreWidth {
Width64Bit, Width64Bit,
} }
impl LoadStoreWidth {
#[hdl]
pub fn access_byte_size_sim(this: &<Self as Type>::SimValue) -> NonZeroU64 {
#[hdl(sim)]
match this {
Self::Width8Bit => const { NonZeroU64::new(1).unwrap() },
Self::Width16Bit => const { NonZeroU64::new(2).unwrap() },
Self::Width32Bit => const { NonZeroU64::new(4).unwrap() },
Self::Width64Bit => const { NonZeroU64::new(8).unwrap() },
}
}
}
#[hdl(cmp_eq)] #[hdl(cmp_eq)]
pub enum LoadStoreConversion { pub enum LoadStoreConversion {
ZeroExt, ZeroExt,

View file

@ -127,7 +127,46 @@ impl AddressRange {
}, },
} }
} }
pub const fn is_overlapping(self, other: Self) -> bool {
self.contains(other.start().0) || other.contains(self.start().0)
} }
}
const _: () = {
const N: u64 = 4;
const fn is_overlapping_reference(range1: AddressRange, range2: AddressRange) -> bool {
// we just need to check values < N since all starts/ends are < N
let mut v = 0;
while v < N {
if range1.contains(v) && range2.contains(v) {
return true;
}
v += 1;
}
false
}
let mut start1 = 0;
while start1 < N {
let mut end1 = 0;
while end1 < N {
let mut start2 = 0;
while start2 < N {
let mut end2 = 0;
while end2 < N {
let range1 = AddressRange::from_wrapping_range_inclusive(start1..=end1);
let range2 = AddressRange::from_wrapping_range_inclusive(start2..=end2);
assert!(
range1.is_overlapping(range2) == is_overlapping_reference(range1, range2)
);
end2 += 1;
}
start2 += 1;
}
end1 += 1;
}
start1 += 1;
}
};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, serde::Serialize, serde::Deserialize)]
#[non_exhaustive] #[non_exhaustive]

View file

@ -8,6 +8,7 @@ use crate::{
MOpVariantVisitOps, MOpVariantVisitor, MOpVisitVariants, RenamedMOp, mop_enum, MOpVariantVisitOps, MOpVariantVisitor, MOpVisitVariants, RenamedMOp, mop_enum,
}, },
rename_execute_retire::ExecuteToUnitInterface, rename_execute_retire::ExecuteToUnitInterface,
unit::load_store::LoadStoreToDCacheInterface,
}; };
use fayalite::{ use fayalite::{
bundle::{Bundle, BundleType}, bundle::{Bundle, BundleType},
@ -18,6 +19,7 @@ use serde::{Deserialize, Serialize};
use std::ops::ControlFlow; use std::ops::ControlFlow;
pub mod alu_branch; pub mod alu_branch;
pub mod load_store;
macro_rules! all_units { macro_rules! all_units {
( (
@ -333,7 +335,7 @@ all_units! {
#[create_dyn_unit_fn = |config, unit_index, filter| todo!()] #[create_dyn_unit_fn = |config, unit_index, filter| todo!()]
#[extract(transformed_move_mop, transformed_move_mop_sim, transformed_move_mop_sim_ref, transformed_move_mop_sim_mut)] #[extract(transformed_move_mop, transformed_move_mop_sim, transformed_move_mop_sim_ref, transformed_move_mop_sim_mut)]
TransformedMove(TransformedMoveOp), TransformedMove(TransformedMoveOp),
#[create_dyn_unit_fn = |config, unit_index, filter| todo!()] #[create_dyn_unit_fn = |config, unit_index, filter| load_store::LoadStore::new(config, unit_index, filter).to_dyn()]
#[extract(load_store_mop, load_store_mop_sim, load_store_mop_sim_ref, load_store_mop_sim_mut)] #[extract(load_store_mop, load_store_mop_sim, load_store_mop_sim_ref, load_store_mop_sim_mut)]
LoadStore(LoadStoreMOp<DestReg, SrcReg>), LoadStore(LoadStoreMOp<DestReg, SrcReg>),
} }
@ -391,6 +393,7 @@ impl RenamedMOpFilter for () {
pub struct UnitIO { pub struct UnitIO {
pub cd: Option<Expr<ClockDomain>>, pub cd: Option<Expr<ClockDomain>>,
pub from_execute: Expr<ExecuteToUnitInterface<PhantomConst<CpuConfig>>>, pub from_execute: Expr<ExecuteToUnitInterface<PhantomConst<CpuConfig>>>,
pub to_d_cache: Option<Expr<LoadStoreToDCacheInterface<PhantomConst<CpuConfig>>>>,
} }
pub trait UnitTrait: pub trait UnitTrait:

View file

@ -1617,6 +1617,7 @@ impl UnitTrait for AluBranch {
UnitIO { UnitIO {
cd: None, cd: None,
from_execute: this.from_execute, from_execute: this.from_execute,
to_d_cache: None,
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -94,13 +94,17 @@ fn formal_harness(
let UnitIO { let UnitIO {
cd: unit_cd, cd: unit_cd,
from_execute: unit_from_execute, from_execute: unit_from_execute,
to_d_cache,
} = dyn_unit.io(unit); } = dyn_unit.io(unit);
if let Some(unit_cd) = unit_cd {
connect(unit_cd, cd);
}
connect( connect(
unit_from_execute, unit_from_execute,
ExecuteToUnitInterfaces::unit_fields(decode_and_run.to_units)[unit_index], ExecuteToUnitInterfaces::unit_fields(decode_and_run.to_units)[unit_index],
); );
if let Some(unit_cd) = unit_cd { if let Some(to_d_cache) = to_d_cache {
connect(unit_cd, cd); unimplemented!("to_d_cache for {unit:?}: {to_d_cache:?}");
} }
} }
hdl_assert(cd.clk, !decode_and_run.error, ""); hdl_assert(cd.clk, !decode_and_run.error, "");