Simple RISC-V Emulator in WebAssembly
This is an exciting project I've been thinking about. A RISC-V Emulator in WASM that runs in your browser, perhaps on this very page!
I have a soft spot for TypeScript (basically with which I wrote this entire website), but I love Rust even more. When Mr.Moonshine told me his idea, I was very excited. After fighting the Rust compiler with some whining and cursing, we got a simple prototype that has registers, memories, ALU, with a five level pipeline.
Last week I got the idea to turn this babe into a runnable package on browser so everyone can try RISC-V without leaving the blog or downloading any file. The best option would be to turn it into a WebAssembly package. This means we can run a performance-oriented program at a near-native binary speed in a website.
Rust to WASM
The translation from Rust to WASM went very smooth. Our emulator has one only main entry that takes a 'ROM' file in hex format. So we just use the tool
The only problem I encountered was the limitation from the browser. By default, we allocated 4GB memory for RAM in the emulator. However, browsers don't allow that much memory in a single web page, so I cut it down to 256MB until further research. Interestingly, Safari on iOS can also run WASM, but it doesn't even allow 256MB. Now I cut it down to 4MB to make it run.
At this stage, we don't have to worry about running out of memory. But this thing does show that there is still a lot of work to be done afterwards.
Next Step: More functionalities
It's too early to show off this project. We still don't support calling convention (e.g. stack memory), error handling, interrupts, device I/O, privilege mode, etc. We don't even have branch instructions. Some of them are easy to implement, but some of them need further discussion.
The final step is to make this emulator a minimal virtual machine on which we can run Operating Systems. Think of running an Linux virtual machine in your browser tab (or maybe in your mobile browser tab)!
Some efforts has been made on other architectures to run virtual machines (emulators) with WASM. Here I put some brilliant projects.
For example, on X86:
And on RISC-V:
How can I make you read the entire blog without giving you anything fun? I made this little toy that actually runs a little piece of RISC-V assembly with WebAssembly. Just click the "Run" button and see how the machine works! If you don't believe me, feel free to press F12 and check the
rv_emu_rs.wasm file (it won't load until you click the button)!
An update to the demo example is on Rv32_emu (mstmoonshine.github.io), but it is still only a preliminary demonstration. I'll keep posting to keep up if we implement some big features.
YouTube video: Building The Worlds First CPU in TypeScript? (No Really!) ↩
© LICENSED UNDER CC BY-NC-SA 4.0