diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/binary.rs | 2 | ||||
| -rw-r--r-- | src/isa/funct3.rs | 8 | ||||
| -rw-r--r-- | src/isa/mod.rs | 13 | ||||
| -rw-r--r-- | src/isa/opcodes.rs | 6 | ||||
| -rw-r--r-- | src/lib.rs | 5 | ||||
| -rw-r--r-- | src/memory.rs | 15 | ||||
| -rw-r--r-- | src/simulator.rs | 49 | 
7 files changed, 78 insertions, 20 deletions
| diff --git a/src/binary.rs b/src/binary.rs index e1e6d45..a2a9d38 100644 --- a/src/binary.rs +++ b/src/binary.rs @@ -7,7 +7,7 @@ use std::path::Path;  use std::str;  pub struct Binary { -    words: Vec<u32>, +    pub words: Vec<u32>,  }  #[derive(Debug)] diff --git a/src/isa/funct3.rs b/src/isa/funct3.rs new file mode 100644 index 0000000..d9a626a --- /dev/null +++ b/src/isa/funct3.rs @@ -0,0 +1,8 @@ +pub const ADDI: u32 = 0x0; +pub const SLLI: u32 = 0x1; +pub const SLTI: u32 = 0x2; +pub const SLTIU: u32 = 0x3; + +pub const LW: u32 = 0x2; + +pub const SW: u32 = 0x2; diff --git a/src/isa/mod.rs b/src/isa/mod.rs index 5e9a7dc..ac8ce45 100644 --- a/src/isa/mod.rs +++ b/src/isa/mod.rs @@ -1,6 +1,7 @@  pub mod opcodes; +pub mod funct3; -enum Register { +pub enum Register {      X0 = 0,      X1 = 1,      X2 = 2, @@ -15,6 +16,12 @@ enum Register {      X11 = 11,  } +impl Register { +    pub fn as_num(self) -> usize { +        self as usize +    } +} +  pub struct Instruction {      word: u32,  } @@ -29,4 +36,8 @@ impl Instruction {      pub fn opcode(&self) -> u32 {          self.word & 0x7F      } + +    pub fn funct3(&self) -> u32 { +        (self.word >> 12) & 0x3 +    }  } diff --git a/src/isa/opcodes.rs b/src/isa/opcodes.rs index 0ea7613..33af0f6 100644 --- a/src/isa/opcodes.rs +++ b/src/isa/opcodes.rs @@ -1,2 +1,4 @@ -pub const Branch: u32 = 0x12; -pub const IntegerImmediate: u32 = 0x13; +pub const BRANCH: u32 = 0x12; +pub const INTEGER_IMMEDIATE: u32 = 0x13; +pub const LOAD: u32 = 0x3; +pub const STORE: u32 = 0x23; @@ -10,7 +10,10 @@ fn it_works() {      use std::path::Path;      println!("Test");      match binary::Binary::new_from_hex_file(Path::new("../riscv/kernel.hex")) { -        Ok(_) => println!("Ok"), +        Ok(b) => { +            let mut simulator = simulator::Simulator::new(1, b); +            simulator.run(); +        },          Err(err) => println!("Error: {:?}", err),      }  } diff --git a/src/memory.rs b/src/memory.rs index 854b0ea..3409ed4 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,21 +1,28 @@  use isa::{Instruction}; +use binary::{Binary};  pub struct Memory {      memory: Vec<u32>,  }  impl Memory { -    pub fn new(size: usize) -> Memory { +    pub fn new(size: usize, binary: Binary) -> Memory { +        let mut memory = binary.words.clone(); +        if size > memory.len() { +            let remainder = size - memory.len(); +            memory.reserve(remainder); +        }          Memory { -            memory: Vec::with_capacity(size), +            memory: memory,          }      }      pub fn read_word(&self, address: usize) -> Option<u32> { -        self.memory.get(address).map(Clone::clone) +        // memory is word-addressed but addresses are byte-addressed +        self.memory.get(address / 4).map(Clone::clone)      }      pub fn read_instruction(&self, pc: usize) -> Option<Instruction> { -        self.memory.get(pc).map(Clone::clone).map(Instruction::new) +        self.memory.get(pc / 4).map(Clone::clone).map(Instruction::new)      }  } diff --git a/src/simulator.rs b/src/simulator.rs index 86ddfab..8ecf6e7 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -3,7 +3,6 @@ use binary::{Binary};  use memory::{Memory};  pub struct Simulator { -    binary: Binary,      num_cores: usize,      memory: Memory,  } @@ -17,19 +16,25 @@ struct RegisterFile {      registers: [u32; 32],  } +impl RegisterFile { +    fn write_word<T: Into<isa::Register>>(&mut self, reg: T, value: u32) { +        // TODO: should be safe to use unchecked index +        self.registers[reg.into().as_num()] = value; +    } +} +  impl Simulator {      pub fn new(num_cores: usize, binary: Binary) -> Simulator { +        let memory = Memory::new(0x2000, binary); +        // TODO: initialize GP, registers (GP is in headers)          Simulator { -            binary: binary,              num_cores: num_cores, -            memory: Memory::new(0x20000), +            memory: memory,          }      }      pub fn run(&mut self) {          let mut cores = vec![Core { pc: 0x10000, }; self.num_cores]; -        // TODO: set up memory, cache, devices -        // TODO: map binary into RAM          loop {              for core in cores.iter_mut() {                  self.step_core(core); @@ -40,19 +45,41 @@ impl Simulator {      fn step_core(&mut self, core: &mut Core) {          if let Some(inst) = self.memory.read_instruction(core.pc) {              match inst.opcode() { -                isa::opcodes::Branch => { +                isa::opcodes::BRANCH => { -                } -                isa::opcodes::IntegerImmediate => { -                     -                } +                }, +                isa::opcodes::INTEGER_IMMEDIATE => match inst.funct3() { +                    isa::funct3::ADDI => { +                        println!("ADDI"); +                    } +                    _ => { +                        panic!("Invalid integer-immediate funct3code: 0x{:x}", inst.funct3()); +                    } +                }, +                isa::opcodes::LOAD => match inst.funct3() { +                     isa::funct3::LW => { +                        println!("LW"); +                    } +                    _ => { +                        panic!("Invalid load funct3code: 0x{:x}", inst.funct3()); +                    } +                }, +                isa::opcodes::STORE => match inst.funct3() { +                     isa::funct3::SW => { +                        println!("SW"); +                    } +                    _ => { +                        panic!("Invalid store funct3code: 0x{:x}", inst.funct3()); +                    } +                },                  _ => { -                     +                    panic!("Invalid opcode: 0x{:02X}", inst.opcode());                  }              }          }          else {              // trap          } +        core.pc += 4;      }  } | 
