Как понять блокирующие и неблокирующие операторы в verilog? - PullRequest
0 голосов
/ 01 февраля 2020

Я понял основную разницу c между блокирующими и неблокирующими операторами в Verilog. Но все же я не могу понять, что происходит &, когда и где использовать блокирующие и неблокирующие операторы. Например, рассмотрим простой код dff:

module dff (clk, reset,d, q, qb);
input      clk;
input      reset;
input      d;
output     q;
output     qb;

reg        q;

assign qb = ~q;

always @(posedge clk or posedge reset)
begin
  if (reset) begin
    // Asynchronous reset when reset goes high
    q <= 1'b0;
  end else begin
    // Assign D to Q on positive clock edge
    q <= d;
  end
end
endmodule

Но если я напишу те же самые логи c, используя технику двухсегментного кодирования:

module dff(input wire d,
           clk,
           reset,
           en,
           output wire q);

reg q;
reg r_reg, r_next;

always @(posedge clk, posedge reset)
if(reset) 
  r_reg<=1'b0;
else
  r_reg<=r_next;

always @*
  if(en)
    r_reg=d;
  else
    r_reg=r_next;

assign q<=r_reg;
endmodule

Теперь в этом коде Я просто не понимаю, почему в первом блоке всегда используется <= и почему во втором блоке всегда используется =. Я также знаю, что в комбинационной логике c схема = рекомендуется использовать & в последовательном <=, что рекомендуется использовать. Но все же я не смог найти ответ на использование блокирующих и неблокирующих операторов. Можете ли вы помочь мне!?

1 Ответ

1 голос
/ 01 февраля 2020

Блокирующие / неблокирующие назначения являются только артефактом моделирования. Вопреки мнению, 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>

...