Registers & Shift Registers
A single D flip-flop stores one bit. Nearly everything a real digital system needs to remember — a byte, a 32-bit instruction, an address — is wider than that. This page covers how flip-flops combine into multi-bit storage, and the specific sub-family, shift registers, that move data sideways as well as store it.
Parallel registers
A register is simply a bank of D flip-flops sharing a common clock, one flip-flop per bit, all updating together:
On every active clock edge, the entire D[3:0] value is captured into Q[3:0] simultaneously — this is the basic mechanism behind every pipeline stage, every CPU register file entry, and every intermediate value held between combinational stages in a synchronous design. Two refinements are almost universal in practice:
- Enable: a register that updates on every clock edge is rarely useful on its own — real registers add an
ENinput that, when low, makes the register hold its current value regardless ofD, by feedingD_effective = EN ? D : Qback into each flip-flop (a MUX in front of each D input, choosing between new data and the flip-flop's own current output). - Reset: an initialization mechanism that forces the register to a known value (usually all-0) independent of
DandCLK— either synchronous (takes effect only on the next clock edge, keeping all state changes tied to the clock) or asynchronous (takes effect immediately, useful for guaranteeing a known power-up state but riskier if it can assert briefly at an inconvenient moment relative to the clock).
Shift registers
A shift register connects flip-flops in a chain instead of in parallel — each flip-flop's Q output feeds directly into the next flip-flop's D input. Every clock edge, data shifts one position down the chain rather than each bit staying put:
Shift registers are classified by how data gets in and out, which gives four standard configurations:
- SISO (Serial-In, Serial-Out) — data enters one bit per clock at
SerialInand exits one bit per clock atSerialOut, exactly the chain above. Used as a pure delay line — an n-stage SISO register delays a serial stream by exactly n clock cycles. - SIPO (Serial-In, Parallel-Out) — same serial input, but every flip-flop's
Qis also broken out as an output, so after n clock cycles an n-bit value that arrived one bit at a time is now available all at once, in parallel. This is the standard serial-to-parallel converter — exactly what a UART receiver uses to reassemble a byte from a serial bit stream. - PISO (Parallel-In, Serial-Out) — the reverse: an n-bit value is loaded into all flip-flops simultaneously (via a parallel-load path that bypasses the normal shift-input MUXes, using the same enable/MUX trick as the parallel register above), then shifted out one bit per clock. This is the standard parallel-to-serial converter — how a UART transmitter turns a byte into a serial bit stream, one bit per clock, for transmission.
- PIPO (Parallel-In, Parallel-Out) — data loads in parallel and reads out in parallel; the "shift register" here doesn't actually need to shift for its primary function, but the same flip-flop chain can typically still shift as a secondary mode. This is functionally just the parallel register from the section above, framed as a degenerate case of the shift-register family.
The universal shift register
A universal shift register combines all four modes into a single reconfigurable block, selecting its behavior with a mode-select input feeding a MUX in front of every flip-flop's D input:
Mode | Operation
00 | Hold (no change)
01 | Shift right (toward SerialOut)
10 | Shift left (toward SerialIn, reversed direction)
11 | Parallel load
Each flip-flop's actual D input is a 4-to-1 MUX output, selecting between its own current Q (hold), the previous stage's Q (shift right), the next stage's Q (shift left), or the corresponding parallel-input bit (load) — directly reusing the MUX-as-selector idea from Multiplexers, Decoders & Comparators, just with flip-flop outputs and a parallel data bus as the MUX's data inputs instead of plain combinational signals. The 74194 family of ICs is the classic real-world example of exactly this circuit, and the same select-per-flip-flop structure is the template for any register file or pipeline stage in a real processor that needs to conditionally hold, shift, or reload its contents based on control logic elsewhere in the design.
What's next
Registers hold and move data, but they don't produce new values on their own — the next page covers counters, which use flip-flops together with feedback logic to generate a repeating sequence of values entirely on their own, driven by nothing but the clock.