PipeScope
A see-through five-stage pipelined CPU. Run GCC-built RISC-V and MIPS programs in your browser one clock cycle at a time and watch forwarding, stalls, branch flushes, memory accesses, and peripheral I/O as they happen.
In 1981, John Hennessy and his graduate students at Stanford began designing a new processor. They called it MIPS, short for “Microprocessor without Interlocked Pipeline Stages.” In a pipeline, when an instruction tries to use a result its predecessor hasn’t finished computing, a hardware circuit called an interlock normally holds it back. Hennessy’s team left that circuit out. The compiler reordered instructions to avoid the dangerous sequences, and it also filled the slot right after each branch, the delay slot.
The project ended in 1984, and the commercial R2000 chip followed a year later. The textbook Hennessy wrote with David Patterson, Computer Organization and Design, taught the five-stage pipeline with MIPS; a RISC-V edition came out in 2017. That same year the two of them received the Turing Award. In 2021, MIPS Technologies stopped developing the MIPS architecture and moved to RISC-V.
In that textbook, the pipeline is a single diagram, and a diagram doesn’t move. With five instructions in flight at once, when exactly does a forwarding path switch on? Why does the instruction right after a load have to wait a cycle? When a branch is taken, what happens to the instruction that was already fetched? PipeScope answers by sending a real program through that same textbook datapath, one cycle at a time. It runs both RISC-V and MIPS, so you can set the delay slot Hennessy’s team handed to the compiler next to the flush RISC-V uses instead.
The pipeline on screen really runs the program. A pipeline simulator, written in Rust and compiled to WebAssembly, loads the ELF executable that GCC produced and runs it as is. It supports both RISC-V (RV32IM) and MIPS32: open an executable and it recognizes the architecture, then switches the datapath drawing, the register names, and the instruction explanations to match. The C source travels inside the executable, so you can see which source line each instruction in the pipeline came from. The results are checked against a reference simulator that runs the same program one instruction at a time.

What you can see
- The datapath. The five-stage datapath from the computer-architecture textbooks, drawn in full, down to the control unit, the hazard detection unit, and the forwarding unit: 31 blocks and 81 signals for RISC-V, 34 blocks and 83 signals for MIPS. Only the paths actually used this cycle light up. Zoom in and the wires get names and bit widths; zoom in further and every wire shows the value it carries.
- What happened this cycle. Each stage’s work is spelled out in a sentence. You can read, right there, why a hazard arose and how it was resolved, where a forwarded value came from and where it went, and which instruction a branch threw away.
- The inspector. Click a block to see its inputs, its outputs, and what it did this cycle. Click a wire to see its value in hex, decimal, and binary, and for a control signal, a table of what each value means.
- The system bus and the 7-segment display. The view from outside the CPU chip. Follow, byte by byte, how four instruction bytes are read from RAM and assembled, how the address decoder chooses between RAM and the peripheral, and how a single
swchanges the digits on an eight-digit 7-segment display. - Rewind and compare. Step backwards through the last 20,000 cycles. Turn forwarding off and run on stalls alone to see the same result at a worse CPI, or turn hazard handling off entirely and watch the program get the wrong answer.


RISC-V
It implements the 32-bit RISC-V integer instructions (RV32I) and the multiply/divide extension (M). The immediate generator gathers the immediate bits scattered through the instruction word according to its format (I, S, B, U, J), and branches and jal compute their targets from the instruction’s own PC. Branches are resolved in the ID stage. RISC-V has no delay slot, so when a branch is taken, the one instruction IF fetched in the meantime is discarded. That flush shows up in the IF stage header, as an erased cell in the pipeline chart, and on the IF.Flush wire in the datapath, and the toolbar keeps count. Compressed instructions (the C extension), ecall, and CSR instructions are not supported.
MIPS
The same pipeline also runs MIPS32. It implements the integer instructions GCC emits, with branch delay slots that behave as they do on real MIPS, so code from GCC runs unmodified. Multiply and divide results go to the HI/LO registers, and conditional moves and traps are supported too. The examples are built from the same C sources for both architectures, so you can switch between them to compare a branch flush with a delay slot side by side, or see the same division stay a divu on RISC-V but turn into a multiply (mult) on MIPS.

What it doesn’t support
Neither architecture has floating point, system calls, interrupts, or a cache. With no operating system there is no printf either; output goes to a memory-mapped 7-segment display.
Getting started
Opened from this page, the app starts with the RISC-V hazard demo. Press Step (→) to advance one cycle and Back (←) to undo it. The example list is split into RISC-V and MIPS groups, each with the hazard demo and six programs built from C. The interface is available in English, Korean, and Japanese, and you can switch while a program is running.