From 2a5cc1a0988f0a69c6b7e95fe8abecf92195332a Mon Sep 17 00:00:00 2001 From: David Li Date: Mon, 28 Dec 2015 09:26:11 -0700 Subject: Implement basic cache lookup --- src/memory.rs | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/memory.rs b/src/memory.rs index ceec504..a8b15e2 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -28,7 +28,7 @@ pub enum MemoryError { pub type Result = ::std::result::Result; pub trait MemoryInterface { - const LATENCY: u32; + fn latency() -> u32; fn read_word(&self, address: isa::Address) -> Result; fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()>; @@ -50,6 +50,8 @@ pub struct Memory { #[derive(Clone)] struct FetchRequest { + address: isa::Address, + prefetch: bool, cycles_left: u32, } @@ -67,11 +69,12 @@ type CacheSet = Vec; // investigate how LRU is implemented // TODO: use hashtable for a way? // TODO: hashtable-based FA cache? -pub struct Cache { +pub struct Cache { num_sets: u32, num_ways: u32, block_words: u32, cache: Vec, + next_level: T, } impl Memory { @@ -95,7 +98,9 @@ impl Memory { } impl MemoryInterface for Memory { - const LATENCY: u32 = 100; + fn latency() -> u32 { + 100 + } fn read_word(&self, address: isa::Address) -> Result { // memory is word-addressed but addresses are byte-addressed @@ -117,8 +122,8 @@ impl MemoryInterface for Memory { } } -impl Cache { - pub fn new(sets: u32, ways: u32, block_words: u32) -> Cache { +impl Cache { + pub fn new(sets: u32, ways: u32, block_words: u32, next_level: T) -> Cache { let set = vec![CacheBlock { valid: false, tag: 0, @@ -130,6 +135,7 @@ impl Cache { num_ways: ways, block_words: block_words, cache: vec![set; sets as usize], + next_level: next_level, } } @@ -155,16 +161,27 @@ impl Cache { } } -impl MemoryInterface for Cache { - const LATENCY: u32 = 1; +impl MemoryInterface for Cache { + fn latency() -> u32 { + 100 + } fn read_word(&self, address: isa::Address) -> Result { - Err(MemoryError::InvalidAddress) + let (tag, index, offset) = self.parse_address(address); + let ref set = self.cache[index as usize]; + for way in set { + if way.tag == tag { + return Ok(way.contents[(offset / 4) as usize]); + } + } + Err(MemoryError::CacheMiss { + stall_cycles: Cache::::latency() + T::latency() + }) } fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> { - Err(MemoryError::InvalidAddress) + // XXX: temporary + self.next_level.write_word(address, value) } - } -- cgit v1.2.3