XDC的基本语法可以分为时钟约束、IO约束以及时序例外约束,对一个设计进行约束的先后顺序也可以按照这三类约束依次进行。
时钟约束
时钟约束必须最早创建,端口进来的主时钟以及GT的输出RXCLK/TXCLK都必须由用户使用create_clock自主创建。如果是差分输入的时钟,可以仅在差分对的P侧用get_ports获取端口,并使用create_clock创建。
create_clock-name clk_200 - period 5 [get_ports clk200_p]
针对vivado自动推导的衍生时钟,比如MMCM/PLL/BUFR的输出时钟,可以由vivado自动推导,用户无需创建。
但是,工具不能自动推导出使用寄存器和组合逻辑搭建的分频器等衍生的时钟,必须有用户使用create_generated_clock来创建。举例如下
Clk1 是原本就有的主时钟,clk2 是衍生出来的时钟。注意创建时钟,语法不一样。
为什么时钟要进行时钟约束,不约束有什么后果?这里还是不知道。
I/O约束
在设计的初级阶段,可以不加IO约束,让工具专注于满足FPGA内部的时序要求。当时序要求基本满足后,再加上IO约束跑实现。
1 不加任何IO约束的端口,时序要求被视为无穷大。
2 XDC中的set_input_delay/set_output_delay 是从系统 角度来约束。
3 典型的IO时序,包括系统同步,源同步,SDR和DDR等。在vivado图形界面的XDC templates中有示例。2014.1版后,还有一个timing constraints wizard可供使用。timing constraints wizard 用过,操作简单,需要知道信号最大最小延迟和板间最大最小延迟即可。
(芯片引脚上有信号的最大最小延迟,板子上的默认都是0,不知道这样操作可以不)
http://group.chinaaet.com/273/4100028543 timing constraints wizard 使用方法
时序例外约束
时序例外约束包括set_max_delay/set_min_delay,set_multicycle_path,set_false_path等,这类约束除了要满足XCD的先后顺序优先级外,还要遵循自身的优先级限制。总的准则是,针对同一条路径,对约束目标描述越具体的优先级越高。
还有其他的技巧和说明,参考链接
http://xilinx.eepw.com.cn/news/article/a/1375
https://www.cnblogs.com/moluoqishi/p/10655539.html 常用的约束语法看这里
/ 新的起点///
约束的管理
时序分析是建立在时序约束的基础之上。FPGA设计有4类时序路径的起点和终点:
时序路径 |
起点 |
终点 |
应用约束 |
输入端口到FPGA内部第一级触发器的路径 |
Chip A/clk |
Rega/D |
Set_input_delay |
FPGA内部触发器之间的路径 |
Rega/clk |
Regb/D |
Create_clock |
FPGA内部末级触发器到输出端口的路径 |
Regb/clk |
Chipb/D |
Set_output_delay |
FPGA输入端口到输出端口的路径 |
输入端口 |
输出端口 |
Set_max_delay |
表中 1 2 3 所示路径可归结为一个统一的模型:触发器+组合逻辑+触发器。
一个完整的时序路径由源时钟路径、数据路径和目的时钟路径2部分构成。约束的目的则是为了验证下面公式是否成立:
Tco为发端寄存器时钟到输出时间;Tlogic为组合逻辑延迟;Trouting为两级寄存器之间的布线延迟;Tsu为接收端寄存器建立时间;Tskew为两级寄存器的时钟歪斜,其值等于时钟统一边沿到达两个寄存器时钟端口的时间差;Tclk为系统所能达到的最小时钟周期。在FPGA中,对于同步设计Tskew可忽略(认为值等于0)。由于Tco和Tsu取决于芯片工艺,因此,一旦芯片型号选定就只能通过Tlogic和Trouting来改善Tclk。其中,Tlogic和代码风格有很大关系,Trouting和布局布线策略有很大关系。
时钟周期约束
在vivado 中,通过creat_clock可轻松创建时钟周期约束。
creat_clock的对象必须为主时钟(primary clock)。主时钟通常有两种情形:一种是时钟由外部时钟源提供,通过时钟引脚进入FPGA,该时钟引脚绑定的时钟为主时钟;另一种是高速收发器(GT)的时钟RXOUTCLK或TXOUTCLK。对于7系列FPGA,需要对GT的这两个时钟手工约束(GTX的时钟IP核生成时候如果界面上有配置时钟频率,这里是不需要约束的)。
那如何确定主时钟呢?除了根据上面两种情况判断外,还可以通过TCL 输入指令来获取。在输入指令之前,要先open synthesized design。个人还是喜欢第一个指令,直观。
report_clock_networks –name mynetwork
check_timing –override_defaults no_clock
确定了主时钟,就可以对其创建时钟周期约束:
情形1:主时钟之间有明确的相位关系
-waveform不仅确定了时钟的占空比,也确定了时钟之间的相位关系。
(1)clka频率为200Mhz,等占空比。(初始化为1,waveform不是从0开始)
(2)clkb频率为100Mhz,占空比为40:60。
(3)clkc频率为200Mhz,等占空比,时钟抖动为120ps。
下面这些指令,可以在tools --- language templates ---- XDC 里面对应查找
create_clock -name
情形2:主时钟之间为异步关系
主时钟之间如果是异步关系,则需要通过set_clock_groups命令明确指定。
set_clock_groups -asynchronous -group
如果两个主时钟还通过MMCM或PLL生成了其他时钟,若这两个主时钟为异步关系,则它们的生成时钟也为异步关系。
学习了创建时钟,和异步时钟,就迫不及待的试了一下。我用的是一个SRIO 的例子,代码中有3路X4 的srio。在XDC文件中创建了SRIO 的参考输入时钟(也就是代码中引脚输入的时钟),同时把这三个时钟设置为不相关。但是,查看编译时间,生成bit文件的时间前后并未变化,糟糕的是,竟然IP核内部还出现了时序错误……IP 核内部代码时序报错,一脸懵,又不知道怎么改。
后来,查看IP核当时的生成文件,_ooc.xdc 。这个文件是在创建IP核的时候就生成的。里面不仅有参考时钟输入约束(也就是端口的引脚输入),还有内部GTX 生成时钟的约束。猜想可能是IP核已经创建的时候,我自己再创建的,不太好吧。
3:差分时钟的约束
差分时钟只约束P端即可
4:在同一端口创建多个时钟
5:高速收发器的时钟约束
记得好像是IP核中的XDC文件已经自动约束了,需要查验一下。
6:创建虚拟时钟
只有在创建输入或输出延迟约束时才会使用虚拟时钟。顾名思义,虚拟时钟并没有与之绑定的物理引脚。之所以创建虚拟时钟,是因为传输给FPGA的数据所用到的捕获时钟是由FPGA内部生成的,与主时钟频率不同;或者PCB上有clock buffer导致时钟延时不同。
如下图所示,din的发送时钟为200MHZ,而FPGA的主时钟clkin为100MHZ,捕获时钟由该主时钟通过MMCM生成。
create_clock –name sysclk –period 10 [get_ports clkin]
create_clock –name vclk –period 5
set_input_delay 2 –clock vclk [get_ports din]
上述的时间单位,都是ns。
下图是clock buffer导致时钟延迟不同。
create_clock –name –period 10 [get_ports clkin]
create_clock –name –period 10
set_clock_latency -source 1 [get_clocks virclk]
set_input_delay –clock virclk –max 4 [get_ports din]
set_input_delay –clock virclk –min 2 [get_ports din]
谨慎使用为路径约束,时序错误基本都是代码逻辑写的不正确,最先要从代码查找问题。伪路径并不表示该路径不存在,而是指基于该路径的电路功能不会发生或该路径无须时序约束。(基于该路径的电路功能不会发生,以前也遇到过用了伪路径,的确没有时序错误,但是代码逻辑不对了)。对于异步时钟的跨时钟域路径,要从设计上保证跨时钟路径的安全性,从约束角度而言可以将其设置为伪路径。
set_false_path –from[] –to [] 。 通常在图形化界面中设置,XDC文件自动生成。