StudyRISC-V reference
riscvsim executes RV32I and RV32M instructions on a five-stage pipeline. The browser and CLI use the same Rust engine.
addi x1, x0, 5
addi x2, x1, 3
add x3, x2, x1Install
Quick install
curl -fsSL https://studyriscv.com/install.sh | shHomebrew
brew tap rawcache/riscvsim
brew install riscvsimCLI
run
riscvsim run program.s
riscvsim run program.s --verbose
riscvsim run program.s --max-cycles 5000000| Flag | Effect |
|---|---|
-v, --verbose | Print every retired instruction and register change. |
--max-cycles N | Stop after N cycles. Default: 1,000,000. |
-i, --interactive | Open the terminal simulator. |
Interactive session
riscvsimRunning riscvsim with no arguments opens the interactive session: the pipeline, register, memory, and output views, plus a slash-command prompt. Anything not starting with / is assembled and run as RISC-V source.
| Command | Effect |
|---|---|
/help | List every slash command. |
/run <file> | Load and run an assembly file. |
/demo [n] | Load a built-in sample program and run it. |
/serve [--port N] | Open the loaded program in the browser UI. |
/reset | Reset the loaded program. |
/version | Show installed and latest versions. |
/doctor | Inspect versions, PATH copies, and update instructions. |
/examples | Show the sample-program walkthrough. |
/exit | Leave the session (also /quit). |
tui
riscvsim tui
riscvsim tui program.s
riscvsim tui program.s --tourOpens the same interactive session with a file preloaded. --tour replays the first-run walkthrough.
serve
riscvsim serve program.s
riscvsim serve program.s --port 4300Starts an in-memory local session and serves the browser interface. Closing the process ends the session. This stays available as a top-level command for scripting; /serve inside the interactive session does the same thing for the program you already have loaded.
doctor
riscvsim doctorReports the active executable, every PATH-visible copy, likely install methods, versions, and the latest published release.
Assembly syntax
.data
values: .word 1, 2, 3
label: .asciz "ok"
.text
main:
la t0, values
lw a0, 0(t0)
ret| Directive | Support |
|---|---|
.text, .data | Select the text or data section. |
.word, .half, .byte | Emit integer data. |
.ascii, .asciz, .string | Emit string data. |
.align, .p2align | Align data by a power of two. |
RV32IM instructions
| Family | Instructions |
|---|---|
| Upper and jump | lui auipc jal jalr |
| Branches | beq bne blt bge bltu bgeu |
| Loads | lb lh lw lbu lhu |
| Stores | sb sh sw |
| Immediate ALU | addi slti sltiu xori ori andi slli srli srai |
| Register ALU | add sub sll slt sltu xor srl sra or and |
| Multiply and divide | mul mulh mulhsu mulhu div divu rem remu |
| System | ecall ebreak fence |
Pseudo-instructions such as li, la, mv, j, call, and ret expand during assembly.
Memory map
0x00000000 text segment
0x10000000 data segment
0x7ffffffc initial stack pointerThe stack grows toward lower addresses. Loads and stores use little-endian byte order.
Pipeline
IF -> ID -> EX -> MEM -> WBThe engine implements forwarding, a one-cycle load-use stall, and a two-bit branch predictor. A misprediction flushes two younger instructions.
Rust engine
use sim_engine::{assemble, Pipeline};
let program = assemble(source)?;
let mut pipeline = Pipeline::new(program);
pipeline.step_cycle();
let snapshot = pipeline.snapshot();pub fn assemble(source: &str) -> Result<Program, Vec<AsmError>>
pub fn c_to_asm(source: &str) -> Result<String, TranslateError>
pub fn asm_to_c(source: &str) -> Result<String, TranslateError>WASM interface
import init, { assemble_pipeline } from "./riscvsim_core.js";
await init();
const sim = assemble_pipeline(source);
sim.step_cycle();
const snapshot = sim.snapshot();
const bytes = sim.read_memory(0x10000000, 16);| Method | Result |
|---|---|
step_cycle() | Advance one pipeline cycle. |
step_cycles(n) | Advance up to N cycles. |
run_to_completion(max) | Run until halt or the cycle cap. |
step_back() | Restore the previous snapshot when available. |
reset() | Restore the loaded program to cycle zero. |
snapshot() | Return pipeline, register, memory, and halt state. |
Translation interface
const assembly = translate_c_to_asm(cSource);
const illustrative = translate_asm_to_c(assemblySource);translate_c_to_asm compiles the supported C subset to runnable RV32IM assembly.
translate_asm_to_c returns illustrative pseudocode. Its output is not compilable C.
| Supported C | Not supported |
|---|---|
| Integer variables and arrays, arithmetic, comparisons, conditionals, loops, functions, calls, recursion | Pointers, structs, globals, strings, floats, standard library calls |