The Emulator is a minimal RISC-V emulator written in Go, focused on the RV32I base integer instruction set. The goal is to build it incrementally to understand how a CPU fetches, decodes, and executes instructions. This emulator is intentionally simple. No third-party packages, no abstractions too early. The goal is to learn how computers execute code, at the instruction level.
The Assembler is a minimal RISC-V assembler written in C. It converts human-readable assembly code (.asm
) into machine code in the RISC-V RV32I instruction format. The assembler is intentionally kept simple to mirror the incremental approach of the emulator.
- Hands-on learning for the RISC-V basics
- Revision of Go & C programming languages
- Experiments to combine multiple programming languages
Instruction | Description | Assembler | Emulator |
---|---|---|---|
ADD |
Add two registers | ✅ | ✅ |
ADDI |
Add register + immediate | ✅ | ✅ |
LW |
Load word from memory | ✅ | ✅ |
SW |
Store word to memory | ✅ | ✅ |
BEQ |
Branch if equal | ✅ | ✅ |
JAL |
Jump and link | ✅ | ✅ |
From the project root:
make rasm # Builds the assembler and places binary at out/rasm
./out/rasm sample/sample.asm -o sample/out.s # Runs the assembler
You can explore some of the sample risc-v asm codes from docs/sample
make emu # Runs the emulator
You can feed the output .s
file from assembler as the program slice in main.go, line#13
- Combine the assembler and emulator into a single toolchain
- Add unit tests and more documentation
- Implement enhancements and improvements based on further learning
This is my first project built with the help of 🤖 Generative AI specifically, ChatGPT. I’ve used it to:
- Understand binary encoding of RISC-V mnemonics and instruction formats
The assembler wasn’t part of the original plan, it was introduced to save time and eliminate the frustration of manual and prompt based HEX generation, an example instance can be found here: headaches of manual of prompt based hex generation