forked from libre-chip/cpu
WIP adding fetch::l1_i_cache
This commit is contained in:
parent
c62d33048c
commit
de81b9d8a4
3 changed files with 116 additions and 0 deletions
|
|
@ -37,6 +37,8 @@ pub struct CpuConfig {
|
||||||
pub max_branches_per_fetch: NonZeroUsize,
|
pub max_branches_per_fetch: NonZeroUsize,
|
||||||
pub max_fetches_in_flight: NonZeroUsize,
|
pub max_fetches_in_flight: NonZeroUsize,
|
||||||
pub log2_fetch_width_in_bytes: u8,
|
pub log2_fetch_width_in_bytes: u8,
|
||||||
|
pub log2_cache_line_size_in_bytes: u8,
|
||||||
|
pub l1_i_cache_line_count: NonZeroUsize,
|
||||||
/// default value for [`UnitConfig::max_in_flight`]
|
/// default value for [`UnitConfig::max_in_flight`]
|
||||||
pub default_unit_max_in_flight: NonZeroUsize,
|
pub default_unit_max_in_flight: NonZeroUsize,
|
||||||
pub rob_size: NonZeroUsize,
|
pub rob_size: NonZeroUsize,
|
||||||
|
|
@ -63,6 +65,13 @@ impl CpuConfig {
|
||||||
v
|
v
|
||||||
};
|
};
|
||||||
pub const DEFAULT_LOG2_FETCH_WIDTH_IN_BYTES: u8 = 3;
|
pub const DEFAULT_LOG2_FETCH_WIDTH_IN_BYTES: u8 = 3;
|
||||||
|
pub const DEFAULT_LOG2_CACHE_LINE_SIZE_IN_BYTES: u8 = 6;
|
||||||
|
pub const DEFAULT_L1_I_CACHE_LINE_COUNT: NonZeroUsize = {
|
||||||
|
let Some(v) = NonZeroUsize::new(256) else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
v
|
||||||
|
};
|
||||||
pub const DEFAULT_UNIT_MAX_IN_FLIGHT: NonZeroUsize = {
|
pub const DEFAULT_UNIT_MAX_IN_FLIGHT: NonZeroUsize = {
|
||||||
let Some(v) = NonZeroUsize::new(8) else {
|
let Some(v) = NonZeroUsize::new(8) else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
|
@ -77,6 +86,8 @@ impl CpuConfig {
|
||||||
max_branches_per_fetch: Self::DEFAULT_MAX_BRANCHES_PER_FETCH,
|
max_branches_per_fetch: Self::DEFAULT_MAX_BRANCHES_PER_FETCH,
|
||||||
max_fetches_in_flight: Self::DEFAULT_MAX_FETCHES_IN_FLIGHT,
|
max_fetches_in_flight: Self::DEFAULT_MAX_FETCHES_IN_FLIGHT,
|
||||||
log2_fetch_width_in_bytes: Self::DEFAULT_LOG2_FETCH_WIDTH_IN_BYTES,
|
log2_fetch_width_in_bytes: Self::DEFAULT_LOG2_FETCH_WIDTH_IN_BYTES,
|
||||||
|
log2_cache_line_size_in_bytes: Self::DEFAULT_LOG2_CACHE_LINE_SIZE_IN_BYTES,
|
||||||
|
l1_i_cache_line_count: Self::DEFAULT_L1_I_CACHE_LINE_COUNT,
|
||||||
default_unit_max_in_flight: Self::DEFAULT_UNIT_MAX_IN_FLIGHT,
|
default_unit_max_in_flight: Self::DEFAULT_UNIT_MAX_IN_FLIGHT,
|
||||||
rob_size,
|
rob_size,
|
||||||
}
|
}
|
||||||
|
|
@ -141,6 +152,17 @@ impl CpuConfig {
|
||||||
.checked_shl(self.log2_fetch_width_in_bytes.into())
|
.checked_shl(self.log2_fetch_width_in_bytes.into())
|
||||||
.expect("log2_fetch_width_in_bytes is too big")
|
.expect("log2_fetch_width_in_bytes is too big")
|
||||||
}
|
}
|
||||||
|
pub fn cache_line_size_in_bytes(&self) -> usize {
|
||||||
|
1usize
|
||||||
|
.checked_shl(self.log2_cache_line_size_in_bytes.into())
|
||||||
|
.expect("log2_cache_line_size_in_bytes is too big")
|
||||||
|
}
|
||||||
|
pub fn l1_i_cache_size_in_bytes(&self) -> usize {
|
||||||
|
self.l1_i_cache_line_count
|
||||||
|
.get()
|
||||||
|
.checked_mul(self.cache_line_size_in_bytes())
|
||||||
|
.expect("L1 I-Cache is too big")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(get(|c| c.fetch_width.get()))]
|
#[hdl(get(|c| c.fetch_width.get()))]
|
||||||
|
|
@ -161,6 +183,18 @@ pub type CpuConfigLog2FetchWidthInBytes<C: PhantomConstGet<CpuConfig>> = DynSize
|
||||||
#[hdl(get(|c| c.fetch_width_in_bytes()))]
|
#[hdl(get(|c| c.fetch_width_in_bytes()))]
|
||||||
pub type CpuConfigFetchWidthInBytes<C: PhantomConstGet<CpuConfig>> = DynSize;
|
pub type CpuConfigFetchWidthInBytes<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.log2_cache_line_size_in_bytes.into()))]
|
||||||
|
pub type CpuConfigLog2CacheLineSizeInBytes<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.cache_line_size_in_bytes()))]
|
||||||
|
pub type CpuConfigCacheLineSizeInBytes<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.l1_i_cache_line_count.get()))]
|
||||||
|
pub type CpuConfigL1ICacheLineCount<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
#[hdl(get(|c| c.l1_i_cache_size_in_bytes()))]
|
||||||
|
pub type CpuConfigL1ICacheSizeInBytes<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
#[hdl(get(|c| c.rob_size.get()))]
|
#[hdl(get(|c| c.rob_size.get()))]
|
||||||
pub type CpuConfigRobSize<C: PhantomConstGet<CpuConfig>> = DynSize;
|
pub type CpuConfigRobSize<C: PhantomConstGet<CpuConfig>> = DynSize;
|
||||||
|
|
||||||
|
|
|
||||||
81
crates/cpu/src/fetch.rs
Normal file
81
crates/cpu/src/fetch.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
|
use crate::config::{
|
||||||
|
CpuConfig, CpuConfigCacheLineSizeInBytes, CpuConfigFetchWidthInBytes,
|
||||||
|
CpuConfigL1ICacheLineCount, CpuConfigMaxFetchesInFlight, PhantomConstCpuConfig,
|
||||||
|
};
|
||||||
|
use fayalite::{
|
||||||
|
int::UIntInRangeInclusiveType, memory::ReadWriteStruct, prelude::*,
|
||||||
|
util::ready_valid::ReadyValid,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
pub enum MemoryOperationKind {
|
||||||
|
Read,
|
||||||
|
Write,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
|
pub struct MemoryOperationStart<C: PhantomConstGet<CpuConfig> + PhantomConstCpuConfig> {
|
||||||
|
pub kind: MemoryOperationKind,
|
||||||
|
pub addr: UInt<64>,
|
||||||
|
pub write_data: ArrayType<UInt<8>, CpuConfigFetchWidthInBytes<C>>,
|
||||||
|
pub config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
pub enum MemoryOperationErrorKind {
|
||||||
|
Generic,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
pub enum MemoryOperationFinishKind {
|
||||||
|
Success(MemoryOperationKind),
|
||||||
|
Error(MemoryOperationErrorKind),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
|
pub struct MemoryOperationFinish<C: PhantomConstGet<CpuConfig> + PhantomConstCpuConfig> {
|
||||||
|
pub kind: MemoryOperationFinishKind,
|
||||||
|
pub read_data: ArrayType<UInt<8>, CpuConfigFetchWidthInBytes<C>>,
|
||||||
|
pub config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
|
pub struct MemoryInterface<C: PhantomConstGet<CpuConfig> + PhantomConstCpuConfig> {
|
||||||
|
pub start: ReadyValid<MemoryOperationStart<C>>,
|
||||||
|
/// when both start and cancel are triggered in the same clock cycle, that means to cancel and then start a new memory operation
|
||||||
|
pub cancel: ReadyValid<UIntInRangeInclusiveType<ConstUsize<1>, CpuConfigMaxFetchesInFlight<C>>>,
|
||||||
|
#[hdl(flip)]
|
||||||
|
pub finish: ReadyValid<MemoryOperationFinish<C>>,
|
||||||
|
pub config: C,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[hdl]
|
||||||
|
type CacheLine<C: PhantomConstGet<CpuConfig> + PhantomConstCpuConfig> =
|
||||||
|
ArrayType<UInt<8>, CpuConfigCacheLineSizeInBytes<C>>;
|
||||||
|
|
||||||
|
#[hdl_module]
|
||||||
|
pub fn l1_i_cache(config: PhantomConst<CpuConfig>) {
|
||||||
|
#[hdl]
|
||||||
|
let cd: ClockDomain = m.input();
|
||||||
|
#[hdl]
|
||||||
|
let memory_interface: MemoryInterface<PhantomConst<CpuConfig>> =
|
||||||
|
m.output(MemoryInterface[config]);
|
||||||
|
#[hdl]
|
||||||
|
let mut i_cache =
|
||||||
|
memory_array(ArrayType[CacheLine[config]][CpuConfigL1ICacheLineCount[config]]);
|
||||||
|
#[hdl]
|
||||||
|
let ReadWriteStruct::<_, _> {
|
||||||
|
addr: port_addr,
|
||||||
|
en: port_en,
|
||||||
|
clk: port_clk,
|
||||||
|
rdata: port_rdata,
|
||||||
|
wmode: port_wmode,
|
||||||
|
wdata: port_wdata,
|
||||||
|
wmask: port_wmask,
|
||||||
|
} = i_cache.new_rw_port();
|
||||||
|
connect(port_clk, cd.clk);
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod decoder;
|
pub mod decoder;
|
||||||
|
pub mod fetch;
|
||||||
pub mod instruction;
|
pub mod instruction;
|
||||||
pub mod next_pc;
|
pub mod next_pc;
|
||||||
pub mod powerisa_instructions_xml;
|
pub mod powerisa_instructions_xml;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue