Free · Open Source · RV32IMAF

Learn RISC-V by
watching it run.

RAVEN is a free RISC-V simulator and IDE that runs in your terminal. Write assembly, assemble with one keystroke, and step through the program while the registers, memory, cache, the five-stage pipeline, and address translation all update as it runs. You see what the machine does, not just what it prints.

RV32IMAF Architecture
5-Stage Pipeline
Cache + TLB Simulator
Free Open Source
Editor Run Pipeline Cache VM Docs RV32IMAF
.text
main:
1 li a0, 10 ; n = 10
2 call fib
3 ecall
fib:
5 addi sp, sp, -8
6 sw ra, 4(sp)
7 sw a0, 0(sp)
8 blt a0, 2, base
main:
0x00 li a0,10 [I]
0x04 call fib [J]
0x08 ecall [S]
fib:
0x0c addi sp,sp,-8 [I]
0x10 sw ra,4(sp) [S] ×4
0x14 sw a0,0(sp) [S] ×4
0x18 blt a0,2,base [B] ×4
addi sp, sp, -8
type I-type
opcode 001_0011
rd x2 (sp)
rs1 x2 (sp)
funct3 000
imm -8
rs1 val 0x7FFFFFF8
result 0x7FFFFFF0
~1 cy [ALU]
IFlw t2
IDadd t1
EXbubble
MEMlw t0
WBaddi sp
load-use hazard · t0 not ready, EX stalls one cycle
forward MEM→EX active · predictor: taken · redirect on miss
cycle 37 stalls 6 flushes 2 IPC 0.82
5-stage in-order · full forwarding · 1-bit predictor · Main / Config subtabs
I-Cache
Hits2,048
Misses128
Hit rate94.1%
MPKI62.5
D-Cache
Hits840
Misses160
Hit rate84.0%
MPKI190.5
AMAT 1.12 cy IPC 0.89 cycles 1,024 RAM writes 288 B
Policy: LRU  ·  4-way  ·  16 B lines  ·  16 sets  ·  write-back
VA 0x0001_0A40 → VPN 0x00010 · off 0xA40
PA 0x0041_0A40 ← PPN 0x00410 · off 0xA40
VPN→PPN 0x10→0x410RWXUHIT
VPN→PPN 0x11→0x411RW-UHIT
VPN→PPN 0x2F→ walk----MISS
satp.mode Sv32 TLB hit 96.4% faults 3
Modes: Off / Sv32 / Custom / Manual · 4 KiB pages · configurable TLB geometry
Instruction Reference
addrd, rs1, rs2rd = rs1 + rs2
subrd, rs1, rs2rd = rs1 - rs2
addird, rs1, immrd = rs1 + imm
lird, immrd = imm [pseudo]
lwrd, off(rs)rd = mem[rs+off]
swrs2, off(rs1)mem[rs1+off] = rs2
beqrs1, rs2, lblif rs1 == rs2: jump
jalrd, lblrd = pc+4; jump
calllblra = pc+4; jump [pseudo]
ecallsystem call (a7 = nr)
cycle 42 CPI 1.12 IPC 0.89 PAUSED
Why RAVEN

One terminal app for the whole loop

Write, assemble, run, debug, and profile your RISC-V programs in a single window. No toolchain to install, no black boxes to trust.

Write and run in the same window

Built-in editor with syntax highlighting for instructions, registers, directives, and labels. Press Ctrl+R to assemble instantly, with no Makefile and no terminal juggling. Import .asm files from other simulators or export your work as a binary. It even loads ELF32 RISC-V binaries built by a real toolchain.

Syntax Highlighting Import / Export Ctrl+R Build

Step through every instruction

Run free, pause, or advance one instruction at a time. See exactly which register changes, by how much, and why. Set breakpoints on any instruction.

All 32 registers, always visible

Integer registers shown with ABI names (ra, sp, a0–a7, s0–s11…) plus hex and decimal side by side. Recently changed registers are highlighted automatically, and the float bank is one keypress away.

See inside every instruction

Each instruction is decoded into its fields: opcode, rd, rs1, rs2, funct3, funct7, sign-extended immediate. Understand encoding, not just mnemonics.

Run the five-stage pipeline

Step the classic IF, ID, EX, MEM, WB pipeline one cycle at a time. See instructions flow through each stage, watch forwarding paths light up, and catch load-use stalls, branch flushes, and cache stalls as they happen.

Watch virtual memory translate

A working MMU walks the page table and translates virtual addresses to physical ones a page at a time. See VPN to PPN mappings, TLB hits and misses, page faults, and the live page-table tree. Flip between Sv32, a custom scheme, or hardware-accurate manual mode.

Full RV32IMAF, plus multi-hart

Base integer (RV32I), multiply/divide (M), atomics (A), and single-precision float (F). Every instruction your textbook covers, plus the pseudo-instructions used in real code. Spawn extra harts and watch several cores run at once.

Make the memory hierarchy visible

A full I-cache + D-cache simulator tracks every fetch and memory access. Configure geometry and replacement policy, then watch hit rates, AMAT, and IPC update live. Compare configurations with a built-in baseline export.

I-Cache & D-Cache LRU / LFU / Clock / FIFO / MRU / Random Live Stats Visual Matrix
Workflow

Write → Run → Understand

RAVEN is built around one loop: write code, run it, and see exactly what happens inside the machine.

01 · WRITE

Editor Tab

Type RISC-V assembly in the built-in editor. Syntax highlighting colours instructions, registers, labels, and directives. Ghost hints show operand syntax as you type. Press Ctrl+R to assemble instantly; any error points at the exact line and reason.

02 · RUN

Run Tab

Step instruction by instruction or run free. The instruction list shows the current PC, decoded type badge, and execution heat. Registers and memory update on every step.

03 · PROFILE

Cache, Pipeline & VM Tabs

Switch to the Cache, Pipeline, or VM tab to see hit rates, AMAT, IPC, pipeline stalls, and address translation. Change a policy or a scheme, run again, and compare.

Pipeline Simulator

Step the pipeline one cycle at a time

The sequential view runs instruction by instruction. The pipeline view runs cycle by cycle, so you can see the hazards, stalls, and forwarding paths that the textbook only draws on paper.

  • Classic five stages. IF, ID, EX, MEM, WB, in order. Advance one cycle, run free, or pause, and watch each instruction move down the stages.
  • Hazards and forwarding. Data hazards are detected and resolved by bypass paths you can toggle on or off, so you can see exactly when a value is forwarded and when it can't be.
  • Branch prediction. Predict, redirect, and squash the wrong path. Flip the predictor and bypass settings to see how mispredictions cost you cycles.
  • Stalls made visible. Load-use stalls, replays, and MEM stalls from cache latency all show up as bubbles in the stage view.
  • Main and Config subtabs. Inspect the hazard map and per-cycle history, tune the pipeline behaviour, and export configs and results with Ctrl+E, Ctrl+L, and Ctrl+R.
Pipeline · Stages
StageInstructionState
IFlw t2, 0(t1)ok
IDadd t1, t0, t3ok
EXbubblestall
MEMlw t0, 0(sp)fwd
WBaddi sp, sp, -8ok
Hazard load-use · t0 forwarded MEM→EX next cycle
Cache Simulator

See the memory hierarchy work

Most simulators hide the cache. RAVEN shows the whole thing: per-access tracking, live statistics, a visual matrix of every cache line, and configurable policies so you can test what you learned in class.

  • Separate I-Cache and D-Cache. Instruction fetches and data loads/stores are tracked independently, with hit rates, miss counts, and MPKI reported per cache, plus extra levels (L2, L3) when you want them.
  • Six replacement policies. LRU, FIFO, LFU, Clock, MRU, and Random. Swap policy mid-run and watch your hit rate react, which makes it easy to compare what the textbook describes.
  • Configurable geometry. Sets, ways, block size, write policy, and inclusion policy, with three built-in presets (Small, Medium, Large) for quick starting points.
  • Academic metrics. AMAT (Average Memory Access Time), IPC, a CPI breakdown, and MPKI: the same numbers your architecture course asks you to calculate, computed for you.
  • Visual matrix view. Every set and way rendered as a colour-coded grid. Valid, tag, and dirty state are visible per cache line, and you can scroll the whole cache at a glance.
Cache · Stats
CacheHitsMissesRate
I-Cache 2 048 128 94.1 %
D-Cache 840 160 84.0 %
· · ·
Policy LRU · 4-way · 16 B lines · 16 sets
Virtual Memory & TLB

Follow an address from virtual to physical

Programs use virtual addresses; RAM uses physical ones. RAVEN's MMU walks the page table, translates one page at a time, and caches the result in the TLB, and it shows you every step.

  • Four modes. Off, Sv32, a Custom paging scheme you reshape yourself, or hardware-accurate Manual mode where your program drives satp and its own tables.
  • Didactic by default. In Sv32 and Custom the simulator installs a page map for you, so even a plain loop shows TLB hits and misses with no setup code.
  • The page table, live. Watch the real tree rooted at satp, straight from RAM: pointer entries expand into child tables, leaves are (super)pages, and cached entries are marked.
  • Configurable TLB. Set entry count, associativity, hit latency, and miss penalty. Apply resets the TLB; flush just drops the cached translations.
  • Faults and demand paging. In Manual mode, delegate page faults to supervisor mode, install the missing entry in a handler, run sfence.vma, and sret back to retry the access.
VM · Translation
VPNPPNPermTLB
0x000100x00410RWXUhit
0x000110x00411RW-Uhit
0x0002Fwalk…----miss
· · ·
satp Sv32 · 4 KiB pages · root PT @ 0x80020000
Included Programs

Real programs to run, study, and modify

Every example in RAVEN is ready to open, step through, and experiment with. Start with these, then write your own.

quick_sort_20_push_pop.s RISC-V Assembly
.data
arr: .word 33,12,7,25,9,13,5,1,44,3,18,2,29,8,21,6,10,17,14,4
msg: .asciz "Quicksort (20 elements)"
nl:  .byte  10, 0

.text
    printStrLn msg
    la   a0, arr          ; base address
    li   a1, 0            ; lo = 0
    li   a2, 19           ; hi = 19
    call quicksort

    la   t0, arr
    li   t4, 20
    li   t1, 0
print_loop:
    slli t2, t1, 2
    add  t2, t0, t2
    lw   t3, 0(t2)
    print    t3
    printStr nl
    addi t1, t1, 1
    blt  t1, t4, print_loop
    li   a0, 0
    li   a7, 93           ; syscall: exit
    ecall

; quicksort(a0=base, a1=lo, a2=hi)
quicksort:
    bge  a1, a2, qs_done
    push ra
    push s1  ; base
    push s2  ; lo
    push s3  ; hi
    push s4  ; pivot index
    mv   s1, a0
    mv   s2, a1
    mv   s3, a2
    call partition        ; → a0 = pivot index
    mv   s4, a0
    mv   a0, s1
    mv   a1, s2
    addi a2, s4, -1
    call quicksort        ; recurse left
    mv   a0, s1
    addi a1, s4, 1
    mv   a2, s3
    call quicksort        ; recurse right
    pop  s4
    pop  s3
    pop  s2
    pop  s1
    pop  ra
qs_done:
    ret

; partition(a0=base, a1=lo, a2=hi) → a0 = pivot index
partition:
    push ra
    push s0  ; pivot value
    push s1  ; base
    push s2  ; lo
    push s3  ; hi
    push s4  ; i
    push s5  ; j
    mv   s1, a0
    mv   s2, a1
    mv   s3, a2
    slli t0, s3, 2
    add  t0, s1, t0
    lw   s0, 0(t0)      ; pivot = arr[hi]
    addi s4, s2, -1     ; i = lo - 1
    mv   s5, s2          ; j = lo
part_loop:
    bge  s5, s3, part_done
    slli t1, s5, 2
    add  t1, s1, t1
    lw   t2, 0(t1)      ; arr[j]
    blt  s0, t2, skip_swap
    addi s4, s4, 1      ; i++
    beq  s4, s5, skip_swap
    slli t3, s4, 2
    add  t3, s1, t3
    lw   t4, 0(t3)      ; arr[i]
    sw   t2, 0(t3)      ; arr[i] = arr[j]
    sw   t4, 0(t1)      ; arr[j] = arr[i]
skip_swap:
    addi s5, s5, 1
    j    part_loop
part_done:
    addi t0, s4, 1       ; pivotIndex = i + 1
    slli t1, t0, 2
    add  t1, s1, t1
    lw   t2, 0(t1)
    slli t3, s3, 2
    add  t3, s1, t3
    lw   t4, 0(t3)
    sw   t4, 0(t1)      ; swap pivot into place
    sw   t2, 0(t3)
    mv   a0, t0
    pop  s5
    pop  s4
    pop  s3
    pop  s2
    pop  s1
    pop  s0
    pop  ra
    ret

Recursive Quicksort

Full recursive quicksort on a 20-element integer array. Demonstrates proper RISC-V calling convention with push/pop to save callee-saved registers across recursive calls.

  • Recursive call + stack frame via push/pop
  • Callee-saved registers (s0–s5)
  • Pointer arithmetic for in-place swaps
  • Partition function as a subroutine
  • exit(93) via raw ecall
bubble_sort_20.s RISC-V Assembly
.data
arr: .word 20,1,19,2,18,3,17,4,16,5,15,6,14,7,13,8,12,9,11,10
msg: .asciz "Sorted values:"
nl:  .byte  10, 0

.text
    printStrLn msg
    la   t0, arr       ; base address
    li   t4, 20        ; n = 20
    li   t1, 0         ; i = 0

outer:
    li   t2, 0
    sub  s2, t4, t1
    addi s2, s2, -1   ; limit = n - 1 - i

inner:
    slli t3, t2, 2    ; offset = j * 4
    add  t3, t0, t3   ; &arr[j]
    addi t5, t3, 4    ; &arr[j+1]
    lw   s0, 0(t3)
    lw   s1, 0(t5)
    blt  s0, s1, no_swap
    sw   s1, 0(t3)
    sw   s0, 0(t5)
no_swap:
    addi t2, t2, 1
    blt  t2, s2, inner
    addi t1, t1, 1
    blt  t1, t4, outer

    li   t2, 0
print_loop:
    slli t3, t2, 2
    add  t3, t0, t3
    lw   a0, 0(t3)
    print    a0
    printStr nl
    addi t2, t2, 1
    blt  t2, t4, print_loop

    li   a0, 0
    li   a7, 93        ; syscall: exit
    ecall

Bubble Sort

Classic O(n²) sort over a 20-element array in .data. Great for watching D-cache access patterns in the Cache tab, where the tight inner loop shows excellent spatial locality.

  • Static data with .word directive
  • Pointer arithmetic (slli + add)
  • In-place swap with lw / sw
  • Nested loop control with blt
  • exit(93) via raw ecall
syscall_echo_linux.s RISC-V Assembly
.data
buf: .space 64

.text
    ; Linux-style syscall ABI:
    ;   a7 = syscall number
    ;   a0..a5 = arguments
    ;   a0 = return value

    li   a0, 0        ; fd = stdin (0)
    la   a1, buf
    li   a2, 64       ; max bytes
    li   a7, 63       ; read(fd, buf, count)
    ecall            ; → a0 = bytes read

    mv   t0, a0       ; save byte count
    li   a0, 1        ; fd = stdout (1)
    la   a1, buf
    mv   a2, t0       ; exact bytes to echo
    li   a7, 64       ; write(fd, buf, count)
    ecall

    li   a0, 0
    li   a7, 93       ; exit(0)
    ecall

Echo, Raw Linux ABI

No pseudo-instructions. Pure Linux-style ecall: put the syscall number in a7, arguments in a0–a5, fire ecall. Return value lands in a0. Reads a line from stdin and writes it straight back to stdout.

  • read(63): stdin → buffer
  • write(64): buffer → stdout
  • exit(93): clean exit
  • BSS allocation with .space
  • Return value of read used as write length
io_prompt_linux.s RISC-V Assembly
.data
prompt: .asciz "Your name? "
greet:  .asciz "Hi, "
buf:    .space 64

.text
    ; --- write prompt to stdout ---
    li   a0, 1        ; fd = stdout
    la   a1, prompt
    li   a2, 11       ; len("Your name? ")
    li   a7, 64       ; write
    ecall

    ; --- read name from stdin ---
    li   a0, 0        ; fd = stdin
    la   a1, buf
    li   a2, 64       ; max bytes
    li   a7, 63       ; read
    ecall            ; → a0 = bytes read
    mv   t0, a0       ; save byte count

    ; --- write "Hi, " to stdout ---
    li   a0, 1
    la   a1, greet
    li   a2, 4        ; len("Hi, ")
    li   a7, 64       ; write
    ecall

    ; --- write the name back ---
    li   a0, 1
    la   a1, buf
    mv   a2, t0       ; bytes_read from earlier
    li   a7, 64       ; write
    ecall

    li   a0, 0
    li   a7, 93       ; exit(0)
    ecall

Interactive Prompt, Raw Syscalls

Composes output from three separate write calls (a prompt string, a greeting prefix, and the user's input), all using raw Linux ABI. No pseudo-instructions, no helpers.

  • Three distinct write(64) calls
  • Return value of read reused as write length
  • fd=0 (stdin), fd=1 (stdout)
  • Data pointers via la (load address)
  • exit(93): Linux-compatible clean exit
Instruction Set

Full RV32IMAF, every instruction your course covers

From basic arithmetic to atomics and floating-point. RAVEN supports the complete standard instruction set, so you never hit a wall mid-course.

R Arithmetic & Logic
ADDSUBANDORXOR SLLSRLSRASLTSLTU MULMULHDIVREM
I Immediate Ops
ADDIANDIORIXORI SLTISLTIUSLLISRLISRAI
LS Loads & Stores
LBLHLWLBULHU SBSHSW
A Atomics (RV32A)
LR.WSC.W AMOSWAP.WAMOADD.W AMOAND.WAMOOR.WAMOXOR.W AMOMAX.WAMOMIN.W AMOMAXU.WAMOMINU.W
B Branches & Jumps
BEQBNEBLTBGEBLTUBGEU JALJALRLUIAUIPC
SYS System
ECALLEBREAKHALT
F Float (RV32F)
FLWFSW FADD.SFSUB.SFMUL.SFDIV.S FSQRT.SFMIN.SFMAX.S FMADD.SFMSUB.S FEQ.SFLT.SFLE.S FCVT.W.SFCVT.S.W FMV.W.XFMV.X.W
M extension (multiply/divide) A extension (atomics) F extension (single-precision float)
Beyond the IDE

A headless CLI and an embeddable engine

The same core that powers the IDE also runs from the command line and ships as a Rust crate, so you can script runs, grade assignments, and build your own tools on top of RAVEN.

Headless CLI

Assemble, simulate, and export stats without opening the TUI. Point it at a .s source, a FALC .bin, or an ELF, and redirect the numbers to a file.

$ raven build program.s
$ raven run program.s --pipeline
$ raven run program.s --format csv --out stats.csv
$ raven export-config --out my.rcfg

CLI Reference

Embeddable SDK

The raven-engine crate runs the assembler and simulator headless, so you can embed them in tests, autograders, and other Rust tools.

grader.rs Rust
use raven_engine::Falcon;

let result = Falcon::new()
    .asm(".text\n li a0, 42\n li a7, 93\n ecall\n")
    .max_cycles(10_000)
    .run()?;

assert_eq!(result.exit_code, Some(42));
assert_eq!(result.reg("a0"), 42);
// result.stdout(), result.pc(), result.read_word(addr)…

crates.io docs.rs

Get Started

Running in under a minute

RAVEN is a single binary. No toolchain to install and no container to set up.

Recommended

Download & Run

Grab the binary for your OS from the Releases page and run it directly. RAVEN opens immediately.

1
Download the binary for your OS from the Releases page.
2
Run the executable, and RAVEN's IDE opens immediately.
3
Write assembly or open an included example and press Ctrl+R to assemble.

Build from Source

Requires Rust (rustup.rs). Gives you the latest version and full access to the source.

$ git clone https://github.com/Gaok1/Raven-RiscV raven-riscv
$ cd raven-riscv
$ cargo run
RAVEN opens, start writing assembly
Who is it for?

Made for computer architecture students

If you're studying RISC-V for a university course, on your own, or just out of curiosity, RAVEN is built for you. Register naming, memory layout, and calling conventions follow the standard spec exactly, so what you see here is what you'll see on the exam.

  • Students. Follow your textbook exactly. RAVEN's register ABI names, little-endian layout, and instruction encoding match the RISC-V spec and every major computer architecture textbook.
  • Teachers. Live-demo pipeline stages, cache behaviour, virtual memory, and calling conventions without any setup. Step through student assignments during office hours.
  • Self-learners. Curious how a CPU actually works? Start with a simple add, step through it, and watch the machine state change. Build up from there.
Run › Registers
ABIHEXDEC
zero0x000000000
ra0x0000002840
sp0x7FFFFFF0-16
a00x0000003755
a10x0000000A10
s00x0000002234
s10x0000001521
· · ·