aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2016-01-04 14:19:56 -0700
committerDavid Li <li.davidm96@gmail.com>2016-01-04 14:19:56 -0700
commitbb8162c22e34ac588f92b4d3783c39d04a67ec2c (patch)
tree08d7b613bd201a9524e3fef36c99dc3fcafcff17 /src
parentf71937d4bb74ad0ba8937da94643ddfe403ea346 (diff)
Fix cache sharing bug
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs6
-rw-r--r--src/memory.rs6
-rw-r--r--src/simulator.rs30
3 files changed, 26 insertions, 16 deletions
diff --git a/src/lib.rs b/src/lib.rs
index c3fa51b..35951c2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -51,14 +51,16 @@ fn test_elfloader() {
let (data, data_offset) = data.unwrap();
let mmu = memory::IdentityMmu::new();
+ // TODO: make this a method; have it accept a MMU
let memory = memory::Memory::new_from_text_and_data(
0x8000,
text, text_offset as usize,
data, data_offset as usize);
let memory_ref = Rc::new(RefCell::new(Box::new(memory) as Box<memory::MemoryInterface>));
let cache = Rc::new( RefCell::new( Box::new( memory::DirectMappedCache::new(4, 4, memory_ref.clone())) as Box<memory::MemoryInterface>) );
- let core = simulator::Core::new(start, cache.clone(), Box::new(mmu));
- let mut simulator = simulator::Simulator::new(vec![core], memory_ref.clone());
+ let core = simulator::Core::new(start, 0x1000, cache.clone(), Box::new(mmu));
+ let core2 = simulator::Core::new(start, 0x3000, cache.clone(), Box::new(memory::IdentityMmu::new()));
+ let mut simulator = simulator::Simulator::new(vec![core, core2], memory_ref.clone());
simulator.run();
}
diff --git a/src/memory.rs b/src/memory.rs
index db0dca4..9bc3643 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -307,8 +307,12 @@ impl<'a> MemoryInterface for DirectMappedCache<'a> {
fn step(&mut self) {
for set in self.cache.iter_mut() {
if let Some(ref mut fetch_request) = set.fetch_request {
- if fetch_request.cycles_left > 0 {
+ // Start filling the cache once the cycles_left would
+ // have hit 0, so that the consumer never gets
+ // stall_cycles = 0
+ if fetch_request.cycles_left > 1 {
fetch_request.cycles_left -= 1;
+ return;
}
// read all the words in a line from the next
// level, until we get a stall
diff --git a/src/simulator.rs b/src/simulator.rs
index 571fafe..38e8f88 100644
--- a/src/simulator.rs
+++ b/src/simulator.rs
@@ -28,6 +28,8 @@ pub struct Core<'a>{
running: bool,
cache: SharedMemory<'a>,
mmu: Box<Mmu + 'a>,
+ cycle_count: u32,
+ stall_count: u32,
}
pub struct Simulator<'a> {
@@ -75,22 +77,30 @@ impl RegisterFile {
impl<'a> Core<'a> {
// TODO: take Rc<RefCell<>> to Memory as well?
- pub fn new(entry: isa::Address, cache: SharedMemory<'a>, mmu: Box<Mmu + 'a>) -> Core<'a> {
+ pub fn new(entry: isa::Address, sp: isa::Address,
+ cache: SharedMemory<'a>, mmu: Box<Mmu + 'a>) -> Core<'a> {
+ let mut registers = RegisterFile::new();
+ registers.write_word(isa::Register::X2, sp);
Core {
pc: entry,
- registers: RegisterFile::new(),
+ registers: registers,
stall: 0,
running: true,
cache: cache,
mmu: mmu,
+ cycle_count: 0,
+ stall_count: 0,
}
}
fn step(&mut self, inst: isa::Instruction) {
let pc = self.pc;
+ self.cycle_count += 1;
+
if self.stall > 0 {
self.stall -= 1;
+ self.stall_count += 1;
return;
}
@@ -279,8 +289,7 @@ impl<'a> Core<'a> {
let result = self.cache.borrow_mut().read_word(address);
match result {
- Ok(value) =>
- self.registers.write_word(inst.rd(), value),
+ Ok(value) => self.registers.write_word(inst.rd(), value),
Err(MemoryError::CacheMiss { stall_cycles }) => {
self.stall = stall_cycles;
return;
@@ -310,7 +319,7 @@ impl<'a> Core<'a> {
match result {
Ok(()) => (),
Err(MemoryError::CacheMiss { stall_cycles }) => {
- self.stall = stall_cycles;
+ self.stall = stall_cycles - 1;
return;
},
Err(MemoryError::InvalidAddress) => {
@@ -352,7 +361,6 @@ impl<'a> Core<'a> {
impl<'a> Simulator<'a> {
pub fn new(cores: Vec<Core<'a>>, memory: SharedMemory<'a>)
-> Simulator<'a> {
- // TODO: pass in GP, SP, _start
// TODO: initialize GP, registers (GP is in headers)
Simulator {
cores: cores,
@@ -361,18 +369,12 @@ impl<'a> Simulator<'a> {
}
pub fn run(&mut self) {
- // hardcode SP
- self.cores[0].registers.write_word(isa::Register::X2, 0x7FFC);
- let mut total_cycles = 0;
- let mut stall_cycles = 0;
loop {
let mut ran = false;
- total_cycles += 1;
for core in self.cores.iter_mut() {
if !core.running {
continue;
}
- if core.stall > 0 { stall_cycles += 1; }
let pc = core.pc;
let pc = core.mmu.translate(pc);
@@ -390,7 +392,9 @@ impl<'a> Simulator<'a> {
}
if !ran {
println!("All cores are not running, stopping...");
- println!("Stalled cycles: {} of {}", stall_cycles, total_cycles);
+ for (i, core) in self.cores.iter().enumerate() {
+ println!("Core {}: stalled {} of {}", i, core.stall_count, core.cycle_count);
+ }
break;
}
}