Открыть сервис

Неблокирующее присваивание

Неблокирующее присваивание (англ. 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). Неблокирующее присваивание обрабатывается следующим образом:

  1. Вычисление: на этапе активных событий вычисляется значение правой части выражения.
  2. Планирование: создаётся событие обновления для левой части, которое помещается в очередь неблокирующих присваиваний (NBA-регион).
  3. Обновление: после завершения всех активных и реактивных событий текущего временного шага, все запланированные неблокирующие присваивания выполняются одновременно.

Этот механизм гарантирует, что при чтении переменной в том же временном шаге (например, в другом блоке 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 →