PPA最佳原则: 全称是Performance,Power,Area,即性能,功耗,面积。这个PPA贯穿整个IC设计实现的全过程。
一, import design
1, 检查时钟周期是否符合SPEC
# 如果前端修改了时钟周期,而后端不知道的情况下继续跑优化,出现这种情况那就很浪费时间了,所以最好在完成设计导入之后及时与前端人员确认时钟约束是否正常。
# 频率 = 1 / 周期(period)
命令: report_clocks
2, 检查log中是否有ERROR
3, checkDesign -netlist 会报出哪些信息
1) std cell / macro / io pad / nets 的数量
2) std cell / macro / io pad 的面积
3) instance = std cell + macro
...
# 经验估算core的面积 = std_area / 0.65 + macro_area / 0.82
二, floorplan
floorplan :
innovus -files../scripts/02_create_floorplan.tcl | tee 02_create_floorplan.log
1)指定芯片/模块的尺寸(大小)
2)检查memory摆放的方向是否正确(poly方向需要和标准单元,memory的poly方向一致)
3)把设计中的io port摆放到顶层要求的位置(edit => Pin edit)
4)添加endcap(边界)和tapcell(闩锁效应)
5)添加power switch cell (可选)
验证tapcell vios
verifyWellTap \
-cell TAPCELLBWP40P140 \
-rule 30 \
-wellCutCell {BOUNDARY_LEFTBWP40P140 BOUNDARY_RIGHTBWP40P140} \
-report WellTapCheck.rpt
如何评价数字后端设计中floorplan的好坏?
从此没有难做的floorplan(数字后端设计实现floorplan篇)
三, powerplan
1)打上高层的M8和M9 Power Stripe
2)sroute铺power rail
3)设置via rule进行power stripe和power rail的打孔,形成power mesh
4)检查powerplan是否存在pg floating
verifyConnectivity -noAntenna -noSoftPGConnect -noUnroutedNet -error 1000000 -net VDD
verifyConnectivity -noAntenna -noSoftPGConnect -noUnroutedNet -error 1000000 -net VSS
5)检查powerplan是否存在short和open
verify_PG_short -no_routing_blkg
6)检查floorplan&powerplan是否有drc violation
verify_drc -limit 10000
- 一个强制供电网络的标准:
IR Drop符合设计spec(静态3-5%,动态14%)
EM满足foundary的signoff要求
供电电阻足够小
Calibre
# 生成.gds2文件
setStreamOutMode -version 688
setStreamOutMode -textSIze 0.1
setStreamOutMode -virtualConnection true
setStreamOutMode -uniquifyCellNamesPrefix true
setStreamOutMode -SEvianames true
streamOut ../data/cortexa7Core.gds2 source-mapFile /data/tech/gdsout_5X2Y2Z_innovus.map -libName DesignLib -units 1000 -mode ALL
在innovus中使用
# innovus中执行
source [file join $::env(CALIBRE_HOME) lib cal_enc.tcl]
# 打开calibre
calibredrv xxx.gds -l /data/tech/drc/forDRV.layerprops
使用add_via_definition定义通孔之后 执行add power stripe系统不再默认向上或者向下打via了
这是因为如果我们用了add_via_definition这个命令之后,在打power stripe的时候需要指定power stripe去打via的金属层。如果没有定义add_via_definition这个命令,innovus默认情况下是会用设计里面所有的金属层去打via的,即你用了M8打垂直方向的power stripe,而那么在打sroute的时候,工具是会识别到power stripe的via约束,他可以向下一直打via连接到M1,也可以向上一直打via连接到最顶层的M10。所以没有定义add_via_definition约束的时候,我们打完power stripe之后,再打power rail,他们之间是会自动连接在一起的。
但是如果我们用了add_via_definition这个命令去定义via的约束之后,power stripe的via通孔默认约束就失效了,他不会自动向上或者向下打via了,所以我们会发现,打了M8之后,他不会自动跟M9连接在一起,打power rail的时候也不会跟M8连接在一起。
这个时候我们需要手动给M9和M8这两个power stripe再添加一个via的约束,告诉他们需要往哪一层去打via。命令如下:
setViaGenMode -optimize_cross_via true
add_via_definition -name via12_usrdefine -via_rule VIAGEN12 -row_col {1 10} -cut_size {0.13 0.05} -bottom_enclosure {0.02 0.02} -top_enclosure {0.02 0.02} -cut_spacing {0.1 0.1}
add_via_definition -name via23_usrdefine -via_rule VIAGEN23 -row_col {1 10} -cut_size {0.13 0.05} -bottom_enclosure {0.02 0.02} -top_enclosure {0.02 0.02} -cut_spacing {0.1 0.1}
add_via_definition -name via34_usrdefine -via_rule VIAGEN34 -row_col {1 10} -cut_size {0.13 0.05} -bottom_enclosure {0.02 0.02} -top_enclosure {0.02 0.02} -cut_spacing {0.1 0.1}
add_via_definition -name via45_usrdefine -via_rule VIAGEN45 -row_col {1 10} -cut_size {0.13 0.05} -bottom_enclosure {0.02 0.02} -top_enclosure {0.02 0.02} -cut_spacing {0.1 0.1}
add_via_definition -name via56_usrdefine -via_rule VIAGEN56 -row_col {1 10} -cut_size {0.13 0.05} -bottom_enclosure {0.02 0.02} -top_enclosure {0.02 0.02} -cut_spacing {0.1 0.1}
add_via_definition -name via67_usrdefine -via_rule VIAGEN67 -row_col {1 10}
add_via_definition -name via78_usrdefine -via_rule VIAGEN78 -row_col {1 10}
add_via_definition -name via89_usrdefine -via_rule VIAGEN89 -row_col {2 5}
setViaGenMode -viarule_preference {via12_usrdefine via23_usrdefine via34_usrdefine via45_usrdefine via56_usrdefine via67_usrdefine via78_usrdefine via89_usrdefine}
setAddStripeMode -stacked_via_top_layer M8 -stacked_via_bottom_layer M1
addStripe -nets {VSS VDD} \
-layer M8 \
-direction vertical \
-width 6 \
-spacing 2 \
-set_to_set_distance 30 \
-start_from left \
-start_offset 1 \
-uda power_stripe_M8
setAddStripeMode -stacked_via_top_layer M9 -stacked_via_bottom_layer M8
addStripe -nets {VSS VDD} \
-layer M9 \
-direction horizontal \
-width 6 \
-spacing 2 \
-set_to_set_distance 30 \
-start_from bottom \
-start_offset 1 \
-uda power_stripe_M9
sroute -connect { corePin } \
-layerChangeRange { M1(1) M8(8) } \
-corePinTarget { none } \
-allowJogging 1 \
-crossoverViaLayerRange { M1(1) M8(8) } \
-nets { VDD VSS } \
-allowLayerChange 1 \
-targetViaLayerRange { M1(1) M8(8) } \
-uda power_rail_M1
在打M8的时候,我们需要先加入setAddStripeMode -stacked_via_top_layer M8 -stacked_via_bottom_layer M1这个命令,告诉工具M8这根power stripe可以向下打via一直连接到M1,也就是后面用sroute打的power rail,在打power rail的时候,就会自动把M8到M1之间的通孔给补齐,并且按照我们上面约束的通孔规则来打,即一行十列的via矩阵。而打M9的时候,需要先加入setAddStripeMode -stacked_via_top_layer M9 -stacked_via_bottom_layer M8这个命令,告诉工具M9这根power stripe需要跟M8 power stripe连接在一起,这样在打M9的时候,工具也会一起添加VIA8这个通孔,把两层金属连接起来。
top级别才需要打power ring, block级别不需要这一步.
四, placement
Placement前
1)检查placement blockage是否正确添加,以及确认blockage的类型
2)整理dont use list
3)设置好dont_touch的cell
4)确保时钟clock已经被设置为 ideal network
5)FIX住所有的Macro和预先想place好的cell
6)检查 pin access。
Placement 基本上的顺序是:
1)首先是做coarse place,所有的std cell都有一个大致的位置,这个时候std cell可能是会有overlap的情况或者或者不在row上面
2)接着做coarse place的setup timing优化,DRV优化等
3)之后做place的合法化放置,也是可以理解为detail place。在此之前std cell都是coarse place,std cell的位置比较随意,彼此之间可能会重合,或者不在row上面,这一步就是将他们摆到row上面去,同时std cell之间不能有重合或者1倍filler cell的间距
4)最后再进行timing的优化
Placement --
1, 环境mode设置
2, 执行place_opt_design
3, 检查setup timing,DRVs是否符合预期,一般reg2reg(这里的reg2reg泛指除了io相关的path,包括reg2reg、reg2cgate、reg2mem等等,因为io相关的path是我们人为设置的input delay和output delay,这些一般我们都是设置60%的时钟周期,属于过约束,在时序上是不准确的,在block阶段是不用关注的)的wns小于100ps,drv基本clean即可继续往下走
4, 检查routing congestion是否满足要求,一般总的overflow需要小于1.5% (overflow)
5, 检查cell的desity是否满足要求,一般要求不要大面积出现超过80%的情况即可
6, 检查max displacememt时候满足要求,一般要求优化过程中该数值小于100um
7, 查看设计的利用率
8, 设计的时钟频率
setup: 每个阶段setup的WNS 控制在100ps左右即可以接着往下跑下面的流程,并非每个阶段的timing都要没有violation。
DRV: 只要不是floorplan的问题或者不是特别大的都可以在pt timing signoff阶段做fixing
整体density尽量不要超过80%,而且局部density不要高于85%。主要是防止绕线detour和hold buffer没地方插
- local congestion 解决方法
#第一种是检查place优化的mode
setPlaceMode -congEffort high
# 设置完后重新跑opt即可
place_opt_design
#第二种是局部区域congestion优化
congRepair -area
#注意: 这个命令可以在做完place_opt_design的基础上做congestion优化。
#由于这个命令会根据congestion结果将它周围的cell均摊开,因此可能会搬动较多的cell。
#所以这个命令不适用于post-cts timing 优化后来使用。
#第三种 Module Padding
setPlaceMode -modulePadding module factor
#这里的factor值需要根据自己的设计和经验来设定,通常取值范围为1.2-2.0。
#举个例子,比如这个值为2,表示工具在做global placement的时候会将这个module里面的每颗cell看做成2颗这样的cell ,
#所以做出来的效果是这个module占用的面积更大,约为原来的两倍,cell之间的space就更大了。
#但需要注意的是,这个命令只在global placement阶段起作用,在后续的refinePlace工具是不follow的。
#第四种 Instance Padding
在数字IC后端实现中经常会把innovus中的几种padding结合起来使用来达到一个最佳的congestion优化效果。
foreach i [dbGet [dbGet -p2 top.insts.cell.name AOI*].name DTMF_INST/RESULTS_CONV_INST/*] {
specifyInstPad $i 2
}
#第五种 Cell Padding
实际项目中经常会碰到某个module中包含大量的AOI,OAI,NAD这种高pin density的cell。
往往这种地方容易有local congestion问题。那解决的方法就是将这类cell设置padding。
这个与ICC/ICC2中的keepout是一样的效果。
只不过S家的单位是具体距离,而C家的单位是多少site。
specifyCellPad cellName 6 (这里的6并非是6um)
#第六种 Density Placement Blockage
对于局部区域的congestion问题,
特别是各种窄channel的地方或拐角的地方,经常需要添加density placement blockage。
这种blockage其实就是传统所说的partial placement blockage
。主要的原理是通过控制该区域的density来解决congestion的问题。
五, CTS 时钟树综合 & CTS_opt
CTS前
● 此时应该做完标准单元的摆放,而且确保标准单元是legal的。
● placement的congestion map和cell density map比较合理
● Timing可以接受
1, 05_cts做完之后不用检查时序,只需要检查clock skew和clock latency是否合理,clock path是否存在兜圈的情况
- 到了06_ctsopt之后,我们才需要检查时序是否满足要求,这个时候有了真实的clock skew,我们就需要开始优化hold时序,跟place阶段的timing评估标准一样,只要reg2reg的setup和hold wns小于100ps,drv基本修复,就可以继续往下走
3, 做完ctsopt之后,大家需要对timing进行检查,需要明白common path和crpr对于timing的影响
单独指定某个clk端latency(tree的做长做短)
set_colock_latency -0.1 FF1/clk
告诉工具这个寄存器的clk端的信号到达时间是-0.1ns.
这里意味着这个寄存器的时钟到达时间比其他寄存器快0.1ns(100ps), 负号表示相对关系!
所以FF1的setup更容易满足了
七, route
三个阶段,分别是global route 、Track Assignment 、Detail route。
Global route:可以预估design的congestion情况,这步会引用Gcell的概念分析track能通过gcell的数量,如果任何一个gcell存在congestion,工具在做global route时就会避开congestion区域来做global route。
Track Assignment:就是将每一个net分配到特定的track上并铺设实际的金属轨迹,轨道尽量长、尽量直且有较少的打孔via。
Detail route:是按照上述的分配进行实际的绕线同时会检查drc的问题。
在Route后,我们已经有了真实的绕线情况,这个时候就不需要考虑congestion map,直接看route之后的drc情况即可。
1, 绕线结束后我们主要关心绕线的DRC即可.
2, 理解天线效应的修复操作.
如何评判route结果的好坏?
(1) short和open的数量控制在两位数以内
(2) 比较少的DRC
(3) 没有多少天线效应
(4) 没有因为长绕线而引起的DRV问题
(5) 没有比较大的timing violation,opt之后能够控制在50ps以内即可