2015-11-05 44 views
0

我有两个有关在测试台中使用非阻塞赋值的问题。在测试平台中使用非阻塞赋值:Verilog

  1. 我们可以在总是@(posedge clk)w.r.t testbench中使用阻塞赋值吗?我想我们可以使用,因为我们不必担心硬件。但我需要确认。
  2. 我在测试平台中使用了下面的代码,但它不能按预期工作。


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如果我使用非阻塞赋值不递增。但是如果我使用阻塞分配,它按预期工作。我需要帮助分析它。

+0

这已经不是主题:如果没有异步电路涉及您的项目,您可能想在代码中使用'if'语句而不是'while'语句。 – e19293001

回答

0

非阻塞分配总是可以在测试台代码中使用。这变成无限循环通过使用非阻塞赋值

参照的SystemVerilog LRM 1800年至2012年第10.4.2节,

非阻断程序分配允许分配调度,而不会阻塞程序流。

参照节4.9.4,

非阻塞赋值语句(见10.4.2)总是计算更新值和日程表更新为NBA更新事件,无论是在当前时间如果延迟为零,或者如果延迟为非零,则作为未来事件。

在此,时钟的posedge,让说x = 0时所以它是假设循环被执行。非阻塞任务的RHS在活跃区域进行评估,而实际任务在NBA区域完成。

所以,X增量1 计划NBA相同时间标记的区域。另外,由于它是一个非阻塞语句,while循环的条件在活动区域​​中再次被检查而不会阻塞任何东西(再次获得x = 0)。再次,x预计将在NBA区域中递增并且该循环永远持续。因此,您无法增加x。类似的评论适用于l。

虽然使用阻断赋值,该值是立即分配给表达的LHS,因此X/L增加而增加。

另外,$display执行于活动区域,所以你将无法获得x的值为1.下图应该给你清晰的想法。

Event regions

有关活动区的更多信息,请参阅CummingsSNUG2006Boston_SystemVerilog_Events纸。

+0

令人难以置信的解释......感谢你:)那么你认为我不得不担心在此使用阻塞任务吗?我的意思是我需要找到另一种使用** NBA **来实现这个部分的方法吗? – ssgr

+0

我认为使用阻塞任务将是一个更好的选择。在这里,我只有一些粗略的想法,在NBA声明之前使用**#1或其他延迟**,但这不是一个好的编码练习。如果你删除while循环并且在条件中使用if(x!= OUT_MAX_SIZE_32 && ...)或者其他一些逻辑操作可能会很好。 – sharvil111

1

您可以也应该在测试平台中使用非阻塞赋值。模拟器不知道你的设计和你的测试台之间的区别。您需要以防止竞争条件的方式进行编码。

从你展示的代码中,我不明白为什么它会有所作为,除非在其他地方有xl其他你没有显示的任务。

+0

我已经使用** x **和** l **的唯一其他地方是**初始**块,我已经将它们初始化为零。 – ssgr