← Paleocomputing · Русский

Oberon and the RISC5 machine

A whole computer — from the logic gate to the window on screen — that fits in one head. Here it boots right in the browser, on the real description of the circuit, written by Niklaus Wirth.

184lines — the processor core
4,953lines — kernel, files, compiler, OS, windows
1.2 MBis what all of it weighs in a browser
1986the year of the system that will boot

What this is

In the 1980s Niklaus Wirth did something nobody has repeated since: not a language, not an operating system and not a processor separately, but all of it at once — and so that one person could see the whole.

The processor core is described in 184 lines, 538 with the multiplier, divider and floating point. With all its periphery — video, mouse, keyboard, ports, SD card — 935. The system on top of it, together with its own compiler and window interface, is another 4,953. About six thousand lines from gate to window. That is a week's reading.

A modern operating system has tens of millions of lines, and nobody holds it whole in their head — not one person in the world answers for the entire chain. Oberon is a rare place where a claim about computers can be checked all the way through, without running into a single "magic happens here".

This is not an emulator. What runs in the browser is a simulation of the circuit itself: the state of every wire on every clock. What it shows is what a real chip would have done. That is why the numbers it produces can be put forward.

What you can try right now

Nothing to install: the lab opens in a browser and every task checks itself.

  1. The system on real hardware

    Convince yourself there is a circuit under that window, not an imitation.

  2. There is no memory protection here

    See what happens when there is none — and why it does not kill the system.

  3. The system rebuilds itself

    Run the rebuild and wait while it builds its own compiler.

  4. Cycles per instruction

    Measure it and check against what the circuit promises.

  5. The heap runs out mid-command

    Drive the system out of memory in the middle of work and watch what follows.

  6. Fixed point: two generations

    Build the compiler with the compiler, then again — and compare the results byte for byte.

  7. Your first module

    Write a program in Oberon, compile it inside the system and run it.

  8. The interface key

    Break compatibility between modules and watch the system catch it.

  9. Inside the code generator

    Reach the place in the compiler where processor instructions finally appear.

  10. The garbage collector from inside

    Make garbage, watch the heap fill, and find out why the collector only runs between commands.

  11. One task at a time

    Write a background task, starve it with a long command, then freeze the whole system with it.

  12. The cost of a check, by hand

    Switch to the core with a bounds-check instruction and measure what the check costs in your own loop — with the check done by hardware, by software, and not at all.

  13. Your own built-in function

    Teach the compiler a new built-in, rebuild the compiler inside the running system, and compile a module that uses it.

The handbook

Eight chapters, from "why this" to "what we measured". The labs refer to them as they go, but they can be read on their own.

If you would rather check us yourself

Everything we claim reproduces with one command. Verilator and a C++ compiler are needed:

git clone https://github.com/tym83/paleocomputing
cd paleocomputing/impl
make deps     # check the environment
make check    # about eight minutes

In those eight minutes the instruction-set tests run, the system boots, a step-by-step comparison against a reference model covers 14.6 million instructions, the compiler builds itself, and the system rebuilds itself entire — 37 files byte for byte.

Two labs do not fit in a browser: they need the circuit and the compiler rebuilt. There is a container for those — you give it a change and get a verdict, with neither git nor network needed inside.

Whose is what here

Taken ready: the RISC5 core and its periphery — Niklaus Wirth, projectoberon.net; the Project Oberon system image; the command-line compiler and the reference emulator — pdewacht.

Ours: the benches and the measuring instrumentation, a RISC5 assembler, the test sets, the browser build, the labs and the handbook. Plus 53 lines of change in the processor's description — the added bounds check instruction, for the sake of which the measurement was undertaken.

What these numbers do not mean

We measured what an array bounds check costs: 2.2% of the time. It matters what that does not mean.

  1. This is Oberon, not "in general". The figure belongs to this machine and this work. What travels is the method and the conclusion about spread, not the numbers.

  2. This processor has no cache and no branch prediction. So we measured the same loop elsewhere instead of guessing. The check takes the same two instructions everywhere — compare and branch — but its price differs: on RISC5 those two instructions are two of the loop's eleven cycles, on Apple M4 and AMD EPYC nothing measurable, a steady 2–6% on an Arm Neoverse N2 server core, where this tight loop runs out of issue width; put the check on the critical path and it costs two cycles everywhere, just as on RISC5. Modern compilers usually delete it outright when they can prove the index is in range; Wirth's never does. On CHERI the check lives inside the load and costs no instruction at all. The whole ladder, with every loop body: finding 61 and finding 63.

  3. It was not run on a live board. But it was placed and routed on real FPGA fabric (Lattice ECP5): with wire delays counted, the core holds the design's 25 MHz with room to spare, and the bounds-check instruction does not slow it down. The cycle counts still come from the circuit model, not from a board.

  4. This is no exposé of Wirth. The inconsistencies we found are in the distribution and the auxiliary tools, and some are explained by the history of versions.