使用TimeQuest进行SDRAM时钟约束实例
0赞特权同学的《SDRAM时钟相移估算》针对SDRAM的相移设置做了一些介绍,也列举了一个活生生的例子进行讲解。很多朋友在实际应用中即便对SDRAM的时序模型熟悉了,当可能仍然不知道在TimeQuest这个工具上如何进行时序约束和分析,尤其对于这个SDRAM专用时钟的约束分析。本文就是要和大家来探讨实际应用中如果使用TimeQuest进行SDRAM时钟约束。
这个实例中,PLL的输出时钟clk1为100MHz,相移为0ns。PLL的输出时钟clk2为100MHz,相移为1.5ns(具体为什么不是本文讨论的重点,可以参考《SDRAM时钟相移估算》)。同时,这个clk1作为FPGA内部SDRAM控制器的时钟,而clk2输出到外部连接到SDRAM的时钟管脚。为了说明问题,我们首先会给这个作为SDRAM时钟的sdram_clk信号使用Set Maximum Delay与Set Minimum Delay添加时序约束:
set_max_delay -from [get_clocks {sys_ctrl:uut_sys_ctrl|PLL_ctrl:uut_PLL_ctrl|altpll:altpll_component|_clk2}] -to [get_ports {sdram_clk}] 5.000
set_min_delay -from [get_clocks {sys_ctrl:uut_sys_ctrl|PLL_ctrl:uut_PLL_ctrl|altpll:altpll_component|_clk2}] -to [get_ports {sdram_clk}] 1.000
该约束的意义就是希望PLL的输入时钟_clk2到sdram_clk管脚上的延时在1ns~5ns。然后我们得到的Setup slack分析结果如图1所示。
图1
_clk2到sdram_clk路径延时为1.567ns。
下一步我们要产生一个名为SDRAMCLK的生成时钟,用于SDRAM数据、地址等信号的时序约束。这个生成时钟的约束有讲究,却并不难。如图2所示,命名为SDRAMCLK,时钟源(Source)选择PLL的输出时钟clk2,目的时钟(Targets)选择连接到SDRAM上的sdram_clk。
图2
约束完成后产生约束脚本如下:
create_generated_clock -name {SDRAMCLK} -source [get_nets {uut_sys_ctrl|uut_PLL_ctrl|altpll_component|_clk2}] -master_clock {sys_ctrl:uut_sys_ctrl|PLL_ctrl:uut_PLL_ctrl|altpll:altpll_component|_clk2} [get_ports {sdram_clk}]
然后就可以使用生成时钟SDRAMCLK约束相关的数据总线或地址总线。例如可以对数据信号进行约束:
set_input_delay -add_delay -max -clock [get_clocks {SDRAMCLK}] 4.500 [get_ports {sdram_data[0]}]
set_input_delay -add_delay -min -clock [get_clocks {SDRAMCLK}] -2.000 [get_ports {sdram_data[0]}]
然后我们任意查看一组Registers to Outputs的Setup time和Hold time约束报告,分别如图3和图4所示。
图3
图4
看到了吧,这时候的锁存沿(latch clock,即SDRAMCLK)的时钟网络延时(Clock network delay)就是图1中看到的1.567ns。那么也就说明所产生的这个约束SDRAM的时钟是真实的时钟,它的路径延时也是真实的。