DAC7512时序约束(转载)

三,DAC7512控制器
    DAC7512是一个具有三线串行接口的DAC。我们基于FPGA用Verilog语言实现了一个简单的DAC7512的控制器。下面是控制器的结构图:


 
    DAC7512控制器由三个模块组成,PLL用来生成控制器所要的时钟C0(25MHz)和C1(50MHz),其lock信号用来做为控制器的异步reset。da_data模块生成要送往DAC7512的数据,其中DA_DATA为数据,DA_DATA_EN为数据有效信号,该模块使用C0时钟,整个属于C0时钟域。DAC7512模块用于将DA_DATA转换成符合DAC7512接口标准的串行数据并送给DAC7512,要用到C1(50MHz)和DA_SCLK(C1二分频,25MHz)两个时钟。
    DAC7512控制器一共有四个输入输出端口。CLK_IN为PLL的基准时钟,为25MHz。DA_DIN,DA_SCLK和DA_SYNC为三线串口,都为输出端口。
    由于C0,C1是由同一个PLL输出的,DA_SCLK是由C1经二分频得到的,三者之间是同步的,处于同一个clock group中。
    DAC7512模块的详细设计资料可参照本博客中 “FPGA设计中DAC7512控制的Verilog实现” 的文章。不过要注意一点的是,在串行总线上,DA_DIN是在DA_SCLK的下降沿有效的。把DA_DIN设计为C1时钟域的信号,并控制其值只在DA_SCLK为高电平的时候发生变化。这样可以把DA_DIN与DA_SCLK之间的时序要求转换为DA_DIN在C1时钟域的时序要求,细节我们会在下面介绍。


四,用TimeQuest对DAC7512控制器进行时序分析 
   在对某个对象下时序约束的时候,首先要能正确识别它,TimeQuest会对设计中各组成部分根据属性进行归类,我们在下时序约束的时候,可以通过命令查找对应类别的某个对象。
     TimeQuest对设计中各组成部分的归类主要有cells,pins,nets和ports几种。寄存器,门电路等为cells;设计的输入输出端口为ports;寄存器,门电路等的输入输出引脚为pins;ports和pins之间的连线为nets。具体可以参照下图(此图出自Altera Time Quest的使用说明)。


 
      下面我们按照本文第二部分用TimeQuest做时序分析的基本操作流程所描述的流程对DAC7512控制器进行时序分析。
       建立和预编译项目的部分相对简单,涉及到的也只是QuartusII的一些基本操作,这里我们就不再做具体的叙述。主要介绍如何向项目中添加时序约束和如何进行时序验证。首先建立一个名称与项目top层名字一致的sdc文件,然后按照下面的步骤添加时序约束。
1. 创建时钟
     添加时序约束的第一步就是创建时钟。为了确保STA结果的准确性,必须定义设计中所有的时钟,并指定时钟所有相关参数。TimeQuest支持下面的时钟类型:
a) 基准时钟(Base clocks)
b) 虚拟时钟(Virtual clocks)
c) 多频率时钟(Multifrequency clocks)
d) 生成时钟(Generated clocks)
我们在添加时序约束的时候,首先创建时钟的原因是后面其它的时序约束都要参考相关的时钟的。
基准时钟:
     基准时钟是输入到FPGA中的原始输入时钟。与PLLs输出的时钟不同,基准时钟一般是由片外晶振产生的。定义基准时钟的原因是其他生成时钟和时序约束通常都以基准时钟为参照。
    很明显,在DAC7512控制器中,CLK_IN是基准时钟。我们用下面的命令来创建这个基准时钟:
create_clock -name CLK_IN -period 40 -waveform {0 20} [get_ports {CLK_IN}]
    其中,create_clock是创建时钟的命令,后面是命令的各种选项。其中-name CLK_IN选项给出了时钟的名字,即CLK_IN。-period 40给出了时钟的周期,即40ns。-waveform {0 20}给出了时钟的占空比,即50/50。最后的[get_ports {CLK_IN}] 是嵌套的tcl命令,给出了CLK_IN对应的port,实际上也就是CLK_IN的输入引脚。
    在sdc文件里添加上述命令后,在quartusII里编译设计,然后通过tools –> TimeQuest Time Aanlyzer命令打开TimeQuest。在TimeQuest的Tasks窗口,找到Report Clocks,双击之,TimeQuest就会在右边主窗口给出设计中已成功添加的时钟信息。如下图所示,可以看到CLK_IN,其类型为基准时钟,周期为40ns,频率为25MHz,targets项为CLK_IN,即表示这个时钟是连接在CLK_IN端口上的。这说明上面create_clock的命令已经在设计中正确创建了时钟CLK_IN。


 
       实际上对于create_clock命令,我们可以通过quartus II的帮助系统(http://quartushelp.altera.com/current/),查找它的语法。在QuartusII的帮助里,可以查找到:
Syntax    create_clock [-h | -help] [-long_help] [-add] [-name<clock_name>] -period <value> [-waveform <edge_list>] [<targets>]
    另外,帮助系统里有很详尽的关于该命令的描述,并且给出了各种使用的范例。不仅仅是这一个命令,所有的命令都可以在帮助系统里找到。如果看到一个陌生的命令,或者不知道命令该如何使用,那么最好的办法就是在帮助系统里查找该命令。
PLL时钟:
     上面我们创建了基准时钟。下面我们创建PLL输出的时钟。
     在Altera的FPGA中,PLL电路是通过ALTPLL的IP库被添加到设计中的。下图是一个典型的ALTPLL的结构图。


 
        从图上可以看到,当我们选定了基准时钟和PLL的参数以后,PLL的输出c0和c1的参数就随之确定了。所以在QuartusII环境下,可以通过一个简单的命令让软件自动生成PLL输出的时钟的时序约束。
derive_pll_clocks
     这个命令会自动创建PLL输出的C0和C1的相关时序约束。同样的,在sdc文件里添加该命令,然后编译,在TimeQuest里查看时钟信息。如下图所示,derive_pll_clocks在系统里添加了两个时钟,PLL1|altpll_component|auto_generated|pll1|clk[0]和PLL1|altpll_component|auto_generated|pll1|clk[1]。可以看出,时钟是按“PLL层次结构+时钟端口名字”的规则命名的。时钟的类型为created clock,周期频率是在PLL里设定好的。duty_cycle为50/50。Clock source为PLL1|altpll_component|auto_generated|pll1|inclk[0],实际上就是我们之前定义的CLK_IN。


 
       用derive_pll_clocks命令创建PLL相关的时钟很是方便,但不好的地方就是,时钟的命名太过复杂,我们在添加与此时钟相关的时序约束时,就必须用这种名字很长的时钟,容易出错,且可读性也差。所以建议还是采用create_generated_clock命令来创建PLL的时钟。
       create_generated_clock命令的语法如下,可以从quartusII的帮助系统里找到每个参数的详细解释。
Syntax    create_generated_clock [-h | -help] [-long_help] [-add] [-divide_by <factor>] [-duty_cycle <percent>] [-edge_shift<shift_list>] [-edges <edge_list>] [-invert] [-master_clock<clock>] [-multiply_by <factor>] [-name <clock_name>] [-offset<time>] [-phase <degrees>] -source <clock_source> [<targets>]
      可以用下面的命令来创建PLL的两个时钟C0和C1。我们把时钟命名为CLK25M和CLK50M,source clock为CLK_IN。
create_generated_clock -name CLK25M -source CLK_IN -duty_cycle 50.000 -multiply_by 1 -master_clock {CLK_IN} [get_pins {PLL1|altpll_component|auto_generated|pll1|clk[0]}]
create_generated_clock -name CLK50M -source CLK_IN -duty_cycle 50.000 -multiply_by 2 -master_clock {CLK_IN} [get_pins {PLL1|altpll_component|auto_generated|pll1|clk[1]}]
      用这两个命令创建的时钟与derive_pll_clocks命令创建的时钟的本质是一样的,只是给时钟定义了不同的名字。当然我们也可以用derive_pll_clocks中对时钟的命名方式来使用create_generated_clock命令。
    同样的,可以按照上面的方法,在TimeQuest里查看创建时钟的结果,如下图所示。
 


       到此为止,我们创建了PLL的基准时钟以及PLL输出的两个时钟CLK25M和CLK50M。
DA_SCLK时钟:
       在TimeQuest的Tasks窗口里,选择Report Unconstrained Paths命令,TimeQuest会报告出所有需要下约束但实际并没有约束的情况。在Report里的Unconstrained Path列表下,我们可以查看这个报告。双击Clock Status Summary,就可以在主窗口看到所有时钟的情况。见下图,很明显,软件辨识出DAC7512模块下的DA_SCLK为时钟信号,但是我们并没有对该时钟添加约束,所以用红色将这个时钟显示了出来。下一步我们就来创建这个时钟。
 


        DA_SCLK是用CLK50M通过二分频电路得到的。所以其source clock为CLK50M。但是,我们在使用create_generated_clock命令创建该时钟的时候,在-source的参数里,却不能直接使用CLK50M,而必须使用CLK50M所对应的pin,即PLL1|altpll_component|auto_generated|pll1|clk[1]。 这主要是因为-source参数只支持pins,ports和registers。
       DA_SCLK是由CLK50M通过二分频电路生成的,其代码如下:
reg DA_SCLK;
always @(posedge CLK50M or negedge RESET)
begin
if(~RESET)
DA_SCLK <= 1'b0;
else
DA_SCLK <= ~DA_SCLK;
end
     可以看到,本质上DA_SCLK为一个寄存器的输出,所以使用get_registers命令获取DA_SCLK。DA_SCLK是由CLK50M经二分频电路生成的,所以-divide_by的参数应该是2。
      综上所述,用下面的命令创建DA_SCLK:
create_generated_clock -name DA_SCLK -divide_by 2 -source [get_pins {PLL1|altpll_component|auto_generated|pll1|clk[1]}] [get_registers {DAC7512:DAC7512|DA_SCLK} ]
     到此为止,DAC7512控制器中所有4个时钟都创建好了。如下图所示:
 


      我们再看TimeQuest中Unconstrained Paths中clock Status Summary,就会发现,所有的时钟都已经被添加了约束。


用Quartus II Timequest Timing Analyzer进行时序分析 :实例讲解 (三)
  (2012-06-26 10:28:46)
 转载▼
标签: 
杂谈

   上面已经把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]
     在DAC7512控制器里,CLK25M,CLK50M和DA_SCLK三个时钟是同步时钟。默认情况下,它们已经被软件放到了同一个group里,所以我们不需要对其做任何的处理。
    但假设CLK25M属于一个group,而CLK50M和DA_SCLK属于另外一个group,我们就要用set_clock_groups命令把二者设为异步时钟,命令如下:
set_clock_groups -asynchronous -group {CLK25M} -group {CLK50M DA_SCLK}
     我们对比一下把CLK25M设定为CLK50M的异步时钟前后TimeQuest对时序分析的处理情况来看这个命令的作用。下面是在添加这个命令前后TimeQuest中Report clock transfer的结果。
在没有添加这个命令前,软件默认三个时钟都是同步时钟,所以会分析并报告出三个时钟之间所有的timing path。
 
       在添加这个命令以后,软件认为CLK25M和CLK50M/DA_SCLK是异步时钟,所以就直接将CLK25M和CLK50M/DA_SCLK之间的timing path设为false 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命令由软件自动计算并添加。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值