aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cache.rs8
-rw-r--r--src/isa/mod.rs4
-rw-r--r--src/memory.rs59
3 files changed, 58 insertions, 13 deletions
diff --git a/src/cache.rs b/src/cache.rs
deleted file mode 100644
index 26fdc18..0000000
--- a/src/cache.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// pub struct Cache {
-// }
-
-// impl Cache {
-// pub fn new(sets: usize, ways: usize, block_size: usize) -> Cache {
-
-// }
-// }
diff --git a/src/isa/mod.rs b/src/isa/mod.rs
index 565e6e0..dd803c5 100644
--- a/src/isa/mod.rs
+++ b/src/isa/mod.rs
@@ -2,6 +2,8 @@ pub mod opcodes;
pub mod funct3;
pub mod funct7;
+pub type Word = u32;
+
#[derive(Debug, PartialEq)]
pub enum Register {
X0 = 0,
@@ -84,6 +86,8 @@ impl Register {
#[derive(Copy, Clone, Debug)]
pub struct Instruction {
+ // TODO: rename word to something correct - instructions are not always a
+ // word
word: u32,
}
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) {
+
+ }
+}