更新时间:2023-05-27 16:16
非阻塞赋值操作符用小于等于号(即<=)表示,由时钟节拍决定,在时钟上升到来时,执行赋值语句右边,然后将begin-end之间的所有赋值语句同时赋值到赋值语句的左边。非阻塞赋值允许其他的Verilog语句同时进行操作。
非阻塞赋值操作符用小于等于号(即<=)表示。为在赋值操作时刻开始时计算非阻塞赋值符的RHS表达式,赋值操作时刻结束时更新LHS。在计算非阻塞赋值的RHS表达式和更新LHS期间,其他的Verilog语句,包括其他的Verilog非阻塞赋值语句都能同时计算RHS表达式和更新LHS。非阻塞赋值允许其他的Verilog语句同时进行操作。
非阻塞赋值是由时钟节拍决定,在时钟上升到来时,执行赋值语句右边,然后将begin-end之间的所有赋值语句同时赋值到赋值语句的左边,注意:是begin—end之间的所有语句,一起执行,且一个时钟只执行一次。
主要是下面两个要点:
(1)在描述组合逻辑的always块中用阻塞赋值,则综合成组合逻辑的电路结构:
(2)在描述时序逻辑的always块中用非阻塞赋值,则综合成时序逻辑的电路结构。
为什么一定要这样做呢?这是因为要使综合前仿真和综合后仿真一致的缘故。如果不按照上面两个要点来编写Verilog代码,也有可能综合出正确的逻辑,但前后仿真的结果就会不一致。
为了更好地理解上述要点,需要对Verilog语言中的阻塞赋值和非阻塞赋值的功能和执行时间上的差别有深入的了解。为了解释问题方便,下面定义两个缩写字:
RHS——方程式右手方向的表达式或变量可分别缩写为RHS表达式或RHS变量;
LHS——方程式左手方向的表达式或变量可分别缩写为LHS表达式或LHS变量。
IEEEVerilog标准定义了有些语句有确定的执行时间,有些语句没有确定的执行时间。若有两条或两条以上语句准备在同一时刻执行,但由于语句的排列顺序不同(而这种排列顺序的不同是IEEEVerilog标准所允许的),却产生了不同的输出结果。这就是造成Verilog模块冒险和竞争现象的原因。
非阻塞赋值的操作可以看作为两个步骤的过程;
(1)在赋值时刻开始时,计算非阻塞赋值RHS表达式;
(2)在赋值时刻结束时,更新非阻塞赋值LHS表达式。
在状态变量的赋值或开关变量的赋值中,已明确建议大家使用非阻塞赋值。这不但是因为综合工具要求这样做,最根本的原因是与非阻塞赋值语句语意对应的电路结构正是我们想要实现的。这两种赋值语句对应着两种不同的电路结构。阻塞赋值对应的电路结构往往与触发沿没有关系,只与输入电平的变化有关系。而非阻塞赋值对应的电路结构往往与触发沿有关系,只有在触发沿时才有可能发生赋值的情况。
阻塞和非阻塞赋值的区别在阻塞是顺序执行而非阻塞是并行执行。
以下面的语句举例
非阻塞赋值
always@(posedge clk)
begin
b<=a;
c<=b;
end
阻塞赋值
always@(posedge clk)
begin
b=a;
c=b;
end
两种不同的赋值方式结果是不同的,非阻塞赋值b<=a;c<=b;两条语句是同时执行的,而阻塞赋值b=a;c=b;两条语句先执行b=a后执行c=b。
结合编程语句区分如下:
· 非阻塞(non-blocking) 赋值语句(b<= a):
- 块内的赋值语句同时赋值;
- b的值被赋成新值a的操作, 是与块内其他赋值语句同时完成的;
- 建议在可综合风格的模块中使用非阻塞赋值。
· 阻塞(blocking) 赋值语句(b = a):
- 完成该赋值语句后才能做下一句的操作;
- b的值立刻被赋成新值a;
- 硬件没有对应的电路,因而综合结果未知。