缓冲区的非阻塞或阻止分配?

时间:2014-04-12 20:11:13

标签: buffer verilog fpga fifo

我正在尝试在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 [0]之前被temp_buffer [2]覆盖吗?

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

这两个块是否一致,或强制必须阻止赋值语句,为什么?

2 个答案:

答案 0 :(得分:6)

这个阻止的最小示例,请注意=

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 Flip-Flop

非阻止时,请注意<=

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 Flip-Flops

缓冲区的创建方式如下:

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

enter image description here

更多信息here.

答案 1 :(得分:3)

两个块都不同。

使用阻止分配时,在分配完成之前,下一个语句不会开始执行。

 x = #5 y + z;

此声明按如下方式执行:

  1. 评估RHS表达式并保存结果
  2. 等待指定的延迟
  3. 执行作业
  4. 因此,在您的情况下,在分配您创建的缓冲区时没有延迟,并且verilog会将其解释为单个触发器。

    x <= y + z;
    

    正常的非阻塞分配执行如下:

    1. 评估RHS表达式并将结果保存在临时缓冲区中
    2. 完成执行程序块中除了其他非阻塞分配之外的所有其他事件
    3. 最后执行作业。
    4. 因此,在您的第二个示例中,temp_buffer[2]获取前一个值temp_buffer[1]。因此,有一个循环延迟,您可以在此之前访问该值。所以在得到实际输出之前有一串触发器(取决于你的代码)。

      同样,之前答案中的链接是一篇很好的文章,可以阅读。还有一些 Sunburst Design Link2