Free · Open Source · RV32IMF

Learn RISC-V by
watching it run.

RAVEN is a free RISC-V simulator and IDE for the terminal. Write assembly, assemble with one keystroke, and step through every instruction — watching registers, memory, and the cache update in real time. Nothing is a black box.

RV32IMF Architecture
Step-by-Step Debugger
I+D Cache Simulator
Free Open Source
Editor Run Cache Docs RV32IMF
.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]
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
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

Everything a student needs — nothing more

One terminal app. Write, assemble, run, debug, and profile your RISC-V programs without installing a toolchain.

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 — no Makefile, no terminal juggling. Import .asm files from other simulators or export your work as binary.

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.

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.

Full RV32IMF — complete ISA

Base integer (RV32I), multiply/divide (M), and single-precision float (F). Every instruction your textbook covers, plus the pseudo-instructions used in real code.

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 — errors show 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 Tab

Switch to the Cache tab to see hit rates, AMAT, IPC, and a visual matrix of every cache line. Change the replacement policy and run again to compare.

Cache Simulator

The memory hierarchy, finally visible

Most simulators hide the cache. RAVEN exposes everything — per-access tracking, live statistics, a visual matrix of every cache line, and configurable policies so you can experiment with what you learned in class.

  • Separate I-Cache & D-Cache — instruction fetches and data loads/stores tracked independently. Hit rates, miss counts, and MPKI reported per cache — just like a real processor.
  • Six Replacement Policies — LRU, FIFO, LFU, Clock, MRU, Random. Swap policy mid-run and immediately see how it affects your hit rate. Perfect for comparing what your textbook describes.
  • Configurable Geometry — sets, ways, block size, write policy, inclusion policy. Three built-in presets (Small / Medium / Large) for quick starting points.
  • Academic Metrics — AMAT (Average Memory Access Time), IPC, CPI breakdown, and MPKI. The same numbers your architecture course asks you to calculate — computed automatically.
  • Visual Matrix View — every set and way rendered as a colour-coded grid. Valid, tag, dirty state visible per cache line. Scroll through the entire cache state 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
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.fas 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

Quicksort — Recursive

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.fas 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 — 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.fas 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.fas 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 RV32IMF — every instruction your course covers

From basic arithmetic to 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
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) F extension (single-precision float)
Get Started

Running in under a minute

RAVEN is a single binary. No VM, no Docker, no toolchain setup.

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 — 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 raven
$ cd raven
$ 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, self-study, or just curiosity — RAVEN is designed for you. Register naming, memory layout, and calling conventions follow the standard spec exactly. No surprises.

  • 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, 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
· · ·