digiwleeaLearn
Open the lab →

The register file

The CPU's fast scratch storage

7 min read

A register file is a small array of registers with several independent read and write ports addressed by register number, so a datapath can read two source operands and write one result in the same clock cycle.

An 8-bit register stores one byte, and you write it by asserting its write-enable and pulsing the clock. A CPU needs a handful of these that it can name, so it can hold several values at once and pick any of them by number. Line up N registers, give them an address, and add ports to read and write the one the address selects: that is a register file, the fast scratch storage the processor does its work in.
You already have all three ingredients. The registers are 8-bit registers. Choosing which one to *write* is an addressing job, so it uses a decoder. Choosing which one to *read* is a selection job, so it uses a multiplexer. The file is those blocks wired together, addressed by register number.
Think of a small rack of numbered lockers. A 2-bit address names one of four lockers. To put something away you open exactly the addressed locker (the decoder); to take something out you reach into the addressed locker and pull its contents onto the counter (the mux). Because looking in one locker does not disturb another, you can read from two lockers and drop something into a third all at once.

N registers, a log2(N)-bit address

With four registers R0-R3 you need a 2-bit address, because two bits count to four (log2(4) = 2). In general N registers need a log2(N)-bit register number: eight registers need a 3-bit address, thirty-two (a typical RISC file) need 5 bits. Each read or write port carries its own address, so a port can name any register independently of the others.

The write port: a decoder plus write-enable

The write port takes a write address WA, a data bus DIN, and a global write-enable WE. Feed WA into a decoder; it raises exactly one select line, select_k, for the addressed register. Each register's own write-enable is that select ANDed with WE, so on a clock edge only the addressed register loads DIN and every other register holds. This is the same select AND write trick that gates a write into one cell of RAM.
WE_k = select_k WE (only the addressed register loads on a write)

The read ports: one mux each, and why more than one

A read port takes a read address and drives that register's value onto a read bus. That is exactly a multiplexer: the register outputs are the data inputs, the read address is the select, and the output is the chosen register's value. One mux, one read port, one register on the bus.
So why give the file two read ports? Because a single operation usually needs two source operands. To compute R3 = R1 + R2 the ALU must see R1 and R2 at the same instant, and one mux can only surface one register at a time. Add a second, independent mux with its own read address and the file can present two different registers on two buses simultaneously. A typical register file is 2-read, 1-write (2R1W): read two operands and write one result every cycle. The ports are independent, so reading does not disturb writing.

A worked cycle: R3 = R1 + R2

Say the four registers hold R0 = 0, R1 = 25, R2 = 17, R3 = 0, and the datapath wants R3 = R1 + R2 in one cycle. Register numbers in binary: R0 = 00, R1 = 01, R2 = 10, R3 = 11.
  1. Set read-port-A address to 01 (R1). Its mux drives 25 onto bus A.
  2. Set read-port-B address to 10 (R2). Its mux drives 17 onto bus B, at the same time.
  3. The ALU adds the two buses: 25 + 17 = 42.
  4. Set the write address to 11 (R3), route the ALU result to DIN, raise WE, and pulse the clock. The decoder raises only select_3, so only R3 loads, becoming 42.
  5. R0, R1, R2 are untouched, and because the read ports are independent of the write port, reading R1 and R2 while writing R3 in the same cycle is perfectly fine.
The full architecture at 4 words by 1 bit (a 2R1W file): a 2-to-4 decoder turns the write address WA1 WA0 into one-hot write selects (each ANDed with WE), and two multiplexers form the two read ports, QA selected by RA1 RA0 and QB by RB1 RB0. Open it in the lab: write a 1 into register 2 (set WA = 10, DIN = 1, raise WE, clock), then read it on port A (RA = 10) while port B reads a different register. Widen each cell to an 8-bit register and it stores a byte per register.
Two things to get right. First, one read port cannot serve two operands: an add needs both sources at once, so you need one mux per read port, not one mux shared between them. Second, read-during-write of the same register needs a defined policy: if a port reads R1 in the very cycle another port writes R1, does it see the old value or the new one? Real files pick one rule (often the old value, since the write lands on the clock edge) and stick to it. Do not assume it just works out.
The register file is the working storage a CPU actually computes on. A RISC processor keeps its operands in a register file (often thirty-two registers, with register 0 hardwired to 0), reads two per instruction, and writes one back, all in a cycle. It sits between our single 8-bit register (one value) and RAM (many values, but one slow single-port access at a time): a register file is small, multi-port, and fast, exactly what the arithmetic core needs feeding it. It is the storage the datapath is built around.
Try it
On the 4-register file, you want to copy R2 into R0 in one cycle: read R2 and write the result into R0. What read address and what write address do you set, and why can the read and the write happen together?

Frequently asked

What is a register file?

A register file is a small array of registers with several independent read and write ports addressed by register number. It lets a datapath read two source operands and write one result in the same clock cycle, and it is the fast working storage a CPU computes on. It is built from registers, a decoder for the write port, and a multiplexer per read port.

What is the difference between a register file and RAM?

Both are addressed banks of storage, but a register file is small, multi-port, and fast while RAM is large and single-port. A register file has a handful of registers (say 32) with two or three ports, so it reads two operands and writes one result every cycle; RAM has thousands or millions of cells but usually only one access per cycle. The register file is where the CPU works; RAM is where the program and its data live.

Why does a register file have two read ports?

Because most operations need two source operands at once. To compute R3 = R1 + R2 the ALU must see R1 and R2 simultaneously, and a single multiplexer can only present one register at a time. A second, independent read mux with its own address lets the file surface two different registers on two buses in the same cycle. The common organization is 2-read, 1-write (2R1W).

How is a register selected for reading or writing?

By its register number. Each port carries an address; N registers need a log2(N)-bit address. For a write, the address feeds a decoder that raises one write-enable, so only the addressed register loads on the clock edge. For a read, the address is the select of a multiplexer that routes the chosen register's value onto the read bus.

Every lesson here builds toward one thing: a working CPU, from the transistor up.

Open the free lab →
Found this useful? Share itShare on X