SDC 中clock uncertainty ideal propagated virtual clock 闲谈

今天突然想起写这个话题其实是别人来问我。我就突然想起这些东西,虽然是基础,但是还是感觉有必要单独摘出来说一下的。不过很多基础概念我不想废话,特别基础的我也不太想解释(因为我相信大家是有一定基础的)废话不多说上干货。

clock uncertainty 分为 SKEW + JITTER + 其他不确定因素。

SKEW 就是clock到不同sink 点的差值。
JITTER 就是clock的抖动导致时钟的周期会有偏差。
其它不确定因素就是除了上面两种因素外影响时钟的情况。

既然原理清楚,那么SYN PR STA 中会有哪一些变化呢?

首先一般setup uncertainty 设置的值是小于hold uncertainty 的值的。
因为HOLD 是不考虑JITTER 的 而SETUP 是要考虑的。 (至于原因是STA setup hold 分析的基础概念)

另外在ccopt 也就是张完clocktree之后要重新设置clock uncertainty 。clock uncertainty 整体值都会变小。

因为这个时候clocktree 已经绕好了。SKEW 值已经确定下来。就不需要用uncertainty 来悲观模拟了。

至于其他不确定因素可能会在clock period 上乘以一个值比如0.98来升频,模拟。

======================================
topic 1 结束下来来说 propagate clock virtual clock

首先只有在ccopt clock tree张完后clock tree 会被工具自动propagated
innovus 会 set_propagated_clock [all_clocks ]
这时候所有内部clock 都会propagated ,这会导致io部分的input output delay 的结果变的悲观。 这是假的。因为外部clock 是ideal的。 所以为了平衡这种情况。innovus会默认做update_io_latency 这个默认被植入到innovus
ccopt 当中。 这时候你会看到所有的clock 都会设置一个负值 set_clock_latency -source -xxx 来平衡掉clock tree 和io外部clocktree延时不平衡的问题。

但是这带来了另一个问题就是这种在看innovus timing report 时候很不方便。因为你看到的clock tree 延时被减了一部分。很不方便。

为了解决这种问题。就产生了方法二

在innovus ccopt 时候关掉 update_io_latency 的操作。 然后sdc owner 在写sdc时候给所有的master clock 创建virtual clock 来约束IO

然后ccopt 之后通过人为自己写脚本,计算内部clock tree 的最长和最短 tree 长的平均值,然后用set_clock_latency 来反标到virtual clock 上这样就io部分内外clock 就平衡了。

比如
proc innovus_update_io_latency {ref_clock virtual_clock} {
foreach c_mode [all_constraint_modes -active] {
set clock_long [get_ccopt_skew_group_delay -longest -skew_group ${ref_clock}/${c_mode} -check_type setup]
set clock_short [get_ccopt_skew_group -delay -shortest -skew_group ${ref_clock}/${c_mode} -check -setup ]
set tree_latency [expr ($clock_long + $clock_short)/2]
set tree_latency [format “%.4f” $tree_latency]
set_interactive_constraint_mode $c_mode
set update_cmd "set_clock_latency -source $tree_latency $virtual_clock "
eval $update_cmd
set_interactive_constraint_mode {}
}}

然后方案3 ,这个是一种思路有的PR 工具我听说张完clock tree 后会吧propagated_clock设置到port上

比如 set_propagated_clock [get_ports $clock_ports ]

这样内部clock network 是propagated 了。但是clock 本身还是ideal的。
这时候再给clock 设置set_clock_latency xxx [get_clocks xxx] 来平衡内外差。

(注意这个时候不是set_clock_latency -source 而是set_clock_latency)

好了这就是全部。觉得好的话麻烦点个赞

1 个赞

你好,请问这种情况是怎么回事?用的是方法1。谢谢。


左边innovus report timing的时候发现没有时钟传输延迟,导致最终pt里面检测in2reg的时候hold时序不通过
不知道为什么innovus里面没有时钟传输延迟,如果innovus里面也计入时钟传输延迟的话,pt那边应该就不会有问题了

你的innovus 在ccopt 过后工具自动为了平衡io delay sdc里面给clock port 设置了 set_clock_latency -source -0.153 [get_ports CLK]

但是你的pt sdc里面没有这条。然后就导致你看到的结果。

感谢回复,这个问题困扰我几天了。
但是我觉得pt是对的,时钟的延迟大于数据的延迟才能保证hold是对的。
我设置的input_delay min是0,相当于输入的时候时钟数据是对齐的。那么经过内部clock tree之后,数据的延迟要大于时钟的延迟才能保证hold。所以我才认为pt是对的,innovus那边有问题

innovus确实也产生了latency.sdc这个文件,每个corner各有一个。
但是我report_property [get_clocks sys_clock]时发现时钟并没有带延迟信息

与你的理解相反,从结果看反而pt 更悲观。 当然也谈不上对错。io delay么。

innovus ccopt 过后你的clock port propagte , 有了延时。但是你的io 部分的launch clock 本来也应该有一个延时,但是那东西目前是虚拟的不存在的。所以innovus给你的block clock port 上反标一个负的延时来平衡这种悲观差异。

pt 因为你吃的sdc里面丢掉了反标的负延时。所以结果更悲观。因为在顶层看你的block 的io是有launch clock 的而launch clock 是有延时的。

不要试图用get_property 来观察这种差别。本来那个sdc命令应该是设置到port上的。clock 的property 应该是不带的。 或许你可以report_clock等命令观察。但是我一般看下timing报告就知道了。

感谢大佬提供思路。
此处我画了一下pt的延迟图。我的约束是input_delay min是0,在这个地方检测hold是否满足。分别计算时钟和数据的延迟,发现hold确实有问题。难道我理解的有问题吗?

没太明白你想问啥,图画的没啥问题,图中那个hold slack 应该是个负值(0.92-0.154), 如果你把图里的capture clock 往左推像innovus干的那样 , hold slack不就正了么。

我是觉得pt分析的结果是对的,而innovus不应该把capture clock往左推,innovus应该跟pt用一样的时钟,这样innovus才能在数据路径上插入足够的buffer,最终在pt里面校验hold的时候也不会有violation。
但是我不知道怎么样才能让innovus不把capture clock往左推。
按照你的思路innovus也没错,这是我不能理解的

pt和innovus的结果都是对的,之所以结果不同,因为你给的sdc输入文件是不一样的。 pt的没带innovus 的 set_clock_latency 。 innovus也不是把tree推短,那个值是个虚拟值。 你的tree 物理走cell该多长还是多长并没有变。 你要不加我微信吧 18502999181 。我拉你进技术群。