Open a desktop PC from 1998 and you find a small city: a CPU chip, rows of memory chips, a sound
card, a modem card, a disk controller, a graphics board — dozens of packages shouting at each other
across centimetres of copper trace. Open a modern phone and you find… one chip. The CPU is in
there. The memory controller is in there. The USB port's brains, the timers, the display engine,
the AI accelerator — all in there, on one die. You have spent five modules building and
The chips-on-a-board approach lost for three compounding reasons. Cost: every
separate package needs its own slice of silicon overhead, its own pins, its own board area and
assembly step — one die amortises all of that. Power: driving a signal across a
board trace costs hundreds of times the energy of an on-chip wire, because board traces are
enormous capacitors by chip standards; a phone that had to shout across a board would be a
hand-warmer. Latency: on-chip neighbours talk in fractions of a nanosecond, while
a trip through package pins and back is an eternity the clock cannot hide. The
So who lives on the die? A typical SoC's cast list:
Different vendors pick different casts, but every SoC answers the same organising question: when the CPU executes a load or a store, who answers?
The answer is the memory map. Every block that software can talk to claims a range of addresses, and the whole 32-bit (or larger) address space is carved up like territory on a map:
| Range (start) | Size | Owner | What lives there |
|---|---|---|---|
0x0000_0000 | 64 KiB | Boot ROM | the first instructions ever fetched |
0x2000_0000 | 128 KiB | SRAM | fast on-chip working memory |
0x4000_0000 | 4 KiB | UART | serial-port registers |
0x4001_0000 | 4 KiB | Timer | counter and compare registers |
0x4002_0000 | 4 KiB | GPIO | pin input/output registers |
0x8000_0000 | 1 GiB | DRAM | main memory, via the controller |
Here is the move that makes the whole scheme sing: memory-mapped I/O. The UART's
transmit register is not reached by some special "talk to a device" instruction — it simply
is address 0x4000_0000. A store to that address drops a byte into the UART;
a load from the timer's range reads the current count. The same lw/sw
instructions your CPU already speaks — the exact datapath you built — control every device on the
chip. Software's view of hardware is just… addresses.
Turning an address into an owner is address decode: combinational logic (you could
write it in an afternoon of always_comb) that inspects the high bits and routes the
transaction. High bits pick the block; low bits are the offset — which register
or word inside it. Address 0x4001_0008 decodes as "the timer block, offset 8".
Step through the diagram and watch a system condense around one spine. Every box that joins brings its own address range — its entry in the org chart:
Notice the shape: a few masters on top (blocks that start transactions — the CPU, the DMA engine) and many slaves below (blocks that answer). The spine between them is the interconnect — it gets two whole lessons of its own next.
Address decode is so central it deserves running code. Here is the map above as data, and a decoder that answers the only question the fabric ever asks — including what happens when an address lands in nobody's territory:
The store to 0x4000_0000 decodes to "UART, offset 0" — that byte is on its way out of
the serial port. And 0x5000_0000 hits a hole: no block claims it, so
a well-built fabric returns an error response and the CPU takes a fault. (A badly built one hangs
forever waiting for an answer that never comes — a bug every SoC bring-up team has met at 2 a.m.)
Nobody designs all of an SoC. A phone-chip team typically licenses the CPU cluster (say, Arm cores), buys or reuses the standard peripherals and interconnect — collectively called IP blocks ("intellectual property") — and spends its own designers on the blocks that differentiate the product: the camera pipeline, the neural engine, the modem. Integration is the craft of making a hundred blocks from a dozen sources behave as one chip. That works only because the blocks agree on standard interfaces — which is exactly what the next lesson's AXI protocol is for.
Integration also owns the concerns no single block can: system-level decisions. Where does the CPU fetch its very first instruction? (The boot ROM, at a fixed, agreed address.) Which device interrupt is wired to which CPU input? (The interrupt map.) In what order do a hundred blocks come out of reset, and who feeds each one its clock? (The clock and reset trees.) None of these belong to the UART or the CPU — they belong to the system, and getting them wrong bricks a chip made of individually perfect blocks.
In 1983, Motorola's DynaTAC "brick" phone carried its radio, logic and audio on roughly a dozen boards' worth of components — and cost about $4,000. By the late 1990s a phone needed a handful of chips: a baseband processor, separate memory, a power-management chip, radio chips. Today a budget smartphone's main SoC folds the CPU cluster, GPU, modem logic, image processors and dozens of peripherals into a single package smaller than your thumbnail — billions of transistors that cost less than the brick's battery did. The driver is the economics in this lesson run for forty years straight: every generation, moving one more chip's job onto the main die made the system cheaper, cooler and faster — so every generation, one more chip vanished.
The classic integration bug: two blocks are configured with overlapping address
ranges — say a new accelerator is dropped in at 0x4001_0000, where the timer
already lives. Now a store to that range has two possible owners. Depending on how the decode was
built, either both blocks respond — two slaves driving one response channel, giving bus
contention and corrupted data — or the decoder's priority logic silently prefers one, and
the other block becomes unreachable in a way no simulation of either block alone will ever catch.
The lesson: the memory map is a chip-wide contract with single ownership. Real
teams keep it in one machine-readable file, generate the decoder and the software headers
from it, and gate every merge on an overlap check. One map, one owner per address, no exceptions.