Lesson 1. BCD → 7-segment decoder
In picturesFour switches set a digit 0–9 in binary; a circuit of gates lights the right bars of that digit on a segment LCD. This is the first building block of the watch / Game & Watch: time is stored inside as binary numbers, but the screen needs digits made of bars. Between them sits a decoder — a circuit without memory that decides, from 4 bits, which of the 7 segments to light.
Result: chip DEC4x1, 150 transistors, all 10 digits correct.
0. What you need to know
BCD — every decimal digit is stored in 4 bits: D3 D2 D1 D0 (D3 is the most significant). 5 = 0101, 9 = 1001. The combinations 1010…1111 (10–15) never occur in BCD.
Segments are named by letters — a on top, then clockwise, g in the middle:
1. The screen
- Place a Segment LCD (palette, the read-out icon next to the dot display).
- ⚙ → Size field:
24×30(click the number, type, Enter). - Right panel Stamps → size L 21 → section Digits → first tile (the eight without a point) → click in the middle of the field →
Esc. S(select) → magic-wand click on the top segment →Enter(New pin) → namea→ Enter. Clockwise the same way: top-rightb, bottom-rightc, bottomd, bottom-lefte, top-leftf, middleg.- Close the editor. The body now has 7 pins
a…g→ hang labelsa b c d e f gon them.
2. Inputs
Four Input switches → labels D0 D1 D2 D3. For convenience add a Display (bus) on D0..D3 to see the number.
3. Method: truth table → formula
Step 1. A table row = one AND of all inputs. An input that is 1 in that row is taken as is; an input that is 0 goes through NOT (a label with the prefix n: nD0 = NOT D0). Such an AND is 1 in exactly that row.
Step 2. OR all those ANDs together. The formula is already correct, just long.
Step 3. Simplify.
- Strike out an input: the struck-out position "flips" → a row gets added. If the added row is a free one (10–15) — striking out is allowed. If it is a real digit with a different value of the segment — not allowed. ⚠ The test is exactly "which row gets added", not "this input is the same in all my rows". Digits 8 and 9 are real.
- Merge two rows: if they differ in exactly one input, the pair = one AND without that input (
X·B + X·¬B = X). One row may be used in several merges. - Factor out a common term:
nD0·nD2 + nD0·D1 = nD0·(nD2 + D1).
If there are fewer zeros than ones — it is easier to describe when the segment is off and invert at the end. "OR, then NOT" = one NOR gate; "AND, then NOT" = one NAND — fewer transistors (in CMOS the native gates are exactly NAND and NOR; AND = NAND + NOT).
⚠ Trap: you can't chain NAND or NOR to get "more inputs" — each one adds its own NOT. NAND(NAND(A,B),C) is not NAND3 (on 111 it gives 1). Correct: NAND(AND(A,B), C). AND and OR can be chained: AND(AND(A,B),C) is an honest AND3.
Reuse. The same "digit detector" (for example, the AND for one) is needed by several segments — build it once, put a label on it, refer to the label.
4. Truth table
| Digit | D3 D2 D1 D0 | a | b | c | d | e | f | g |
|---|---|---|---|---|---|---|---|---|
| 0 | 0 0 0 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| 1 | 0 0 0 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 2 | 0 0 1 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 |
| 3 | 0 0 1 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
| 4 | 0 1 0 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
| 5 | 0 1 0 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
| 6 | 0 1 1 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
| 7 | 0 1 1 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| 8 | 1 0 0 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| 9 | 1 0 0 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
| 10-15 | free | anything — may be used when simplifying | ||||||
5. Deriving each segment
Segment a — off on 1, 4
| Row | AND | Strike out → adds | Result |
|---|---|---|---|
| 1 = 0001 | nD3·nD2·nD1·D0 | nD3 → 1001 = 9 (a=1) ✗ the others are digits too ✗ | nD3·nD2·nD1·D0 |
| 4 = 0100 | nD3·D2·nD1·nD0 | nD3 → 1100 = 12, free ✓ | D2·nD1·nD0 |
a = NOR( nD3·nD2·nD1·D0 , D2·nD1·nD0 )
Segment b — off on 5, 6
Observation: when D2 = 0 it is always on → term nD2. When D2 = 1 it is on for 4 (00) and 7 (11) — when D1 and D0 are equal → nD1·nD0 + D1·D0.
b = nD2 + nD1·nD0 + D1·D0 (shorter: b = NAND( D2, XOR(D1, D0) ) — 2 gates)
Segment c — off on 2
| Row | AND | Strike out → adds | Result |
|---|---|---|---|
| 2 = 0010 | nD3·nD2·D1·nD0 | nD3 → 1010 = 10, free ✓ nD2 → 0110 = 6 ✗ D1 → 0000 = 0 ✗ nD0 → 0011 = 3 ✗ | nD2·D1·nD0 |
c = NAND3( nD2, D1, nD0 ) — built as NAND + NOT + NAND = 10 transistors (the first try, AND4 + NOT, would be 20: AND4 = three ANDs of 6). An honest CMOS NAND3 from transistors is 6 (see section 7).
Segment d — off on 1, 4, 7
| Row | AND | Strike out → adds | Result |
|---|---|---|---|
| 1 = 0001 | nD3·nD2·nD1·D0 | every one gives a digit (9,5,3,0) ✗ | nD3·nD2·nD1·D0 (=1) |
| 4 = 0100 | nD3·D2·nD1·nD0 | nD3 → 1100 = 12 ✓ | D2·nD1·nD0 (=4) |
| 7 = 0111 | nD3·D2·D1·D0 | nD3 → 1111 = 15 ✓ | D2·D1·D0 (=7) |
d = NOT( 1 + 4 + 7 ) — the "1" and "4" detectors are already built for a, reuse them.
Segment e — on for 0, 2, 6, 8 (fewer ones — take them, no NOT at the end)
Merges (pairs differing in one input; 10 and 14 are free):
| Rows | Differ in | Gives |
|---|---|---|
| 0, 2, 8, 10 | D3, D1 | nD2·nD0 |
| 2, 6, 10, 14 | D3, D2 | D1·nD0 |
e = nD2·nD0 + D1·nD0 → factor out nD0: e = nD0 · (nD2 + D1) — 2 gates.
Segment f — off on 1, 2, 3, 7
| What | How | Gives |
|---|---|---|
| 1 = 0001 | can't drop nD3: adds 9 (f=1) ✗ | nD3·nD2·nD1·D0 |
| 2 and 3 (+10, 11) | differ in D0 | nD2·D1 |
| 3 and 7 (+11, 15) | differ in D2 | D1·D0 |
f = NOT( 1 + nD2·D1 + D1·D0 ) — reuse "1"; D1·D0 is shared with b.
Segment g — off on 0, 1, 7
| What | How | Gives |
|---|---|---|
| 0 and 1 | differ in D0; can't drop nD3 (8, 9) | nD3·nD2·nD1 |
| 7 = 0111 | nD3 → 1111 = 15 ✓ | D2·D1·D0 (=7) |
g = NOR( nD3·nD2·nD1 , 7 )
6. Assembly
Helper gates with 3–4 inputs
Built as chains of two-input gates and folded with Ctrl+G into chips (input ports A B C [D], output Y):
| Element | Inputs | Output (→) |
|---|---|---|
| AND3 | ||
| AND | A, B | ab |
| AND | ab, C | Y |
| AND4 | ||
| AND | A, B | ab |
| AND | ab, C | abc |
| AND | abc, D | Y |
| OR3 | ||
| OR | A, B | ab |
| OR | ab, C | Y |
| NAND3 | ||
| NAND | A, B | nab |
| NOT | nab | ab |
| NAND | ab, C | Y |
The decoder DEC4x1
INPUT PORTS: D0 D1 D2 D3 · OUTPUT PORTS: a b c d e f g
| Element | Inputs | Output (→) | |
|---|---|---|---|
| NOT | D0 | nD0 | |
| NOT | D1 | nD1 | |
| NOT | D2 | nD2 | |
| NOT | D3 | nD3 | |
| AND4 | nD3, nD2, nD1, D0 | nD3nD2nD1D0 | ← digit 1 |
| AND3 | D2, nD1, nD0 | D2nD1nD0 | ← digit 4 |
| AND3 | D2, D1, D0 | D2D1D0 | ← digit 7 |
| AND | D0, D1 | D0D1 | |
| NOR | nD3nD2nD1D0, D2nD1nD0 | a | |
| AND | nD0, nD1 | nD1nD0 | |
| OR | nD1nD0, D0D1 | b_low | |
| OR | nD2, b_low | b | |
| NAND3 | nD2, D1, nD0 | c | |
| OR3 | nD3nD2nD1D0, D2nD1nD0, D2D1D0 | d_off | |
| NOT | d_off | d | |
| OR | nD2, D1 | e_or | |
| AND | e_or, nD0 | e | |
| AND | nD2, D1 | nD2D1 | |
| OR3 | nD3nD2nD1D0, nD2D1, D0D1 | f_off | |
| NOT | f_off | f | |
| AND3 | nD3, nD2, nD1 | nD3nD2nD1 | |
| NOR | nD3nD2nD1, D2D1D0 | g |
(Nets like b_low, d_off, e_or, f_off, nD2D1, nD3nD2nD1 can be plain wires without a name — the names are only there so the table reads clearly.)
Fold into a chip: select everything and Ctrl+G → chip DEC4x1, input ports D0 D1 D2 D3, output ports a b c d e f g. On the canvas: switches D0..D3 → DEC4x1 → labels a..g → LCD pins.
Test: click the switches through 0000…1001 — every digit looks like a real one.
What it shows for 10–15: the digits 2, 3, 4, 5, 6, 7 — because we dropped D3 almost everywhere. That's the price of simplifying: on numbers that never occur the screen draws whatever (the real 7447 chip does the same).
7. Even cheaper (for later)
| Segment | As built | Shorter |
|---|---|---|
| b | AND + OR + OR | XOR(D1,D0) + NAND(D2, ·) |
| c | NAND3 from NAND+NOT+NAND (10) | NAND3 from transistors (6) |
| d | OR3 + NOT | NOR3 (6 transistors) |
| f | OR3 + NOT | NOR3 |
| g | AND3(nD3,nD2,nD1) | same formula; 7 is already D2D1D0 ✓ |
NAND3 from transistors: 3 pmos in parallel (VCC ↔ Y), 3 nmos in series (Y → … → GND). NOR3 is the opposite: 3 pmos in series, 3 nmos in parallel.
8. The whole lesson as one paste (Cmd+I)
Creates AND3 AND4 OR3 NAND3 DEC4x1 in the library and places power, 4 switches D0..D3 and DEC4x1 with labels a..g on the canvas.
- Paste into a project where these chips don't exist yet (otherwise the library gets two with the same name).
- The netlist language does not describe the Segment LCD — place it by hand following section 1 and hang the labels
a..gon its pins.
chip AND3 { portIn(A) portIn(B) portIn(C) portOut(Y) AND(A, B, ab) AND(ab, C, Y)} chip AND4 { portIn(A) portIn(B) portIn(C) portIn(D) portOut(Y) AND(A, B, ab) AND(ab, C, abc) AND(abc, D, Y)} chip OR3 { portIn(A) portIn(B) portIn(C) portOut(Y) OR(A, B, ab) OR(ab, C, Y)} chip NAND3 { portIn(A) portIn(B) portIn(C) portOut(Y) NAND(A, B, nab) NOT(nab, ab) NAND(ab, C, Y)} chip DEC4x1 { portIn(D0) portIn(D1) portIn(D2) portIn(D3) portOut(a) portOut(b) portOut(c) portOut(d) portOut(e) portOut(f) portOut(g) NOT(D0, nD0) NOT(D1, nD1) NOT(D2, nD2) NOT(D3, nD3) AND4(nD3, nD2, nD1, D0, nD3nD2nD1D0) AND3(D2, nD1, nD0, D2nD1nD0) AND3(D2, D1, D0, D2D1D0) AND(D0, D1, D0D1) NOR(nD3nD2nD1D0, D2nD1nD0, a) AND(nD0, nD1, nD1nD0) OR(nD1nD0, D0D1, b_low) OR(nD2, b_low, b) NAND3(nD2, D1, nD0, c) OR3(nD3nD2nD1D0, D2nD1nD0, D2D1D0, d_off) NOT(d_off, d) OR(nD2, D1, e_or) AND(e_or, nD0, e) AND(nD2, D1, nD2D1) OR3(nD3nD2nD1D0, nD2D1, D0D1, f_off) NOT(f_off, f) AND3(nD3, nD2, nD1, nD3nD2nD1) NOR(nD3nD2nD1, D2D1D0, g)} power(VCC)ground(GND)input(D0)input(D1)input(D2)input(D3)DEC4x1(D0, D1, D2, D3, a, b, c, d, e, f, g)¿No te sale? Algo no funciona →