Разница между блокирующим и неблокирующим назначением Verilog


15

Я читал эту страницу http://www.asic-world.com/verilog/verilog_one_day3.html, когда наткнулся на следующее:

Обычно мы должны сбрасывать триггеры, поэтому каждый раз, когда часы переходят от 0 к 1 (позиция), мы проверяем, установлен ли сброс (синхронный сброс), затем мы продолжаем с нормальной логикой. Если мы посмотрим внимательнее, то увидим, что в случае комбинационной логики у нас было «=» для присваивания, а для последовательного блока у нас был оператор «<=». Ну, «=» - это блокирующее назначение, а «<=» - это неблокирующее назначение. «=» выполняет код последовательно внутри начала / конца, тогда как неблокирующая «<=» выполняется параллельно.

Я был совершенно уверен, что неблокирующие назначения были последовательными, в то время как блокирующие назначения были параллельными. В конце концов, вы можете делать блокирующие присваивания с помощью операторов присваивания вне блоков всегда, и все они выполняются параллельно. Это ошибка, или поведение внутри блока всегда отличается? И, если поведение внутри блока всегда отличается, могут ли быть сделаны неблокирующие назначения вне блока всегда?

Ответы:


21

был вполне уверен, что неблокирующие назначения были последовательными, в то время как блокирующие назначения были параллельными.

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

Неблокирующее назначение выполняется параллельно, потому что оно описывает назначения, которые все выполняются одновременно. Результат выписки во 2-й строке не будет зависеть от результатов выписки в 1-й строке. Вместо этого 2-я строка будет выполняться так, как если бы 1-я строка еще не произошла.


Так что насчет присваивания? Они просто в своем классе?
Пустая Звезда

4
Да, assignоператоры встречаются вне всегда блоков и обычно используются для описания комбинаторной (незапираемой) логики (в то время как всегда блоки, за некоторыми исключениями, описывают последовательную логику). AFAIK, assignоператоры всегда выполняются «параллельно» всякий раз, когда их LHS изменяет значение.
Фотон

Хорошо ... У меня начинает складываться впечатление, что Verilog не самый элегантный язык. Это будет похоже на изучение C.
Void Star

1
Verilog был разработан, чтобы «описать» аппаратное обеспечение, которое уже существует. Использование его в качестве языка для проектирования (синтеза) аппаратных средств - взлом.
Фотон

4
если Verilog "как изучение C" является проблемой, взгляните на VHDL. У некоторых людей довольно сильные предпочтения по отношению к одному или другому. Для некоторых VHDL слишком многословен. Для меня это гораздо лучше продумано. (семантика присвоения сигнала / переменной, например, намного более ясна, чем блокировка / отсутствие). stackoverflow.com/questions/13954193/… и sigasi.com/content/vhdls-crown-jewel Вы можете предпочесть это или ненавидеть. Но это стоит посмотреть.
Брайан Драммонд

6

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

Назначение блокировки вступает в силу сразу же после его обработки. Неблокирующее присвоение происходит в конце обработки текущей «дельты времени».

Блоки всегда могут использоваться для моделирования комбинаторной или последовательной логики (systemverilog имеет Always_comb и Always_ff, чтобы сделать это явным). При моделировании комбинаторной логики обычно более эффективно использовать =, но обычно это не имеет значения.

При моделировании последовательной логики (например, всегда @ (posedge clk)) вы обычно используете неблокирующие выражения. Это позволяет определить «состояние после фронта часов» в терминах «состояние до фронта часов».

Иногда полезно использовать блокирующие назначения в последовательных блоках всегда как «переменные». Если вы сделаете это, то должны помнить о двух ключевых правилах.

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

Нарушение этих правил может привести к сбоям синтеза и / или поведенческим различиям между симуляцией и синтезом.


«Не получайте доступ к регистру, который установлен с помощью назначений блокировки внутри последовательного блока всегда снаружи блока всегда, в котором он назначен». «Не могли бы вы объяснить это?
user125575

Различные последовательные блоки всегда не имеют определенного порядка. Таким образом, чтение набора «reg» с блокировкой в ​​одном блоке всегда из другого блока всегда приведет к непредсказуемому поведению.
Питер Грин

И даже если кажется, что он работает в симуляции, инструмент синтеза должен посмотреть на это и сказать «Нет». Я использую локальные регистры для этих промежуточных переменных и проверяю, чтобы они всегда присваивались на каждом такте перед чтением, чтобы не подразумевалось «хранилище».
Грегго

IIRC, по крайней мере, в квартусе, считается только предупреждением, а не ошибкой.
Питер Грин

5

Термин « блокирующее назначение» сбивает с толку людей, поскольку кажется, что слово « блокировка» предполагает последовательную логику. Но в синтезированной логике это не означает , что все работает параллельно .

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

С юридической точки зрения все работает очень хорошо. Вы можете, на самом деле, рассмотрим =быть блокирование (время последовательного) операции даже в пределах always_combпоследовательностей. Тем не менее, различие между последовательным по времени и параллельным не делает абсолютно никакой разницы в этом случае, потому что always_combблок определен для повторения до тех пор, пока последовательность команд не сойдет в стабильное состояние - что именно и будет делать аппаратная схема (если она соответствует времени требования).

Синтезируемое подмножество Verilog (и особенно SystemVerilog) чрезвычайно просто и легко в использовании - если вы знаете необходимые идиомы. Вы просто должны отказаться от умного использования терминологии, связанной с так называемыми поведенческими элементами в языке.


В поведенческих стилях кодирования ( по сравнению с RTL ) может иметь значение различие между блокированием и неблокированием. В некоторых случаях инструмент синтеза может быть в состоянии вывести функционально эквивалентные RTL из конструкций поведенческих компонентов.
Нобар

Конечно, процедурный режим SystemVerilog, особенно применимый к initialоператорам внутри programблоков, использует (последовательное по времени) назначение блокировки исключительно. Это полезно для разработки тестового стенда , но обычно не для спецификации RTL.
Нобар
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.