我正在学习Verilog语言(我已经使用了VHDL),我不理解以下代码的模拟:
module exam2011;
integer a,b,c,d;
always
begin
c = #1 a;
#2 b=a;
d = a;
end
initial
begin
a = 0; b = 0; c = 0; d = 0;
#1 a=1;
#2 a=2;
#2 a=3;
#2 a=4;
#2 a=5;
end
initial $monitor($time, “a=%d, b=%d, c=%d, d=%d”,a,b,c,d);
endmodule
结果:
# 0a= 0, b= 0, c= 0, d= 0
# 1a= 1, b= 0, c= x, d= 0
# 3a= 2, b= 1, c= x, d= 1
# 4a= 2, b= 1, c= 1, d= 1
# 5a= 3, b= 1, c= 1, d= 1
# 6a= 3, b= 3, c= 1, d= 3
# 7a= 4, b= 3, c= 3, d= 3
# 9a= 5, b= 5, c= 3, d= 5
# 10a= 5, b= 5, c= 5, d= 5
首先,我不知道我的想法是否正确:当我们同时改变"a"的值和"b"one_answers"d"的值(它们是"a")时,这些改变是如何执行的?另外,我真的不明白如何解释分配"="之后的延迟命令#。
谢谢你的帮助。
输出始终取决于模拟器。'always'和'initial'语句并行执行。尽管它在我们看来是并行的,但它是由模拟器在相同的时间戳中按顺序执行的。
当前时间戳中的所有事件完成后,模拟器将增加时间戳。在你的代码中,看起来'always'语句是在'initial'语句之前执行的。让我试着解释清楚一点。
c = #1 a;
这个语句等价于
temp = a; //sample the value of 'a'
#1; // Wait for 1 unit of time
c = temp; //assign the sampled value to 'c'
由于'always'语句第一次进入模拟器队列,它将'a'的值采样为'x',并在第0次将其存储在临时变量中。然后,它进入'initial'语句,并将'a','b','c'和'd'赋值为0。在#1时间单元之后,在'always'语句中将'a'的采样值'x'赋值给'c'。
#2 b = a;
这个语句等价于
#2 //Wait for 2 time unit
b = a //sample the value of 'a' and assign to b
在3个时间单位之后,由于'always'块位于模拟器队列的顶部,'a'的值仍然是'1',它被分配给'c'。在这个'initial'语句被执行之后,'2'的值被赋给'a'。其余的输出以相同的方式表现。
如前所述,Output取决于模拟器。我认为对于时间戳#9,"initial"块首先进入模拟器队列。所以它把a更新为5。在同一时间戳中,'always'块在'initial'块之后执行。所以'c'和'd'被赋予了'a'的更新值'5'。
由于时间戳仍然是#9,因此对'a'的值'5'进行采样并存储在临时变量中。这后来被分配给时间戳#10的"c"。希望这能说得通。
所以这不是一个好的编码方式。这将导致模棱两可的结果。为了说明这个模棱两可的结果,我可以举一个例子。考虑以下代码。
always@(posedge clk)
begin
cnt = cnt+1;
end
always@(posedge clk)
begin
A = cnt;
end
如果初始值为40,下一个时钟周期A的值是多少?看,现在输出依赖于模拟器。它取决于哪个'always'块首先进入模拟器队列。如果第一个'always'块首先执行,则'A'的值为'41',否则为'40'。这可以通过使用非阻塞语句"<="来消除。
always@(posedge clk)
begin
cnt <= cnt+1;
end
always@(posedge clk)
begin
A <= cnt;
end
现在'A'将是40不管模拟器。希望这对你有所帮助。