第一次把IC Compiler II下面直接叫ICC2装好拿到新工艺PDK兴冲冲打开icc2_shell准备跑第一个block结果发现事情没想象中那么简单老ICC里靠create_mw_lib建立物理库那套流程在ICC2里已经被create_workspace取代了。很多从旧流程迁移过来的工程师第一反应是去读design或者直接找create_block结果卡在workspace这个概念上好几天连一个空的block都建不起来。这篇文章写给准备上手ICC2或者已经被workspace绕晕的工程师。我会从create_workspace这条命令入手讲清楚它为什么存在、每个参数背后到底在干什么、实际项目里怎么搭一套不出错的创建序列以及我在多个项目里踩过的那些坑。内容偏流程和运维视角不是help文档的复读读完你至少能自己拼出一个能跑的workspace创建脚本。1. 先搞清楚create_workspace 在 ICC2 里到底扮演什么角色1.1 workspace 本质上是“装载设计环境的内存容器”很多刚接触ICC2的人会把create_workspace理解成“打开一个设计文件”这个理解不准确。workspace更像是一个带齐图纸、工具和分工表的会议室每个block对应一个workspace里面放着这个block的MMMC配置、加载好的参考库、当前打开的floorplan、各种option状态。create_workspace干的事情是把这一整套分析环境装载到内存里而不是单纯读一个.ndm或者.db文件。打个比方你用文本编辑器打开一个文件你还需要一套语法高亮、编译器路径、工程配置ICC2也一样它在分析你的网表和版图之前必须先知道工艺信息、库信息、corner信息。这些信息不提前装载好后面的place_opt、route_opt根本没有办法跑。所以ICC2把“装载环境”这一步单独做成了命令也就是create_workspace。1.2 为什么ICC2要把workspace单独拎出来而不是像老ICC那样全局一套库老ICC时代design和库的关系是“全局绑定”你打开工具库就在那儿全芯片只有一个上下文。ICC2要支撑多block并行、多corner分析、分布式跑法这种全局模型不够用。每个block可能需要不同的库版本、不同的约束、不同的scenario如果放在同一个全局上下文里并行跑两个block很容易互相污染。workspace机制就是为了隔离。每个workspace有独立的library resolution、独立的MMMC上下文、独立的option状态。好处很明显并行跑几十个block互不干扰坏处也很明显很多人不理解“为什么我只是想看一眼版图还要先create_workspace”。实际上你哪怕只是打开一个已经存在的设计也得先有一个workspace去承载它——这正是create_workspace存在的价值。1.3 create_workspace 和 create_block 不是一回事别搞混这是新手最容易搞混的地方。create_workspace管的是环境create_block管的是设计对象本身。实际工程里最常见的标准动作是create_workspace -name blockA -block_reference_libraries $ref_libs -tech_file $tech_file create_block -name blockA -tech_file $tech_file current_block blockA先用create_workspace搭好环境再用create_block创建一个空白block或者用open_block/读入方式加载已有block。有些版本的ICC2里create_workspace带-block参数可以直接打开已有数据这时候就不需要再显式create_block。但不管哪种方式你的第一步永远是先把workspace立起来。2. create_workspace 参数全拆解每个选项背后的实际用途2.1 库类型分组为什么ICC2把库拆得那么细create_workspace有一组看起来让人头大的库参数实际用熟了之后会发现这个拆分是合理的。我常用的版本核心选项大致长这样create_workspace -name workspace名称 -block_reference_libraries block参考物理库.ndm/.db -tech_file 工艺文件.tf -link_libraries 逻辑链接库.db -timing_libraries 时序分析库 -physical_libraries 物理分析库 -si_libraries 信号完整性分析库 -post_route_drc_libraries 布线后DRC库 -delay_corner 延迟corner -operating_condition 工作条件 -mode 约束模式 -scenario scenario列表 -block 指定已有block名称不同版本选项名称可能略有差异有的写成-timing有的写成-timing_libraries用之前先敲help create_workspace确认一下这个习惯能帮你省不少事。为什么要分这么细因为ICC2在做综合、floorplan、布线、signoff时对库的需求完全不同。提前按用途把库归类好工具就不用每次临时去找也方便针对不同分析目标做取舍。比如post-route DRC阶段要用的库和综合阶段要用的库就经常不一样分开指定可以避免加载了多余的库导致内存浪费。2.2 库参数之间的关系参考库 vs 链接库-block_reference_libraries和-link_libraries是最容易混淆的两个参数。简单说-block_reference_libraries是给block物理实现用的提供floorplan、macro、memory的物理形状信息通常是NDM格式老流程里是MW。-link_libraries是给网表链接用的用来解析netlist里的cell reference通常是.db格式的逻辑库。实际项目中这两种库都要给。如果只给参考库没给链接库网表里的std cell解析不出来只给链接库没给参考库版图上没有cell形状floorplan根本画不了。我见过最典型的报错是Error: Cant find technology file ... Error: Cant load reference library ...这种基本都是库参数不完整导致的。排查的时候先别慌一个一个确认tf路径对不对、ndm路径对不对、link库的.db路径对不对90%的问题出在路径拼写上。2.3 MMMC相关参数scenario、mode、corner怎么联动MMMCmulti-mode multi-corner是ICC2的核心概念之一。create_workspace里有一组和MMMC联动的参数-mode、-scenario、-delay_corner、-operating_condition。很多flow的写法是先在脚本里用create_library_set、create_delay_corner、create_constraint_mode、create_scenario定义好所有MMMC对象再在create_workspace里用-scenario指定要装载哪些scenario。工具会做一个“快照”式的关联把指定的scenario连同背后的library set和corner一起装进workspace。如果create_workspace里不提供任何MMMC参数工具在创建workspace后会自动生成默认的scenario和mode。这看起来很方便但坑在于默认的mode和corner没有任何时序库关联你后面跑时序分析会发现库是空的。所以正式流程里我几乎不用默认MMMC都是显式指定。2.4 冷门参数也有大用处browse_mode、floorplan参数、block参数有些参数平时用不到但特定场景下能救命。-browse_mode是一个很多人不知道的好东西。它只加载物理信息不加载时序库适用于快速浏览版图结构、确认macro摆放、检查电源网络。打开速度快、内存占用小。但注意browse_mode下不能跑时序分析也不能做任何优化只能看。-floorplan_ref_library和-floorplan_name用于指定已有的floorplan模板。如果你的项目有标准的floorplan模板库可以在创建workspace时直接指定省得进去之后再手动导入。-block参数用于打开已经保存的block的workspace上下文。相比从零创建指定-block会把之前保存的analysis context一起恢复包括加载好的库、场景、约束非常适合接着上次的进度继续干活。3. 真实项目中的创建顺序一套能直接落地的命令序列3.1 从清晰的变量定义开始写项目脚本我习惯把所有路径和库名先存成变量再传给命令。这样既方便维护也能在日志里清楚地定位到底用了哪些文件。set block_name cortex_a53_top set tech_file /pdk/tsmc7ff/tf/tsmc7ff_9T.tf set ref_libs [list \ /pdk/tsmc7ff/ndm/tsmc7ff_sc9t_base.nda \ /pdk/tsmc7ff/ndm/tsmc7ff_sram_2k.nda \ /pdk/tsmc7ff/ndm/tsmc7ff_io.nda \ ] set link_libs [list \ /pdk/tsmc7ff/db/tsmc7ff_sc9t_ffg0p88v0p88v_125c.db \ /pdk/tsmc7ff/db/tsmc7ff_sc9t_ssg0p72v0p72v_125c.db \ ] set timing_libs [list \ /pdk/tsmc7ff/db/tsmc7ff_sc9t_ffg0p88v0p88v_125c.db \ /pdk/tsmc7ff/db/tsmc7ff_sc9t_ssg0p72v0p72v_125c.db \ ]变量准备好之后再用create_workspace就清爽很多create_workspace -name $block_name \ -block_reference_libraries $ref_libs \ -tech_file $tech_file \ -link_libraries $link_libs \ -timing_libraries $timing_libs这里有个容易被忽略的点tech_file在create_workspace和create_block里都可能出现。我的经验是create_workspace阶段就给 tf可以把工艺信息和workspace绑定后续创建block时不需要重复给。但如果你的flow里不同block用不同tf那就在create_block里单独指定灵活处理。3.2 MMMC配置的时机先定义对象再创建workspace实际项目flow里最常见的做法是先在icc2_shell里source一个mmmc.tcl把所有library_set、delay_corner、constraint_mode、scenario都定义好然后再执行create_workspace -scenario。这样workspace创建后自动带上完整的MMMC分析上下文进去就能直接干活。一个典型的mmmc.tcl片段create_library_set -name lib_fast \ -timing [list /pdk/tsmc7ff/db/tsmc7ff_sc9t_ffg0p88v0p88v_125c.db] create_library_set -name lib_slow \ -timing [list /pdk/tsmc7ff/db/tsmc7ff_sc9t_ssg0p72v0p72v_125c.db] create_delay_corner -name dc_fast -library_set lib_fast create_delay_corner -name dc_slow -library_set lib_slow create_constraint_mode -name func_mode \ -sdc_files [list /proj/blockA/constraints/blockA_func.sdc] create_scenario -name func_fast \ -delay_corner dc_fast -constraint_mode func_mode create_scenario -name func_slow \ -delay_corner dc_slow -constraint_mode func_mode然后在主脚本里source -echo /proj/blockA/scripts/mmmc.tcl create_workspace -name $block_name \ -block_reference_libraries $ref_libs \ -tech_file $tech_file \ -link_libraries $link_libs \ -scenario {func_fast func_slow}这种做法的好处是MMMC对象定义和workspace创建分离方便调试。如果MMMC文件里有错source阶段就会报错不会等到workspace创建半天之后才发现scenario不对。3.3 首次导入已有数据拿到网表和SDC之后的正确姿势如果是新设计工作流通常是创建workspace → 创建block → 读入网表 → 读入约束 → 检查环境。create_workspace -name $block_name \ -block_reference_libraries $ref_libs \ -tech_file $tech_file \ -link_libraries $link_libs \ -scenario {func_fast func_slow} create_block -name $block_name current_block $block_name link_block -netlist /proj/blockA/netlist/blockA.v read_sdc /proj/blockA/constraints/blockA_top.sdc check_workspacecheck_workspace是个值得养成习惯的命令它会检查当前workspace的完整性比如库引用是否正确、约束是否完整、是否有missing cell。我第一次跑新block时一定会执行一次把报出来的warning全部过一遍再继续。4. 最容易翻车的几个坑真实报错与完整排查链路4.1 库加载warning被忽略后面冒出一堆“幽灵违例”有次项目跑到布线后DRC阶段一个完全没动过的宏突然报出天线违例位置和形状都莫名其妙。当时第一反应是DRC rule设置有问题查了半天没结果。最后回溯到workspace创建日志发现一开始就有一行warningWarning: Cell SRAM_2K is defined in multiple reference libraries. The last one will be used.问题出在-block_reference_libraries里同时给了两个版本不一致的NDM库其中一个旧库里的SRAM_2K物理尺寸和新库不一致。工具当时没报错只给了warning但物理上用的却是错误版本后续所有分析都基于这个错误物理信息。排查链路看到异常DRC违例别急着改约束或者调antenna rule先回看workspace创建日志搜warning/conflict/redefinition关键词。一旦发现“multiple libraries”字样的warning立刻检查库列表把重复的cell库清理掉。库版本混用这种事在多人协作、多项目复用的环境里特别容易发生。4.2 scenario名字拼错工具居然不报错另一个隐蔽的坑是MMMC scenario名字输错。有一次脚本里create_scenario定义的名字是func_fast_125c但create_workspace -scenario写成了func_fast工具没有报错只是静默地少加载了一个scenario。后续跑报告时report_scenarios只列出了func_fast_125c没觉得异常直到report_qor发现少了 corner 数据才回头去查。这个坑在于ICC2对-scenario里找不到的名字有时候只是warning有时候直接忽略不会fail整个命令。排查链路创建workspace后第一件事就是敲get_scenarios检查当前加载了哪些场景对照MMMC定义检查是否有遗漏。我在项目脚本里固定写一段set expected_scenarios {func_fast_125c func_slow_125c func_typical_25c} set loaded_scenarios [get_scenarios -quiet] foreach scen $expected_scenarios { if {[lsearch $loaded_scenarios $scen] 0} { error Missing scenario: $scen } }脚本里加启动断言比事后发现corner缺失要高效得多。4.3 browse_mode打开workspace后不退出导致后续操作异常团队里有同事喜欢用icc2_shell -browse_mode开workspace查版图查完不退出挂在服务器上。过了几天另一个人在同一目录下跑正常模式创建workspace结果提示workspace已经被锁定或状态异常甚至出现MMMC配置被覆盖的情况。browse_mode设计出来是为了快速查看但它也会在workspace目录下写状态文件。如果你用browse_mode打开后又在这个session里做了保存动作哪怕只是保存了workspace options就会污染正常流程。排查链路遇到workspace状态异常先查这个目录下有没有多个历史session文件把无关的browse session清理掉。我现在的规矩是browse_mode只用来“看”绝不在里面做任何保存看完立刻退出。4.4 重复source MMMC文件导致的同名对象flow脚本写好之后难免要反复调试。问题出在mmmc.tcl被source了多次create_library_set里的对象名已经存在工具不会报错只会提示Warning: Library set lib_fast already exists. The existing object will be used.然后后面定义的lib_slow可能因为某种原因覆盖了lib_fast的关联导致corner指向了旧对象。这种问题非常隐蔽因为warning一闪而过不仔细看根本发现不了。排查链路get_library_sets输出所有对象看看有没有重复定义在MMMC脚本开头加保护逻辑if {[sizeof_collection [get_library_sets -quiet]] 0} { remove_library_sets [get_library_sets -quiet] }每次source前先清理再重新定义这样能保证MMMC对象的唯一性。这个习惯帮我省了很多莫名其妙的corner错误。4.5 变量名引用问题一个导致整条命令失效的细节还有个很小但很坑的问题create_workspace -name传变量时如果变量是列表而不是字符串workspace名字会变成一串奇怪的东西。有一次我写set block_name [list blockA blockB] create_workspace -name $block_name ...结果workspace名字直接变成{blockA blockB}后面的命令全乱了。排查链路加载workspace前先echo $block_name确认变量内容。变量传递这种基础细节往往是最容易浪费半天时间的地方。5. 与周边命令的搭配create_workspace 不是一条孤立命令5.1 用 get_workspace_options 检查当前环境配置创建完workspace后如果想确认当前环境用的什么库、什么配置可以用get_workspace_options查看。它能给出当前workspace的各种option状态包括参考库路径、tech file路径等。在调试“为什么有的库没加载进去”的时候比翻再多的日志都管用。我一般会写一个小脚本proc check_ws {ws_name} { set opts [get_workspace_options $ws_name] puts Workspace: $ws_name puts Reference libraries: [get_attribute $opts block_reference_libraries] puts Tech file: [get_attribute $opts tech_file] }然后项目里统一跑一遍确认所有block的workspace配置一致。这在多人协作时特别重要——你永远不知道别人在本机加载了哪些奇怪的库。5.2 保存与恢复save 和 create_workspace 的配合ICC2里保存数据用得最多的是write_design或save_block把 block 数据落到磁盘。下次要继续干活时不需要傻乎乎地重新创建workspace直接用create_workspace -name $block_name -block $block_name就能把之前的workspace上下文一起恢复。这里有个经验workspace上下文里保存的不只是design数据还有当时加载的库、scenario、option状态。用-block参数恢复比手工重新source一堆脚本要快得多也可靠得多。但前提是保存时的环境是干净的所以我习惯每次保存前跑一次check_workspace。5.3 批处理流程中的workspace管理并行任务千万别共享ICC2在实际项目里很少单跑一个block经常是几十个任务并行。并行时最容易犯的错误是多个任务复用同一个workspace目录导致库加载冲突、session文件互相覆盖。我现在的做法是每个任务单独建一个工作目录目录下再建对应的workspace。所有路径在脚本里用绝对路径不用相对路径——分布式跑法下相对路径特别容易出事。批处理脚本里设置set_workspace_options禁止自动保存防止并行任务把别人的workspace覆盖掉。set_workspace_options -allow_auto_save false5.4 把workspace创建封装成proc统一团队入口项目走到中期我习惯把整个workspace创建过程封装成一个proc放在公共脚本库里proc create_ws_from_template {block_name} { source -echo /proj/common/scripts/mmmc.tcl set ref_libs [get_standard_ref_libs] set tech_file [get_standard_tech_file] create_workspace -name $block_name \ -block_reference_libraries $ref_libs \ -tech_file $tech_file \ -link_libraries [get_standard_link_libs] \ -scenario [get_standard_scenarios] check_workspace }这样每个新人都能通过同一个入口创建工作区不会拿着五花八门的参数乱试。团队内统一入口之后很多因为个人配置差异导致的灵异问题都消失了。6. 最后再分享一点个人体会用ICC2这些年我最有感触的不是哪条命令多么复杂而是这工具有很多“不报错但会坑你”的地方。create_workspace是每个ICC2项目的第一个门槛恰恰是第一步最容易出错。库路径写错、scenario名对不上、变量引用有问题、browse session残留这些问题单看都不难但叠在一起就非常消耗精力。我现在自己接手一个新block流程固定成这样先check环境变量 → source MMMC → create_workspace → 马上get_scenarios和check_workspace→ 再看log里有没有warning/conflict/missing。走完这一套才继续后面的floorplan或placement。这个习惯帮我挡掉了不少本可以避免的返工。如果你刚接触ICC2别急着研究复杂的multi-corner优化脚本先把create_workspace跑顺。这条命令理顺了后面create_block、link_block、读约束、跑floorplan都会顺很多。 SEO 优化官网定制响应式建站教育培训建站