aboutsummaryrefslogtreecommitdiff
path: root/src/memory.rs
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2015-12-20 18:25:51 -0500
committerDavid Li <li.davidm96@gmail.com>2015-12-20 18:26:02 -0500
commitea76448fb43b760afa6a9380756b038c62ed9792 (patch)
tree96d62c03486b3d5287c3710233ce85c1fc8f00bd /src/memory.rs
parentde3428fe0a808ffd693675583992a39aa4247287 (diff)
Add Cache API
Diffstat (limited to 'src/memory.rs')
-rw-r--r--src/memory.rs59
1 files changed, 54 insertions, 5 deletions
diff --git a/src/memory.rs b/src/memory.rs
index b7e3721..c15bd84 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -1,12 +1,34 @@
-use isa::{Instruction};
+use isa::{self, Instruction};
use binary::{Binary};
+pub type Address = usize;
+
pub struct Memory {
memory: Vec<u32>,
}
+#[derive(Clone)]
+struct CacheBlock {
+ valid: bool,
+ tag: u32,
+ contents: Vec<u32>,
+}
+
+// TODO: probably want different caches for different strategies, and
+// investigate how LRU is implemented
+// TODO: use hashtable for a way?
+// TODO: hashtable-based FA cache?
+pub struct Cache {
+ num_sets: usize,
+ num_ways: usize,
+ block_words: usize,
+ cache: Vec<Vec<CacheBlock>>,
+}
+
+// TODO: refactor impls into a MemoryController(?) trait
+
impl Memory {
- pub fn new(size: usize, binary: Binary) -> Memory {
+ pub fn new(size: Address, binary: Binary) -> Memory {
let mut memory = binary.words.clone();
if size > memory.len() {
let remainder = size - memory.len();
@@ -17,12 +39,12 @@ impl Memory {
}
}
- pub fn read_word(&self, address: usize) -> Option<u32> {
+ pub fn read_word(&self, address: Address) -> Option<isa::Word> {
// memory is word-addressed but addresses are byte-addressed
self.memory.get(address / 4).map(Clone::clone)
}
- pub fn write_word(&mut self, address: usize, value: u32) -> Option<()> {
+ pub fn write_word(&mut self, address: Address, value: isa::Word) -> Option<()> {
let address = address / 4;
if address >= self.memory.len() {
None
@@ -33,7 +55,34 @@ impl Memory {
}
}
- pub fn read_instruction(&self, pc: usize) -> Option<Instruction> {
+ pub fn read_instruction(&self, pc: Address) -> Option<Instruction> {
self.memory.get(pc / 4).map(Clone::clone).map(Instruction::new)
}
}
+
+impl Cache {
+ pub fn new(sets: usize, ways: usize, block_words: usize) -> Cache {
+ Cache {
+ num_sets: sets,
+ num_ways: ways,
+ block_words: block_words,
+ cache: vec![vec![CacheBlock {
+ valid: false,
+ tag: 0,
+ contents: vec![0; block_words],
+ }; ways]; sets],
+ }
+ }
+
+ fn read_word(&self, address: Address) -> Option<isa::Word> {
+ None
+ }
+
+ fn write_word(&mut self, address: Address, value: isa::Word) -> Option<()> {
+ None
+ }
+
+ fn invalidate(&mut self, address: Address) {
+
+ }
+}