在所有的后端工具里边,有三个重要的引擎:auto-place,CTS,auto-route三个。这里边的auto-place是决断了整个设计时序的基点。由于,auto-place的动作是在设计的preCTS阶段,所以这里的设计时序就是广义上说的:数据路径(datapath)时序(timing )。当然,就算是到了CTS/route阶段后,也可以继续利用auto-place数据优化的功能,在数据库上做数据路径增量优化(optDesign -increment)。可以说,数据路径的优化手段,实际上是贯穿在整个后端流程上的。
这里结合过往的经验,以及invs特有的先进策略,一起来看看,数据路径优化里边的重要知识点:路径分组(path group)。看看这其中的奥妙和有趣的事情。ICer GO!
众所周知,无论是综合工具(DC、genus或者precision等)抑或是APR工具(icc、icc2或者invs等),数据路径优化(data path optimization)一直是影响时序质量的重要因素。由于综合使用了ideal clock,可以说,data path的优化就是综合阶段的主要工作,这个和后续的APR工具的第一个主动作:auto-place,形成了前后连贯,相辅相成。尽管这两个引擎和所处工具的位置不同,但是目标是高度一致:优化数据路径的时序。这也是最近两年聚合型R2G工具大行其道的一个重要原因。
- S家的Fusion Compiler: DCG + ICC2
- C家的iSpatial: genus + innovus
无论什么工具,数据路径优化(data path optimization)一直是基于路径分组(path group)进行的,想要提高数据路径优化就需要了解路径分组(path group)的理论。
经典路径分组(path group)理论
在经典的数据路径优化理论(主要是基于S家,因为DC是综合界的长期主导),对于数据路径优化,DC采用了基于**时钟域(clock domain)**的方式进行处理:每一个时钟域都会被工具判定为一个路径分组(path group)。
路径分组(path group)的基础知识
PS:虽然最新的DC也提供了基于违例(violation)和设计层次(hierarchy)的自动路径分组(path group)创建命令;create_auto_path_groups
,但是这个命令只是一个补充性的,并没有动摇S家传统的路径分组方式。
S家的这种分组方式对用户是很友好的,基本就是将SDC的create_clock
和create_generate_clock
命令直接翻译成了group_path
命令,映射关系见下表:
SDC命令 | 类group_path命令 | comment |
---|---|---|
create_clock PCLK1 | group_path -to $FF_under_PCLK1 | 主clock |
create_generte_clock -name gen_clk1_pclk1 -master PCLK1 -add -pin ...... | group_path -to $FF_under_gen_clk1_pclk1 | 分频clock |
create_generte_clock -name gen_clk2_pclk1 -master PCLK1 -add -pin ...... | group_path -to $FF_under_gen_clk2_pclk1 | 分频clock |
create_clock PCLK2 | group_path -to $FF_under_PCLK2 | 主clock |
create_generte_clock -name gen_clk1_pclk2 -master PCLK2 -add -pin ...... | group_path -to $FF_under_gen_clk1_pclk2 | 分频clock |
create_generte_clock -name gen_clk2_pclk2 -master PCLK2 -add -pin ...... | group_path -to $FF_under_gen_clk2_pclk2 | 分频clock |
这个简单的映射方法,有两个潜在的问题:
- 如果有gen-clock的存在,按照时钟传播理论,那么主clock和gen-clock会同时送达同一个FF
- 如果有多个主clock存在,跨时钟域路径(cross domain data path)处理方式
利用下图,来解释一下这两个问题:
- 基于SDC层叠(cascade clock)理论,所有的FF都是使用离它最近的clock或者gen-clock,所以上述的FF1~FF4都是使用了gen-clock,所以这些FF都只会被归为gen-clock的domain
- 默认情形,SDC里边所有的clock都是做同步(synchronous)关系处理,除非用户单独指定,命令是:
set_clock_groups -group $PCLK_1_GRP -group $PCLK_2_GRP [-physically_exclusive| -logically_exclusive| -asynchronous
所以,使用下面的SDC命令,DC/SDC 就可以明确每个FF所归属的时钟域和同步时序关系了:
create_clock/clock_generate_clock
set_clock_groups ......
基于路径分组的优化策略
前边说过,这种方式最大的优势就是方便,除过声明clock domain之间的同步、异步等关系,用户不用再做其他设定,工具就可以处理后续的事宜。
基于上,整个S家的R2G流程都是使用上述的path group 理论进行时序优化的。基本流程如下:
- 基于path group进行WNS优化,同时兼顾TNS。(工具总是基于WNS来进行优化,这样才能有效的提高整体设计质量。相反只要TNS的重要新并非那么高了)
- 默认的path group具有同样的优先级(weight),除非用户指定。对于具有优先级区别的路径分组,工具会在出现修复冲突的时候,使用优先级进行解冲突(conflict)
所以这里会衍生出一个新的问题,譬如下图:
对于上述路径,FF2会在同一个clock domain下有两个路径,FF1->FF2和SRAM1->FF2,如果此时有下列情景:
- FF1-> FF2 violation -1ns
- SRAM1-> FF2 violation -0.5ns
基于WNS理论,由于-1ns的存在,这个时候工具就不会去做SRAM1->FF2的timing修复。但是用户可能更为关注的是SRAM1->FF2的violation,所以通常的做法就是使用group_path进行再次分组,譬如:
group_path -name GRP1 -from FF1 -to FF2
group_path -name GRP2 -from SRAM1 -to FF2
这样就会产生两个平行的组,工具都可以看到他们的TNS,所以大概率的结果会是下面的结果:
FF1 -> FF2 | SRAM1 -> FF2 | |
---|---|---|
分组前 | -1ns | -0.5ns |
分组后 | -1ns | -0.3ns (可能好于分组前) |
这个做法很常用,并且对S家的流程也很有好用,但是这里提高SRAM->FF2的代价是跳过了FF1->FF2优化,也就是说整个数据库的WNS(-1ns)并没有发生变化。
但是最近使用了invs后,对invs的分组理论进行了学习和理解,发现了一个新思路,很有趣。
invs 路径分组(path group)的新思路
C家的R2G流程,基本还是沿用了S家的时序分析基本理论,基于SDC是标准的时序约束交付数据,C家严格遵循,除过一些猫叫咪的名词差异(leading/tailing等),核心的理论是完全一样的。
PS:这里要给C家点赞,确实S家在前端和中端的统治地位不容撼动,打不过我就加入,这个也是顺应当下的商业策略的。
近似的,C家的时序路径的优化也是基于path group的WNS的,WNS优先级大于TNS。
传统路径分组(path group)的挑战
在读入SDC后,某些FF会继承一个或者多个clock domain的属性,这种比较常见,相应的描述可以参见S家的这个变量
这个变量默认是true,也就是说无论是S家还是C家,对于这种一个FF上有多个clock的情形默认是可以直接支持的,这样也对RTL/SDC的设计提供了尽量大的宽容度,一个图例如下:
譬如这里的FF1,就会有两个clock到达:gen_clk1_pclk1和gen_clk2_pclk1,按照传统S家的路径分组理论,FF1会被分别归入到gen_clk1_pclk1和gen_clk2_pclk1两个分组,按照默认方式,下面的path就有可能形成一个冲突(conflict)
FF0 -> FF1 vs FF2-> FF1
S家的工具默认的行为就是对每一个组进行修复,组合组之间不做一致性合并(merge),如果在FF0->FF1和径FF2->FF1的数据路径优化发生分歧(conflict),如果两个path’ group优先级恰巧又一样,S家的工具只能确保一个结果会好一点,这是因为:数据路径的修复在同一时间只能关注一个数据分组(path group)
这个情形在设计中非常常见,如果使用了传统分组,一个风险就是:**同样重要的时序很有可能不会同时被工具优化到最好。**所以,在借鉴了S家的分组方式,C家提出了自己的分组方式思想:基础路径分组(BPG:BasicPathGroup)
BasicPathGroup (BPG)的理论和特点
基于上述传统路径分组的优劣势,C家提出了一个新的思路:在传统路径分组的基础上,叠加一层新马甲(wrapper):BasicPathGroup (BPG)。通过BPG这个wrapper,可以较好的解决传统路径分组的短板。
这里看一下S家的时序分析理论,任何工具对时序质量的统计都是基于终点的(endpoint,EP),这个是所有STA工具评判时序质量的统计基础。但是由于时钟交叠(clock domain overlap)的情景,会导致在一个EP,产生多个report_timing的结果(multi path group per FF),同时也会让place_opt的引擎遇到类似的局面:一个单一FF,会同时出现多个path group的分组。
与其继续深耕,不如化繁从简(PS:这个确实是C家长期坚持的一个策略:简单就是美好),使用BPG,破除传统的基于clock domain的路径分组(path group),让每个EP回归到原本应该就应该有的形态:独一性(unique)。
使用BGP的方式,在上述情境下,FF1只会归为一个path group,这样就可以缓解传统路径分组的冲突(conflict)困扰。
默认invs流程,会使用BPG的方式进行分组,这里会有两类明确的组:
- reg2reg: 沿触发时序逻辑到沿触发时序逻辑
- reg2cgate:沿触发时序逻辑到电平触发的时序逻辑
除过上述两个组,其余所有未被覆盖的组都被工具称作default。所以,一个数据库,在invs里边的默认BGP的加持下会有这样的情形:
all = reg2reg + reg2cgate + default
当然,这里边并非说明:all 就等于设计里边的reg + cgate的数量总和,这是因为:如果你的设计里边有了IO 时序约束,那么大概率会有IN2REG或者REG2OUT的类型,这样:all >= reg_count + cgate_count。
默认,在同为Effort High的路径分组下,invs给出了自己的权重配比:reg2reg > reg2cgtage > default
采用的BGP分组:invs工具无论在何种情形下, 每一个reg,cgate都只有唯一的最高优先级的主分组,这个会给基于TNS修复方式的place 引擎解放了手脚,大大提升了修复结果。
当然,如果用户自己明确知道数据库里边有IO的时序路径,并且需要关注,也可以使用下列命令进行配置,
createBasicPathGroups -expanded
设计里边的组会有下面的加总公式:
all = default + reg2reg + reg2cgate + in2reg + reg2out + in2out
invs也会配置一个合理的默认优先级,具体如下:
reg2reg > reg2cgate > default > [in2out | reg2out | in2reg]
C家这里的默认处理还是很合理的。这个也符合用户的常规需求。
使用BGP模式的时候,在optDesign的过程中,工具会根据系统情形,对 reg2reg、reg2cgate 等组进行逐个优化,基于每个BGP分组,对于所有隶属于High Effort path group的最差的TNS group进行优化: optDesign always work on worst(TNS_grp_1 … TNS_grp_n)'s group
每个组的WNS的EP进行优化的原则是:无论这个EP属于那个clock domain,invs只会去做到这个EP最差的路径优化
这个方式,在multi-clock per FF情形,或者复杂fanin的timing path的情形,是可以得到更好的优化结果,因为在同一时间的优化是绝对专注的,不会有其他的同优先级的path group的path出现。所以,在默认情况下,invs就会得到不差于传统path group分组方式的结果。
C家通过BGP的wrapper,巧妙的处理了复杂数据路径优化种的冲突问题,让工具可以更为专一的进行优化,而不是把精力浪费在了仲裁(arbiter)和path group反复迭代(iteration)上。
usefulSkew + BGP:时序修复的双杀
众所周知,invs里边有很强大的usefulSkew技能,此技能贯穿了auto-place,CTS和auto-route等阶段(PS:这里要注意,usefulSkew只是追加,不能替代原有的三大引擎)。
如果当使用BGP后,每个EP都有了独一的最高优先级的path group,这样invs在调节usefulSkew上的计算量(compute consume)会大幅降低。因为每一个path的skew调节,都需要工具去评估这个path原有的margin才能做出判断,如果一个EP分属于不同的组(但是是同优先级的组),每个组在这个EP的slack形态大概率不一致,工具需要数倍的计算时间和依赖考量(dependency),互相牵制,工具只能选择在那个修复瞬间的最优解,但是,随着path group被不断被轮询修复(repair iteration),上一次的usefule的修复方式,可能已经过时(out-of-date),这样数据就会形成相互牵制(lock),类似一个状态机(SM),但是它无法自收敛,最终随着data path optimization的圈数达到极限(iteration limit),数据的状态就有点中间态的意味,不太会达到一个好的收敛度。
拥有了BGP的usefulSkew,就像插上了翅膀的马达,由于依赖度的大幅度降低,可以专注clock skew的调优工作,这个时候才能把usefulSkew的性能彻底释放出来。
和所有的工具命令一样,BGP也不是完全丝滑,譬如:由于可读性和命令一致性的原因,针对BGP,invs也在report_timing的命令里边做了一些变通处理,这个后续会讲到。
未完待续 (To be continued ) …
【敲黑板划重点】
path group是data path optimization的数据分类基石,理解其中的理论可以有助于优化命令和设计流程。
参考资料
Synopsys Design Compiler® User Guide
Cadence Innovus User Guide