上面已经把DAC7512控制器中所有的时钟都创建好了。下面我们再额外讨论一下关于时钟属性方面的一些问题和在做时序分析时的处理方法。对于具有单一时钟的系统,设计和时序分析都相对简单。但是现在很多设计都有多个甚至几十个时钟乃至更多的时钟。比如说DAC7512控制器,在设计中用到的时钟实际上是有3个,CLK25M,CLK50M和DA_SCLK。在对多时钟设计进行时序分析的时候,我们首先要搞清楚各时钟之间的关系。
当设计中有多个时钟时,时钟之间可能存在三种关系,分别是同步,异步和互斥。如果两个或者多个时钟具有相同的source和固定的相位差,那么这些时钟是同步时钟。在DAC7512的控制器里,CLK25M,CLK50M和DA_SCLK的source都是CLK_IN,所以可以认为他们三个是同步的。
如果两个或者多个时钟之间没有任何关系,则称之为异步时钟。比如说CLKA来源于晶振A,而CLKB来源于其他系统的输入,CLKA和CLKB就为异步时钟。对于异步时钟来讲,两个时钟域的时钟沿有可能在任意时刻出现,相互之间不会有任何关系。如果一条timing path的起始点是在CLKA,而终点在CLKB,即这条timing path跨越了CLKA和CLKB两个时钟域,那么STA软件是不会对该timing path做分析的。实际上这等同于在这两个时钟之间设定了一条false path。
如果两个时钟不会相互作用,那么称这两个时钟为互斥的。举个例子来讲,PCIE GEN2可以工作在GEN1和GEN2两种模式,在GEN1模式下,时钟为125MHz,在GEN2的模式下,时钟为250MHz,但在某一个特定时间里,时钟只可能为125MHz或者250MHz,这两个频率的时钟不会共存,相互之间也不会有相互作用。
下图给出了时钟的三种关系的例子。
做时序分析时,在创建好所有的时钟后,需要定义这些时钟之间的关系。我们可以把同步时钟放到一个group中,然后在定义时钟之间的关系时,可以使用group来定义。在默认情况下,TimeQuest认为设计中所有的时钟都是同步的,并把所有的时钟都放在同一个group里。如果设计中有异步时钟,就需要用命令把异步时钟分组并定义出来。
在TimeQuest里,我们用set_clock_groups来定义时钟的group。下面是命令的语法,更详细的说明请参照quartusII的帮助系统。
Syntax |
set_clock_groups [-h | -help] [-long_help] [-asynchronous] [-exclusive] -group <names> [-logically_exclusive] [-physically_exclusive] |
关于选项说明:
-asynchronous: 时钟是异步不相关的,时钟有完全不同的时钟源;
-exclusive: 时钟是互斥的,即时钟不会再同一时刻同时有效;
实际上,这两个选项的效果是完全一样的,...TimeQuest treats both options,"-exclusive" and "asynchronous", as if they were the same.
这与对各个时钟使用set_false_path的效果是完全一样的,不过结构远比set_false_path简洁,而且时钟越多效果越明显。
如:
1 create_clock -period [0.000 10.000] -name clkA [get_ports sysclk[0]] 2 create_clock -period [0.000 10.000] -name clkB [get_ports sysclk[1]] 3 #set clkA and clkB to be mutually exclusive clocks 4 set_clock_groups -exclusive -group{clkA} -group{clkB} 5 #The previous line is equivalent to following two commands 6 set_false_path -from [get_clocks clkA] -to [get_clocks clkB] 7 set_false_path -from [get_clocks clkB] -to [get_clocks A]
在DAC7512控制器里,CLK25M,CLK50M和DA_SCLK三个时钟是同步时钟。默认情况下,它们已经被软件放到了同一个group里,所以我们不需要对其做任何的处理。
但假设CLK25M属于一个group,而CLK50M和DA_SCLK属于另外一个group,我们就要用set_clock_groups命令把二者设为异步时钟,命令如下:
1 set_clock_groups -asynchronous -group {CLK25M} -group {CLK50M DA_SCLK}
我们对比一下把CLK25M设定为CLK50M的异步时钟前后TimeQuest对时序分析的处理情况来看这个命令的作用。下面是在添加这个命令前后TimeQuest中Report clock transfer的结果。
在没有添加这个命令前,软件默认三个时钟都是同步时钟,所以会分析并报告出三个时钟之间所有的timing path。
那如果我们假设CLK25M和CLK50M是互斥时钟的话,又会是什么情况呢?用下面的命令将CLK25M和CLK50M设为互斥时钟:
set_clock_groups -exclusive -group {CLK25M} -group {CLK50M}
还是看TimeQuest中Report clock transfer的结果,可以发现CLK25M和CLK50M之间的timing path都被设定为false path了。
再看一下关于Clock uncertainty的知识
简单的说,Clock uncertainty是指时钟边沿实际到达时间与理论到达时间之间的差异和变化。在做时序分析的时候,是需要加上clock uncertainty来计算timing path的延时的。Clock uncertainty的大小是比较难确定的,在ASIC设计中,clock uncertainty的值往往要根据所使用的工艺,以往项目的经验等各种因素来决定。但在FPGA的设计中,我们能参考的资料不多,特别是对于PLL输出的时钟,因为我们对PLL本身的参数并不是非常的了解,所以很难给出合适的clock uncertainty的值。在FPGA设计中定义PLL的时候,我们要定义参考时钟的精度,这会直接影响到PLL输出时钟的clock uncertainty的值。如下图所示,25.000MHz即为输入基准时钟的精度。
有了输入时钟的精度,TimeQuest会根据PLL本身的属性,自动计算出各输出时钟的uncertainty值。如果要在设计中由软件加入clock uncertainty的值,可以使用下面的命令:
derive_clock_uncertainty
除非你对系统的时钟有充分的理解并确切知道时钟的属性,否则不建议使用set_clock_uncertainty命令直接定义FPGA中各时钟的uncertainty属性。推荐使用derive_clock_uncertainty命令由软件自动计算并添加。