我的 HDL 编译器 (Quartus II) 生成时序报告。其中,节点有“时钟偏差”列。我发现的时钟偏差的唯一定义是在TimeQuest 文档中(参见第 7-24 页):
要手动指定时钟到时钟传输的时钟不确定性或偏差,请使用该
set_clock_uncertainty
命令。
因此,如果偏差是“不确定性”,为什么我的一些时钟偏差是负的(例如 -0.048)?究竟什么是时钟偏差?
我的 HDL 编译器 (Quartus II) 生成时序报告。其中,节点有“时钟偏差”列。我发现的时钟偏差的唯一定义是在TimeQuest 文档中(参见第 7-24 页):
要手动指定时钟到时钟传输的时钟不确定性或偏差,请使用该
set_clock_uncertainty
命令。
因此,如果偏差是“不确定性”,为什么我的一些时钟偏差是负的(例如 -0.048)?究竟什么是时钟偏差?
现代数字逻辑器件通常 (*) 采用“同步设计实践”进行设计:全局同步边沿触发寄存器传输设计风格 (RTL):所有时序电路都分解为连接到全局时钟信号 CLK 的边沿触发寄存器和纯组合逻辑。
这种设计风格使人们能够快速设计数字逻辑系统,而无需考虑时序。只要从一个时钟沿到下一个时钟沿有足够的时间让内部状态稳定下来,他们的系统就会“正常工作”。
有了这种设计风格,时钟偏差和其他与时序相关的问题就无关紧要了,除了弄清楚“这个系统的最大时钟速率是多少?”。
究竟什么是时钟偏差?
例如:
...
R1 - register 1 R3
+-+
->| |------>( combinational ) +-+
...->| |------>( logic )->| |--...
->|^|------>( )->|^|
+-+ ( ) +-+
| +--->( ) |
CLK | +->( ) CLK
| |
R2: | |
+-+ | |
...->| |->+ |
->|^|->--+
+-+
|
CLK
在实际硬件中,“CLK”信号永远不会在每个寄存器上完全同时切换。时钟偏差Tskew 是下行时钟相对于上行时钟的延迟 ( a ):
Tskew(源,目的地)=destination_time - source_time
其中 source_time 是上游源寄存器(在本例中为 R1 或 R2)的有效时钟沿的时间,destination_time 是某个下游目标寄存器(在本例中为 R3)的“相同”有效时钟沿的时间.
时钟偏差的影响是什么?
(也许这里的时序图会更清楚)
为了使事情正常工作,即使在最坏的情况下,R3 的输入也不得在 R3 的建立时间或保持时间内改变。更糟糕的是,为了让事情正常工作,我们必须设计这样的东西:
Tskew(R1, R3) < Tco - Th。
Tclk_min = Tco + Tcalc + Tsu - Tskew(R1, R3)。
在哪里:
过多的正偏差是一场彻底的灾难。过多的正偏斜(对于某些数据组合)会导致“潜行路径”,这样,R3 不会在时钟 N+1 处锁存“正确数据”(先前在时钟 N 处锁存到 R1 和 R2 中的数据的确定性函数) ,在时钟 N+1 锁存到 R1 和 R2 的新数据可能会泄漏,打乱组合逻辑,并导致错误数据在“相同”时钟沿 N+1 锁存到 R3。
任何数量的负偏斜都可以通过降低时钟速率来“修复”。它只是“不好”,因为它迫使我们以较慢的时钟速率运行系统,以便在 R1 和 R2 在时钟沿 N 锁存新数据之后,让 R3 的输入有时间稳定下来,然后是 R3在“下一个”时钟沿 N+1 锁存结果。
许多系统使用时钟分配网络,试图将偏差减少到零。与直觉相反,通过沿时钟路径(从时钟发生器到每个寄存器的 CLK 输入的路径)小心添加延迟,可以增加时钟边沿波前从一个寄存器的 CLK 输入物理传播到下一个寄存器的CLK输入要快于光速。
Altera文档提到
“避免在时钟路径中使用组合逻辑,因为它会导致时钟偏移。”
这是指许多人编写编译到 FPGA 上的 HDL 以某种方式导致全局 CLK 信号以外的东西驱动某些寄存器的本地 CLK 输入的事实。(这可能是“时钟门控”逻辑,以便仅在满足某些条件时才将新值加载到寄存器中;或仅让 N 个时钟中的 1 个通过的“时钟分频器”逻辑,等等)。本地 CLK 通常以某种方式从全局 CLK 派生——全局 CLK 滴答作响,然后本地 CLK 不会改变,或者(全局 CLK 之后的短暂延迟,信号通过“其他”传播)本地 CLK 改变一次。
当那个“其他东西”驱动下游寄存器 (R3) 的 CLK 时,它会使偏斜更加积极。当“其他东西”驱动上游寄存器(R1 或 R2)的 CLK 时,它会使偏斜更负。有时,驱动上游寄存器的 CLK 的任何东西和驱动下游寄存器的 CLK 的东西都具有几乎相同的延迟,使得它们之间的偏差几乎为零。
一些 ASIC 内部的时钟分配网络经过精心设计,在某些寄存器上具有少量的正时钟偏差,这使上游的组合逻辑有更多的时间来稳定,因此整个系统可以以更快的时钟速率运行。这称为“时钟偏差优化”或“时钟偏差调度”,与“重定时”有关。
我仍然对这个set_clock_uncertainty
命令感到困惑——我为什么要“手动指定”倾斜?
(*) 一个例外: 异步系统。
来自维基百科:
在同步电路中,时钟偏移 (\$T_{Skew}\$) 是两个顺序相邻寄存器之间的到达时间差。给定两个顺序相邻的寄存器 \$R_i\$ 和 \$R_j\$,寄存器时钟引脚的时钟到达时间分别为 \$T_{Ci}\$ 和 \$T_{Cj}\$,则时钟偏差可以是定义为:
$$T_{偏斜 i,j} = T_{Ci} - T_{Cj}$$
时钟偏差可以是正的或负的。如果时钟信号完全同步,则在这些寄存器中观察到的时钟偏差为零。
所以一个寄存器的时钟偏差量是相对于另一个寄存器的。由于它是相对的,它可以是积极的或消极的。
一些插图:
以您提供的 TimeQuest 文档中定义的时钟内传输为例:
当寄存器到寄存器的传输发生在器件的内核中并且源时钟和目标时钟来自同一个 PLL 输出引脚或时钟端口时,就会发生时钟内传输。
因此,如果目标寄存器在物理上更靠近时钟生成电路,则时钟可能会在到达源寄存器之前到达目标寄存器,从而导致实际为正的超前时钟偏移。如果目标寄存器在源寄存器之后接收到时钟边沿,则时钟偏差将滞后或为负。
换句话说,时钟偏差是关于在时间单位中时钟边沿将到达两个单独的寄存器的时间上的不确定性,这些寄存器相对于寄存器到寄存器传输中的源寄存器。
扩展该定义以包括时钟间传输以及建立和保持时间会有点混乱。因此,可能更容易将其视为两个寄存器之间的边沿或保持时间的“同步程度”。我们倾向于将“同步”视为“同时发生”。但事情很少会在完全相同的时间发生。所以我们需要容忍那个时间。公差通常用正负(即±)表示。
时钟偏移是指由于距离、电容等原因,时钟在不同时间到达电路的不同点,这可能会导致其发生故障。我认为负面的一定是时钟在到达参考点之前到达那个点