这篇博客,通过举例说明:非阻塞赋值和阻塞赋值的区别?

一般非阻塞赋值用于时序逻辑,而阻塞赋值用于组合逻辑;

非阻塞赋值语句是并行执行的,等到一个时钟完成后才完成赋值,而阻塞赋值是顺序执行的,下一条赋值语句要等到上一条赋值语句完成后才能赋值,并且阻塞赋值是立即完成的;

例如:


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 的赋值运算符