From f235d8e500e9fd9945d07ed347ccab5214d26eba Mon Sep 17 00:00:00 2001 From: David Li Date: Fri, 25 Dec 2015 10:57:04 -0700 Subject: Add trait for memory interface --- src/memory.rs | 68 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 18 deletions(-) (limited to 'src/memory.rs') diff --git a/src/memory.rs b/src/memory.rs index ffe37c4..51d8199 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,6 +1,31 @@ use isa::{self, Instruction}; use binary::{Binary}; +#[derive(Debug)] +pub enum MemoryError { + InvalidAddress, + CacheMiss, +} + +pub type Result = ::std::result::Result; + +pub trait MemoryInterface { + const LATENCY: u32; + + fn read_word(&self, address: isa::Address) -> Result; + fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()>; + + // fn read_halfword(&self, address: isa::Address) -> Result; + // fn write_halfword(&self, address: isa::Address) -> Result<()>; + + // fn read_byte(&self, address: isa::Address) -> Result; + // fn write_byte(&self, address: isa::Address) -> Result<()>; +} + +pub struct Mmu { + memory: T, +} + pub struct Memory { memory: Vec, } @@ -23,8 +48,6 @@ pub struct Cache { cache: Vec>, } -// TODO: refactor impls into a MemoryController(?) trait - impl Memory { pub fn new(size: isa::Address, binary: Binary) -> Memory { let mut memory = binary.words.clone(); @@ -37,25 +60,29 @@ impl Memory { } } - pub fn read_word(&self, address: isa::Address) -> Option { + pub fn read_instruction(&self, pc: isa::Address) -> Option { + self.memory.get(pc / 4).map(Clone::clone).map(Instruction::new) + } +} + +impl MemoryInterface for Memory { + const LATENCY: u32 = 100; + + fn read_word(&self, address: isa::Address) -> Result { // memory is word-addressed but addresses are byte-addressed - self.memory.get(address / 4).map(Clone::clone) + self.memory.get(address / 4).map(Clone::clone).ok_or(MemoryError::InvalidAddress) } - pub fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Option<()> { + fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> { let address = address / 4; - if address >= self.memory.len() { - None + if address >= self.memory.len() || address <= 0 { + Err(MemoryError::InvalidAddress) } else { self.memory[address] = value; - Some(()) + Ok(()) } } - - pub fn read_instruction(&self, pc: isa::Address) -> Option { - self.memory.get(pc / 4).map(Clone::clone).map(Instruction::new) - } } impl Cache { @@ -72,15 +99,20 @@ impl Cache { } } - fn read_word(&self, address: isa::Address) -> Option { - None + fn invalidate(&mut self, address: isa::Address) { + } +} - fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Option<()> { - None +impl MemoryInterface for Cache { + const LATENCY: u32 = 1; + + fn read_word(&self, address: isa::Address) -> Result { + Err(MemoryError::InvalidAddress) } - fn invalidate(&mut self, address: isa::Address) { - + fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> { + Err(MemoryError::InvalidAddress) } + } -- cgit v1.2.3