Microcode vs Hardwired Control
So far, every decoder we've described produces its control signals in essentially one shot — opcode bits go in, control wires come out, all within a handful of gate delays. That works beautifully for simple, single-cycle operations like ADD Rd, Rr. But what about an instruction that needs to fetch an operand from memory, compute on it, and write the result back to memory, all as one instruction? That can't happen in one clock cycle's worth of wire-asserting. Something has to sequence multiple sets of control signals, one cycle after another, for a single instruction. Two very different engineering philosophies emerged to solve this — and which one a chip picked says everything about its era and its priorities.
The Problem: Some Instructions Need a Sequence, Not a Snapshot
A simple instruction is a single "snapshot" of control signals lasting one clock cycle. A complex instruction is really a recipe — a sequence of snapshots that must fire in order:
Generating these five distinct control-signal sets, in the correct order, for potentially dozens of different complex instructions, is a much harder design problem than the single-shot decoder from lesson 2. Two solutions emerged historically.
Learning Objectives
By the end of this lesson, you should be able to:
- Explain why some instructions require multiple control steps.
- Distinguish a microinstruction from an ISA-level instruction.
- Compare microcoded control with hardwired control in speed, flexibility, and design effort.
- Relate CISC and RISC instruction-set style to control-unit implementation.
- Explain why predictable control timing makes pipelining easier.
Approach 1: Microcode — The Opcode Indexes a Table of Sequences
In a microcoded control unit, the opcode doesn't directly drive control wires. Instead, it's used as an address into a small, fast internal ROM — the microcode ROM (sometimes called the control store) — and what comes back isn't one control word, but the starting address of a sequence of control words called microinstructions. A tiny internal sequencer then steps through that sequence, one microinstruction per clock cycle, until the macro-instruction is complete.
Each row in that ROM is a literal bit-pattern of control signals for one cycle. Conceptually:
A compact microcode sequence might look like this:
- Fetch: memory read enabled,
PC_inc = 1. - Decode address: ALU adds or forwards address fields as needed.
- Read operand: memory read enabled again for the data operand.
- ALU operation:
ALU_OP = ADD, register write still disabled. - Writeback: register write enabled, flags updated, memory write disabled.
This is precisely how Intel's 8085 and, more famously, x86 chips (from the original 8086 through many later generations) implemented their famously large, irregular instruction sets. Complex string-manipulation or BCD-arithmetic instructions on x86 could burn dozens of clock cycles, each one driven by a row read out of microcode ROM.
Why microcode made sense for CISC
CISC instruction sets are large and irregular by design — variable-length encodings, instructions that do a lot of work per opcode (e.g., x86's REP MOVS doing an entire memory block copy). Building purely combinational decode logic for hundreds of irregular instructions, many of which are functionally similar but not identical, would mean enormous, hard-to-verify gate networks. Microcode turns that hardware design problem into something closer to a software problem: write a new row in ROM and you've defined a new instruction's behavior, without touching the surrounding silicon at all. This made CISC chips easier to extend, easier to patch (some chips even allowed microcode updates), and cheaper to design for sprawling instruction sets — at the cost of speed.
Worked Example: One Instruction, Many Control Words
Consider a simplified "add memory to accumulator" instruction:
ACC = ACC + memory[HL]
A microcoded controller might use one microinstruction per internal step:
| Step | Main control action | Why it is separate |
|---|---|---|
| 1 | Put PC on address bus and read opcode |
External memory fetch needs a bus cycle |
| 2 | Increment PC and decode opcode |
The next instruction address must be prepared |
| 3 | Put HL on address bus and read operand |
Data memory read uses the same bus |
| 4 | Feed operand and ACC into ALU |
ALU needs stable inputs |
| 5 | Latch result and flags | State changes happen on a clock edge |
The ISA exposes this as one instruction, but internally the control unit executes a small program of control words. That internal program is the microcode.
Approach 2: Hardwired Control — Wired Directly, No Sequencer Table Lookup
A hardwired control unit, by contrast, builds the multi-cycle sequencing directly out of combinational and simple state-machine logic — usually a small finite state machine (FSM) with named states (Fetch, Decode, Execute, Writeback), where the state itself, combined with the opcode, directly produces control signals through logic gates. There's no ROM lookup table of sequences to step through; the sequencing logic is the hardware.
AVR and ARM (especially Cortex-M, and classic ARM cores like the ARM7TDMI) use hardwired control. Because RISC instruction sets are deliberately kept small, fixed-width, and regular, the combinational logic needed to decode them directly stays manageable — this regularity is exactly the design discipline RISC ISAs commit to, which you may recall from the CISC vs RISC fundamentals lesson, and it's why hardwired control became viable at all.
Why hardwired made sense for RISC
No ROM lookup means no ROM access latency. Control signals appear within a few gate-delays of the opcode and state being known, rather than waiting on a memory-like ROM read. For a philosophy built entirely around "make the common case (simple, single-cycle instructions) blazingly fast," this is exactly the right trade: pay more design effort up front (hand-crafting or synthesizing precise gate logic for each regular instruction class) in exchange for the fastest possible signal generation at runtime.
Head-to-Head Comparison
- Control source: microcoded CPUs read a control store; hardwired CPUs use logic gates and FSM state.
- Best fit: microcode suits large, irregular CISC instruction sets; hardwired control suits small, regular RISC encodings.
- Design effort: microcode can add behavior by adding rows; hardwired control needs optimized logic.
- Speed: microcode pays ROM/sequencer latency; hardwired control produces signals with fewer gate delays.
- Patchability: some microcoded CPUs can accept updates; hardwired behavior is fixed in silicon.
- Cycles per instruction: microcoded instructions often vary widely; hardwired RISC instructions tend to be one or a few predictable cycles.
- Pipelining: variable sequences make scheduling harder; fixed-latency stages pipeline more cleanly.
The Foreshadow: Hardwired Control Enables Pipelining
This last row deserves its own spotlight, because it's the thread that ties directly into our final lesson. Pipelining — overlapping the fetch, decode, and execute stages of consecutive instructions so the CPU is always working on several instructions at different stages simultaneously — depends on every stage having predictable, fixed timing. If the control unit's job is "look up a variable-length sequence in ROM and step through it," the number of cycles per instruction becomes data-dependent and irregular, which makes pipeline scheduling extremely difficult (this is part of why early CISC pipelining was so notoriously hard, and why later x86 chips quietly moved toward hardwired/RISC-like cores internally, translating x86 instructions into simpler internal micro-ops on the fly).
AVR's two-stage pipeline (fetch/execute overlap) and ARM Cortex-M's 1-3 stage pipelines are only practical because their hardwired control units guarantee that, in the overwhelming majority of cases, an instruction's control signals are ready exactly when the pipeline expects them — no ROM-lookup uncertainty in the way.
Common Mistakes
- Confusing microcode with assembly language. Microcode is internal CPU control data, not the programmer's ISA.
- Assuming all CISC chips are slow and all RISC chips are single-cycle. Modern implementations are more nuanced.
- Believing hardwired control means "no state machine"; multi-cycle hardwired controllers still have states.
- Ignoring verification cost. Hardwired control can be fast but difficult to modify once silicon ships.
- Forgetting that microcode updates may patch behavior but cannot change arbitrary physical datapath limits.
Summary
Microcode and hardwired control are two answers to the same problem — "how do I sequence control signals across multiple clock cycles for one instruction" — and the answer a chip picked reveals its priorities: microcode trades speed for design flexibility and instruction-set complexity (CISC's bet), while hardwired control trades design effort for raw speed and predictability (RISC's bet). That predictability is exactly what makes pipelining tractable — and pipelining is the next big leap once you've mastered the single-cycle mechanism we're about to walk through, instruction by instruction, clock edge by clock edge.
Next: The Fetch-Decode-Execute Cycle, One Clock Edge at a Time
Further Reading
- Hennessy and Patterson, Computer Architecture: A Quantitative Approach, instruction-set and implementation trade-offs.
- Intel, Intel 64 and IA-32 Architectures Software Developer's Manual, microcode update and instruction behavior references.
- Patterson and Hennessy, Computer Organization and Design, control implementation chapters.
- Arm, Cortex-M Technical Reference Manuals, pipeline and control overview sections.