Microcontrollers & architecture 3 min read

Harvard vs von Neumann

A von Neumann CPU fetches instructions and data over one shared bus, so each memory cycle is either a fetch or a data access. A Harvard CPU gives code and data separate buses, so it can fetch the next instruction while it reads or writes data.

Left: in a von Neumann design the CPU reaches one memory, holding both instructions and data, over a single shared bus. Right: in a Harvard design the CPU has an instruction bus to program memory in Flash and a separate data bus to data memory in SRAM.
One shared road for code and data, or two separate ones.

One road or two

The von Neumann design keeps the program and its data in the same memory and reaches both over one bus. It is simple and flexible: code can be loaded into RAM and run like any other data. The catch is the von Neumann bottleneck. When an instruction needs data, the next instruction fetch has to wait for the bus.

The Harvard design, named after the Harvard Mark I that read its instructions from punched tape, separates the two. With an instruction bus and a data bus working in parallel, a pipelined core can keep fetching while it works on data.

What real chips do

Von NeumannHarvard
BusesOne, sharedSeparate for code and data
Memory accessFetch and data take turnsFetch and data can overlap
Address spacesOneSeparate (pure Harvard)
ExamplesArm Cortex-M0 and M0+AVR, PIC, 8051

Most modern parts are a modified Harvard mix. An Arm Cortex-M3 or M4 has separate I-Code and D-Code buses for speed, but both reach the same 4 GB address space, so one pointer type can read anything. Desktop CPUs do the same thing inside the core with split instruction and data caches.

Why it shows up in your code

On a pure Harvard AVR, Flash and SRAM have separate address spaces. A const table is still copied into scarce SRAM at startup unless you mark it PROGMEM and read it with a special function:

const uint8_t table[] PROGMEM = { 1, 2, 4, 8 };
uint8_t v = pgm_read_byte(&table[2]);   // reads Flash via the LPM instruction

On a Cortex-M, the same const table simply stays in Flash and you read it with an ordinary pointer.