VIVADO 进阶

发布时间 2023-04-29 11:43:15作者: VincentZJ

原则

合适的代码风格
精准的时序约束
管理高扇出网络
层次化设计结构
处理跨时钟域设计
少而精的物理约束
选择实现策略
共享控制信号
读懂日志报告
TCL作用

代码风格

  

高扇出网络

   高扇出网络几乎是限制 FPGA 设计实现更高性能的第一大障碍,所以我们需要很严肃地对待设计中的高扇出网络 。

   report_high_fanout_nets ,在给其加上 -timing 的选项后,可以在报告高扇出路径的同时报告出这条路径的 Slack,帮助用户直观了解当前路径的时序裕量。此外,这个命令在报告中还会指出高扇出网络的驱动类型,是 FF 或是 LUT 等 。

   找到目标后,可以利用 max_fanout 来限定其扇出值,让工具在实现过程中复制驱动端寄存器来优化。如果高扇出网络并不是由同步逻辑来驱动,则可能需要修改代码。还有一些工具层面上的降扇出方法,比如选择更强更有针对性的策略,或是允许多次物理优化 phys_opt_design,甚至是通过我们在《用 Tcl 定制 Vivado 设计实现流程》 中提到的“钩子”脚本等方式来进行局部降扇出的物理优化等等 

   但有一点需要注意, Vivado 综合选项中的全局扇出限定要慎用,不要将其设置的过低以免综合出的网表过于庞大,带来资源上的浪费,并可能导致局部拥塞。 

XDC约束时钟篇

  时钟约束必须最早创建。

  vivado自动推导的衍生时钟需要用户指定时钟名字。

  用户自己分频的时钟需要 create_generated_clock 来创建 

  IO约束

   在设计的初级阶段,可以不加 I/O 约束,让工具专注于满足 FPGA 内部的时序要求。当时序要求基本满足后,再加上 I/O 约束跑实现。 XDC 中的 I/O 约束有以下几点需要注意: 

     不加任何 I/O 约束的端口时序要求被视作无穷大 

     XDC 中的 set_input_delay / set_output_delay 对应于 UCF 中 OFFSET IN / OFFSET OUT,但视角相反。OFFSET IN / OFFSET OUT 是从 FPGA 内部延时的角度来约束端口时序,set_input_delay /set_output_delay 则是从系统角度来约束。 

     典型的 I/O 时序,包括系统同步、源同步、 SDR 和 DDR 等等 , Timing Constraints Wizard 可供使用 

  时序例外约束

     时序例外约束包括 set_max_delay/set_min_delay, set_multicycle_path, set_false_path 等,这类约束除了要满足 XDC 的先后顺序优先级外,还受到自身优先级的限制。一个总的原则就是针对同一条路径,对约束目标描述越具体的优先级越高。不同的时序例外约束以及同一约束中不同条件的优先级如下所示: 

  

  时序的零起点

    用 create_clock 定义的主时钟的起点即时序的“零起点”,在这之前的上游路径延时都被工具自动忽略。所以主时钟创建在哪个“点”很重要

   时钟的定义也遵从 XDC/Tcl 的一般优先级,即:在同一个点上,由用户定义的时钟会覆盖工具自动推导的时钟,且后定义的时钟会覆盖先定义的时钟。若要二者并存,必须使用 -add 选项 

  同步和异步时钟

    在 XDC 中,所有的时钟都会被缺省认为是相关的,也就是说,网表中所有存在的时序路径都会被 Vivado 分析。这也意味着 FPGA 设计人员必须通过约束告诉工具,哪些路径是无需分析的,哪些时钟域之间是异步的 

      

  重叠时钟

     重叠时钟是指多个时钟共享完全相同的时钟传输网络,例如两个时钟经过一个 MUX 选择后输出的时钟,在有多种运行模式的设计中很常见。 

     如果 clk125 和 clk250 除了通过 clkcore_buf 后一模一样的扇出外没有驱动其它时序元件,我们要做的仅仅是补齐时钟关系的约束。 

 -physically_exclusive 表示不可能同时通过 

  在很多情况下,除了共同的扇出,其中一个时钟或两个都还驱动其它的时序元件,此时建议的做法是在clkcore_buf 的输出端上创建两个重叠的衍生钟,并将其时钟关系约束为physically_exclusive 表示不可能同时通过。这样做可以最大化约束覆盖率

VIVADO中分析CDC

   我们可以使用 report_clock_interaction 命令( GUI 支持)来鉴别和报告设计中所有的时钟关系。执行命令后会生成一个矩阵图,其中对角线上的路径表示源时钟与目标时钟相同的时钟内部路径,其余都是 CDC 路径。 

  Vivado 还会根据网表和已读入的约束分析出 CDC 路径的约束情况,并分颜色表示。例如绿色代表有时序约束,红色代表不安全的 CDC 路径但是没有约束时序例外,橙色表示有部分路径已约束为 false path 的不安全 CDC 路径

   矩阵下方是时钟关系表格,可以就各种条件进行筛选和排序,方便定位 CDC 路径。建议的做法是:首先,对“Common Primary Clock”排序(显示为 Yes 或 No),这么做可以快速鉴别出那些安全和不安全的 CDC路径,接着观察对应的“Inter-Clock Constraints”栏内的内容,判断已读入的 XDC 中是否对这类路径进行了合理的约束。 

  在CDC约束之前必须确定设计采用了什么方法

  1.打两拍

    这种情况下,为了更长的平均无故障时间,需要配合ASYNC_REG约束,将打两拍的寄存器放在同一个slice,降低走线延时的不一致和不确定性

set_property ASYNC_REG TRUE [get_cells [list sync0_reg sync1_reg]]

  对于两个主时钟分别经过MMCM产生时钟,需要设置异步时钟组约束

  

2.FIFO

  跨时钟域设计经常使用FIFO,但是根据FIFO实现方式不同,约束也不同

  (1)FIFO使用内部的硬核BRAM搭建,这种情况所有的控制逻辑在BRAM内部,是推荐的FIFO设计。需要的XDC也十分简单,将读写时钟set_clock_groups就行

  (2)带有格雷码控制的FIFO,这种FIFO的计数器个格雷码部分是需要BRAM外部的逻辑搭建,就不能简单约束异步时钟组。如图所示,存储器外部用逻辑搭建的读写指针属于不同时钟域,存在跨时钟域。如果仅仅将读写时钟设置异步时钟组,也就是说,两个时钟域之间的路径全部是伪路径,就会导致所有的跨时钟域读写路径全部不做时序分析,那么读写指针和相关控制逻辑也就失去了存在的意义。

  

所以。这种情况推荐的做法是,不做set_clock_groups,转而使用set_max_delay来约束跨时钟域路径。以写入侧分析,基本原则就是约束从cell1到cell2的路径之间的延时小于cell2驱动时钟的一个周期的值,读出侧同理。

  set_max_delay $delay -from [get_cells cell1] -to [get_cells cell2] -datapath_only  [get_property PERIOD $rd_clock]

如果使用IP Catalog产生这种FIFO,XDC是会随着IP源代码一起输出,只需要注意FIFO的读写时钟没有被用户自己的XDC约为false_path或者异步时钟组

XDC约束I/O篇

input delay

   XDC 中可以用于 I/O 约束的命令包括 set_input_delay /set_output_delay 和 set_max_delay / set_min_delay 。其中,只有那些从FPGA 管脚进入和/或输出都不经过任何时序元件的纯组合逻辑路径可以用set_max_delay / set_min_delay 来约束,其余 I/O 时序路径都必须由set_input_delay / set_output_delay 来约束。如果对 FPGA 的 I/O 不加任何约束, Vivado 会缺省认为时序要求为无穷大,不仅综合和实现时不会考虑I/O 时序,而且在时序分析时也不会报出这些未约束的路径 

  系统同步的input_delay

  FPGA和上游器件使用的是一个时钟,这就十分简单,只需要考虑Tco和Tdelay

   设置和分析 I/O 约束一定要有个系统级思考的视角,如上右图所示, Launch Edge 对应的是上游器件的时钟,而 Capture Edge 则对应 FPGA 的输入时钟,正因为是系统同步时钟,所以可以将其视作完全同步而放在一张图上分析,这样一来,就可以用一般时序分析方法来看待问题。

  上述 -max 后的数值是Tcko 的最大值加上板级延时的最大值而来,而-min 后的数值则是由两个最小值相加而来

  源同步接口(也就是数据传输存在随路时钟)  

   为了改进系统同步接口中时钟频率受限的弊端,一种针对高速 I/O 的同步时序接口应运而生,在发送端将数据和时钟同步传输,在接收端用时钟沿脉冲来对数据进行锁存,重新使数据与时钟同步,这种电路就是源同步接口电路( Source Synchronous Interface)。 

   源同步接口最大的优点就是大大提升了总线的速度,在理论上信号的传送可以不受传输延迟的影响,所以源同步接口也经常应用 DDR 方式,在相同时钟频率下提供双倍于 SDR 接口的数据带宽 

   源同步接口的约束设置相对复杂,一则是因为有 SDR、 DDR、中心对齐( Center Aligned)和边沿对齐( Edge Aligned)等多种方式,二则可以根据客观已知条件,选用与系统同步接口类似的系统级视角的方式,或是用源同步视角的方式来设置约束。 

  

   对源同步接口进行 Input 约束可以根据不同的已知条件,选用不同的约束方式。一般而言,FPGA 作为输入接口时,数据有效窗口是已知条件,所以方法 2 更常见, Vivado IDE 的 Language Templates中关于源同步输入接口 XDC 模板也是基于这种方法。但不论以何种方式来设置 Input 约束,作用是一样,时序报告的结果也应该是一致的。 

  

针对上图中心对齐源同步SDR接口时序,分别按照两种方式约束,需要知道的已知条件和计算方式不同,但是结果相同

  

DDR类型接口约束

  以源同步为例,分别对输入接口的中心对齐和边沿对齐分析

  中心对齐 

  

   可以这样计算输入接口约束: DDR 方式下数据实际的采样周期是时钟周期的一半;上升沿采样的数据( Rise Data)的 -max 应该是采样周期减去这个数据的发送沿(下降沿)之前的数据有效窗口值 dv_bfe,而对应的-min 就应该是上升沿之后的数据有效窗口值 dv_are ;同理,下降沿采样的数据( Fall Data)的 -max应该是采样周期减去这个数据的发送沿(上升沿)之前的数据有效窗口值 dv_bre,而对应的-min 就应该是下降沿之后的数据有效窗口值 dv_afe 。 

边沿对齐

  

   可以这样计算输入接口约束:因为已知条件是数据相对于时钟上升沿和下降沿的 skew,所以可以分别独立计算;上升沿的 -max 是上升沿之后的数据 skew (skew_are ),对应的-min 就应该是负的上升沿之前的数据 skew (skew_bre );下降沿的 -max 是下降沿之后的数据 skew (skew_afe ),对应的-min 就应该是负的下降沿之前的数据 skew (skew_bfe )。 

 出现负值并不代表延时真的为负,而是跟数据相对于时钟沿的方向有关。请一定牢记 set_input_delay 中-max/-min 的定义,即时钟采样沿到达之后最大与最小的数据有效窗口( set_output_delay 中 -max/-min 的定义与之正好相反,详见后续章节举例说明)。
  在这个例子中,数据是边沿对齐,只要有 jitter 跟 skew 的存在,最差情况下,数据有效窗口在到达时钟采样沿之前就已经结束,所以会有负数出现在-min 之后。因此,在实际应用中, FPGA 用作输入的边沿对齐DDR 源同步接口的情况下,真正用来采样数据的时钟会经过一个 MMCM/PLL 做一定的相移,从而把边沿对齐 变成中心对齐。 

   另外,在经过 MMCM/PLL 相移后的采样时钟跟同步接口输入的时钟之间需要做 set_false_path 的约束(如下述例子)而把那些伪路径从时序报告中剔除,这里不再详述。 

虚拟时钟(没有随路时钟,需要创建虚拟时钟)

  举例来说,上游器件用一个 100MHz 的时钟送出数据到 FPGA,实际上这个数据每两个时钟周期才变化一次,所以可以用 50MHz 的时钟来采样。 FPGA 有个 100MHz 的输入时钟,经过 MMCM 产生一个 50MHz 的衍生时钟,并用其来采样上游器件送来的同步数据。当然,系统级的设计上,必须有一定的机制来保证上游器件中的发送时钟和 FPGA 中的接收时钟的时钟沿对齐。

   此时,我们可以借助虚拟时钟的帮助来完成相应的 Input 接口约束 

output delay

  set_up/hold based method

max路径指的是建立时间,数据传输最大不能晚于 捕获边沿 - 建立时间,

min路径指的是保持时间,数据传输最快不能早于 捕获边沿 - 保持时间,下一个数据要在保持时间后才能到