ENIAC, finished in 1945, was programmed with patch cables and switches. Its program was its wiring. Running a different program meant rewiring the machine, which took days.
In June 1945 John von Neumann circulated the First Draft of a Report on the EDVAC. It described a machine that keeps its program in the same memory as its data. A new program is a new set of words in memory, not new wiring. The ideas came out of the ENIAC group's work with Eckert and Mauchly, but the report carried only von Neumann's name, and the design is named after him. Nearly every general purpose computer since follows it.
Fig 1 is a card computer. Each part of it is one unit of the architecture. Press Play to run a five instruction program that adds two numbers, or press Step to run it one bus transfer at a time.
Memory, live. Green words are instructions, brown words are data. The filled address is the one in PC. The shaded slot is the drawer the shuttle is using.
| Unit | In Fig 1 | Job |
|---|---|---|
| Input | Keypad | Moves data from outside into memory. |
| Memory | Cabinet, drawers 0 to 7 | Holds instructions and data. Each drawer holds one word. The drawer number is its address. |
| Control unit | Left half of the right case: PC window and lamp | Fetches the next instruction, decodes it and directs the other units. |
| ALU | Right half of the right case: ACC window and crank | Does the arithmetic and logic. |
| Output | Card reader with a screen | Moves results from memory to the outside. |
| Bus | Rails and shuttle | Carries one word at a time between the units. |
The control unit and the ALU together form the CPU, which is why they share one case in the figure. Three registers matter for this program:
Every drawer holds a 6 bit word. An instruction word is a 3 bit opcode followed by a 3 bit address. On the instruction cards in Fig 1, the back row of holes is the opcode and the front row is the address, one hole for each 1 bit.
| Opcode | Mnemonic | Effect |
|---|---|---|
001 | LOAD a | ACC ← M[a] |
010 | ADD a | ACC ← ACC + M[a] |
011 | STORE a | M[a] ← ACC |
100 | OUT a | Output ← M[a] |
101 | HALT | Stop |
The program in Fig 1, with the default inputs:
| Address | Word | Meaning |
|---|---|---|
| 0 | 001 101 | LOAD 5 |
| 1 | 010 110 | ADD 6 |
| 2 | 011 111 | STORE 7 |
| 3 | 100 111 | OUT 7 |
| 4 | 101 000 | HALT |
| 5 | 000 011 | Data: a = 3 |
| 6 | 000 100 | Data: b = 4 |
| 7 | Result, written by STORE 7 |
000 011. LOAD 5 reads it as the number 3. If PC ever reached 5, the control unit would
decode the same word as opcode 000 with address 3. The only thing that makes a word an
instruction is that PC points at it.
The control unit repeats one cycle until it decodes HALT:
A read copies a word and leaves the drawer as it was. A write replaces the drawer's contents. The figure shows this: the shuttle carries a copy of each card, and STORE 7 drops a new card into drawer 7. The Fetch-Execute Cycle article breaks each phase into register transfers.
| Instruction | Memory accesses | PC after | ACC after |
|---|---|---|---|
| LOAD 5 | fetch M[0], read M[5] | 1 | 3 |
| ADD 6 | fetch M[1], read M[6] | 2 | 7 |
| STORE 7 | fetch M[2], write M[7] | 3 | 7 |
| OUT 7 | fetch M[3], read M[7] | 4 | 7 |
| HALT | fetch M[4] | 5 | 7 |
Adding two numbers took 9 memory accesses, and 5 of them were instruction fetches. Every one went over the same bus, one at a time. The CPU cannot fetch the next instruction while the bus is moving data.
As processors became much faster than memory, this shared path became the limit on performance. John Backus called it the von Neumann bottleneck in his 1977 Turing Award lecture. Modern CPUs work around it rather than remove it: caches keep recent words close to the CPU, separate level 1 instruction and data caches let a fetch and a data access happen together, and prefetching starts reads before they are needed.
000 011 before the program runs. What happens when PC reaches 2?