2应用及分析 通常非阻塞赋值产生寄存器等存储元件,对应的物理器件是带存贮功能的元件,如寄存器、触发器等。阻塞赋值则对应网线(wire)类型,通常与物理连线对应。这是两种赋值方式的最明显的差异,也是时序逻辑用非阻塞、组合逻辑用阻塞的重要原因。但这并不是绝对的,事实上阻塞赋值对应网线(wire)型,亦可对应寄存器(reg)型;阻塞赋值也能生成存贮元件,因此不能片面理解。在组合逻辑里,锁存器可能引发测试问题,带来隐患。说明在建模时,首先要从硬件出发来考虑问题,应先在头脑中形成电路结构,由于赋值方式的不同,综合结果差异甚大,运用不当很可能会导致建模失败。阻塞赋值在时序逻辑中亦有着重要应用,在需要实时更新的组合逻辑中只有阻塞赋值能满足要求。
以下示例代码的功能是计算传送过来的data中1和0的个数。
reg[5:0]count0,count1;
always@(posedgeclk,negedgeRst_n)
begin
if(!Rst_n)
...
else
begin
count0=0;//语句1
count1=0;//语句2
for(i=0;i<=11;i=i+1)
begin
if(data==1)
count1=count1+1;//语句3
elseif(data==0)
count0=count0-1;//语句4
else
count0=count0+0;//防止生成锁存器
end
end
end
在这段代码里,count0、count1的值必须在每次计数之前被清零,count0、count1必须实时更新。显然,只有阻塞赋值能满足要求。非阻塞赋值分两步完成,所有的更新事件在单位仿真周期末同时执行,只有最后一个值有效,所以非阻塞赋值无法完成计数任务。阻塞赋值却能很好地胜任,因为阻塞赋值估值和更新一次性完成。
事件上,在时序逻辑中经常碰到上述实时更新问题,非阻塞赋值往往无法实现,如用阻塞赋值则可很好地解决问题。
正如阻塞赋值在时序逻辑中有重要应用一样,非阻塞赋值在组合逻辑中亦有不可替代的应用。在组合逻辑中用非阻塞赋值可以把组合逻辑改造成流水线。可执行如下所示纯组合逻辑代码,将生成纯组合逻辑,综合结果如图2所示。
inputa,b,c,clk,sel;
outputout;
regout,temp;
always@(posedgeclk)
begin
temp=a&b;//语句1
if(sel)
out=temp|c;//语句2
else
out=c;//语句3
end
若把上面代码中语句1、语句2、语句3阻塞赋值("=")改为非阻塞赋值("<="),则综合结果如图3所示。