我正在尝试在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
这两个块是否一致,或强制必须阻止赋值语句,为什么?
答案 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个触发器:
非阻止时,请注意<=
:
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个触发器:
缓冲区的创建方式如下:
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
更多信息here.
答案 1 :(得分:3)
两个块都不同。
使用阻止分配时,在分配完成之前,下一个语句不会开始执行。
x = #5 y + z;
此声明按如下方式执行:
因此,在您的情况下,在分配您创建的缓冲区时没有延迟,并且verilog会将其解释为单个触发器。
x <= y + z;
正常的非阻塞分配执行如下:
因此,在您的第二个示例中,temp_buffer[2]
获取前一个值temp_buffer[1]
。因此,有一个循环延迟,您可以在此之前访问该值。所以在得到实际输出之前有一串触发器(取决于你的代码)。
同样,之前答案中的链接是一篇很好的文章,可以阅读。还有一些 Sunburst Design Link2