VHDL中的进程是否可以重入?

use*_*016 13 process delay vhdl reentrancy

是否有可能两个或更多顺序运行进程VHDL

如果在进程的顺序执行未完成时发生另一个事件(在敏感信号列表上)会发生什么?

是否有可能或我的VHDL模型在过程中完全错误?

Bri*_*ond 51

进程运行时不会发生任何事件!

当某个进程被某个事件唤醒时,它会运行完成("结束进程")或显式的"等待"语句,然后进入休眠状态.从概念上讲,这需要零时间.这意味着如果你的进程中有循环,它们就会被完全展开,当你综合时,你将生成足够的硬件来并行运行每一次迭代.此外,任何过程,函数等都是零时间 - 除非它们包含一个明确的"等待"语句(在这种情况下,进程在"等待"时暂停,就好像该过程已被内联).

在整个过程中,所有信号都具有当过程醒来时它们最初具有的值,并且任何信号分配都会被存储起来,以后发生.(变量立即更新;过程中的后续语句看到新值).

当进程挂起(处于"等待"或"结束进程")时,在所有其他进程也挂起之前不会发生任何事情.(但记住他们都没有时间!).如果一个进程在"结束进程"暂停,它将在其敏感性列表唤醒它时从头开始重新启动.如果它以明确的"等待"暂停,则"等待"将指定事件或未来时间,这将在"等待"之后重新启动它.(注意:1:不要在同一个过程中混合灵敏度列表和等待样式!2:等待直到某个事件是可合成的(尽管某些工具可能会对象);等待一段时间只是模拟)

然后执行所有信号分配.由于所有过程都处于睡眠状态,因此可以消除所有竞争条件和时间危险.其中一些分配(如时钟的"1")将导致事件在对它们敏感的过程上进行调度.

在完成所有信号分配之后,时间步进一个无限短的标记(称为增量循环),然后唤醒具有预定事件的所有过程.

这一直持续到发生增量循环,其中没有安排新的事件,并且最后模拟可以通过实时步骤前进.

从而

process(clk)
begin
if rising_edge(clk) then
   A <= B;
   B <= A;
end if;
end process;
Run Code Online (Sandbox Code Playgroud)

在VHDL中是无危险的.

如果您需要使用Verilog,请注意其中一些情况会有所不同,并且您无法在仿真结果中依赖相同级别的可预测性.


当然,在综合中,我们生成的硬件需要一些实时来执行这个过程.但是,综合和后端工具(布局和布线)保证要么忠实地遵守这个模型,要么失败并报告它们失败的原因.例如,它们将累计所有实际延迟并验证总和小于指定的时钟周期.(除非你将时钟速度设置得太高!).

因此,结果是,只要工具报告成功(并且您正在设置时钟速度正确的时序约束),您可以假装上述"零时间"模型为真,并且真实的硬件行为将与模拟匹配.保证,禁止工具错误!

  • 为什么这个答案究竟不是每个VHDL教程都有?我现在用VHDL做了一些事情,你仍然为我澄清了一些基础知识! (5认同)

zen*_*hoy 6

当开始使用VHDL(或任何其他HDL)时,放弃顺序代码的所有概念非常重要,而是专注于通过硬件的数据流.在硬件中,一切都是固有的并行(一切都同时发生),但使用不断变化的数据(输入信号)来计算不断变化的结果(输出信号)!

无需进入更高级的主题,如变量,等待命令等,过程中的所有内容都会同时发生.如果在同一进程中发生冲突事件(多次写入同一信号),则进程中的最后一个语句将获胜,这通常是VHDL中"顺序"代码混淆的地方.

这是因为将值分配给信号的方式.为信号分配值时,信号的值不会立即改变!相反,记住指定的值,并且稍后将作为实际信号值提交(为下一个delta周期做准备,这实际上是下一个时间量段).

由于下一个增量周期不会开始,直到前一个增量周期的所有进程都完成,因此信号值只会在没有进程运行时发生变化.一旦所有信号都改变了,下一个增量周期就开始了,任何对一个改变信号敏感的过程都将被执行.

如果一个过程对它也写入的信号很敏感,那么你就有了所谓的组合回路,例如,输出馈送输入的门.这(几乎)总是在电路中出错,并且通常会导致模拟器进入无限增量循环.

这就是我现在要写的全部内容,因为当我写这篇文章时,布莱恩·德拉蒙德的答案刚刚出现,但我可以随意发表评论,我会补充更多细节.