给我们的小兄弟cell们排排位置
在结束了power步骤后,我们进入到了第一个自动化的大步骤了,这里是实现的重要一步。APR里边的AP(auto-place)就是指此步骤,所以说,真正和工具死磕的时候到啦!按照惯例,有图有真相:
如上图所示,为了能让place的结果更有(fei)利(hua)于timing、physical,我们要在真正开始place_opt命令前加入必要的控制、约束手段。通过下文的讲解,你可以看到这些手段的必要性和重要性。
第一步:set ideal clock network:理想化所有的clock
我们timing分析都是基于data和clock的,在import的文章里边,我们说过dc 综合的目标就是只关注于data path,前提是所有的clock都是ideal(理想化的,零延迟,驱动能力无限大)。在place这一步,我们将继续这个事业,但是目标是把cell 都放置到真正的版图上,然后做data path的优化,而不是像DC那样,cell是随意放置的。
为了让place步骤专注于data path的优化,我们一上来先做一遍set ideal clock的指令,确保时钟的理想化。
第二步:apply user timing addons:基于物理位置影响,添加额外的时序约束
在一开始,我们的数据库里边,已经从综合那里拿到了主要的时序约束,包括clock的定义、timing exception (MCP、false_path等等),但是这些可能是不太够的。因为综合的环境相对比较宽松,不用太精细的约束可能也能让timing得到满足,但是在真实的物理世界,cell和cell的实际物理距离会引入data path 的delay显著增大。这时候需可能需要基于place的QoR,加上和前端同事的讨论、确认,才能把时序约束逐步细化。这很有可能是一个帆布迭代的过程。切记,只有正确的约束才能导向正确的方向,在不合适或者过约束的数据库上修timing,都是事倍功半的。
除过std-cell距离问题,在place阶段还有一个重要的信息,就是IO terminal的位置。所有的interface timing都是要经过IO port,按道理,IO timing 不应该很难修,因为通常都会在做partition的时候,综合考量高速、低速时钟的控制范围,block的边界一般都不会是超高速的接口,但是,例外总会发生。需要在综合的时候使用合适(不紧不松)的IO timing constraint,到了这一步,基于place QoR,再做进一步的约束优化,目标是让工具在合理的范围内做最大的优化。
综上所属,以下几点需要我们仔细:
1: 对于所有的IO都应该有约束,
2:仅对于critical的接口实施正常weight的优化,其他的IO可以使用weight来降低它的优先级。
3: 如果timing 特别紧张的部分,可以相应调高weight来增强它的优化街别
第三步:apply physical constraint: 物理的约束
这里我们要添加物理约束来引导place 命令的行为,通过引导,达到让工具做出来的结果朝我们期望的方向发展。例如:对某个区域的cell density过高的处理,限制某个区域std-cell逻辑门的放置等等。具体如下:
1:placement blockage
顾名思义,这类约束是限制std-cell的摆放的,对于不同的需求,会有以下几类不同特点的blockage供用户选择使用
hard blockage: 强制遮挡,被这种blockage覆盖的区域,是不能放置任何std-cell的,只要有cell放在这个区域,工具在legalize的时候,就会强制把cell 挪出来。如下图所示,在place结束的数据库,hard blockage区域是没有std-cell的:
Partial blockage: 部分遮挡,这个命令会部分的遮挡某个区域,防止std-cell进入。用户可以加一个百分比,例如遮挡40%,那么这个区域的目标density大概就是60%,这个目标限定只局限于coarse placement,在优化的时候工具会自动忽略这个约束,所以整个流程就熟后,受限制区域可能会超出给定目标值。
Partial blockage advanced: 部分遮挡的加强版。在单纯部分遮挡的基础上,引入了更多的约束条件:register avoid(禁止register进入)、buffer only(只允许放置buffer/inverer)等属性,来控制工具的行为。
2: routing guide,routing blockage: 绕线引导和遮挡
Routing_guide: 是一种绕线引导物理约束,它可以对指定绕线层、区域进行约束。包括
a: track 利用率
b: pre-route/signal (电源网络布局/普通信号线)绕线的限定
c: prefer/non-prefer (优选绕线方向)绕线的约束 等等
Routing blockage:在某一区域,完全阻挡某一层、某几层的绕线。
之所以我们在这里place阶段提到routing_guide、routing_blockage,是因为place的算法已经加入了global routing的考量,所以这些routing 的约束也会影响place的结果,相应的place的优化结果也会提升、考虑routing的QoR,这个会在routing的步骤体现出来。
3:bound:std-cell的布局的干预
Bounds(绑定)是一个有趣的物理约束,在自动布局阶段,按照通常行为,基于timing -driven工具可以自动放置所有的std-cell,但是有时候,由于某种原因,工具的结果和我们的期望有出入,这个时候使用bounds是可以帮助我们引导工具的放置行为,
Bounds的创建可以基于leaf_cell或者hierarchy cell,由于实际的操作都是基于leaf_cell,所以,准确的用法使基于leaf cell,这样方便检查和回溯。
对应不同的用法,一般有如下三种bound的方式
Hard:指定的cell必须放到指定区域,但是其他cell也是可以进来的
Soft:指定的cell可以放到指定区域或其周边区域,其他cell也是可以进来的
Exclusive: 指定cell必需放置进来,别的cell是不允许进来的
通过使用bound,我们可以让强制让制定leaf cell放到bound的区域内。
Bound的应用需要注意,因为上文我们讲到了macro的摆放会影响工具place的结果,原因就是工具是timing-driven的,这样的一个显性的结果就是同层级的cell会放置的比较近。所以如果我们调整bound,一定也会影响工具的摆放,在使用的时候要注意bound的创建对QoR的影响。
第四步:pre-place setup: place前的最后一招
在使用完工具提供的native命令对数据库进行调整后,有些时候,这些还是不能解决所有问题,尤其是遇到复杂模块的时候。这时候,我们要借助一下脚本来对当前模块做进一步的调整,这个调整的目的就是,减轻工具的运算量,让所有的数据向收敛的方向发展。
1:channel placement: 如下图:
基于图例,我们可以看到整个block有四个地方需要出port,具体对应的数据流为
Port_main -> default_VA -> SW1/SW2
Port_part1 -> default_VA -> SW1/SW2
Port_part2 -> default_VA -> SW1/SW2
Port_part3 -> macro、SW2 and default
对于port_part1 和port_part2,这里的channel_1 和channel_2是非常狭窄的通道,为了保证绕线的通过性,首先,我们应该阻止任何std-cell 的逻辑cell在这里的布局,但是在某些情况下,这些还不够。
使用过自动布局工具的同学应该知道,基于工具优化的方式,再这样狭窄通道,有两个可选区域的时候,经常会出现,反复跨过macro的行为,类似下图:
这种系鞋带是的布局规划,是很不利后期绕线和时序收敛的,使用前述方法也是不太容易约束工具行为的。所以这里我们需要使用脚本来解鞋带。创建guide buffer来认为干预这个区域的布局,结果如下图:
加之使用placement blockage 来限制别的std-cell进入这个区域,这样就可以解掉这个问题了
同样对于port_part3,使用脚本合理添置guide buffer可以有效提高QoR。
2:magnet placement:
工具有一套命令会去做std-cell的与其相关联的逻辑进行就近摆放,例如你已经在floorplan里边摆好了port,我们可以让工具把相关的std-cell摆到port的附近,这样可以有效收敛相关逻辑物理距离。但是对于macro要谨慎使用,由于很多macro会share逻辑,很多时候,并不是把他们聚集在某个区域是个更优的选择。这个工具命令的结果,会把对应的逻辑摆放到目标cell的附近,并且可以legalize和fixed。
3: ESD protect buffer:放置ESD保护器件
在某些工艺下,基于PAD的设计,PAD core的一些输出信号,需要做ESD的保护处理,防止出现ESD violation,这时候就需要我们在pre-place阶段来规划。通常来讲ESD buffer不是工具的target library,所以工具不会在place阶段使用它。为了弥补这个问题,我们需要把ESD buffer放到link library里边,然后使用insert buffer命令来预插入ESD buffer,考虑到timing DRC的要求,这些cell不应该离PAD cell过远。
一般常用的手动就是这样了,在开始place_opt命令前,各位同学备份一下当前节点的数据库,因为你可能需要反复在这个地方进行调试、迭代。
第四步:place:真正的大招来了
一个模块的实现,place这个命令可能会占据整个run time 的30%左右,从一个std-cell处于原始位置的状态,到最后按照用户需求和约束达到布局完成,这里边的动作和计算量会非常的大,一般规模的模块place主命令大概需要20~30小时,甚至50小时以上,这还不包括你的server crash、overload等意外情况。在runtime 这方面,Synopsys家也是很努力的,icc2在这方面是有所提高的。
1:place命令的理解和应用
Place_opt命令的主要动作是:
这三个步骤里边每一步的最后,都有legalize ,言下之意,就是工具的任何的粗布局、优化的结果,都要以最终的legalize来收尾。所以,任何的displacement都会导致工具的修复的偏差。这里建议个问题同学,在你的place log里边查看displacement是一个重要检查手段。
Place_opt 命令里边提供了几个常用选项
-optimize_dft:如果用户提供了scan_def文件,place命令可以调整scan_chain的前后顺序,来优化绕线
-area_recovery:在时序优化的时候,同时也对面积进行优化,结果是会降低cell density,同时timing上会有些许影响
-congestion:这个是优化routing congestion的主要选项,建议打开。
-cts:在place_opt完成cts的步骤,如果你的flow里边有专门的cts步骤来解clock tree,建议不要使用它。
-optimize_icgs:优化clock gating timing,前提是要在数据库里边加载所有cts的配置,如果选择使用专门的cts步骤,建议不开。
-power:优化power 和leakage power,对于leakage power,需要用户提供不同VT类型(via command set_multi_vth_constoraint),供工具选择VT cell。对于通常的power 优化,可以不开这个选项,但是要打开变量 icc_preroute_power_aware_optimization 来让工具优化power。
-spg:当用户使用compile_ultr –spg命令来做综合,同时要使用DDC的格式作为import的输入量,这个时候place_opt命令会自动使用DDC的floorplan信息。如果这里的floorplan被place_opt命令使用,就等价于余毒入了一个initial placement动作。所以place_opt命令里,就会自动跳过initial placement步骤。这个选项是不能和-skip_initial_placement同时使用的。
-skip_initial_placement:跳过最初的initial placement,这个接口是允许用户对placement做初始化的懂多,有些第三方工具提供的initial placement 会使用DEF的方式读入,如果使用第三方工具的输入,这里是需要initial_placement,然后把后边的步骤交给place_opt命令。这里initial placement需要包括,std-cell is_placeed 属性是 true,所有的macro,is_fixed/is_placeed属性是true。Highfanout的net已经被解掉。
-layer_optimization:工具可以自动去看到用户的net search pattern和set_net_search_pattern_delay_estimation_options 来使用layer promotion 的方式来提高timing,
方法如下:
Icc_shell> create_net_search_pattern -net_length_lower_limit 200 -connect_to_port
1
Icc_shell>set_net_search_pattern_delay_estimation_options -pattern1-min_layer_name METAL7 -max_layer_name METAL8
通过以上的定义,place_opt 命令,会把所有长于200um 并且连接到port的net,进行layer promotion,使用的规则是:最底层是metal7,最高层metal8。当你创建create_net_search_pattern,会返回一个ID值,这里的ID是1,所以在第二个命令里的pattern后面跟的是1
2:Place 结果的检查
在之前的几个步骤,我们都没有设计到检查这个步骤,但是从place开始,我们需要对数据库的结果进行排查,只有对place的质量了然于心,才能在后面使用的时候得心应手:
a:timing检查
在place阶段,重要的目的就是修复和优化data path的timing。因为这时候clock tree都是ideal,所以这个时候的setup timing计算,都是基于cell的placement和virtual connection来估算net、cell延迟来估算timing的。总体上将,如果place 阶段的setup timing不能被完全满足,那么后期很难修出来,对于比较差的violation(
a1:timing约束是不是合适:通过查看report_timing的报告来定位。
a2:timing path 上面有没有乒乓绕线:可以使用change_selection [get_timing_path] 的命令 在版图上查看timing path,看看有没有detour的cell placement。一个timing path的图示大概如下图:
a3:其他种种
有时候,我们会碰到一些net上有很大的delay,如上图箭头处所示。在有些情形下工具就是不修,放在那里。这时候我们需要仔细看一下原因。首先你要查看当前group里边的最大的violation(就是通常说的WNS),如果你的net delay不是发生在最差的path上,工具很有可能会拒绝修复,工具是timing driven的机制,但是深入了解后,你会发现是WNS机制,他是从大的violation开始修起,直到修不动,同时也会兼顾DRC cost 的影响。
局部区域density 过高导致修复不利,这时候可能由于legalize导致在high cell density区域发生了large displacement,所以工具不能有效的修复timing。
逻辑深度影响timing,如果发现由于data path过长,导致拍数过多,我们需要考虑ungroup的方法,降低逻辑深度,从而减少data path的时延。
驱动能力导致的问题:默认情况,工具会使用library里边的所有std-cell,但是一般的library都会有各种驱动能力的cell,这时候如果工具使用过多的驱动能力小的cell,可鞥会影响timing,所以,需要人为干预,禁止工具使用过小驱动能力的cell来保证timing。
b:report hierarchy:这个经常用来全局查看placer的摆放结果,
从下图可以看到,同样颜色表示属于同一个逻辑层次,大部分逻辑都是按照hierarchy来摆放的,这样更利于缩短cell和cell之间的物理距离,从而改善timing
c: report cell density:工具提供了cell density的视图,具体如下图示例
这是基于std-cell的density视图,可以直观地感受到,工具在做完place_opt后,整个die区域的cell分布密度情况,对于高密度的区域需要留意,因为任何想放进去的优化cell都可能由于high density导致large displacement,这样是无法达到最佳优化效果的。
整个place是所有APR工具的核心命令之一,一个placer工具的一般需要3~4年的开发时间,其中的奥妙自然是很深的。对于工程师而言,一定要了解工具的特性和倾向性,这样才能成为工具的朋友。说到底,工具是为我们的工作服务的,工程师存在的价值就是让工具能发挥出自身的特点,高效的实现我们的APR目标。
我们用了以上的篇幅讨论了place步骤和特点,相信你的工作中一定会遇到各种各样的实际问题,如果上述经验能够对你的工作起到些许帮助,作者就深感欣慰了。希望通过上边的讲解,我们都能对工具有一个更深的认识和了解,从而助力我们的日常的布局工作。
Data path的优化,到这里就告一段落了,下一讲开始,clock就要入场了,敬请期待下面的讲解:CTS。
轻触添加“艾思后端设计“微信群
猛戳关注我们的公众号
领取专属 10元无门槛券
私享最新 技术干货