Harvard Architecture

Most computers use the von Neumann architecture: a single memory holds both program instructions and data. It's simple and flexible — you can treat code as data and vice versa. But it has a bottleneck: the processor can't fetch an instruction and read data simultaneously because they share the same bus.

The Harvard architecture solves this by physically separating instruction memory (ROM) from data memory (RAM). The processor gets two independent buses: one for instructions, one for data. While the ALU works with data from RAM, the program counter simultaneously fetches the next instruction from ROM. Think of a chef with a recipe book and a fridge: keeping the book inside the fridge next to the sausage would be absurd — so programs and data get separate homes.

ROM holds the program code itself — the "add," "store," "jump" instructions. The processor only reads instructions from it and never overwrites them during operation. RAM is the scratchpad: the processor constantly writes, erases, and stores intermediate results there — the player's coordinates, the score, the health.

This separation is what buys you parallelism. While the decoder figures out the current instruction, the program counter is already pulling the next one from ROM. That's why the Harvard design is faster — and that's exactly what you'll build in level 1.18.

Why one bus is a bottleneck

The alternative is the von Neumann architecture: instructions and data share one memory and one bus. It's simpler and more flexible: code can be modified at runtime and memory doesn't sit idle. But there's a price: the bus can carry only one thing at a time — either an instruction or data.

This is the famous "von Neumann bottleneck": the processor waits for the bus to free up, so it can't read an instruction and write a result at once. With two roads, the Harvard design has no such traffic jam.

Inside the Ershov Computer

The final computer in level 1.18 is a classic Harvard design. Data flows left to right along the chain: ProgramCounter → ROM → Splitter → Decoder → Register8 and ALU8 → RAM.

The program counter puts an address on the ROM, ROM returns a command byte, and the Splitter cuts it in half: high bits 4–7 are the opcode (what to do), low bits 0–3 are the operand (what to do it with). The decoder turns the opcode into control signals; registers and the ALU do the actual work with data, which lives in RAM — a separate memory on a separate bus.

We built the 8-bit registers in the article about your first byte, and the program counter is covered in the next article. What matters right now is the big idea: instructions and data never get in each other's way.

The data path: how LDA reaches the accumulator

Take the LDA instruction — "load into the accumulator." LDA loads an immediate value: the instruction's operand comes from the ROM, passes through a multiplexer (at that moment it selects the instruction's operand, not the data bus), and lands directly in the accumulator register. The accumulator captures the value on the next clock edge, so the data has time to settle on the bus first.

The data bus carrying RAM contents is a separate road from the instruction bus the ROM delivers instructions and their operands on, so a single tick can finish reading an instruction and deliver data at once — that's what makes the Ershov Computer fast.

Harvard vs von Neumann

Here are the key differences in a table.

PropertyHarvard architecturevon Neumann architecture
MemorySeparate ROM and RAMOne shared memory
BusesTwo: instructions and dataOne shared bus
Fetch instruction + write dataSimultaneously, in parallelOnly one at a time
SpeedFaster for simple workloadsSimpler, but slower
Modifying code at runtimeImpossible: ROM is read-onlyPossible
In the gameLevel 1.18 — the Ershov ComputerTheoretical alternative
Von Neumann Harvard CPU Memory instructions + data one bus CPU ROM instructions RAM data instructions data
Von Neumann: one memory and one bus for everything. Harvard: instruction and data memories are separate — they work in parallel

One tick, in numbers

Let's trace a concrete tick. Suppose the program counter reads the next instruction from ROM[3] while the ALU simultaneously writes a computed result to RAM[12].

Step 1. The program counter puts the value 3 on the address bus — ROM prepares to output the instruction byte.
Step 2. At the same time the ALU's result is written to RAM[12] over the data bus: address 12 is already set and the data has settled.
Step 3. On the clock edge the accumulator and registers latch their values, and the program counter increments.
Result: fetching an instruction and writing data take a single tick.

Try that in the von Neumann architecture: first the bus carries the instruction, then the data — two ticks instead of one. On thousands of instructions, the Harvard design wins noticeably.

Summary

1. In the Harvard architecture, instructions (ROM) and data (RAM) live in separate memories and travel on separate buses.

2. The main benefit is parallelism: the processor reads the next instruction and writes data in one tick.

3. In the von Neumann architecture instructions and data share one bus — simpler, but slower (the von Neumann bottleneck).

4. The Ershov Computer chain is: PC → ROM → Splitter → Decoder → Register8/ALU8 → RAM.

5. The LDA instruction loads an immediate value from the ROM through the MUX straight into the accumulator.

In level 1.18 you will assemble the final Ershov Computer: wire the program counter, ROM, decoder, registers, ALU, and RAM into a single Harvard design and run your first program on it. Keep the big idea in mind: instructions travel on their own bus, data on theirs — and they never interfere.

Try it in the simulator →