Load / Store operations

This commit is contained in:
Ben Kyd
2023-07-18 22:18:04 +01:00
parent f46b560559
commit 0c55749742
10 changed files with 96 additions and 41 deletions

View File

@@ -22,11 +22,11 @@ pub struct CPUState {
pub x: [rv32::Word; 32],
pub pc: rv32::Word,
pub trap: rv32::Word,
pub bus: Rc<RefCell<Bus>>,
}
pub struct CPU {
state: CPUState,
bus: Rc<RefCell<Bus>>,
instruction_decoder: Rc<RefCell<decode::DecodeCycle>>,
extensions: Vec<char>,
}
@@ -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(())
}

View File

@@ -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),

View File

@@ -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));
}
}
}

View File

@@ -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<rv32::Byte>);
impl RAM {
pub fn new() -> RAM {
println!("VM > Initialised RAM with size: {} bytes", DRAM_SIZE);
RAM(vec![0; DRAM_SIZE as usize])
}

BIN
test/test

Binary file not shown.

View File

@@ -1,6 +1,11 @@
addi x2, x0, 0x123
addi x3, x0, 0x123
beq x2, x3, main
addi x2, x0, 0x69
lui x3, 0xB00B5
bne x2, x3, main
lui x1, 0x420
mai:
addi t0, x0, 100
main:
addi x1, x0, 0x69
lui x8, 0x80000
lw x9, 0x0(x8)
# addi x8, x8, 1
# sw x8, 0x80000000

Binary file not shown.

View File

@@ -1,2 +1,3 @@
:100000001301301293013012630231009302400653
:1000000013019006B7510BB063143100B7004200E2
:0C00100093009006370400808324040055
:00000001FF

View File

@@ -4,10 +4,13 @@ test: file format elf64-littleriscv
Disassembly of section .text:
0000000000000000 <main-0xc>:
0: 12300113 addi sp,zero,291
4: 12300193 addi gp,zero,291
8: 00310263 beq sp,gp,c <main>
0000000000000000 <main-0x10>:
0: 06900113 addi sp,zero,105
4: b00b51b7 lui gp,0xb00b5
8: 00311463 bne sp,gp,10 <main>
c: 004200b7 lui ra,0x420
000000000000000c <main>:
c: 06400293 addi t0,zero,100
0000000000000010 <main>:
10: 06900093 addi ra,zero,105
14: 80000437 lui s0,0x80000
18: 00042483 lw s1,0(s0) # ffffffff80000000 <__global_pointer$+0xffffffff7fffe7e4>

View File

@@ -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