Справка

Всё, что нужно знать для начала работы.

Основы

Каждый уровень предлагает собрать логическую схему с заданным поведением. В левой части экрана — холст, куда вы перетаскиваете и соединяете компоненты. Справа — боковая панель с вкладками.

Вкладка «Задание» показывает задание текущего уровня: название, цель и таблицу истинности, которой должна соответствовать схема.

Сверху находится панель элементов (палитра) — оттуда перетаскиваются компоненты на холст. Слева от палитры — кнопки: ▶ (Запустить тест) для проверки схемы, (Очистить) для сброса, (Подсказка).

При нажатии схема проверяется по таблице истинности. Результат показывается под таблицей: какие строки совпали, а какие — нет. Если все тесты пройдены, появляется кнопка «Следующий уровень →».

Визуализация сигналов

Провода на холсте меняют цвет в зависимости от того, какой сигнал по ним идёт:

По активным проводам бегут точки потока — небольшие кружки, движущиеся вдоль линии. Они показывают направление передачи сигнала: от выхода одного элемента ко входу другого.

Входные узлы (Input / Bus Input) можно переключать прямо на холсте, не запуская тест. Кликните по кружку «0» на входе — он сменится на «1», сигнал мгновенно пробежит по всей цепи, и цвета всех проводов обновятся. Это полезно для отладки: можно вручную «подёргать» входы и посмотреть, как реагирует схема, не дожидаясь полной проверки.

Подсветка ошибок

При нажатии ▶ (Запустить тест) схема проверяется по таблице истинности. Если в какой-то строке ожидаемое значение на выходе не совпадает с фактическим:

Подсветка ошибок сохраняется до тех пор, пока вы не измените схему (добавите/удалите элемент или соединение) или не запустите тест заново. При успешном прохождении всех тестов подсветка автоматически снимается.

Вкладка «Инфо»

Справа находится вкладка «Инфо». Выделите любой компонент на холсте — его описание, категория и таблица истинности появятся в этой вкладке. Это удобный справочник: не нужно искать документацию — вся информация о вентиле перед вами.

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

Над таблицей истинности отображается временная диаграмма сигналов. Колонки разделены пунктирными линиями — каждый такт отдельно.

Наведите мышь на строку в нижней таблице — на диаграмме подсветится соответствующий столбец. Наведите мышь на столбец диаграммы — подсветится строка в таблице. Это помогает сопоставлять ожидаемые и фактические значения с временными отрезками.

Тактовый генератор

Начиная с 10-го уровня в правой панели появляется блок «Clock Control». Он управляет тактовым сигналом для схем с памятью и обратными связями.

Пошаговый режим () помогает понять, что делает схема: один щелчок — один такт. Автоматический режим () нужен, чтобы проверить стабильность работы во времени.

На уровне 16 появляется панель ассемблера для программирования процессора. Подробнее об ассемблере →

Управление

Подсказки

На каждом уровне доступны три уровня подсказок. Нажмите кнопку в панели инструментов. Третья подсказка покажет готовое решение.

Режимы

ИИ-Наставник

В правой боковой панели доступна вкладка «ИИ-Наставник» — ИИ-помощник, который анализирует вашу схему, находит ошибки и задаёт наводящие вопросы в сократическом стиле. Доступно 100 запросов в день.

Кнопки-шорткаты отправляют типовые запросы:

ИИ-Наставник может ошибаться. Не доверяйте ему слепо — перепроверяйте результаты.

Ассемблер (уровень 16)

Архитектура процессора

На 16-м уровне вы собираете 8-битный компьютер по гарвардской архитектуре с раздельной памятью команд и данных:

Панель ассемблера

При наличии ROM на схеме в правой панели появляется вкладка «Ассемблер». Она содержит:

Формат инструкции

Каждая инструкция — 1 байт. Старшие 4 бита (7:4) — opcode, младшие 4 бита (3:0) — operand (адрес 0–15).

 7 6 5 4  3 2 1 0
┌────────┬─────────┐
│ Opcode │ Operand │
└────────┴─────────┘

Система команд

МнемоникаOpcodeДействиеПример
NOP 0 No operation NOP0x00
ADD 1 Acc = Acc + RAM[X] ADD 30x13
SUB 2 Acc = Acc − RAM[X] SUB 70x27
AND 3 Acc = Acc & RAM[X] AND 10x31
OR 4 Acc = Acc | RAM[X] OR 20x42
LDA 5 Acc = RAM[X] LDA 50x55
STA 6 RAM[X] = Acc STA 100x6A
JMP 7 PC = X (безусловный переход) JMP 00x70
JZ 8 if Acc=0: PC = X (условный переход) JZ 70x87
HLT 15 Останов тактирования HLT0xF0

Правила синтаксиса

Пример программы: компиляция и выполнение

; Простейшая программа — 4 инструкции
LDA 5
ADD 3
STA 0
HLT

После нажатия ▶ Выполнить программа компилируется и сразу запускается. В панели лога появятся строки компиляции:

[AsmPanel] === Compile & Run ===
[Asm]  ROM[0] = 0x55  (LDA 5)
[Asm]  ROM[1] = 0x13  (ADD 3)
[Asm]  ROM[2] = 0x60  (STA 0)
[Asm]  ROM[3] = 0xf0  (HLT)
[Asm] Compile done: 4 instruction(s)
[Asm] ROM[0..3]: 0x55 0x13 0x60 0xf0

Затем — строки выполнения (только нечётные тики — rising edge):

[AsmPanel] PC=0, play
[CPU] Tick 1   PC=0  →  LDA 5   [0x55]
[CPU] Tick 3   PC=1  →  ADD 3   [0x13]
[CPU] Tick 5   PC=2  →  STA 0   [0x60]
[CPU] Tick 7   PC=3  →  HLT     [0xf0]
[HLT] PC=4 (prev=3) instruction=0xf0 → HALT detected, stopping

Важно: инициализация RAM

LDA 5 загружает значение из RAM[5], а не константу 5. Поскольку вся RAM при старте заполнена нулями, аккумулятор после LDA 5 будет равен 0. ADD 3 добавит RAM[3] = 0. Результат всегда 0.

Для осмысленной работы с данными инициализируйте RAM через консоль браузера (F12 → Console) перед нажатием «Выполнить»:

const ram = graph.findNodesByType('tc/RAM')[0];
ram.memory[5] = 5;   // RAM[5] = 5
ram.memory[3] = 3;   // RAM[3] = 3

После инициализации и выполнения LDA 5; ADD 3; STA 10; HLT в RAM[10] будет записано 8.

Пример: работа с данными

; Загрузить значение из RAM[10], удвоить, сохранить в RAM[11]
LDA 10    ; Acc = RAM[10]
ADD 10    ; Acc = Acc + RAM[10] = RAM[10] * 2
STA 11    ; RAM[11] = Acc
HLT

Пример: условный переход (JZ)

; Тест JZ: если аккумулятор = 0 — переход на адрес 5
LDA 0     ; Acc = RAM[0] = 0
ADD 0     ; Acc = 0 + 0 = 0 (Zero flag = 1)
JZ  5     ; Jump to addr 5 (срабатывает)
STA 15    ; ← пропускается
HLT       ; ← пропускается
NOP       ; адрес 5 — точка перехода
HLT       ; останов здесь

Чтение памяти через консоль

// Проверить содержимое RAM после выполнения программы
const ram = graph.findNodesByType('tc/RAM')[0];
console.log('RAM[10]:', ram.memory[10]);
console.log('RAM[11]:', ram.memory[11]);

// Проверить содержимое ROM после компиляции
const rom = graph.findNodesByType('tc/ROM')[0];
const hex = Array.from(rom.memory.slice(0, 8))
  .map(b => '0x' + b.toString(16).padStart(2, '0')).join(' ');
console.log('ROM[0..7]:', hex);

Как выполняется инструкция (2 тика на команду)

Каждая инструкция занимает ровно два такта Clock. На первом (фронт 0→1) происходит выборка и выполнение, на втором (спад 1→0) — фиксация результата:

Тик N   (0→1): PC выдаёт адрес → ROM → Splitter → Decoder → ALU/RAM
                  Результат готов, но ещё не записан в регистры.

Тик N+1 (1→0): Регистры захватывают данные. PC не меняется.

Именно поэтому в логе инструкции отображаются только на нечётных тиках (1, 3, 5, …) — это rising edge, когда инструкция реально выполняется.

Что пишется в лог-панель

ПрефиксКогда появляется
[Asm]Компиляция: каждая инструкция и итоговый дамп ROM
[AsmPanel]Нажатие ▶ Выполнить — этапы компиляции и запуска
[CPU]Каждый нечётный тик — выполняемая инструкция
[HLT]Обнаружение HALT — тактирование остановлено

Лог очищается при каждом нажатии ▶ Выполнить перед компиляцией. История между запусками не сохраняется.

Пример: безусловный переход (JMP)

; Бесконечный цикл между адресами 2 и 3
LDA 0
STA 15
JMP 2     ; ← возврат на JMP (цикл)
HLT       ; никогда не выполнится

Программа зациклится — HLT не сработает. Нажмите ⏸ Pause на панели Clock Control для остановки. В логе убедитесь, что PC зацикливается на 2.

Пример: трассировка данных

При RAM[10] = 7 (установлено через консоль):

LDA 10    ; Acc = RAM[10]
ADD 10    ; Acc = Acc + RAM[10] = RAM[10] * 2
STA 11    ; RAM[11] = Acc
HLT
ТикPCИнструкцияАккRAM[10]RAM[11]
10LDA 10770
31ADD 101470
52STA 1114714
7HLT

Горячие клавиши

КлавишаДействие
F9Запустить проверку уровня
F12Открыть консоль разработчика
DeleteУдалить выделенный элемент

Известные ограничения