这篇博客,通过举例说明:非阻塞赋值和阻塞赋值的区别?
一般非阻塞赋值用于时序逻辑,而阻塞赋值用于组合逻辑;
非阻塞赋值语句是并行执行的,等到一个时钟完成后才完成赋值,而阻塞赋值是顺序执行的,下一条赋值语句要等到上一条赋值语句完成后才能赋值,并且阻塞赋值是立即完成的;
例如:
always@(posedge clk) begin
b <= a;
c <= b;
end
可见,在时序逻辑中使用非阻塞赋值会生成触发器。(有几条赋值语句就会生成几个触发器)
如果使用阻塞赋值呢?
如:
always@(posedge clk) begin
b = a;
c = b;
end
可以看到区别,第一条语句生成了一个触发器,第二条语句会综合成一个连线,这就是阻塞赋值与非阻塞赋值的区别。
为了更有说服力,再举一个例子:
always@(posedge clk) begin
c = a&b;
d = c;
end
可见,第二条赋值同样综合出来是一条连线。
作为对比,再用非阻塞赋值来看:
always@(posedge clk) begin
c <= a&b;
d <= c;
end
可见,非阻塞赋值综合出来的电路是触发器;
在秋招面试以及笔试中,会经常被问道,如果在组合逻辑使用非阻塞赋值会怎么样?
我们刚刚实验了在时序逻辑中使用阻塞赋值会怎么样?也该看看在组合逻辑中使用非阻塞赋值是什么情况了?
如:
always@(*) begin
b <= a;
c <= b;
end
假如用阻塞赋值:
可见,和使用阻塞赋值没什么区别。
同样,为了更有说服力,再举一个例子:在赋值的同时做了运算。
always@(*)begin
c <= a & b;
d <= c;
end
有了上面的讨论,也应该能猜到综合出来的电路和阻塞赋值没什么区别。
我们可以这么说,在时序逻辑中,使用阻塞赋值,会出现意料之外的结果;
在组合逻辑中,使用非阻塞赋值,则和使用阻塞赋值没什么区别。
最后,为了让代码规范无误,我们一定要遵循规则,在时序逻辑中使用非阻塞赋值,在组合逻辑中使用阻塞赋值。
相关链接:
【Verilog HDL】赋值语句之阻塞赋值方式与非阻塞赋值方式
【 Verilog HDL 】进一步了解 Verilog HDL 的赋值运算符