尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

从ITF/IRCX自动生成EMX工艺文件的脚本解析与实现

从ITF/IRCX自动生成EMX工艺文件的脚本解析与实现 干模拟版图或者电磁仿真这一行的朋友对ITF/IRCX这几个字母一定不陌生。每回在EMX里建无源器件模型最折磨人的不是画版图是把工艺文件里那一堆层名、厚度、电阻率、介电常数一个一个手动抄进去。抄错一个小数点整个仿真结果就废了。我刚开始用EMX的时候也这么干过一次三层金属两层介质抄了半小时最后跑出来的电感和实测差了20%一查发现是某一层厚度单位从微米给我敲成了纳米。从那以后我就在想这种机械的体力活能不能写个脚本自动从ITF/IRCX文件里解析出来直接生成EMX能认的工艺文件今天就把我折腾出来的这套脚本思路完整拆给你们原理、代码、坑一次性说清楚。这套方法特别适合三类人一是刚开始用EMX、手里只有代工厂ITF文件却找不到现成EMX工艺文件的工程师二是要频繁切换工艺节点、每次都要重复整理工艺参数的版图/仿真岗三是想给自己的流程加点自动化、但又不想从零研究文件格式的工具党。文章不追求给你一个开箱即用的成品而是把解析思路和关键映射关系讲透你拿过去改改正则、调调映射表就能套在自己家的工艺文件上。1. 先别急着写脚本把ITF/IRCX的结构摸清楚1.1 ITF/IRCX到底是什么和EMX有什么关系ITF全称Interconnect Technology File是代工厂发给设计公司做寄生参数提取用的互连工艺文件IRCX可以理解成ITF的一种XML化或者更新形式的变体本质上描述的是同一套物理信息——每一层金属的厚度、方块电阻每一层介质的厚度、介电常数还有通孔、钝化层、衬底这些内容。EMX是Cadence环境里做电磁仿真的工具它的三维求解器需要知道每层导体的几何和电学参数才能在版图基础上构建出真实的物理结构。所以逻辑链很简单代工厂给的是ITF/IRCXEMX要的是自己的techfile两者描述的是同一个物理世界只是表达格式不同。这里有个特别容易忽略的点EMX的工艺文件在很多PDK里其实是代工厂直接提供的你不需要自己转换。但如果你用的是非主流工艺、自研的MEMS流程、或者拿到的是个不完整的PDK那就得自己动手了。还有种常见情况是PDK里的EMX版本和你安装的EMX版本不匹配加载时报错这时候自己解析ITF重新生成一份反而是最快的解法。1.2 一个典型ITF文件从头到尾长什么样不同代工厂的ITF格式细节会有差异但骨架几乎是一样的。我简化一下一个典型的ITF文件大概长这样* V1.2 DIELECTRIC ILD1 { THICKNESS 0.50 ; EPSILON 3.90 ; } CONDUCTOR M1 { THICKNESS 0.50 ; RESISTANCE 0.079 ; SIDEWALL 0.50 ; } VIAPLUG VIA1 { THICKNESS 0.50 ; RESISTANCE 8.00 ; }看起来挺规整实际文件里会比这个乱得多。注释行、单位说明、温度系数、应力参数各种和EMX无关的字段全混在一起有的层名字还带前缀后缀比如TM1、M1_DUMMY、V1_CAD光靠肉眼去挑绝对会疯。所以第一步是把行分类DIELECTRIC、CONDUCTOR、VIAPLUG分别对应EMX里的介质层、金属层、通孔层这是解析的主线。1.3 文件格式差异ITF、IRCX、以及加密变体IRCX文件通常带有XML标签比如layer nameM1 typeconductor这种结构解析起来反而比ITF简单因为格式更固定。麻烦的是某些代工厂会用加密后的ITF文件头写着# qrc encrypted之类正文全是乱码。遇到这种文件别硬刚联系代工厂或者PDK厂商要一份解密的版本正常处于保密协议下他们都会给。还有的工艺文件会把数值写成表达式比如THICKNESS 0.5e-6单位直接给你用米而不是微米解码脚本时这两类都得兼容。所以无论脚本写得再好第一步永远是先人工打开文件看一眼整体结构。我吃过一次亏拿到一个新工艺的ITF直接上正则去匹配CONDUCTOR块结果匹配出来是空的一看原来关键字写的是LAYER M1而不是CONDUCTOR M1中间还多了一个缩进层级。看文件结构再写解析这是省时间的捷径不是浪费时间。2. EMX工艺文件需要哪些参数脚本这步才是灵魂2.1 EMX需要的五大类参数EMX定义一层导体基本绕不开五样东西层名、厚度、电导率或者方块电阻、侧壁角taper、层的上下位置关系。介质层需要的是层名、厚度、介电常数。通孔层需要有效电阻。衬底需要电阻率和介电常数。其中厚度和电导率是绝对的核心差一点都不行。有个细节要特别注意EMX里有的版本用电阻率ρ单位Ω·m有的版本用方块电阻Ω/sq两者之间的换算是ρ Rsheet × t这里的t必须是厚度。比如ITF里M1的方块电阻是0.079 Ω/sq厚度是0.5微米那电阻率就是0.079 × 0.5 × 10⁻⁶ 3.95 × 10⁻⁸ Ω·m。这个值接近铝的电阻率看着就很合理。如果你在脚本里排除这个换算直接把0.079填到电阻率那一栏EMX算出来的金属损耗会小一个量级Q值虚高仿真结果绝对骗人。2.2 单位换算与电阻率计算单位换算是脚本里最容易出bug的地方没有之一。ITF里激光距离通常用微米但有些老文件用的是纳米介电常数EPSILON一般没单位但有的文件会给相对介电常数有的给绝对介电常数差一个8.854×10⁻¹²倍。我建议在整个脚本的开头就定义好统一的内部单位——全部转成微米和欧姆·米后面所有计算都在这个基准上进行最后再转去输出EMX的格式。再看一个我经常见到的坑通孔的RESISTANCE在ITF里通常是一个通孔的电阻值单位是欧姆。但EMX的通孔定义需要的可能是方块电阻或者单位面积电阻这两个概念完全不同。如果你的工艺文件里通孔有具体尺寸信息可以直接算如果只是给出单孔电阻那就需要在脚本里额外维护一个孔尺寸的常量表根据通孔的实际开口尺寸换算成EMX能用的值。这个映射关系没法纯靠解析ITF得到必须结合版图或设计规则里的通孔尺寸来填。2.3 层名映射表和常见命名差异层名映射是整个自动生成流程里最需要人工介入的地方。ITF里的层名往往和版图层的名字不一致比如ITF里写M1EMX里也写M1但有时ITF里是METAL1EMX里的层名却是M1还有的工艺金属层名字带后缀比如M1_RF但EMX期望的名字是普通M1。这靠正则解决不了只能靠一个映射表。我在脚本里维护一个字典layer_map { METAL1: M1, METAL2: M2, VIA1: V1, V12: V1, ILD1: D1 }实际写映射表时建议从版图层的真实名字出发因为EMX最终对齐的是版图的物理层。这里有一个小技巧打开Virtuoso的LSW窗口看层名列表和ITF里的层名逐一对照把两边名字一致或不一致的都记下来一次记全以后这个工艺的所有脚本都能复用。第一批层名映射表建好后面换工艺、换节点也只是往表里加几行的事。3. 脚本解析与自动生成实操3.1 用什么语言写脚本整体分几步我选用Python来写解析脚本因为它处理文本和正则确实方便而且几乎所有EDA环境里都能直接跑。当然你用Perl、awk甚至shell加sed也能完成但如果要做单位换算和层名映射Python的数据结构会让代码干净很多。整个脚本的核心流程就是四步第一步读文件并按关键字切块第二步从每个块里正则提取想要的参数第三步做单位换算和层名映射第四步把结果按EMX格式拼接输出。前两步占80%的代码量但真正的逻辑复杂度都在第三步的映射和换算上。我建议把第四步的输出函数单独拆出来这样以后想输出成别的工具格式只要改一个函数就行。3.2 正则解析与数据提取示例假设ITF文件结构是上文那种块状格式核心解析代码我写了这么一段import re def parse_itf(file_path): with open(file_path, r, encodingutf-8, errorsignore) as f: text f.read() layers [] # 匹配 DIELECTRIC / CONDUCTOR / VIAPLUG 三种块 pattern re.compile( r(?PtypeDIELECTRIC|CONDUCTOR|VIAPLUG)\s r(?Pname\w)\s* r\{(?Pbody.*?)\}, re.S ) for m in pattern.finditer(text): layer {type: m.group(type), name: m.group(name)} body m.group(body) t re.search(rTHICKNESS\s*\s*([0-9.eE-]), body) r re.search(rRESISTANCE\s*\s*([0-9.eE-]), body) e re.search(rEPSILON\s*\s*([0-9.eE-]), body) if t: layer[thickness] float(t.group(1)) if r: layer[resistance] float(r.group(1)) if e: layer[epsilon] float(e.group(1)) layers.append(layer) return layers这段正则用命名分组把三种类型一次匹配出来body部分再单独提取THICKNESS、RESISTANCE、EPSILON。对于规范格式的ITF文件这套解析已经能覆盖大部分情况。注意re.S标志一定不能丢它让.能匹配换行符否则多行块就匹配不全。如果你手里的ITF格式是缩进式的比如块内容缩进了两格或者层名前面带*注释标记正则的匹配范围要做相应调整。我的经验是先跑一遍脚本打印出所有匹配到的层名和人工看文件得到的层名列表对比少了哪个就说明那种格式没匹配上然后针对性调正则。这个迭代过程一般两三轮就能稳定。3.3 从提取结果拼出EMX工艺文件解析完之后根据提取到的参数和层名映射表来生成EMX工艺文件。EMX的techfile格式不同版本略有差异但常用的一种是这样的METAL M1 { THICKNESS 0.50 RESISTIVITY 3.95e-8 } DIELECTRIC D1 { THICKNESS 0.50 EPSILON 3.9 } VIA V1 { THICKNESS 0.50 RESISTIVITY 8.00 }对应的输出代码可以这么写def gen_emx(parsed_layers, layer_map): lines [] for layer in parsed_layers: mapped_name layer_map.get(layer[name], layer[name]) if layer[type] CONDUCTOR: rho layer[resistance] * layer[thickness] * 1e-6 lines.append(fMETAL {mapped_name} {{) lines.append(f THICKNESS {layer[thickness]:.4f}) lines.append(f RESISTIVITY {rho:.4e}) lines.append(}) elif layer[type] DIELECTRIC: lines.append(fDIELECTRIC {mapped_name} {{) lines.append(f THICKNESS {layer[thickness]:.4f}) lines.append(f EPSILON {layer[epsilon]:.4f}) lines.append(}) return \n.join(lines)这段代码把“解析得到的字典列表”和“输出字符串”彻底隔离后续想改成输出成XML格式或者加一个衬底定义都不影响前面的解析逻辑。生成完文件后建议先打开看一眼重点检查单位是不是在合理范围内。3.4 自动化的边界哪些能做、哪些不能省写自动化脚本最重要的不是写得多而是知道哪里该自动、哪里必须人工。我自己的原则是一切能从ITF里正则提取的物理参数全部自动走但层名映射表的初始建立必须人工核对因为名字错一处在EMX里直接报错还好怕的是名字映射到了别的层上仿真时电感变成了一条断线但工具又不报错排查起来极其痛苦。另一个不能省的人工点是衬底参数。ITF文件里通常包含衬底相关信息但格式五花八门有的给的是衬底方块电阻有的给的是衬底电阻率定义的位置也不固定。我的做法是衬底参数单独写在脚本配置区作为手工常量每次换工艺时手动更新。这样解析脚本可以全自动跑但整体流程里保留两个需要人确认的“检查点”——一个是层名映射表一个是衬底参数看起来不够“全自动”但实际用下来反而更稳。4. 踩坑记录与排查技巧4.1 层名匹配不上导致EMX报错最常见的一个报错是类似ERROR (EMX-161): Conductor layer M1 not found in layout这种明明生成的工艺文件里有M1EMX却说不认识。十有八九是版图层的真实物理名和你生成的文件里的层名差一个大小写或者差一个前缀。举个真实例子某工艺的版图里顶层M1叫M1_TEXT但ITF里就叫M1我生成的文件里只有M1EMX在跑版图时就找不到对应层。排查方法是在Virtuoso里打开要仿真的GDS或者版图用LSW查一下每一层的physical name然后回到脚本的layer_map里补一条映射。这类问题不需要动核心代码纯粹是映射表的事。我建议在生成EMX文件时把所有映射过的层名打一条log对照一遍版图层的名字基本就不会有漏网之鱼。4.2 厚度单位不同导致仿真偏差ITF里大部分厚度单位确实是微米但有一次我在脚本里特意加了自动识别单位的功能结果反而出了幺蛾子。那时候一个文件里既有THICKNESS 0.5又有THICKNESS 5000AA代表埃也就是0.05微米。我的脚本只按浮点数提取没带单位解析直接把5000当成微米输出生成的EMX文件里那个介质层厚得离谱跑出来的耦合电容完全不对。后来我把单位的自动识别重写了一遍把所有带单位后缀的值全部换算成微米规则是无单位默认按文件头部声明的单位一般是微米带A值除以10000转成微米带um或μm值不变带nm值除以1000转成微米同时输出时把所有数值统一保留四位小数方便肉眼检查。这个改动之后再也没被单位坑过。4.3 通孔电阻和TAPER角度的特殊处理通孔层是最容易让脚本流于表面的地方。ITF里VIAPLUG块给出的RESISTANCE是单孔电阻它跟孔的尺寸直接相关。EMX在计算通孔阵列时需要的是通孔层的有效导电率而不是单孔电阻。如果你直接把单孔电阻填进去EMX会把它当成整层材料的体电阻率计算结果必然出问题。我的处理方式是在脚本里单独维护一个via_area配置项记录这个工艺的通孔开口面积。比如一个0.13工艺的通孔开口是0.13×0.13微米面积是0.0169平方微米那么通孔层的有效电阻率可以估算为单孔电阻乘以面积再乘以厚度公式是ρ_via R_via × A_via / t_via。这样算出来的值才能喂给EMX不然通孔阵列的电阻会差出一个数量级。还有一个边角参数是TAPER也就是金属侧壁的角度。普通工艺手册里一般给的是90度也就是垂直侧壁但有些射频工艺为了做厚铜会有向内倾斜的侧壁。这个参数ITF里不一定直接给要给也常常叫SIDEWALL。如果你的EMX版本支持TAPER定义我建议先用默认90度跑一遍遇到仿真结果跟实测对不上的时候再仔细抠这个参数因为调整TAPER对电感的影响通常只在毫米波频段才明显。4.4 无效工艺文件在EMX里的报错表现生成的工艺文件在EMX里加载失败常见报错有三种。第一种是unexpected character at line ...多半是输出文件里有中文字符或者全角空格脚本生成的文本里不会出现这种问题但如果你在映射表里手写了一个中文注释混进了输出就会这样。第二种是missing required parameter说明某层块里缺少必填字段比如METAL块里没有THICKNESS原因是解析时相应的正则没匹配上跑一下解析函数的输出看看那个层的dict里缺了哪个key。第三种比较隐蔽EMX能正常加载但仿真时模型总是被忽略掉某层这通常是层与层之间的上下顺序乱了介质层排在了金属层前面。排查第三种报错时最有效的办法是把生成的工艺文件手动打开从第一行往后读一遍看金属层和介质层的交替顺序是否与工艺实际一致衬底在最下面往上依次是介质、金属、介质、金属……如果发现连续两层金属中间没有介质那大概率是ITF里的某层类型被标记错了回到解析函数看看那一层是被解析成了CONDUCTOR还是DIELECTRIC手动修正块的类型判断逻辑。5. 验证生成的工艺文件避免带病上线5.1 最小验证结构测试法生成的工艺文件不能光看格式对不对就直接拿去跑大电感建议先用一个最小测试结构验证。我在每个新工艺第一次生成完文件之后都会画一个最简单的单圈方形电感就两层金属外加一段微带线然后分别用EMX和理论公式算一下低频电感量。如果生成文件里的层参数没问题2GHz下这个单圈电感的电感量应该跟经验公式算出来的误差在5%以内如果误差到了20%以上先检查金属厚度和介质厚度。还有一个快速验证点是高频自谐振频率如果你生成的工艺文件里介质介电常数偏大自谐振频率会明显偏低这个现象比电感量偏差更直观。5.2 脚本的复用与工艺库维护脚本写完之后我强烈建议把它变成一个工艺库维护工具而不是一次性脚本。我会为每个工艺节点建一个目录里面放三类东西原始的ITF/IRCX文件、解析脚本的配置文件映射表、通孔面积、衬底参数、以及脚本生成出来的EMX工艺文件。这样半年后想更新某个参数只要改配置文件再跑一遍脚本几秒钟就能重新生成不需要再手动改EMX文件也避免改错。配置文件的格式我用最简单的YAML因为可读性好非程序员同事也能直接改via_area_um2: 0.0169 substrate_resistivity: 10.0 substrate_epsilon: 11.9 layer_map: METAL1: M1 METAL2: M2 VIA1: V1这套习惯坚持下来之后换工艺节点从原来的一下午缩短到十分钟而且再也不用手动去填EMX界面里的参数了。5.3 最后再分享一个个人体会这个脚本我前后迭代了好几版最开始的版本直接把ITF里的字段名原封不动输出到EMX文件后来发现不同工艺的ITF字段名五花八门远没有我想象的标准化。那段经历让我养成了一个习惯无论解析代码写得多好都要在流程里留一个“人工检查工艺文件”的环节不是对HTML代码不放心而是工艺数据本身太重要一个参数错了流片就没了。现在我在每个工艺文件生成完以后都会在注释里把原始ITF的版本号、代工厂名、生成时间、改过哪些映射全部写进去。这个习惯救过我一次因为后来发现用的通孔面积是上个工艺的就是靠文件头的注释才追溯出来的。自动化脚本减少的是重复劳动不是思考本身。映射表的核对、衬底参数的确认、通孔面积的填写这些环节依然需要人来做判断但这正是像我们这样的工程师体现价值的地方。把这套流程跑通了之后会发现EMX工艺文件生成这件事真的可以彻底告别手动算了。
返回列表