From 28ae5df372c3501078583a1d22be61d032b6c0db Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Mon, 22 May 2023 13:59:56 +0100 Subject: [PATCH] Ok this is epic --- .gitmodules | 3 ++ riscv-gnu-toolchain | 1 + src/main.rs | 90 +++++++++++++++++++++++++++++++++++++++++---- test/Makefile | 18 +++++++++ test/basic.S | 6 +++ test/test.S | 6 +++ test/test.c | 4 ++ 7 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 .gitmodules create mode 160000 riscv-gnu-toolchain create mode 100644 test/Makefile create mode 100644 test/basic.S create mode 100644 test/test.S create mode 100644 test/test.c diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1a00aef --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "riscv-gnu-toolchain"] + path = riscv-gnu-toolchain + url = https://github.com/riscv/riscv-gnu-toolchain diff --git a/riscv-gnu-toolchain b/riscv-gnu-toolchain new file mode 160000 index 0000000..2c4d31f --- /dev/null +++ b/riscv-gnu-toolchain @@ -0,0 +1 @@ +Subproject commit 2c4d31fc60fca753c4379f716ff0cea5dc5b5c9f diff --git a/src/main.rs b/src/main.rs index 8c46107..44c72ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,18 @@ +use std::io::Read; +use std::io::BufReader; +use std::fs::File; + const XLEN: usize = 32; + +const DRAM_SIZE: usize = 1 * 1024 * 1024 * 1024; // 1GB +const DRAM_BASE: usize = 0x800000000; + // define words as byte fraction -const QUADWORD: usize = 16; -const DOUBLEWORD: usize = 8; -const WORD: usize = 4; -const HALFWORD: usize = 2; -const BYTE: usize = 1; +//const QUADWORD: usize = 16; +//const DOUBLEWORD: usize = 8; +//const WORD: usize = 4; +//const HALFWORD: usize = 2; +//const BYTE: usize = 1; type QuadWord = u128; type DoubleWord = u64; @@ -12,18 +20,84 @@ type Word = u32; type HalfWord = u16; type Byte = u8; +struct Bus { + // 1GB of memory + memory: Vec, +} + +impl Bus { + fn new() -> Bus { + Bus { + memory: vec![0; DRAM_SIZE], + } + } +} + +impl Default for Bus { + fn default() -> Self { + Self::new() + } +} + +struct Instruction { + opcode: u8, + rd: u8, + rs1: u8, + rs2: u8, + funct3: u8, + funct7: u8, + imm: u32, +} + struct VMRV32I { + // 32 bi bus + bus: Bus, // 32 registers x: [Word; 32], // 32-bit program counter pc: Word, } -struct VMChunk { +impl VMRV32I { + fn new() -> VMRV32I { + VMRV32I { + bus: Bus::new(), + x: [0; 32], + pc: 0, + } + } + fn load_prog(&mut self, file: &str) { + println!("VM > Loading program: {}", file); + + let f = File::open(file).expect("file not found"); + let mut reader = BufReader::new(f); + let mut buffer = Vec::new(); + reader.read_to_end(&mut buffer).expect("error reading file"); + + print!("VM > Program size: {} bytes", buffer.len()); + // put program at the base of DRAM + for i in 0..buffer.len() { + self.bus.memory[i + DRAM_BASE] = buffer[i]; + } + + println!("VM > Program loaded to 0x{:08x}", self.pc); + } + + fn init_cpu(&mut self) { + println!("VM RISC-V 32I CPU"); + println!("-----------------"); + println!("VM > Initializing CPU"); + + self.pc = DRAM_BASE as Word; + self.x[0] = 0; // x0 is tied to ground + } } fn main() { - println!("Hello, world!"); -} + println!("VM Starting Up"); + let mut cpu = VMRV32I::new(); + cpu.load_prog("test.bin"); + cpu.init_cpu(); +} diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..b683d27 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,18 @@ +GCC_COMPILER=riscv32-unknown-elf-gcc +GCC_OBJCOPY=riscv32-unknown-elf-objcopy + +all: + assemble + build + @echo "Done" + +assemble: + $(GCC_COMPILER) -S test.c + +build: + $(GCC_COMPILER) -Wl,-Ttext=0x0 -nostdlib -march=rv64i -mabi=lp64 -o test test.S + $(GCC_OBJCOPY) -O binary test test.bin + +clean: + rm -f test test.bin + diff --git a/test/basic.S b/test/basic.S new file mode 100644 index 0000000..9d1b64f --- /dev/null +++ b/test/basic.S @@ -0,0 +1,6 @@ +ADDI x2, x0, 1 + +loop: + SUB x1, x1, x2 + SW x1, 4(x0) + BLT x0, x1, loop diff --git a/test/test.S b/test/test.S new file mode 100644 index 0000000..9d1b64f --- /dev/null +++ b/test/test.S @@ -0,0 +1,6 @@ +ADDI x2, x0, 1 + +loop: + SUB x1, x1, x2 + SW x1, 4(x0) + BLT x0, x1, loop diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..3d13523 --- /dev/null +++ b/test/test.c @@ -0,0 +1,4 @@ +int main() { + int x = 1 + 2; + return 0; +}