System on a Chip
A system on a chip (SoC) is an integrated circuit that puts most or all of the parts of a useful computer onto a single piece of silicon: one or more processor cores, on-die memory, a bus or network fabric that wires them together, peripheral controllers for I/O, and the surrounding plumbing of clocks, resets, power islands, and analog interfaces (Wikipedia, “System on a chip”). The point of integration is not a single performance number. It is the elimination of off-chip wires: every signal that stays on die is faster, lower power, and lower assembly cost than one that crosses a bond wire to a neighbour package. The category stretches from a 20,736-LUT softcore running on a Gowin GW2AR-18 (Sipeed, “Tang Nano 20K”) up to a 28-billion-transistor Apple M4 fabricated on TSMC’s N3E node (Wikipedia, “Apple M4”). Everything in between (the SiFive FU540 with four U54 cores plus an E51 monitor on a 28 nm die, the Espressif ESP32-C3 with a single RV32IMC core and integrated Wi-Fi, the Raspberry Pi’s BCM2835) is the same idea at different scales.
Mental Model
flowchart TB subgraph SOC["A typical SoC die"] subgraph COMPUTE["Compute"] CPU["CPU cluster<br/>(1-N cores, L1 caches)"] GPU["GPU / vector / NPU<br/>(optional)"] L2["Shared L2 / LLC"] CPU --> L2 GPU --> L2 end subgraph FABRIC["Interconnect"] BUS{"Bus or NoC<br/>(AXI / Wishbone / mesh)"} end subgraph MEMSYS["Memory system"] MC["DRAM controller<br/>(LPDDR / DDR / SDRAM)"] SRAM["On-die SRAM / scratchpad"] ROM["Mask ROM (boot)"] end subgraph PERIPH["I/O peripherals"] UART["UART"] SPI["SPI / I2C"] USB["USB / Ethernet / Wi-Fi MAC"] GPIO["GPIO / ADC / DAC"] end subgraph PLATFORM["Platform glue"] CLK["Clock tree, PLLs"] RST["Reset controller"] PMC["Power management,<br/>voltage islands"] IRQ["Interrupt controller<br/>(PLIC / GIC / NVIC)"] EFUSE["eFuse, secure boot,<br/>key store"] end L2 <--> BUS BUS <--> MC BUS <--> SRAM BUS <--> ROM BUS <--> UART BUS <--> SPI BUS <--> USB BUS <--> GPIO IRQ -.->|"wires to all peripherals"| BUS CLK -.->|"clocks every block"| COMPUTE PMC -.->|"power domains"| COMPUTE end EXT["Off-chip:<br/>DRAM die, NOR flash,<br/>antenna, sensors"] MC <-->|"bond wires + PCB traces"| EXT
Building blocks of a typical SoC. What it shows: a compute cluster (CPU plus optional GPU or accelerator) sits behind a shared cache, a bus or network-on-chip moves traffic between compute, memories, and peripherals, and a platform layer of clocks, resets, power management, and an interrupt controller knits the whole die into something a single program can drive. The insight to take: the SoC is defined less by what it computes than by what it does not need off the die. Memory controllers replace external memory glue chips, an integrated UART replaces an MC1488 line driver, an on-die Wi-Fi MAC replaces a Marvell 88W chip, and an interrupt controller replaces an 8259A. The boundary of the SoC is the boundary of “things that no longer have to be a separate package.”
How “System on a Chip” Got Its Modern Meaning
Until the early 1990s, even a modest computer was a board full of chips. An Acorn Archimedes from 1987 used four discrete integrated circuits to handle CPU, memory controller, video, and I/O: the ARM2 microprocessor, the MEMC memory controller, the VIDC video controller, and the IOC I/O controller (Wikipedia, “System on a chip”). The ARM250, shipped in 1992, fused those four blocks onto one die. It is the first chip that Wikipedia’s SoC history article calls “Acorn’s first SoC” (Wikipedia, “System on a chip”). The follow-on ARM7500 took the same approach for the next generation and was licensed widely into set-top boxes.
The motivation was always the same. Each chip-to-chip boundary costs board area, board layers, package pins, power dissipation, and electromagnetic radiation. It also costs latency: an on-die wire of a few millimetres dissipates a few picojoules, while a bond wire plus a centimetre of PCB trace plus another bond wire dissipates orders of magnitude more and adds tens of picoseconds of propagation. When transistor budgets started to make integration feasible, the economics drove relentlessly toward absorbing peripheral chips into the CPU die.
Two streams of integration ran in parallel. The microcontroller stream pulled small peripherals (UART, SPI, GPIO, ADC, timers) and a few kilobytes of SRAM and flash onto a single die around a small CPU: the Intel 8051 family from 1980, the Atmel AVR from the mid-1990s, the STM32 from 2007. By the time the Espressif ESP32 launched in 2016, an MCU was expected to ship not just CPU and memory but a full radio: 2.4 GHz Wi-Fi 4 transceiver, Bluetooth 5.0 LE, the RF balun, the matching network, the band-pass filter (Espressif, “ESP32-C3 datasheet”). The discrete “modem chip” disappeared into the MCU. The application processor stream pulled the chipset (memory controller, PCI bridges, USB hub, audio codec, GPU) onto the CPU die. The first big mobile SoCs (the TI OMAP and Qualcomm MSM lines starting in the early 2000s, then Apple’s A4 in 2010) made the phone the canonical SoC platform. By the M1 in 2020, Apple Silicon completed the absorption: the M1 integrated CPU cores, GPU, Neural Engine, and an LPDDR4X memory controller on a 5 nm TSMC process at 16 billion transistors, and the laptop chipset disappeared entirely (Wikipedia, “Apple silicon”). The Apple M4 launched in May 2024 carries this to 28 billion transistors on TSMC’s N3E process, with the M4 Max variant landing on November 8, 2024 (Wikipedia, “Apple M4”).
Uncertain
Verify: the exact transistor count for the Apple M4 Max. Reason: Wikipedia’s M-series transistor-count table lists 28 billion for the base M4 but leaves the M4 Pro and M4 Max rows blank (Wikipedia, “Transistor count”). Secondary sources circulate a “roughly 95 billion” estimate, but Apple has not published an official figure as of mid-2026. To resolve: cite an official Apple press release or a confirmed die-photo analysis once one appears, or use the verified family-trend bracket (M3 Max was 92 billion) and flag.
The Building Blocks, Layer by Layer
Compute
At the heart sits one or more processor cores. A microcontroller-class SoC typically ships one to two cores: the ESP32-C3 has a single RV32IMC core running at up to 160 MHz (Espressif, “ESP32-C3 datasheet”). A mid-range application SoC ships an asymmetric cluster: the SiFive FU540 has four U54 application cores and one E51 monitor core (SiFive, “FU540-C000 Manual v1.0”). A high-end mobile or laptop SoC ships ten or more cores split between performance and efficiency clusters, optionally with a GPU and a neural-processing unit on the same die. Whatever the size, each core has its own L1 instruction and data caches; the cluster shares an L2 or last-level cache. The FU540, for example, includes “a 2 MiB shared L2 cache divided into 4 address-interleaved banks” of 16-way set-associative storage (SiFive FU540 Manual).
Memory hierarchy
On-die SRAM gives single-cycle access and disappears off-die DRAM latency. A microcontroller often runs entirely out of on-die SRAM: the ESP32-C3 has 400 KB of on-chip SRAM plus a 384 KB mask ROM holding bootloader and bootstrap, with 16 KB of that SRAM configurable as a unified instruction and data cache (Espressif, “ESP32-C3 datasheet”). Application-class SoCs add a DRAM controller for external LPDDR or DDR memory, often with the DRAM die stacked atop the SoC in a package-on-package configuration (Wikipedia, “System on a chip”). Apple’s M-series unifies CPU and GPU access to the same LPDDR pool, eliminating the discrete-GPU pattern of copying data across PCIe (Wikipedia, “Apple silicon”).
Interconnect
The cores, caches, memories, and peripherals all hang off a bus or a network-on-chip. The bus is the part of the SoC that most varies in scale. A small open-source softcore wires everything onto an Wishbone Bus, the public-domain OpenCores standard with a tiny CYC/STB/ACK handshake (Wishbone B4 specification, OpenCores 2010). A commercial ARM-based SoC uses AMBA AXI for high-performance memory traffic and AMBA APB for peripherals. A large multi-core or many-core design replaces the bus with a packet-switched network-on-chip (NoC) of mesh or ring topology, because a single shared bus cannot scale to dozens of masters without serialization collapsing throughput (Wikipedia, “System on a chip”).
Peripherals
Anything that the chip needs to talk to in the outside world has a controller on die. The categories are durable: digital serial buses (UART, SPI, I2C), parallel and memory-style buses (NAND flash, eMMC, SDIO), wired networking (USB, Ethernet, PCIe), wireless (Wi-Fi MAC, Bluetooth controller, cellular modem, 802.15.4 radio), analog (ADCs, DACs, comparators), and signal-processing accelerators (cryptographic engines, video decoders, image-signal processors). The Espressif ESP32-C3 illustrates the microcontroller end of the spectrum in a 5 mm by 5 mm QFN32 package: two UARTs, three SPI controllers, an I2C, an I2S, a TWAI/CAN controller, a USB Serial/JTAG, two 12-bit SAR ADCs, a six-channel LED PWM controller, plus the Wi-Fi 4 and Bluetooth 5 LE radios and their RF front end (Espressif, “ESP32-C3 datasheet”).
Platform glue
The least glamorous but most pervasive blocks are the platform infrastructure. A clock tree distributes one or more PLL-derived clocks across the die, with gating to disable clocks for idle blocks. A reset controller sequences power-on. Voltage islands let blocks operate at different supply voltages so that low-power blocks do not pay the dynamic power cost of high-performance blocks. An interrupt controller routes asynchronous peripheral events to the CPU’s interrupt input: on a RISC-V SoC, that is typically a Core Local Interruptor (CLINT) for the standard machine-timer and software interrupts plus a Platform-Level Interrupt Controller (PLIC) for prioritized external interrupts (Wikipedia, “RISC-V”). An eFuse array, secure boot ROM, and crypto accelerators provide a root of trust for chips that have to ship with secure features (the ESP32-C3 includes 4096 bits of eFuse, AES-128/256, SHA, RSA, HMAC, and a true random-number generator (Espressif, “ESP32-C3 datasheet”)).
SoC vs Chiplet vs Discrete CPU + Chipset
A SoC is a monolithic die: every block listed above lives on one piece of silicon and is connected by on-die metal. That choice is excellent for power and latency but punishing for yield. The probability that a die comes off the wafer defect-free falls roughly with the inverse exponential of die area, so a 600 mm² monolithic die at TSMC N3 yields far worse than five 120 mm² dies on the same process. It is also inflexible: every block has to be fabricated on the same process node, even if the cost or power optimum for analog or I/O blocks is on a more relaxed node.
A chiplet approach splits the system across multiple small dies (chiplets) co-packaged in a single module (Wikipedia, “Chiplet”). The first commercially successful chiplet design was AMD’s first-generation EPYC (“Naples”, 2017), which combined four separate Zeppelin dies in a multi-chip module. AMD’s Zen 2 generation (Ryzen 3000 and EPYC Rome, 2019) made the chiplet pattern canonical: a 7 nm “core complex die” (CCD) holds eight CPU cores, a 14 nm “I/O die” holds the memory controllers and PCIe controllers, and a single package combines several CCDs around one I/O die. Nvidia’s H100 datacenter GPU and Intel’s Sapphire Rapids, Meteor Lake, and Arrow Lake CPUs use chiplet packaging today (Wikipedia, “Chiplet”). The benefits are exactly the trade-off of integration: better yield (each chiplet is small enough to ship defect-free), heterogeneous integration (each chiplet can use its optimal process), and reusable intellectual property (the same chiplet can ship in many SKUs). The cost is the inter-chiplet link: signals between chiplets have to leave the die, traverse silicon interposer or organic substrate routing, and re-enter the receiving die. That link has measurable latency, power, and silicon-area overhead that monolithic SoCs do not pay. Industry standards (UCIe, AIB) try to bring this overhead down (Wikipedia, “Chiplet”).
A discrete CPU plus chipset is the older model that integrated SoCs replaced. A Pentium-era PC had a CPU in one socket, a “northbridge” chip handling DRAM controller and graphics bus, a “southbridge” chip handling USB, SATA, audio, and slower peripherals, plus several smaller support chips. The model survives in some workstation and server segments (Intel Xeon plus C-series PCH), but mobile, embedded, and consumer laptop markets have moved almost entirely to integrated SoC designs because the power, latency, and board-area costs of the chipset model became indefensible.
The line between SoC, chiplet, and multi-chip module is fuzzy at the high end. Apple’s M1 Ultra (March 2022) combined two M1 Max dies through a 2.5 TB/s “UltraFusion” silicon interposer to present a single 114 billion-transistor “chip” to software (Wikipedia, “Transistor count”; Wikipedia, “Apple silicon”). Strictly that is a chiplet design, but Apple markets it as a single SoC. The taxonomy is less rigid than vendors’ marketing implies.
How “SoC” Stretches from a Tiny FPGA Softcore to Apple M-Series
The fascinating part of the SoC concept is how the same word covers eight orders of magnitude of complexity.
At the very bottom: a hobbyist RISC-V softcore synthesized into a Tang Nano 20K FPGA. The chip is a Gowin GW2AR-LV18, with 20,736 LUT4 logic cells, 828 Kbit of block SRAM across 46 BSRAM blocks, 48 18 by 18 multipliers, and 64 Mbit of in-package SDRAM (Sipeed wiki, “Tang Nano 20K”; Gowin, “GW2A-LV18 datasheet”). A typical project consumes maybe 5,000 to 8,000 LUT4s for the CPU, hangs a Wishbone bus off it, fans the bus out to a CLINT, a PLIC, a UART, and a memory controller fronting the in-package SDRAM, and calls the whole thing a “SoC.” It is a SoC: every piece lives on one die, the FPGA configuration RAM. It just runs at one or two orders of magnitude lower clock than a hard SoC.
In the middle: the SiFive FU540, the first commercially available Linux-capable RISC-V SoC. Four U54 application cores plus one E51 monitor core, 2 MB of shared 16-way L2 cache, a DDR4 memory controller, a Gigabit Ethernet MAC, SPI, UART, GPIO, CLINT, and PLIC, all fabricated on TSMC’s 28 nm process (SiFive, “FU540-C000 Manual v1.0”; SiFive, “FU540-C000 Manual v1.4”). The FU540 shipped on the HiFive Unleashed dev board with 8 GB of external DDR4 with ECC and 32 MB of QSPI flash (SiFive HiFive Unleashed board). Same blocks as the FPGA softcore, real silicon, real performance.
At the top: the Apple M4 family. The base M4 is 28 billion transistors on TSMC N3E with up to ten CPU cores, ten GPU cores, a Neural Engine, an integrated LPDDR5X memory controller, the entire I/O subsystem (USB4, Thunderbolt, PCIe), the Image Signal Processor for camera capture, video encoders, the Secure Enclave coprocessor, and a unified memory architecture (Wikipedia, “Apple M4”; Wikipedia, “Apple silicon”). The M4 Max (November 2024) scales to up to sixteen CPU cores and forty GPU cores in roughly the same architectural shape.
The same conceptual block diagram fits all three. The compute block changes from a 5,000-LUT softcore to four U54s to ten Apple performance cores. The interconnect changes from a single Wishbone bus to a TileLink ring to a packet-switched on-die mesh. The peripheral list grows from UART plus GPIO to UART plus GigE to USB4 plus PCIe plus Wi-Fi 6E plus the Neural Engine. But the SoC concept (one die, every component the CPU needs, plus the plumbing to connect them) is the same.
Configuration and Code: A Minimal SoC Memory Map
Every SoC has a memory map: which addresses route to which on-die block. A typical small RISC-V SoC memory map looks like this (the definitely-not-esp32 project’s v1.0 layout, derived from the SiFive FU540 layout for compatibility):
0x0000_0000 - 0x0000_FFFF Boot ROM 64 KiB (initial M-mode boot stub)
0x0200_0000 - 0x0200_BFFF CLINT ~48 KiB (mtime, mtimecmp, msip)
0x0C00_0000 - 0x0FFF_FFFF PLIC 64 MiB (priority, claim/complete)
0x1000_0000 - 0x1000_0FFF UART 4 KiB (TX/RX/STATUS/CTRL regs)
0x8000_0000 - 0x83FF_FFFF Main RAM 64 MiB (DDR or in-package SDRAM)
Line-by-line: the boot ROM lives at the reset vector so the CPU can fetch its first instruction after reset; the CLINT and PLIC live at well-known addresses inherited from the SiFive RISC-V platform spec; the UART is a small 4 KiB window because it has only a handful of registers; main RAM lives at 0x8000_0000 (the standard RISC-V “DRAM base”) and stretches as far as the memory controller allows. The bus fabric uses the high bits of the address to decode which slave handles a transaction; everything below the bus boundary is the same SoC concept, just at different scales.
Failure Modes and Misunderstandings
- “A SoC is just a CPU with more stuff on it”: not quite. A SoC is fundamentally an integration product. A CPU is a single block; a SoC is the agreement among many blocks about how they share clock, power, address space, and interrupts. The hard problem in modern SoC design is verification across all those interfaces. Wikipedia notes that “functional verification” alone accounts for roughly 70 percent of chip-design lifecycle effort (Wikipedia, “System on a chip”).
- “SoC means microcontroller”: false. The SoC concept covers both microcontrollers and the M4 Max. The microcontroller world (ARM Cortex-M, RISC-V RV32 cores, AVR) is dominated by SoCs because the economics demand integration. The application processor world (mobile, laptop, datacenter accelerators) is dominated by SoCs for the same reason.
- “More integration is always better”: false in two ways. First, thermal density rises with integration; the Wikipedia article notes that SiP (system in package) “may be preferred when thermal constraints exist,” because the dies can be separated enough to spread heat (Wikipedia, “System on a chip”). Second, monolithic yield falls exponentially with die area; past some size, the chiplet approach is cheaper per shipped good unit even after the inter-chiplet overhead.
- “SoC is just a marketing term”: also false. Until the early 1990s, integrating CPU plus memory controller plus video plus I/O onto a single die was not feasible at consumer transistor budgets. The ARM250 from 1992 was the proof-of-concept that it could be done, and the term has a specific technical meaning: one die, one package, the components a useful computer needs (Wikipedia, “System on a chip”).
Alternatives and When to Choose Them
- Monolithic SoC: best for mobile, embedded, and consumer designs where power per transaction matters and the die fits comfortably on a single reticle. ESP32-C3, A-series and M-series Apple Silicon, Snapdragon, Exynos, MediaTek Dimensity all fit here.
- Chiplet / multi-chip module: best for high-end designs where the system is too large for a single yieldable die, or where heterogeneous integration (logic on N3, I/O on N5, analog on N7) saves cost. AMD EPYC, Intel Sapphire Rapids, Apple M-series Ultra variants. Pays an inter-chiplet latency tax.
- System in package (SiP): best for tight space constraints where the dies do not need to be tightly coupled but must share a package footprint. Stacked LPDDR atop a SoC is the canonical example. The wireless module form factor (ESP32-C3-MINI-1, Nordic nRF modules) is a SiP that adds the antenna and matching network atop a chip.
- Discrete CPU plus chipset: best for the server and workstation segments where socketed upgrades, large memory channel counts, and platform configurability outweigh integration savings. Intel Xeon with C740-series PCH, AMD EPYC SP5 platforms.
- FPGA softcore SoC: best for prototyping, education, low-volume custom hardware, and projects where bringing up a fabricated SoC is infeasible. The Tang Nano 20K is the canonical cheap target.
Production Notes
- The Espressif ESP32-C3 is a complete real-world example at the small end: a single die in a 5 mm by 5 mm QFN32 package containing CPU, 400 KB SRAM, 384 KB ROM, Wi-Fi 4 radio, Bluetooth 5 LE controller, two UARTs, three SPIs, USB Serial/JTAG, two ADCs, full security stack (Secure Boot V2, Flash Encryption, AES, SHA, RSA, HMAC, RNG), and the platform glue (Espressif, “ESP32-C3 datasheet”). See ESP32-C3 for the full breakdown. The MINI-1 module wraps the chip plus an external flash plus a PCB antenna into a 13.2 mm by 16.6 mm SiP.
- The SiFive FU540 is the canonical “midsize” RISC-V SoC: enough integration to run Linux but small enough to study end-to-end. Its memory map and CLINT/PLIC layout became the de facto reference for the broader RISC-V open-source ecosystem; the Core Local Interruptor register layout that QEMU’s
sifive_umachine implements is the FU540’s (QEMU, “SiFive HiFive Unleashed”). - For definitely-not-esp32 specifically, the v1.0 SoC is the smallest interesting end of the spectrum: a single RV32IMC core in roughly 5,000 to 8,000 LUT4s, PMP for isolation, a Wishbone bus, a CLINT, a PLIC, a UART, and a memory controller fronting the Tang Nano 20K’s in-package SDRAM. The blog series treats every block in this list as a separate post; this MOC is the index of the underlying concepts.
See Also
- Tang Nano 20K
- ESP32-C3
- Wishbone Bus
- Core Local Interruptor
- Platform-Level Interrupt Controller
- Universal Asynchronous Receiver-Transmitter
- Physical Memory Protection
- Field-Programmable Gate Array
- Register-Transfer Level
- RISC-V Instruction Set Architecture
- RV32IMC
- Microkernel
- Computer Architecture MOC