总线同步器电路的时序约束


10

我有一个总线同步器电路,用于跨时钟域传递宽寄存器。

我将提供简化的描述,省略异步重置逻辑。

数据在一个时钟上生成。更新间隔了许多(至少一打)时钟沿:

PROCESS (src_clk)
BEGIN
   IF RISING_EDGE(clock) THEN
      IF computation_done THEN
          data <= computation;
          ready_spin <= NOT ready_spin;
      END IF;
   END IF;
END PROCESS;

用于新鲜数据的控制信号,该信号经过NRZI编码(因此,总线上的有效字对应于控制信号上的转换)。控制信号通过充当同步器的DFF链。

PROCESS (dest_clk)
BEGIN
   IF RISING_EDGE(dest_clk) THEN
      ready_spin_q3 <= ready_spin_q2;
      ready_spin_q2 <= ready_spin_q1;
      ready_spin_q1 <= ready_spin;
   END IF;
END PROCESS;

同步器电路引入了短暂的延迟,这为数据总线稳定提供了足够的时间。数据总线直接采样,没有亚稳态风险:

PROCESS (dest_clk)
BEGIN
   IF RISING_EDGE(dest_clk) THEN
      IF ready_spin_q3 /= ready_spin_q2 THEN
         rx_data <= data;
      END IF;
   END IF;
END PROCESS;

编译成Cyclone II FPGA后,它可以很好地工作。但是,TimeQuest报告设置和保持时间违规,因为它无法识别同步器。更糟糕的是,Quartus手册说

专注于改善显示最差松弛的路径。钳工在松弛最差的路径上最努力地工作。如果您修复了这些路径,则钳工可能能够改善设计中其他失败的时序路径。

因此,我想在项目中添加正确的时序约束,以便Quartus将Fitter的精力用于设计的其他领域。

我非常确定这set_multicycle_path是正确的SDC(摘要设计约束)命令,因为数据线将具有多个稳定的目标时钟周期,但是我找不到使用此命令描述时钟域交叉逻辑的完整示例。 。

我真的很感谢为同步器编写SDC时序约束的一些指导。如果您发现此方法有问题,也请告知我。


时钟细节:

外部时钟发生器:两个通道,refclk = 20 MHz,refclk2 = refclk / 2(10 MHz,及相关)。

Altera PLL:src_clk = refclk * 9/5 = 36 MHz

Altera PLL:dest_clk = refclk2 * 10 = 100 MHz

我还有另一个方向的数据,分别是100 MHz src_clk和36 MHz dest_clk。


TL; DR:以上代码的正确SDC时序约束是什么?


1
拟议的FPGA设计站点上这样做会更好,但该提议尚未达到beta。
Ben Voigt

您可以发布src_clk和dest_clk的时钟定义吗?它们以任何方式(同步倍数)相关吗?如果它们是不相关的时钟,则在这种情况下通常使用set_false_path。
安迪(Andy)

@Andy:我添加了一些细节。感谢您的协助。
Ben Voigt

Answers:


9

我没有使用Quartus的经验,因此请将其作为一般建议。

在时钟域之间的路径上工作时,计时工具会将时钟扩展到其周期的最小公倍数,并选择最接近的一对边沿。

对于从36 MHz时钟(27.777 ns)到100 MHz时钟(10 ns)的路径,如果我正确进行了快速计算,则最接近的一对上升沿在源时钟上为138.888 ns,在目标时钟上为140 ns。对于这些路径,这实际上是900 MHz的限制!根据四舍五入(或对于没有关系的时钟),结果可能比这差。

至少有三种方法可以为该结构编写约束。我要打电话给钟表fast_clkslow_clk因为我认为这很容易说明。

选项1:使用禁​​用计时 set_false_path

最简单的解决方案是使用set_false_path禁用时钟之间的计时:

set_false_path -from [get_clocks fast_clk] -to [get_clocks slow_clk]
set_false_path -from [get_clocks slow_clk] -to [get_clocks fast_clk]

这并不是严格正确的,因为同步器需要定时才能正常工作。如果物理实现相对于控制信号延迟了太多数据,则同步器将无法工作。但是,由于路径上没有任何逻辑,因此不太可能违反时序约束。set_false_path即使在ASIC中,对于低概率故障而言,在工作量与风险之间的权衡要比FPGA更为谨慎,ASIC通常用于这种结构。

选项2:放宽约束 set_multicycle_path

您可以使用来为某些路径留出更多时间set_multicycle_path。通常,将多周期路径与紧密相关的时钟(例如,交互的1X和2X时钟)一起使用,但是如果该工具足够支持,它将在这里工作。

set_multicycle_path 2 -from [get_clocks slow_clk] -to [get_clocks fast_clk] -end -setup
set_multicycle_path 1 -from [get_clocks slow_clk] -to [get_clocks fast_clk] -end -hold

设置的默认边沿关系是单周期,即set_multicycle_path 1。这些命令-end为设置路径提供了一个周期的端点时钟()。-hold设置多循环路径时,几乎总是需要比设置约束小一号的调整,有关更多信息,请参见下文。

要类似地在另一个方向上约束路径(将约束放宽较快时钟的一个周期),请更改-end-start

set_multicycle_path 2 -from [get_clocks fast_clk] -to [get_clocks slow_clk] -start -setup
set_multicycle_path 1 -from [get_clocks fast_clk] -to [get_clocks slow_clk] -start -hold

选项3:直接用 set_max_delay

这类似于的影响,set_multicycle_path但省去了思考边缘关系和对保持约束的影响的麻烦。

set_max_delay 10 -from [get_clocks fast_clk] -to [get_clocks slow_clk]
set_max_delay 10 -from [get_clocks slow_clk] -to [get_clocks fast_clk]

您可能希望将其与set_min_delay保留支票配对,或者保留默认的保留支票。set_false_path -hold如果您的工具支持,您也可以禁用保留检查。


多循环路径边缘选择的详细内容

要了解与每个设置调整配对的保持调整,请考虑以下具有3:2关系的简单示例。每个数字代表时钟的上升沿:

1     2     3
4   5   6   7

默认设置检查使用边2和6。默认保持检查使用边1和4。

将多周期约束2应用于会-end调整默认设置和保持检查以使用它们最初使用的下一条边,这意味着设置检查现在使用边2和7,保持检查使用边1和5。对于两个时钟以相同的频率计时,这种调整是有道理的-每个数据启动都对应一个数据捕获,并且如果将捕获沿移出一位,则保持检查也应移出一位。如果单个时钟的两个分支中的一个具有较大的延迟,则这种约束可能有意义。但是,对于这种情况,不希望使用边沿1和5进行保持检查,因为解决该问题的唯一方法是在路径上添加整个延迟时钟周期。

多周期保持约束1(用于保持,默认值为0)调整目标时钟的边沿,用于保持检查后退一个边沿。2周期设置MCP和1周期保持MCP约束的组合将导致使用边2和7进行设置检查,并使用边1和4进行保持检查。


2

我不知道Altera的答案,但是在Xilinx Land中,您可以设置从一个时钟域到另一个时钟域的时间延迟。您必须计算数学(它取决于设计),但通常是两个时钟周期中最短的。将此时间视为任何两个信号(包括您的控制信号)之间的最大偏差,就可以算出您的同步电路是否能够处理它。

set_mulicycle_path不是正确的用法,因为通常可以处理源和目标都在同一时钟域上的情况。同样,我基于Xilinx的经验,因此您的工作量可能会有所不同。


1

我认为将set_false_path放在同步器上是安全的。

您也可以在qsf中放入“ set_global_assignment -name SYNCHRONIZER_IDENTIFICATION AUTO”,以帮助Quartus发现同步器。


那会是什么样? set_false_path -from ready_spin -to ready_spin_q2?和set_false_path -from data -to rx_data
Ben Voigt

set_false_path -from src_clk -to ready_spin我不确定将错误的路径放在数据上是否合适,因为您没有同步它。
fbo 2011年

0

我怀疑问题是,尽管您可能知道总线信号在锁存点附近的任何位置都不会改变,但软件却不知道。最好的选择是大概告诉软件输入的总线信号与总线时钟同步,并在实际锁存它们之前禁用任何优化(理论上,优化器可以用等效的替代电路来代替(如果输入确实是同步的,但如果输入的时钟周期改变了,则可能引发循环),而您绘制的电路不会在意。


不能set_multicycle_path告诉合成器/定时分析器源信号可以多久改变一次吗?而且我不确定您所说的“总线时钟”是什么意思,这里有一条信号总线跨越时钟域,那么您将哪个时钟称为“总线时钟”?我认为您是对的,如果合成器在我不进行更新的期间引入了毛刺,那么仍然可能存在亚稳态data。我想我可以在那里专门实例化DFF块:(
Ben Voigt

@BenVoigt:我认为“ set_multicycle_path”通常用于告诉时序验证器两个锁存点之间的组合逻辑链应允许取N(Tc)-Ts-Tp(N次循环时间减去采样时间减去锁存器传播时间),而不仅仅是Tc-Ts-Th。我不知道这样的事情如何与不同时钟的闩锁相互作用。
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.