原创 TimeQuest User Guide 翻译3

2015-3-30 21:25 2313 19 19 分类: FPGA/CPLD

I/O Timing

(Note:这部分不会明确的包含source-synchronous interface的内容,虽然他们都使用相同的规则)
     IO约束仅仅有两个.sdc命令,分别是
set_input_delay    set_output_delay  ,但是这两个命令开始还是比较难理解的。其实这两个命令最重要的内容,就是描述在FPGA的外面发生了什么,通过得到外部的描述,TimeQuest能够得到FPGA内部需要满足的要求是什么。这里我将其分成五个步骤:

1. 添加
create_clock   命令,为IO接口创建一个virtual clock。
2. 为IO口添加
set_input_delay  或者 set_output_delay  。分别用-min和-max选项各添加两个描述,并将0.0作为它们的value(这部分将在第5步重新修改);
3. 设定FPGA clock和virtual clock之间的setup 、hold relationship。、
4. 添加Multicycle如果必要的话;
5. 修改-max 和-min delay value 来保证外部延时(修改第2步的0.0值)。

需要指出的是,
set_output_delay   set_output_delay  的值是在最后一步确认的。这对很多新人来说是完全相反的步骤。在浏览后续步骤之后,大家就能了解这是为什么了。同时可能注意到了,双向IO口,同时最为输入输出口,会同时用到前面两个约束。

Step 1) Use create_clock to add a virtual clock for the I/O interface

这总是第一步。如果FPGA设备和一个66MHz的PCI设备、200MHz的DAC设备通信,那么设计者会添加如下命令:

create_clock -period 15.151 -name pci_clk_ext
create_clock -period 5.0 -name dac_clk_ext

注意到,这里并没有将时钟连接到FPGA的某个端口,这样它们就变成了virtual clock;他们在FPGA外部存在。接下来就要介绍怎么使用这两个vritual clock。

Step 2) Add set_input_delay or set_output_delay on the I/O port/s Add it twice, once using -min and once using -max. Use the value 0.0 for both delays, and the virtual clock for the clock

这部分命令虽然会有点长,但是却很简单。如果约束一个叫做DAC_DATA[5]的端口,我会添加一下命令到.sdc文件中:

set_output_delay -clock dac_clk_ext -max 0.0 [get_ports DAC_DATA[5]]
set_output_delay -clock dac_clk_ext -min  0.0 [get_ports DAC_DATA[5]]

如上所示,-
clock  选项用来描述第一步生成的virtual clock。同时-max和-min值是0.0。(我们会修改0.0的值在第5步)。
对于一个输入总线,我想对每根信号线使用相同的约束,那么我会这样写:

set_input_delay -clock adc_clk_ext -max 0.0 [get_ports ADC_DATA
  • ]
    set_input_delay -clock adc_clk_ext -min  0.0 [get_ports ADC_DATA
  • ]

    这步是相当直接明了的,因为我只是按照步骤操作,并没有进行任何消耗脑细胞的分析过程。虽然简单,但我们不能忽略这几句话产生的作用,虽然本质上讲,除了描述FPGA外部在发生什么,它们并没有约束任何东西。让我们看看我们的输出约束:
    1. set_output_delay \        #有一个寄存器被FPGA的输出端口所驱动
    2. -clock dac_clk_ext \     #该寄存器的时钟是所谓的 virtual clock dac_clk_ext
    3. -max/- min 0. 0 \           #外部延时有0.0 的最大值 和最小值
    4. [get_ports DAC_DATA[5] \  #该寄存器被FPGA的端口 DAC_DATA[[5]驱动
    下面换成结构图来分析一下这个命令:
    20150330212124774.jpg
    如上图所示,我们仅仅描述的是FPGA外部的电路。
    这样就构成了一个完整的寄存器到寄存器之间的分析模型(对应于FPGA内部的两寄存器间时序分析模型)。
    Step 3) Determine the default setup and hold relationship between the FPGA clock and virtual clock

    这一步要求设计者决定FPGA内部的时钟和外部的virtual clock 之间的 setup 、hold relationship。这一步通常是很直截了当的,因为大多数情况下,发射沿时钟和锁存沿时钟是同周期并且没有时钟偏移的,它们的关系如下图左上角所示:
    20150330212139787.jpg
    对IO口来说,virtual clock将会成为外部输入的发射时钟(launch clock)或者外部输出寄存器的锁存时钟(latch clock)。在Timing Analysis Basics章节里面有关于setup hold relationship的详细介绍。相比于挖掘这些relationship,这里我将要说明TimeQuest的relationship是怎样被展示的,因此设计者不需要提前搞明白。举个例子,设计中有一个100MHz的时钟输入FPGA中,它经过PLL并驱动数据输出100Mbps。经过之前的约束步骤以后,设计者创建了一个10ns的外部时钟,并将其应用在输出端口:

    create_clock -period 10.0 -name tx_clk_ext
    set_output_delay -clock tx_clk_ext -max 0 .0 [get_ports {TX_DATA
  • TX_PAR}]
    set_output_delay -clock tx_clk_ext -min 0 .0 [get_ports TX_DATA
  • TX_PAR}]

    该例子当中,创建了一个叫做 tx_clk_ext的虚拟时钟。tx_clk_ext作为外部寄存器的触发时钟,TX_DATA
  • 和TX_PAR作为驱动端口。到寄存器的最大最小延时设置成0.0ns。介于FPGA内部时钟也是10ns的周期,并且没有相移,所以默认的setup relationship就是 10ns,默认的hold relationship就是0ns。如果设计者不能确定这些条件,那么可以使用iterative method命令读入.sdc文件,并使用 report timing 命令来报告这些端口。
    在TimeQuest的下拉菜单中,Reports->Custom Reports->Report Timing。就将虚拟时钟的名字tx_clk_ext填入 “To Clock ”选项中,然后运行report timing twice,一次得到setup relationship,一次得到 hold relationship。
    20150330212358610.jpg
    左边代表setup 关系分析,红色框出的列即是relationship,10ns。在summary of paths下面是第一条路径的细节信息。
         当launch clock进入FPGA,到达源寄存器(这里是FPGA内部的输出寄存器),然后经过输出端口到达外部寄存器,数据到达时间必须大于0ns(hold relationship 决定),小于10ns(setup relationship决定)。鉴于设计的外部延时最大最小都是0.0ns,即没有外部数据延时,则至需要FPGA内部的延时在0~10ns之间即可。到这里为止,我们得到了一个完整的时序约束,虽然这不一定是我们想得到的最好分析结果。
    Step 4) Add multicycles
    这一步通常不是必要的。但是如果第3步默认条件下 的分析不满足时序要求,则需要使用multicycle来修正setup 和 hold relationship。最一般的例子便是设计者需要open the window(改变relationship的窗口大小?) 或者 shift the window(将relationship的窗口整体后移?)。注意到这一步,我们并不会去确认外部延时的大小(诸如外部寄存器的Tsu,Tco,以及外部走线延时),这个会在第5步的时候解决。第4步仅仅是确保时钟relationship关系正确。
    下面是一个flash 接口的示例:

    set_multicycle_path -setup -to [ get_ports {FLASH_DATA
  • }] 4
    set_multicycle_path -hold  -to [ get_ports {FLASH_DATA
  • }] 3

    这两句话高速TimeQuest FLASH_DATA进入FPGA有4个时钟周期的余量,如果原来的relationship是10ns和0ns,现在就是40ns和0ns。
    如果FPGA内部的时钟有一个相移,而外部时钟没有,那么设计者可能需要 shift the window  。比如,如果FPGA提供给外部输出寄存器的时钟信号有500ps的延时,那么默认的setup relationship只有500ps。而shift the window操作则如下:

    set_multicycle_path -setup -to [ get_ports {FLASH_DATA
  • }] 2
    or:
    set_multicycle_path -setup -from [ get_clocks {pll |clk[ 0]} -to [get_clocks clk_ext] 2


    第一句话修改了输出路径的clock relationship。第二句话则修改了这两个时钟间路径的所有relationship。任意一条命令都能正确工作。如果时钟是10ns周期,那么此处的修改则会让setup relationship从0.5ns变成9.5ns,而hold relationship则从-9.5ns到0.5ns。
    注意到如果FPGA时钟的相移是往前的而不是向后的,那么multicycle可能就必要设置了。例如,时钟周期10ns,相移是提前了0.5ns。那么setup relationship就变成了9.5ns,不需要额外设置multicycle。
    输入的设置则和上面相反。这部分在章节 default setup and hold  , specifically the   affect of phase-shifts  .有详细介绍。
    Step 5) Modify the -max and -min delays to account for external delays.
    到这里为止,我们得到了正确的relationship,现在到了修改-max -min 值的时候了。当前他们的值还是0ns,这意味着模型没有延时,整个data window(即余量时间)都被FPGA 的延时用了。但实际上,data window 中的一部分是被外部设备延时和走线延时(board delay)利用的。-max 和-min就是估计这些外部的延时的。
    当-max和-min都为0,则外部延时不会对我们的内部分析产生影响。一旦-max增大,则会缩小我们的 setup relationship。如:如果我们默认的setup relationship是10ns,而-max 为4ns,那么FPGA最大的data delay只能是6ns(而不是之前的10ns了)。注意到setup relationship仍然是10ns,只不过是FPGA内部延时要求变了。所以-max越大,FPGA的数据延时越小,时序越难满足。Tco就必须很小。
         -min则很容易混淆视听,因为它完全是以相反的方式在工作的。即-min越小,越难满足。如果hold relationship是0ns,而-min是 -1ns(Note:这里负号是因为Th保持时间,见下面的计算公式),则对FPGA来说,唯一满足时序的方式就是在1ns之后得到输出数据,见下图:
  • 20150330212427499.jpg
    第一幅图显示的是默认的relationship,第二幅则是存在外部延时的relationship。FPGA在第二幅图中必须满足数据输出时间在1ns~6ns之间。同样的,对于外部寄存器输入FPGA的时序约束:
    20150330212440758.jpg
    大家可能对两个箭头不从同一个点开始表示疑惑。这里传达的信息是:当外部launch clock 发射数据时,可能在 -1ns~4ns之间任意一个时间点到达FPGA,因而我们使用最大的来分析setup relationship,最小的分析hold relationship。
    外部延时是怎样添加到timing reports中,见章节correlating constraints to the timing reports.
    以输出为例,默认relationship是数据要在0~10ns之间传递过来,当外部延时改为-1ns~4ns,外部设备使用了10ns window中的5ns,所以FPGA只有5ns的 时间余量来工作。这里特地说明这一点,是因为设计者总是不能立即看清存在的relationship,点出来有助于大家的理解。
    现在我们来看看外部延时是怎么工作的,首先看FPGA到外部输出:

    External device parameters:
    Tsu_ext = Tsu of external device
    Th_ext   = Th of external device
    Data delays on board:
    Max_fpga2ext = Max board delay to external device
    min_fpga2ext  = min board delay to external device

    set_output_delay -max = Tsu_ext (外部寄存器建立时间) + Max_fpga2ext(最大board delay)
    set_output_delay -min  = -Th_ext (外部寄存器保持时间,有负号) + Min_fpga2ext(最小board delay)

    而外部数据输入FPGA则是如下:
    External device parameters:
    Tco_ext       = Tsu of external device
    minTco_ext = Th of external device
    Data delays on board:
    Max_ext2fpga = Max board delay from external device to FPGA
    min_ext2fpga  = min board delay from external device to FPGA
    Clock delays on board:
    Max_clk2fpga = Max delay from board clock to FPGA
    min_clk2fpga  = min board delay from clock to FPGA
    Max_clk2ext   = Max delay from board clock to external device
    min_clk2ext    = min board delay from clock to external device

    set_input_delay -max = Tco_ext(外部寄存器建立时间) + Max_ext2fpg(最大到FPGA的board delay)
    set_input_delay -min  = minTco_ext (外部寄存器保持时间)+ min_ext2fpga(最小到FPGA的board delay)

    设计者可以将参数和公式输入到.sdc文件中,这部分在Tcl Syntax部分有写。

    注意到,这里公式并没有考虑到board level 的时钟偏斜(clock skew),同时这里假设到FPGA和到外部寄存器的时钟是相同的。实际上有一个很好的描述board-level clock delay的 .sdc约束命令。接下来会给大家说明。我看到很多设计者将board-level clock skews 计算到-max 和-min 的值里(注意当时钟到目的寄存器时间大于到源寄存器时间,clock skew是正的)。总之,加入skew的计算公式如下:

    External device parameters外部寄存器参数:
    Tsu_ext = Tsu of external device
    Th_ext = Th of external device
    Data delays on board板上数据延时:
    Max_fpga2ext = Max board delay to external device
    min_fpga2ext = min board delay to external device
    Clock delays on board板上时钟延时:
    Max_clk2fpga = Max delay from board clock to FPGA
    min_clk2ext = min board delay from clock to external device
    Max_clk2ext = Max delay from board clock to external device
    min_clk2fpga = min board delay from clock to FPGA

    set_output_delay -max = Tsu_ext(外部寄存器建立时间) + Max_fpga2ext(FPGA到外部寄存器最大板上延时) - (min_clk2ext - Max_clk2fpga)= Tsu_ext + Max_fpga2ext - (min_clk_skew)
    set_output_delay -min = -Th_ext +  min_fpga2ext -  (Max_clk2ext - min_clk2fpga)= -Th_ext + min_fpga2ext -  (Max_clk_skew)

    对输入延时来说:
    External device parameters:
    Tco_ext = Tco of external device
    minTco_ext = min Tco of external device
    Data delays on board:
    Max_ext2fpga = Max board delay from external device to FPGA
    min_ext2fpga = min board delay from external device to FPGA
    Clock delays on board:
    Max_clk2fpga = Max delay from board clock to FPGA
    min_clk2fpga = min board delay from clock to FPGA
    Max_clk2ext = Max delay from board clock to external device
    min_clk2ext = min board delay from clock to external device

    set_input_delay -max = Tco_ext + Max_ext2fpg - (min_clk2fpga - Max_clk2ext)= Tco_ext + Max_ext2fpg - (min_clk_skew)
    set_input_delay -min  = minTco_ext + min_ext2fpga - (Max_clk2fpga - min_clk2ext)= minTco_ext + min_ext2fpga - (Max_clk_skew)

    下面是一个框图
    20150330212508692.jpg
    板上时钟画了两个,一个用于输入,一个用于输出,通常情况它们其实是一个时钟源。
    计算方程在上面已经给出了。SDC有着非常好的约束命令,允许设计者输入board-level的外部时钟延时:

    set_clock_latency -source - late 2 . 0 [get_clocks clk_fpga ]
    set_clock_latency -source - early 1 . 8 [get_clocks clk_fpga ]
    set_clock_latency -source - late 2 . 3 [get_clocks clk_ext ]
    set_clock_latency -source - early 2 . 1 [get_clocks clk_ext ]

    TimeQuest将会自动把这些信息加入数序分析中,而不用我们自己去计算。这样我们不就用担心时钟偏斜,到底在计算时间是减还是加,搞得一头雾水。到底采用将board-level 时钟延时加入到-max -min中,还是使用set_clock_latency命令让TimeQuest自己去计算分析,都取决于设计者。只要用好了,效果是一样的。





    PARTNER CONTENT

    文章评论0条评论)

    登录后参与讨论
    EE直播间
    更多
    我要评论
    0
    19
    关闭 站长推荐上一条 /3 下一条