一、阻塞赋值和非阻塞赋值
1.1 非阻塞赋值
通常非阻塞赋值用于时序逻辑,阻塞赋值是用于组合逻辑。非阻塞赋值语句是并行执行的,等到一个时钟完成后才完成赋值,而阻塞赋值是顺序执行的**,下一条赋值语句要等到上一条赋值语句完成后才能赋值**,并且阻塞赋值是立即完成的;
非阻塞赋值代码如下所示:
always@(posedge clk or negedge rst_n)
begin
if(rst_n==1'b0)
begin
b<=1'b0;
c<=1'b0;
end
else
begin
b<=a;
c<=b;
end
end
电路如下所示:
仿真波形如下所示
在45秒到55秒这个时间内,即使输入信号a发生改变了,信号b和c都不会发生改变,只有在下一个时钟上升沿来之后,b和c的信号才会改变。
图中的红色虚线表示的就是下一个时钟上升沿,在这个时钟上升沿之前,a的值是从1变化为0,在时钟沿之前值是为0。所以这个时钟上升沿之后b的值为0。
同理c的值也是如此,b的值在时钟沿之前值是为1,所以这个时钟上升沿之后c的值为0。可见b,c的值分别是由时钟上升沿之前a,b的值决定。
所以非阻塞赋值是要等到一下一个时钟上升沿发生之后,信号才会发生变化,同时信号的变化是并行的,只受到上升沿之前对应信号的值影响。
1.2 阻塞赋值
阻塞赋值代码如下所示:
always@(*)
begin
b=a+1;
c=b+1;
end
电路图如下所示:
仿真波形如下所示
因为阻塞赋值是用于组合逻辑,就不涉及时钟信号。
当输入信号a,从0变为1时,b的值立马变成2,而不是1。
同理c的值变为3,是b变化后的值2,再加上1的结果。
由此可见,阻塞赋值当输入信号改变时,输出信号也立即随着改变。而且下一条赋值语句要等到上一条赋值语句完成后才能赋值,上面的例子就是c=b+1,是等待b=a+1的赋值语句完成才赋值的。
所以总结一下:
1.非阻塞赋值用于时序逻辑
2.非阻塞赋值所赋值的变化一般是时钟上升沿之后变化
3.变化的值是用时钟上升沿之前的值赋值,不是用时钟上升沿后的值进行赋值
非阻塞赋值第2点和第3点对应到电路上体现出来的特征就是综合出来的电路有触发器。
1.阻塞赋值用于组合逻辑
2.输入信号变化时,阻塞赋值所赋值就立刻发生变化
3.变化的值是用之前赋值语句完成后的值赋值,这一点是与非阻塞赋值最大的区别
因为阻塞赋值综合出的电路没有触发器所以没有非阻塞赋值滞后一拍赋值的特性