ArticlesProjectsWeeklyCredentialsAbout

TMC #0007: Von Neumann Architecture: Stored-Program Computer Simulator

Python simulator of the stored-program architecture described in von Neumann's "First Draft of a Report on the EDVAC" (1945). A 256-word memory machine with nine opcodes demonstrates the fetch-decode-execute cycle, conditional branching, and the bottleneck that still haunts modern CPUs.

von-neumannstored-programfetch-executearchitecturecomputer-historypythonsimulator

Python simulator of the stored-program computer architecture from John von Neumann's 1945 EDVAC report: the blueprint that every computer built since has followed.

What's in the code

von_neumann_sim.py: single self-contained file, no dependencies:

  • VonNeumannMachine: 256 × 16-bit word memory; registers PC, ACC, MAR, MDR, IR; nine-opcode instruction set (NOP, LDA, STA, ADD, SUB, JMP, JZ, JN, OUT, HLT). The step() method executes exactly one fetch-decode-execute cycle and returns the internal state for inspection.
  • instr(opcode, addr): assembler helper: packs a 4-bit opcode and 8-bit address into a 16-bit instruction word. Programs are written as lists of these values and loaded into memory with load(), which writes them as plain integers: indistinguishable from data. This is the stored-program principle made literal.
  • demo_stored_program_principle(): loads a two-instruction program, prints the raw memory dump (showing the program as ordinary numbers), then runs it. Makes tangible what "instructions are data" means.
  • demo_sum_1_to_10(): sums the integers 1–10 using a conditional loop; prints 55. Uses LDA, ADD, SUB, STA, JZ, JMP. Pass --trace to see every fetch-decode-execute cycle annotated.
  • demo_fibonacci(): computes the first 10 Fibonacci numbers using the same machine, different numbers in memory. The hardware is unchanged; only the contents of the memory array differ. Outputs 0 1 1 2 3 5 8 13 21 34.
  • Von Neumann Bottleneck note: printed at the end: explains why the shared instruction/data bus caps throughput at Bmem/2B_\text{mem}/2 and why every modern CPU (caches, pipelines, prefetchers) is fighting this constraint.

Running it

python3 von_neumann_sim.py           # all three demos
python3 von_neumann_sim.py --trace   # with per-cycle instruction trace

No dependencies beyond the Python standard library. Tested on Python 3.10+.

Source code
# TMC #0007 — Von Neumann Architecture Simulator

Companion code for [The Thinking Machine Chronicles #0007](https://rishisharma.in/articles/tmc-0007-von-neumann-architecture): _The Blueprint of Every Computer Ever Built — Von Neumann Architecture_.

A minimal stored-program computer simulator in pure Python, demonstrating the architecture described in John von Neumann's "First Draft of a Report on the EDVAC" (30 June 1945).

## The architecture

| Component          | Detail                                                          |
| ------------------ | --------------------------------------------------------------- |
| Memory             | 256 × 16-bit words (instructions and data share the same space) |
| Registers          | PC, ACC, MAR, MDR, IR                                           |
| Instruction format | 8-bit opcode \| 8-bit address (packed into 16-bit word)         |
| Opcodes            | NOP, LDA, STA, ADD, SUB, JMP, JZ, JN, OUT, LDI, HLT             |

## Running

```bash
python3 von_neumann_sim.py           # three demos
python3 von_neumann_sim.py --trace   # with per-cycle fetch-decode-execute trace
```

No dependencies. Python 3.10+.

## What the demos show

| Demo                     | What it illustrates                                                                                                         |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| Stored-program principle | The program is printed as a raw memory dump before execution — instructions are plain integers, indistinguishable from data |
| Sum 1–10                 | Conditional loop with JZ and JMP; outputs 55                                                                                |
| Fibonacci(10)            | Same machine, different numbers → `0 1 1 2 3 5 8 13 21 34`                                                                  |

## Writing your own programs

Use `instr(opcode, addr)` to assemble instructions:

```python
from von_neumann_sim import VonNeumannMachine, instr, LDA, ADD, OUT, HLT

m = VonNeumannMachine()
m.memory[0x10] = 7
m.memory[0x11] = 35
program = [
    instr(LDA, 0x10),   # ACC = 7
    instr(ADD, 0x11),   # ACC = 7 + 35 = 42
    instr(OUT, 0x10),   # this prints memory[0x10], not ACC
    # to print ACC: STA to a spare address, then OUT that address
]
m.load(program)
m.run()
```

## Historical note

EDVAC itself wasn't completed until 1949. The first machine to actually run a stored program was the Manchester SSEM ("Baby") on 21 June 1948. Von Neumann's own IAS machine at Princeton ran in 1951. The simulator here uses 16-bit words and 8-bit addresses for simplicity; EDVAC's design used 44-bit words and acoustic mercury delay-line memory.