用 Innovus 的工程师,大多数人都知道安装目录下有个 gift 脚本文件夹。但具体里面装了些什么,哪些能用、哪些已经过时了,可能没几个人真的翻过。最近我把安装目录里的脚本从头到尾捋了一遍,有些发现挺有意思的。
先说结论:这批脚本的价值分布很不均匀。有些是日常能用的好工具,有些已经彻底被原生命令替代了,还有一些是特定场景下才会派上用场的"冷兵器"。
这批脚本的官方名称叫 GIFT 脚本集,历史可以追溯到 Encounter 9.1 时代。命名统一带 user 前缀,就是为了不和内置命令冲突。启用方式很简单,一行命令:
innovus> source <install>/share/innovus/gift/scripts/userEnableGiftScripts.tcl
innovus> userEnableGiftScripts
之后 info commands user* 就能看到新加载的 189 个 proc。但全量加载有个问题:这 189 个脚本里,有相当一部分的查询功能已经被现代 Innovus 的 dbGet 和 get_db 完全覆盖了。比如 userFindInsts.tcl、userFindNetsByInst.tcl、userSelectInsts.tcl 这一类,在 Encounter 时代它们是唯一的选择,但现在用 dbGet 一行搞定的事情,没必要绕道去调一个 proc。所以我建议:别一键全部 source,按需挑有用的加载。
那哪些是真正有用的?
排第一的是 blockage 和 halo 操作相关的脚本。userBlockageUtils.tcl 是一套通用的 blockage 创建和转换过程集,userCreateRouteBlkForAllHardMacros.tcl 能一键给所有 hard macro 打 routing blockage,userChangeHalosToZeroDensityScreens.tcl 和 userChangeHardBlockagesToZeroDensityScreens.tcl 能把 halo 和硬 blockage 转成 0% density screen。这些操作在原生命令里没有直接等价物,或者需要好几步才能实现,GIFT 脚本把它封装成了一个 proc 调用。
层次化设计相关的脚本也很实在。userAutoPartition.tcl 能按规模和连通性自动识别 partition 候选,对于早期做 partition 划分评估很有帮助。userGenRunScriptForPtn.tcl 可以为所有 partition 一键生成并行 P&R 的运行脚本,省去手写重复脚本的工作量。userAddFeed2Partition.tcl 和 userAddFeedFile2Partition.tcl 处理 feedthrough 插入,在做顶层集成时经常会用到。
还有几个我称之为"冷兵器"的脚本,平时想不到,但遇到特定问题时会很管用。
userShortenScenicRoute.tcl 能重新绕那些被绕远了的时序关键 net,用来改善时序。userDumpTcl.tcl 可以把当前 floorplan 里的选中对象反生成可重现的 Tcl 命令,调试时特别有用——你手动调好了某个模块的位置,跑一把这个脚本,下次就能复现。userCheckPoint.tcl 实现了带标签的 checkpoint 保存和自动重启恢复,跑长流程时万一中途断了,能省很多重跑的时间。userVerifyBump.tcl 做 flip-chip bump 检查,验证 bump 是否落在了电源网上、IO cell 的 pin 是否正确。
报告类的脚本里,userSummary.tcl 值得单独提一下。它会扫描 timingReports 目录,把各轮时序结果汇总到一起,方便你直观地看到时序随着流程推进是怎么变化的。这个在调试流程时很实用。
说完了有用的,也得说说哪些可以跳过。
最大的那类——查找和选择类的脚本,占了将近四分之一。userFindInsts.tcl、userFindNets.tcl、userSelectInstsByNet.tcl 等等。这些在 Encounter 时代是刚需,但现在原生命令已经全覆盖了。举个例子,userSelectInstsByNet 做的事情是选中某个 net 上的所有 inst,用现代命令一行就能搞定:
# LUI 风格
selectNet my_net; selectInst
# CUI 风格
select_obj [get_cells -of [get_nets my_net]]
类似地,userFindAllSequential 找所有时序元件可以用 get_cells -filter "is_sequential==true",userRptHighFanoutNets 可以用 report_net -high_fanout,userGetAllBidirIos 可以用 get_pins -filter "direction==inout"。这些原生命令更快、更标准、文档更全,完全没有绕道 GIFT proc 的必要。
同样,格式转换类的 userdc2rcwireload.tcl、userSEgds2FEgds2Map.tcl 也已经有了更现代的工具替代。userCreateZeroReg.tcl 脚本的 README 自己都标注了"已废弃,用内置 saveTestcase 代替"。
还有一个兼容性问题值得注意。这批脚本是 Encounter 9.1 时代的产物,那时候还没有 Common UI 这回事。我统计了一下:189 个脚本里,84 个用了 dbGet——这是 Legacy UI 的专属 API,Common UI 下对应的命令是 get_db。用了 Common UI 风格 get_db 的脚本,只有 1 个。换句话说,这批脚本骨子里是 Legacy UI 的。
不过好消息是 Innovus 在 Common UI 模式下向后兼容这些老命令,实测全部 189 个脚本能在 CUI 下无报错加载。唯一一个同时提供了 CUI 版本的脚本是 userCutBlockages_CUI.tcl,它和原版 userCutBlockages.tcl 定义相同的 proc,内部实现从 dbGet 换成了 get_db。更有意思的是,如果你全量 source 所有脚本,_CUI 版本因为字母序靠后会自动覆盖原版——也就是说你什么都不用做,拿到的就是 CUI 版本。
那其他 188 个脚本在 CUI 下有没有隐患?短期看没有,长期看官方建议新开发用 CUI 命令。如果你正在从 LUI 往 CUI 迁移,这些脚本可以先用着,等流程稳定了再逐步替换。
除了 GIFT 脚本集,安装目录里还有一套容易被忽略的东西:FoundationFlows。
这是 Cadence AE 搭建的官方参考流程框架,本质是一个流程生成器加配置模板。它的用法是先用 tclsh gen_flow.tcl -m flat all 生成流程脚本,然后用 make 执行。最值得借鉴的是它的 PLUG 机制——每个流程步骤(init、place、cts、route、signoff)都有 pre_ 和 post_ 钩子脚本,你在 innovus_config.tcl 里取消注释就能在对应步骤注入自定义操作。这种钩子式的流程架构设计得很干净,如果你在搭自己的流程,可以参考它的思路。
不过要注意,它的工艺适配能力其实很浅。setup.tcl 里有个 vars(process),设成 "28nm" 或 "7nm" 之类,生成器会根据数值判断要不要跑 post-route wire spreading(>16nm 才跑),剩下的几十处引用基本只是往注释里写个工艺名做标记。真正的库路径、techfile 绑定靠的是 vars(library_sets) 和 vars(<corner>,qx_tech_file) 这些变量。所以不要以为设个 process 就自动适配工艺了,该配的库一个都不能少。
还有一个小工具值得单独推荐:nagelfar。
它是一个 Tcl 静态语法检查器,安装目录里包含了 Innovus 全部命令的语法数据库。你在写完 Tcl 流程脚本之后,跑一把 nagelfar your_script.tcl,能查出命令参数写错、选项拼错之类的低级错误。实测它对 select_obj -name test 这种非法选项能准确报出 E Bad option,对不在语法库里的命令报 W Unknown command。而且它还分 Legacy UI 和 Common UI 两套语法库,nagelfar -common_ui 切换到 CUI 命令集。这种静态检查在流程脚本动辄几千行的项目里,能帮你省去不少 debug 时间。
最后说说 bin 目录下的格式互转工具。oa2def/def2oa、oa2lef/lef2oa、oa2verilog、oa2strm/strm2oa(GDSII)这四对工具是日常使用频率最高的。它们负责在 OA 数据库和其他标准格式之间来回转换,是做数据交接时的主力工具。spefredu 能做 SPEF 约减,spefchecker 能检查 SPEF 文件格式是否正确。这些工具虽然不叫"脚本",但它们就在安装目录的 bin 里,随 Innovus 一起发布,用起来很方便。
回过头来看,Innovus 自带的这批脚本和工具,质量参差不齐,但其中确实藏了一些好东西。我的建议是:别全盘接收,也别全盘否定。blockage 操作、partition 辅助、checkpoint 断点续跑这几个场景值得优先试;查找选择类的直接跳过,用原生命令;FoundationFlows 的 PLUG 钩子架构可以当参考;nagelfar 装进你的 CI 流程里。
你的日常流程里,有没有用到这些自带的脚本?或者你有自己珍藏的好用脚本?欢迎分享。
144