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.
⚠️ The segment sizes should not exceed the memory size provisioned in hardware.
Both engines
Step and Back move a whole C statement or pseudo-op expansion at a time, not one machine instruction.
Clock
CLK_DIV_BITS
3.13 MHz
JavaScript model
Maximum number of instructions executed per run before pausing. Default: 100,000,000.
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.
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 filedetected 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.
The MMIO layout and ecall system call services follow the conventions of
RARS,
the RISC-V Assembler and Runtime Simulator.
The microarchitecture terminology and some of the general ideas follow Sarah L. Harris and
David Harris, Digital Design and Computer Architecture: RISC-V Edition. The datapaths
here are a different design from the book's.