If you don't want to delegate the fun of learning to an LLM, here's how I've built a RV64IM simulator in C in a weekend. All you need is an opcode table, the RISC-V specs and to implement each instruction; the good thing of RISC CPUs is that instructions are very simple (i.e. pretty much everything is a variation of `dest = src1 OP src2`) and memory instructions are dedicated. The other cool thing is that there are no "flags". Start with the base instruction set, then you can add M on top later. 64-bit support requires just a handful more instructions to zero/sign extend from 32-bit.Then, wire your simulator to https://github.com/riscv-software-src/riscv-tests, and there you have an official test suite. When everything passes, you have a fully-compliant RISC-V CPU. You can at this point tell GCC or Rust or your favourite language to compile to RV32IM and see it run on your simulator. It's a very gratifying process.
If you get at this stage, you might want to use the ecall instruction to hard-code I/O operations such as "read from stdin" or "print a character", and there you have a sandboxed CPU that you can target with your favourite programming language. Make it run DOOM (start with https://github.com/ozkl/doomgeneric and see which I/O do you need), or turn it into a toy game console; the sky's the limit.
---
Here's a copy-paste of the list of resources I have saved in my notes:
- https://github.com/libriscv/libriscv
A very fast RISC-V VM with sandboxing of memory and syscalls.
- https://luplab.gitlab.io/rvcodecjs/
RISC-V Instruction Encoder/Decoder
- https://www.cs.sfu.ca/~ashriram/Courses/CS295/assets/noteboo...
Reference card
- https://cs.brown.edu/courses/csci1952y/2024/assets/docs/risc...
Spec
- https://riscv-software-src.github.io/riscv-unified-db/manual...
- ABI: https://lists.riscv.org/g/tech-psabi/attachment/61/0/riscv-a...
Good luck!