ADD example program and ISA Inst Types implemented
This commit is contained in:
65
Cargo.lock
generated
65
Cargo.lock
generated
@@ -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"
|
||||
|
||||
@@ -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
13
src/bus.rs
Normal 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
59
src/inst.rs
Normal 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,
|
||||
}
|
||||
85
src/main.rs
85
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<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
31
src/ram.rs
Normal 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
17
src/rv32.rs
Normal 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
4
test/add.S
Normal file
@@ -0,0 +1,4 @@
|
||||
main:
|
||||
addi x29, x0, 5
|
||||
addi x30, x0, 37
|
||||
add x31, x30, x29
|
||||
BIN
test/add.bin
Normal file
BIN
test/add.bin
Normal file
Binary file not shown.
22
test/test.s
22
test/test.s
@@ -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"
|
||||
Reference in New Issue
Block a user