Verilog的阻塞赋值和非阻塞赋值

"令人挠头"

Posted by LiYanXin on August 1, 2018

Blocking vs. Non-Blocking Assignment round1

There are three types of assignments in Verilog:

1
2
3
Continuous assignments (assign x = y;). Can only be used when not inside a procedure ("always block").
Procedural blocking assignment: (x = y;). Can only be used inside a procedure.
Procedural non-blocking assignment: (x <= y;). Can only be used inside a procedure.

In a combinational always block, use blocking assignments. In a clocked always block, use non-blocking assignments.

总结是,连续性赋值 assign语句只能在always块外部写,过程性赋值包括阻塞赋值(x = y)和非阻塞赋值(x <= y),可以出现在always块中。 那么阻塞性赋值和非阻塞性赋值的区别是什么呢?

Blocking vs. Non-Blocking Assignment round2

阻塞:在进程语句块中(initial或者always或者其他),当前赋值语句的执行阻塞了后面语句的执行。 即后面语句的赋值需要等到当前赋值过程完成才能得以执行,即可认为执行过程是顺序执行的(我们要明白Verilog中,大多数情况模块都是并发执行的)。

非阻塞:当前赋值语句的执行不会阻塞后续语句的执行,即可以认为当前赋值语句的完成和后续的执行过程是并发执行的。

1
2
3
4
5
6
7
8
9
10
11
12
13
   下面通过一个例子说明:

	initial              |           initial
	begin                |           begin
	b=a;                 |            b<=a;
	c=b;                 |            c<=b;
	end                  |           end             

上述左侧为阻塞赋值,右侧为非阻塞赋值;

 左侧代码中,当b=a执行完之后,即b的值已经变成了a;此时,c的值被赋给b的值,实际上,c的值就是a的值了,即c=b=a;

 而右侧代码,b被赋给a的值,c被赋给b的值同时发生,即c得到得到的b的值,并非是改变后的b的值,而是b没有改变之前的原来的值。