XILLINX时序约束命令解析&Anlogic例子说明

文章目录

  • 时钟
    • primary clock 基准时钟
    • master clock主时钟
    • 虚拟时钟
    • 生成时钟
    • 安路俩条衍生时钟语句
    • 时钟延迟
    • 时钟不确定性
  • IO约束
    • 设置输入延时
    • 设置输出延时
  • 时序例外
    • 设置伪路径
    • 设置时钟组
    • 设置最大最小延迟
    • 设置多周期路径

目录

时钟

primary clock 基准时钟

primary这里有“基本的”更贴切,虽然其有“主要的、首要的、初级的、原发性的”意思。
提供的基准时钟有俩种情况:

  • 时钟由外部时钟源提供,通过输入引脚进入FPGA;
  • 高速收发器(GT)的时钟RXOUTCLK或TXOUTCLK;

注:对于7系列FPGA,需要对GT的这俩个时钟手工约束;对于UltraScale FPGA,只需要对GT的输入时钟约束即可。

约束用到的TCL命令:
XILLINX时序约束命令解析&Anlogic例子说明_第1张图片
对于此create_clock命令,可以定义基准时钟(时序分析的起点),也可以定义虚拟时钟。
虚拟时钟在设计里没有源头,虚拟时钟是用作输入输出延迟时使用,但是在设计里并不是物理存在。
那么,对于一个物理真实存在的时钟也可以生成一个新时钟,并且这个新时钟可以从主时钟那派生出它的许多属性,用的命令是 create_generated_clock 。
要注意,如果你使用create_clock命令而不是用create_generated_clock命令来创建一个“生成时钟”,新创建的这个时钟不继承源时钟的任何属性。那么将导致内部插入的母时钟延迟和抖动不会传播给生成的时钟,这就会导致错误的时序分析。

命令解析:

-period <arg>
必须要的,是指定被创建的时钟对象的周期,以纳秒为单位,值必须大于0-name <arg>
可选的,被创建的时钟对象的名字。如果你省略了名字,系统就会通过被定义的源头“<objects>”来生成名字。
你当然可以不通过源"< objects >",用“-name”来自己命名。
对于创建设计中没有物理源头的虚拟时钟时,你肯定要选“-name< arg >,因为虚拟时钟是无“< objects >”,所以才需自己创建。

-waveform <arg1 arg2 ...>
可选的,指定时钟的上升沿和下降沿时间,以纳秒为单位,要覆盖到一个整时钟周期才行。
你可以使用多个上升沿和下降沿来定义波形的特征,但是边沿数必须是偶数值,这样才能把波形俩个边沿都表征出来。
第一个指定的时间"arg1"代表第一个上升过渡时间,第二个参数“arg2”指随之而来的下降沿。
如果下降沿的值小于上升沿的值,意味着下降沿出现在上升沿之前。
若是不指定波形,系统会默认波形上升沿在时刻0.0ns,下降沿是指定周期的一半的时间时刻。

-add
可选的,在同一源上定义不同的时钟波形,以同时分析不同的时钟波形。用“-name”来指定添加的新的时钟。
若你不对此操作进行说明(即不用-add操作),那么 create_clock 命令将覆盖掉已经存在的时钟名字。

-quiet
可选的,安静的执行命令,不从命令台返回任何消息。命令台会返回TCL_OK,而不是任何在执行过程遇到的错误。


-verbose
可选的,临时解除任何消息限制,并且从命令台返回所有信息。verbose有详细的意思。注:消息限制可以由set_msg_config命令来进行定义。


< objects >
可选的,端口、pin脚、网络都可能是这个被定义的时钟的源。
如果你定义一个时钟在一个源对象上,源上已经有一个时钟,新的时钟将覆盖掉原来的时钟,除非你使用“-add”操作。
如果没有"< objects >"操作被说明来连接到时钟对象上,被创建的时钟就会被当做虚拟时钟。

master clock主时钟

主时钟可以是基准时钟,也可以是其他的生成时钟。在好多资料里面,把primary clock和master clock翻译成都是主时钟,其实是有区别的。那么怎么鉴别这个是主时钟呢?这就要谈到时钟时序约束命令
create_generated_clock,主时钟是这条命令的起点。生成的时钟属性是由主时钟衍生而来,而不是说明他们的周期和波形,所以必须要描述电路是如何通过转换主时钟来产生生成时钟的。

对于生成时钟有三种情况:

  • 用户定义的生成时钟(用户自定义的生成时钟所定义到的网表对象上是不会被工具进行自动衍生的)
  • 工具自动衍生时钟(若主时钟已经被定义【就基准时钟定义后】,Vivado IDE会自动在Clock Modifying Blocks的输出pin脚上创建约束)
  • 重命名自动衍生时钟

用户自定义的生成时钟:

  • 用create_generated_clock命令来定义
  • 要依附于一个网络列表对象,最好是时钟根时钟脚

指定主时钟是用“ -source ”操作,表示着设计中传播的主时钟pin脚或端口。在数字IC设计中create_generated_clock 是用来说明generated clock与source clock的相位(边沿)关系,同时根据source clock找到master clock的关系,最终会确定generated clock和master clock的相位关系。我们常用设计中主要的时钟源点(一般指基准时钟,为了简单方便在FPGA里我们先定义这个create_clock命令,把primary clock定义好后,下面定义生成时钟时源选的就是primary clock所以一些资料才把主时钟和primary clock看成是一样的)或者设计生成的时钟源单元的输入引脚来确定为“主时钟”。

举个例子,primary clock是一个周期为10ns的时钟。primary clock通过寄存器REGA来驱动其寄存器时钟pin脚来实现二分频,相对应产生的二分频时钟就叫clkdiv2。
XILLINX时序约束命令解析&Anlogic例子说明_第2张图片
那么俩条等效的约束语句如下:
create_clock -name clkin -period 10 [get_ports clkin]
#Option 1: master clock source is the primary clock source point

create_generated_clock -name clkdiv2 -source [get_ports clkin] -divide_by 2 [get_pins REGA/Q]
#Option 2: master clock source is the REGA clock pin
create_generated_clock -name clkdiv2 -source [get_pins REGA/C] -divide_by 2
\ [get_pins REGA/Q]

注意,在数字IC设计领域里的master clock和Xillinx的定义说明有点区别,也导致我之前比较疑惑,现在梳理一下。
书《Static Timing Analysis for Nanometer Designs A Practical Approach》里明确提到,生成时钟(generated clock)是由主时钟衍生而来,主时钟是用create_clock来进行定义的。
xillinx文档ug835对create_generated_clock的-source操作描述为“master clock source object pin/port”,在数字IC中,这个-source是表示生成时钟的源时钟,xillinx就是把这个叫做主时钟,而xillinx里的primary clock是数字IC所指的master clock,两者用同一TCL命令进行时钟定义(create_clock)。

微信公众号“吾爱IC社区”有一篇文章“深度解析Create_clock与Create_generated_clock的区别”中一个例子很值得思考。作者写道:
在数字IC设计中,芯片中各个模块的工作频率可能都不太一样。因此有了时钟产生电路(clock generation)。这个电路含有时钟切换电路,时钟分频,倍频电路以及clock reset电路。通常我们通过create_generated_clock来定义时钟分频和倍频电路后的时钟。
create_generated_clock 是用来说明generated clock与source clock的相位(边沿)关系。同时根据source clock找到master clock以及source clock 和master clock的关系, 最终会确定generated clock和master clock的相位(边沿)关系。
在genereated clock的时候一定要明确generated clock与master clock的相位关系(rise->rise or rise->fall or fall->rise or fall->fall), 这些关系由桥梁source clock嫁接,所以有了generated clock和source clock,以及source clock和master clock的关系。

如果根据声明找到的generated clock和master clock(作者是在数字IC设计的角度这么看的,这里对应的就是xillinx里说的primary clock)的关系和实际的关系不一致,则会造成一些分析错误。比如静态时序分析STA的时候找不到generated clock和source clock(就是-source的option,对应是xillinx所说的master clock)相位关系,会将generated clock的source latency设置为0。
见下图:
XILLINX时序约束命令解析&Anlogic例子说明_第3张图片
XILLINX时序约束命令解析&Anlogic例子说明_第4张图片
根据上面的定义,generated_clock是定义在二分频的输出端Q上,其source为CLK。但是我们知道Udiv这个寄存器的时钟端CK与CLK是反相的(相位差180°)。
根据声明,generated和master clock的关系如下(工具会根据source clock找到master clock,并确定source clock和master clock的关系,当前source clock即master clock[注:再次强调一下,换成xillinx的说法就是,当前master clock即primary clock])。但是实际电路是source clock和master clock存在180°相位差的,因此以上定义的generated_clock是不正确的。
分析电路的状态方程及数字波形应该为:
XILLINX时序约束命令解析&Anlogic例子说明_第5张图片
所以UFF1到UFF2的setup检查为launch clock edge为T=5ns时刻,capture clock edge为T=15ns时刻(默认为single cycle path)。
作者说,可以用俩种方法来定义分频后的时钟:

  • 改变generated clock的source,即让generated clock和source clock的路径唯一且单一(单一是指,声明的相位边沿关系和实际相位边沿关系一致)。做法如下:
    create_generated_clock
    -name CLKdiv2 \

    -divide_by 2 \

    -source[get_pins Udiv/CLK] \

    [get_pins Udiv/Q]

这样generated clock和source clock的关系和声明的一致。 工具会根据声明的source clock 找到它的master clock,同时确定source clock和master clock相位相反的关系, 由此就确定了generated clock和master clock的关系

  • 直接声明generated clock和master clock的相位边沿关系。如下:
    create_generated_clock

-name CLKdiv2 \

-edges {2 4 6} \

-source CLK \

[get_pins Udiv/Q]

作者说虽然这俩种方法都可以用来定义generated_clock,但是考虑到后期review constraint的便利性,建议使用第二种方法实现。对于Vivado来说,我不知道是不是设置成第二种方便,不过第一种是很好记的,觉得首推。

虚拟时钟

虚拟时钟也是通过create_clock命令来定义,只是没有指定源对象(source object)。
虚拟时钟一定要在input/output delay约束前来使用,为input/output delay服务。
对于到达FPGA端口上的数据din,软件工具在综合的时候是可以推导出终点的时钟域的,但是起点呢,工具无法推导,那么就需要手动来告诉工具起点的时钟是什么样的,所以定义了虚拟时钟,而且虚拟时钟又可以与设计时钟分离,在对虚拟时钟特性上进行约束时,可以不改变设计时钟的特性。

下面的情景用虚拟时钟:

  • 外部器件到FPGA使用非设计时钟:
      可能是FPGA里的时钟倍频、分频而来;
      可能是FPGA内部MMCM/PLL生成而来。
  • 在PCB上路径延时不同,在不改变内部时钟特性情况下,我们需要来对I/O设置时钟延迟和抖动约束:
      可能板子由于Clock Buffe chip导致时延不同。

总结一下,如果不设置虚拟时钟,那么在设置输入延迟和输出延迟的时候,参考时钟都是同一个时钟;但是该时钟在输入路径和输出路径中所处的情况并不一定是相同的,比如时钟频率不同或者latency不同。

那么这个时候就应该分别考虑各自的实际情况来选择设置输入输出延迟的参考时钟,显然此时共用一个时钟是不行的,因为如果给参考时钟添加latency,势必会对两者都产生影响。那么就需要新建一个虚拟时钟作为参考时钟,然后根据自己路径上的实际情况给虚拟时钟添加latency或做一些其他的设置。

例1:vclk has sample period as internal clock (MMCM output clk)
XILLINX时序约束命令解析&Anlogic例子说明_第6张图片
create_clock -name sysclk -period 10 [get_ports clkin]

create_clock -name vclk -period 5

set_input_delay 4 -clock sysclk [get_ports dina]

set_input_delay 2 -clock vclk [get_ports dinb]

例2:external clock has delay
XILLINX时序约束命令解析&Anlogic例子说明_第7张图片
create_clock -name sysclk -period 10 [get_ports clkin]

create_clock -name virtclk -period 10

set_clock_latency -source 1 [get_clocks virtclk]

set_input_delay -clock virtclk -max 4 -min 2 [get_ports dina]

例3:
系统同步输入接口情况下,上游器件送入的数据并不是跟某个FPGA 中已经存在的真实时钟相关,而是来自于一个不同的时钟,所以这时用到虚拟时钟。
上游器件用一个100MHz时钟送出数据到FPGA,实际上这个数据每两个时钟周期才变化一次,所以可以用50MHz时钟来采样。FPGA有个100MHz输入时钟,经过MMCM产生一个50MHz衍生时钟,并用其来采样上游器件送来的同步数据。当然,系统级设计上,必须有一定机制保证上游器件的发送时钟和FPGA中的接收时钟的时钟沿对齐。此时,可以借助虚拟时钟完成相应Input 接口约束。

create_clock -name clk_100 -period 10 [get_ports i_clk_100mhz]

create_clock -name clk_50_virtual -period 20

set_input_delay -max 5.2 -min 2.0 -clock clk_50_virtual [get_ports i_data_50]

生成时钟

XILLINX时序约束命令解析&Anlogic例子说明_第8张图片
根据设计中存在的物理时钟对象创建一个新的时钟对象。

时钟被添加到设计中可以有三种方法:
1、Primary physical或虚拟时钟可以用create_clock命令;
2、用create_generated_clock命令来从primary physical clock定义衍生时钟;
3、当时钟经过MMCM/PLL/BUFR,通过VIVADO软件自动产生衍生时钟;
命令解析:

-name<arg>
可选的。在指定的对象上创建生成时钟的名称,或者在指定对象上分配给一个已经存在的时钟。
如果没有名字定义,生成时钟将会被赋予<object>同样的名字,如果同一个名字被分配到多个<object>上,名字将被分配给第一个对象上。

-add
可选的。在同一信号源上定义多个时钟,用于同时分析不同的时钟波形。使用 -name 命令来指定一个新的时钟。
如果没有此-add操作,create_clock命令将自动分配一个名字,且覆盖之前的时钟名字。-master_clock和-name操作一定要加上-add。

-source<arg>
可选的。主时钟的pin或port,从中导出生成时钟。
主时钟必须是先前定义的物理时钟,不是一个虚拟时钟,但是可以是一个primary时钟或者另外一个生成时钟。
如果这个source pin或port被多个时钟定义了,这个 -master_clock选项必须被使用来定义 在source上 哪一个时钟被用来定义生成时钟。

-edge<arg>
可选的。列出主时钟的边沿,用来定义生成时钟的翻转边沿。
通过数主时钟的相应的边沿序号数,从第一个边沿开始数,用序列号123来指定生成时钟的翻转边沿位置。
生成时钟翻转的序号数定义了时钟的周期占空比等信息,
位置1是生成时钟的第一个上升沿,位置2是生成时钟的第一个下降沿,此时定义了占空比 。位置3是生成时钟的第二个上升沿,此时有了时钟周期的信息。

-edge_shift <arg>
可选的。通过定义一个值,来指示生成时钟相较于主时钟的偏移。

create_generated_clock -name gen_clk -source [get_pins clk_IBUF_BUFG_inst/O] -edges {1 3 4} -edge_shift {2.0 0.0 1.0} -add -master_clock [get_clocks  "*"] [get_pins {shiftr_reg[13]/C}]
上面的SDC语句图示如下:

XILLINX时序约束命令解析&Anlogic例子说明_第9张图片

-divide_by <arg>
可选的。主时钟建立生成时钟的分频值。必须>=1且为整数。

-multiply_by <arg>
可选的。主时钟建立生成时钟的倍频值。必须>=1且为整数。

-combinational
可选的。Vivado计算生成时钟的延迟时,默认会追踪生成时钟的源管脚与上级时钟的源管脚之间的所有组合和时序路径。
某些情况下可能只希望考虑组合逻辑路径,在命令行后添加-combinational选项即可。

-duty_cycle <arg>
可选的。用倍频命令时,指示生成时钟的占空百分比0.0-100,默认值是50.0-invert
可选的。产生一个相位翻转的生成时钟。

-master_clock<arg>
可选的。如果在source pin或source port有多个时钟。要指定是由哪一个主时钟来产生生成时钟的。
-add和-name操作一定要指定-master_clock

-quiet
可选的。安静的执行命令,不从命令台返回任何消息。命令台会返回TCL_OK,而不是任何在执行过程遇到的错误。

-verbose
可选的,临时解除任何消息限制,并且从命令台返回所有信息。verbose有详细的意思。注:消息限制可以由set_msg_config命令来进行定义。

< objects >
必须要的。生成的时钟应该分配给的引脚或端口对象。
如果指定的对象已经有时钟定义了,用-add操作来增加新生成的时钟,这样就不会覆盖掉已存在此对象上的时钟了。

安路俩条衍生时钟语句

命令(sdc command):
derive_pll_clocks

组件(options):
-gen_basic_clock
derive_pll_clocks指自动在所有用到的PLL clkc[x]端口生成时钟约束,生成时钟的频率、相位都是按照PLL内部的参数设定。-gen_basic_clock将在对应的PLL refclk上定义FIN频率的基准时钟,否则将自动搜索refclk pin以及所连net上定义的时钟。该命令生成的时钟将在flow运行时才生效。

命令(sdc command):
derive_clocks

组件(options):
-period
-waveform { }

命令在没有定义的时钟管脚上自动创建生成时钟。

此命令在正式设计时不建议使用,所有的时钟设计都必须有约束用来进行时序分析,如果设计中没
有一个时钟约束的存在,则系统会默认时钟约束为以下两个约束(50Mhz):
derive_clocks -period 20
derive_pll_clocks

时钟延迟

XILLINX时序约束命令解析&Anlogic例子说明_第10张图片
该命令定义指定时钟、端口或引脚的时钟源或网络延迟。寄存器时钟引脚上的总时钟延迟是时钟源延迟和网络延迟的总和。
在实际环境中,FPGA 的时钟都不是绝对完美的,都有一定的延迟,其中延迟包括外部时钟到达FPGA 管脚的延迟即source latency 和FPGA管脚到达目的寄存器的延迟即network latency。network latency 是Timing Analyzer 能够自动检测并分析到的。而source latency 无法被Timing Analyzer 所知道,需要设计者告知其实际情况。比如外部反馈时钟external feedback clock 需要指定输出I/O 到输入I/O 的延迟。

命令解析:

-clock <args>
可选的。指定 有延迟要分配給指定对象的时钟列表中的时钟,
如果-clock这个变量(argument)没有使用,时钟延迟值将应用于通过指定引脚和端口的所有时钟。

-rise/fall
可选的。-rise定义上升时钟沿的延迟,-fall定义下降时钟沿的延迟。

-min/max
可选的。定义用于多种情况分析的指定时钟的最小延迟/最大延迟。

-source
可选的。定义延迟是属于源延迟。时钟源延迟只能被指定在时钟对象和时钟源pin脚上。没有-source就默认为网络延迟。

-late/early
可选的。-late通过延迟值-latency,表示比时钟边沿晚到的时间。-early通过延迟值-latency,表示比时钟边沿早来的时间。
这个-early和-late是互斥的,俩组件是互斥的,只有当用-source时才有可能使用。

<latency>
必须的。时钟延迟值,以纳秒为单位。

<objects>
必须的。指需要使用延迟的clock、pin或port等对象。指定引脚或端口对象将延迟分配给引脚或端口的可传递扇出中的所有寄存器时钟引脚。
如果-clock被使用,延迟应用于指定时钟的所有寄存器时钟引脚。另外,若是<objects>指定了一个时钟,这个-clock变量就没有必要了,且会被忽视。

时钟不确定性

时钟的不确定性主要的构成因素为时钟抖动,在FPGA 系统中,抖动一般分为三种,分别是输入抖动(实际的时钟沿与理想时钟沿的差异,输入抖动一般在创建主时钟时指定。)、周期抖动(时钟周期的偏差,主要由时钟源Pll 本身来决定,比如定义时钟周期为10ns,但是由于
pll 的精度问题,不能保证每个时钟周期都是严格等于10ns,可能在10±0.1ns 范围内变化。)、系统抖动(系统抖动是由于电源噪声,电路板噪声或系统的任何额外抖动引起的整体抖动。)。时钟不确定性用set_clock_uncertainty。
时钟源到达不同DFF 时钟输入端的延时差异叫SKEW。
XILLINX时序约束命令解析&Anlogic例子说明_第11张图片
此条命令用来增加设计中时钟不确定性,但不覆盖默认抖动计算,这被称为用户时钟不确定性。这条命令提供了一个在不改变时钟定义和时钟关系下过约束设计中的一些时钟。它可以独立地约束建立时间和保持时间路径,通过使用-setup和-hold组件。

命令解析:

-setup
可选的。用于建立时间检查的时钟不确定性设置。安路里面,setup uncertainty 在setup 时序分析时减少了时钟的setup required time。

-hold
可选的。用于保持时间检查的时钟不确定性设置。安路里面,hold uncertainty 在hold 时序分析时增加了时钟的hold required time。

-from <source_clock_name>
可选的。指定时钟不确定性的源时钟(起点时钟)。

-rise_from <source_clock_name>
可选的。指定时钟不确定性源时钟上升沿(指定起点时钟上升沿)

-to <destination_clock_name>
可选的。指定时钟不确定性的终点时钟。

-fall_from <source_clock_name>
可选的。指定时钟不确定性源时钟下降沿(指定起点时钟下降沿)

-rise_to <destination_clock_name>
可选的。指定时钟不确定性的终点时钟上升沿。

-fall_to <destination_clock_name>
可选的。指定时钟不确定性终点时钟下降沿。

<uncertainty>
必须的。时钟网络不确定度值,纳秒为单位

<objects>
可选的。指定要约束的目标时钟。

例1:
给时钟ipclk 指定0.5ns 的时钟建立时间不确定性set_clock_uncertainty -setup 0.5 [get_clocks {ipclk}]
未对ipclk 时钟加set_clock_uncertainty 的约束时序分析setup check 结果如下图,红色框内显示clock uncertainty 的值为0。
XILLINX时序约束命令解析&Anlogic例子说明_第12张图片
加了该约束语句后的时序分析setup check 结果如下图,红色框内显示clock uncertainty 的值为-0.5ns
XILLINX时序约束命令解析&Anlogic例子说明_第13张图片

例2:
给时钟ipclk 指定0.5ns 的时钟保持时间不确定性
set_clock_uncertainty -hold 0.1 [get_clocks {ipclk}]
未对ipclk 时钟加set_clock_uncertainty 的约束时序分析hold check 结果如下图,红色框内显示clockuncertainty 的值为0。
XILLINX时序约束命令解析&Anlogic例子说明_第14张图片
加了该约束后的时序分析hold check 结果如下图,红色框内显示clock uncertainty 的值为0.1ns。
XILLINX时序约束命令解析&Anlogic例子说明_第15张图片

IO约束

设置输入延时

XILLINX时序约束命令解析&Anlogic例子说明_第16张图片
指定在primary输入端口时钟沿 的外部系统路径延迟。输入延迟值是以纳秒为单位,可正可负,正负取决于器件接口上时钟和数据的相位关系。
命令解析:

-clock <arg>
可选的。(指定源寄存器驱动的时钟)指示与输入延迟相关的时钟,
默认是使用上升沿,不过当用-clock_fall变量(argument,或叫组件)时,就表示是使用下降沿。
这里的时钟可以是虚拟时钟。

-clock_fall
可选的。指定相对于时钟下降沿。

-reference_pin <arg>
可选的。-reference_pin 为 input/output delay 添加一个参考点,参考点为pin或port ,
跟-clock的参数其实是一个意思,毕竟时钟也是通过pin输入进来的。
工具会考虑参考点处的 source latency 和 network latency,用作 input/output delay 的时序分析。

-rise
可选的。指定端口的上升转换的输入延迟。默认是上升和下降转换延迟。

-fall
可选的。指定端口的下降转换的输入延迟。默认是上升和下降转换延迟。

-max
可选的。表示输入延迟的最大(最长)路径延迟。

-min
可选的。表示输入延迟的最小(最短)路径延迟。

-add_delay
可选的。对已经使用set_input_delay约束在某端口的情况下,添加另外的延迟约束到端口上,如果不加,新的命令会取代已存在的延迟。

-network_latency_included
可选的。表示时延值中包含参考时钟的时钟网络时延。
除非指定的输入或输出延迟值包括源延迟或网络延迟,否则Vivado时序引擎会在时钟延迟之后考虑时钟边缘到达捕获触发器。

-source_latency_included
可选的。表示时延值中包含参考时钟的源端延迟。

< delay >
必须的。延迟值。

< objects >
必须的。分配延迟值的端口。

场景一:系统同步
XILLINX时序约束命令解析&Anlogic例子说明_第17张图片
如上图所示,ASIC 与FPGA 为同源时钟,且FPGA 的输入数据DIN 为ASIC 的输出数据DOUT,那么在FPGA 对DIN 进行数据采样时,其到达FPGA 内部寄存器的时间应该仍然满足其建立保持时间,否则采样的数据就会出错。现对上面的情景做如下延迟分析:

set_input_delay(-max)来约束输入建立时间(setup time),即在外部最大输入延迟时,输入数据仍然能满足建立时间。
input delay max
= Board Delay(max) - Board clock skew(min) + Tco(max)
= (Tdata_PCB(max) + Tcl) + Tco(max) -(Tclk2(min)-Tclk1(max))

Data arrival time =launch edge + input delay max + Tdataint
Required time =latch edge + Tclk2int - Tsu
Slack =required time - data arrival time

Tdata_PCB(max):
为数据PCB 的布线延迟时间;
Tcl :
为电容充电延迟时间;
Tco:
代表了整个时钟到达ASIC 到寄存器然后从ASIC 输出接口输出数据的时间;
launch eddge:
源端寄存器数据发送时钟沿;
input delay max:
外部输入最大延迟;
Tdataint:
数据从FPGA 输入管脚到到达目的寄存器的最大延迟;
Latch_edge:
目的端寄存器接收数据的时钟采样沿;
Tclk2int:
为时钟从FPGA 管脚到达目的寄存器的延迟;
Tsu:
寄存器对数据进行采样要求的建立时间;

set_input_delay(-min)来约束输入保持时间(hold time),即在外部最小输入延迟时,输入数据仍然能满足保持时间。
input delay min
= Board Delay(min) - Board clock skew(max) + Tco(min)
= (Tdata_PCB(min) + Tcl) + Tco(min) - (Tclk2(max)-Tclk1(min))

Data arrival time = launch edge + input delay min + Tdataint
Required time = latch edge + Tclk2int + Th
Slack = data arrival time - required time

Launch edge:
源端寄存器数据发送时钟沿;
input delay min:
外部输入最小延迟;
Tdataint:
数据从FPGA 输入管脚到到目的寄存器的最小延迟;
Tdata_PCB(min):
为数据PCB 的布线最小延迟时间;
Latch_edge:
目的端寄存器接收数据的时钟采样沿;
Tclk2int:
为时钟从FPGA 管脚到达目的寄存器的延迟;
Th:
时钟对数据进行采样要求的保持时间;

具体例子分析1:
XILLINX时序约束命令解析&Anlogic例子说明_第18张图片
本例假设约束的输入最大延迟input delay max 为1.5+1-(-0.5)=3ns ,输入最小延迟input delay min=0.5+1-(+0.5)=1ns
create_clock -name pclk -period 8 -waveform {0 4} [get_ports {pclk}]
set_input_delay -clock pclk -max 3 [get_ports {den} {hsync} {pdata} {vsync}]
set_input_delay -clock pclk -min 1 [get_ports {den} {hsync} {pdata} {vsync}]
通过软件时序分析建立时间setup time 的结果如下图:
XILLINX时序约束命令解析&Anlogic例子说明_第19张图片
Data arrival time =launch edge + input delay max + Tdataint=0+3ns+1.453ns=4.453ns
Required time =latch edge + Tclk2int - Tsu= 8ns + 3.417ns - (-0.177ns)= 11.594ns
Slack = Required time - Data arrival time= 11.594ns – 4.453ns= 7.141ns

通过软件时序分析保持时间hold time 的结果如下图:
XILLINX时序约束命令解析&Anlogic例子说明_第20张图片
Data arrival time =launch edge + input delay min + Tdataint= 0ns + 1ns + 1.368ns= 2.368ns
Required time =latch edge + Tclk2int + Th= 0 +3.742ns + 0.178ns= 3.920ns
Slack = data arrival time - required time= 2.368ns – 3.920ns= -1.552ns
注意,在算保持时间余量的时候,Data_arrival_time和Required_time都是从一个时钟沿算的。意思是,Data_arrival_time算的是捕获沿后下一个数据的到达时间,而Data_required_time是当前数据理论上要保证的在捕获沿后的保持时间。

具体例子分析2:
大部分接口采样的应用项目中分为2 种,一种是通过虚拟时钟,虚拟时钟与源端发送的时钟同频,另外一种是通过PLL 产生采样时钟,通过此采样时钟采样源端的数据。
不论以上哪2 种方式,用户逻辑都需要处理实际的数据与时钟对应关系,做相应的逻辑处理,SDC仅用于告诉TD 工具时钟与数据对应关系。

#Created Clock
create_clock -name pclk -period 40 -waveform {0 20}
#Set Input/Output Delay
set_input_delay -clock pclk -max 3 [get_ports {den} {hsync} {pdata} {vsync}]
set_input_delay -clock pclk -min 1 [get_ports {den} {hsync} {pdata} {vsync}]

场景二:源同步
XILLINX时序约束命令解析&Anlogic例子说明_第21张图片
假设:
1)在源同步信号输入时,时钟和数据都由外部ASIC 输出,就是数据输入与采样时钟的关系已经由上级确定了(边沿对齐或中间对齐)。
a. 没有时钟抖动clock_skew;
b. 目标器件FPGA 也是用数据发送时钟进行接收数据的采样;
2)数据与时钟的布线是一样的,他们之间的相位关系保持输出时一致。
XILLINX时序约束命令解析&Anlogic例子说明_第22张图片
如上图所示
(1) 对于FPGA 的输入时钟clkin 与datain 来说,其setup/hold 时间关系已经被确定了;
(2) 推导set_input_delay 的时间值是tsu & th 的关系等式。

最大延迟时间推导:
由于数据的PCB 布线延迟与CLK 的PCB 布线延迟时间是相同的,那计算外部输入延迟时,时钟与数据的延迟可以抵消。
可得:
input delay max = Board Delay(max) - Board clock skew(min) + Tco(max)= Tco(max)
data arrival time = launch edge + input delay max+ Tdatainta
required time = latch edge + Tclk2int - Tsu
slack = required time - data arrival time

如果要满足建立时间要求,slack 要大于或者等于0。
latch edge - Tsu = launch edge + input delay max
input delay max = (latch edge - launch edge) - Tsu
即:
Tco(max) = (latch edge - launch edge) - Tsu= 8 - Tsu

最小延迟时间推导:
input delay min = Board Delay(min) - Board clock skew(max)+ Tco(min)
data arrival time =launch edge + input delay min + Tdataint
required time =latch edge +Tclk2int+ Th
slack =data arrival time - required time
如果要满足保持时间要求,slack 要大于或者等于0
launch edge + input delay min = latch edge + Th
input delay min = (latch edge -launch edge) + Th
input delay min = Th
即:
Tco(min) =Th

*注:latch edge,launch edge 都为0。

具体例子分析:
在DVI,HDMI 等众多应用中,FPGA 通常采用相关解码芯片出来的时钟,进行对输入端口约束时
钟与相位的关系,可以使用以下语句进行描述。
#Set Input/Output Delay
set_input_delay -clock pclk -max 3 [get_ports {den} {hsync} {pdata} {vsync}]
set_input_delay -clock pclk -min 1 [get_ports {den} {hsync} {pdata} {vsync}]
注意
此处的值主要是指FPGA 外端的延迟值。约束结果可以在时序报告中进行查看约束后的相关建立以及保持时间裕量,如下图:
XILLINX时序约束命令解析&Anlogic例子说明_第23张图片

设置输出延时

XILLINX时序约束命令解析&Anlogic例子说明_第24张图片
指定在primary输出端口时钟沿的外部系统路径延迟。输出延迟值是以纳秒为单位,可正可负,正负取决于器件外部时钟和数据的相位关系。
set_output_delay组件意义和set_input_delay差不多。

场景一:系统同步
XILLINX时序约束命令解析&Anlogic例子说明_第25张图片
XILLINX时序约束命令解析&Anlogic例子说明_第26张图片
如上图所示,FPGA 发送数据到ASIC,两者为同源时钟,FPGA 的输出数据DOUT 为ASIC的输入数据DIN,现约束在FPGA 数据输出最终到达ASIC 后对DIN 进行数据采样所经过PCB 走线等外部输出延迟,是否仍然满足ASIC 对输入数据的建立与保持时间的要求。现对上面的场景做如下延迟分析:
set_output_delay(-max)来约束输出最大输出延迟,即分析在外部最大输出延迟时,输入数据仍然能满足ASIC 的建立时间(setup time)的要求。有篇不错的博客讲解了输入输出延时https://blog.csdn.net/qq_35787848/article/details/113941094

与输入延时不同,输入延时是人为设置的提供给FPGA设计工具的一个外部条件,分析的位置在目的寄存器数据数据和时钟;而输出延时则是FPGA内的一个性质,我们需要给出外部条件,也就是给出PCB走线延时和捕获寄存器的建立时间与保持时间。FPGA设计工具会根据这些条件来调整输出延时。分析的位置在输出的端口(required time和data arrival time是针对输出端口的)

output delay max = Board Delay(max) - Board clock skew(min) + Tsu= (Tdata_PCB(max) + Tcl) - (Tclk2(min)-Tclk1(max)) + Tsu
data arrival time = launch edge + Tclk1int + Tco (max) + Tdataint
required time = latch edge - output delay max- Setup Uncertainty
slack = required time - data arrival time

set_output_delay(-min)来约束最小输出延迟,即分析在外部最小输出延迟时(即数据保持有效时间最小时),输入数据仍然能满足ASIC 的保持时间(hold time)的要求。
output delay min = Board Delay(min) - Board clock skew(max) - Th= (Tdata_PCB(min) + Tcl) - (Tclk2(max)-Tclk1(min)) - Th
data arrival time = launch edge + Tclk1int + Tco (min) + Tdataint
required time = latch edge - output delay min+Hold uncertainty
slack = data arrival time - required time

注:
output delay max:
数据输出FPGA 后外部的最大延迟;
output delay min:
数据输出FPGA 后外部的最小延迟;
Board Delay(min/max):
板级数据最大/最小延迟;
Board clock skew(min/max):
板级时钟最大/最小抖动;
Tdata_PCB(min/max):
最大/最小PCB 布线延迟时间;
Tcl:
板级电容延迟时间;
Tclk1(min/max):
OSC 时钟到达FPGA 管脚的最大/最小外部延迟时间;
Tclk2(min/max):
OSC 时钟到达ASIC 管脚的最大/最小外部延迟时间;
Tsu:
为ASIC 所要求的数据对采样时钟的建立时间;
Th:
为ASIC 所要求的数据对采样时钟的保持时间;
launch eddge:
源端寄存器数据发送时钟沿;
Tclk1int:
为时钟从FPGA 管脚到达输入寄存器的延迟时间;
Tco:
包括数据从输入寄存器进入到输出的延迟时间以及最后到达FPGA 管脚之前的所有延迟时间;
Tdataint:
为数据从寄存器输出到FPGA 管脚的输出延迟时间;
Latch_edge:
目的端寄存器数据接收时钟采样沿;

具体例子分析:
XILLINX时序约束命令解析&Anlogic例子说明_第27张图片
本例假设约束的最大输出延迟output delay max 为1+0.5+2=3.5ns ,最小输出延迟output delay min为1-0.5-0.4=0.1ns
添加如下约束语句:
create_clock -name clk_120 -period 8.3 -waveform {0 4.15} [get_nets {clk_120m}]
set_output_delay -clock clk_120 3.5 [get_ports {SPI_MISO}]
set_output_delay -clock clk_120 -min 0.1 [get_ports {SPI_MISO}]
通过TD软件时序分析建立时间的结果如下图:
XILLINX时序约束命令解析&Anlogic例子说明_第28张图片
data arrival time = launch edge + Tclk1int + Tco (max) + Tdataint=0 + 2.268ns + (0.146ns + 0.330) + 5.541ns=8.285ns
required time = latch edge - output delay max - Setup Uncertainty= 8.3ns -3.5ns -0.0ns=4.8ns
Slack = required time - data arrival time=4.8ns - 8.285ns=-3.485ns

通过TD软件时序分析hold time的结果如下图:
XILLINX时序约束命令解析&Anlogic例子说明_第29张图片
data arrival time = launch edge + Tclk1int + Tco (min) + Tdataint== 0 + 1.925ns + (0.140ns + 0.283ns) + 5.275ns=7.623ns
required time = latch edge - output delay min + Hold uncertainty=0-0.1ns+0.0=-0.1ns
slack = data arrival time - required time=7.623ns - (-0.1ns)=7.723ns

场景二:源同步
在源同步系统中,FPGA 作为数据发起者,发送数据的同时,同时也发送时钟给下游器件。见下图:
XILLINX时序约束命令解析&Anlogic例子说明_第30张图片
1)在源同步信号输出时,与源同步输入类似,时钟和数据都是源器件FPGA 输出,下级目标器件ASIC 采样时钟和数据都是FPGA 的输出时钟和数据,没有时钟抖动clock_skew;

2)数据与时钟的布线是一样的,他们之间的相位关系保持输出时一致。
XILLINX时序约束命令解析&Anlogic例子说明_第31张图片
由于数据的PCB 布线延迟与CLK 的PCB 布线延迟时间是相同的,计算外部输出延迟时,时钟与数据的延迟可以抵消。所以:
output delay max = Board Delay(max) - Board clock skew(min) + Tsu= Tsu
output delay min = Board Delay(min) - Board clock skew(max) - Th = -Th

由此可得出,在源同步系统中,假设时钟和数据的PCB 布线一致,在设置set output delay 时,最大的输出延迟为ASIC 的建立时间要求Tsu,最小输出延迟为ASIC 的负保持时间要求-Th。
XILLINX时序约束命令解析&Anlogic例子说明_第32张图片
在源同步系统中,对FPGA 进行约束set output delay 设置时,应有如下:

1)必须告诉TD 软件的Timing Analyzer 时钟源到时钟输出管脚的路径,如上图所示;

2)对dataout 进行set_output_delay 约束时应以时钟输出管脚clkout 为参考时钟;
 a)产生时钟管脚clkout 的时钟时,用create_generated_clock 去产生(-source 应为PLL 的输出时钟);
 b)在set_output_delay 约束语句中用-clock 来建立时钟输出管脚clkout 与数据输出管脚dataout 之间的联系;
 添加如下约束语句:
create_clock -name clk_27m -period 37 -waveform {0 18.5} [get_ports {clk_27m}]
 create_generated_clock -name clkout -source [get_ports {clk_27m}] -multiply_by 6 get_ports {clkout}
 set_output_delay -clock clkout -max 0.5 [get_ports {dataout}]
 set_output_delay -clock clkout -min -0.5 [get_ports {dataout}]

时序例外

什么是伪路径:
  1)在电路中,该路径没有发挥真正的功能;
  2)不需要工具对其时序分析;

为什么要伪路径:
  1)可以去除无效的路径,留给软件工具更多的逻辑资源和布线空间,来满足其他更多要满足时序要求;
  2)可以节省编译时间和资源;

时序例外false paths:
  False path 一般是用于对路径做不相关处理,即告诉Timing Analyzer 时序分析时忽略该约束路径。一般分为两方面进行约束:
    基于逻辑的路径与正常的电路运行期间不相关路径,例如:一些用于测试的逻辑路径,以及一些静态寄存器;
    基于时钟域的路径,设计师不希望此部分时序路径被分析到,例如:桥接异步时钟域的同步化电路;
  建立false path 的方法有两种方式即两种约束语句:
    set_false_path 约束在涉及到特定节点时使用,
        比如从同一个输入管脚到一系列的寄存器的所有路径,
        或从一个时钟域的寄存器到另外一个时钟域的所有路径。
    set_clock_groups 约束,仅在涉及到时钟域时使用。

设置伪路径

CSDN一篇关于假路径的博客:https://blog.csdn.net/m0_61544122/article/details/125824103
XILLINX时序约束命令解析&Anlogic例子说明_第33张图片

-from:
指定源节点,可以是管脚,接口,时钟,寄存器;
-to:
指定目的节点;
-rise from & -fall from:
用于指定源节点的传输时钟约束为上升沿还是下降沿;
-rise to & -fall to:
用于指定目的节点的传输时钟约束为上升沿还是下降沿;
-through:
指定约束只应用于经过某一些特定节点名的路径;
-setup & -hold:
约束仅用于建立/保持时间分析,这里即指不分析该路径的建立/保持时间,省略该关键字时则表示两者都不分析;

例子1:
异步时钟域,如下图,
XILLINX时序约束命令解析&Anlogic例子说明_第34张图片
在应用电路中,同时会使用同步器,跨时钟进行数据采集。clk_a 和clk_b 时钟频率不一致,如逻辑上用户已经做好了处理,不需要考虑setup 和hold 相关参数,如上图所示从DF10 到DF11 的数据路径,设计师不希望对该路径进行时序分析时,可以对其进行约束:

set_false_path -from [get_clocks {clk_a}] -to [get_clocks {clk_b}]
或者
set_clock_groups -asynchonous -group [get_clocks { clk_a}] -group [get_clocks { clk_b}]

注意:

  1. 上面SDC 语句set_false_path,是单方向的,如果有相反的反向,需要再补充相关语句。
  2. 上面的目标对象是时钟,会对设计中所有的相对应的对象做约束,如果约束具体的路径,需要使用具体到位置伪路径约束。

例如在设计时有数据从clk_27m 跨时钟域到ipclk 做同步处理时,用户不对该路径进行false path 的约束,那么TD 软件中Timing Analyzer 的分析结果会有一系列setup/hold slack 不满足,如下图所示:
XILLINX时序约束命令解析&Anlogic例子说明_第35张图片
如果在sdc 约束文件里加如下约束语句:

create_clock -name clk_27m -period 37 -waveform {0 18.5} [get_ports {clk_27m}]
create_clock -name ipclk -period 6.734 -waveform {0 3.367} [get_ports {ipclk}]
set_false_path -from [get_clocks {clk_27m}] -to [get_clocks {ipclk}]
set_false_path -from [get_clocks {ipclk}] -to [get_clocks {clk_27m}]

则TD 软件种Timing Analyzer 将不会对其进行时序分析。

例2:
具体网络到某一个寄存器之间的路径
下面例子中的rst_cnt[28]是在时钟clk 产生的复位信号,而该复位信号会到另外一个时钟的寄存器的复位端,从一个时钟域到另外一个时钟域,导致removal check 为负。如下图所示:
XILLINX时序约束命令解析&Anlogic例子说明_第36张图片
在设计中除了做同步化处理之外,如功能上可以达到满足,可以增加此复位信号到时钟之间的伪路径,
set_false_path -from [get_nets {rst_cnt[28]}] -to [get_clocks {clk_in}]

设置时钟组

XILLINX时序约束命令解析&Anlogic例子说明_第37张图片

-exclusive:
指两个时钟不是同时有效的,例如时钟复用(clock multiplexer);
-asynchronous:
指两个时钟是异步关系即相位不相关,但是是同时存在的;
-group:
指定某个时钟域与另外一个时钟域之间是异步或不相关关系;

例1:时钟复用
在时钟复用的情况下即在任何时刻下只有其中一个时钟去驱动该寄存器时,Timing Analyzer 不应去
分析该跨时钟域的路径。
XILLINX时序约束命令解析&Anlogic例子说明_第38张图片
选择时钟c0 还是c1 去驱动后面的寄存器的情况下,可做如下约束:
set_clock_groups -exclusive -group [get_clocks {clk_c0}] -group [get_clocks {clk_c1}]

例2:不同时钟间,跨时钟域采样
XILLINX时序约束命令解析&Anlogic例子说明_第39张图片
set_clock_groups -asynchronous -group [get_clocks {clk_c0}] -group [get_clocks {clk_c1}]

或者

set_false_path -from [get_clocks {clk_c0}] -to [get_clocks {clk_c1}]
set_false_path -from [get_clocks {clk_c1}] -to [get_clocks {clk_c0}]

例3:时钟复用(在一个时钟端口上可能存在两个时钟频率)
XILLINX时序约束命令解析&Anlogic例子说明_第40张图片
输入时钟管脚来自同一个晶振,clkin 有两个时钟频率148.5Mhz 或74.25Mhz,可做如下约束:这样就不再是一个时钟去驱动所有寄存器了。

create_clock -name clk_120 -period 8.3 -waveform {0 4.15} [get_ports {clk_120m}]

create_clock -name clk_148p5 -period 6.734 -waveform {0 3.367} [get_ports {clkin}]

create_clock -name clk_74p25 -period 13.468 -waveform {0 6.734} [get_ports {clkin}] -add

set_clock_groups -exclusive -group [get_clocks {clk_120}] -group [get_clocks {clk_148p5}]

set_clock_groups -exclusive -group [get_clocks {clk_120}] -group [get_clocks {clk_74p25}]

set_clock_groups -exclusive -group [get_clocks { clk_148p5}] -group [get_clocks {clk_74p25}]

设置最大最小延迟

csdn博客写了关于最大最小延迟:https://blog.csdn.net/qq_44385725/article/details/123362321
知乎一篇讲时序时钟建模的文章:https://zhuanlan.zhihu.com/p/161059437,https://www.cnblogs.com/IClearner/p/6440488.html
Static Timing Analysis for Nanometer Designs:A Practical Approach》的翻译https://zhuanlan.zhihu.com/p/345536827
最大最小延迟约束主要是为了解决异步信号之间的时序路径进行时序约束的问题。最大延迟约束(set_max_delay)将默认覆盖建立时间分析中的最大路径延迟;最小延迟约束(set_min_delay)将默认覆盖保持时间分析中的最小路径延迟。所谓的最大、最小延迟约束主要应用于异步跨时钟域路径中,而对于其他的路径,一般不使用最大最小延迟约束,特别是Pin2Reg与Reg2Pin的路径,一般不使用最大最小延迟约束。Max/Min Delay,主要约束端口之间以及内部组合逻辑之间的组合路径。
XILLINX时序约束命令解析&Anlogic例子说明_第41张图片
XILLINX时序约束命令解析&Anlogic例子说明_第42张图片
设置时序路径上的延迟。延迟值必须分配给由至少一个-from、-through或-to参数定义的时序路径。一般的路径延迟(如-to端点)将被更具体的路径(如:-from/-to, or -from/-through/-to )定义。datapath_only只能用于set_max_delay中。

命令解析

-rise/fall
可选的。应用于上升沿/下降沿时序路径延迟值。
如果-rise和-fall选项都没有指定,就默认包含上升沿之间和下降沿之间路径。

-reset_path
可选的。
在使用新的指定的路径延时约束前,清除上升或下降沿的延迟约束。
如果命令仅用-to选项,则会清除到终点的所有路径。
如果命令仅用-from选项,则会清除从起点开始的所有路径。
当用了-from/-to或-from/-through/-to选项,才会对定义的路径进行复位(清除)。

-from/to <element_name>
可选的。
-from列出路径的起始点或时钟。
一个有效的起始点可能是基本的输入端口、输入输出双向端口、或时序元件的时钟pin。
如果指定了一个时钟,那么与该时钟相关的所有基本的输入端口和输入输出双向端口 以及连接到该时钟的寄存器的所有时钟端引脚 都用作起点。
-to列出路径的终点或时钟。
一个有效的终点可能是基本的输出端口、输入输出双向端口、或时序元件的数据pin。
如果指定了一个时钟,那么与该时钟相关的所有基本的输出端口和输入输出双向端口 以及连接到改时钟的寄存器的所有数据端引脚 都用作终点。

-rise_from/fall_from <element_name>
可选的。
-rise_from延迟约束从源或时钟的上升沿开始。
-fall_from延迟约束从源或时钟的下降沿开始。

-rise_to/-fall_to <element_name>
可选的。
-rise_to延迟约束以终点或时钟上升沿结束。
-fall_to延迟约束以终点或时钟下降沿结束。

-through <element_name>
可选的。
列出经过的pins、cells或nets。

-rise_through/-fall_through <element_name>
可选的。
延迟约束应用于经过的pins、cells、nets的上升沿/下降沿。

-datapath_only
可选的。
从指定路径的延迟计算中排除时钟倾斜和抖动。
此选项用于约束具有不同时钟的时序元件之间的延迟,在这种情况下,不希望在延迟计算中考虑时钟倾斜和抖动。
只需要考虑第一个触发器的Clock-to-Q延迟、两个触发器之间的导线延迟和第二个触发器的建立时间。

<delay>
必须的。
指定延迟数值。以纳秒为单位。可正可负的浮点数表示。默认为0

例1:在下面例子中,x_in 和y_in 是工程中的输入端口,sum_out 是输出端口,中间经过一定的组合逻辑
(如加法),完成特定的功能,见下图:
在这里插入图片描述
对输入接口和输出接口之间添加如下约束:
set_max_delay -from [get_ports {x_in}] -to [get_ports {sum_out}] 10

set_min_delay -from [get_ports {x_in}] -to [get_ports {sum_out}] 6

set_max_delay -from [get_ports {y_in}] -to [get_ports {sum_out}] 9

set_min_delay -from [get_ports {y_in}] -to [get_ports {sum_out}] 5

set_max_delay 分析结果如下图:
XILLINX时序约束命令解析&Anlogic例子说明_第43张图片
set_min_delay 时序分析结果如下图:
XILLINX时序约束命令解析&Anlogic例子说明_第44张图片

设置多周期路径

set_multicycle_path 命令用于设置允许多个时钟周期延时的时序路径。

XILLINX时序约束命令解析&Anlogic例子说明_第45张图片
命令解析

-setup/-hold:
指定该命令所约束的时序路径类型,仅用于setup 或者hold 选项;

-start/-end:
为跨时钟域时使用的选项,指定延时为launch/latch 时钟对应的周期,
默认情况下,setup check 使用latch 时钟而hold check 使用launch clock;

-from:
指定源节点,可以是clocks 或inputs 的列表;

-to:
指定目的节点,可以是clocks 或outputs 的列表;

-through:
指定约束只应用于经过某一些特定节点名的路径,可以是输入输出接口或者nets 列表;


指定周期数,对于-setup 表示源节点到目标节点的路径需要多少个时钟周期数,
而对于-hold 表示在软件默认情况下,数据hold 检测沿的基础上往回调多少个时钟周期数;

注意:当约束仅设置-setup 时,setup check 将允许时序路径最多使用N 即个时钟周期,但同时hold check 会变为要求时序路径最少延迟时间为N-1 时钟周期;当仅使用-hold 选项时,则将hold check 的约束设置为N (即)个时钟周期却不影setup check 的约束。所以在常规使用场景下,为了让setup check 能使用多个时钟周期而不影响hold check, 需要两条命令搭配使用,即设定一条N 个周期的setup 约束,再配合一条N-1 个周期的hold 约束。

命令原理:
在Timing Analyzer 分析建立、保持时间过程中,往往都是假设数据发送时钟沿为launch edge,数据捕获沿为latch edge;在单周期路径时,launch edge 和latch edge 为相邻最近的两个时钟沿,而在多周期路径中,launch edge 和latch edge 是间隔多个时钟周期的两个时钟沿,这个间隔周期数根据实际使用值来指定。

单周期路径:
XILLINX时序约束命令解析&Anlogic例子说明_第46张图片
如上图所示,在单周期时,Timing Analyzer 的setup 检查时间为红色实线即destination clk 的第1 个edge,在此基础上,hold 检查时间为蓝色实线即前一个时沿第0 个edge。

如此进行多周期约束:
XILLINX时序约束命令解析&Anlogic例子说明_第47张图片
如上图所示,Timing Analyzer 进行setup 的检查时间由红色虚线(1 clock edge)后移动到红色实线(2 clock edge),data require time 的时间变长了,data arrived time 的时间余量更多了,即放宽了setup 检测的条件。进行多周期约束只指定-setup,hold 为缺省的情况下,软件默认hold 检查的点为蓝色虚线部分(1 clock edge),这样的话虽然对setup 的检测条件放宽了,但是却缩紧了hold 的检测条件,因为实际情况时,设计师希望对hold 检测的点是在蓝色实线部分(0 clock edge),这时设计师便可以配合再约束一条指定-hold 的多周期约束。

应用示例:
XILLINX时序约束命令解析&Anlogic例子说明_第48张图片
如上图所示,两个寄存器的驱动时钟都是clk_120m,但因一些中间逻辑,此延迟可能需要花费不少逻辑延迟,在时序分析时可能并不是默认的单周期分析。

仅有约束如下:
create_clock -name clk_120 -period 8.3 -waveform {0 4.15} [get_nets {clk_120m}]

当未进行多周期约束时,TD 软件的Timing Analyzer 对其setup slack 分析的结果见下图:
Capture clock edge = 8.3ns
XILLINX时序约束命令解析&Anlogic例子说明_第49张图片
XILLINX时序约束命令解析&Anlogic例子说明_第50张图片
当进行多周期约束时,有如下约束语句:
create_clock -name clk_120 -period 8.3 -waveform {0 4.15} [get_nets {clk_120m}]

set_multicycle_path -setup -end -from [get_clocks {clk_120}] -to [get_clocks {clk_120}] 2

set_multicycle_path -hold -start -from [get_clocks {clk_120}] -to [get_clocks {clk_120}] 1

TD 软件的Timing Analyzer 对其setup slack 分析的结果如下图:
Capture clock edge = 16.6ns
XILLINX时序约束命令解析&Anlogic例子说明_第51张图片

你可能感兴趣的:(Vivado,数字时序,fpga开发)