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!
I made a post a while back that details the entire process: https://www.reddit.com/r/EmuDev/comments/1t1or4j/doom_runs_o...