# The priority encoder

*Highest request wins*

A priority encoder is a combinational circuit that outputs the binary index of the highest-numbered active input, resolving the case where several request lines are high at once, and adds a 'valid' output that is 1 whenever any input is active.

Group: Processor
URL: https://digiwleea.wleeaf.dev/learn/priority-encoder/

The plain [encoder](https://digiwleea.wleeaf.dev/learn/encoder-demux/) has one strict rule: exactly one input may be high (a [one-hot](https://digiwleea.wleeaf.dev/learn/decoder/) input). Feed it a single active line and it reads back that line's number. But raise two lines at once and it breaks. For the 4-to-2 encoder `A1 = I2 OR I3`, `A0 = I1 OR I3`, raising `I1` and `I2` together gives `A1 A0 = 11`, which is the code for input `3`, an input that is not even active. The [OR](https://digiwleea.wleeaf.dev/learn/or/) gates just blended two addresses into a third, meaningless one.

Real inputs are rarely so polite. Several devices can request attention in the same instant, several buttons can be down together. A **priority encoder** solves the ambiguity by assigning each input a rank: when more than one is high, it reports the **highest-numbered** one and ignores the rest. It also answers a question the plain encoder cannot: is *anything* active at all?

## The priority rule

Number the inputs `I0` (lowest priority) up to `I3` (highest). The output address `A1 A0` names the highest-numbered input that is currently `1`. If `I3` is high, the answer is `3` no matter what `I2`, `I1`, `I0` are doing; if `I3` is `0` but `I2` is high, the answer is `2`; and so on down. A lower input matters only when every input above it is `0`.

That is exactly the `don't care` idea from a [K-map](https://digiwleea.wleeaf.dev/learn/karnaugh/): once a higher input is known to be `1`, the lower inputs stop affecting the answer, so we can leave them unspecified. Writing the table that way collapses all sixteen input combinations into five priority rows.

| I3 | I2 | I1 | I0 | A1 | A0 | V |
| --- | --- | --- | --- | --- | --- | --- |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 0 | 1 | 0 | 0 | 1 |
| 0 | 0 | 1 | - | 0 | 1 | 1 |
| 0 | 1 | - | - | 1 | 0 | 1 |
| 1 | - | - | - | 1 | 1 | 1 |

_The priority table, where - means don't care (that input does not affect the row's answer). Read it top to bottom: the first row whose fixed 1 matches wins. The last row (I3 = 1) covers eight input combinations at once, because once I3 is high nothing below it matters. V (valid) is 0 only when every input is 0._

## Reading the equations off the table

Group the rows the way a [K-map](https://digiwleea.wleeaf.dev/learn/karnaugh/) would and each output falls out as a small expression. The high address bit `A1` is `1` for exactly the two top-priority cases (input `3` or input `2`), so it is a plain [OR](https://digiwleea.wleeaf.dev/learn/or/). The low bit `A0` is `1` for input `3` and for input `1`, but the input-`1` case only counts when `I2` is `0` (otherwise input `2` would have won, forcing `A0` back to `0`), so that term is guarded by `NOT I2`:

```
A1 = I3 OR I2      A0 = I3 OR (NOT I2 AND I1)
```

Check the tricky overlap by hand. Raise `I2` and `I1` together with `I3 = 0`: `A1 = 0 OR 1 = 1`, and `A0 = 0 OR (NOT 1 AND 1) = 0 OR (0 AND 1) = 0`, giving `A1 A0 = 10`, address `2`. The higher input `I2` won cleanly, and `I1` was correctly ignored. The plain encoder gave `11` on the same inputs; the priority version gives the right answer, `2`.

## The valid output earns its keep

Look at the top two table rows. With every input `0` the address is `00`, and with only `I0` high the address is *also* `00`. The address alone cannot tell `nothing is active` from `input 0 is active`. That is what the **valid** output `V` is for: it is `1` whenever any input is high and `0` only when all are low, so a reader checks `V` first and trusts the address only when `V = 1`.

```
V = I3 OR I2 OR I1 OR I0     (1 when any input is active)
```

_Circuit diagram: A 4-to-2 priority encoder: A1 = I3 OR I2, A0 = I3 OR (NOT I2 AND I1), and a valid output V that ORs all four inputs. Open it in the lab and raise inputs in combination: with I2 and I1 both high the address reads 10 (input 2 wins), and V stays 1 for every non-empty input. Drop all four inputs and V goes 0._

> **WARN:** Two classic mistakes. First, **dropping the valid output**: without `V` you cannot distinguish `no request` from `request 0`, since both read address `00`. Second, **getting the priority direction backwards** or forgetting the guard term: the low bit's input-`1` case must be gated by `NOT I2`, or a simultaneous `I2` would leave `A0` stuck at `1` and report address `11` (input 3) when input `2` should have won. And do not reach for a plain [encoder](https://digiwleea.wleeaf.dev/learn/encoder-demux/) when two lines can be high at once: it blends their addresses into a wrong number.

**Q (Try it):** On the priority encoder you raise `I3`, `I1`, and `I0` all at once (`I2 = 0`). What are `A1`, `A0`, and `V`? Then drop `I3` so only `I1` and `I0` are high. What changes?

**A:** With `I3 = 1`: `A1 = I3 OR I2 = 1`, `A0 = I3 OR (NOT I2 AND I1) = 1`, so `A1 A0 = 11`, address `3`, and `V = 1`. `I3` is the top priority, so `I1` and `I0` are ignored. Drop `I3` (now `I2 = 0`, `I1 = 1`, `I0 = 1`): `A1 = 0 OR 0 = 0`, `A0 = 0 OR (1 AND 1) = 1`, giving `A1 A0 = 01`, address `1`. The next-highest active input, `I1`, now wins, and `I0` is still ignored. `V` stays `1` the whole time because something is always active.

> **KEY:** The priority encoder is how a computer decides **which request to serve first**. An interrupt controller wires each device to one input line; when several devices interrupt at once, the encoder hands the CPU the number of the highest-priority one, and `V` tells it an interrupt is pending at all. The same shape appears wherever many signals compete for one answer, from finding the leading `1` in a number to arbitrating a shared bus. Next you will see how a bank of registers, addressed the same numbered way, becomes the CPU's fast working storage: the [register file](https://digiwleea.wleeaf.dev/learn/register-file/).

### FAQ

**Q:** What is a priority encoder?

**A:** A priority encoder is a combinational circuit that outputs the binary index of the **highest-numbered** active input, even when several inputs are high at once, plus a **valid** output that is `1` whenever any input is active. For a 4-to-2 priority encoder, `A1 = I3 OR I2`, `A0 = I3 OR (NOT I2 AND I1)`, and `V = I3 OR I2 OR I1 OR I0`.

**Q:** What is the difference between an encoder and a priority encoder?

**A:** A plain [encoder](https://digiwleea.wleeaf.dev/learn/encoder-demux/) assumes its input is one-hot (exactly one line high); if two lines are high it ORs their addresses into a wrong number. A priority encoder ranks the inputs and reports the highest-numbered active one, so it gives a sensible answer for any input pattern, and it adds a valid output that a plain encoder lacks.

**Q:** Why does a priority encoder need a valid output?

**A:** Because the address alone is ambiguous: `no input active` and `only input 0 active` both produce address `00`. The valid output `V` is `1` whenever any input is high and `0` only when all inputs are low, so a reader checks `V` first and trusts the encoded address only when `V = 1`.

**Q:** Where are priority encoders used?

**A:** In interrupt controllers, where many devices can request the CPU's attention at the same time and the encoder reports the highest-priority one to service first. More generally they appear in bus arbitration, in finding the position of the leading `1` in a word (used by floating-point normalization), and anywhere several competing signals must collapse to a single chosen index.
