Delta cycle,也被称为增量周期,最早可追溯于1971年,VHDL从CONLAN BCL时间模型中采取了增量周期这一概念,而在CONLAN BCL时间模型中将其称为步进。Delta cycle对VHDL仿真波形过程有着重要影响,是VHDL仿真信号波形形成过程重要的一环。如果我们在设计与仿真VHDL波形过程中没有得到想要的结果,或许通过了解delta cycle的基本原理能够有一定的启发作用,让我们更加清楚VHDL是如何在仿真过程中处理一系列的波形事件。
1. Delta cycle 原理与组成阶段
在VHDL仿真过程中,一些波形信号会在少于单位时间(比如纳秒级)以内发生不确定性的变化,而通过量化时间我们可以在以增量周期(delta cycle)为额外的时刻来描述这些细微变化。这也是delta cycle能够更加清晰有逻辑地展示VHDL波形仿真变化过程的原因。这也同样可以用来解释一些“近似平行”VHDL指令运行过程。
每个delta cycle都包含两个阶段: 过程评估阶段(Process evaluation phase)和信号更新阶段(Signal update phase)。由于VHDL仿真运行是根据Process中内容进行操作,而Process中的敏感列表信号是用来触发进程(Process)运行的条件,一旦其发生变化都会触发进程(Process)运行,从而使整个仿真执行直到信号稳定仿真停止。因此在第一阶段中,主要就是触发进程执行直到下一个停止信号(如进程结束end command,wait语句或者等待下一次敏感列表的触发)。这一阶段会执行所有在进程中的语句但不包括信号幅值(Signal allocation),该赋值会在下一阶段执行。
在第二阶段中,会执行进程中的信号赋值(Signal allocation),同时这一过程会根据敏感列表是否被触发而进行多次执行(进程被触发多次执行,则会重复第一阶段),直到所有信号都处于稳定状态。下图展示了delta cycle俩阶段的构成图,以及我们用于分析实际问题时会使用的时序表:
2. 简单例子理解delta cycle中信号变化过程
在此我们先举一个简单的进程例子,并通过简单的文字分析来说明VHDL在仿真执行这个进程时的过程,初步了解delta cycle中信号如何变化。
ARCHITECTURE behavior OF example IS
SIGNAL a,b : integer := 0;
BEGIN
a <= 1 AFTER 10ns, 2 AFTER 20ns, 3 AFTER 30ns;
PROCESS(a)
VARIABLE c : integer := 0;
BEGIN
b <= a + 2;
c := 2 * b;
END PROCESS;
END behavior;
上述代码中a与b都为信号,c为进程中的变量,三者初始值都被设为0. 其中信号a会在10ns后被赋值为1,20ns后赋值为2,30ns后赋值为3,同时信号a是进程的敏感列表,即a的值一旦变化进程就会触发执行。
0ns时:我们从0ns开始分析,由于仿真开始后,信号a从未知值(x)被赋值为0,因此有变化,触发进程。由于信号b的变化属于delta cycle中的第二阶段,因此在第一阶段中信号b值为0(即在0ns时)。 变量c的赋值属于变量赋值,属于delta cycle中第一阶段,此时b仍为0,因此c在0ns为0。然后delta cycle第一阶段结束,第二阶段开始回到对信号b进行赋值,接着一个完整的delta cytcle结束,因此在1Δ时刻后b变为2.。该进程第一次执行完毕,由于信号a值在10ns之前没有变化,因此进程结束,0ns时b和c的值变化过程如下图所示:
10ns时:时间来到10ns,此时信号a值从0变为1,触发进程。信号b的变化依旧发生在delta cycle第二阶段,变量c变化发生在delta cycle第一阶段(即在10ns时刻中),因此c的值为2*2=4(在第一阶段,信号b的值还处于之前2的状态)。而在第二阶段信号b变为1+2=3,然后该delta cycle结束,因此信号b在1Δ时刻后变为3(但在10ns该时刻上仍处于之前值2)。该进程第二次执行完毕,等待下一次信号a的变化。10ns时b和c的值变化过程如下图所示:
20ns以及30ns的仿真过程原理与上述一致,在此就不再赘述。接下来我们再用一个有多个敏感列表和包含更复杂逻辑运算符的赋值语句的进程作为例子,并使用相关的时序分析表列出每个信号或变量在仿真delta cycle中变化的过程。
3. delta cycle时序分析
ARCHITECTURE behavior OF example IS
SIGNAL a : std_ulogic := '0';
SIGNAL e : std_ulogic := '1';
BEGIN
a <= '1' AFTER 2 ns, 'X' AFTER 3ns;
PROCESS(a, e)
VARIABLE v : std_ulogic := '1';
BEGIN
e <= v XOR a;
v := NOT a AND e;
END PROCESS;
END behavior;
上述代码描述一个有2个敏感列表的进程,有两个信号a和e被赋初值分别为'0'和'1',1个变量v初值为‘1’。同时信号a会随着时间变化,2ns后变成‘1’,3ns后变成'X'不确定值。
0ns + 1Δ 时间段:
0ns时信号a和e都从未知值变为初始值,将触发进程。根据delta cycle阶段,第一阶段执行变量v的赋值,此时a为’0‘, e为’1‘,则v为'1'。第二阶段执行信号e的赋值,之前变量v值(初始值)为'1', a为'0',因此e为’1‘,即1Δ时刻后信号e值变为'1';
1Δ时,信号e从之前初始值’1‘变为’1‘,与之前值一致,此时敏感列表中的信号不再变化,进程结束。等待下一次敏感列表触发。下图为该时间段的时序分析表:
2ns + 3Δ时间段:
2ns时,信号a值从‘0’变为‘1’,触发进程。此时delta cycle第一阶段中变量v首先进行赋值操作,此时信号e的值仍为上次‘1’,信号a值为'1',因此v的值为’0‘。第二阶段中进行信号e的赋值操作,此时信号a值为'1',变量v上次的值为'1'(这里需要注意!即使变量v在第一阶段先进行赋值操作,但进程中信号e赋值语句是在变量v赋值语句之前的,因此信号e的赋值中需要取变量v之前的值),因此信号e的值变为’0‘,即1Δ时刻后,信号e值为’0’。下图为该时段时序分析表:
1Δ时,信号e从之前值‘1’变为了'0',触发了进程。第一阶段依旧变量v先赋值计算,此时信号a值为'1',信号e值为'0',因此变量v值变为‘0’。第二阶段信号e赋值计算,此时信号a值为‘1’,变量v上一次值是'0',因此信号e值为‘1’,即2Δ时刻信号e值变为‘1’。下图为该时段时序分析表:
2Δ时,信号e从之前值‘0’变为了'1',再次触发了进程。第一阶段变量v先赋值计算,此时信号a值仍为'1',信号e值为'1',因此变量v值变为‘0’。第二阶段信号e赋值计算,此时信号a值为‘1’,变量v上一次值为'0',因此信号e值为‘1’,即3Δ时刻信号e值也为‘1’。下图为该时段时序分析表:
3Δ时,信号e值不再变化,进程结束。等待下一次敏感列表触发。至此该时间段仿真完成。
至于在3ns后的仿真delta cycle过程分析如同上述,在此不再赘述。下图为全时段下仿真时序分析表,有兴趣的可以按照上述分析过程进行自我练习并核对结果。
4. 总结与联想
分析delta cycle仿真过程可以让我们对于信号变化的细节有着更加细致深入的了解与认知,但需要注意的是这些变化都是在细微时间内发生的,在平常功能设计分析中,这些时间段都可以认为是零延迟的,因为这些变化都在比单位时间更小的时间内发生,对于分析功能有无漏洞有一定辅助作用,当然如今的仿真器都能很好地将电路实际情况仿真出来方便核查与分析。
此外,在上篇所提到的延迟模型delay model主要对发生在单位时间上的信号变化进行分析,而该篇所提及的delta cycle则是对发生在单位时间上以及之间的细微时间段信号变化进行分析。两者并无冲突,有时是需要一同考虑进行信号分析。即发生在delta cycle的信号变化都会属于其单位时间内(零延迟),延迟模型会根据最新的在delta cycle中的信号值进行赋值操作与延迟。以下述赋值语句代码与时序分析表为例,发生在0到1ns之间的delta cycle信号变化都会被认为是在0ns单位时间内发生的,因此y值从’1‘变化到’0‘,z值在1ns时也会从'1'更新为'0',以此类推后续的信号变化:
z <= y AFTER 1ns;