进程运行时不会发生任何事件!
当进程被事件唤醒时,它会运行到完成(“结束进程”)或显式“等待”语句,然后进入睡眠状态。理论上,这需要零时间。这意味着,如果您的流程中有循环,它们会有效地完全展开,并且当您综合时,您将生成足够的硬件来并行运行每个迭代。此外,任何过程、函数等都花费零时间 - 除非它们包含显式的“等待”语句(在这种情况下,进程在“等待”处挂起,就像过程已被内联一样)。
在整个过程中,所有信号都具有进程唤醒时最初具有的值,并且所有信号分配都会被存储起来,以便稍后发生。 (变量立即更新;流程中的后续语句会看到新值)。
当进程挂起时(在“等待”或“结束进程”),在所有其他进程也挂起之前不会发生任何事情。 (但请记住,它们都需要零时间!)。如果进程在“结束进程”处挂起,当其敏感度列表将其唤醒时,它将从头重新启动。如果它在显式“等待”处挂起,则该“等待”将指定一个事件或未来时间,这将在“等待”之后重新启动它。 (注:1:不要在同一过程中混合敏感度列表和等待样式!2:等待直到某个事件可综合(尽管某些工具可能会反对);等待一段时间只是模拟)
然后执行所有信号分配。由于所有进程都处于睡眠状态,因此消除了所有竞争条件和计时风险。其中一些分配(例如时钟的“1”)将导致事件被调度到对它们敏感的进程上。
所有信号分配完成后,时间向前推进一个无限短的周期(称为增量周期),然后唤醒所有具有预定事件的进程。
这种情况一直持续到发生增量循环为止,其中没有安排新事件,最后模拟可以按实时步骤前进。
Thus
process(clk)
begin
if rising_edge(clk) then
A <= B;
B <= A;
end if;
end process;
在 VHDL 中是无危险的。
如果您需要使用 Verilog,请注意其中一些情况的发生方式有所不同,并且您不能依赖仿真结果中相同级别的可预测性。
当然,在综合过程中,我们生成硬件,这需要一些实时时间来执行此过程。然而,综合和后端工具(布局和布线)保证要么忠实地遵守该模型,要么失败并报告失败的原因。例如,他们会将所有实际延迟相加,并验证总和是否小于您指定的时钟周期。 (除非您将时钟速度设置得太高!)。
因此,结果是,只要工具报告成功(并且您正确设置了时钟速度等时序约束),您就可以假装上述“零时间”模型是正确的,并且真实的硬件行为将与模拟相匹配。有保证,排除工具错误!