# The seven-segment display decoder

*Turning a 4-bit digit into a numeral*

A seven-segment display decoder is a combinational circuit that maps a 4-bit binary-coded-decimal input (the digits 0 to 9) to seven outputs named a through g, each driving one bar of the numeral so the lit bars spell the digit.

Group: Processor
URL: https://digiwleea.wleeaf.dev/learn/seven-segment/

A [decoder](https://digiwleea.wleeaf.dev/learn/decoder/) turns a binary code into one specific output line, and [binary-coded decimal](https://digiwleea.wleeaf.dev/learn/bcd/) stores one decimal digit (`0` to `9`) in four bits. Put those two ideas together and you get one of the most recognizable circuits in electronics: the part that turns a 4-bit digit into the glowing bars of a numeral on a calculator, a microwave clock, or a scoreboard. It is a [decoder](https://digiwleea.wleeaf.dev/learn/decoder/) with a twist. Instead of raising a single one-hot line, it raises the whole *set* of segment lines that draw the digit, and every one of those lines is a small boolean function you can derive with a [Karnaugh map](https://digiwleea.wleeaf.dev/learn/karnaugh/).

> **TIP:** Picture the display as seven tiny bars arranged in a figure-eight: two stacked squares that share one bar across the middle. Light the right subset of bars and you draw any digit. Light all seven and you get an `8`; light only the two on the right and you get a `1`. The decoder's entire job is to decide, for each input digit, which bars to switch on.

## The seven bars, named a to g

The segments have standard names, `a` through `g`. Reading the figure-eight from the top: `a` is the bar across the top, `b` and `c` are the two bars down the right side, `d` is the bar across the bottom, `e` and `f` are the two bars down the left side, and `g` is the bar across the middle. Fixing these positions is what lets us write one truth-table column per segment.

- `a` : top bar.
- `b` : upper-right bar.
- `c` : lower-right bar.
- `d` : bottom bar.
- `e` : lower-left bar.
- `f` : upper-left bar.
- `g` : middle bar.

## Which segments each digit lights

Now the heart of the lesson: for every digit `0` to `9`, which of the seven bars are on? A `1` means the segment is lit, a `0` means it is dark. This table is the complete specification of the decoder, and every entry can be checked by looking at how the numeral is actually drawn.

| digit | a | b | c | d | e | f | g |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 2 | 1 | 1 | 0 | 1 | 1 | 0 | 1 |
| 3 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
| 4 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
| 5 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
| 6 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| 7 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| 8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 9 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |

_Which segments light for each digit. Check a few by eye: 0 lights the whole outer loop (a,b,c,d,e,f) but not the middle bar g; 1 lights only the right pair b,c; 7 lights a,b,c (a top bar and the right side); and 8 lights all seven._

A couple of rows are worth pausing on. The digit `0` is the only one that lights all of the outer loop while leaving `g` dark, which is exactly what stops it looking like an `8`. The digit `1` is the sparsest, just `b` and `c`. And the middle bar `g` stays dark for precisely three digits, `0`, `1`, and `7`, the three numerals with no horizontal stroke through their waist.

## It is really a lookup table (so it is a decoder)

Look at the table column by column rather than row by row. Each segment (`a`, `b`, `c`, ... `g`) is its own output, and its column is a full truth table over the four BCD input bits. So a seven-segment decoder is nothing more than **seven independent boolean functions that share the same four inputs**. That is why it counts as a [decoder](https://digiwleea.wleeaf.dev/learn/decoder/): four address-like bits go in, and a fixed pattern of output lines comes out, read straight from a stored table. You could even burn the whole table into a small [ROM or PLA](https://digiwleea.wleeaf.dev/learn/rom-pla/) and skip the algebra entirely. Here, though, we derive one segment by hand so you can see the gates behind the lookup.

## Deriving segment a from the table

Take segment `a`, the top bar. From the table it is lit for the digits `0, 2, 3, 5, 6, 7, 8, 9` and dark only for `1` and `4`. Writing the input as the four BCD bits `D3 D2 D1 D0` (weights `8 4 2 1`) gives this sub-table, one output column for `a`:

| D3 | D2 | D1 | D0 | a |
| --- | --- | --- | --- | --- |
| 0 | 0 | 0 | 0 | 1 |
| 0 | 0 | 0 | 1 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 0 | 1 | 1 | 1 |
| 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 0 | 1 | 1 | 0 | 1 |
| 0 | 1 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 | 1 |
| 1 | 0 | 0 | 1 | 1 |

_Segment a as a function of the four BCD bits, for the ten valid digits 0 to 9. It is 0 only in the rows for 1 (0001) and 4 (0100). The six input patterns 1010 to 1111 never occur in valid BCD, so they are don't-cares we may set either way to shrink the logic._

Drop these into a four-variable [Karnaugh map](https://digiwleea.wleeaf.dev/learn/karnaugh/) with the six invalid patterns (`10` to `15`) marked as don't-cares. Grouping the `1`s (and using the don't-cares wherever they help make a bigger block) gives four clean groups:

1. All eight cells with `D3 = 1` are `1` or don't-care, so the whole block collapses to the single term `D3` (it covers digits `8` and `9`).
2. All eight cells with `D1 = 1` are `1` or don't-care, giving the term `D1` (it covers `2, 3, 6, 7`).
3. The block where `D2 = 0` and `D0 = 0` is all `1` or don't-care, giving `D2'·D0'` (it covers digit `0`).
4. The block where `D2 = 1` and `D0 = 1` is all `1` or don't-care, giving `D2·D0` (it covers digit `5`).

OR the four groups together. The last two, `D2'·D0'` and `D2·D0`, are exactly the two cases where `D2` and `D0` are **equal**, which is the [XNOR](https://digiwleea.wleeaf.dev/learn/xnor/) of those two bits. So the whole segment collapses to a strikingly short expression:

```
a = D3 + D1 + D2'·D0' + D2·D0 = D3 + D1 + (D2 XNOR D0)
```

> **TIP:** That XNOR term is a nice sanity check on the whole method. Segment `a` (the top bar) is off for only two digits, `1` and `4`. In both, `D3` and `D1` are `0`, and `D2` and `D0` disagree (`1` is `0001`, `4` is `0100`), so `D2 XNOR D0` is `0` and the top bar goes dark. For every other digit at least one of `D3`, `D1`, or the equality of `D2` and `D0` holds, and the bar lights.

The circuit below is that expression built from real gates: an [XOR](https://digiwleea.wleeaf.dev/learn/xor/) and a [NOT](https://digiwleea.wleeaf.dev/learn/not/) form the `D2 XNOR D0` term, and two [OR](https://digiwleea.wleeaf.dev/learn/or/) gates fold in `D3` and `D1`. Open it in the lab, dial the four bits to each digit, and confirm `a` matches the table.

_Circuit diagram: Segment a of the decoder: a = D3 + D1 + (D2 XNOR D0), with the XNOR built as an XOR feeding a NOT. Set the four BCD inputs D3..D0 (weights 8, 4, 2, 1) to a digit; a (the top bar) should be high for every digit except 1 (0001) and 4 (0100)._

## Seven functions, one shared input

The full decoder is just six more derivations exactly like that one, each reading its own column out of the segment table and minimizing it, all sharing the same four input bits. Some come out short (segment `c`, the lower-right bar, is dark for only the digit `2`, so its logic is tiny), and some are busier. Stack the seven minimized functions side by side and you have a complete BCD-to-seven-segment decoder: four wires in, seven segment drivers out, a numeral on the glass.

**Q (Try it):** Use the segment `a` equation, `a = D3 + D1 + (D2 XNOR D0)`, to predict the top bar for digit `4` (input `0100`) and digit `6` (input `0110`). Then check both against the segment table above.

**A:** Digit `4` is `D3 D2 D1 D0 = 0100`: `D3 = 0`, `D1 = 0`, and `D2 = 1` while `D0 = 0`, so `D2 XNOR D0 = 0`. The sum `0 + 0 + 0` is `0`, so `a = 0`, the top bar is dark. The table agrees: `4` is drawn with no top stroke. Digit `6` is `0110`: `D1 = 1`, so `a = 0 + 1 + ... = 1`, the top bar is lit, which also matches the table (a `6` does have a top bar). The equation reproduces the table row for row.

> **WARN:** **Common mistakes.** First, the digit font is a convention, not a law: some displays draw `6` without the top bar `a`, `7` with an extra upper-left `f`, or `9` without the bottom `d`, so a different font gives slightly different equations. Verify against the exact table you are building for. Second, the six input patterns `1010` to `1111` are not valid BCD; treating them as don't-cares is a design choice that minimizes the gates, but a real chip (like the 7447) instead defines fixed, sometimes blank or odd, patterns for them, so do not assume they are free unless your spec says so. Third, watch the display polarity: a **common-cathode** display lights a segment on a `1`, but a **common-anode** display is active-low and lights on a `0`, which inverts every output. Finally, segment `g` (the middle bar) is dark for `0`, `1`, and `7`, not just `0`, a spot people often get wrong.

> **KEY:** The seven-segment decoder is where abstract logic becomes something you can read at a glance: it is the bridge from a binary count to a human numeral, and it shows a [decoder](https://digiwleea.wleeaf.dev/learn/decoder/) is really a stored table of boolean functions, one per output line. That same look-it-up pattern reappears in a [ROM or PLA](https://digiwleea.wleeaf.dev/learn/rom-pla/) and in the control logic of a CPU. Next, feed this decoder from a [counter](https://digiwleea.wleeaf.dev/learn/counter/) that ticks once per second and you have built the display of a digital clock.

### FAQ

**Q:** What is a seven-segment display decoder?

**A:** It is a combinational circuit that takes a 4-bit binary-coded-decimal digit (`0` to `9`) and drives seven outputs, named `a` through `g`, each controlling one bar of the numeral. The lit bars spell the digit, so `0000` lights all bars except the middle one to draw a `0`, and `1000` (`8`) lights all seven.

**Q:** How is a seven-segment decoder different from a normal decoder?

**A:** A plain [decoder](https://digiwleea.wleeaf.dev/learn/decoder/) raises exactly one one-hot output line for a given input code. A seven-segment decoder instead raises a whole *set* of output lines (the segments that draw the digit) for each input, so it is seven independent boolean functions sharing the same four input bits rather than a single one-hot selector.

**Q:** What is the boolean equation for segment a?

**A:** For a standard common-cathode digit font, segment `a` (the top bar) minimizes to `a = D3 + D1 + (D2 XNOR D0)`, using the four BCD bits `D3 D2 D1 D0` and treating the six invalid input patterns as don't-cares. It is high for every digit except `1` and `4`, the only two with no top stroke.

**Q:** Why does the seven-segment decoder use don't-cares?

**A:** A 4-bit input has sixteen patterns, but valid [BCD](https://digiwleea.wleeaf.dev/learn/bcd/) uses only ten (`0000` to `1001`); the six patterns `1010` to `1111` never occur, so their outputs can be set to whatever makes the [Karnaugh map](https://digiwleea.wleeaf.dev/learn/karnaugh/) groups largest. Using those don't-cares shrinks each segment's logic to fewer, simpler gates.
