Блокирующие / неблокирующие назначения являются только артефактом моделирования. Вопреки мнению, Verilog не описывает аппаратное обеспечение. Verilog описывает желаемое поведение оборудования, пытающегося встроить его в управляемую событиями схему моделирования.
Вот простой пример регистра сдвига, который использует 2 флопа:
always @(posedge clk)
out1 = in;
always @(posedge clk)
out2 = out1;
Теперь, каким будет выход out2? Поскольку мы имеем дело с симуляцией, то это зависит от порядка выполнения этих двух операторов. Либо это будет старое значение out1, либо новое (фактически значение in);.
В оборудовании такого беспорядка нет. Он будет сбрасывать значение, существовавшее в заданное время, значение old out1 (ну, если нет необычных задержек в часах).
Для того, чтобы соответствовать этому поведению, не -блокирующее назначение было введено. Verilog симуляция выполняется в тиках симуляции. Каждый тик до тех пор, пока есть события, которые могут вызвать переоценку других блоков. Неблокирующие назначения запланированы к выполнению в конце такого тика с текущими значениями rhs (в действительности существует несколько зон планирования). Итак, рассмотрим следующее:
always @(posedge clk)
out1 <= in;
always @(posedge clk)
out2 <= out1;
В приведенном выше примере все назначения произойдут в конце тика. 'out2` будет присвоено значение, которое существовало во время <=, поэтому это будет старое значение out1. Теперь не имеет значения, в каком порядке они выполняются. </p>
Итак, рекомендация верхнего уровня состоит в том, чтобы использовать блокирующие назначения (=) для комбинационных логик c и использовать неблокирующие назначения (<=) для всех выходов состояния устройств, флопов и защелок. Обратите внимание, что некоторые временные переменные внутри устройств состояния, которые используются только для внутренних целей, также должны быть назначены с блокировкой. Кроме того, никогда не используйте неблокирующие назначения в деревьях часов. </p>