Неблокирующее или блокирующее назначение для буфера?

Я пытаюсь реализовать небольшой строчный буфер в Verilog. Я помещаю данные с одного конца и читаю с другого.

wire [29:0] temp_pixel;
reg  [29:0] temp_buffer[2:0];

Я могу использовать такие операторы блокировки, и они должны работать должным образом.

always @(posedge TD_CLK27)
begin
temp_buffer[0] = temp_buffer[1];
temp_buffer[1] = temp_buffer[2];
temp_buffer[2] = temp_pixel;
end

Но могу ли я использовать неблокирующие операторы (показанные ниже) и при этом получить ожидаемый результат? Или temp_buffer [1] будет перезаписан temp_buffer [2], прежде чем он будет прочитан в temp_buffer [0]?

always @(posedge TD_CLK27)
begin
temp_buffer[0] <= temp_buffer[1];
temp_buffer[1] <= temp_buffer[2];
temp_buffer[2] <= temp_pixel;
end

Будут ли оба блока работать одинаково, или это обязательно должно блокировать операторы присваивания и почему?


person Jay K    schedule 12.04.2014    source источник
comment
Ни один из этих примеров не создает буферов. Первый создает 1 триггер, второй - 3 триггера.   -  person N8TRO    schedule 13.04.2014
comment
@ N8TRO Не могли бы вы прояснить, как он создает один шлепок?   -  person Jay K    schedule 13.04.2014


Ответы (2)


Оба блока разные.

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

 x = #5 y + z;

Этот оператор выполняется следующим образом:

  1. Вычисляет выражение RHS и сохраняет результат
  2. Дождитесь указанной задержки
  3. Выполнить задание

Таким образом, в вашем случае нет задержки при назначении ваших буферов, которые вы создали, и verilog интерпретирует это как один триггер.

x <= y + z;

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

  1. Оцените выражение RHS и сохраните результат во временном буфере.
  2. Завершить выполнение всех других событий в процедурном блоке, кроме других неблокирующих назначений.
  3. Выполните задание в конце.

Итак, во втором примере temp_buffer[2] получает предыдущее значение temp_buffer[1]. Таким образом, существует задержка цикла, до которой вы можете получить доступ к значению. так что перед получением фактического результата существует ряд триггеров (в зависимости от вашего кода).

Опять же, ссылка в предыдущем ответе - отличный документ для чтения. Есть еще несколько Sunburst Design Link2

person chitranna    schedule 13.04.2014

Этот минимальный пример блокировки, обратите внимание на =:

module test(
input  data_in, clk,
output data_out
);

reg [2:0] temp;

always @(posedge clk)
begin
   temp[2] = data_in;
   temp[1] = temp[2];
   temp[0] = temp[1];
end

assign data_out = temp[0];

endmodule

создает 1 триггер:

1 шлепок

Хотя неблокирует, обратите внимание на <=:

module test(
input  data_in, clk,
output data_out
);

reg [2:0] temp;

always @(posedge clk)
begin
   temp[2] <= data_in;
   temp[1] <= temp[2];
   temp[0] <= temp[1];
end

assign data_out = temp[0];

endmodule

создает 3 триггера:

3 шлепанца

Буферы создаются так:

module test(
input  data_in, clk,
output data_out
);

wire [2:0] temp;

   buf(temp[2], data_in);
   buf(temp[1], temp[2]);
   buf(temp[0], temp[1]);

assign data_out = temp[0];

endmodule

введите описание изображения здесь

Дополнительная информация здесь.

person N8TRO    schedule 13.04.2014