Theory: The von Neumann Model & Non-von Neumann Models
Almost every computer you have ever used follows one design idea from the 1940s: keep the program in memory, just like data. This section explains where that idea came from, what a “von Neumann machine” is, how it runs a program (the fetch-decode-execute cycle), its main weakness (the von Neumann bottleneck), and the alternatives (Null & Lobur, §1.7–1.8).
Before Stored Programs: Programming the ENIAC
On the ENIAC (first generation), all programming was done at the digital logic level:
- Programming the computer meant moving plugs and wires on plugboards and setting switches.
- A different hardware configuration was needed for every unique problem type. Changing from one calculation to another could take days of rewiring, and the “program” existed only as the physical wiring.
Intuition. Imagine a calculator where, to switch from adding to finding square roots, you must open the case and re-solder the circuits. That is ENIAC. A stored-program computer is like a modern calculator app: the hardware stays fixed, and you just load a different program.
The Stored-Program Concept
- The inventors of the ENIAC, John Mauchly and J. Presper Eckert, conceived of a computer that could store its instructions in memory.
- The idea has since been ascribed to the mathematician John von Neumann, a contemporary of Mauchly and Eckert, whose 1945 report on the EDVAC described it.
- Stored-program computers have become known as von Neumann architecture systems (around 1947).
Stored-program concept: the program’s instructions are stored in the same memory as the data, as binary numbers. To run a different program, you load different numbers into memory; no rewiring is needed. Because instructions are just data, programs (compilers, loaders, operating systems) can even create and load other programs.
Mini-example
In a stored-program machine, memory might hold 1104 at address 100 and 0023 at address 104. The first is an instruction (“load the value at address 104”), the second is data (35 in decimal). Memory itself does not know the difference: it depends only on whether the CPU fetches the word as an instruction or as an operand.
Characteristics of a von Neumann Machine
Today’s stored-program computers have these characteristics:
- Three hardware systems:
- a central processing unit (CPU), containing a control unit, an arithmetic logic unit (ALU), registers and a program counter;
- a main memory system, holding both programs and data;
- an I/O system.
- The capacity to carry out sequential instruction processing (one instruction after another, in the order given by the program counter, unless a jump changes it).
- A single data path between the CPU and main memory. This single path is known as the von Neumann bottleneck.
Diagram loads as you scroll.
The von Neumann Bottleneck
Every instruction and every data operand has to travel over the same single path between CPU and memory, one transfer at a time. Processors have become far faster than memory, so the CPU often sits idle waiting for the bus. No matter how fast the CPU is, it cannot run instructions faster than memory can deliver them.
Modern machines soften (but do not remove) the bottleneck with cache memory, wider buses, and separate instruction and data caches (a Harvard-style idea, below).
Mini-example
If the bus moves one word every 5 ns and an instruction needs 2 memory transfers (fetch itself + fetch its operand), each instruction takes at least 2×5=10 ns, so at most 1/(10×10−9)=108=100 million instructions per second, even with a 5 GHz CPU.
The Fetch-Decode-Execute Cycle
Von Neumann computers run programs with the fetch-decode-execute cycle (also called the instruction cycle):
- Fetch: the control unit fetches the next instruction from memory, using the program counter (PC) to know where it is, and then increments the PC to point at the following instruction.
- Decode: the instruction is decoded into a form the ALU can understand (which operation? which operands?).
- Fetch operands: any data operands required are fetched from memory and placed into registers in the CPU.
- Execute: the ALU executes the instruction and places the result in a register or in memory.
Then the cycle repeats with the next instruction.
Diagram loads as you scroll.
Register-Level Walkthrough
To see the cycle concretely, we use the registers of the simple MARIE machine studied later in this course:
| Register | Name | Role |
|---|
| PC | Program counter | Address of the next instruction |
| IR | Instruction register | Holds the instruction being executed |
| MAR | Memory address register | Address sent to memory |
| MBR | Memory buffer register | Data just read from / about to be written to memory |
| AC | Accumulator | Holds the working value (results of the ALU) |
Each instruction is 16 bits (4 hex digits): the first hex digit is the opcode (1 = Load, 2 = Store, 3 = Add, 7 = Halt) and the last three are the address. Memory (all values in hex):
Address Contents Meaning
100 1104 Load 104 (AC <- M[104])
101 3105 Add 105 (AC <- AC + M[105])
102 2106 Store 106 (M[106] <- AC)
103 7000 Halt
104 0023 data: 35
105 FFE9 data: -23
106 0000 data: 0 (result goes here)
Executing the first instruction (Load 104), starting with PC = 100:
| Step | Phase | Operation | PC | IR | MAR | MBR | AC |
|---|
| (initial) | | | 100 | ---- | --- | ---- | ---- |
| 1 | Fetch | MAR ← PC | 100 | ---- | 100 | ---- | ---- |
| 2 | Fetch | IR ← M[MAR] | 100 | 1104 | 100 | ---- | ---- |
| 3 | Fetch | PC ← PC + 1 | 101 | 1104 | 100 | ---- | ---- |
| 4 | Decode | MAR ← IR[11–0]; opcode 1 = Load | 101 | 1104 | 104 | ---- | ---- |
| 5 | Get operand | MBR ← M[MAR] | 101 | 1104 | 104 | 0023 | ---- |
| 6 | Execute | AC ← MBR | 101 | 1104 | 104 | 0023 | 0023 |
After one full cycle, AC = 002316 = 35 and PC = 101, ready to fetch the Add. (The rest of the program is traced in Worked Example 3.)
Notice that the PC is incremented during fetch, before the instruction is executed. So while an instruction is executing, PC already points to the next one.
Non-von Neumann Models
Some systems break one or more of the von Neumann characteristics:
| Model | Departure from von Neumann | Example / use |
|---|
| Harvard architecture | Separate memories (and paths) for instructions and data, so an instruction fetch and a data access can happen at the same time | Microcontrollers (e.g. AVR, PIC), digital signal processors. Most modern CPUs are “modified Harvard”: separate L1 instruction and data caches over one main memory |
| Special-purpose processors (GPU) | Offload work from the main CPU to many simple cores working in parallel | Graphics, scientific computing, training neural networks |
| Dataflow computing | No program counter: an instruction executes as soon as its input data are available | Research machines; ideas used inside out-of-order CPUs |
| Quantum computing | Uses qubits that can be in superpositions of 0 and 1 | Factoring, simulation of molecules |
| Cellular automata | Grid of simple cells, each updating from its neighbours’ states | Simulation, theoretical models |
| Parallel computing | Many processors executing at the same time instead of one sequential stream | Multicore CPUs, supercomputers, clusters |
| Machine intelligence | Computation done by networks of artificial neurons rather than explicit instruction sequences | ANN, DNN, GPT-style models; neuromorphic chips |
Mini-example
A microcontroller has a 32 KB flash memory for its program and a separate 2 KB RAM for data, each with its own bus. Because instructions and data are in separate memories, it is a Harvard architecture.
Worked Examples
Exercise 1
Explain why the ENIAC needed a “different hardware configuration for every unique problem type”, and how the stored-program concept solved this.
Show solution ↓Hide solution ↑
Solution
- On the ENIAC the program was the wiring. Which unit added, which multiplied and where results went was decided by plugs, cables and switches. A new type of problem needed a new arrangement of the hardware, i.e. physical rewiring (which could take days).
- The stored-program concept (Mauchly and Eckert; described by von Neumann) puts the instructions in memory as binary numbers, alongside the data. The hardware is a fixed, general-purpose machine that fetches and executes whatever instructions are in memory.
- To change the program you just load different numbers into memory, which takes seconds, and the same hardware solves any problem.
Exercise 2
Put these steps into the correct order of the fetch-decode-execute cycle, and name the register that is used in each:
(A) the ALU performs the operation; (B) the operand is read from memory; (C) the instruction is read from the address held in the program counter; (D) the opcode is examined to find out what to do; (E) the program counter is increased by 1.
Show solution ↓Hide solution ↑
Solution
| Order | Step | Register(s) involved |
|---|
| 1 | (C) read the instruction at the address in the PC | PC → MAR, memory → IR |
| 2 | (E) increment the program counter | PC |
| 3 | (D) decode the opcode | IR (control unit reads it) |
| 4 | (B) read the operand from memory | address part of IR → MAR, memory → MBR |
| 5 | (A) ALU performs the operation | AC, MBR (result to AC) |
Order: C → E → D → B → A, and then the cycle repeats.
Exercise 3
Continue the register-level walkthrough from the Theory section. After Load 104, the registers hold PC = 101, IR = 1104, MAR = 104, MBR = 0023, AC = 0023. Trace the next two instructions, Add 105 (3105) and Store 106 (2106), showing PC, IR, MAR, MBR and AC after each step. What is stored in address 106 at the end?
Show solution ↓Hide solution ↑
Solution
Instruction 2: Add 105 (at address 101)
| Step | Operation | PC | IR | MAR | MBR | AC |
|---|
| Fetch | MAR ← PC | 101 | 1104 | 101 | 0023 | 0023 |
| Fetch | IR ← M[MAR] | 101 | 3105 | 101 | 0023 | 0023 |
| Fetch | PC ← PC + 1 | 102 | 3105 | 101 | 0023 | 0023 |
| Decode | MAR ← IR[11–0]; opcode 3 = Add | 102 | 3105 | 105 | 0023 | 0023 |
| Operand | MBR ← M[MAR] | 102 | 3105 | 105 | FFE9 | 0023 |
| Execute | AC ← AC + MBR | 102 | 3105 | 105 | FFE9 | 000C |
The addition in hex: 002316+FFE916=1000C16; only 16 bits are kept, so AC = 000C16. (FFE916 is −23 in 16-bit two’s complement, so this is 35+(−23)=12 ✓.)
Instruction 3: Store 106 (at address 102)
| Step | Operation | PC | IR | MAR | MBR | AC |
|---|
| Fetch | MAR ← PC | 102 | 3105 | 102 | FFE9 | 000C |
| Fetch | IR ← M[MAR] | 102 | 2106 | 102 | FFE9 | 000C |
| Fetch | PC ← PC + 1 | 103 | 2106 | 102 | FFE9 | 000C |
| Decode | MAR ← IR[11–0]; opcode 2 = Store | 103 | 2106 | 106 | FFE9 | 000C |
| Execute | MBR ← AC | 103 | 2106 | 106 | 000C | 000C |
| Execute | M[MAR] ← MBR | 103 | 2106 | 106 | 000C | 000C |
At the end M[106] = 000C16 = 12, and PC = 103 points to Halt, which stops the machine on the next cycle.
Exercise 4
A von Neumann computer’s memory bus can complete one word transfer every 10 ns. Every instruction needs one transfer to fetch the instruction and one transfer to read or write its operand.
(a) What is the maximum number of instructions per second, however fast the CPU is?
(b) A Harvard machine has separate instruction and data memories, each with its own 10 ns bus, so the instruction fetch and the operand transfer can overlap. What is its maximum rate?
(c) What does this show about the von Neumann bottleneck?
Show solution ↓Hide solution ↑
Solution
(a) Both transfers share the single path, so they happen one after the other:
tinstr=2×10 ns=20 ns⇒rate=20×10−9 s1=5×107=50 million instructions/s(b) With two separate paths working in parallel, one instruction can complete every 10 ns:
rate=10×10−9 s1=108=100 million instructions/s(c) The speed limit in (a) comes entirely from the single CPU–memory path, not from the CPU: even a 5 GHz processor (0.2 ns per cycle) would spend most of its time waiting. That is the von Neumann bottleneck. Separating instruction and data traffic (Harvard), or adding caches, raises the limit (here it doubles).
Exercise 5
Classify each system as von Neumann, Harvard, or another non-von Neumann model, and justify briefly:
(a) A desktop PC where programs are loaded from disk into the same RAM that holds their data.
(b) A microcontroller with program code in on-chip flash and variables in a separate SRAM, on separate buses.
(c) A machine where each instruction fires as soon as all its input values have been computed; there is no program counter.
(d) A graphics card with thousands of small cores rendering pixels simultaneously.
(e) A computer that stores information in qubits.
Show solution ↓Hide solution ↑
Solution
| Classification | Justification |
|---|
| (a) | von Neumann | One main memory holds both program and data; single CPU–memory path; sequential fetch-decode-execute |
| (b) | Harvard | Separate memories and paths for instructions and data |
| (c) | Dataflow (non-von Neumann) | Execution driven by data availability, not by a program counter |
| (d) | Parallel / special-purpose (GPU) (non-von Neumann) | Many processors working at the same time to offload work from the CPU |
| (e) | Quantum computing (non-von Neumann) | Uses qubits instead of classical bits |