From b0f627e9df022cedefee871bdaa64c8e06198a1c Mon Sep 17 00:00:00 2001 From: David Li Date: Wed, 30 Dec 2015 10:24:36 -0700 Subject: Convert simulator to using cache --- src/memory.rs | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'src/memory.rs') diff --git a/src/memory.rs b/src/memory.rs index 9f606e4..2170556 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -31,11 +31,18 @@ pub enum MemoryError { pub type Result = ::std::result::Result; pub trait MemoryInterface { - fn latency() -> u32; + fn latency(&self) -> u32; fn read_word(&mut self, address: isa::Address) -> Result; fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()>; + fn read_instruction(&mut self, address: isa::Address) -> Option { + match self.read_word(address / 4) { + Ok(word) => Some(Instruction::new(word)), + Err(_) => None, + } + } + // fn read_halfword(&self, address: isa::Address) -> Result; // fn write_halfword(&self, address: isa::Address) -> Result<()>; @@ -70,11 +77,11 @@ struct CacheBlock { // investigate how LRU is implemented // TODO: use hashtable for a way? // TODO: hashtable-based FA cache? -pub struct DirectMappedCache { +pub struct DirectMappedCache { num_sets: u32, block_words: u32, cache: Vec, - next_level: Rc>, + next_level: Rc>, } impl Memory { @@ -95,16 +102,10 @@ impl Memory { memory: memory, } } - - pub fn read_instruction(&self, pc: isa::Address) -> Option { - self.memory.get((pc / 4) as usize) - .map(Clone::clone) - .map(Instruction::new) - } } impl MemoryInterface for Memory { - fn latency() -> u32 { + fn latency(&self) -> u32 { 100 } @@ -126,11 +127,17 @@ impl MemoryInterface for Memory { Ok(()) } } + + fn read_instruction(&mut self, pc: isa::Address) -> Option { + self.memory.get((pc / 4) as usize) + .map(Clone::clone) + .map(Instruction::new) + } } -impl DirectMappedCache { - pub fn new(sets: u32, block_words: u32, next_level: Rc>) - -> DirectMappedCache { +impl DirectMappedCache { + pub fn new(sets: u32, block_words: u32, next_level: Rc>) + -> DirectMappedCache { let set = CacheBlock { valid: false, tag: 0, @@ -172,16 +179,16 @@ impl DirectMappedCache { } } -impl MemoryInterface for DirectMappedCache { - fn latency() -> u32 { +impl MemoryInterface for DirectMappedCache { + fn latency(&self) -> u32 { 100 } fn read_word(&mut self, address: isa::Address) -> Result { let normalized = self.normalize_address(address); + let stall = self.latency() + self.next_level.borrow().latency(); let (tag, index, offset) = self.parse_address(address); let ref mut set = self.cache[index as usize]; - let stall = DirectMappedCache::::latency() + T::latency(); if set.tag == tag { return Ok(set.contents[(offset / 4) as usize]); } -- cgit v1.2.3