From ad805c698cd1c4d68d090f842fb14621c32ee8d6 Mon Sep 17 00:00:00 2001 From: David Li Date: Fri, 8 Jan 2016 10:04:27 -0700 Subject: Refactor into multiple files --- src/shareable_cache.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/shareable_cache.rs (limited to 'src/shareable_cache.rs') diff --git a/src/shareable_cache.rs b/src/shareable_cache.rs new file mode 100644 index 0000000..b6c6654 --- /dev/null +++ b/src/shareable_cache.rs @@ -0,0 +1,104 @@ +use rustv::isa; +use rustv::memory::{MemoryInterface, Result, SharedMemory}; + +/// A cache that can be used as two separate caches or one +/// set-associative cache. +struct ShareableCache<'a> { + // The idea is to create two separate ShareableCaches, one for + // each player. + primary: SharedMemory<'a>, + secondary: SharedMemory<'a>, + secondary_enabled: bool, + use_secondary: bool, +} + +impl<'a> ShareableCache<'a> { + pub fn new(cache1: SharedMemory<'a>, cache2: SharedMemory<'a>) + -> (ShareableCache<'a>, ShareableCache<'a>) { + (ShareableCache { + primary: cache1.clone(), + secondary: cache2.clone(), + secondary_enabled: false, + use_secondary: false, + }, ShareableCache { + primary: cache2.clone(), + secondary: cache1.clone(), + secondary_enabled: false, + use_secondary: false, + }) + } + + pub fn enable_secondary(&mut self) { + self.secondary_enabled = true; + self.use_secondary = true; + } + + pub fn disable_secondary(&mut self) { + self.secondary_enabled = false; + } +} + +impl<'a> MemoryInterface for ShareableCache<'a> { + fn latency(&self) -> u32 { + self.primary.borrow().latency() + } + + fn step(&mut self) { + // We only step the primary cache. The idea is that the + // secondary cache should be the primary cache of another + // ShareableCache. + self.primary.borrow_mut().step(); + } + + fn is_address_accessible(&self, address: isa::Address) -> bool { + self.primary.borrow().is_address_accessible(address) || + (self.secondary_enabled && + self.secondary.borrow().is_address_accessible(address)) + } + + fn read_word(&mut self, address: isa::Address) -> Result { + if self.secondary_enabled { + if self.primary.borrow().is_address_accessible(address) { + self.primary.borrow_mut().read_word(address) + } + else if self.secondary.borrow().is_address_accessible(address) { + self.secondary.borrow_mut().read_word(address) + } + else { + self.use_secondary = !self.use_secondary; + if self.use_secondary { + self.secondary.borrow_mut().read_word(address) + } + else { + self.primary.borrow_mut().read_word(address) + } + } + } + else { + self.primary.borrow_mut().read_word(address) + } + } + + fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> { + if self.secondary_enabled { + if self.primary.borrow().is_address_accessible(address) { + self.primary.borrow_mut().write_word(address, value) + } + else if self.secondary.borrow().is_address_accessible(address) { + self.secondary.borrow_mut().write_word(address, value) + } + else { + self.use_secondary = !self.use_secondary; + if self.use_secondary { + self.secondary.borrow_mut().write_word(address, value) + } + else { + self.primary.borrow_mut().write_word(address, value) + } + } + } + else { + self.primary.borrow_mut().write_word(address, value) + } + } +} -- cgit v1.2.3