Неблокирующее присваивание¶
Неблокирующее присваивание (англ. non-blocking assignment, NBA) — это механизм присваивания значений сигналам в языках описания аппаратуры (HDL), таких как Verilog и SystemVerilog, при котором присваивание не выполняется немедленно, а откладывается до конца текущего временного шага симуляции. В отличие от блокирующего присваивания (blocking assignment), неблокирующее присваивание позволяет моделировать параллельную работу аппаратных регистров и триггеров, избегая состояния гонки и неопределённого поведения при описании синхронных цифровых схем.
¶Основные характеристики
Неблокирующее присваивание обозначается оператором <= (в отличие от блокирующего =). При выполнении такого оператора в процессе симуляции вычисляется значение правой части выражения, но присваивание левой части откладывается до конца текущего временного шага. Это означает, что все неблокирующие присваивания, выполняемые в одном временном шаге, обрабатываются одновременно, что соответствует поведению реальных регистров, обновляющих свои состояния по фронту тактового сигнала.
Ключевые особенности:
- Отложенное выполнение: присваивание происходит после завершения всех активных событий текущего временного шага.
- Параллельная семантика: несколько неблокирующих присваиваний, выполняемых в одном блоке
always, обрабатываются как одновременные. - Использование в синхронных схемах: NBA является стандартным способом описания поведения регистров и триггеров, управляемых тактовым сигналом.
¶История
Механизм неблокирующего присваивания был введён в языке Verilog (стандарт IEEE 1364) в 1995 году как часть спецификации языка. До этого симуляция цифровых схем на Verilog сталкивалась с проблемами недетерминизма при использовании блокирующего присваивания в синхронных блоках. Введение NBA позволило моделировать параллельное обновление регистров, что критически важно для корректного описания конвейерных и многостадийных схем. В последующих версиях стандарта (Verilog 2001, SystemVerilog) механизм был расширен и уточнён, включая правила для смешанного использования блокирующих и неблокирующих присваиваний.
¶Синтаксис и правила использования
¶Оператор присваивания
В Verilog и SystemVerilog неблокирующее присваивание записывается как: `` reg_a <= expression; ` где reg_a — переменная типа reg или logic, а expression` — любое допустимое выражение.
¶Контекст применения
NBA обычно используется внутри блоков always, чувствительных к фронту тактового сигнала (например, always @(posedge clk)). В таких блоках все присваивания должны быть неблокирующими, чтобы избежать состояния гонки. В комбинационных блоках (например, always @(*)) рекомендуется использовать только блокирующее присваивание, так как NBA может привести к неожиданному поведению при моделировании.
¶Правила смешивания
Смешивание блокирующих и неблокирующих присваиваний в одном блоке always не рекомендуется, так как это может привести к недетерминизму. Стандарт IEEE 1364-2001 определяет, что порядок выполнения блокирующих и неблокирующих присваиваний в одном блоке не определён, что может привести к различным результатам в разных симуляторах.
¶Механизм работы в симуляции
Симуляция Verilog/SystemVerilog использует событийно-управляемую модель. Временной шаг делится на несколько фаз (регионов), определённых стандартом IEEE 1800 (SystemVerilog). Неблокирующее присваивание обрабатывается следующим образом:
- Вычисление: на этапе активных событий вычисляется значение правой части выражения.
- Планирование: создаётся событие обновления для левой части, которое помещается в очередь неблокирующих присваиваний (NBA-регион).
- Обновление: после завершения всех активных и реактивных событий текущего временного шага, все запланированные неблокирующие присваивания выполняются одновременно.
Этот механизм гарантирует, что при чтении переменной в том же временном шаге (например, в другом блоке always) будет использовано старое значение до обновления, что соответствует поведению синхронных регистров.
¶Примеры
¶Пример 1: Сдвиговый регистр
``verilog module shift_register ( input clk, input rst, input data_in, output reg [3:0] q ); always @(posedge clk or posedge rst) begin if (rst) q <= 4'b0000; else begin q[0] <= data_in; q[1] <= q[0]; q[2] <= q[1]; q[3] <= q[2]; end end endmodule ` В этом примере все присваивания неблокирующие, поэтому значения сдвигаются одновременно: на каждом такте q[1] получает старое значение q[0]`, а не новое, что соответствует работе аппаратного сдвигового регистра.
¶Пример 2: Ошибка при использовании блокирующего присваивания
``verilog // Неправильно: блокирующее присваивание в синхронном блоке always @(posedge clk) begin a = b; b = a; // a уже обновлено, поэтому b получит новое a, а не старое end ` При использовании блокирующего присваивания b получит значение b (так как a` уже обновлено), что не соответствует параллельной работе регистров. Исправление — замена на неблокирующее присваивание.
¶Применение
Неблокирующее присваивание является стандартом де-факто при описании синхронных цифровых схем на Verilog и SystemVerilog. Оно используется в проектировании:
- Регистров и триггеров: описание D-триггеров, сдвиговых регистров, счётчиков.
- Конвейерных архитектур: моделирование многостадийных конвейеров, где данные передаются между стадиями по тактам.
- Синтезируемых RTL-модулей: все синтезируемые блоки, чувствительные к фронту тактового сигнала, должны использовать NBA для корректного синтеза.
- Тестовых окружений: в тестбенчах NBA может использоваться для моделирования задержек и параллельных событий.
¶Сравнение с блокирующим присваиванием
| Характеристика | Блокирующее присваивание (=) | Неблокирующее присваивание (<=) |
|---|---|---|
| Время выполнения | Немедленно, в порядке следования | Откладывается до конца временного шага |
| Семантика | Последовательная | Параллельная |
| Типичное применение | Комбинационная логика | Синхронные регистры |
| Риск состояния гонки | Высокий в синхронных блоках | Низкий |
| Синтезируемость | Да, для комбинационных схем | Да, для синхронных схем |
¶Критика и ограничения
Несмотря на широкое распространение, неблокирующее присваивание имеет ряд ограничений:
- Сложность отладки: из-за отложенного выполнения может быть сложно отследить последовательность событий в симуляции.
- Неправильное использование в комбинационных блоках: применение NBA в комбинационной логике может привести к несинтезируемому коду или неожиданным задержкам.
- Производительность симуляции: обработка очереди неблокирующих присваиваний требует дополнительных ресурсов, что может замедлить симуляцию больших схем.
- Ограничения в некоторых стилях кодирования: в некоторых методологиях (например, при использовании системных функций Verilog) NBA может быть неудобным.
¶Интересные факты
- В языке VHDL аналогом неблокирующего присваивания является оператор
<=для сигналов, который также откладывает обновление до конца процесса. - Стандарт SystemVerilog ввёл дополнительное понятие «блокирующего присваивания с задержкой» (delay control), которое может имитировать поведение NBA.
- Некоторые симуляторы позволяют настраивать порядок обработки неблокирующих присваиваний для повышения производительности, что может нарушить совместимость.
¶Источники
- IEEE Standard for Verilog Hardware Description Language (IEEE Std 1364-2001)
- IEEE Standard for SystemVerilog—Unified Hardware Design, Specification, and Verification Language (IEEE Std 1800-2017)
- Sutherland, S. (2002). The Verilog PLI Handbook. Kluwer Academic Publishers.
- Thomas, D. E., & Moorby, P. R. (2002). The Verilog Hardware Description Language. Springer.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →


