EmbeddedRelated.com

Harvard Architecture

Category: Architecture

Harvard architecture is a processor design in which instruction memory and data memory occupy separate address spaces and are accessed over independent buses, allowing the CPU to fetch an instruction and read or write data simultaneously. This contrasts with von Neumann architecture, where a single shared bus and address space handles both instructions and data.

In practice

Harvard architecture appears throughout the embedded world, particularly in microcontrollers where program code lives in on-chip flash and data lives in SRAM. Classic examples of strict Harvard designs include the PIC16 and PIC18 families (Microchip), the AVR family (Atmel/Microchip), and many DSP cores such as those in the TI C2000 and Analog Devices SHARC families. (Note that PIC32, being MIPS-based with a unified address space, does not follow the same strict Harvard model.) The separation means the CPU can read the next opcode from flash at the same time it reads or writes a RAM variable, which can improve throughput without requiring a faster clock, provided the pipeline and memory banks support true concurrent access.

In practice, the physical separation also simplifies memory protection in simpler cores: because code and data are in distinct address spaces, a runaway pointer in SRAM cannot trivially overwrite flash (which is typically write-protected at the hardware level). This is one reason Harvard-style designs remain popular for small, safety-conscious MCUs.

A common source of confusion arises when placing constant data -- lookup tables, string literals, coefficient arrays -- in flash. On a strict Harvard machine, the data bus cannot reach program memory directly, so the compiler must emit special load-from-program-memory instructions or use ISA-specific mechanisms to access constants in program memory (for example, AVR's LPM or PIC's TBLRD, though the exact approach varies by architecture and toolchain). Forgetting this and storing a large const array in RAM wastes scarce SRAM and can be a subtle bug for developers coming from desktop backgrounds.

Many modern ARM Cortex-M cores use a modified Harvard architecture: they expose a unified address space to software (like von Neumann), but internally maintain separate instruction and data buses (I-Code/D-Code and System buses on ARMv7-M). This gives most of the throughput benefit of Harvard without the programmer-visible address-space split, though tightly coupled memory (TCM) on parts like the STM32H7 or i.MX RT series can still be configured to behave in a more strictly Harvard fashion for deterministic access.

Frequently asked

What is the practical performance benefit of Harvard architecture over von Neumann?
Because instruction fetches and data accesses use separate buses, they can occur in the same clock cycle rather than taking turns on a shared bus. This can reduce the impact of the 'von Neumann bottleneck' for workloads that mix frequent instruction fetches with frequent data reads or writes, though the actual benefit depends on pipeline depth, memory wait states, and whether a given loop is bus-bound rather than compute-bound. On simple pipelines with concurrent-access memory, this can meaningfully improve effective memory bandwidth without increasing clock speed.
Are ARM Cortex-M processors Harvard or von Neumann?
They are commonly called 'modified Harvard.' The programmer sees a single flat 32-bit address space (von Neumann style), but internally ARMv7-M cores have separate I-Code and D-Code AHB buses plus a System bus, so instruction fetches and data accesses can proceed in parallel. Some higher-end MCUs such as the STM32H7 and NXP i.MX RT additionally expose ITCM and DTCM (instruction and data tightly coupled memories) that behave more like a classical Harvard split.
Why do AVR and PIC programs need special instructions to read constant data from flash?
In a strict Harvard design, the data bus has no path into program memory. The CPU can execute code stored in flash, but cannot treat flash addresses as ordinary data pointers. AVR uses the LPM (Load Program Memory) instruction; PIC uses TBLRD. Compilers and linkers typically handle this automatically when you declare data as const and use the appropriate memory qualifier (PROGMEM on AVR, for example), but you must be aware of it when writing or reviewing low-level code.
Can a Harvard architecture run self-modifying code or load code dynamically?
On a strictly Harvard machine with write-protected program memory, self-modifying code and runtime code loading are either impossible or require special hardware support (a write path into program memory, as found on many PIC and AVR parts via their self-programming mechanisms). Modified Harvard designs, like Cortex-M, support this more readily because the unified address map allows code to be written to RAM and then executed from RAM, though the instruction cache (where present) must be invalidated after writing new code.
How does Harvard architecture affect linker scripts and memory layout in embedded projects?
On strictly Harvard MCUs, the linker must place initialized data in two locations: an image in flash (load address, LMA) and a runtime copy in SRAM (virtual address, VMA). Startup code copies the flash image to SRAM before main() runs. This LMA/VMA split is common in embedded linker scripts and is important to understand when debugging a freshly ported BSP, though the exact handling varies by target and toolchain. On modified Harvard Cortex-M targets the concept is the same, even though the address spaces are unified.

Differentiators vs similar concepts

Harvard architecture is most often contrasted with von Neumann (Princeton) architecture, which uses a single shared bus and address space for both instructions and data. The key practical difference is that Harvard allows simultaneous instruction fetch and data access, while von Neumann serializes them. The term 'modified Harvard' is used for designs (such as ARM Cortex-M) that present a unified address space to software but use physically separate internal buses, blending properties of both. Harvard should not be confused with the concept of cache hierarchy: a processor can have a split L1 instruction/data cache (which resembles Harvard internally) while still presenting a von Neumann address space, and many do.