📅  最后修改于: 2021-01-11 15:03:32             🧑  作者: Mango
Verilog设计和测试平台通常具有许多代码行,这些代码行包含始终或初始块,连续赋值以及其他过程语句,这些过程语句在模拟过程中的不同时间处于活动状态。
Verilog模型中信号值的每次更改都被视为更新事件。并且,对这些更新事件敏感的诸如Always和Assign块之类的过程将以任意顺序进行评估,称为评估事件。
由于这些事件可以在不同的时间发生,因此可以通过将它们安排在由模拟时间安排的事件队列中来更好地管理和确保其正确执行顺序。
module tb;
reg a, b, c;
wire d;
// 'always' is a process that gets evaluated when either 'a' or 'b' is updated.
// When 'a' or 'b' changes in value it is called an 'update event'.
// When 'always' block is triggered because of a change in 'a' or 'b' it is called an evaluation event.
always @ (a or b) begin
c = a & b;
end
// Here 'assign' is a process that is evaluated when either 'a' or 'b' or 'c' gets updated.
assign d = a | b ^ c;
endmodule
模拟步骤可以分为四个不同的区域。活动事件队列只是当前需要执行的一组流程,从而导致将更多进程安排到活动队列或其他事件队列中。可以将事件添加到任何区域,但始终从活动区域中删除事件。
当前时间步的活动队列中的所有事件均已执行。模拟器将时间提前到下一个时间步并执行其活动队列。
module tb;
reg x, y, z
initial begin
#1 x = 1;
y = 1;
#1 z = 0;
end
endmodule
模拟在时间0开始,并且计划在模拟时间达到1个时间单位(将x和y分配给1)时执行第一条语句。
这是当前时间的活动队列,以1时间为单位。然后,模拟器将在z分配0的另外1个时间单位之后安排下一条语句。
在仿真期间,对于相同的设计和测试平台,可能存在竞态条件最终给出不同的输出。不确定行为的原因之一是因为活动事件可以从队列中删除并以任何顺序进行处理。
当同时触发多个过程时,电气和电子工程师协会( IEEE )标准未指定执行过程的顺序。它是任意的,并且因模拟器而异。这称为非确定性。
有两种常见的不确定性案例,它们是由相同的根本原因引起的,但以不同的方式表现出来。
情况1:当多个语句在零时间执行时,它们的执行顺序会影响结果。因此,不同的执行顺序会给出不同但正确的结果。在零时间执行意味着在不增加仿真时间的情况下评估语句。
always @(d)
q = d;
assign q = ~d;
当变量d更改时,计划同时执行这两个过程,一个过程块和一个连续分配。
如果始终对始终块进行评估,则始终块为变量q分配新的d值。然后执行连续分配。它将d的新值的补数分配给变量q。
如果首先评估连续赋值,则q获得d的新值的补数。然后,过程分配将新值(非补码)分配给q。因此,两个订单产生相反的结果。
情况2:当同时执行块中的交错过程语句时,将考虑这种情况。同时调度两个过程块时,不能保证一个块中的所有语句都在另一个块中的语句开始之前完成。来自两个块的语句可以按交错顺序执行。
always @(posedge clk) // always block1
begin
x = 1'b0;
y = x;
end
always @(posedge clk) // always block2
begin
x = 1'b1;
end
当clk的上升沿到达时,两个总是块都被触发。一个交织顺序是
x = 1'b0;
y = x;
x = 1'b1;
在这种情况下,y为0。另一个交织顺序为
x = 1'b0;
x = 1'b1;
y = x;
在这种情况下,y为1。