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(-)
(limited to 'src')
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