From f41bd7970ba6a2222857130fd27fb84e2cabec90 Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Wed, 24 May 2023 22:13:14 +0100 Subject: [PATCH] ADD example program and ISA Inst Types implemented --- Cargo.lock | 65 +++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- src/bus.rs | 13 ++++++++ src/inst.rs | 59 +++++++++++++++++++++++++++++++++++ src/main.rs | 85 +++++++++++++++++++++------------------------------ src/ram.rs | 31 +++++++++++++++++++ src/rv32.rs | 17 +++++++++++ test/add.S | 4 +++ test/add.bin | Bin 0 -> 12 bytes test/test.s | 22 ------------- 10 files changed, 224 insertions(+), 75 deletions(-) create mode 100644 src/bus.rs create mode 100644 src/inst.rs create mode 100644 src/ram.rs create mode 100644 src/rv32.rs create mode 100644 test/add.S create mode 100644 test/add.bin delete mode 100644 test/test.s diff --git a/Cargo.lock b/Cargo.lock index 8c35cef..985844e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,71 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "modular-bitfield" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" +dependencies = [ + "modular-bitfield-impl", + "static_assertions", +] + +[[package]] +name = "modular-bitfield-impl" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +dependencies = [ + "proc-macro2", +] + [[package]] name = "riscy-rust" version = "0.1.0" +dependencies = [ + "modular-bitfield", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" diff --git a/Cargo.toml b/Cargo.toml index 77e9b88..d9c7b83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,5 @@ name = "riscy-rust" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +modular-bitfield = "0.11.2" diff --git a/src/bus.rs b/src/bus.rs new file mode 100644 index 0000000..2dac9a5 --- /dev/null +++ b/src/bus.rs @@ -0,0 +1,13 @@ +pub const DRAM_BASE: u32 = 0x80000000; + +use crate::ram; + +pub struct Bus { + pub memory: ram::RAM, +} + +impl Bus { + pub fn new() -> Bus { + Bus { memory: ram::RAM::new() } + } +} diff --git a/src/inst.rs b/src/inst.rs new file mode 100644 index 0000000..a6f3e07 --- /dev/null +++ b/src/inst.rs @@ -0,0 +1,59 @@ +use modular_bitfield::prelude::*; + +#[bitfield] +pub struct RType { + opcode: B7, + rd: B5, + funct3: B3, + rs1: B5, + rs2: B5, + funct7: B7, +} + +#[bitfield] +pub struct IType { + opcode: B7, + rd: B5, + funct3: B3, + rs1: B5, + imm: B12, +} + +#[bitfield] +pub struct SType { + opcode: B7, + imm_l: B5, + funct3: B3, + rs1: B5, + rs2: B5, + imm_h: B7, +} + +#[bitfield] +pub struct BType { + opcode: B7, + imm_11: B1, + imm_4_1: B4, + funct3: B3, + rs1: B5, + rs2: B5, + imm_10_5: B6, + imm_12: B1, +} + +#[bitfield] +pub struct UType { + opcode: B7, + rd: B5, + imm: B20, +} + +#[bitfield] +pub struct JType { + opcode: B7, + rd: B5, + imm_19_12: B8, + imm_11: B1, + imm_10_1: B10, + imm_20: B1, +} diff --git a/src/main.rs b/src/main.rs index ed2e00f..d798a0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,60 +2,32 @@ use std::fs::File; use std::io::BufReader; use std::io::Read; -const XLEN: usize = 32; +mod rv32; +mod bus; +mod ram; +mod inst; -const DRAM_SIZE: usize = 1 * 1024 * 1024 * 1024; // 1GB -const DRAM_BASE: usize = 0x8000; +use crate::ram::*; +use crate::bus::*; -// 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; - -type QuadWord = u128; -type DoubleWord = u64; -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: Byte, - rd: Byte, - rs1: Byte, - rs2: Byte, - funct3: Byte, - funct7: Byte, - imm: Word, +#[repr(align(8))] +union Instruction { + inst: rv32::Word, + r: std::mem::ManuallyDrop, + i: std::mem::ManuallyDrop, + s: std::mem::ManuallyDrop, + b: std::mem::ManuallyDrop, + u: std::mem::ManuallyDrop, + j: std::mem::ManuallyDrop, } struct VMRV32I { // 32 bi bus - bus: Bus, + bus: bus::Bus, // 32 registers - x: [Word; 32], + x: [rv32::Word; 32], // 32-bit program counter - pc: Word, + pc: rv32::Word, } impl VMRV32I { @@ -79,7 +51,7 @@ impl VMRV32I { // put program at the base of DRAM for i in 0..buffer.len() { - self.bus.memory[i + DRAM_BASE] = buffer[i]; + self.bus.memory.0[i] = buffer[i]; } println!("VM > Program loaded to 0x{:08x}", self.pc); @@ -91,8 +63,19 @@ impl VMRV32I { println!("VM > Initializing CPU"); self.bus = Bus::new(); - self.pc = DRAM_BASE as Word; - self.x[0] = 0; // x0 is tied to ground + self.pc = DRAM_BASE as rv32::Word; + self.x[0] = 0x00000000; // x0 is tied to ground + self.x[2] = self.bus.memory.len() as u32; // x2 the addressable space + } + + fn fetch(&mut self) -> Instruction { + Instruction { inst: 0xFFFFFFFF } + } + + fn exec(&mut self) { + while self.pc > self.bus.memory.len() as u32 { + let inst = self.fetch(); + } } } @@ -101,6 +84,6 @@ fn main() { let mut cpu = VMRV32I::new(); cpu.init_cpu(); - cpu.load_prog("./test/test.bin"); + cpu.load_prog("./test/add.bin"); + cpu.exec(); } - diff --git a/src/ram.rs b/src/ram.rs new file mode 100644 index 0000000..fac70e5 --- /dev/null +++ b/src/ram.rs @@ -0,0 +1,31 @@ +use crate::rv32; + +pub const DRAM_SIZE: u32 = 1 * 1024 * 1024 * 1024; // 1GB + +pub struct RAM(pub Vec); + +impl RAM { + pub fn new() -> RAM { + RAM(vec![0; DRAM_SIZE as usize]) + } + + pub fn len(&mut self) -> usize { + self.0.len() + } + + //fn read(&mut self, address: XLen as usize) -> T { + //let memory = &self.0; + //let shift: T; + //// Little endian!!! + //match T { + ////QuadWord: + ////DoubleWord: + //Word => shift = (memory[address] as T) + //| ((memory[address] as T) << 8) + //| ((memory[address] as T) << 16) + //| ((memory[address] as T) << 24) + ////HalfWord: + ////Byte: + //} + //} +} diff --git a/src/rv32.rs b/src/rv32.rs new file mode 100644 index 0000000..f723c0e --- /dev/null +++ b/src/rv32.rs @@ -0,0 +1,17 @@ +pub const XLEN: usize = 32; +pub type XLen = u32; + +// 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; + +pub type QuadWord = u128; +pub type DoubleWord = u64; +pub type Word = u32; +pub type HalfWord = u16; +pub type Byte = u8; + + diff --git a/test/add.S b/test/add.S new file mode 100644 index 0000000..4e2462c --- /dev/null +++ b/test/add.S @@ -0,0 +1,4 @@ +main: + addi x29, x0, 5 + addi x30, x0, 37 + add x31, x30, x29 diff --git a/test/add.bin b/test/add.bin new file mode 100644 index 0000000000000000000000000000000000000000..07d354d152fa11c8e4b7cc7e703ceb254f457b09 GIT binary patch literal 12 TcmbQt7r-FQAHcMk|2`uC5={dL literal 0 HcmV?d00001 diff --git a/test/test.s b/test/test.s deleted file mode 100644 index 2af7076..0000000 --- a/test/test.s +++ /dev/null @@ -1,22 +0,0 @@ - .file "test.c" - .option nopic - .attribute arch, "rv32i2p1" - .attribute unaligned_access, 0 - .attribute stack_align, 16 - .text - .align 2 - .globl main - .type main, @function -main: - addi sp,sp,-32 - sw s0,28(sp) - addi s0,sp,32 - li a5,3 - sw a5,-20(s0) - li a5,0 - mv a0,a5 - lw s0,28(sp) - addi sp,sp,32 - jr ra - .size main, .-main - .ident "GCC: (g2ee5e430018) 12.2.0"