来自:http://xilinx.eetrend.com/article/7735
上一篇《XDC约束技巧之时钟篇》介绍了XDC的优势以及基本语法,详细说明了如何根据时钟结构和设计要求来创建合适的时钟约束。我们知道XDC与UCF的根本区别之一就是对跨时钟域路径(CDC)的缺省认识不同,那么碰到FPGA设计中常见的CDC路径,到底应该怎么约束,在设计上又要注意些什么才能保证时序报告的准确性?
CDC的定义与分类
CDC是Clock Domain Crossing的简称,CDC时序路径指的是起点和终点由不同时钟驱动的路径。在电路设计中对这些跨时钟域路径往往需要进行特别的处理来避免亚稳态的产生,例如使用简单同步器、握手电路或是FIFO来隔离。
安全的CDC路径
所谓安全的CDC路径是指那些源时钟和目标时钟拥有相同的来源,在FPGA内部共享部分时钟网络的时序路径。这里的安全指的是时钟之间的关系对Vivado来说是全透明可分析的。
不安全的CDC路径
不安全的CDC路径则表示源时钟和目标时钟不同,且由不同的端口进入FPGA,在芯片内部不共享时钟网络。这种情况下,Vivado的报告也只是基于端口处创建的主时钟在约束文件中所描述的相位和频率关系来分析,并不能代表时钟之间真实的关系。
在Vivado中分析CDC
在ISE中想要快速定位那些需要关注的CDC路径并不容易,特别是要找到不安全的CDC时,因为ISE缺省认为所有来源不同的时钟都不相关且不做分析,要报告出这类路径,需要使用ISE Timing Analyzer (TRCE) ,并加上 “-u” (表示unconstrained)这个选项。
在Vivado中则容易许多,我们可以使用report_clock_interaction命令(GUI支持)来鉴别和报告设计中所有的时钟关系。执行命令后会生成一个矩阵图,其中对角线上的路径表示源时钟与目标时钟相同的时钟内部路径,其余都是CDC路径。
Vivado还会根据网表和已读入的约束分析出CDC路径的约束情况,并分颜色表示。例如绿色代表有时序约束,红色代表不安全的CDC路径但是没有约束时序例外,橙色表示有部分路径已约束为false path的不安全CDC路径。
矩阵下方是时钟关系表格,可以就各种条件进行筛选和排序,方便定位CDC路径。建议的做法是:首先,对“Common Primary Clock”排序(显示为Yes 或No),这么做可以快速鉴别出那些安全和不安全的CDC路径,接着观察对应的“Inter-Clock Constraints”栏内的内容,判断已读入的XDC中是否对这类路径进行了合理的约束。
第二步,可以对“Path Req (WNS)”由小到大进行排序,找到那些数值特别小(例如小于100ps)或是显示为“Unexpanded”的CDC路径,结合是否共享“Common Primary Clock”来鉴别此类路径,作出合理的约束。
过小的Path Req (WNS)一般都表示此类跨时钟域路径缺少异步时钟关系或其它时序例外的约束,如果两个时钟连“Common Primary Clock”也不共享,则100%可以确认为异步时钟,应该加上相应的时钟关系约束。
显示为“Unexpanded”的时钟关系,表示Vivado在一定长度(缺省为1000)的周期内都没有为两个时钟的频率和相位找到固定的关系,则无法推导出相应的Path Req 约束值。此类CDC需要特别留意,也要加上异步时钟关系约束。
这个矩阵还支持交互式的时序分析,选中任意一个方框,右键显示下拉菜单:选择Report Timing,会报告出这一格代表的时钟域(本时钟域或是跨时钟域)内最差的时序路径;选择 Set Clock Groups则可以设置时钟关系约束并添加到XDC文件中。
CDC的设计与约束
CDC路径在FPGA设计中普遍存在,在设置相应的约束前,必须了解设计中采取了怎样的方法来处理跨时钟域路径。
简单同步器
对于单根跨时钟域路径,一般采用简单同步器(Simple Synchronizer),就是由至少两级CE端和Reset/Clear端接死的寄存器序列来处理。
这种情况下,为了更长的平均无故障时间MTBF(Mean Time Between Failures),需要配合一个ASYNC_REG的约束,把用作简单同步器的多个寄存器放入同一个SLICE,以降低走线延时的不一致和不确定性。
set_property ASYNC_REG TRUE [get_cells [list sync0_reg sync1_reg]]
在XDC中,对于此类设计的CDC路径,可以采用set_clock_groups来约束。
用FIFO隔离CDC
在总线跨时钟域的设计中,通常会使用异步FIFO来隔离。根据FIFO的实现方式不同,需要加入不同的XDC约束。
Build-in硬核FIFO
这种FIFO实际上就是用FPGA内部的BRAM来搭建,所有控制逻辑都在BRAM内部,是推荐的FIFO实现方式。其所需的XDC也相对简单,只要像上述简单同步器的时钟关系约束一样用set_clock_groups将读写时钟约束为异步即可。
带有格雷码控制的FIFO
为了在亚稳态下做读写指针抽样也能正确判断空满状态,设计中也常用一种带有格雷码控制的FIFO来实现异步时钟域的隔离。计数器和读写指针等需要用BRAM外部的逻辑搭建,这样的结构就不能简单约束set_clock_groups,还要考虑这些外部逻辑如何约束。
如下图所示FIFO,在存储器外部有一些用FPGA逻辑搭建的写指针和读指针控制,分属不同的时钟域,存在跨时钟域的时序路径。
此时如果仅将读写时钟用set_clock_groups约束为异步时钟,相当于设置从A到B和从B到A的路径全部为false path。根据《XDC约束技巧之时钟篇》所列,false path的优先级最高,很显然这么做会导致所有跨读写时钟域的路径全部不做时序分析,读写指针和相关控制逻辑也就失去了存在的意义。
所以建议的做法是不设set_clock_groups约束,转而采用set_max_delay来约束这些跨时钟域路径。以写入侧举例,一个基本的原则就是约束从cell1到cell2的路径之间的延时等于或略小于cell2的驱动时钟一个周期的值。读出侧的约束同理。
set_max_delay $delay –from [get_cells cell1] –to [get_cells cell2] –datapath_only
如果用户使用Vivado的IP Catalog来产生此类FIFO,这样的XDC会随IP的源代码一起输出(如下所示),使用者仅需注意确保这个FIFO的读写时钟域没有被用户自己的XDC约束为false path或是异步clock groups 。
自2013.4开始,Vivado中还提供一个称作methodology_checks的DRC检查,其中包含有对此类异步FIFO的max delay约束与时钟域clock groups约束的冲突检查。
CDC约束方案的对比
CDC路径在FPGA设计中普遍存在,不少公司和研发人员都有自己偏爱的约束方式,这些方式通常有各自适用的环境,当然也各有利弊。
全部忽略的约束
最大化全部忽略CDC路径的约束,即采用set_clock_groups 或是set_false_path对时钟关系进行约束,从而对跨时钟域的路径全部忽略。
示例:set_clock_groups -asynchronous -group clkA -group clkB
优势:简单、快速、执行效率高。
劣势:会掩盖时序报告中所有的跨时钟域路径,容易误伤,不利于时序分析。
使用datapath_only约束
datapath_only是从ISE时代的UCF中继承过来的约束,在XDC中必须作为一个选项跟set_max_delay配合使用,可以约束在时钟之间,也可以对具体路径进行约束。
示例:set_max_delay 10 -datapath_only -from clkA -to clkB
优势:简便、执行效率较高。
劣势:1) 需要特别留意是否设置了过于严格的约束,因为使用者经常会使用较快的时钟周期来约束跨时钟域路径 。2) 注意约束优先级的关系,是否跟设计中其它的约束有冲突。3) set_max_delay而没有配套设置set_min_delay的情况下,同一路径只做setup分析而不做hold分析。
逐条进行时序例外约束
对设计中的CDC路径分组或逐条分析,采用不同的时序例外约束,如set_false_path,set_max_delay和set_multicycle_path等来约束。
示例:set_false_path -from [get_cells a/b/c/*_meta*] -to [get_cells a/b/c/*_sync*]
优势:灵活、针对性好、便于时序分析和调试。
劣势:1) 逐条约束会占用大量时间来调试和分析,效率低下。2) 时序例外的优先级比较复杂,多种时序例外约束共存的情况下,很容易产生意想不到的冲突,进一步增加调试时间,降低效率。3) 这么做极容易产生臃肿的XDC约束文件,而且时序例外的执行更耗内存,直接导致工具运行时间变长。
小结
CDC路径的分析和约束不仅在FPGA设计中至关重要,也是数字电路设计领域一个非常重要的命题。IP提供商、EDA公司都有不少关于CDC的技术文档。Vivado相比于Xilinx.上一代产品ISE,已经在CDC的鉴别和分析方面有了很大改进,XDC相比于UCF,在CDC路径的约束上也更为高效,覆盖率更高。
希望本篇短文可以帮助Vivado的用户快速掌握对FPGA设计中CDC路径的鉴别、分析和约束方法,提高设计效率。