aboutsummaryrefslogtreecommitdiff
path: root/src/memory.rs
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2015-12-30 10:24:36 -0700
committerDavid Li <li.davidm96@gmail.com>2015-12-30 10:24:36 -0700
commitb0f627e9df022cedefee871bdaa64c8e06198a1c (patch)
treef23684fc8ced573c7bda1eac5957a729f4ff2b40 /src/memory.rs
parent6abcabdc03a1aa6072481fb825442c282836101c (diff)
Convert simulator to using cache
Diffstat (limited to 'src/memory.rs')
-rw-r--r--src/memory.rs39
1 files changed, 23 insertions, 16 deletions
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<T> = ::std::result::Result<T, MemoryError>;
pub trait MemoryInterface {
- fn latency() -> u32;
+ fn latency(&self) -> u32;
fn read_word(&mut self, address: isa::Address) -> Result<isa::Word>;
fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()>;
+ fn read_instruction(&mut self, address: isa::Address) -> Option<Instruction> {
+ match self.read_word(address / 4) {
+ Ok(word) => Some(Instruction::new(word)),
+ Err(_) => None,
+ }
+ }
+
// fn read_halfword(&self, address: isa::Address) -> Result<isa::HalfWord>;
// 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<T: MemoryInterface> {
+pub struct DirectMappedCache {
num_sets: u32,
block_words: u32,
cache: Vec<CacheBlock>,
- next_level: Rc<RefCell<T>>,
+ next_level: Rc<RefCell<MemoryInterface>>,
}
impl Memory {
@@ -95,16 +102,10 @@ impl Memory {
memory: memory,
}
}
-
- pub fn read_instruction(&self, pc: isa::Address) -> Option<Instruction> {
- 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<Instruction> {
+ self.memory.get((pc / 4) as usize)
+ .map(Clone::clone)
+ .map(Instruction::new)
+ }
}
-impl<T: MemoryInterface> DirectMappedCache<T> {
- pub fn new(sets: u32, block_words: u32, next_level: Rc<RefCell<T>>)
- -> DirectMappedCache<T> {
+impl DirectMappedCache {
+ pub fn new(sets: u32, block_words: u32, next_level: Rc<RefCell<MemoryInterface>>)
+ -> DirectMappedCache {
let set = CacheBlock {
valid: false,
tag: 0,
@@ -172,16 +179,16 @@ impl<T: MemoryInterface> DirectMappedCache<T> {
}
}
-impl<T: MemoryInterface> MemoryInterface for DirectMappedCache<T> {
- fn latency() -> u32 {
+impl MemoryInterface for DirectMappedCache {
+ fn latency(&self) -> u32 {
100
}
fn read_word(&mut self, address: isa::Address) -> Result<isa::Word> {
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::<T>::latency() + T::latency();
if set.tag == tag {
return Ok(set.contents[(offset / 4) as usize]);
}