在开始之前有两件事想征求一下大家的意见:
-
最近有同学反映文章中很多专业词汇不太明白,因此想开一个系列专门讲一些后端的基础知识和词汇,毕竟后端的知识颇为繁杂,对入门者极为不利。因此如果大家有不懂的知识尽管留言,我会以适当的形式统一讲解。
-
如果有人对提高效率的脚本、命令等感兴趣,我也想将自己的一点经验和大家分享。如果大家有实际工作或学习中遇到的这方面问题也可以留言提出来,看看能不能有比较好的解决方案。
言归正传,上次讨论了CTS的策略以及CTS用的SDC的基本写法。在进一步讨论之前,我们先回忆一下CTS的基本流程:
在我们已经决定了如何进行时钟树综合后,就需要对EDA工具进行一系列的设置来使其能够忠实地反应我们的策略。因此,今天我们谈谈CTS的设置。
有人可能担心不同的工具中CTS的方法是否会有不同。以我接触过几种主要的工具的经验来看,虽然某些设置的叫法可能不同,但是其本质并没有变化。比如Innovus的CCOpt中将这些设置称为CTS spec,但是其本质内容大同小异。
在具体讨论CTS设置之前,我们首先需要了解工具在CTS阶段的行为到底是什么。换句话说,所谓时钟树综合,到底是在综合什么东西呢?
时钟树综合阶段,工具首先对clock line上的cell/net进行DRV优化,主要包括max_transition, max_capacitance, max_fanout, max_net_length等约束;在此之后,会分别对每个clock的latency和skew进行优化,也就是尽量缩短每个clock的latency并减小sink之间的skew;最后,如果有clock之间的latency需要balance,还会将这些clock的latency尽量做平。
1. Target Skew:clock内部或clock之间需要实现的目标skew值。
在之前的文章中提到过,对于CTS我们需要达到三个目标:skew尽量小、latency尽量短、common path尽量长。而target skew这个设置的目的就是告诉工具,我们希望时钟树综合后能够达到的skew值是多少。在ICC2中可以采用如下命令实现:
set_clock_tree_optio
ns -target_skew 100 -clock CLK ;# unit : ps
2. Clock Max Transition: clock line上cell的最大transition/slew值。
我们知道transition基本是cell高低电平翻转所需要的时间。对于clock line上的cell,我们一般需要对其施加比其他cell更严格的transition约束。不同工艺,不同design和不同时钟频率的芯片对此可能都有不同的设置,但是我们可以大致遵从时钟周期的10%-20%的规律。对于某些频率较低的design可能需要更紧的约束。在ICC2中可以通过如下命令实现:
set_max_transition 200 -clock_path [get_clocks CLK] ;# unit : ps
3. CTS exceptions:精确控制部分时钟树的设置。在此我们遵从ICC的术语,在ICC2中某些术语已经弃用,但仍能找到对应的设置方法。
stop pin : 使CTS在某处停止或者用于告诉工具将某些pin/port辨认为sink;
set_clock_balance_points -clock clock -consider_for_balancing true -balance_points pins
exclude pin : 将某些pin/port从balance对象中移除,否则CTS将默认balance所有sink;
set_clock_balance_points -clock clock -consider_for_balancing false -balance_points pins
float pin : 用于对某些sink设置useful skew。用法为在sink的clock pin上加上一个正的或者负的delay,从而使工具在计算latency的时候考虑到这些delay而把clock tree做长或者做短。
set_clock_balance_points -clock [get_clocks CLK] -delay 50 -balance_points [get_pins U2/CLK]
non-stop pin : 工具CTS时可能会在某些地方停住,此时我们需要告诉工具穿过这些地方 继续向前,比如分频DFF。在ICC2中取消了原来在ICC中存在的non-stop pin设置,改为统一在sdc中通过create_generate_clock来实现这一功能。
4. CTS cells : 控制clock line上使用cell的种类。
因为我们需要clock line上的delay和variation尽可能的小,所以很多时候就需要人为规范CTS时使用的cell种类。一般在多种Vth共存的design中,我们总是会使用最快的cell,同时尽可能避免特别小和特别大的cell用于CTS。
set_lib_cell_purpose -include cts [get_lib_cells $cts_cells]
5. Clock Routing Rules : 控制时钟树上net的绕线规则。包括金属层、线宽、线间距、是否需要shielding等(NDR:Non-Default Rule)。
一般来说clock绕线需要选取尽量高层的金属,尽量宽的线宽来实现更短的latency,同时需要尽量宽的线间距来降低crosstalk的影响。因此,常用的routing rule可能包括2x width 2x spacing, 3x width 2x spacing等,有些公司可能还需要加上shielding。此设置可应用create_routing_rule来实现:
create_routing_rule CTS_NDR -default_reference_rule \
-widths { M1 0.1 M2 0.11 M3 0.11 M4 0.11 M5 0.11 } \
-spacings { M2 0.16 M3 0.45 M4 0.45 M5 1.1 }
上述routing rule还有很多其他option,大家可以在实际使用中慢慢体会。
6. 设置balance groups。
在实际设计中,我们有时可能会遇到某些path的launch和capture分属于不同的clock,因此需要对不同的clock进行balance。可以通过下面的命令实现:
create_clock_balance_group -objects {clk1 clk2 clk3} -name balance_group1
至此,CTS的基本设置就算告一段落了。其实在ICC2中还有很多其他的option和命令来微调CTS,但是对于clock不太复杂的design,上述设置完全够用了。
除了保证CTS的基本质量之外,对于某些特殊design或者先进工艺,CTS的EM以及Power问题也是我们关注的重点。尤其是在传统CTS之外的一些特殊时钟树,比如H-tree, fishbone等,都是一些很有意思的话题。希望以后我们有机会能够共同探讨。
在下次CTS系列的最后一片文章中,我将会和大家聊聊如何调用工具命令跑CTS以及如何查看CTS的结果,同时会涉及如何debug一些CTS的常见问题,敬请关注。