
简介Cadence ICC User Guideiccug是官方发布的集成电路验证覆盖率工具使用指南对应Product Version 15.12015年6月出版主要面向使用ncsim进行HDL仿真与覆盖率分析的芯片验证工程师。文档系统讲解icc的安装配置、覆盖率模型与指标、收集流程、结果分析、报告合并比较、脚本自动化及许可证管理并针对大规模设计给出问题排查与性能优化建议。资源为单个PDF文件压缩包约14.09MB适合有一定仿真基础、希望提升验证完备性的数字IC设计与验证人员阅读。已有293人学习下载可作为日常查阅的工具手册。1. ICC User Guideiccug到底在讲什么第一次拿到 ICC User Guide 这份手册圈内习惯简称 iccug的人十有八九是抱着「翻一翻、跑个流程」的心态开始的。结果翻开目录就被 floorplan、placement、CTS、routing 一堆词砸晕真正上手跑第一版布局布线时连 target density 该填 0.7 还是 0.85 都要犹豫半天。我见过 A 同学在全局布线阶段发现 cell density 只有 70%congestion 却爆红一片拆开 ICC 的报告才发现是电源网络占位和 blockage 没提前处理——这类问题手册里都有写但你不知道去哪一章找。ICC 是数字后端物理实现工具负责把综合后的门级网表一步步变成带物理信息的版图数据最后交给验证和签核。iccug 这份用户手册解决的问题就是让你搞清楚 ICC 在 APR 流程里到底接管哪一段、输入输出是什么、每一步命令背后的物理约束怎么设。适合数字后端工程师、芯片设计团队里刚接触物理实现的同学以及所有想知道「综合之后芯片是怎么摆出来的」的人。它不是一句「运行 place_opt 就行」能带过的活儿参数设错一步后面全是返工。2. 跑 ICC 之前库文件、网表与约束的准备2.1 先搞清 ICC 在 APR 流程里接管哪一段逻辑综合做完你手里有综合后的门级网表通常是 .v 或 .vg 格式里面全是门级单元和它们之间的连线但没有物理位置也没有时钟树更没有电源网络。ICC 干的活就是从这张逻辑网表出发经过 floorplan、placement、时钟树综合、布线、布线后优化最终输出带物理信息的网表和版图文件。常见做法是把它放在综合和后端签核之间前端综合给网表和约束ICC 吃进去做物理实现输出给 DRC/LVS 和时序签核工具。很多新手容易搞混的一点是ICC 不负责逻辑综合也不负责最终签核它只负责中间的物理实现。你在综合阶段用到的时序约束ICC 会重新读一遍但约束写法必须符合 ICC 的语法子集否则流到 physical optimization 阶段时常常静默丢失。我一般会先跑一个空的 ICC 交互式会话把库、网表、约束全部 load 进去跑check_design确认没有缺库、缺 pin、约束冲突再开始跑正式流程。这个习惯帮我挡掉了后面一半的暗坑。2.2 技术文件与物理库从 LEF/GDS 到 ICC 的库格式ICC 读的不是你综合时用的 Liberty 时序库就能直接跑的它需要物理信息。现代 ICC 版本里你至少需要三样东西标准单元的物理库LEF 或 GDS 提取出的抽象技术文件.tf描述工艺的 layer、via、track、site 等信息时序库.db 或 .lib以及对应的 Milkyway 或 NDM 库如果工艺厂给你的是 LEF 和 GDS就不能直接 create_mw_lib。常见做法是先用 Milkyway 或 NDM 的数据准备流程把 LEF/GDS 转换成 ICC 能识别的物理库格式。NDM 是较新的库格式加载更快而且能在库内部同时带上时序和物理信息省去你在多个库之间同步的麻烦。下面是转换成 NDM 库常见的初始化脚本片段set TECH_FILE xxx_1p9m.tf set LEF_FILES [list stdcells.lef io.lef macro.lef] set LIB_FILES [list stdcells_tt.db stdcells_ff.db stdcells_ss.db] create_ndm -lib_name my_lib_ndm \ -tech_file $TECH_FILE \ -lef_files $LEF_FILES \ -lib_files $LIB_FILES { set_tracks -layer M1 -track_width 0.08 -track_pitch 0.14 set_layout -site core_site }这段脚本的作用是创建一份带物理信息的 NDM 库。-lib_files指定多角度的时序库ICC 在做时序优化时会自动按 setup/hold 最差情况取约束set_tracks设置布线轨道的宽度和间距track 设置错了后面 routing 阶段会出大量 short 和 spacing violationset_layout -site指定标准单元的 sitesite 不匹配会导致 place 阶段报 site 冲突单元根本摆不进去。转换完成后在 ICC 里用load_ndm my_lib_ndm加载即可。这一步卡住的人很多最常见的原因是 LEF 里 macro 的 size 和 GDS 对不上或者 tech file 里 layer 名和 LEF 不一致。排查时先看转换 log 里有没有WARNING: layer M2 not found之类的字样这类 warning 别忽略它会直接导致后续布线层用错。2.3 加载网表与 SDC时序约束必须和综合阶段对齐库准备好之后就是读网表和约束。这里有个很容易翻车的点很多人直接从综合工具目录 copy 一份 SDC 过来路径名没改、clock 定义没对齐结果 ICC 里跑完 place_opt 才发现 clock latency 和理想时钟差了十万八千里。set target_library stdcells_tt.db set link_library * stdcells_tt.db read_verilog post_synth.v link_design read_sdc top.sdc set_clock_uncertainty 0.1 [get_clocks clk] set_clock_transition 0.05 [get_clocks clk] check_timing这里的read_verilog读入综合后的网表link_design把网表和库单元绑定起来。read_sdc之后我建议马上加check_timing它会列出 missing clock、unconstrained port 这类问题。你可能看到一大串 warning比如Clock clk has no latency这不是致命错误但你要意识到 ICC 在 CTS 之前用的是理想时钟模型latency 为 0 是正常的CTS 之后才会长出真实的时钟树延迟。要注意的是SDC 里如果写了set_clock_latency或者set_clock_uncertaintyICC 在做 CTS 之前会把它们当作理想的 skew 预算来处理。你设的 uncertainty 越大CTS 越保守时钟树越长。一般我习惯在综合阶段就定好 uncertainty 的预算ICC 里保持一致不要到物理实现再临时改大否则修 setup 要付出的面积和功耗代价很高。3. ICC 核心流程从 floorplan 到 routed 的完整跑法3.1 floorplan面积、IO 和电源网络的初始设计floorplan 是整个物理实现里最影响命运的环节。它定的是芯片多大、IO 放哪、宏单元摆在哪、电源网络怎么铺。ICC 提供create_floorplan命令你可以手动设定 core 的宽高也可以让它按利用率自动生成。create_floorplan -control_type aspect_ratio \ -core_aspect_ratio 1.2 \ -core_density 0.7 \ -left_io 10 -bottom_io 10 -right_io 10 -top_io 10core_aspect_ratio 1.2表示 core 高度是宽度的 1.2 倍一般从封装和 IO 布局倒退出来core_density 0.7是初始利用率注意它只是把标准单元和宏的面积加总除以 core 面积实际可用率还要扣掉 blockage、电源网络占用的轨道所以 0.7 的密度跑出来实际拥塞往往在 0.75 以上。floorplan 阶段的重头戏是电源网络。常见做法是先建 power ring再拉 power stripe最后给 macro 加 power rail。这一步我强烈建议你用 GUI 看一遍电源网络的走向确保每个 macro 的 VDD/VSS pin 都能被 stripe 覆盖到否则后面 IR-drop 分析一定会出问题。3.2 placement 与优化place_opt 到底在优化什么floorplan 定好接下来就是摆标准单元。ICC 里的place_opt不只是摆单元它同时做时序优化、面积优化和拥塞优化。跑之前可以设置 density 和 congestion 的约束让 place 阶段就别把单元堆到 IO 或者 macro 边上。set_placement_options -congestion_effort auto \ -spacing_effort global \ -target_density 0.7 place_opttarget_density如果你是第一次跑我建议先按 0.6~0.7 来留出余量给后续 CTS 和布线。这个参数不是越高越好0.85 以上的 density 在 28nm 以下工艺里很容易造成局部拥塞布线阶段修都修不回来。congestion_effort auto让 ICC 在 place 阶段就预估全局拥塞看到热点会自动把单元往外挪。跑完 place_opt 之后你先别急着下一步。先看两个报告report_placement看 density 和 macro 分布report_congestion看热点区域。如果热点出现在 macro 密集区说明 floorplan 里 macro 间距留小了如果热点分散在整片 core说明密度设太高。这一步返工成本最低后头 CTS 阶段再发现拥塞代价就是几个小时的迭代。3.3 CTS时钟树综合的三个关键约束时钟树是 ICC 里最吃经验的部分。clock_opt之前你需要先检查 SDC 里的时钟定义、set_clock_uncertainty、set_clock_transition 是否合理还要确认是否定义了时钟树例外clock tree exception比如门控时钟、分频时钟。set_clock_tree_options -max_fanout 32 \ -max_transition 0.15 \ -max_capacitance 0.2 \ -target_skew 0.08 clock_opttarget_skew 0.08表示时钟树综合希望把 skew 控制在 80ps 以内。这里很多人会设一个非常小的目标比如 0.01结果 CTS 插了大量 buffer时钟偏斜是压下来了但功耗和面积爆炸还会给 hold 修复添麻烦。一般 0.05~0.1ns 在大多数工艺下是合理区间具体看时钟频率和工艺库的 buffer 延迟。clock_opt跑完要立刻看report_clock_tree检查 clock tree level 数、skew、transition、max_fanout 是否满足设定。如果某一条时钟路径 transition 超标常见原因是这条 path 上驱动的负载比预想大或者时钟树例外没设对。此时可以对该时钟单独加set_clock_tree_options -clock clk_max1 -max_transition 0.1重新跑。3.4 routing 与 finishroute_opt 和它的后处理CTS 做完就是布线。route_opt是 ICC 里最重的命令之一它做全局布线、详细布线和布线后优化。跑之前先确认天线效应规则antenna rule已经设置否则布线后 DRC 会报出大量 antenna violation。set_route_options -antenna_diode_insertion on \ -antenna_diode_cell DIODE route_opt report_route_quality report_drcantenna_diode_insertion on让 ICC 在布线阶段自动插入天线二极管。report_route_quality会给出 short、open、DRC violation 的汇总report_drc看具体坐标和层。布线之后通常还要跑 post-route optimization 修时序和 DRV常见命令是route_opt -effort high -only_eco它对已有的布线做局部修改不改变整体拓扑。这里有个我早期翻过车的地方route_opt默认的 optimizable effort 不够高第一次跑完可能还有几百个 DRC violation 留在那。不要急着手动修先看报告里 violation 集中在哪一层、哪片区域。如果是同一片区域密集出现 short往往说明局部拥塞手动改没用得回 place 阶段调 density如果是零散几个 short可以直接上route_opt -effort high -only_eco让它自己收。4. ICC 三个必调参数target density、congestion 与 padding4.1 target density往高调还是往低调target density 控制的是标准单元在 core 区域的占用率它是 ICC 里最直观也最容易误导人的参数。新手一看 density 0.6 觉得浪费面积直接调到 0.85结果 place 阶段倒是过了routing 阶段 congested 一片cell 挤在某个区域绕线资源完全不够用。我的经验是0.7 是一个比较稳的起点面积紧张的设计压到 0.75~0.78 要格外留神拥塞面积宽裕的设计跑到 0.65 反而省心。判断依据不是 density 数字本身而是 place_opt 之后report_congestion输出的 total overflow。overflow 为 0 时 density 还有上调空间overflow 超过 0.5% 就该考虑降 density 或加 spacing。4.2 congestion读懂 ICC 的 congestion reportICC 的 congestion 报告分 global routing congestion 和 detail routing congestion 两种前者在 place 阶段就能看后者要到 route 阶段。我在第三章提到过report_congestion看热点但你可能没注意到它还能分行分格点看 GRCglobal routing cell级别的拥塞。report_congestion -overflow_total -max_overflow 40 -gr_based这个命令会按 GRC 粒度输出溢出值-max_overflow 40只看 overflow 超过 40 的重灾区。如果重灾区集中在边界或 macro 周围可以用set_congestion_options -max_util 0.95 -x 坐标 -y 坐标约束某个矩形区域的最大利用率。还有一种常见做法是给重灾区加 soft blockage只挡住标准单元不让往里挤但留出布线通道。注意 soft blockage 不是万能的加多了会造成新的热点属于拆东墙补西墙。4.3 placement padding给布线预留的隐形空间padding 简单说就是在单元之间加空隙降低局部密度给布线留通道。ICC 里常用set_placement_options -placement_padding或者对特定单元加 padding比如set_placement_options -placement_padding {std_cell 0.05}这句的意思是对所有标准单元在水平方向上加 5% 的空隙。我一般在 floorplan 阶段就全局加 3%~5% 的 padding给布线留一点缓冲。但要注意 padding 是全局生效的会在所有区域都摊开单元面积利用率会小幅上升。如果设计面积已经卡得很死就不要加全局 padding改用set_cell_padding只对特定单元加比如对多 pin 的 AOI 或 complex gate 加 padding防止它的 pin 太密导致周边绕线困难。padding 设完之后place 阶段的实际密度会比 target_density 略高因为 padding 占走了面积。也就是说density 0.7 加 5% padding 之后实际有效密度大约在 0.73 左右跑 layout 的时候心里要有个数。5. ICC 使用五条避坑记录从报错到反复 iteration 的经验5.1 现象place_opt 之后 congestion 全红但 density 明明不高这个坑我踩过一次最狠的。density 只有 0.65congestion map 却红了一半。查了半天才发现是 floorplan 阶段给 macro 留的间距不够macro 之间只剩两条 M2 通道标准单元挤在 macro 周围绕不出去。原因macro 周围成为布线瓶颈标准单元 pin 到 macro pin 的连线全部挤在狭长区域。解决回 floorplan 阶段给 macro 加 halo一般用set_keepout_margin -type soft_keepout -outer {2 2 2 2}在 macro 周边留出至少 2 倍 track 的隔离带。加了之后 congestion 很快降下来。5.2 现象CTS 之后 hold violation 暴增clock_opt 跑完report_timing 一看hold violation 从 0 变成几百条。最初以为是 CTS 把 clock path 做短了查了 clock tree report 才发现有一个 gated clock 的子时钟没有设 clock tree exception导致 ICC 把它当独立时钟源时钟树的 latency 比预期短很多。原因门控时钟或分频时钟没在 CTS 前声明set_clock_tree_exceptions -clock ...时钟树综合没有把它并入主时钟树。解决在 clock_opt 之前把 gated clock 和分频时钟的 stop pin 指清楚并检查report_clock_timing里的各时钟 latency 是否在合理范围。5.3 现象route_opt 完成后 short 集中在同一层route 完 report_drc发现所有 short 都集中在某个金属层比如 M4。这种情况通常不是布线能力问题而是该层 track 设置在 NDM 库转换时写错了或者电源 stripe 占用了该层大量轨道。原因技术文件里该 layer 的 track pitch 和实际 LEF 不符或电源网络规划时 stripe 占满某层。解决先回 create_ndm 阶段核对set_tracks参数如果是电源 stripe 占道检查create_power_strap的 layer 设置把 stripe 挪到其它层或者加宽间距。5.4 现象cell density 很低但细节布线无法收敛有一次某模块只有 0.6 的 densityroute 却怎么也收不了尾总剩几十个 short 修不掉。把版图放大一看某块区域被大片 hard blockage 围死标准单元只能往一个窄缝里塞缝里的轨道数量根本不够走线。原因hard blockage 布局失误把标准单元的可布置区域切碎了。解决检查report_blockage列表把不必要的 hard blockage 改成 soft blockage或者重新调整 macro 摆放位置。这个教训让我之后每次 floorplan 完都先看一眼 「white space 是否连续」。5.5 现象同一套脚本换一批库就报 command not found工具换了版本或者库换了格式脚本里某个命令突然报invalid command。比如旧版本支持的create_mw_lib新版本迁移到 NDM 后就要用create_ndm还有set_clock_tree_reference这种老命令在新版本里被合并进了set_clock_tree_options。原因ICC 命令在不同版本间有废弃和合并照着老手册抄脚本必然踩。解决以手上版本的 Command Reference 为准启动 ICC 后用man 命令名查当前版本的语法别迷信网上的老脚本。6. 验证 ICC 结果三步确认布局布线真的收尾了6.1 时序报告别只看 worst path要看修复空间跑完 route_opt 之后我习惯出一份完整的时序报告包含 setup、hold、DRV 三类。report_qor和report_timing -delay_type max/min -nworst 100各来一份。重点不是看那一条 worst path 过了没有而是看最差路径的 slack 分布如果所有路径 slack 都在 0 附近徘徊说明设计余量很小任何电压波动都可能翻车如果还有个别路径 slack 是负的先确认是不是 false path 没设好。6.2 DRC 与 antenna 的验收清单report_drc的 summary 能看 short、open、spacing 和 antenna 的数量。我的验收习惯是 short 和 open 必须为 0spacing violation 在 28nm 以下工艺可以允许个位数但要逐个确认不是系统性偏差。antenna violation 如果还有零散几条可以用insert_diode手动补如果数量多说明 antenna diode 单元没用全或天线规则设置太紧。6.3 功耗和 IR-drop 的初筛ICC 里可以跑report_switching_activity和report_power看动态功耗分布。IR-drop 分析虽然通常是 IR/EM 工具做但 ICC 也能做初步的 rail analysis确认电源网络的压降在可接受范围。这一步我一般只看极端情况某块区域 IR-drop 超过 5%那不管时序过没过都要回头检查电源 stripe 密度。做完这三步才算真正可以签核。我自己的习惯是把每版 ICC 的 density、congestion、DRC、时序报告归档成固定文件名出了任何问题回溯到是哪一版改了什么就一目了然。这个习惯帮我省了无数回头查「上次到底怎么跑出来的」的时间。最后说一句ICC 没有一劳永逸的参数组合每一版工艺、每一个 floorplan 都要重新试你要做的是把避坑经验沉淀成自己的检查清单希望帮到你。本文还有配套的精品资源点击获取