OpenLANE Magic DRC 报错:Metal1 spacing met1.2 间距违例独立排查速查
更新时间:2026-11-06。报错排查篇,属于 EDA 报错排查系列。OpenLANE flow 末尾的 Magic DRC 一旦报出
Metal1 spacing < 0.14um (met1.2),违例几何往往埋在几千行 flow 日志里,很难直接看清。更快的办法是脱离flow.tcl,用一个最小 Tcl 脚本在 Magic 里独立跑 sky130A full DRC,把问题压缩成两块矩形之间的一条缝隙。本篇用同一结构的两组版图做对照:间距 0.03um 时被判 2 个 rule hits,放宽到 0.20um 后零命中。flow 内其他阶段的硬失败可对照 GRT-0119 布线拥塞失败 与 PDN-0191 制造网格报错。
首屏答案:Metal1 spacing < 0.14um (met1.2) 的意思是 sky130A 工艺的 met1.2 规则要求同层 met1 金属间距至少 0.14um,而你的版图里两条 met1 矩形只隔了 0.03um,Magic 按规则 deck 判决违例。独立排查的命令序列只有五条:drc euclidean on 对齐工艺的欧几里得度量,drc style drc(full) 加载完整规则集,drc on 开启检查,drc catchup 追平全部待查几何,drc listall why 逐条列出违例规则与坐标。修复方向不是关检查,而是改版图——本例把缝隙从 0.03um 放宽到 0.20um,复跑立刻拿到 === TOTAL: 0 rule hits ===。
先用一张分诊漏斗把排查路径收窄:这个报错的规则名同时给了阈值和编号,本质是一道比大小的几何题,不需要开 GUI 翻整块版图。
这张漏斗越往下信息越确定。现象层给出规则名和命中计数,规则层把合法阈值讲明白,真正需要人做的只是几何层那一次减法:0.53 - 0.50 = 0.03um,与 0.14um 一比就知道差在哪。机制层提醒的是工具姿势——不开 full style、不切欧几里得度量,同样的版图可能漏报,排查结论本身就不可信。
本文要回答的问题
Metal1 spacing < 0.14um (met1.2)这行输出里,阈值、规则编号、rect 坐标各怎么读?- 脱离 OpenLANE flow 独立跑 Magic DRC,和 flow 末尾自带的 DRC 检查有什么区别,为什么排查要用前者?
- met1.2 规则的 0.14um 是怎么量出来的,
drc euclidean on与drc style drc(full)各自解决什么问题? - 在无图形界面的服务器上,五条 DRC 命令按什么顺序敲,有哪些实测出来的坑?
- 改完版图复跑,log 里出现什么才算真正过关?
一、报错原文:Magic 独立 DRC 的两份判决书
先把复现环境说清楚。本次没有跑 flow.tcl,而是在 OpenLANE 容器内直接调用 Magic,执行一个只画两块 met1 矩形的最小 Tcl 脚本:第一条矩形宽 0.5um、高 2.0um,左下角在原点;第二条同样尺寸,左下角放在 x=0.53um 处。两条矩形之间的缝隙因此是 0.03um。命令带 -dnull(不启动图形设备)和 -noconsole(不进交互窗口),专门适配无头服务器:
读这段输出抓三个字段。第一,DRC style is now "drc(full)" 与紧跟的 Loading DRC CIF style. 是切换证据,说明脚本里确实打开了 full style,接下来跑的是 sky130A 完整规则集而不是默认子集。第二,Metal1 spacing < 0.14um (met1.2) 是核心判决:规则文本前半截是人话描述——Metal1 的间距小于 0.14um,括号里的 met1.2 是 sky130 规则手册里的编号,拿这个编号可以回查工艺文档确认适用条件;下一行 rect: 106 0 128 400 给出违例区域在 Magic 内部单位下的坐标框。第三,=== TOTAL: 2 rule hits === 是命中计数,同一条 met1.2 在违例几何上计了两次。排查时不必纠结计数口径,规则名加违例坐标已经把问题钉死在两条矩形之间的缝隙上。
为什么要独立跑而不是看 flow 日志?OpenLANE 在 flow 尾声也会调 Magic 做整版 DRC,但完整版图有成千上万条几何,违例报告淹没在长日志里,定位区域、辨认规则都很慢。独立 DRC 把版图缩成故意构造的两块矩形,一次只验证一条规则,改完几何几秒钟出判决,适合做规则机理的对照实验。flow 内的失败定位见 GRT-0119 布线拥塞失败实录,与本篇是两种排查姿势。
二、谁在判错:Magic、OpenLANE 容器与 sky130A 规则 deck
这条报错涉及三层工具链,职责分清才不会修错地方。版本号全部照抄 log 头部的三行记录,没有凭印象写:
| 层 | 组件与版本 | 在本次检查里的角色 |
|---|---|---|
| 版图编辑与 DRC 引擎 | Magic 8.3 revision 413(2023-07-12 编译) | 加载规则 deck,对版图几何逐条判决并输出 rule hits |
| 运行环境 | OpenLane d054702b 官方 Docker 容器 | 提供 Magic 二进制、sky130A.magicrc 与工艺目录,无头模式运行 |
| 工艺数据 | sky130A tech 1.0.424 | 提供 met1.2 在内的全套设计规则与层名定义,0.14um 阈值的来源 |
关键认知:0.14um 不是 Magic 的参数,是 sky130A 的工艺事实。Magic 本身只是一个通用版图编辑器,它不知道金属间距该是多少;判决依据来自启动时 -rcfile sky130A.magicrc 加载的工艺配置,以及 drc style drc(full) 之后载入的 CIF 风格规则 deck。换一个工艺节点,同一条命令跑出来的阈值和规则编号会整体换掉,不要把本篇的 0.14um 往 sky130 以外的工艺上套。
环境坑也要先排除:镜像 tag 与 PDK 版本不匹配时,Magic 可能加载错规则目录,表现为规则文本异常或层名找不到,排查见 docker tag 不匹配速查;配置键名报错是另一个家族,见 OpenLANE 未知配置键报错。本篇 log 头部明确打出 Sourcing design .magicrc for technology sky130A,容器、PDK、rcfile 配套,剩下的是纯几何问题。
三、根因拆解:met1.2 的 0.14um 与那条 0.03um 缝隙
把 bad case 的几何数据摊开算一遍。log 里两次 Root cell box 分别对应两条矩形的尺寸与落点,单位是 microns:第一条占据 x 轴 0.000 到 0.500,第二条占据 0.530 到 1.030。两条矩形都是 0.5um 宽、2.0um 高,长边平行相对,中间的缝隙就是 0.530 - 0.500 = 0.030um。met1.2 要求 met1 同层间距不小于 0.14um,实际值不到阈值的四分之一,判决没有任何模糊空间。
这里要讲清两个机制,否则照着命令敲也容易得到错误结论。
第一个是度量方式。Magic 的 DRC 支持曼哈顿距离与欧几里得距离两种度量,sky130A 的规则 deck 按欧几里得距离定义间距——不只水平竖直相邻要算,角对角、斜对的几何同样按两点间直线距离计入。脚本开头先执行 drc euclidean on,就是让引擎的度量方式与工艺 deck 对齐;不打开它,遇到斜向相邻的几何可能漏报,你以为干净的版图其实藏着违例。
第二个是规则风格。Magic 启动后默认的 DRC style 只覆盖一组常用规则,跑全套 sky130 signoff 检查必须显式切到 drc(full)。log 里的 DRC style is now "drc(full)" 就是这一切换的回执,随后 Loading DRC CIF style. 表示完整规则表已经载入。今晚实测时,同一份 bad 版图如果不切 full style,met1.2 这类规则根本不在检查范围内,输出会是零违例——这个「零命中」是假的,比报错更危险。
把从报错到修复的完整路径画成一张排错流程图,颜色按角色区分:红是报错与根因两端,蓝是排查动作,橙是修复动作,绿是修复后的通过态。
读这张图抓住一条主线:先对齐工具姿势,再谈几何修复。跳过蓝色两步直接改版图,引擎用什么度量、跑了哪些规则都不知道,后面的零命中无法自证。根因节点的算式虽然简单,成立前提却是检查环境已与工艺 deck 对齐。
四、排查清单:五条 DRC 命令与三个实测坑
在 Magic 的 Tcl 解释器里(或写进脚本由 -noconsole 模式执行),完整检查序列如下,顺序不要乱:
drc euclidean on
drc style drc(full)
drc on
drc catchup
drc listall why逐条说用途。drc euclidean on 切欧几里得度量;drc style drc(full) 载入 sky130A 完整规则集;drc on 打开后台 DRC,此后版图变动会触发增量检查;drc catchup 阻塞等待引擎处理完全部待查几何,脚本化运行缺了它可能提前退出;drc listall why 逐条打印违例规则名与坐标,也就是 CASE A log 里那份判决的来源。
今晚在容器里反复试跑时踩了三个坑,都值得记下来:
| 坑 | 实测表现 | 正确做法 |
|---|---|---|
| 层名写错 | 按别家工艺的习惯写 metal1,Magic 报找不到该层,paint 命令直接失败 | sky130A 规则 deck 里的层名是 met1,met2、met3 同理,先查工艺层名表再下笔 |
| 误用旧命令 | 在 Tcl 脚本里敲 newcell 建新 cell,解释器回 invalid command | newcell 是老交互界面的命令,Tcl 模式下用 cellname create 一类的 Tcl 接口建新 cell |
| 不开 full style | 不执行 drc style drc(full) 就跑检查,bad 版图也输出零违例 | 任何 signoff 结论之前先确认 log 里出现 DRC style is now "drc(full)" |
第三个坑最隐蔽,因为它不报错、只给假阴性。判断方法很简单:每次跑完翻一眼 log,确认 full style 的回执行在违例报告之前出现过,再去读 TOTAL 计数。另外 drc listall why 在零违例时输出为空,不要把「命令没输出」误判成命令没执行——结合 TOTAL: 0 rule hits 一起看才是完整结论。
五、修复与复跑:间距放宽到 0.20um 后的零命中
修复动的是版图几何,不是检查开关。把第二条 met1 矩形的左下角从 x=0.53um 挪到 x=0.70um,矩形宽度仍是 0.5um,新的缝隙是 0.70 - 0.50 = 0.20um,高于 met1.2 的 0.14um 阈值并留出 0.06um 余量。Tcl 脚本的其余部分——rcfile、euclidean、full style、五条 DRC 命令——一字不动,保证两次判决口径完全一致:
过关信号有两个。其一,=== DRC VIOLATIONS (good) === 之后打印的是 No errors found.,而不是 CASE A 里的规则名与 rect 坐标;其二,结尾 === TOTAL: 0 rule hits === 与 CASE A 的 2 rule hits 形成干净对照。注意两份 log 的前置行完全同构——同样的 Magic 版本、同样的 drc(full) 回执、同样的 CIF style 载入,唯一差异就是第二条矩形的落点,因此这个零命中是可自证的:检查环境没变,变的只有几何。
工程上补一句:0.20um 不是经验最优值,只是为跨过 0.14um 阈值并留余量取的整。真实设计的间距还要满足布线器轨距与周边密度约束,改完应回到完整 flow 让详细布线与整版 DRC 再验一遍——独立 DRC 确认规则机理,flow 内 signoff 负责最终背书,两者不能互相替代。
实验环境
- 机器/系统:云主机 / Ubuntu 22.04(OpenLane 官方 Docker 容器内无头运行,Magic 带
-dnull -noconsole) - 工具版本:Magic 8.3 revision 413(容器内,2023-07-12 编译);OpenLane d054702b 容器;sky130A tech 1.0.424(版本照抄 log 三行头)
- 日期:2026-11-06
- 完整命令:
magic -dnull -noconsole -rcfile sky130A.magicrc drc-bad.tcl(CASE A,两条 met1 矩形间距 0.03um,2 rule hits);magic -dnull -noconsole -rcfile sky130A.magicrc drc-good.tcl(CASE B,间距 0.20um,0 rule hits)
代码获取
复现用的两份 Tcl 脚本(drc-bad.tcl / drc-good.tcl)、rcfile 配置与一键运行脚本在公开仓 https://github.com/derekzhuo/geek-doc.cn/tree/main/experiments/openlane-magic-drc-errors。按目录内 README 准备好 volare 管理的 sky130A PDK,在 OpenLane 容器内执行 PDKR=$HOME/.volare ./run.sh 即可依次重现「met1.2 判决 2 rule hits → 间距放宽后 0 rule hits」的完整对照,两次运行的几何差异只在第二条矩形的 x 坐标。
这一篇在知识体系里的位置
本篇是 EDA 报错排查系列 中 OpenLANE 签核(signoff)阶段错误簇的一员,处理的是「flow 能跑完、但几何过不了工艺规则」这一类问题。同属 OpenLANE flow 的硬失败可按阶段串读:floorplan 阶段的数值合法性问题见 PDN-0191 制造网格报错,布线阶段的容量问题见 GRT-0119 布线拥塞失败,配置加载阶段的键名问题见 OpenLANE 未知配置键报错,容器与 PDK 配套问题见 docker tag 不匹配速查。本篇的独特姿势是脱离 flow、用最小版图在 Magic 内独立验证单条规则,这套方法同样适用于 enclosure、width 等其他 sky130 规则的机理确认。
总结
Metal1 spacing < 0.14um (met1.2) 的本质是几何间距不达工艺要求:sky130A 的 met1.2 规则规定同层 met1 间距至少 0.14um,本例两条 0.5um 宽矩形只隔 0.03um,被 Magic 8.3 的 full DRC 判出 2 个 rule hits。排查脱离 flow.tcl、用最小 Tcl 脚本独立跑 Magic,先 drc euclidean on 对齐欧几里得度量、drc style drc(full) 载入完整规则集,再 drc on、drc catchup、drc listall why 拿到带坐标的违例清单;绕开三个实测坑——层名是 met1 不是 metal1、Tcl 模式没有 newcell 命令、不切 full style 会出假阴性零命中。修复只改版图不改检查:缝隙放宽到 0.20um 后同一口径复跑,No errors found 加 TOTAL: 0 rule hits 即为过关,真实设计还需回到完整 flow 做整版 signoff 背书。