15.6 Register File: CPU-Internal Storage for Operands
Explain how a register file provides multiple simultaneous read ports and a write port to store and supply CPU operands, and trace how an instruction's register addresses select data.
A register file is the small, extremely fast block of storage inside a CPU that holds its general-purpose registers — the handful of values (typically 8 to 32, depending on the architecture) that instructions read operands from and write results to. Unlike main memory, which is large but relatively slow to access, a register file is built for speed: it must supply operands to the ALU (Section 15.1) fast enough to keep up with one instruction executing per clock cycle, which is why it is architecturally its own dedicated, tightly-coupled storage block rather than just a fast corner of general memory.
Structure: Multiple Registers, Read Ports, and a Write Port
A register file is built from multiple registers — a small array of individually addressable storage locations, each wide enough to hold one operand (commonly 32 or 64 bits in a modern general-purpose CPU). Address selection picks which specific register within that array is being read or written on a given cycle: a register address is simply a binary index (for example, a 5-bit address selects one of 32 registers), decoded internally to enable the corresponding storage cell.
Because most instructions need two source operands and produce one destination result, a typical register file provides two read ports and one write port operating simultaneously within a single clock cycle: Read Address A selects the data that appears on Register A's output, Read Address B independently selects the data that appears on Register B's output, and a separate Write Address, together with a write-enable control signal, determines which register — if any — is updated with new data on that same cycle's clock edge. Supporting two simultaneous, independent reads plus one write in a single cycle is exactly what lets a simple CPU datapath read both ALU operands and write back the previous instruction's result without needing multiple clock cycles just for register access.
• Multiple registers — a small array of fast, individually addressable storage locations. • Read Address A → Register A: one independent read port. • Read Address B → Register B: a second, simultaneous independent read port. • Write Address + write-enable → Destination Register: the write port, gated to a clock edge. • Address selection (decoding a binary register index) picks which physical register each port accesses.
Why Two Read Ports and One Write Port
The specific choice of two read ports plus one write port is not arbitrary — it directly matches the operand shape of a typical instruction set: most arithmetic and logic instructions (Sections 15.1–15.3) take exactly two source register operands and produce exactly one destination result, so a register file with two read ports and one write port can service a complete instruction's register needs within a single cycle, with no port contention. Instruction sets or microarchitectures that issue more than one instruction per cycle (superscalar designs) need correspondingly more read/write ports, at increasing hardware cost, since each additional simultaneous port requires additional decoding and routing hardware.
The write port's write-enable signal matters as much as its address: not every instruction writes a register result (a store-to-memory instruction, for example, may not write back to the register file at all), so the control unit asserts write-enable only when the currently executing instruction actually needs to update a destination register, preventing an unintended write from corrupting register state on cycles where no register write was intended.
• Two read ports + one write port matches the typical 'two source operands, one destination' instruction shape. • Superscalar (multi-instruction-per-cycle) CPUs need more ports, at higher hardware cost. • A write-enable control signal, gated by the clock, ensures registers are only updated when an instruction actually intends to write a result.
Practical and Real-World Applications
Every general-purpose CPU architecture — from small embedded microcontrollers to high-performance desktop and server processors — includes a register file as CPU register storage, holding the operands and results instructions operate on far faster than any access to main memory could provide. In a classic single-cycle or pipelined datapath (Section 15.7), the register file sits directly between the instruction fetch/decode stage (which supplies the read addresses from the instruction's encoded register fields) and the ALU (which consumes the two read outputs as operands), with the write port closing the loop by feeding computed results back in for the next instruction to use.
Code Examples
The instruction's two source register fields (R1, R2) drive the register file's two independent read ports simultaneously, supplying both ALU operands in the same cycle. The ALU computes the sum, and the instruction's destination field (R3) drives the write port — with write-enable asserted, since this ADD instruction does intend to write a result — updating R3 on the next clock edge. Expected result: R3 ← R1 + R2
Two simultaneous reads (R1, R2) plus one gated write (R3) — the full register-file service for one ADD instruction in a single cycle.
Instruction: ADD R3, R1, R2 (R3 <- R1 + R2)
Read Address A = R1 → Register A output = value of R1
Read Address B = R2 → Register B output = value of R2
[ ALU computes R1 + R2 ]
Write Address = R3, Write Enable = 1, Write Data = ALU result
→ R3 is updated with R1 + R2 on this clock edgeRegister file ports
Two independent read ports let a single-cycle instruction fetch both ALU operands at once; the single write port, gated by write-enable, updates one destination register per cycle.
Read Address A ──►┌───────────────┐──► Register A (data out)
Read Address B ──►│ Register File │──► Register B (data out)
Write Address ──►│ (N registers) │
Write Data ──►│ │
Write Enable ──►└───────────────┘Important Rules
A register file holds multiple registers, each addressable by a binary index.
Two independent read ports let two source operands be read in the same cycle.
One write port, gated by a write-enable signal, updates at most one destination register per cycle.
Read Address A → Register A, Read Address B → Register B, Write Address → Destination Register — the standard access pattern.
Port count is matched to the instruction set's typical operand shape; wider instruction issue (superscalar) needs more ports.
Where register files show up
Every CPU's general-purpose register set — R0–R31 in many RISC architectures, or the general registers in a CISC processor — is physically implemented as a register file, and GPUs and DSPs use analogous, often much wider, register files to feed their own parallel execution units.
Assuming a register file can only be read from or written to in a given cycle, not both at once.
Recognize that a register file's separate read and write ports operate simultaneously within the same clock cycle — a well-designed single-cycle datapath reads two operands and writes back a previous result in the very same cycle.
The whole point of having independent read and write ports (rather than a single shared access path) is to allow simultaneous access — two reads and a write can all happen in one clock cycle without conflict, which is essential for a single-cycle-per-instruction CPU design.
Why do most general-purpose CPU register files provide exactly two read ports and one write port? A. It is an arbitrary historical convention with no technical reason B. It matches the typical instruction shape of two source operands and one destination result, letting a full instruction's register access happen in a single cycle C. Register files can never have more than two read ports due to a physical limit D. One read port is always reserved exclusively for the program counter
B. It matches the typical instruction shape of two source operands and one destination result, letting a full instruction's register access happen in a single cycle — Most arithmetic/logic instructions need exactly two source operands and produce exactly one result, so two read ports plus one write port lets a register file fully service a typical instruction's register needs in one clock cycle — matching hardware to the common case without paying for unused ports.
What is the role of the write-enable signal on a register file's write port? A. It selects which of the two read ports is active B. It determines the clock frequency of the CPU C. It ensures a register is only updated when the currently executing instruction actually intends to write a result, preventing unintended writes D. It converts the write address from binary to decimal
C. It ensures a register is only updated when the currently executing instruction actually intends to write a result, preventing unintended writes — Not every instruction writes back to the register file (a memory store instruction, for example, typically does not), so the control unit asserts write-enable only for instructions that do intend to update a destination register, ensuring register state isn't corrupted on cycles where no write was meant to happen.
A register file has 3 read ports and 1 write port. What does this suggest about the kind of instructions or CPU design it supports, compared to the standard 2-read/1-write design described in this lesson?
A 3-read/1-write register file suggests support for instructions that take three source operands in a single cycle (such as a fused multiply-add instruction, R4 = R1 * R2 + R3, which needs three source registers read simultaneously), or a more complex issue scheme than the standard two-operand arithmetic/logic instruction shape assumed by a basic 2-read/1-write design — this comes at the cost of additional decoding and routing hardware for the extra port.
Think about what kind of instruction would need three simultaneous source operands read in a single cycle.