⚙ Settings & Configuration
This changes how much code the compiler emits, often by several times over. -O0 keeps every C statement separate and -O3 unrolls and inlines, so both are usually the largest; -Os is the smallest.
Making sure it still fits the hardware
The program has to fit the instruction memory the processor actually has. In this simulator that limit is Code (.text) size in Settings → Linker; on the FPGA it is set by IROM_DEPTH_BITS in Wrapper.v, and the two have to agree. The status bar reports the size after every assemble, and says by how many words the program overruns if it does. Raising the optimisation level, or raising both limits together, are the two ways out — raising only the linker setting will build here and then silently truncate on hardware.
💡 Note: C source code is compiled online via Compiler Explorer (Godbolt) REST API
Base addresses and segment sizes (hex). Stack top (sp) defaults to Data Base + Data Size, but can be customized. Applying reloads the program with the new layout.
⚠️ FPGA Hardware Notice: The segment sizes should not exceed the memory size provisioned in hardware.
Settings for the built-in JavaScript model. They take effect immediately. In HDL mode they are dimmed, because they do not reach that engine.
Both engines
Step and Back move a whole C statement or pseudo-op expansion at a time, not one machine instruction. Shared with HDL Simulation.
JavaScript model
Maximum number of instructions executed per run before pausing. Default: 100,000,000.
Cycles consumed per instruction category — the estimate behind the Cycles readout in the toolbar. The hardware engine counts real clock edges instead.
Your Verilog is compiled inside your browser and is never uploaded anywhere, so it has to be loaded once per session.
Processor sources
Drop your .v files here, or
Include Wrapper.v, RV.v and every submodule.
You can also drop them anywhere on the page, or open them with 📂 Open.
None of the loaded files declares module Wrapper. The generated testbench instantiates Wrapper by name, so add your Wrapper.v.
Simulation
Synthesises your core with Yosys and checks the netlist against your RTL.
What this does, and the one-off download
Every run is simulated twice: once as you wrote it, and once as the gate-level netlist Yosys produces. The two are compared and the first point where they differ is reported — which is what an inferred latch, an incomplete sensitivity list or a race between blocking assignments looks like. The panels keep showing the RTL run, so stepping and the register view are unaffected; register writes are not compared, because synthesis leaves no register array to read.

Ticking this downloads the synthesiser the first time you use it (about 13 MB). Nothing is fetched until you tick it, and your browser caches it for a year, so later sessions start immediately. Synthesis takes 20–35 seconds and is redone only when your Verilog changes.
Clock cycles a fresh Run records, and how many more each Resume adds.
Step and Back move a whole C statement or pseudo-op expansion at a time, not one machine instruction. Shared with JS Simulation.
Recording & output
Needed for Step and Back. Turning it off is slightly faster.
A ⭳ VCD button appears in the toolbar once a run has produced one. Reports the first instruction where your hardware and the functional model disagree. Costs a second execution.
Register file detected automatically
load your sources to detect the register file
How HDL mode works
The assembled program reaches your Wrapper as AA_IROM.mem and AA_DMEM.mem through its own $readmemh — assemble first, then run. Run records the whole simulation; Step and Back then move through that recording, so stepping is instant and works in both directions. Run becomes Resume once there is a recording — it continues to the next breakpoint, and records another Cycles worth when it reaches the end. Reset is how you start the hardware over. Changing a DIP switch, a button, the accelerometer or the UART input while paused is timestamped at the current cycle and the run replayed — everything before that point comes out identical, so you keep your place, and the very next instruction already sees the new value.
Credits

Part of CG3207, NUS. Written by Rajesh Panicker.

The MMIO layout and ecall system call services follow the conventions of RARS, the RISC-V Assembler and Runtime Simulator.

The code editor is CodeMirror 6, and C is compiled by Compiler Explorer. HDL mode runs on Icarus Verilog, compiled to WebAssembly by verisim, and post-synthesis simulation runs on Yosys, compiled to WebAssembly by YoWASP.

RV NUS-CG3207 RISC-V Functional and HDL Simulator

Ready Cycles: 0  |  Instr: 0  |  PC: 0x00400000
# ABI Name Content (Hex) Content (Dec)
Variable Address Content (Hex) Content (Dec)
Full word (LSB to the right)  ·  Editable
Addr Content (Hex) Content (ASCII)
LEDs (LED[15:0]) & DIP Switches (SW[15:0])
PC[8:2] (LED[15:9]) CLK (LED[8]) User OUT (LED[7:0]) 0xFFFF0060 WO
DIP Switches 0xFFFF0064 RO (SW15..SW0)
Push Buttons 0xFFFF0068 RO
BTNL | BTNC | BTNR — click to toggle or use arrow keys (← ↓ →)
7-Segment Display 0xFFFF0080 WO
Cycle Counter  0xFFFF00A0 RO
Total Cycles: 0
UART Serial Console (115200 8N1)  0xFFFF0000–0xFFFF000C RX_VALID: 0  ·  TX_READY: 1
instr/char
· RX Queue: 0 bytes (empty)
3-Axis Accelerometer & Temp  0xFFFF0040–0xFFFF0044 DREADY: 1
X Axis: 0 (0x00, +0.00g)
Y Axis: 0 (0x00, +0.00g)
Z Axis: 64 (0x40, +1.00g)
Temp: 25°C (0x19)
X | Y | Z | T — hold, then ← → to adjust
OLED 96x64 Pixel Display  0xFFFF0020–0xFFFF0030 SWAP PENDING: 0
OLED_COL: 0 (0–95)
OLED_ROW: 0 (0–63)
OLED_CTRL: 0x00
Mode: vary_pixel_data_mode  ·  Format: 8-bit (3R-3G-2B)
Single buffered  ·  writes appear at once
LSB to the right
All panels are hidden — use the buttons above to show the various panels.
Waveforms ctrl+scroll zooms · shift+scroll pans · click a wave to go there