奇怪的VHDL问题:rising_edge(CLK)不开火



我有一个大型仿真测试平台,它正在执行两个Kintex Ultrascale FPGA之间的接口。我遇到了最奇怪的问题:我无法触发 rising_edge(CLK) 语句。

在设计中有多个实例:我将沿着逻辑路径追踪,最终发现一个没有触发的rising_edge(无论什么)。

这是踢球者:用 CLK'EVENT 和 CLK='1' 替换rising_edge会导致逻辑正确触发,但我无法通过一千个源文件将它们全部替换,然后将其推送到团队存储库 - 这将是荒谬的(加上代码是有效的,并且已被多次使用,因此进行这样的更改将浪费大量时间)。

rising_edge也等效于 CLK'LAST='0' 和 CLK'EVENT 和 CLK='1' - 此语句也不会触发。所以一定是CLK'LAST='0'不满意,对吧?(如果 CLK'EVENT 和 CLK='1' 触发,并且添加 CLK'LAST='0' 没有触发,那么一定是导致问题的最后一个项目)。

但是,我查看了增量视图,我看不到 0 到 1 之间的中间值 - 没有中间的高 Z 状态,没有未定义的信号,什么都没有。它看起来很完美。

我已经用几个不同的Modelsim版本进行了测试,结果相同(只是为了确保它不是工具回归)。

到底是什么原因造成的?

我唯一能想到的非标准是,我使用外部名称将时钟/数据驱动到层次结构的几层,但它们将预期值更新到波形窗口。

使用外部名称来强制值是否会导致边缘丢失,即使信号看起来正确(甚至低到增量?),还是会导致某种波形窗口差异?是什么原因导致CLK'LAST实际上丢失了?

谢谢大家!

如果CLK的类型不是bit,例如,如果它是std_ulogicstd_logic则不,则不,rising_edge(CLK)不等同于:

CLK'EVENT and CLK='1'

或:

CLK'LAST='0' and CLK'EVENT and CLK='1'

rising_edge(CLK)还涉及'L''H';对于从'0''L''1''H'的任何转换,它都返回true。也就是说,以下任何一项:

'L' -> 'H'
'L' -> '1'
'0' -> 'H'
'0' -> '1'

虽然CLK'EVENT and CLK='1'评估为适用于以下任何一项:

'U' -> '1'
'X' -> '1'
'0' -> '1'
'Z' -> '1'
'W' -> '1'
'L' -> '1'
'H' -> '1'
'-' -> '1'

因此,例如,从'H''1'的过渡不是rising_edge(CLK)的上升沿,但对CLK'EVENT and CLK='1'来说却是上升沿。相反,从'0''H'的过渡对rising_edge(CLK)来说是一个上升优势,但对CLK'EVENT and CLK='1'来说却不是。

此问题的另一个潜在原因不太可能:您使用的是rising_edge函数的自定义版本......

我假设您正在对这些分层信号使用VHDLforce。如果是这样,我在使用 ModelSim 时遇到了同样的问题。我不确定这是否与ModelSim对VHDL-2008的支持实现有关,或者究竟是什么。

自从找到这个以来,我通常通过 TCL 宏而不是 VHDL 使用 ModelSimforce命令,因为 ModelSim 命令的行为似乎更可预测(包括被rising/falling_edge()识别)并且(没有 IEEE 1076 可供参考)我相信它支持比 VHDL 版本更多的选项。

最新更新