# Decoders

*One-hot addressing*

A decoder turns an n-bit binary address into one-hot outputs, raising exactly the single output named by the address. It is how an address selects one specific register or memory location.

Group: Processor
URL: https://digiwleea.wleeaf.dev/learn/decoder/

A [multiplexer](https://digiwleea.wleeaf.dev/learn/mux/) chooses one of several inputs using a select code. A **decoder** is the part that turns a binary **address** into those select lines. Give it an n-bit address and it raises exactly one of its `2^n` outputs: the one whose number matches the address. Every other output stays `0`. That pattern, a single `1` among `0`s, is called **one-hot**, and it is how a CPU points at one register or one memory location out of many.

## 2-to-4: two address bits, four lines

Two address bits `A1 A0` count from 0 to 3, so a 2-to-4 decoder has four outputs `Y0`-`Y3`. Output `Yk` is `1` exactly when the address equals `k`. Read the address as a binary number and that output line lights up.

| A1 | A0 | Y0 | Y1 | Y2 | Y3 |
| --- | --- | --- | --- | --- | --- |
| 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 0 | 0 |
| 1 | 0 | 0 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 | 0 | 1 |

_Exactly one output is high in every row, and it marches down the column as the address counts up. Address 2 (A1 A0 = 10) raises Y2 and nothing else._

## Each output is one AND of the address bits

Each output detects one specific combination of the address bits, so each is a single [AND](https://digiwleea.wleeaf.dev/learn/and/) gate. The trick is which form of each bit to feed it. For the bits that should be `0` in that address, feed the **inverted** bit; for the bits that should be `1`, feed the bit straight. The AND is then `1` only for that one address.

1. Make `NOT A0` and `NOT A1` with two [NOT](https://digiwleea.wleeaf.dev/learn/not/) gates, so both the true and inverted form of each address bit is available.
2. `Y0 = NOT A1 AND NOT A0` (address `00`).
3. `Y1 = NOT A1 AND A0` (address `01`).
4. `Y2 = A1 AND NOT A0` (address `10`).
5. `Y3 = A1 AND A0` (address `11`).

> **TIP:** An analogy: a decoder is a **mailroom**. You hand it an address (the binary number), and it lights the lamp over exactly one mailbox, the one with that number, leaving every other lamp dark. A mux does the reverse: it reads the letter out of the lit box. Address in, one box selected.

_Circuit diagram: A 2-to-4 decoder (DEC2): two address inputs A0/A1, four one-hot outputs Y0-Y3. Open it in the lab and count the address up; watch the single high output step across Y0 to Y3._

**Q (Try it):** Set the address `A1 A0 = 11` on the decoder. Which single output goes high, and what do the other three read? Confirm in the lab.

**A:** `A1 A0 = 11` is binary for `3`, so `Y3` goes high and `Y0`, `Y1`, `Y2` all stay `0`. Exactly one output is ever `1` (the one-hot property), and it is the output whose number matches the address. `Y3 = A1 AND A0`, true only when both address bits are `1`.

> **TIP:** The pattern scales straight up. A **3-to-8** decoder has three address bits and eight outputs, each an AND of three bit-forms; an 8-bit address drives a 256-line decoder the same way. The output count doubles with every address bit, which is exactly why an n-bit address can name `2^n` things.

## The decoder as a universal function generator

Look again at the truth table: output `Yk` is `1` for exactly one input combination, the one numbered `k`, and `0` for every other. That is the exact definition of a **minterm** (see [canonical forms](https://digiwleea.wleeaf.dev/learn/canonical-forms/)). So an n-to-`2^n` decoder does more than address memory: it hands you **all `2^n` minterms of n variables at once**, one on each output line. Pair that with a fact from Boolean algebra, that any function equals the OR of the minterms on its `1`-rows (its **canonical sum of products**), and the decoder turns into a build-anything box. Feed your n variables into the address, then OR together exactly the output lines that sit on your function's `1`-rows. No gate algebra, no [Karnaugh map](https://digiwleea.wleeaf.dev/learn/karnaugh/): read the `1`-rows straight off the truth table and wire those lines into one OR gate.

Here is the classic demonstration: a **full adder** with no adder logic at all, just a 3-to-8 decoder and two OR gates. A full adder takes three one-bit inputs, `A`, `B`, and a carry-in `Cin`, and produces a `SUM` bit and a carry-out `COUT`. Wire `A`, `B`, `Cin` into the decoder's three address bits (`A` most significant, `Cin` least), so line `Yk` lights up for the row numbered `k`.

| A | B | Cin | SUM | COUT |
| --- | --- | --- | --- | --- |
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |

_Full adder truth table, rows numbered 0 to 7 from the top. SUM is 1 on rows 1, 2, 4, 7; COUT is 1 on rows 3, 5, 6, 7. Each row number is the one decoder line that goes high for it._

1. Feed `A`, `B`, `Cin` into the 3-to-8 decoder's address inputs. Now line `Yk` is high on exactly row `k`, and the decoder already supplies both the true and inverted form of every input internally, so you add no inverters of your own.
2. `SUM` is `1` on rows `1, 2, 4, 7`, so `SUM = Y1 OR Y2 OR Y4 OR Y7`: a single OR gate over those four lines.
3. `COUT` is `1` on rows `3, 5, 6, 7`, so `COUT = Y3 OR Y5 OR Y6 OR Y7`: one more OR gate over those four lines.
4. That is the whole adder. The decoder made every minterm; the two OR gates just collect the ones each output needs.

> **WARN:** Two easy slips. First, OR the lines for the `1`-**rows**, never the `0`-rows: wiring `SUM`'s four `0`-rows (`0, 3, 5, 6`) into an OR gives you `NOT SUM`, the complement, not `SUM`. Second, this recipe assumes an **active-high** decoder, where the chosen line goes `1` and the rest sit at `0` (the convention this lesson uses). Many real decoder chips are **active-low**: the chosen line drops to `0` while the others sit at `1`. With those you collect the same `1`-row lines through a **NAND** instead of an OR (De Morgan's law makes it equivalent). Always match the collecting gate to your decoder's output polarity.

> **KEY:** This is the decoder's version of the [multiplexer-as-universal](https://digiwleea.wleeaf.dev/learn/mux-universal/) trick: both drop any truth table straight into hardware with no minimization. The decoder route adds a neat symmetry, feed the SAME `1`-row lines into a **NOR** gate instead of an OR and you get the function's complement `f'` for free (NOR is just OR then NOT). And one decoder feeds many OR gates at once, so a single 3-to-8 decoder generates the full adder's `SUM` and `COUT` together. Generalize that sharing and you have a [ROM or PLA](https://digiwleea.wleeaf.dev/learn/rom-pla/): a decoder makes every minterm, and a programmable OR plane picks which minterms each output collects.

**Q (Try it):** You want a 3-input **majority** function `M(A, B, Cin)` that is `1` whenever two or more of its inputs are `1`. Using a 3-to-8 decoder fed by `A B Cin`, which output lines do you OR together? (Hint: compare your answer to one of the two outputs you just built.)

**A:** Majority is `1` on exactly the rows with two or three `1`s: `011` (row 3), `101` (row 5), `110` (row 6), and `111` (row 7). So `M = Y3 OR Y5 OR Y6 OR Y7`, the very same OR gate as the full adder's `COUT`. Carry-out simply IS the majority of `A`, `B`, `Cin`, which is why an adder carries exactly when at least two of its three inputs are `1`.

> **KEY:** Hold this thought for [memory](https://digiwleea.wleeaf.dev/learn/ram/): a decoder takes the address bits and lights up the one cell you mean, while a [multiplexer](https://digiwleea.wleeaf.dev/learn/mux/) (or a tri-state bus) reads that cell's value back out. Address in, one-hot select, data out: a decoder plus a mux is the skeleton of RAM and of a register file. First, though, we widen our storage from one bit to a whole byte: the [8-bit register](https://digiwleea.wleeaf.dev/learn/register8/).

### FAQ

**Q:** What is a decoder?

**A:** A **decoder** takes an n-bit binary address and activates exactly **one** of its `2^n` output lines: the one whose number matches the address. Every other output stays `0`. That pattern, a single `1` among `0`s, is called **one-hot**, and it is how an address points at one register or one memory cell out of many.

**Q:** What is the difference between a decoder and a multiplexer?

**A:** They are mirror images. A **decoder** takes an address and raises one of many output lines (address in, one-hot select out). A [multiplexer](https://digiwleea.wleeaf.dev/learn/mux/) takes the same kind of select code but routes one of many *inputs* down to a single output (many in, one out). A decoder lights the right mailbox; a mux reads the letter out of the lit box.

**Q:** How is each decoder output built?

**A:** Each output is a single [AND](https://digiwleea.wleeaf.dev/learn/and/) gate over the address bits. For the bits that should be `0` in that address you feed the **inverted** bit (via a [NOT](https://digiwleea.wleeaf.dev/learn/not/) gate), and for the bits that should be `1` you feed the bit straight, so the AND is `1` only for that one address. For example `Y2 = A1 AND NOT A0` (address `10`).

**Q:** How many outputs does an n-bit decoder have?

**A:** It has `2^n` outputs: the count doubles with every address bit. Two address bits give a 2-to-4 decoder, three give a 3-to-8 decoder, and an 8-bit address drives a 256-line decoder. That doubling is exactly why an n-bit address can name `2^n` things.

**Q:** Can a decoder implement any Boolean function?

**A:** Yes. An n-to-`2^n` decoder outputs all `2^n` **minterms** of its n inputs, one per line, and any Boolean function is the OR of the minterms on its `1`-rows (its canonical sum of products). So feed your variables into the address and OR together exactly the output lines for the truth table's `1`-rows: one OR gate per output realizes the function with no algebra. Because one decoder can drive many OR gates, it can generate several functions of the same inputs at once (for example a full adder's `SUM` and `COUT`), which is the idea behind a ROM or PLA.
