FPGA之时序约束

在quartus ii中,为了确保得到准确的静态时序分析结果,我们必须要对设计里所有的时钟进行约束。 
quartus ii里的静态时序分析工具支持以下几种类型的时钟约束: 
(1) Base clocks 基础时钟; 
(2) Virtual clocks 虚拟时钟; 
(3) Multifrequency clocks 多频率时钟; 
(4) generated clocks 生成时钟。 
在sdc里编写约束文件时,首先要对时钟进行约束,因为其他的约束都是参考时钟进行的。静态时序分析是从sdc的上面到下面依次读取你写的约束指令的。 
1、创建 Base clocks 基础时钟 约束 
基础时钟是输入fpga的主要时钟,基础时钟是由片外的晶振或者外部器件产生的,是整个设计的时钟源头,其余的generated clocks以及其它约束都是用base clocks作为参考时钟的。 
用create_clock 指令 对输入时钟进行约束,下面的7-8是对一个输入的时钟作约束

-period 10 是指输入的时钟周期是10ns,即频率为100Mhz; 
-waveform {2.5 7.5}是指时钟偏移2.5ns(周期/4),即相位偏移了90°; 
-get_ports clk_sys 是指输入的时钟是从clk_sys这个管脚输入fpga的。 
这里写图片描述

对同一个输入管脚有多个频率的时钟进行约束,在第二条指令后加 -add, 该约束命令表示从clk_sys管脚输入的时钟 有100M和200M两种频率。格式如下: 
这里写图片描述

2、创建 Virtual clocks 虚拟时钟 约束 
虚拟时钟并没有真正的输入源,是通过指令虚拟出来的。虚拟时钟主要是用在I/O输入输出约束上,用来代表与fpga相连的外部器件的时钟。比如源同步输入时,就可以通过创建虚拟时钟进行输入最大最小延迟约束。 
下面是创建一个名称为 my_virt_clk,周期10ns的虚拟时钟。注意这里没有get_ports 项。 
这里写图片描述

3、创建 Multifrequency clocks 多频率时钟 约束 
指令格式如下,上面在2里已经讲过。 
这里写图片描述

4、创建 generated clocks 生成时钟 约束 
generated clocks是指从PLL生成的时钟,或者由程序分频产生的时钟。在sdc里用create_generated_clock指令对生成时钟进行约束。Options 里有综括号的表示是可选的,不是必须的。格式如下: 
这里写图片描述 
-name 用来指定通过create_generated_clock指令生成的时钟名称 
-source 指用来生成时钟的源时钟,比如在PLL里,指输入PLL的源时钟 
-master_clock 是指源时钟如果有几个不同的频率,该master_clock指示源时钟用的哪个频率的时钟作为source clock 
-divide_by 时钟的分频值 
-multipl_by 时钟的倍频值 
-duty_cycle 生成时钟的占空比 
-invert 生成时钟反相 
-phase 生成时钟相位偏移值

下面是用程序进行分频产生时钟的例子 
一个寄存器把输入的时钟CLK_IN进行二分频输出 
这里写图片描述 
对其进行时钟约束,指令如下: 
这里写图片描述

再举一个PLL生成时钟约束的例子: 
下面是在程序里例化的一个PLL,输入时钟CLK是 25Mhz,产生4个输出时钟 
outclk_0 是125M,outclk_1是 25M,outclk_2 是2.5M,outclk_3 是50M

这里写图片描述

首先对输入时钟CLK进行约束,指令如下: 
这里写图片描述 
其次,再对PLL生成的时钟进行约束,指令如下: 
PLL为了生成输出的4个时钟,先产生了一个500Mhz的临时时钟,名称为pll_inst|pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0],后面输出的时钟都是以这个时钟作为源进行分频的。

这里写图片描述
line160-164产生一个500Mhz的时钟 
- name 名称为pll_inst|pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0] 
-source 指该模块的输入时钟管脚名称为pll_inst|pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|refclkin 
-duty_cycle 50 即生成时钟占空比为50% 
-multiply_by 20 即倍频20 ,所以该时钟频率为 源输入时钟频率25M*20=500M 
-master_clock {altera_tse_CLK} 即为输入该模块的时钟名称 是altera_tse_CLK 
gen_pins 指该模块输出500Mhz时钟的管脚名称为pll_inst|pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0]

line166-170输出125Mhz时钟,名为 clk_125M_0deg 
- name 名称为clk_125M_0deg 
-source 指该模块的输入时钟管脚名称为pll_inst|pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|vco0ph[0] 
-duty_cycle 50 即生成时钟占空比为50% 
-multiply_by 1 即倍频1 
-divide_by 4 分频4,所以该时钟频率为输入时钟频率500M*1/4=125Mhz 
-master_clock即为输入该模块的时钟名称是 pll_inst|pll_inst|altera_pll_i|general[0].gpll~FRACTIONAL_PLL|vcoph[0] 该时钟就是line160-164产生的公共时钟 
gen_pins 指该模块输出500Mhz时钟的管脚名称为pll_inst|pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk

line172-176输出125Mhz时钟,名为 clk_25M_0deg

line178-182输出2.5Mhz时钟,名为 clk_2_5M_0deg

line184-188输出50Mhz时钟,名为 mm_clk

对于上面的那些输入时钟或者管脚的名称是怎么知道的? 
我是先在sdc里输入 derive_pll_clocks 这条指令 进行全编译,编译后在 编译报告里的Timequest ->clocks里就有对应的名称了。然后在进行上面的约束,就行了。

5、derive_pll_clocks 
该命令是将程序里所有的PLL生成的时钟都进行约束,生成约束时钟的名称不能修改。所以为了可以灵活地修改生成时钟的名称,很多时候都是用create_generated_clock 指令来对PLL生成时钟进行约束。 
下面就是用两种方式对PLL生成的时钟进行约束 
这里写图片描述
用create_generated_clock指令生成的时钟名字是可以修改的,比如上面生成的时钟名称 c100,c200,c200_shift 
而用derive_pll_clocks 生成的时钟名称是固定的 是PLL模块输出管脚的名称

6、derive_clock_uncertainty 
对时钟的uncertainty 进行约束,时钟的uncertainty指的是时钟的jitter抖动和skew偏斜。 用derive_clock_uncertainty,静态时序分析工具会自动地去计算时钟的uncertainty,而不用手动去添加。

7、set_clock_groups 创建时钟分组 命令 
由于静态时序分析工具 默认所有的时钟都是相关的,这样会把一些没有关联的信号进行分析,导致错误的分析结果,所有需要用该命令去把时钟进行分组。 
set_clock_groups 有两个类型 : 
-exclusive:表示所分的组是互斥的,不能同时存在。 
-asynchronous:表示所分的组是异步的,即不相关的。 
下面是创建两个互斥的时钟分组,时钟clk_A 和clk_B分在不同的组,是互斥的。两者不会在程序里同时存在。 
这里写图片描述 
下面是创建两个异步的时钟分组,时钟clk_A 和clk_B为一组,clk_C为另外一组,这样clk_A ,clk_B 与clk_C就是异步的,不相关的。 
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值