我在理解这样一个简单的事情时遇到了问题:阻塞和非阻塞分配。
我创建了一个小型测试平台,只是为了模拟这段代码的行为:
module ATest(clk, out);
input wire clk;
output reg [7:0] out;
reg [7:0] A;
initial begin
A <= 8'b0;
end
always @(posedge clk) begin
A = A + 1;
out = A;
end
endmodule
模拟之后,我得到了这个浪潮:
我期望A
和out
下的值相同,因为我按顺序为它们分配值。为什么out
&#34;不关心&#34;在第一个时钟?
然后我尝试使用非阻塞分配。我将部分代码更改为:
always @(posedge clk) begin
A <= A + 1;
out <= A;
end
我得到了这个浪潮:
我在这里没有任何期待,因为非阻塞性陈述对我来说是个谜。为什么A
和out
都设置为&#34;不关心&#34;?
另外,我在每个页面上都找到了不同的名字,所以请帮助我: 阻塞和非阻塞是否可以与顺序和并发作为术语互换?哪一个是正确的:非阻塞语句或并发语句?
谢谢。
答案 0 :(得分:2)
如果不深入Verilog Simulators使用的模拟周期,您可以将非阻塞与阻塞分配视为:
阻止分配在执行给定分配时内联发生,这意味着如果我有A = A + 1
这样的行,则表示我们采用A
的当前值,添加1并分配{ {1}}新的价值。因此,赋值“阻止”执行直到完成。
非阻挡分配(NBA)的发生时间略早于执行线路时。您可以将非阻塞分配视为告诉模拟器稍后安排此分配的行(注意,稍后仍然使用相同的模拟时间步,因此所有这些仍然在simtime t中发生)。因此,如果你有类似A
的内容,这意味着在执行此行时获取A <= A + 1
的值,添加1并安排A
稍微更新为该值位,但继续沿着那一行继续前进。因此,如果后面的下一行是A
,则此行将使用旧值out = (A == 1) ? 1 : 0
执行,而不是递增的值。一旦模拟器完成了活动代码,它就可以继续执行所有非阻塞分配。现在,A
将获得递增的值,所有其他非阻塞分配将生效。
那么,对你的例子。在第一种情况下,我们看到了NBA的延迟效应。在A
块中,initial
被赋值为0,这意味着A
将稍后取值0(仍然在sim时间0内记住);即,分配计划在所有阻塞分配运行后进行(不严格为真,但在这种情况下有效)。此外,你有时钟的发生,所以A
块运行。在这里,always
采用值A
,但请记住,A + 1
的分配没有发生,因此A
的初始值仍为A
。所以,8'bx
也是A + 1
。由于这是一个阻止任务,它立即发生。所以,8'bx
并没有因为不关心而改变。继续,A
获取out
的当前值,即A
。所以,我们不关心8'bx
。在完成这些和其他阻塞分配之后,现在我们完成了NBA,在这种情况下,out
变为0.因此,仍然在sim时间0内,A
变为0并且我们完成了。在时钟的下一个位置,A
为0,A
无关紧,您的out
块按预期运行,递增always
和赋值{{1}相同的值。
如果你改变A
区块以使用NBA(如果它被认为是一个注册表就应该这样),情况就会略有改变。 out
区块仍会导致NBA计划always
成为0.但是现在,initial
区块会有所不同。现在,A
而不是将always
分配给不关心,它会将A <= A + 1
安排成A
(请记住,右边的表达式代表什么值assign是内联计算的,因此A
仍然使用8'bx
,因为不像以前那样关心;什么是更改是A + 1
采用这个新值时)并且这是在{{1因此,A
的两个NBAs都已设置,但是A
为0的那个NBA首先发生,并且被后来的A
赋值消失了A
。 A
同样安排A
,但现在,8'bx
永远不会变为0.因此,out
和8'bx
都会被A
卡住}。
您可以通过Verilog或SystemVerilog LRM来更好地了解SIM卡周期以及真正发生的事情,但我希望这有助于您更好地理解其中的差异!
答案 1 :(得分:1)
您的问题来自于initial
块中使用非阻止分配。请改用initial A = 8'b0;
。
这可能是两个分配处理方式的原因。 =
分配以递增方式完成,任何新值都可用于后续分配。通过<=
分配所做的更改仅在处理完所有分配后才可用。
因为您的第一个边缘位于t = 0(处理初始块时),所以在第一个示例A
中分配了0
,但0
不可用到out
之前,直到它被处理完毕。第一个周期看起来很奇怪,但其他一切都没问题。在第二个中,A
分配了0
和A+1
,因此模拟器使用always
块而不是initial
,与A+1
一起使用当A
仍然是未知值时。因此,A
和out
的值永远不会知道。
答案 2 :(得分:0)
条款相同。 &#34;阻止&#34;与&#34;顺序&#34;相同因为&#34;阻止&#34;表示必须在模拟器移动到下一行(按顺序)之前完成分配。 &#34;非阻断&#34;意味着可以一次完成所有行。作为Verilog的一切,它有助于想象硬件的意图,所以你可能会认为它是&#34; parallel&#34; vs.&#34; serial&#34;有时。
模拟中0时刻是否有正时钟边沿?