Load / Store operations
This commit is contained in:
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
|
||||
|
||||
15
test/test.S
15
test/test.S
@@ -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
|
||||
|
||||
BIN
test/test.bin
BIN
test/test.bin
Binary file not shown.
@@ -1,2 +1,3 @@
|
||||
:100000001301301293013012630231009302400653
|
||||
:1000000013019006B7510BB063143100B7004200E2
|
||||
:0C00100093009006370400808324040055
|
||||
:00000001FF
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user