热度 18
2013-3-9 12:48
6296 次阅读|
0 个评论
TimeQuest 之 multicycle paths 王敏志 (现在发现字数会莫名其妙超出) 实际应用实例 图 6 是本人实际工作中设计的一个工程部分示意框图,在全编译之后主要是图中的三个 PLL 的输出时钟有报告时序问题,在不进行时序约束的时候上板调试是没有遇到什么问题的,只是这么多时序违约报告不知道长时间运行是否稳定,所以有必要仔细分析每一个违约时序报告。 图 6 这个工程只是对于 CLKIN (外部 100MHz 时钟)和 PLL 的输出进行约束,如下所示 create_clock -period 10.000 -name refclk -waveform {0 5} create_clock -period 10.000 -name clkin -waveform {0 5} derive_pll_clocks 全编译之后查看 TimeQuest 的报告图 7 所示, *pll*clk 、 *pll*clk 和 *pll*clk 分 图 7 别是图 6 中的 100MHz 、 250MHz 和 62.5MHz 三个时钟我们发现这三个时钟都有报告时序违约,而且 250MHz 的 Fmax 报告才不到 94MHz 。打开 TimeQuest 分别对这三个时钟的红色报告执行 report timing 命令并进行分析,图 8 显示了对于 100MHz 时钟执行 Report Timing 后的结果,产生违约的路径的 Launch clock 是 62.5MHz , Latch clock 是 100MHz ,也就是说这些违约路径都是跨时钟域的路径,再分析源代码发现这些路径都是跨时钟传递数据,逻辑设计保证在传递数据的时候能安全传递,即通过握手控制信号保证数据稳定传输,所以这些路径可以认为是 false paths 。针对这些路径加入 false paths 约束如下 set_false_path -from }]\ -to }] 再重新编译工程,发现 100MHz 的时序违约没有了,如图 9 所示。 图 8 、对 100MHz 时序违约路径执行 Report Timing 命令结果 图 9 、解决 *pll|clk 即 100MHz 时序违约 重新打开 TimeQuest ,依照从易到难原则,这次解决 *pll|clk 即 62.5MHz 时钟时序违约问题。同样执行 Report Timing 命令我们得到类似图 8 的报告界面,如图 10 所示。 图 10 、对 62.5MHz 时序违约路径执行 Report Timing 命令结果 产生违约的路径的 Launch clock 是 100MHz , Latch clock 是 62.5MHz ,也就是说这些违约路径同样都是跨时钟域的路径,再分析源代码发现这些路径都是跨时钟传递的控制信号(图 6 框图所示),这些 100MHz 时钟域的控制信号和 62.5MHz 时钟域被控制的模块是完全异步的关系,所以这些路径可以认为是 false paths 。针对这些路径加入 false paths 约束如下 set_false_path -from }]\ -to }] 上述 false paths 命令其实就是前面 false paths 命令的反向操作,即这两条 false paths 命令分别“ cut ”了 100MHz 和 62.5MHz 这两个时钟域之间路径的时序分析。再重新编译工程,发现 62.5MHz 的时序违约没有了,如图 11 所示。 图 9 、解决 *pll|clk 即 62.5MHz 时序违约 还剩最后一个,总的 slack 到 -10.586ns ,打开 TimeQuest 并对此违约路径执行 Report Timing 命令,报告结果如图 12 所示。 图 12 、对 250MHz 时序违约路径执行 Report Timing 命令结果 由于负 slack 量很大,所以时序违约也许不止一种情况(实际情况也确实如此),图 12 所示的报告默认只报告最差的 10 条。仔细分析图 12 已经报告出来的这些违约路径,发现跟图 8 和图 10 报告的违约路径类似,也都是一些跨时钟域的路径,这里的 Launch clock 是 100MHz , Latch clock 是 250MHz 。也就是说可以把这些路径当作 false paths 处理,由于本文是论述多周期,所以我想是不是可以通过加入多周期约束来解决这个问题呢?尽管 100MHz 与 250MHz 不是整数倍的关系,但是图 12 时序图看出可以加入一个 4 周期的 end 建立多周期约束,同时加入一个 3 周期的保持多周期来解决这个问题。命令如下所示: set_multicycle_path -from }] -to }] -end -setup 4 set_multicycle_path -from }] -to }] -end -hold 3 ( 注:本人不确定多周期是否必须两个时钟必须要是整数倍关系,但根据这个例子似乎不是也可行啊! ) 重新编译工程,发现 250MHz 还是有时序违约,但是负的 slack 减少了,如图 13 所示 图 13 打开 TimeQuest 针对违约路径执行 Report Timing 命令,得到的报告结果如图 14 所示 图 14 仔细分析图 14 报告的违约路径,以及时序图,这些违约路径的 Launch clock 和 Latch clock 为同一时钟,即 250MHz 时钟。研究这些违约路径的原始代码发现 from node 其实是一个计数器的输出,而此计数器的计数频率虽然是 250MHz ,但是有条件的计数,所以这些路径更适合加多周期约束,这里先使用 false paths 约束,最后再把图 12 和图 14 所示的违约路径分别改成 false paths 和多周期路径约束。这里先加入的 false paths 如下所示 set_false_path -from }] -to }] 重新编译工程,发现 250MHz 的时序违约没有了,而它的 Fmax 也提高到 250MHz 以上了,如图 15 所示(注意和图 7 比较)。 图 15 附 1 前面有提到图 12 所示的违约路径应该 false paths 约束,而图 14 所示的违约路径应该加多周期路径约束。那么首先将图 12 所示的违约路径修改成 false paths 约束,约束命令如下,也即 Launch clock 是 100MHz ,而 Latch clock 是 250MHz 时钟。 set_false_path -from }] -to }] 重新编译后的结果如图 16 所示。 图 16 上图显示修改成 false paths 约束后似乎也能解决时序违约问题,对比图 15 , Fmax 似乎跑的更高一些。而图 14 所示的时序违约路径的约束修改为多周期路径约束并没有成功,不管我如何加多周期约束在 FIT 的时候都是通不过,提示“ Critical Warning (332008): Read_sdc failed due to errors in the SDC file ”,也许是多周期语法有错?下面列出我尝试过的命令格式: 第一条: set_multicycle_path -end -setup –to }] 3 第二条: set_multicycle_path -end -setup –to }] 3 第三条:加上 –from 即从时钟到上述 PINs 也不行。 第四条:将“ get_pins” 改成“ get_cells ”以及“ get_registers ”也不行。 所以对于图 14 显示的违约路径还是加 false paths 来处理。最终工程的时序报告如图 16 所示。