aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2015-12-25 15:15:50 -0700
committerDavid Li <li.davidm96@gmail.com>2015-12-25 15:15:50 -0700
commit05ae121c98be750aeca537ded7338c0cbf5f5b4c (patch)
treee218f1bf68377cfc25eb991f05b26266ace95d03 /src
parentf235d8e500e9fd9945d07ed347ccab5214d26eba (diff)
Convert PC to u32
Diffstat (limited to 'src')
-rw-r--r--src/isa/mod.rs3
-rw-r--r--src/memory.rs38
-rw-r--r--src/simulator.rs9
3 files changed, 38 insertions, 12 deletions
diff --git a/src/isa/mod.rs b/src/isa/mod.rs
index 5458255..b7ac405 100644
--- a/src/isa/mod.rs
+++ b/src/isa/mod.rs
@@ -9,8 +9,7 @@ pub type SignedHalfWord = i16;
pub type Byte = u8;
pub type SignedByte = i8;
-// TODO: directly encode PC as u32, as architecturally specified
-pub type Address = usize;
+pub type Address = u32;
#[derive(Debug, PartialEq)]
pub enum Register {
diff --git a/src/memory.rs b/src/memory.rs
index 51d8199..ae3b6fc 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -4,7 +4,9 @@ use binary::{Binary};
#[derive(Debug)]
pub enum MemoryError {
InvalidAddress,
- CacheMiss,
+ CacheMiss {
+ stall_cycles: u32,
+ },
}
pub type Result<T> = ::std::result::Result<T, MemoryError>;
@@ -51,6 +53,7 @@ pub struct Cache {
impl Memory {
pub fn new(size: isa::Address, binary: Binary) -> Memory {
let mut memory = binary.words.clone();
+ let size = size as usize;
if size > memory.len() {
let remainder = size - memory.len();
memory.reserve(remainder);
@@ -61,7 +64,9 @@ impl Memory {
}
pub fn read_instruction(&self, pc: isa::Address) -> Option<Instruction> {
- self.memory.get(pc / 4).map(Clone::clone).map(Instruction::new)
+ self.memory.get((pc / 4) as usize)
+ .map(Clone::clone)
+ .map(Instruction::new)
}
}
@@ -70,11 +75,14 @@ impl MemoryInterface for Memory {
fn read_word(&self, address: isa::Address) -> Result<isa::Word> {
// memory is word-addressed but addresses are byte-addressed
- self.memory.get(address / 4).map(Clone::clone).ok_or(MemoryError::InvalidAddress)
+ self.memory.get((address / 4) as usize)
+ .map(Clone::clone)
+ .ok_or(MemoryError::InvalidAddress)
}
- fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> {
- let address = address / 4;
+ fn write_word(&mut self, address: isa::Address, value: isa::Word)
+ -> Result<()> {
+ let address = (address / 4) as usize;
if address >= self.memory.len() || address <= 0 {
Err(MemoryError::InvalidAddress)
}
@@ -99,6 +107,23 @@ impl Cache {
}
}
+ fn parse_address(&self, address: isa::Address) -> (u32, u32, u32) {
+ // TODO: use constant in ISA module for word->byte conversion
+ let offset_mask = (self.block_words * 4 - 1) as u32;
+ let offset = address & offset_mask;
+ let index_mask = (self.num_sets - 1) as u32;
+ let index_shift = 32 - (self.block_words * 4).leading_zeros();
+ let index = (address >> index_shift) & index_mask;
+ let tag_shift = index_shift + (32 - self.num_sets.leading_zeros());
+ let tag = address >> tag_shift;
+
+ (tag, index, offset)
+ }
+
+ fn prefetch(&mut self, address: isa::Address) {
+
+ }
+
fn invalidate(&mut self, address: isa::Address) {
}
@@ -111,7 +136,8 @@ impl MemoryInterface for Cache {
Err(MemoryError::InvalidAddress)
}
- fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> {
+ fn write_word(&mut self, address: isa::Address, value: isa::Word)
+ -> Result<()> {
Err(MemoryError::InvalidAddress)
}
diff --git a/src/simulator.rs b/src/simulator.rs
index 5eb68e2..127ac8a 100644
--- a/src/simulator.rs
+++ b/src/simulator.rs
@@ -277,8 +277,9 @@ impl Simulator {
let base = core.registers.read_word(inst.rs1());
let address = ((base as isa::SignedWord) + imm) as isa::Address;
match self.memory.read_word(address) {
- Ok(value) => core.registers.write_word(inst.rd(), value),
- Err(MemoryError::CacheMiss) => return,
+ Ok(value) =>
+ core.registers.write_word(inst.rd(), value),
+ Err(MemoryError::CacheMiss {..}) => return,
Err(MemoryError::InvalidAddress) => {
self.trap(core, Trap::IllegalRead {
address: pc,
@@ -300,7 +301,7 @@ impl Simulator {
let address = ((base as isa::SignedWord) + imm) as isa::Address;
match self.memory.write_word(address, val) {
Ok(()) => (),
- Err(MemoryError::CacheMiss) => return,
+ Err(MemoryError::CacheMiss {..}) => return,
Err(MemoryError::InvalidAddress) => {
self.trap(core, Trap::IllegalWrite {
address: pc,
@@ -319,7 +320,7 @@ impl Simulator {
0x0 => {
// System call
println!("System call {}:", core.registers.read_word(isa::Register::X10));
- let address = core.registers.read_word(isa::Register::X11) as usize;
+ let address = core.registers.read_word(isa::Register::X11);
println!("Argument {:X}: {:?}", address, self.memory.read_word(address));
}
_ => {