根据之前的介绍,我们已经掌握了ICC2和Innovus中如何根据工具提供的Clock Tree Analysis Window来分析时钟树的结构(Innovus对应的是Clock Tree Debugger)。
下图为本次IC训练营Cortexa7core的时钟结构。其中用绿色框出来的是之前所说的common clock ga
ting,为了把common clock path做得更长点,已经建议各位将它摆放至block中心位置。关于clock gating cell的摆放已经在每日问题解答中给出解释。
但是细心的同学已经发现时钟结构上还有一个分支,是不经过那个common clock gating的,如下图用黄色标注的分支N。经过分析,这个module其实就是我们的u_cortexa7noram/u_ca7clk。这个module看名字就像是时钟产生
电路,值得注意的是这个module中有一少部分的reg是要与其他分支进行交互的,即要做timing check。
这里补充一点:这个时钟结构图上的任何cell,只要被选中后就会在layout上同步高亮出来。
那这样会出现一个情况是:分支N与其他分支的common clock path会比较短。从我们报出来的timing path(将clock tree展开)看,它们只有四级的common path,即CTS_cts_trgdly_40331/ZN是它们最后一个common point。Common clock path一旦比较短,那么考虑OCV效应下的CRPR补偿就会比较小(28nm必须考虑OCV),从而setup和hold可能就会有violation。
CRPR能补偿crosstalk吗?
下方为一条timing path的launch clock path和capture clock path的具体情况。
clock CLKIN (rise edge) 0.00 0.00
source latency 0.00 0.00
CLKIN (in) 0.01 0.01 r
CTS_cts_trgdly_40332/ZN (CKND2BWP40P140) 0.04 0.05 f
CTS_cts_trgdly_40336/ZN (CKND2BWP40P140) 0.06 0.11 r
CTS_cts_trgdly_40338/ZN (CKND12BWP40P140) 0.03 0.14 f
CTS_cts_trgdly_40337/ZN (CKND12BWP40P140) 0.02 0.16 r
CTS_cts_trgdly_40335/ZN (CKND2BWP40P140) 0.04 0.20 f
CTS_cts_trgdly_40331/ZN (CKND16BWP40P140) 0.03 0.22 r
CTS_cto_dtrdly_37819/ZN (CKND2BWP40P140) 0.05 0.27 f
CTS_cto_dtrdly_40324/ZN (CKND16BWP40P140) 0.02 0.30 r
CTS_cto_dtrdly_40326/ZN (CKND2BWP40P140) 0.02 0.32 f
CTS_cto_dtrdly_40325/ZN (CKND2BWP40P140) 0.04 0.35 r
CTS_cto_dtrdly_40323/ZN (CKND2BWP40P140) 0.04 0.39 f
CTS_cto_dtrdly_37818/ZN (CKND16BWP40P140) 0.01 0.40 r
CTS_cts_inv_421737750/ZN (CKND3BWP40P140) 0.04 0.44 f
CTS_cts_inv_421237745/ZN (CKND6BWP40P140) 0.09 0.53 r
u_cortexa7noram/u_ca7clk/cnt_valueb_reg_reg_57_/CP (SDFQD0BWP40P140)
0.01 0.54 r
clock CLKIN (rise edge) 1.40 1.40
source latency 0.00 1.40
CLKIN (in) 0.01 1.41 r
CTS_cts_trgdly_40332/ZN (CKND2BWP40P140) 0.04 1.45 f
CTS_cts_trgdly_40336/ZN (CKND2BWP40P140) 0.05 1.50 r
CTS_cts_trgdly_40338/ZN (CKND12BWP40P140) 0.02 1.52 f
CTS_cts_trgdly_40337/ZN (CKND12BWP40P140) 0.02 1.54 r
CTS_cts_trgdly_40335/ZN (CKND2BWP40P140) 0.04 1.58 f
CTS_cts_trgdly_40331/ZN (CKND16BWP40P140) 0.02 1.60 r
u_cortexa7noram/u_ca7clk/u_ca7cell_clkgate/u_clkgate/Q (CKLNQD6BWP40P140)
0.04 1.64 r
u_cortexa7noram/u_ca7clk/u_ca7cell_clkgate/CTS_cts_inv_418937722/ZN (CKND16BWP40P140)
0.02 1.66 f
u_cortexa7noram/u_ca7clk/u_ca7cell_clkgate/CTS_cts_inv_418437717/ZN (CKND16BWP40P140)
0.02 1.68 r
u_cortexa7noram/u_ca7clk/u_ca7cell_clkgate/CTS_cts_inv_417437707/ZN (CKND16BWP40P140)
0.02 1.69 f
u_cortexa7noram/u_ca7clk/u_ca7cell_clkgate/CTS_cts_inv_416437697/ZN (CKND16BWP40P140)
0.02 1.71 r
u_cortexa7noram/u_ca7clk/u_ca7cell_clkgate/CTS_cts_inv_414337676/ZN (CKND16BWP40P140)
0.02 1.73 f
u_cortexa7noram/u_ca7clk/u_ca7cell_clkgate/CTS_cts_inv_411437647/ZN (CKND16BWP40P140)
0.02 1.76 r
u_cortexa7noram/u_ca7dpu/u_dpu_etmif/u_inter_clkgate_iq/u_clkgate/Q (CKLNQD12BWP40P140)
0.09 1.85 r
u_cortexa7noram/u_ca7dpu/u_dpu_etmif/u_dpu_etmif_d/etmdd_o_reg_63_/CP (SEDFCND4BWP40P140)
0.01 1.86 r
那我们有没有办法把这个common path做长点呢?
方法一:bounds法
我们可以将ca7clkmodule中与其他module(dpu模块)有timing path的寄存器摆放至Common clock gating那个位置来实现。粗暴的做法是将ca7clk这个module做一个bounds或region来实现。根据实际情况需求,也可以再加一颗guide buffer避免工具出错。
方法二:分步做tree思想
这个方法的提出主要目的是让大家体验下分段长tree的基本思想。在CLKIN port处加一颗guide buffer,然后在这颗buffer输出定义一个时钟。这样整条CLKIN的tree就被分成两部分:第一部分是从CLKIN port到guide buffer,第二部分是从guide buffer到所有的sink。
方法三(分步思想二):
在common clock gating的输出端定义时钟,并根据ICG后面的实际tree长度来调整分支N中寄存器的floating pin值。
采用这些方法后我们可以在ICC2中看到如下的clock tree。确实common clock path的级数变多了,符合我们的预期。
这个案例如果不这么做还可能存在一个潜在问题。Port门口附近的绕线资源会比较紧张。因为clock net我们都是设置的ndr。下图为处理前的ca7clk的reg的部分clock tree走线,所有的tree都是在门口port附近垫clock inverter。这部分clock inverter是为了和其他module的sink做balance而加入的。这些clock inverter的cell name是带着特殊的关键字“cts_trgdly”。
原作者:芯农民 吾爱IC社区