What? - Why & Who? - How?
This is a modular emulator for the RV32I processor architecture, written in Rust. It is strongly inspired by Bruno Levy's implementation in Verilog.
The goal of this project is to provide a way to emulate RISC-V programs written in Rust using an emulator that is also written in Rust. This project is primarily intended for educational purposes.
To execute the demo, follow these steps:
- Before proceeding, ensure that
rust
andcargo
are installed on your system. Then, add the target and installcargo-binutils
using the following commands:
rustup target add riscv32i-unknown-none-elf
cargo install cargo-binutils
rustup component add llvm-tools-preview
- Once the repository is cloned. In the terminal, execute the following command:
make run_demo
The provided example is a program
targeting riscv32i-unknown-none-elf
. A linker script is required during the build process to define the memory map of the microarchitecture.
A Makefile
is included, which generates an .elf
file located at example/riscv_asm.elf
, along with several binary files in the example/binaries
directory. Among these binaries, the .mem
file houses the .data
section, while the .prog
file contains the .text
section.
This implementation offers flexibility in creating a "cpu" instance. You can either use the path to the .elf
file or the individual binary files.
The linker script(at example/riscv_asm/link.x
) generates a memory map
. In this memory scheme, the processor perceives the "program" (or ROM) and the "memory" (or RAM) as the same physical hardware. However, this is not always the case. In fact, this implementation separates the program and the memory.
The memory map, as defined by the linker script, allocates 2K for the program and 1K for the RAM, resulting in a contiguous 3K in total. Consequently, the memory must be a Vec<u32>
with 3K positions. However, the actual data is stored starting from mem[2048..]
.
Improving this to utilize less space would be beneficial.
- Preface - The Embedonomicon
- GitHub - rust-embedded/cargo-binutils: Cargo subcommands to invoke the LLVM tools shipped with the Rust toolchain