关于在testbench中使用非阻塞分配,我有两个问题。
always @(posedge clk)
begin
while((state==2'd3) && (x!=OUT_MAX_SIZE_32) && (count_done==4'd4))
begin
$display("a[%d] :%h, %d",l,a[l],x);
a[l] <= {b[x][31], b[x][30], b[x][29], b[x][28], b[x][27], b[x][26], b[x][25], b[x][24]};
a[l+1] <= {b[x][23], b[x][22], b[x][21], b[x][20], b[x][19], b[x][18], b[x][17], b[x][16]};
a[l+2] <= {b[x][15], b[x][14], b[x][13], b[x][12], b[x][11], b[x][10], b[x][9], b[x][8]};
a[l+3] <= {b[x][7], b[x][6], b[x][5], b[x][4], b[x][3], b[x][2], b[x][1], b[x][0]} ;
x <= x+1;
l <= l+4;
end
end
如果我使用非阻止分配, x 和 l 不会递增。但是,如果我使用阻止分配,它会按预期工作。我需要帮助来分析它。
答案 0 :(得分:1)
您可以而且应该在测试平台中使用非阻止分配。模拟器不知道您的设计和测试平台之间的区别。您需要以防止竞争条件的方式编码。
根据您展示的代码,我无法理解为什么它会产生任何影响,除非您在其他地方有x
和l
的其他作业,而您没有展示。
答案 1 :(得分:1)
非阻塞分配始终可用于测试台代码。通过使用非阻塞分配,这将成为无限循环。
参考SystemVerilog LRM 1800-2012第10.4.2节,
非阻塞程序分配允许分配调度而不会阻止程序流程。
参见第4.9.4节,
非阻塞赋值语句(参见10.4.2)始终计算更新值并将更新计划为NBA更新事件,如果延迟为零,则在当前时间步骤中计划;如果延迟为非零,则将其更新为未来事件
这里,在时钟的 posedge ,让我们说 x = 0 ,所以假设执行循环时 。非阻塞指派的RHS在活动区域进行评估,而实际指派则在NBA地区进行。
因此,在相同时间戳的 NBA 区域中 x 的增量为预定。此外,由于它是非阻塞语句,因此在活动区域中再次检查while循环的条件而不阻塞任何内容(再次获得 x = 0 )。同样, x 计划在 NBA 区域递增,此循环继续永久。因此,您无法增加 x 。类似的评论适用于l。
使用阻止分配时,值立即分配给表达式的LHS,因此x / l增加。
此外,$display
在活动区域中执行,因此您无法将x的值设为1.以下图片将为您提供清晰的信息。
有关事件区域的详细信息,请参阅CummingsSNUG2006Boston_SystemVerilog_Events论文。