Memory
- Circular Dependency
- Delayed lines
- Odd ticks
- Bit Inverter
- Bit Switch
- Input Selector
- The Bus
- Saving Gracefully
- Saving Bytes
- Counter
- Little Box
Circular Dependency
Задача: Создайте "круговую зависимость". Это схема, в которой вход компонента зависит от его собственного выхода.
В такой ситуации невозможно определить выход компонента, потому что сперва нужно определить вход, который сам ависит от выхода, образуя петлю.
A → B → C
↑ ↓
└───────┘
Delayed lines
Линия задержки. В задаче предоставлен компонент с задержкой в один tick.
Компонент с задержкой «1 такт» не отдаёт свой вход сразу, а только на следующий шаг симуляции.
tick = 0: вход = A → Delay1 хранит A, Delay2 хранит старое значение
tick = 1: вход = B → Delay1 выдаёт A, Delay2 выдаёт старое значение
tick = 2: вход = C → Delay1 выдаёт B, Delay2 выдаёт A
Синхронизация здесь нужна «логически», чтобы симулятор понимал, что значения обновляются только по тактам, а не мгновенно. Так как в реальном мире электроники, компоненты работают только по тактам.
Задача: Создайте цепь которая выводит свой собственный вход с задержкой в 2 такта.
Решение простое: последовательно два компонента с задержкой 1
Input → [Delay 1] → [Delay 2] → Output
Odd ticks
Нечетные такты.
Мы не дорускаем круговых зависимостей. Но есть одно исключение.
Линия задержки может зависеть от собственного входа. Это потому, что её вход не влияет на остальную схему до следующего такта.
Квадратные контакты в игре никогда не влияют на вывод в тот же такт. Поэтому они никогда не вызывают круговых зависимостей.
Задача: Выведите 0 для четных тактов и 1 для нечетных тактов.
Мы хотим сигнал, который чередуется каждый такт:
- Есть компонент Delay на 1 такт → он помнит прошлое состояние

Odd ticks (www.falstad.com/circuit)
Bit Inverter
Битовый инвертор
Задача: Имеем два входа: invert и value. Когда вход invert 1, выведите обратное от value. Иначе, просто выведите value как есть.
Найти решение которое соответвует такой таблице истинности. Это напоминает поведение XOR
| i/v | 0 | 1 |
|---|---|---|
| 0 | 0 | 1 |
| 1 | 1 | 0 |
Bit Switch (tri-state buffer)
tip
Разблокирует:
- переключатель на 1 бит
S - 8-ми битный
SWC
important
Главная цель битового переключателя (Bit Switch / Tri-state) - дать возможность нескольким источникам делить одну линию, не вызывая короткого замыкания к.з. (в Falstad → singular matrix)
A ─┐
├─── BUS
B ─┘
Если компоненты выдают разные значения по одному и тому же проводу, возникает ошибка (к.з.). Однако у некоторых компонентов выходные контакты могут иметь состояние выхода Z (high-impedance), и они вообще не выдают сигналы, когда компонент не активен,т.е. Z состояние это не просто низкий сигнал LOW/pull-down, а имеено электрическое отключение выхода/обрыв линии. Это относится и к компоненту Bit Switch.
important
На практике, состояние Z применяется в шинах (the bus)
REG0 ──┐
REG1 ──┼─── BUS ──► ALU
REG2 ──┘
У Bit Switch выход “Z” — это значит:
- когда switch выключен → он НИЧЕГО не выдаёт (провод “в воздухе”)
- когда switch включен → он пропускает вход на выход
Поэтому несколько Z выходов можно соединять в один провод, если гарантировано, что включён только один из них.
important
Bit Switch по сути это управляемый буфер с тремя состояниями
| Enable | In | Out |
|---|---|---|
| 0 | X | Z (отключён) |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Задача: Собрать gate XOR используя два переключателя switch и два gate NOT
- Один switch отвечает за случай A=1, B=0
- Второй switch — за A=0, B=1
- Их выходы соединены в один провод
- Одновременно они никогда не активны
| XOR | 0 | 1 |
|---|---|---|
| 0 | 0 | 1 |
| 1 | 1 | 0 |
(A AND !B) ─▶ buffer ┐
├──▶ OUT
(!A AND B) ─▶ buffer ┘

Из 8 штук битовых переключателей, можно сконструировать 8-ми битный переключатель самостоятельно.

Circuit Simulation (gate XOR)
(Собрать gate XOR используя два переключателя switch и два gate NOT)
Если учитывать состояние Z, то при A=1, B=1 оба tri-state буфера отключены, и линия оказывается в состоянии Z — никто не тянет её ни в 0, ни в 1. Чтобы в этом случае получить 0, добавляют pull-down — подтяжку к нулю по умолчанию. Тогда при отсутствии активных драйверов (Z) выход принимает значение 0 по умолчанию.
Bit Switch (www.falstad.com/circuit)
Circuit Simulation (Bit Switch)
(также часто называют "pass transistor logic", "передающий транзистор" или "ключ")
В CircuitJS нет прямого “tri-state buffer” как в игре Turing Complete.
Но есть аналог из реальной электроники для правильного моделирования состояния Z:
- Управляемый ключ на N-MOSFET (или NMOS):
- Сток (Drain) и Исток (Source) подключаются в разрыв вашей сигнальной линии
- Затвор (Gate) — это управляющий вход
- Принцип: Режим ключа предполагает заземлить подложку Body/Bulk, что бы диод не открылся когда на стоке напряжение выше, чем на истоке,что лишит нас возможности управлять затровором Gate. Когда на затвор Gate подается высокий уровень (логическая 1, напряжение, близкое к Vdd), транзистор открывается и проводит сигнал между стоком Drain и истоком Source. Когда на затворе низкий уровень (0), транзистор закрывается и разрывает цепь.
- Недостаток: пороговые потери (Threshold Voltage, Vth) на преодоление барьра открытия транзистора, что снижает выходное напряжение, например если HIGH был 5 Вольт, то на выходе 3.5 Вольт, что в каскаде т.е. дальнейшее использование сигнала HIGH с выхода уже невозможно!
- Transmission Gate (Analog Switch)
- Он состоит из параллельно соединенных N-MOSFET и P-MOSFET, управляемых инверсными сигналами.
- Когда ключ открыт, он отлично передает как 0, так и 1 без потерь напряжения.
- Трёхстабильный буфер (Tri-state buffer)
- По сути, трёхстабильный буфер — это "цифровая" версия Transmission Gate с гарантированными уровнями 0V/5V на выходе.
Bit Switch NMOS,Transmission Gate,Tri-state buffer (www.falstad.com/circuit)
8 bit Switch and 8 bit Multuplexers (MUX) Tri-state buffer:
Input Selector
tip
Разблокирует 8-ми битный MUX / Мультиплексер
Multuplexers (MUX / Мультиплексер)
Задача: Если бит selector input установлен в 0, вывод Byte A, иначе вывод Byte B
Условие задачи (человеческим языком)
Есть:
- Byte A (8 бит)
- Byte B (8 бит)
- Selector (1 бит)
Нужно использовать Selector:
- если Selector = 0 → вывести Byte A и полностью игнорировать B
- если Selector = 1 → вывести Byte B и полностью игнорировать A
Мультиплексер для одного бита выглядит так: OUT = (A & !S) | (B & S)
| S | A | B | OUT |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 0 |
Input Selector 1 bit
Для байта — то же самое, но 8 раз, по одному биту.

Но есть уже готовый компонет, 8-ми битный переключатель

The Bus
Шина.
Задача: На этом уровне имеется 2 байтовых входа и 2 байтовых выхода.
Ваша задача — скопировать верные данные с одного из входов на один из выходов.
Первый входной бит определяет, с какого входа следует копировать данные. Второй входной бит определяет, на какой выход следует копировать данные.
Используйте переключатели, чтобы подключить входы к одному проводу.

Saving Gracefully
Линия задержки позволяет нам использовать значение на 1 такт позже.
Нам нужно создать компонент, который позволит нам использовать значение, когда мы захотим, не важно на сколько тактов позже.
Такое значение называется сохранённым.
Задача:
На этом уровне 2 входа.
(Input Save) Только в случае если первый вход 1, обновите сохранённое значение.
(Input Value) Второй вход указывает какое значение нужно сохранить.
Всегда выводите сохранённое значение.
На этом уровне вам нужно использовать 1 линию задержки. Составьте таблицу истинности для того, что должно поступать на линию задержки. Рассматривайте вход линии задержки как выход для вашей таблицы.
Входами являются два входных сигнала уровня И выход линии задержки, поскольку выход играет роль во входном сигнале. В общей сложности у вас есть 3 «входа» для этой таблицы, что дает вам 8 комбинаций. Как только у вас будут требования к уровням в виде таблицы, решить задачу станет намного проще.
Реализовать поведение согласно таблице истинности:
| Input Save | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
| Input Value | 1₁ | 1₂ | 0₃ | 0₄ | 0 | 1 | 0₅ | 1₆ | 1₇ | 1 | 0 | 0₈ | 0₉ |
| Output | 0₀ | 1₁ | 1₂ | 0₃ | 0₄ | 0₄ | 0₄ | 0₅ | 1₆ | 1₇ | 1₇ | 1₇ | 0₈ |
Эта задача — про запоминание (1-битная память), реализованную через одну линию задержки. Это однобитный регистр с разрешением записи (write enable).
- Input Save — управляющий сигнал
- Input Value — значение, которое можно сохранить
- Delay — задержка на 1 такт (это и есть «память»)
- Output — всегда должен быть сохранённым значением
Поведение:
- Если Save = 1 → обновить сохранённое значение (запомни Value)
- Если Save = 0 → оставить старое значение
- Выход всегда показывает то, что сохранено
Линия задержки не держит значение “сама по себе”. Она каждый такт перезаписывается. Т.е. у нее нет постоянного хранилища, она каждый такт перезаписывается своим же значением но при условии что мы не даем сигнал сохранить новое значение.
Мы не вычисляем Output напрямую. Мы вычисляем что подать на вход Delay на следующем такте.
Обозначим:
- S = Save
- V = Value
- O = OldIn (выход delay)
- D = вход DelayIn (то, что считаем)
Таблица истинности для того, что должно поступать на линию задержки. Рассматриваем вход линии задержки как выход для вашей таблицы.
| Save (S) | Value (V) | OldIn (O) | DelayIn (D) |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 |
Из таблицы напрямую получается логическая функция:
- при Save=0 → DelayIn = OldIn
- при Save=1 → DelayIn = Value
DelayIn = (Save AND Value) OR (NOT Save AND OldIn)


Saving Bytes
Задача: Создать схему, которая может SAVE или LOAD байт.
Когда первый входной бит 1, LOAD память и пошлите её на выход.
Когда второй входной бит 1, SAVE входной байт.
У выхода есть активирующий контакт, активируйте его только если LOAD.
Это байтовая память на 1 ячейку (ОЗУ RAM (Random Access Memory) запись/чтение) с управлением:
Входы
- LOAD (бит) — читать сохранённое значение
- SAVE (бит) — записать новое значение
- DATA IN (байт) — что сохраняем
Выходы
- DATA OUT (байт) — сохранённое значение
- ENABLE (бит) — выход активен только при LOAD

Counter
tip
Разблокирует компонент: 8-bit Counter
Задача: Создайте счётчик, который будет увеличиваться на 1 при каждом такте.
Кроме того, должна быть предусмотрена возможность перезаписи счетчика заданным значением.
Вам даны два входных параметра: бит (MODE) и байт (INPUT_BYTE).
Входной бит (MODE) должен переключаться между подсчетом и перезаписью значением байта.
Каждый такт:
- если MODE = 0 → counter = counter + 1
- если MODE = 1 → counter = INPUT_BYTE
Где:
- MODE (бит) — выбирает режим
- INPUT_BYTE — значение для перезаписи
- counter хранится в регистре (delay byte + обратная связь)
Есть 3 сущности:
- Регистр → хранит counter
- Инкрементер → считает counter + 1
- MUX → выбирает, что писать в регистр
MUX
- Если select = 0 → на выход идёт первый вход (counter)
- Если select = 1 → на выход идёт второй вход (INPUT_BYTE)
Counter (www.falstad.com/circuit)

tip
Этот уровень сумирует наши предущие полученные знания для построения счетчика PC (Program Counter счётчик)
Необходимые знания для построния счетчика:
- полусумматор
- полный сумматор
- 8-битное сложение
- линии задержки
- D-триггеры
- регистры
- SAVE / LOAD
- счётчик (логически)
Little Box
tip
Разблокирует компонент памяти: 256 байтная ОЗУ RAM (Random Access Memory)
Можно ли уместить 4 байта в этом ограниченном пространстве?
Задача:
На этом уровне вы должны построить схему которая может [SAVE] или [LOAD] (показать (выдать) значение выбранного регистра на выход) из 4-х разных байтов памяти.
Вам даётся один быт который определяет нужно ли вам [LOAD]. Другой бит определяет нужно ли вам загружать [SAVE] и к нему прилагается значение.
Кроме того у вас есть 2 бита для адресас, что дает 4 комбинации, одна на каждый байт на этом уровне.
Для этого уровня вам, по сути, нужно создать четырехбайтовую оперативную память ((ОЗУ RAM (Random Access Memory) запись/чтение)) в ограниченном пространстве.
RAM 4×8 бит:
- 4 ячейки памяти
- каждая по 8 бит
- выбор ячейки по 2-битному адресу ADDR[1:0] — (00, 01, 10, 11)
- операции, декодер выбирает ровно один регистр:
- SAVE — при 1 записать байт в выбранную ячейку, при 0 не записывать
- LOAD — при 1 вывести байт из выбранной ячейки, при 0 не выводить
Для начала вам понадобятся четыре 8-битных регистра для независимого хранения и извлечения байтов.
- Соедините все выводы сохранения значений с входом, а все выводы вывода — с выходом.
- Подключите вывод загрузки к выводу разрешения выхода.
Далее соберите 2-битный декодер для активации одного из регистров за раз.
Наконец, используя восемь переключателей, создайте две шины, которые будут управлять выводами загрузки и сохранения регистров, и подключите их к соответствующим входам.
Соедините пары переключателей с соответствующими выходами декодера, и готово!

(Так же можно использовать компонент Switch вместо NOT + AND. Узел Switch можно использовать как логическое И, поскольку для его включения необходимо выполнение двух условий.)
2 bit decoder (2 to 4) нужен для выбора одного из четырех регистров
A B | addr
-------------
0 0 | 0001 D0
0 1 | 0010 D1
1 0 | 0100 D2
1 1 | 1000 D3
RAM 4×8 бит: