Кремний вместо кода: почему Verilog — это не программирование

Ты уже умеешь писать код. Скорее всего, ты знаешь, что такое переменные, циклы for, массивы и условия if/else. Ты привык отдавать компьютеру команды, и он послушно выполняет их одну за другой.

Но на этом уровне симулятора твои программистские рефлексы сыграют с тобой злую шутку. Потому что Verilog — это вообще не язык программирования.

Да, он выглядит как текст. В нём есть скобочки, запятые и точка с запятой в конце строки. Но когда ты пишешь на Verilog, ты не создаешь алгоритм. Ты буквально чертишь схему спайки проводов.

Добро пожаловать в мир HDL — Hardware Description Language (Языков описания аппаратуры).

Главный секрет: здесь нет времени

Вспомни, как работает любой код на Python или C++.

x = 5       # Шаг 1
y = x + 2   # Шаг 2
print(y)    # Шаг 3

Компьютер выполняет строку 1, затем переходит к строке 2, а потом к строке 3. Это последовательный процесс.

В Verilog (и в физическом процессоре) все строки "работают" одновременно. Если ты написал в коде вызов трёх логических вентилей, это не значит, что сначала сработает первый, а потом второй. Это значит, что завод напечатает на куске кремния три микросхемы, соединит их медью, и при подаче тока они все будут работать параллельно.

Анатомия чипа: как устроен код

Давайте соберем простую схему. Допустим, мы делаем замок сейфа (SafeLock), который откроется (open), только если вставлен ключ (key) И при этом не сработала сигнализация (alarm).

В мире железа любая программа — это микросхема (модуль). У неё есть пластиковый корпус и торчащие металлические ножки (пины).

module SafeLock(
    input wire key,       // Входящий пин (вставлен ли ключ)
    input wire alarm,     // Входящий пин (воет ли сирена)
    output wire open      // Выходящий пин (открыть замок)
);

Обратите внимание на слово wire. С английского оно переводится как «провод». Пиша input wire, вы буквально говорите: "Я припаял медный провод ко входу моей микросхемы".

Паяем логику

Чтобы замок открылся, нам нужна логика: КЛЮЧ И (НЕ СИГНАЛИЗАЦИЯ). Нам понадобятся два логических вентиля: not (инвертор) и and (логическое И).

В классическом программировании мы бы написали open = key and not alarm. Но в структурном Verilog мы работаем руками — мы вызываем конкретные детали со склада и соединяем их выводы.

Но как передать сигнал от инвертора к вентилю И? Нам понадобится внутренний провод.

module SafeLock(
    input wire key,
    input wire alarm,
    output wire open
);

    // 1. Отрезаем кусок внутреннего провода. 
    // Он не торчит наружу микросхемы, он спрятан внутри.
    wire safe_alarm; 

    // 2. Ставим инвертор. 
    // Синтаксис вызова: название_детали имя_на_плате(выход, вход);
    not inv1(safe_alarm, alarm); 

    // 3. Ставим вентиль И. 
    // Подключаем к нему ключ и наш внутренний провод. Результат отдаем наружу.
    and and1(open, key, safe_alarm);

endmodule

Разбор полетов

Посмотри на код выше. Что выполнится раньше: not или and? Ответ: ничто. Это просто чертеж.

Когда ты нажмешь кнопку «Синтезировать», симулятор прочитает этот текст и отрисует схему: возьмет вход alarm, пустит его через вентиль not, результат пустит по медному проводу safe_alarm ко входу вентиля and, а ко второму входу подключит провод key.

Золотое правило Verilog: Пиша код, представляй, что у тебя в одной руке паяльник, а в другой — моток проводов. Ты не приказываешь процессору, что делать. Ты создаешь процессор.

На уровне 30 тебе предстоит применить этот подход впервые. Тебе нужно будет собрать вентиль Исключающее ИЛИ (XOR), используя только базовые элементы. Готовь паяльник — мы переходим на кремний.