Урок 0. Логика: 0 и 1, вентили из транзисторов, сумматор
В картинкахФундамент перед часами. Здесь — что такое 0 и 1, три операции над ними (булева алгебра), как из транзисторов получается логический вентиль и как из вентилей собрать полезную вещь — схему, которая складывает два 4-битных числа. Всё дальше в наборе — те же вентили, только их больше.
Итог: NOT (2 транзистора), NAND и NOR (по 4), AND и OR (по 6), XOR (16), полный сумматор FA (50), 4-битный сумматор ADD4 (200) — все 256 сумм от 0+0 до 15+15 верны.
0.1. Симулятор
Всё собирается в браузере: cs.khanin.info. Установка и регистрация не нужны; удобнее работать на компьютере с мышью.
Это учебный симулятор, а не программа для разработки настоящей электроники. Транзистор в нём — идеальный выключатель (открыт или закрыт), сигнал — только 0 или 1. Напряжений, токов, задержек в проводах, нагрева и помех нет. Чтобы понять, как работает логика, память и процессор, этого хватает с запасом; схему для настоящей платы по нему не спроектируешь — там нужны резисторы, расчёт питания и временных запасов.
Как ставить детали, метки, чипы — в разделе «Симулятор за пять минут» перед уроками. Главное здесь: метки с одинаковым именем соединены, Ctrl+G сворачивает выделенное в чип, Export сохраняет работу.
0.2. Булева алгебра: 0, 1 и три операции
Сигнал — 0 или 1 (нет/есть, ложь/истина, выключено/включено). Булева алгебра (Джордж Буль, 1847) — арифметика таких значений. Операций всего три:
- НЕ (NOT) — переворачивает:
НЕ 0 = 1,НЕ 1 = 0. В наборе пишем приставкойn:nA= НЕA. - И (AND) —
A·Bравно 1, только когда оба входа 1. - ИЛИ (OR) —
A + Bравно 1, когда хотя бы один вход 1.
Их комбинации получили свои имена, потому что встречаются постоянно:
| A | B | A·B | A + B | NAND | NOR | XOR |
|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 | 0 | 0 | 0 |
- NAND = НЕ(И), NOR = НЕ(ИЛИ).
- XOR («исключающее ИЛИ»,
A ⊕ B) — 1, когда входы разные. Это сложение одного бита без переноса:1 + 1 = 0, а единица уходит в перенос (пригодится в 0.5).
⚠ Плюс в булевой алгебре — это ИЛИ, а не сложение: 1 + 1 = 1.
Законы, по которым формулы упрощают (каждый проверяется подстановкой 0 и 1):
| Закон | Пример |
|---|---|
| с константой | A·1 = A A·0 = 0 A + 0 = A A + 1 = 1 |
| с самим собой | A·A = A A + A = A |
| с противоположным | A·nA = 0 A + nA = 1 |
| двойное НЕ | НЕ(nA) = A |
| вынос за скобку | A·B + A·C = A·(B + C) |
| склейка | A·B + A·nB = A |
| де Морган | НЕ(A·B) = nA + nB НЕ(A + B) = nA·nB |
Закон де Моргана словами: «не (оба)» = «хотя бы один нет». Он позволяет менять И на ИЛИ ценой переворотов — так в уроке 3 мультиплексор переделан на одни NAND и стал дешевле.
0.3. Транзистор — выключатель
В палитре — деталь Transistor. У неё три ноги: затвор G слева, верх и низ. Затвор управляет, соединены ли верх и низ. Alt + клик по корпусу (на Mac — ⌥ или ⌘ + клик) меняет тип N ↔ P — обычный клик тип не трогает:
- N: затвор = 1 → верх и низ соединены; затвор = 0 → разомкнуты.
- P: наоборот — соединены при затворе = 0.
Правило CMOS (так устроены почти все микросхемы с 1980-х): P-транзисторы ставим сверху, между VCC (источник 1) и выходом; N — снизу, между выходом и GND (источник 0). При любом входе проводит ровно одна половина — выход всегда подключён либо к 1, либо к 0. Никогда к обоим сразу (закоротка) и никогда ни к чему (обрыв, выход «висит»).
0.4. NOT, NAND, NOR из транзисторов
NOT — два транзистора. Вход A идёт на оба затвора: при A = 0 открыт верхний P и выход тянется к 1, при A = 1 — нижний N, выход тянется к 0.
ПОРТЫ-ВХОДЫ: A · ПОРТЫ-ВЫХОДЫ: Y
| Транзистор | Затвор | Верх | Низ |
|---|---|---|---|
| P | A | VCC | Y |
| N | A | Y | GND |
Сборка в чип: Ctrl+G → NOT.
NAND — четыре. Два P параллельно сверху: хватит одного нуля на входе, чтобы выход стал 1. Два N последовательно снизу: выход соединится с землёй, только когда оба входа 1. Точку между двумя N назовём меткой mid.
ПОРТЫ-ВХОДЫ: A, B · ПОРТЫ-ВЫХОДЫ: Y
| Транзистор | Затвор | Верх | Низ |
|---|---|---|---|
| P | A | VCC | Y |
| P | B | VCC | Y |
| N | A | Y | mid |
| N | B | mid | GND |
Сборка в чип: Ctrl+G → NAND.
NOR — зеркально: два P последовательно (выход 1, только когда оба входа 0), два N параллельно (любая единица тянет выход к 0).
ПОРТЫ-ВХОДЫ: A, B · ПОРТЫ-ВЫХОДЫ: Y
| Транзистор | Затвор | Верх | Низ |
|---|---|---|---|
| P | A | VCC | mid |
| P | B | mid | Y |
| N | A | Y | GND |
| N | B | Y | GND |
Сборка в чип: Ctrl+G → NOR.
AND, OR, XOR — из вентилей. Транзисторы больше не нужны: три недостающих вентиля собираются из только что собранных NOT, NAND, NOR.
AND = NAND + NOT — «И-НЕ», а потом перевернуть:
ПОРТЫ-ВХОДЫ: A, B · ПОРТЫ-ВЫХОДЫ: Y
| Элемент | Входы | Выход |
|---|---|---|
| NAND | A, B | n |
| NOT | n | Y |
Сборка в чип: Ctrl+G → AND.
OR = NOR + NOT:
ПОРТЫ-ВХОДЫ: A, B · ПОРТЫ-ВЫХОДЫ: Y
| Элемент | Входы | Выход |
|---|---|---|
| NOR | A, B | n |
| NOT | n | Y |
Сборка в чип: Ctrl+G → OR.
XOR — «хотя бы один, но не оба»: AND( OR(A, B), NAND(A, B) ):
ПОРТЫ-ВХОДЫ: A, B · ПОРТЫ-ВЫХОДЫ: Y
| Элемент | Входы | Выход |
|---|---|---|
| OR | A, B | o |
| NAND | A, B | n |
| AND | o, n | Y |
Сборка в чип: Ctrl+G → XOR.
Проверка. Питание: V (Power) с меткой VCC и G (Ground) с меткой GND; два тумблера X, Y; к выходам — лампочки (LED):
| Элемент | Входы | Выход |
|---|---|---|
| NOT | X | notX |
| NAND | X, Y | nandXY |
| NOR | X, Y | norXY |
| AND | X, Y | andXY |
| OR | X, Y | orXY |
| XOR | X, Y | xorXY |
| LED | notX | |
| LED | nandXY | |
| LED | norXY | |
| LED | andXY | |
| LED | orXY | |
| LED | xorXY |
Пощёлкай тумблерами — лампы должны повторять таблицу из 0.2. Или выдели чип и нажми T — таблица истинности.
Цена в транзисторах: NOT — 2, NAND и NOR — по 4. А AND = NAND + NOT = 6, OR = NOR + NOT = 6: «И» дороже, чем «И-НЕ». Поэтому в CMOS родные вентили — NAND и NOR, и формулы выгодно сводить к ним. XOR — 16 транзисторов.
Эти шесть чипов — NOT, NAND, NOR, AND, OR, XOR — теперь в вашей библиотеке справа, и на них стоит весь набор. Дальше транзисторы руками не ставим: берём эти вентили.
0.5. Сложение одного разряда
Складываем двоичные числа столбиком, как десятичные: 0 + 0 = 0, 0 + 1 = 1, 1 + 1 = 10 — ноль пишем, единицу переносим в следующий разряд. В каждом разряде складываются три бита: A, B и перенос из младшего разряда CI. Выходов два: бит суммы S и перенос дальше CO.
| A | B | CI | S | CO | единиц |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 | 1 |
| 0 | 1 | 0 | 1 | 0 | 1 |
| 0 | 1 | 1 | 0 | 1 | 2 = 10 |
| 1 | 0 | 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 0 | 1 | 2 = 10 |
| 1 | 1 | 0 | 0 | 1 | 2 = 10 |
| 1 | 1 | 1 | 1 | 1 | 3 = 11 |
Как выводили:
S = 1, когда единиц нечётное число — это и есть XOR трёх битов:S = A ⊕ B ⊕ CI.CO = 1, когда единиц две или три. Либо обеAиB(A·B), либо ровно одна из них (A ⊕ B) и перенос:CO = A·B + (A ⊕ B)·CI.
A ⊕ B нужен и для S, и для CO — считаем один раз, метка p.
ПОРТЫ-ВХОДЫ: A, B, CI · ПОРТЫ-ВЫХОДЫ: S, CO
| Элемент | Входы | Выход (→) |
|---|---|---|
| XOR | A, B | p |
| XOR | p, CI | S |
| AND | A, B | g |
| AND | p, CI | pc |
| OR | g, pc | CO |
Сборка в чип: Ctrl+G → FA (full adder — полный сумматор), входы A B CI, выходы S CO, 50 транзисторов. Проверка: T — восемь строк, как в таблице выше.
0.6. Сумматор 4 бит
Четыре FA в цепочку: перенос CO каждого разряда идёт на CI следующего. У младшего разряда переноса нет — CI = GND (0). Перенос старшего — это пятый бит суммы S4: 15 + 15 = 30 = 11110, в четыре бита не влезает.
ПОРТЫ-ВХОДЫ: A0 A1 A2 A3, B0 B1 B2 B3 · ПОРТЫ-ВЫХОДЫ: S0 S1 S2 S3 S4
| Элемент | Входы | Выход (→) |
|---|---|---|
| FA | A=A0, B=B0, CI=GND | S→S0, CO→c1 |
| FA | A=A1, B=B1, CI=c1 | S→S1, CO→c2 |
| FA | A=A2, B=B2, CI=c2 | S→S2, CO→c3 |
| FA | A=A3, B=B3, CI=c3 | S→S3, CO→S4 |
Сборка в чип: Ctrl+G → ADD4, 200 транзисторов.
Такой сумматор называется последовательным переносом (ripple carry): перенос «бежит» от младшего разряда к старшему, как при сложении столбиком. Самый долгий случай — 0111 + 0001: единица переноса проходит через все четыре разряда. Сумматор — сердце любого процессора: из него же делают вычитание, сравнение и счётчики.
0.7. Холст и проверка
- Питание:
V(Power) с меткойVCC,G(Ground) с меткойGND(если уже стоят с проверки вентилей — не нужно). - Восемь тумблеров (
I) → меткиA0 A1 A2 A3иB0 B1 B2 B3. - Чип
ADD4, на его ноги — одноимённые метки:A0…A3,B0…B3,S0…S4. - Три Display (bus). На каждом: клик по ⚙ слева сверху меняет разрядность (4b / 8b / 16b / 32b), клик по
PINслева снизу — ввести имя шины, и табло само читает меткиимя0,имя1, …, без проводов:
| Элемент | Разрядность | Шина |
|---|---|---|
| Display (bus) | 4b | A |
| Display (bus) | 4b | B |
| Display (bus) | 8b | S |
У суммы 5 бит, а у табло таких нет — ставим 8b: битов S5…S7 на холсте нет, табло считает их нулями.
Проверка: 3 + 4 = 7, 7 + 1 = 8 (перенос пробегает все разряды), 15 + 15 = 30 (горит S4). Любые 4-битные числа складываются верно — проверены все 256 пар.
Вставка урока 0 (Cmd+I)
Создаёт в пустом проекте все базовые вентили набора (NOT, NAND, NOR, AND, OR, XOR), FA, ADD4 и ставит на холст питание, проверку вентилей с лампами и сумматор с тремя табло.
# Урок 0 — вентили из транзисторов и 4-битный сумматор.# Вставка: Cmd+I в пустой проект: собирает все базовые вентили набора (NOT NAND NOR AND OR XOR), FA и ADD4.# Транзистор: nmos/pmos(затвор, верх, низ). VCC/GND — общие шины питания. # --- вентили из транзисторов ---chip NOT { portIn(A) portOut(Y) pmos(A, VCC, Y) nmos(A, Y, GND)} # NAND: два P параллельно сверху, два N последовательно снизуchip NAND { portIn(A) portIn(B) portOut(Y) pmos(A, VCC, Y) pmos(B, VCC, Y) nmos(A, Y, mid) nmos(B, mid, GND)} # NOR: два P последовательно сверху, два N параллельно снизуchip NOR { portIn(A) portIn(B) portOut(Y) pmos(A, VCC, mid) pmos(B, mid, Y) nmos(A, Y, GND) nmos(B, Y, GND)} # --- вентили из вентилей ---# AND = NAND + NOT (6 транзисторов)chip AND { portIn(A) portIn(B) portOut(Y) NAND(A, B, n) NOT(n, Y)} # OR = NOR + NOT (6 транзисторов)chip OR { portIn(A) portIn(B) portOut(Y) NOR(A, B, n) NOT(n, Y)} # XOR = «хотя бы один, но не оба»: AND( OR(A,B), NAND(A,B) ) (16 транзисторов)chip XOR { portIn(A) portIn(B) portOut(Y) OR(A, B, o) NAND(A, B, n) AND(o, n, Y)} # --- полный сумматор одного разряда ---chip FA { portIn(A) portIn(B) portIn(CI) portOut(S) portOut(CO) XOR(A, B, p) XOR(p, CI, S) AND(A, B, g) AND(p, CI, pc) OR(g, pc, CO)} # --- 4 разряда: перенос бежит от младшего к старшему ---chip ADD4 { portIn(A0) portIn(A1) portIn(A2) portIn(A3) portIn(B0) portIn(B1) portIn(B2) portIn(B3) portOut(S0) portOut(S1) portOut(S2) portOut(S3) portOut(S4) FA(A0, B0, GND, S0, c1) FA(A1, B1, c1, S1, c2) FA(A2, B2, c2, S2, c3) FA(A3, B3, c3, S3, S4)} # --- на холст: питание, проверка вентилей, сумматор с табло ---power(VCC)ground(GND)input(X)input(Y)NOT(X, notX)NAND(X, Y, nandXY)NOR(X, Y, norXY)AND(X, Y, andXY)OR(X, Y, orXY)XOR(X, Y, xorXY)led(notX)led(nandXY)led(norXY)led(andXY)led(orXY)led(xorXY)input(A0)input(A1)input(A2)input(A3)input(B0)input(B1)input(B2)input(B3)ADD4(A0, A1, A2, A3, B0, B1, B2, B3, S0, S1, S2, S3, S4)display{bits=4, busSource=A}()display{bits=4, busSource=B}()display{bits=8, busSource=S}()Не получается? Что-то не работает →