通过前面00-02脚本的学习,我们已经初步掌握了如何去floorplan,但实际应用中的floorplan远不止这么简单。还需继续学习。。。。。今天看了研三师兄的毕业答辩,突然觉得压力挺大的,师兄们都太优秀了,奋力直追吧。下面继续介绍03脚本,Powerplan,这一部分会对每一条Tcl脚本进行解析并在innovus里面直观的展示出来。
Powerplan:指电源网络规划,它的目的是确保设计中所有cell和device器件都能获取到电,而且需要确保供电充足。
一共有11个步骤,依次详细的说明
(1)work下启动innovus。
找到work文件,cd(进入)work下启动innovus。(work文件是一个统称而已)
(2)restoreDesign之前的一些配置。
这些在之前的文章都已经讲过,此处不再赘述,不清楚可以查看笔者的专栏《数字IC后端小白学习日志》
(3)restoreDesign。
注意此处restore的是02脚本之后的design,已经做过floorplan的design。
restoreDesign的文件:
restoreDesign之后的GUI界面:
(4)在做powerplan之前
在做powerplan之前,先删掉所有的power routing。
好处:可以不去care是否存在power的绕线,直接delete。使用editDelete命令。
-use {POWER} 表示删除power
editDelete -help查看
(5)calculate macro region
calculate macro region,我们要算出macro所占据的区域
为什么要算macro的区域:因为我们需要打两种类型的power:一种是std cell区域的,一直是macro区域的。因为我们打std cell的power的时候需要把hard macro区域给拿掉,所以我们需要calculate macro region。
那么我们如何calculate macro region呢?
首先我们把macro_region定义为空的变量:
那么如何理解foreach里面的内容呢?大家一步一步来,首先我们先得到所有macro的name。
然后我们对每个macro做foreach处理:
然后使用花括号{}表示对每一个macro要做的处理。下面我们以任意一个macro为例,来看对他做了哪些操作,明白之后就会理解foreach的操作了:
先任意选择一个macro,然后我们先得到它的name。
然后我们把该macro的name去set给macro
下一步就很关键了,get该macro所占的区域
如何理解这段脚本。18条命令,我们get到name是$macro的insts。然后19条命令,我们get到name是$macro的insts的route halo的区域。这里的四个{}分别表示该macro的routingHalo的四个点的坐标。而
仅仅是把这个值给macro_box,让每一个macro的macro_box(区域)做“或”的运算,那么最后得到的就是四个macro的macro_box的组合(或起来的结果),也就是macro_region。
当我们运行以上脚本后,它的输出是
也就是四个macro的区域。
(6)create power rails
首先:什么是power rails:连接std cell的power。
-------------------------------------------------------------------------------------------------------------------------
此处对power rails做一些补充:
power rails也就是我们所说的Follow pin:电源轨道。有了这个Power rail后标准单元只要摆放到Row上,这样std cell的PGpin就可以和这个power rail完全贴在一起。看图去理解。
--------------------------------------------------------------------------------------------------------------------------
那么图中哪些是std cell呢,我们先取消勾选std cell:
然后再勾选std cell,那么多出来的部分是不是就是std cell了呢?
先带大家观赏以下运行以上脚本后的效果,再带大家深入解析这些脚本吧。
来一个局部的对比:
加power rails之前:
加power rails之后:
欣赏完了吗?欣赏完了开始干活吧,来解析该脚本。
要setAddStripeMode。首先要reset一下。可以理解为重置为默认mode,然后我们要指定最底层和最顶层要用via连接的是哪些层,此处我们只create Metal1最底层的rails,所以top_layer和bottom_layer都是Metal1。
然后后面的两部分是几乎一样的,只不过一个是对VDD,一个是对VSS。我们以VDD为例
-nets 指定是VDD
-layer 指定使用的层,此处是Metal1
-direction 指定方向,此处为horizontal
-width 一般来说是std cell的VDD的width是多少就设为多少,下图所示是0.12,所以我们也设为0.12
-spacing 这里需要设置为ROW的宽度1.71
-set_to_set_distance:指每一组VDD/VSS之间的距离,因为此处每两个VSS/VDD之间隔了两个Row的高度,所以每组之间的距离为两倍的Row的高度,1.71x2=3.42
-start 这组rail是从下往上打,那么第一个power应该打在什么地方?应该打在第一个std cell出现在的row的地方。这里offset是从die开始算的,所以此处为1.71,即一个row的高度。且此处第一个为VDD,所以-start 1.71
如果是VSS,则应该指定为两倍Row的高度,即3.42
-stop 即从start开始一直打到哪个地方停止。此处需要die的位置(坐标)
到此处,出现了一些common info需要的信息:我们设为(7),暂时跳到(7)然后再来看(6)
stop的地方是$die_y1,能理解了吧。
-area $die_area 先定义整个area的区域,此处即整个die的区域,然后再指定blockage area去减掉部分区域
-area_blockage $macro_region(就是告诉工具在当前指定的blockage里面不要打Metal1的rail)。所以现在你应该明白了为什么要有(5)calculate macro region和(7)common info了吧,都是为了得到std cell的区域,正如开头我们提到的,我们要打两种类型的power,一种是std cell的,一种是hard macro的。到此为止,我们已经得到了std cell的区域,并且通过addStripe打上了VDD和VSS的power rails。
此处还有一个细节需要我们注意,通过图的方式直观的显示出来:
使用以下命令之前
使用命令之后
需要注意的是此时start开始的位置并不是我们理想情况的位置,理想情况是如下所示,所以start应该改为
-start [expr 1.71 - 0.120 / 2.0]
运行后得到结果为
然后以VDD为例,加入VSS:
运行结果前
运行结果后:
(7)common info
先运行看结果
这样就获取了Die Box的高度和宽度。
(8)给memory打power ring
打完power rails之后,我们来给memory打power ring
首先和打power rails一样
setAddRingMode进行reset,然后此处-stacked_via_top_layer 为Metal9
deselectAll是因为我们马上要select,所以select之前先deselect。
一步一步解析:
这一步相信大家是不是觉得较为熟悉了,之前已经用过几次。
我们所加的只不过是对这些进行select,用命令selectInst而已:
使用后发现四个macro都被选中了,且注意右下角:sel 4。
然后有:
这是设置添加环路的模式,指定贯通(stacked)过的底层和顶层。指定贯通过孔的底层为 Metal1,贯通过孔的顶层为 Metal9。其作用是确保在不同金属层之间有贯通的过孔连接,以实现稳定的电源和地连接。
然后需要进行解析的部分是:
这部分是重难点,需要深入理解
-nets {VDD VSS} 指定环路的网络为电源(VDD)和地(VSS)
-type block_ring 指定环路的类型为block_ring,即围绕模块的环路。
-around selected 告诉工具对选择的部分addRing,也就是环绕先前选中的实例(存储器单元)创建环路。这也是为什么我们要先通过dbGet去Get到四个macro,然后selectInst去select它们
-layer 指定环路所在的金属层,有四条边,那么就要告诉工具该ring的上下左右分别用的哪些层
-width 用ruler量width
上下左右都是5,所以
效果图:
-spacing 同样需要上下左右分别指定,都设为1.25。效果图:
-offset 指从边沿(macro里面的power ring)算起,会扩多大的距离,此处都设为5
效果图:
可能存在的问题:
为memory打power ring的时候使用了Metal8,可能会占用较多的绕线资源:
如下图:从Metal1-via1-Metal2-via2-。。。。。-via7-Metal8
(9)power stripes
power stripes就是把所有的std cell区域通过较粗的power金属覆盖上,保证所有的std cell区域的电流都足够强壮
因为对power ring来说,Top和Bottom是Metal9,Left和Right是Metal8。所以power stripes应该是纵向为Metal8,横向为Metal9。
首先也应该对setAddStripeMode设置为reset
然后
告诉工具在做power stripes的时候需要在哪些地方停下来。此处就是告诉工具遇到block_ring的时候停下来,同power ring,告诉工具顶层和底层设为Metal多少。
上面同power ring一样,只不过一个是addRing,一个是addStripe
从底部开始打power stripes,开始的offset是从end cap的边沿开始算的
对于vertical的,同理,左边开始打power stripes,从离end cap35的地方开始打
此处的offset是指能打到的末端开始算起的offset
打power stripes之前
打power stripes之后
再打纵向的
(10)Save Design
以上就是powerplan的全部,然后保存设计
(11)保存之后进行Check
把verify_drc的结果放在指定目录下,给一个error数量的限制 -limit 99999。并检查power的连接是否都连接好了。
发现出现了问题:
问题的原因:
取消勾选Wire
发现不希望wire超出,但是实际上wire超出了
解决办法:给macro加Metal1的Routing blockage。
即重新规划一个routing blockage,使他扩展到boundary
所以需要create routing blockage
思路:
原来扩展的halo扩展的长度为2,我们需要把他扩展到site的位置上
选择任意一个macro,以此为例:
得到该macro的name 和 macro_box
因为我们要使左右边压在site的整数倍,上下边压在Row高度的整数倍,所以需要计算上下左右分别加多少
20.15-2 然后除以site_width(0.20)发现除不尽,用floor置为整数
除掉site_width后得到一个整数,再用整数乘site_width,则距离就得到为site_width的整数倍了,即
因为是向左扩,所以20.15-2 然后除以site_width后数要变小,90.25--90
而向右边扩展则要变大,即:
例如计算为90.25的时候要变为91;
上下边扩展同理
只不过site_width变成了ROW的高度1.71
重新规划routing blockage如下:
再次检查:
没有错误。
总结:
做完上述流程,我们发现Powerplan的主线其实很简单:
打power rails---->打power ring---->打power stripes---->check。
当然也可能是此project过于简单,后续有其他发现也会及时进行完善。