Урок 1. Дешифратор BCD → 7 сегментов

В картинках

Четыре тумблера задают цифру 0–9 в двоичном виде, схема из вентилей зажигает нужные палочки цифры на сегментном ЖК. Это первый узел будущих часов / Game & Watch: время внутри хранится двоичными числами, а на экран нужны цифры из палочек. Между ними — дешифратор: схема без памяти, которая из 4 бит решает, какие из 7 сегментов зажечь.

Итог: чип DEC4x1, 150 транзисторов, все 10 цифр верны.


0. Что понадобится знать

BCD — каждая десятичная цифра хранится в 4 битах: D3 D2 D1 D0 (D3 — старший). 5 = 0101, 9 = 1001. Комбинации 1010…1111 (10–15) в BCD не бывают.

Сегменты называются буквами — a сверху, дальше по часовой, g — середина:

abcdefg
Семь сегментов цифры и их имена: a — верх, дальше по часовой, g — середина

1. Экран

  1. Поставить Segment LCD (палитра, иконка-табло рядом с точечным дисплеем).
  2. ⚙ → поле Size: 24 × 30 (клик по числу, ввести, Enter).
  3. Правая панель Stamps → размер L 21 → раздел Digits → первая плитка (восьмёрка без точки) → клик в центр поля → Esc.
  4. S (выделение) → клик палочкой по верхнему сегменту → Enter (New pin) → имя a → Enter. Так же по часовой: правый верхний b, правый нижний c, нижний d, левый нижний e, левый верхний f, средний g.
  5. Закрыть редактор. На корпусе 7 ног a…g → повесить на них метки a b c d e f g.

2. Входы

Четыре Input-тумблера → метки D0 D1 D2 D3. Для удобства — Display (bus) на D0..D3, чтобы видеть число.


0D31D20D11D0тумблерыDEC4x1без памятиabcdefgЖК: горит «5»0101 = 5
Урок 1 целиком: четыре бита 0101 (= 5) входят в дешифратор, он зажигает сегменты a, c, d, f, g — на ЖК видна пятёрка. Выходы дешифратора соединяются с ногами ЖК метками с теми же буквами.

3. Метод: таблица истинности → формула

Шаг 1. Строка таблицы = одно И (AND) всех входов. Вход, равный в строке 1, берём как есть, равный 0 — через НЕ (метка с приставкой n: nD0 = НЕ D0). Такое И равно 1 ровно в этой строке.

Шаг 2. Все такие И — через ИЛИ (OR). Формула уже верная, просто длинная.

Шаг 3. Сокращение.

  • Вычеркнуть вход: вычеркнутая позиция «переворачивается» → добавляется строка. Добавилась свободная (10–15) — вычёркивать можно. Добавилась настоящая цифра с другим значением сегмента — нельзя. ⚠ Критерий — именно «какая строка добавится», а не «во всех моих строках этот вход одинаковый». Цифры 8 и 9 — настоящие.
  • Склеить две строки: если отличаются ровно одним входом — их пара = одно И без этого входа (X·B + X·¬B = X). Одну строку можно использовать в нескольких склейках.
  • Вынести общий множитель: nD0·nD2 + nD0·D1 = nD0·(nD2 + D1).

Если нулей меньше, чем единиц — проще описать, когда сегмент не горит, и в конце перевернуть через НЕ. «ИЛИ, потом НЕ» = один вентиль NOR; «И, потом НЕ» = один NAND — так меньше транзисторов (в CMOS родные вентили именно NAND и NOR; AND = NAND + NOT).

⚠ Ловушка: NAND и NOR нельзя цеплять цепочкой ради «больше входов» — каждый добавляет своё НЕ. NAND(NAND(A,B),C) — это не NAND3 (на 111 даёт 1). Правильно: NAND(AND(A,B), C). AND и OR цепочкой — можно: AND(AND(A,B),C) — честный AND3.

Переиспользуй. Один и тот же «детектор цифры» (например, И для единицы) нужен нескольким сегментам — собрать один раз, повесить метку, ссылаться на метку.


4. Таблица истинности

ЦифраD3 D2 D1 D0abcdefg
00 0 0 01111110
10 0 0 10110000
20 0 1 01101101
30 0 1 11111001
40 1 0 00110011
50 1 0 11011011
60 1 1 01011111
70 1 1 11110000
81 0 0 01111111
91 0 0 11111011
10-15свободныелюбое — можно использовать при сокращении

5. Вывод по сегментам

Сегмент a — не горит на 1, 4

СтрокаИВычёркиваем → добавитсяИтог
1 = 0001nD3·nD2·nD1·D0nD3 → 1001 = 9 (a=1) ✗
остальные — тоже цифры ✗
nD3·nD2·nD1·D0
4 = 0100nD3·D2·nD1·nD0nD3 → 1100 = 12 свободная ✓D2·nD1·nD0
пример: цифра 4 = 0100nD3=1nD2=0nD1=1D0=0AND4: «это 1»D2=1nD1=1nD0=1AND3: «это 4»01NORa = 0сегмент погас
Сегмент a = NOR(«это 1», «это 4»). На цифре 4 срабатывает детектор «это 4», и NOR гасит сегмент a — у четвёрки верхней палочки нет.

a = NOR( nD3·nD2·nD1·D0 , D2·nD1·nD0 )

Сегмент b — не горит на 5, 6

Наблюдение: при D2 = 0 горит всегда → член nD2. При D2 = 1 горит на 4 (00) и 7 (11) — когда D1 и D0 одинаковые → nD1·nD0 + D1·D0.

b = nD2 + nD1·nD0 + D1·D0 (короче: b = NAND( D2, XOR(D1, D0) ) — 2 вентиля)

Сегмент c — не горит на 2

СтрокаИВычёркиваем → добавитсяИтог
2 = 0010nD3·nD2·D1·nD0nD3 → 1010 = 10 свободная ✓
nD2 → 0110 = 6 ✗
D1 → 0000 = 0 ✗
nD0 → 0011 = 3 ✗
nD2·D1·nD0

c = NAND3( nD2, D1, nD0 ) — собран как NAND + NOT + NAND = 10 транзисторов (первый вариант AND4 + NOT был бы 20: AND4 = три AND по 6). Честный CMOS-NAND3 из транзисторов — 6 (см. раздел 7).

Сегмент d — не горит на 1, 4, 7

СтрокаИВычёркиваем → добавитсяИтог
1 = 0001nD3·nD2·nD1·D0всё даёт цифры (9,5,3,0) ✗nD3·nD2·nD1·D0 (=1)
4 = 0100nD3·D2·nD1·nD0nD3 → 1100 = 12 ✓D2·nD1·nD0 (=4)
7 = 0111nD3·D2·D1·D0nD3 → 1111 = 15 ✓D2·D1·D0 (=7)

d = NOT( 1 + 4 + 7 ) — детекторы «1» и «4» уже собраны для a, переиспользуем.

Сегмент e — горит на 0, 2, 6, 8 (единиц меньше — берём их, без НЕ в конце)

Склейки (пары, отличающиеся одним входом; 10 и 14 — свободные):

СтрокиОтличаютсяПолучается
0, 2, 8, 10D3, D1nD2·nD0
2, 6, 10, 14D3, D2D1·nD0

e = nD2·nD0 + D1·nD0 → выносим nD0: e = nD0 · (nD2 + D1) — 2 вентиля.

Сегмент f — не горит на 1, 2, 3, 7

ЧтоКакПолучается
1 = 0001nD3 нельзя: добавится 9 (f=1) ✗nD3·nD2·nD1·D0
2 и 3 (+10, 11)отличаются D0nD2·D1
3 и 7 (+11, 15)отличаются D2D1·D0

f = NOT( 1 + nD2·D1 + D1·D0 ) — «1» переиспользуем, D1·D0 общий с b.

Сегмент g — не горит на 0, 1, 7

ЧтоКакПолучается
0 и 1отличаются D0; nD3 нельзя (8, 9)nD3·nD2·nD1
7 = 0111nD3 → 1111 = 15 ✓D2·D1·D0 (=7)

g = NOR( nD3·nD2·nD1 , 7 )


6. Сборка

Вспомогательные вентили на 3–4 входа

Собраны цепочкой из двухвходовых и свёрнуты Ctrl+G в чипы (порты-входы A B C [D], выход Y):

ЭлементВходыВыход (→)
AND3
ANDA, Bab
ANDab, CY
AND4
ANDA, Bab
ANDab, Cabc
ANDabc, DY
OR3
ORA, Bab
ORab, CY
NAND3
NANDA, Bnab
NOTnabab
NANDab, CY

Дешифратор DEC4x1

ПОРТЫ-ВХОДЫ: D0 D1 D2 D3 · ПОРТЫ-ВЫХОДЫ: a b c d e f g

ЭлементВходыВыход (→)
NOTD0nD0
NOTD1nD1
NOTD2nD2
NOTD3nD3
AND4nD3, nD2, nD1, D0nD3nD2nD1D0← цифра 1
AND3D2, nD1, nD0D2nD1nD0← цифра 4
AND3D2, D1, D0D2D1D0← цифра 7
ANDD0, D1D0D1
NORnD3nD2nD1D0, D2nD1nD0a
ANDnD0, nD1nD1nD0
ORnD1nD0, D0D1b_low
ORnD2, b_lowb
NAND3nD2, D1, nD0c
OR3nD3nD2nD1D0, D2nD1nD0, D2D1D0d_off
NOTd_offd
ORnD2, D1e_or
ANDe_or, nD0e
ANDnD2, D1nD2D1
OR3nD3nD2nD1D0, nD2D1, D0D1f_off
NOTf_offf
AND3nD3, nD2, nD1nD3nD2nD1
NORnD3nD2nD1, D2D1D0g

(На холсте у меток b_low, d_off, e_or, f_off, nD2D1, nD3nD2nD1, ab… были просто провода без имени — в нетлисте им даны имена, на схему это не влияет.)

Сборка в чип: выделить всё и Ctrl+G → чип DEC4x1, порты-входы D0 D1 D2 D3, порты-выходы a b c d e f g. На холсте: тумблеры D0..D3 → DEC4x1 → метки a..g → ноги ЖК.

Тест: пощёлкать тумблерами 0000…1001 — каждая цифра как настоящая.

Что показывает на 10–15: цифры 2, 3, 4, 5, 6, 7 — потому что почти везде мы выкинули D3. Цена сокращения: на несуществующих числах экран рисует что попало (так же у настоящей микросхемы 7447).


7. Можно ещё экономнее (на будущее)

СегментСобраноКороче
bAND + OR + ORXOR(D1,D0) + NAND(D2, ·)
cNAND3 из NAND+NOT+NAND (10)NAND3 из транзисторов (6)
dOR3 + NOTNOR3 (6 транзисторов)
fOR3 + NOTNOR3
gAND3(nD3,nD2,nD1)та же формула, 7 = уже D2D1D0 ✓

NAND3 из транзисторов: 3 pmos параллельно (VCC ↔ Y), 3 nmos цепочкой (Y → … → GND). NOR3 — наоборот: 3 pmos цепочкой, 3 nmos параллельно.


8. Вставка всего урока одним текстом (Cmd+I)

Создаёт в библиотеке AND3 AND4 OR3 NAND3 DEC4x1 и ставит на холст питание, 4 тумблера D0..D3 и DEC4x1 с метками a..g.

  • Вставлять в проект, где этих чипов ещё нет (иначе в библиотеке будут два одноимённых).
  • Segment LCD язык не описывает — его ставишь руками по разделу 1 и вешаешь метки a..g на ноги.
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)

Не получается? Что-то не работает →