阻塞赋值与非阻塞赋值(verilog篇)
相信刚刚接触verilog的读者,多少对阻塞赋值和非阻塞赋值仍有一些困惑。笔者在这篇文章,带领大家深入的理解这两者的区别。
首先笔者给一些实验及仿真数据。通过修改testbench文件,利用modelsim软件来观察两者的不同。
同样也可以这样写:
输出波形如下:
稍作改动:
输入波形如下:
细心的读者会发现是 " = " 与 " <= "的区别。
1> 当使用 " = " ,记为阻塞赋值。从开始时刻开始,经过2个周期置1,持续4个周期后置0。也就是说在执行一条语句时,其他的语句不能执行。
打个比方,有很多车都要上高架,由于道路堵塞,一次只能通过一辆车,其他车只能等这辆过去后,才能过。
2 > 当使用 " <= " ,记为非阻塞赋值。从开始时刻开始,经过2个周期置1;从开始时刻,经过4个周期后置0。你会发现,经过四个周期后,test信号始终维持低电平,好像最后一句赋值没发生一样。
再打个比方,还是很多车准备过高速路口,通常有多个出口。现在有三辆车都过,这三辆车是互不影响的。
实际上也就是延迟三个周期置高电平,可是延迟两个周期已经置高电平了,可以分析这句一定是同时进行的。
通过作者的分析,相信读者可能加深了对两者区别的理解。
在此笔者推荐用阻塞赋值的方法,书写testbench脚本初始化模块,这样时序较为容易分析。
那么以上两者对电路有那种影响呢?
采用非阻塞赋值,部分代码如下:
always @(posedge clk)
begin
b <= a;
z <= b;
end
其综合对应的电路如下:
采用阻塞赋值,部分代码及综合电路如下:
always @(posedge clk)
begin
b = a;
z = b;
end
区别已经很明显了,具体区别就不再赘述,不过在这里,我想说的是,不要以为加入寄存器变量,一定意味着添加寄存器,这是错误的。
对于阻塞赋值,b为寄存器变量,可没有输出为b的寄存器哟。
综上所述,阻塞赋值和非阻塞赋值各占一片天。always 里面一定是非阻塞赋值,这可不一定哟。
具体问题具体分析,我相信,即使最简单的语法知识,深入分析之后,也会收获很多的。
转载:https://mp.weixin.qq.com/s?__biz=MzI4NTM4NjgyNg==&mid=100000173&idx=1&sn=b6cc881e9e82893b0d8ab22ef2fa7549&chksm=6bedb0885c9a399e334dafd5623a1260950a7ae5f6751fc2206b7d441baa073516b39ca16cfc&mpshare=1&scene=23&srcid=11295jqBMDZ97ciHjoM2uuZP#rd