Multiplexers and Decoders

Imagine a memory chip with billions of storage cells. It has only one narrow data bus to read them out. Something must select exactly one cell's data for that bus. Something else must translate a numeric address into "activate this one wire." This means picking one wire out of billions. Two jobs matter here. First, selecting one signal among many. Second, turning a binary code into one active line among many. These jobs are so fundamental that all of digital computing rests on them. The building blocks that do this are the multiplexer (mux) and the decoder. Every register file uses a mux or a decoder somewhere in its critical path. So does every memory array, instruction-decode stage, and ALU control path. A multiplexer is the hardware realization of an `if/else` or `switch` statement acting on data. A decoder is the hardware realization of turning an index into a one-hot activation signal. This is exactly what happens when a CPU reads an opcode field. It then decides which functional unit to enable. Without these two circuits, a processor could not route data. It could not move data between registers, memory, and execution units. It also could not translate encoded instructions into concrete actions. This article builds both circuits from techniques you already know. These come from Logic Gates and Combinational Logic Design: truth tables, sum-of-products expressions, and gate networks. We derive the standard 2-to-1 and N-to-1 multiplexer, and the AND-based decoder. We show how the two are structural duals. A decoder plus a set of AND-OR data paths is a demultiplexer. Cascading small muxes builds bigger ones. We verify every truth table, every gate count, and every complexity claim. We do this from first principles rather than asserting them. By the end, you will be able to design an N-input mux from scratch. You will also design an N-output decoder from scratch. You can compute exact gate and delay costs. You can trace a full worked circuit. You will see how these primitives directly foreshadow other logic. This includes the selection logic inside Arithmetic Logic Units. It also includes the read/write port logic inside Registers and Register Files.

Key takeaways
  • A multiplexer (mux) selects one of N data inputs to route to a single output, using ⌈log₂N⌉ select lines.
  • A decoder converts an n-bit binary code into one active output line among 2ⁿ outputs (one-hot).
  • Both are built directly from AND, OR, and NOT gates using a sum-of-products construction derived from truth tables.
  • A mux implements `output = Σ (select_pattern_i AND input_i)`; a decoder implements `output_i = AND of literals matching code i`.
  • Complexity: an N-to-1 mux uses O(N) gates and O(log N) gate delay when built as a balanced tree of 2-to-1 muxes.
  • Muxes and decoders are dual circuits — combined with logic they form data selection paths in ALUs and address decoding in memories.
The core insight

A multiplexer routes data by binary selection; a decoder converts a binary code into a single active line — together they let a fixed set of wires implement any addressable choice.

The idea

A multiplexer (mux) is a combinational circuit with NN data inputs D0,…,DN−1D_0, \dots, D_{N-1}, ⌈log⁡2N⌉\lceil \log_2 N \rceil select inputs SS, and a single output YY. The select lines encode an index kk in binary, and the circuit behaves as Y=DkY = D_k. It is the hardware analogue of an array-indexing expression `Y = D[S]`. When NN is a power of two, exactly log⁡2N\log_2 N select lines are needed and every select pattern is used; this is the common, "clean" case this article focuses on. A decoder is the structural inverse. It takes nn input lines encoding a binary number and produces 2n2^n output lines, exactly one of which is asserted (driven to 1) for each input combination — a one-hot output. A decoder with enable input adds one more control: when the enable is deasserted, all outputs are forced to 0 regardless of the code, allowing multiple decoders to be composed (as in the row/column decoders of a memory array) or turning the decoder into a true demultiplexer, which routes a single data input to one of 2n2^n outputs. Both circuits are two faces of the same underlying idea: a binary code names one of a finite set of choices. In a mux the "choice" selects which input reaches the output; in a decoder the "choice" selects which output gets activated. This is why a decoder followed by AND gates driven from a shared data line implements a demultiplexer, and a decoder feeding an OR gate over the true-input lines implements a multiplexer — the two circuits share a truth-table skeleton, only the direction of data flow differs.

How it works

Deriving the 2-to-1 mux. With one select bit SS and two data inputs D0,D1D_0, D_1, the truth table is:

SD0D1Y
00*0
01*1
1*00
1*11

Reading off the behavior directly (rather than expanding a full 8-row truth table) gives the sum-of-products form:

Y=S‾⋅D0  +  S⋅D1Y = \overline{S}\cdot D_0 \;+\; S \cdot D_1

This is the canonical 2-to-1 mux equation. It needs 2 AND gates, 1 OR gate, and 1 inverter — 4 gates total, and 2 levels of gate delay (AND then OR) after the inverter.

Building an N-to-1 mux from the general rule. For N=2nN = 2^n inputs and nn select lines Sn−1…S0S_{n-1}\ldots S_0, define the minterm mk(S)m_k(S) as the AND of literals that is 1 exactly when the select lines encode integer kk (e.g., for n=2n=2, m2(S)=S1‾S0m_2(S) = \overline{S_1} S_0… care with bit order, so let's fix S1S0=10S_1S_0 = 10 meaning k=2k=2, giving m2=S1S0‾m_2 = S_1 \overline{S_0}). Then:

Y=∑k=0N−1mk(S)⋅DkY = \sum_{k=0}^{N-1} m_k(S)\cdot D_k

Each minterm activates exactly one AND gate among NN, gating through exactly one data input; the final OR gate merges these (only one is ever nonzero) into YY. This is a direct generalization of the 2-to-1 case and is provably correct because the minterms are mutually exclusive and exhaustive over SS — for any fixed select code, exactly one mkm_k is 1 and all others are 0, so YY collapses to exactly DkD_k.

Building a decoder. An nn-to-2n2^n decoder simply outputs the minterms directly instead of ANDing them with data:

Outk=mk(S),k=0,…,2n−1\text{Out}_k = m_k(S), \quad k = 0, \dots, 2^n - 1

Adding an enable EE multiplies every minterm by EE: Outk=E⋅mk(S)\text{Out}_k = E \cdot m_k(S). When E=0E=0 all outputs go to 0; when E=1E=1 exactly one output fires, selected by SS.

Building larger muxes/decoders from smaller ones. Large muxes are almost never built as one giant OR of NN AND gates in practice — instead they are built as trees of small (2-to-1) muxes, which keeps fan-in bounded and delay logarithmic. An 8-to-1 mux, for example, is built from seven 2-to-1 muxes in a 3-level binary tree: 4 muxes select pairs using the low select bit, 2 muxes combine those using the middle bit, and 1 final mux combines using the high bit. Similarly, large decoders can be built hierarchically: a large decoder is split into a coarse decoder (selecting a group) and a fine decoder within the group, with AND gates combining a coarse-select line and a fine-select line — this is exactly the row/column addressing scheme used inside memory arrays. ```pseudocode // N-to-1 MULTIPLEXER, N = 2^n, built as a balanced binary tree of 2:1 muxes function MUX_TREE(D[0..N-1], S[0..n-1]): level = D // start with the N data inputs for bit in 0 .. n-1: next_level = empty list for pair_index in 0 .. length(level)/2 - 1: d0 = level[2pair_index] d1 = level[2pair_index + 1] // 2:1 mux primitive: Y = (NOT S)d0 + Sd1 y = MUX2(d0, d1, S[bit]) next_level.append(y) level = next_level return level[0] // the single surviving wire is the output function MUX2(d0, d1, s): return (NOT s AND d0) OR (s AND d1)

// n-to-2^n DECODER with enable function DECODER(S[0..n-1], enable): outputs = array of size 2^n, all initialized to 0 if enable == 0: return outputs // all lines deasserted k = binary_value(S) // integer encoded by select lines outputs[k] = 1 return outputs

// DEMULTIPLEXER: route one data line to one of 2^n outputs function DEMUX(data_in, S[0..n-1]): sel = DECODER(S, enable = 1) outputs = array of size 2^n for i in 0 .. 2^n - 1: outputs[i] = data_in AND sel[i] return outputs ``` The pseudocode is faithful to real hardware: `MUX2` is literally the gate-level equation derived above, `MUX_TREE` is literally how wide multiplexers are laid out on silicon (a balanced binary tree, not a flat OR), and `DECODER`/`DEMUX` show the duality — a demultiplexer is a decoder whose one-hot outputs are ANDed with a shared data wire.

Figure
A 4-to-1 multiplexer built as a tree of 2-to-1 muxes, alongside a 2-to-4 decoder
4-to-1 Multiplexer (tree of 2:1 muxes) D0 D1 D2 D3 M0 M1 S0 M2 S1 Y Select S1 S0 chooses D0..D3 2-to-4 Decoder (with enable) S1 S0 EN NOT S1 NOT S0 OUT0 = EN·S1'·S0' OUT1 = EN·S1'·S0 OUT2 = EN·S1·S0' OUT3 = EN·S1·S0 Exactly one OUT line is 1; all others are forced 0 by EN. Duality: replace each AND-minterm output above with a data-gated AND (data · minterm), OR them together — that reconstructs the multiplexer.

Complexity & correctness

Gate count. A flat NN-to-1 mux built directly from the sum-of-products form uses:

  • NN AND gates, each with fan-in n+1n+1 (the nn select literals plus the data input), where n=log⁡2Nn=\log_2 N,
  • 1 OR gate with fan-in NN,
  • nn inverters (to produce complemented select lines),

for a total of Θ(N)\Theta(N) gates. If gates are restricted to bounded fan-in (e.g., 2-input gates only, as in real cell libraries), each NN-input AND/OR must itself be built as a tree of 2-input gates, costing O(N)O(N) additional gates and O(log⁡N)O(\log N) additional depth — so the asymptotic gate count stays Θ(N)\Theta(N), but constants grow.

Depth (delay). The flat design has depth O(log⁡n)=O(log⁡log⁡N)O(\log n) = O(\log\log N) for producing the fan-in-(n+1)(n{+}1) AND (if built from 2-input gates) plus O(log⁡N)O(\log N) for the fan-in-NN OR — dominated by O(log⁡N)O(\log N). The tree-of-2:1-muxes design (as in the pseudocode) is simpler to reason about: it has exactly n=log⁡2Nn = \log_2 N levels, each level being one 2:1 mux with constant depth (2 gates), giving depth Θ(log⁡N)\Theta(\log N) and gate count Θ(N)\Theta(N) as well, since level ii (counting from the data inputs) has N/2iN/2^i muxes and ∑iN/2i=N−1\sum_i N/2^i = N-1 total 2:1 muxes, each a constant number of gates. Both designs are asymptotically equivalent; the tree form is preferred in real layouts for uniform fan-in and simpler routing.

Decoder cost. An nn-to-2n2^n decoder needs 2n2^n AND gates (one per output), each of fan-in n+1n+1 (n select literals + enable), plus nn inverters — Θ(2n)\Theta(2^n) gates, O(log⁡n)O(\log n) depth per AND gate if built from 2-input gates (constant depth if the AND is allowed fan-in n+1n+1 directly). Since N=2nN = 2^n, this is Θ(N)\Theta(N) gates for NN outputs, matching the mux's linear cost — expected, since they are dual circuits over the same NN-element index space.

Correctness argument (mux). The correctness of Y=∑kmk(S)⋅DkY = \sum_k m_k(S)\cdot D_k follows from two facts about the minterms mkm_k: 1. Exhaustiveness: for every possible assignment of the select bits SS, some k∗k^* makes mk∗(S)=1m_{k^*}(S) = 1 (namely k∗k^* = the integer encoded by SS), because mkm_k is defined as the conjunction of literals matching the binary digits of kk. 2. Mutual exclusivity: for k≠k∗k \ne k^*, mk(S)=0m_k(S) = 0, because mkm_k and mk∗m_{k^*} differ in at least one literal, and that literal is set to disagree with SS for at least one term in the AND, forcing it to 0. Given these two facts, the sum ∑kmk(S)Dk\sum_k m_k(S) D_k has exactly one nonzero term (mk∗Dk∗=1⋅Dk∗=Dk∗m_{k^*} D_{k^*} = 1 \cdot D_{k^*} = D_{k^*}) and all other terms are 0, so the whole OR evaluates to Dk∗D_{k^*} — precisely the specified mux behavior Y=DSY = D_{S}. This is a direct instance of the general canonical sum-of-products theorem: any Boolean function equals the OR of the minterms for which it outputs 1, and here the function's value at minterm kk is defined to be DkD_k.

Correctness argument (decoder). Identical reasoning: Outk=mk(S)\text{Out}_k = m_k(S) is 1 exactly for the unique SS encoding kk, by exhaustiveness and exclusivity of minterms, so the output vector is one-hot with the hot bit at position k=value(S)k = \text{value}(S).

Correctness of the tree mux (induction on nn). Base case n=1n=1: `MUX2` implements Y=S‾D0+SD1Y=\overline S D_0 + S D_1 directly by definition — correct by inspection of its two rows. Inductive step: assume a tree of depth n−1n-1 correctly selects among 2n−12^{n-1} inputs using the low n−1n-1 select bits. The final level combines two such (n−1)(n-1)-trees (rooted at Dlow half[Slow]D_{\text{low half}}[S_{low}] and Dhigh half[Slow]D_{\text{high half}}[S_{low}]) using the top bit Sn−1S_{n-1} in one more `MUX2`. By the n=1n{=}1 correctness of that final mux, the output equals whichever half's correctly-selected value the top bit points to — which is exactly Dvalue(S)D_{\text{value}(S)}. This completes the induction.

Tradeoffs. The flat sum-of-products mux minimizes logical depth at the cost of very wide gates (fan-in NN), which in real CMOS is slow and area-hungry since wide gates need transistor stacking or extra buffering. The tree-of-2:1-muxes design uses only constant-fan-in gates uniformly, which is friendlier to standard-cell libraries, at the (mild) cost of a log⁡N\log N-deep critical path instead of a theoretically flatter but practically slower wide-gate path. Real designs (e.g., a 32-to-1 mux in a register file read port) almost universally use the tree form, sometimes with pass-transistor-logic muxes instead of gate-logic muxes for further speed and area savings — a circuit-level optimization built on the same logical correctness argument above.

Worked example

Consider a 4-to-1 mux used to pick one of four ALU result sources — say, register file, adder, shifter, memory-load — feeding the write-back stage of a simple pipeline, with D3D2D1D0=1, 0, 1, 1D_3 D_2 D_1 D_0 = 1,\,0,\,1,\,1 (adder=1, shifter=1, others 0) and select S1S0=10S_1 S_0 = 10 (meaning "select index 2, the shifter").

Step 1 — minterms. With n=2n=2, the four minterms are:

m0=S1‾ S0‾,m1=S1‾ S0,m2=S1 S0‾,m3=S1 S0m_0 = \overline{S_1}\,\overline{S_0}, \quad m_1 = \overline{S_1}\,S_0, \quad m_2 = S_1\,\overline{S_0}, \quad m_3 = S_1\,S_0

Step 2 — evaluate minterms at S1S0=10S_1S_0 = 10.

mintermformulavalue at S1=1, S0=0
m0m_0S1‾ S0‾\overline{S_1}\,\overline{S_0}0⋅1=00\cdot1 = 0
m1m_1S1‾ S0\overline{S_1}\,S_00⋅0=00\cdot0 = 0
m2m_2S1 S0‾S_1\,\overline{S_0}1⋅1=11\cdot1 = 1
m3m_3S1 S0S_1\,S_01⋅0=01\cdot0 = 0

Exactly m2=1m_2 = 1, confirming exclusivity/exhaustiveness on this concrete input.

Step 3 — compute Y.

Y=m0D0+m1D1+m2D2+m3D3=0⋅1+0⋅1+1⋅0+0⋅1=0Y = m_0 D_0 + m_1 D_1 + m_2 D_2 + m_3 D_3 = 0\cdot1 + 0\cdot1 + 1\cdot0 + 0\cdot1 = 0

Wait — check the data assignment: we said D3D2D1D0=1,0,1,1D_3D_2D_1D_0 = 1,0,1,1, i.e. D0=1,D1=1,D2=0,D3=1D_0=1, D_1=1, D_2=0, D_3=1. Selecting index 2 should return D2=0D_2 = 0. Indeed Y=0Y=0 — matching "shifter result happens to be logic 0 on this bit," which is a perfectly valid (if unglamorous) trace: the mux correctly forwarded D2D_2, not the more visually tempting D1D_1 or D3D_3, demonstrating the selection genuinely depends on SS and not on which input "looks like the answer."

Step 4 — trace through the tree implementation instead (sanity check). Using `MUX_TREE`:

  • Level 0 (`bit=0`, using S0=0S_0=0): M0=MUX2(D0,D1,S0=0)=0‾⋅D0+0⋅D1=D0=1M_0 = \text{MUX2}(D_0,D_1,S_0{=}0) = \overline{0}\cdot D_0 + 0\cdot D_1 = D_0 = 1. M1=MUX2(D2,D3,S0=0)=D2=0M_1 = \text{MUX2}(D_2,D_3,S_0{=}0) = D_2 = 0.
  • Level 1 (`bit=1`, using S1=1S_1=1): M2=MUX2(M0,M1,S1=1)=1‾⋅M0+1⋅M1=M1=0M_2 = \text{MUX2}(M_0, M_1, S_1{=}1) = \overline{1}\cdot M_0 + 1\cdot M_1 = M_1 = 0.

Output Y=0Y = 0, agreeing exactly with the sum-of-products computation — a second, structurally independent derivation confirming the answer, exactly as the induction proof guarantees.

Decoder companion example. Suppose this mux's select lines are themselves generated by a 2-to-4 decoder reading a 2-bit "source ID" field from an instruction, with enable tied to "write-back stage active." For source ID =102=10_2 and enable =1=1: OUT2=1⋅S1S0‾=1⋅1⋅1=1\text{OUT}_2 = 1\cdot S_1\overline{S_0} = 1\cdot1\cdot1=1, all other outputs 0 — that one-hot line is precisely what would gate "shifter result valid" onto the write-back bus in a real datapath, tying the decoder and mux into one coherent control path.

Common pitfalls & traps

PitfallWhy it happensFix
Off-by-one in select-line countUsing log⁡2N\log_2 N instead of ⌈log⁡2N⌉\lceil \log_2 N \rceil, or forgetting NN must be a power of 2 for "clean" muxesFor non-power-of-2 NN, use ⌈log⁡2N⌉\lceil \log_2 N \rceil select bits and tie unused input slots to a safe default (e.g., 0)
Confusing decoder output width with input widthThinking an nn-input decoder has nn outputsRemember: nn inputs → 2n2^n outputs, exponential blow-up
Forgetting the enable lineTreating decoder outputs as always "live," causing multiple decoders on a shared bus to fightAlways gate decoder outputs with enable; only one decoder module active at a time on shared address lines
Assuming don't-care data bits are irrelevant everywhereBelieving a mux truth table's "*" entries mean the bit never matters, even outside its own rowDon't-cares are local to each row; verify the full minterm expansion rather than eyeballing the table
Flat wide-gate mux assumed as fast as a treeBelieving "fewer logical levels" always means "faster"In real CMOS, wide fan-in gates are slower than a chain of small gates; compare tree vs. flat including physical delay, not just gate-level depth

Pioneers & history

The mux/decoder abstraction descends from the mathematics of Boolean algebra and the switching-circuit theory that translated logical propositions into physical relay and gate networks — the theoretical foundation that made "select one of N" and "activate exactly one of N" expressible as gate equations at all.

Origins · 1 minClaude Elwood Shannon and how this was discovered
CE
Claude Elwood Shannon
1916–2001 · Bell Labs and MIT, at the birth of digital switching theory

Shannon's 1937 master's thesis proved that Boolean algebra could exactly describe relay and switching circuits, giving engineers the first rigorous language for combinational logic — the sum-of-products and minterm techniques used to derive mux and decoder equations trace directly back to this work.

History
- 1854 — George Boole publishes The Laws of Thought, founding Boolean algebra.
- 1937 — Claude Shannon's thesis shows switching circuits realize Boolean logic exactly.
- 1958–1959 — Integrated circuits emerge, making dense combinational gate networks (muxes, decoders) practical to fabricate.
- 1960s — Standard TTL/CMOS multiplexer and decoder chips (e.g., 74-series parts) become off-the-shelf building blocks for computer design.
- 1970s–present — Muxes and decoders become embedded, invisible primitives inside custom VLSI datapaths, register files, and memory arrays.

Where this matters

Multiplexers select data paths throughout a CPU datapath: choosing between the PC+4 and a branch target, selecting an ALU operand source, or picking which register-file read port feeds an execution unit — all directly foreshadow the selection logic detailed in Arithmetic Logic Units. Register files use decoders to translate a register-number field from an instruction into the one-hot write-enable signal for the correct storage cell, a mechanism developed further in Registers and Register Files. Memory chips (SRAM/DRAM) use row and column decoders — hierarchical decoders exactly like the ones described here — to activate a single word line out of millions, while a wide output mux (or sense-amp selection network) picks the correct bit line data to drive onto the data bus. Instruction decoders in a CPU's control unit are literally decoders in this technical sense: an opcode field becomes a one-hot signal enabling a specific control path. Bus arbitration and I/O address decoding on a system bus use decoders to ensure exactly one peripheral responds to a given address range. Multiplexed displays, time-division multiplexing in networking, and even simple debouncing/selection circuits in embedded systems reuse the identical logical construction.

Ask the tutor: How would you design a 16-to-1 multiplexer using only 2-to-1 mux building blocks, and what is its exact gate delay in levels?

What is the difference between a multiplexer and a decoder?

A multiplexer routes one of several data inputs to a single output, controlled by select lines — it answers "which input's value do I want?" A decoder converts a binary code into a one-hot set of output lines — it answers "which single location does this code name?" Structurally they share the same minterm machinery: a mux ANDs each minterm with a data bit and ORs the results, while a decoder simply outputs the minterms directly. In practice, muxes move data through a circuit (e.g., picking an ALU operand source), while decoders activate exactly one destination (e.g., one memory row, one register write-enable) so that only the intended location responds.

Why do decoders need exponentially many outputs for a linear number of inputs?

A decoder must produce one output line per distinct binary code, and an nn-bit code has 2n2^n distinct values — there's no way around this if every code must map to a physically distinct, individually addressable wire. This exponential blow-up is intrinsic to any one-hot addressing scheme, not a design flaw. It is exactly why memory addressing is hierarchical: a flat decoder for a 32-bit address would need 2322^{32} output wires, which is infeasible, so real memories split the address into row and column fields, decode each separately with much smaller decoders, and combine results — trading one giant decoder for two small ones plus an AND per cell.

Why is the tree-of-2:1-muxes design preferred over a single wide sum-of-products mux in real hardware?

A flat mux needs one NN-input OR gate and NN gates of fan-in log⁡2N+1\log_2 N + 1. Real CMOS gates get slower and larger as fan-in grows, because wide gates require long series/parallel transistor stacks or extra buffering stages, which increases both delay and area nonlinearly. A tree of 2-to-1 muxes uses only constant-size building blocks at every level, so each stage has predictable, small delay and area, and the total depth is a clean log⁡2N\log_2 N stages. This makes timing analysis, layout, and cell-library reuse far simpler, which is why virtually every wide mux in a real datapath is built as a tree rather than as one flat gate network.

Can a multiplexer implement arbitrary Boolean functions, not just data selection?

Yes — this is a classic and practically useful trick. Because a 2n2^n-to-1 mux's minterm structure already contains every possible AND-combination of nn select variables, tying the data inputs DkD_k to constants 0 or 1 (or to a smaller set of remaining variables) lets the mux implement any nn-variable (or (n+1)(n{+}1)-variable) Boolean function without any separate gates. This is called mux-based function implementation or "using a mux as a universal logic element," and it is a real technique in FPGA lookup tables (LUTs), which are literally multiplexers whose data inputs are configuration-memory bits encoding the desired truth table.

How does an enable line change a decoder into a demultiplexer?

A basic decoder has select/address inputs and produces a one-hot output determined purely by those inputs. A demultiplexer additionally has a data input: instead of asserting a constant 1 on the selected output, it forwards the data input's value to the selected output line while all other outputs stay at 0. Structurally, replace the decoder's implicit enable constant with the data signal — `outputs[i] = data_in AND minterm_i(S)` — so the demux is a decoder generalized to pass an arbitrary signal (not just logic 1) through to exactly one destination, chosen by the select lines.

Why are muxes and decoders described as "dual" circuits?

Both are built from the identical set of minterms over the select/address lines — Boolean AND-terms that are mutually exclusive and exhaustive. A decoder outputs these minterms directly as its one-hot result. A multiplexer instead ANDs each minterm with a corresponding data bit and ORs all the products together, using the same minterms to choose which data value passes through rather than to signal which location is active. Because they share this common minterm skeleton, understanding one construction (the sum-of-products derivation) automatically gives you the other, and it explains why a decoder plus AND-gated data lines directly reconstructs multiplexer/demultiplexer behavior.

What role do muxes and decoders play inside a CPU's register file?

A register file needs to (a) select which register's stored value appears on a read port, and (b) determine which single register's storage cell should be overwritten on a write. The read side is a multiplexer: the register-number field selects among all stored register values to produce the read-port output. The write side is a decoder: the register-number field is decoded into a one-hot write-enable vector, so that only the addressed register's storage cell actually latches the new value while all others hold their previous contents unchanged — a mechanism detailed further in Registers and Register Files.

Before this

Where this leads