9.1 IO 接口

本小节中的示例说明了该如何定义 DUA 输入和输出接口的约束。后面的小节介绍了 SRAM 和 DDR SDRAM 接口的时序约束示例。

 

9.1.1 输入接口

有两种指定输入接口时序要求的方法:

 

以 AC 约束的形式指定 DUA 输入端的波形。

 

指定外部逻辑到输入的路径延迟。

 

指定输入端口的波形

考虑图 9-1 中所示的输入 AC 约束:输入 CIN 在时钟 CLKP 的上升沿之前 4.3ns 必须保持稳定,并且必须要保持稳定直到时钟上升沿之后 2ns。

 

图 9-1

 

首先考虑 4.3ns 的约束,给定时钟周期为 8ns(如图 9-1 所示),这约束了从虚拟触发器(驱动该输入的触发器)到输入端口 CIN 的延迟。从虚拟触发器时钟引脚到 CIN 的延迟最大为 3.7ns(= 8.0-4.3), 这样可确保输入 CIN 处的数据在上升沿之前 4.3ns 到达。因此,AC 约束的这一部分可以等效地指定为 3.7ns 的最大输入延迟。

 

AC 约束还指出,输入 CIN 在时钟上升沿之后 2ns 必须继续保持稳定,这也约束了虚拟触发器的延迟,即从虚拟触发器到输入 CIN 的延迟必须至少为 2.0ns。因此,最小输入延迟指定为 2.0ns。

 

以下是输入延迟约束:

 

create_clock -name CLKP -period 8 [get_ports CLKP]

 

set_input_delay -min 2.0 -clock CLKP [get_ports CIN]

 

set_input_delay -max 3.7 -clock CLKP [get_ports CIN]

 

以下是设计在这些输入延迟约束下的路径报告,首先是建立时间检查:

 

 

指定的最大输入延迟(3.7ns)被添加到了数据路径中。建立时间检查会确保 DUA 内部的延迟小于 4.3ns,这样就可以锁存到正确的数据。接下来是保持时间检查:

 

 

最小输入延迟将被添加到保持时间检查的数据路径中。该检查可确保最早的数据在时钟沿之后的 2ns 处才变化,这样就不会覆盖触发器上捕获到的先前数据。

 

指定输入端口的路径延迟

已知连接到输入的外部逻辑的路径延迟后,指定输入约束就是一件很简单的事情了。将沿外部逻辑路径到输入的任何延迟全部相加起来,然后使用 set_input_delay 命令去指定路径延迟。

 

图 9-2 给出了一条输入的外部逻辑路径示例。Tck2q 和 Tc1 延迟相加就是外部延迟,知道了 Tck2q 和 Tc1,就可以直接获得输入延迟,即 Tck2q + Tc1。

 

图 9-2

 

外部逻辑的最大和最小路径延迟可以转换为以下输入延迟约束:

 

create_clock -name RCLK -period 10 [get_ports RCLK]

 

set_input_delay -max 6.2 -clock RCLK [get_ports INIT]

 

set_input_delay -min 3.0 -clock RCLK [get_ports INIT]

 

上述输入延迟约束的时序检查路径报告与 8.1 节和 8.2 节中的报告类似。

 

请注意,在计算设计内部触发器数据引脚的实际到达时间时,将会根据执行的是最大路径(建立时间)检查还是最小路径(保持时间)检查,分别选择将输入延迟的最大值或最小值添加到数据路径延迟中去。

 

9.1.2 输出接口

与输入接口类似,也可以使用两种方法来指定输出时序要求:

 

以 AC 约束的形式指定 DUA 输出端的波形。

 

指定输出到外部逻辑的路径延迟。

 

指定输出端口的波形

考虑图 9-3 中所示的输出 AC 约束:在时钟 CLKP 的上升沿之前 2ns,输出 QOUT 就应保持稳定。同样,输出 QOUT 需要保持稳定直到时钟上升沿之后的 1.5ns 为止。通常可从与 QOUT 接口的外部模块的建立时间和保持时间要求中获得这些约束值。

 

图 9-3

 

以下是对输出端口时序要求进行的约束:

 

create_clock -name CLKP -period 6 -waveform {0 3} [get_ports CLKP]

 

set_output_delay -clock CLKP -max 2.0 [get_ports QOUT]

 

set_output_delay -clock CLKP -min -1.5 [get_ports QOUT]

 

最大输出路径延迟指定为了 2.0ns,这将确保数据 QOUT 在时钟沿前 2ns 之前允许改变。从虚拟触发器的角度来看,最小输出路径延迟指定为了 -1.5ns,这用于确保在输出 QOUT 上 1.5ns 的保持时间要求。1.5ns 的保持时间要求就是 set_output_delay 中指定的最小值 -1.5。

 

以下是建立时间检查的路径报告:

 

 

在建立时间检查中,将从下一个时钟沿减去最大的输出延迟,以确定在 DUA 输出处数据需要到达的时间。

 

接下来是保持时间检查的路径报告:

 

 

在保持时间检查中,将从捕获时钟边沿中减去最小的输出延迟(-1.5ns),以确定满足保持时间要求的 DUA 输出的数据最早到达时间。注意,最小输出延迟为负值很常见。

 

指定输出端口的路径延迟

在这种情况下,将明确指定外部逻辑的路径延迟。请参见图 9-4 中的示例:

 

图 9-4

 

让我们首先检查建立时间,由 Tc2_max 和 Tsetup 可获得最大输出延迟(set_output_delay -max)。为了检查 DUA 内部触发器(例如 UFF0)和虚拟触发器之间输出路径的建立时间要求,最大输出延迟可指定为 Tc2_max + Tsetup。

 

接下来,让我们检查保持时间,由 Tc2_min 和 Thold 可获得最小输出延迟(set_output_delay -min)。由于捕获触发器的保持时间被添加到了捕获时钟路径中,因此最小输出延迟指定为 Tc2_min-Thold。

 

以下是输出延迟约束:

 

create_clock -name SCLK -period 5 [get_ports SCLK]

 

set_output_delay -max 3.1 -clock SCLK [get_ports RDY]

 

set_output_delay -min 1.45 -clock SCLK [get_ports RDY]

 

这些路径报告与 8.1 节和 8.2 节中的报告相似。

 

9.1.3 时序窗口内的输出变化

set_output_delay 命令可用于指定输出信号相对于时钟的最大和最小到达时间。本节考虑特殊情况,当输出只能在相对于时钟沿的时序窗口内发生改变时,可以指定输出延迟约束来验证时序,在验证源同步(source synchronous)接口的时序时尤其常用。

 

源同步接口中,时钟也与数据一起输出。在这种情况下,通常时钟和数据之间需要有一个时序关系。例如,可能仅在时钟上升沿附近的特定时序窗口内才能改变输出数据。

 

源同步接口的时序要求如下图 9-5 所示:

 

图 9-5

 

该时序要求:DATAQ 的每个比特位(bit)只能在指定的时序窗口中改变,即在时钟上升沿之前 2ns 以及时钟上升沿之后 1ns 之间。这与前面各节中讨论的输出延迟约束有很大的不同,在前几节中,要求数据引脚在时钟上升沿附近的指定时序窗口中保持稳定。

 

我们以 CLKM 为主时钟创建了一个衍生时钟 CLK_STROBE,方便去指定与该接口要求相对应的时序约束。

 

create_clock -name CLKM -period 6 [get_ports CLKM]

 

create_generated_clock -name CLK_STROBE -source CLKM -divide_by 1 [get_ports CLK_STROBE]

 

通过结合建立时间和保持时间检查以及多周期路径约束来指定时序窗口要求。该时序要求对应在单个上升沿(相同的发起沿和捕获沿)处进行建立时间检查。因此,我们将多周期建立时间指定为 0。

 

  • set_multicycle_path 0 -setup -to [get_ports DATAQ]

 

另外,保持时间检查必须在同一时钟沿上执行,因此我们需要将多周期保持时间指定为 -1。

 

  • set_multicycle_path -1 -hold -to [get_ports DATAQ]

 

现在,相对于时钟 CLK_STROBE 指定输出的时序约束:

 

set_output_delay -max -1.0 -clock CLK_STROBE [get_ports DATAQ]

 

set_output_delay -min +2.0 -clock CLK_STROBE [get_ports DATAQ]

 

请注意,输出延迟约束中指定的最小值大于最大值。之所以会这样,是因为在这种情况下,输出延迟约束并不对应于实际的逻辑块。与典型的输出接口(其中输出延迟约束对应于输出处的逻辑块)不同,源同步接口中的 set_output_delay 约束只是一种机制,用于验证输出是否被限制在了时钟有效沿附近的指定窗口内才能切换 。因此,我们才会有最小输出延迟大于最大输出延迟这样的一种异常情况。

 

这是针对以上约束的建立时间检查路径报告:

 

 

请注意,数据发起沿和捕获沿都为在 0 时刻处的相同时钟沿。该报告显示 DATAQ 在 0.61ns 处变化,而 CLK_STROBE 在 0.09ns 处变化。由于 DATAQ 可以在 CLK_STROBE 的 1ns 内被允许变化,因此在考虑了 0.3ns 的时钟不确定性后,正裕量为 0.18ns。

 

以下是保持时间检查的路径报告,用于检查时钟另一侧的界限:

 

 

在上述最小路径分析中,DATAQ 在 0.48ns 处到达,而 CLK_STROBE 在 0.09ns 处到达。由于要求是数据最早可以在 CLK_STROBE 之前 2ns 处发生改变,因此在考虑了 50ps 的时钟不确定度后,我们获得了 2.35ns 的正裕量。

 

源同步接口的另一个示例如图 9-6 所示。在这种情况下,输出时钟是主时钟的二分频,并且是数据同步接口的一部分。输出 POUT 被限制在 QCLKOUT 之前 2ns 和之后 1ns 之间才能进行改变。

 

图 9-6

 

以下是这种情况的时序约束:

 

create_clock -name CLKM -period 6 [get_ports CLKM]

 

create_generated_clock -name QCLKOUT -source CLKM -divide_by 2 [get_ports QCLKOUT]

 

set_multicycle_path 0 -setup -to [get_ports POUT]

 

set_multicycle_path -1 -hold -to [get_ports POUT]

 

set_output_delay -max -1.0 -clock QCLKOUT [get_ports POUT]

 

set_output_delay -min +2.0 -clock QCLKOUT [get_ports POUT]

 

以下是建立时间检查的路径报告:

 

 

请注意,多周期路径约束已将建立时间检查沿向后移了一个周期,以便在同一时钟沿执行检查。输出 POUT 在 0.61ns 处变化,而时钟 QCLKOUT 在 0.27ns 处变化。基于在时钟沿 1ns 内允许变化的要求,并考虑 0.30ns 的时钟不确定度,我们可得 0.36ns 的正裕量。

 

接下来是保持时间检查的路径报告,用于检查时序窗口要求的另一个约束:

 

 

路径报告显示,数据是在 QCLKOUT 时钟边沿之前的 2ns 时序窗口内才发生改变的,并且有 2.17ns 的正裕量。

 

9.2 SRAM 接口

SRAM 接口中的所有数据传输仅发生在时钟的有效沿处,所有信号仅在有效时钟沿处由 SRAM 锁存或由 SRAM 发起。组成 SRAM 接口的信号包括命令(command)、地址(address)、控制输出总线(CAC)、双向数据总线(DQ)和时钟。在写周期(write cycle)中,DUA 将数据写到 SRAM 中去,数据和地址从 DUA 传送到 SRAM 中去,并都在有效时钟沿处被锁存在 SRAM 中。在读周期(read cycle)中,地址信号仍然从 DUA 传送到 SRAM 中去,而数据信号则是由 SRAM 输出给 DUA 的。因此,地址和控制信号是单向的且方向为从 DUA 到 SRAM,如图 9-7 所示。通常将延迟锁定环 DLL(Delay-Locked Loop)放置在时钟路径中,DLL 允许在必要时延迟时钟信号,以解决由于 PVT 和其它外部变化而导致接口上各种信号的延迟变化。通过考虑这些变化,在往返于 SRAM 的读周期和写周期中,都将有良好的时序裕度可用于数据传输。

 

图 9-7

 

图 9-8 显示了典型 SRAM 接口的 AC 特性。请注意,图 9-8 中的数据输入和数据输出是指 SRAM 看到的方向。来自 SRAM 的 Data out 是 DUA 的输入,进入 SRAM 的 Data in 是 DUA 的输出。

 

图 9-8

 

图 9-8 中的要求可以转换为用于 DUA 与 SRAM 之间接口的以下 IO 接口约束:

 

create_clock -name PLL_CLK -period 5 [get_pins UPLL0/CLKOUT]

 

create_generated_clock -name SRAM_CLK -source [get_pins UPLL0/CLKOUT] -divide_by 1 [get_ports SRAM_CLK]

 

set_output_delay -max 1.5 -clock SRAM_CLK [get_ports ADDR[*]]

 

set_output_delay -min -0.5 -clock SRAM_CLK [get_ports ADDR[*]]

 

set_output_delay -max 1.7 -clock SRAM_CLK [get_ports DQ[*]]

 

set_output_delay -min -0.8 -clock SRAM_CLK [get_ports DQ[*]]

 

set_input_delay -max 3.2 -clock SRAM_CLK [get_ports DQ[*]]

 

set_input_delay -min 1.7 -clock SRAM_CLK [get_ports DQ[*]]

 

以下是典型地址引脚的建立时间检查路径报告:

 

 

建立时间检查将验证地址信号是否在 SRAM_CLK 时钟沿之前 1.5ns(SRAM 地址引脚的建立时间)到达 SRAM。

 

以下是相同地址引脚的保持时间检查路径报告:

 

 

保持时间检查将验证地址信号在 SRAM_CLK 时钟沿之后是否继续保持稳定了 0.5ns。