在 Testbench 中使用非阻塞分配:Verilog
Use of Non-Blocking Assignment in Testbench : Verilog
我有两个关于在测试台中使用非阻塞赋值的问题。
- 我们可以在 always @(posedge clk) w.r.t 测试台中使用阻塞赋值吗?我认为我们可以使用,因为我们不必担心硬件。但我需要确认。
- 我在我的测试台中使用了以下代码,但它没有按预期工作。
always @(posedge clk)
begin</p>
<p>while((state==2'd3) && (x!=OUT_MAX_SIZE_32) && (count_done==4'd4))
begin</p>
$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 不会递增。但如果我使用阻塞分配,它会按预期工作。我需要帮助来分析它。
您可以而且应该在您的测试平台中使用非阻塞赋值。模拟器不知道你设计的和你的测试台之间的区别。您需要以防止竞争条件的方式对两者进行编码。
从您显示的代码中,我看不出为什么它会产生任何不同,除非在您没有显示的其他地方对 x
和 l
进行了其他分配。
非阻塞赋值总是可以在测试平台代码中使用。通过使用非阻塞赋值.
,这变成了一个无限循环
参考SystemVerilog LRM 1800-2012第10.4.2节,
The non blocking procedural assignment allows assignment scheduling without blocking the procedural flow.
参照第4.9.4节,
A non blocking assignment statement (see 10.4.2) always computes the updated value and schedules the update as an NBA update event, either in the current time step if the delay is zero or as a future event if the delay is nonzero.
在这里,在时钟的 posedge 处,假设 x=0 所以它假设 while 循环被执行。非阻塞分配的 RHS 在活动区域进行评估,而实际分配在 NBA 区域完成。
因此,x 增加到 1 计划 在 NBA 区域相同 时间戳。此外,由于它是非阻塞语句,因此在活动区域再次检查 while 循环的条件而不会阻塞任何内容(再次获得 x=0)。同样,x 计划在 NBA 区域递增,并且此循环继续 forever。因此,您无法增加 x。类似的评论适用于 l.
同时,使用阻塞赋值,值立即赋值给表达式的LHS,因此x/l增加。
此外,$display
在活动区域中执行,所以你将无法获得x的值为1。下图会让你清楚地了解这个。
有关事件区域的更多信息,请参阅CummingsSNUG2006Boston_SystemVerilog_Events论文。
我有两个关于在测试台中使用非阻塞赋值的问题。
- 我们可以在 always @(posedge clk) w.r.t 测试台中使用阻塞赋值吗?我认为我们可以使用,因为我们不必担心硬件。但我需要确认。
- 我在我的测试台中使用了以下代码,但它没有按预期工作。
always @(posedge clk)
begin</p>
<p>while((state==2'd3) && (x!=OUT_MAX_SIZE_32) && (count_done==4'd4))
begin</p>
$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 不会递增。但如果我使用阻塞分配,它会按预期工作。我需要帮助来分析它。
您可以而且应该在您的测试平台中使用非阻塞赋值。模拟器不知道你设计的和你的测试台之间的区别。您需要以防止竞争条件的方式对两者进行编码。
从您显示的代码中,我看不出为什么它会产生任何不同,除非在您没有显示的其他地方对 x
和 l
进行了其他分配。
非阻塞赋值总是可以在测试平台代码中使用。通过使用非阻塞赋值.
,这变成了一个无限循环参考SystemVerilog LRM 1800-2012第10.4.2节,
The non blocking procedural assignment allows assignment scheduling without blocking the procedural flow.
参照第4.9.4节,
A non blocking assignment statement (see 10.4.2) always computes the updated value and schedules the update as an NBA update event, either in the current time step if the delay is zero or as a future event if the delay is nonzero.
在这里,在时钟的 posedge 处,假设 x=0 所以它假设 while 循环被执行。非阻塞分配的 RHS 在活动区域进行评估,而实际分配在 NBA 区域完成。
因此,x 增加到 1 计划 在 NBA 区域相同 时间戳。此外,由于它是非阻塞语句,因此在活动区域再次检查 while 循环的条件而不会阻塞任何内容(再次获得 x=0)。同样,x 计划在 NBA 区域递增,并且此循环继续 forever。因此,您无法增加 x。类似的评论适用于 l.
同时,使用阻塞赋值,值立即赋值给表达式的LHS,因此x/l增加。
此外,$display
在活动区域中执行,所以你将无法获得x的值为1。下图会让你清楚地了解这个。
有关事件区域的更多信息,请参阅CummingsSNUG2006Boston_SystemVerilog_Events论文。