From 0c55749742f3e1e0829478c63d8af4903c4fa07c Mon Sep 17 00:00:00 2001 From: Ben Kyd Date: Tue, 18 Jul 2023 22:18:04 +0100 Subject: [PATCH] Load / Store operations --- src/cpu/mod.rs | 9 ++++--- src/ext/i/mod.rs | 67 ++++++++++++++++++++++++++++++++++++---------- src/main.rs | 5 ++++ src/system/ram.rs | 5 ++-- test/test | Bin 5024 -> 5032 bytes test/test.S | 15 +++++++---- test/test.bin | Bin 16 -> 28 bytes test/test.hex | 3 ++- test/test.lst | 15 ++++++----- test/test.map | 18 ++++++------- 10 files changed, 96 insertions(+), 41 deletions(-) diff --git a/src/cpu/mod.rs b/src/cpu/mod.rs index 0c23049..597b166 100644 --- a/src/cpu/mod.rs +++ b/src/cpu/mod.rs @@ -22,11 +22,11 @@ pub struct CPUState { pub x: [rv32::Word; 32], pub pc: rv32::Word, pub trap: rv32::Word, + pub bus: Rc>, } pub struct CPU { state: CPUState, - bus: Rc>, instruction_decoder: Rc>, extensions: Vec, } @@ -42,14 +42,15 @@ impl CPU { x: [0; 32], pc: 0, trap: 0, + bus, }, - bus, instruction_decoder, extensions, } } pub fn init(&mut self) { + println!("-----------------"); println!("VM RISC-V 32I CPU"); println!("-----------------"); println!("VM > Initializing CPU"); @@ -65,7 +66,7 @@ impl CPU { } fn fetch(&self) -> rv32::Word { - self.bus.borrow_mut().load_32(self.state.pc) + self.state.bus.borrow_mut().load_32(self.state.pc) } pub fn exec(&mut self) -> Result<(), String> { @@ -79,8 +80,8 @@ impl CPU { .borrow_mut() .decode_exec_inst(inst, &mut self.state)?; - self.dump_reg(); self.state.pc = self.state.pc + rv32::WORD as u32; + self.dump_reg(); } Ok(()) } diff --git a/src/ext/i/mod.rs b/src/ext/i/mod.rs index d9dff4f..0f43d37 100644 --- a/src/ext/i/mod.rs +++ b/src/ext/i/mod.rs @@ -103,7 +103,7 @@ impl Instruction for JALR { } #[derive(Default, Copy, Clone)] -pub struct BRANCH; // Thisis is the first time we write a catchall +pub struct BRANCH; // This is is the first time we write a catchall // instruction, this will match BEQ, BNE, BLT, // BGE, BLTU, BEGE impl Instruction for BRANCH { @@ -156,34 +156,73 @@ impl Instruction for BRANCH { } #[derive(Default, Copy, Clone)] -pub struct Load; - -impl Instruction for Load { - fn name(&self) -> &'static str { +pub struct LOAD; // Another catchall instruction, this will match + // LB, LH, LW, LBU, LHU +impl Instruction for LOAD { + fn name(&self) -> &'static str { "LOAD" } - fn match_inst(&self,inst:rv32::Word) -> bool { + fn match_inst(&self, inst: rv32::Word) -> bool { match_mask!(inst, "xxxxxxxxxxxxxxxxxxxxxxxxx0000011") } - fn step(&self,inst:GenInstruction,state: &mut cpu::CPUState) { - + fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) { + println!("VM > Executing LOAD"); + let inst = unsafe { inst.I }; + let offset = inst.sext_imm(); + let addr = state.x[inst.rs1() as usize].wrapping_add(offset); + match inst.funct3() { + 0b000 => { + state.x[inst.rd() as usize] = state.bus.borrow_mut().load_8(addr) as i8 as i32 as u32 + } + 0b001 => { + state.x[inst.rd() as usize] = state.bus.borrow_mut().load_16(addr) as i16 as i32 as u32 + } + 0b010 => { + state.x[inst.rd() as usize] = state.bus.borrow_mut().load_32(addr) as i32 as u32 + } + 0b100 => { + state.x[inst.rd() as usize] = state.bus.borrow_mut().load_8(addr) as u32 + } + 0b101 => { + state.x[inst.rd() as usize] = state.bus.borrow_mut().load_16(addr) as u32 + } + _ => state.trap = 3, + } } } #[derive(Default, Copy, Clone)] -pub struct Store; +pub struct STORE; -impl Instruction for Store { - fn name(&self) -> &'static str { +impl Instruction for STORE { + fn name(&self) -> &'static str { "STORE" } - fn match_inst(&self,inst:rv32::Word) -> bool { + fn match_inst(&self, inst: rv32::Word) -> bool { match_mask!(inst, "xxxxxxxxxxxxxxxxxxxxxxxxx0100011") } + fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) { + println!("VM > Executing STORE"); + let inst = unsafe { inst.S }; + let offset = inst.sext_imm(); + let addr = state.x[inst.rs1() as usize].wrapping_add(offset); + match inst.funct3() { + 0b000 => { + state.bus.borrow_mut().store_8(addr, state.x[inst.rs2() as usize] as u8) + } + 0b001 => { + state.bus.borrow_mut().store_16(addr, state.x[inst.rs2() as usize] as u16) + } + 0b010 => { + state.bus.borrow_mut().store_32(addr, state.x[inst.rs2() as usize] as u32) + } + _ => state.trap = 3, + } + } } #[derive(Default, Copy, Clone)] @@ -225,15 +264,15 @@ impl Instruction for ADD { } } -#[enum_dispatch(Instruction)] #[derive(EnumIter)] +#[enum_dispatch(Instruction)] pub enum ExtensionI { LUI(LUI), AUIPC(AUIPC), JAL(JAL), JALR(JALR), BRANCH(BRANCH), - LOAD(BRANCH), + LOAD(LOAD), STORE(STORE), ADDI(ADDI), ADD(ADD), diff --git a/src/main.rs b/src/main.rs index b03b0a5..46bbe93 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,6 +86,11 @@ impl VMRV32I { Ok(_) => println!("VM > Program exited peacefully"), Err(e) => println!("VM > Program exited violently with error: {}", e), } + + loop { + println!("VM > CPU has stalled"); + std::thread::sleep(std::time::Duration::from_secs(10)); + } } } diff --git a/src/system/ram.rs b/src/system/ram.rs index b23b4b7..cba81ce 100644 --- a/src/system/ram.rs +++ b/src/system/ram.rs @@ -1,13 +1,14 @@ use crate::system::bus; use crate::system::rv32; -//pub const DRAM_SIZE: u32 = 1 * 1024 * 1024 * 1024; // 1GB -pub const DRAM_SIZE: u32 = 1 * 1024; // 1KB +pub const DRAM_SIZE: u32 = 1 * 1024 * 1024 * 1024; // 1GB +// pub const DRAM_SIZE: u32 = 1 * 1024; // 1KB pub struct RAM(pub Vec); impl RAM { pub fn new() -> RAM { + println!("VM > Initialised RAM with size: {} bytes", DRAM_SIZE); RAM(vec![0; DRAM_SIZE as usize]) } diff --git a/test/test b/test/test index 8dfc0c93f9a1e0039740b68d5a9f0d46c9de041d..6be73fa10ed54ea1bbfc62cd303d2a72d614ba96 100755 GIT binary patch delta 232 zcmZ3WzCwM12BXGAO?gI{iH+hD6D&Ao7$87qdpHX45pde6<0IC{4 zxEe=6aYJ<36sW8Mnl6Uq(q7_M9ID MA$A#0J}4v)06wcH00000 delta 212 zcmZ3XzCe9~2BX46O?gIviH+hD6D&9d7$87k=s0+TNah%*XIekq_YDF8DGs>lhfhLJ&FvZ0_jhHNZcHW7;~ sLvpgGVX$Sf*W`(U-+|_L3Yi1RgF^O<29p_u?HL;;I|9ju70-gW> diff --git a/test/test.hex b/test/test.hex index cd521ea..a52b6cc 100644 --- a/test/test.hex +++ b/test/test.hex @@ -1,2 +1,3 @@ -:100000001301301293013012630231009302400653 +:1000000013019006B7510BB063143100B7004200E2 +:0C00100093009006370400808324040055 :00000001FF diff --git a/test/test.lst b/test/test.lst index 12a9fc6..3e9c15d 100644 --- a/test/test.lst +++ b/test/test.lst @@ -4,10 +4,13 @@ test: file format elf64-littleriscv Disassembly of section .text: -0000000000000000 : - 0: 12300113 addi sp,zero,291 - 4: 12300193 addi gp,zero,291 - 8: 00310263 beq sp,gp,c
+0000000000000000 : + 0: 06900113 addi sp,zero,105 + 4: b00b51b7 lui gp,0xb00b5 + 8: 00311463 bne sp,gp,10
+ c: 004200b7 lui ra,0x420 -000000000000000c
: - c: 06400293 addi t0,zero,100 +0000000000000010
: + 10: 06900093 addi ra,zero,105 + 14: 80000437 lui s0,0x80000 + 18: 00042483 lw s1,0(s0) # ffffffff80000000 <__global_pointer$+0xffffffff7fffe7e4> diff --git a/test/test.map b/test/test.map index fd063e6..cc1f398 100644 --- a/test/test.map +++ b/test/test.map @@ -4,15 +4,15 @@ test: file format elf64-littleriscv SYMBOL TABLE: 0000000000000000 l d .text 0000000000000000 .text 0000000000000000 l d .riscv.attributes 0000000000000000 .riscv.attributes -0000000000000000 l df *ABS* 0000000000000000 ccI1S9sJ.o -000000000000000c l .text 0000000000000000 main -0000000000001810 g *ABS* 0000000000000000 __global_pointer$ -0000000000001010 g .text 0000000000000000 __SDATA_BEGIN__ +0000000000000000 l df *ABS* 0000000000000000 ccvY3sZu.o +0000000000000010 l .text 0000000000000000 main +000000000000181c g *ABS* 0000000000000000 __global_pointer$ +000000000000101c g .text 0000000000000000 __SDATA_BEGIN__ 0000000000000000 *UND* 0000000000000000 _start -0000000000001010 g .text 0000000000000000 __BSS_END__ -0000000000001010 g .text 0000000000000000 __bss_start -0000000000001010 g .text 0000000000000000 __DATA_BEGIN__ -0000000000001010 g .text 0000000000000000 _edata -0000000000001010 g .text 0000000000000000 _end +0000000000001020 g .text 0000000000000000 __BSS_END__ +000000000000101c g .text 0000000000000000 __bss_start +000000000000101c g .text 0000000000000000 __DATA_BEGIN__ +000000000000101c g .text 0000000000000000 _edata +0000000000001020 g .text 0000000000000000 _end