ADD example program and ISA Inst Types implemented

This commit is contained in:
Benjamin Kyd
2023-05-24 22:13:14 +01:00
parent 0a7f8663dd
commit f41bd7970b
10 changed files with 224 additions and 75 deletions

65
Cargo.lock generated
View File

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

View File

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

13
src/bus.rs Normal file
View File

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

59
src/inst.rs Normal file
View File

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

View File

@@ -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<Byte>,
}
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<inst::RType>,
i: std::mem::ManuallyDrop<inst::IType>,
s: std::mem::ManuallyDrop<inst::SType>,
b: std::mem::ManuallyDrop<inst::BType>,
u: std::mem::ManuallyDrop<inst::UType>,
j: std::mem::ManuallyDrop<inst::JType>,
}
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();
}

31
src/ram.rs Normal file
View File

@@ -0,0 +1,31 @@
use crate::rv32;
pub const DRAM_SIZE: u32 = 1 * 1024 * 1024 * 1024; // 1GB
pub struct RAM(pub Vec<rv32::Byte>);
impl RAM {
pub fn new() -> RAM {
RAM(vec![0; DRAM_SIZE as usize])
}
pub fn len(&mut self) -> usize {
self.0.len()
}
//fn read<T>(&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:
//}
//}
}

17
src/rv32.rs Normal file
View File

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

4
test/add.S Normal file
View File

@@ -0,0 +1,4 @@
main:
addi x29, x0, 5
addi x30, x0, 37
add x31, x30, x29

BIN
test/add.bin Normal file

Binary file not shown.

View File

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