Calibre 重复定义:rule already defined 速查
更新时间:2026-10-22。FAQ 速查页,属于 EDA 工具排错系列。Calibre(Siemens EDA 的物理验证工具,DRC/LVS/PEX 三件套)说的「重复定义」和 HDL 编译器不是一套口径:它不编译 filelist,而是把工艺厂给的 SVRF rule deck 逐层 INCLUDE 展开,再读入 GDS/OASIS 版图和 SOURCE 网表。同一个名字在 deck 展开序列里出现两次、同一个 cell 在数据流里有两个 version、同一条
.SUBCKT被读两遍,都会得到already defined/multiple definition一类信息。rule deck 的分层结构见 Calibre SVRF rule deck 解剖,验证流程全貌见 Calibre 物理验证实操,反面问题「一次都没定义」见 Calibre 模块/单元找不到。
本文要回答的问题
- transcript 里的
Rule ... is already defined是哪段 deck 被读了两遍? - 同一条 SVRF 规则在两个 include 文件里各声明一次,Calibre 听谁的?
- GDS stream in 时报同名 cell 有 multiple versions,版图数据还能不能用?
- LVS 网表里同一个
.SUBCKT出现两次,和 rule 重复是同一类问题吗? - 为什么工艺厂原版 deck 不报警告,我自己加了一层 INCLUDE 就满屏重复?
一、报错原文与典型现象
Calibre 的重复定义信息全部进 transcript(启动目录下的 .drc.results/.lvs.report 或重定向 log),五星前缀,且通常带名字但不一定带行号——因为第二次出现的位置才报警,第一次定义的位置要自己回去找。以下是四类典型文案,规则名、cell 名、工程名已占位:
1. SVRF 规则或变量被重复声明(deck 展开阶段,最常见):
***** WARNING: Rule "M1.S.1" is already defined. The new definition will replace the previous one.
***** WARNING: Variable "DRAW_METAL1" redefined while processing include file "proj_overlay.svrf".2. 同一 deck 段被 INCLUDE 多次(常伴随上面一大片规则重定义):
***** WARNING: File "common/stack.svrf" has been included more than once.3. GDS/OASIS 里同名 cell 存在多个 version(读版图阶段):
Warning: Cell "fifo1kx8" has multiple versions in the input stream. The last version read will be used.4. SOURCE 网表同一 subckt/module 两次、layer map 重复映射(LVS/读入阶段):
***** ERROR: Subcircuit "PLL300M" is already defined in source netlist.
***** WARNING: GDS layer 31:0 is mapped more than once (metal1, dummy_m1); the last mapping is used.先分清态度:Warning 级是 Calibre 用后读入的定义覆盖先读入的,流程能走完,但生效的那份规则/cell 未必是你以为的那份——DRC 结果会静默失真;Error 级直接中断(LVS 网表重复多为 Error)。第二条线索是重复对象的种类:rule/VARIABLE 名重复,病根在 deck 的 INCLUDE 结构;cell/subckt/layer 名重复,病根在版图数据或网表输入。
二、原因速查表
| 报错现象 | 可能原因 | 处置 |
|---|---|---|
| 一大批规则同时 already defined | 公共 deck 段被两个上层文件各 INCLUDE 一次 | 加 include guard 或收敛 INCLUDE 入口 |
| 只有自己加的 overlay 规则重复 | 自定义规则文件在 runset 与 deck 内被引用两次 | 去掉一处引用 |
| 规则同名但两份内容不同 | 两个 include 段各自声明了同名 rule | 改名或用 VARIABLE 开关隔离 |
| 换 PDK 版本后大面积重复 | 新旧两套 deck 路径被同时 INCLUDE | 只锚定一套 PDK 根目录 |
| GDS cell multiple versions | 流片数据里同名 cell 多版本,stream 拼接重复 | 回查数据源,只保留权威版本 |
| LVS subckt already defined | 同一网表片段被 SOURCE PATH 读两次 | 网表清单去重,查重复 include |
| layer mapped more than once | layer map 文件里同一层号映射了两个名字 | 改 map,每层唯一映射 |
| Warning 里的生效规则与预期相反 | 后定义覆盖先定义,加载顺序决定结果 | 展开 deck 看实际顺序再调整 |
三、排查决策树
读这张图抓住「先按名字分家」:红色入口是报错本身,蓝色判定只问一句——重复的名字是规则名还是数据名。规则名重复一定发生在 deck 展开层,去查 INCLUDE 结构;数据名重复发生在版图或网表读入层,去查输入数据本身。两条橙色修复线互不相干,混着查只会浪费时间;紫色收尾是统一复验动作。
四、逐条排查展开
第一步:grep 出重复的 INCLUDE,先看结构再看内容。 一大批规则同时报 already defined,几乎都是同一段公共 deck 被 INCLUDE 了两遍——上层工艺 deck INCLUDE 一次,你的 runset 或自定义 overlay 又 INCLUDE 一次。在 deck 根目录递归查文件名:
grep -rn "INCLUDE" . | grep -i "stack.svrf"同一文件出现两行以上命中,就是重复入口。SVRF 的 INCLUDE 是纯文本插入、没有自动去重,被插几次就解析几次。
第二步:给公共段加 include guard,或在入口处收敛。 最省事的修法是给被多处引用的公共段套条件编译开关,SVRF 支持 VARIABLE 配合 #ifndef/#endif 的守卫写法:
#ifndef COMMON_STACK_GUARD
#define COMMON_STACK_GUARD
VARIABLE COMMON_STACK_GUARD 1
... 原有规则 ...
#endif第二次 INCLUDE 时守卫已定义,整段跳过,规则只生效一次。改不了工艺厂交付文件时,就在自己的 runset 侧收敛:只保留一个 INCLUDE 入口,其余删掉。
第三步:展开 deck,核对实际加载序列。 Warning 明说「new definition will replace the previous one」,所以到底哪份规则生效取决于加载顺序,而不是你以为的顺序。把 runset 里 deck 展开(或直接顺着 INCLUDE 从顶层文件数下来),定位同名 rule 的两次声明:内容完全相同是冗余,删掉一处;内容不同是真冲突——两份规则在抢同一个名字,必须给其中一份改名,或用 VARIABLE 开关让两段按工艺/选项互斥生效,不能指望覆盖顺序碰巧正确。
第四步:GDS cell multiple versions 回查数据源,不要在 Calibre 里硬选。 这个 Warning 意味着流片数据里同名 cell 带进来两个不同版本(典型于多块版图 stream 拼接、交付包里混了旧版 GDS),Calibre 只是按读取顺序用最后一个。Calibre 侧没有「选版本」的开关,正确动作是回到版图数据:用流片工具列出该 cell 的来源文件,确认权威版本后重新导出单一 GDS/OASIS。带着这个 Warning 出 DRC 结果,等于在用一份你没核对过的版图签核。GDS/OASIS 数据交接背景见同系列总入口 开源 EDA 报错排错中心。
第五步:LVS 网表重复按「清单重复」和「片段重复」两种处理。 .SUBCKT/module 报 already defined,先在所有 SOURCE 输入里数这个名字:
grep -rn "^.SUBCKT PLL300M" ./netlists/命中两个文件,看是不是同一份网表被 SOURCE PATH(或网表自己的 include)收了两遍——这种删掉重复路径即可;两个文件内容不同,说明设计侧真的存在两份同名模块定义,要回数字侧消除,不是 LVS 环境能解决的问题。
第六步:layer map 每层保持唯一映射。 mapped more than once 直接看 layer map 文件里报错层号(如 31:0)的所有行,后出现的映射会覆盖先出现的,典型于在工艺厂 map 后面又追加了自己的 dummy 层定义却用了同层号。给自定义层换未占用层号,或删掉重复行。purpose(purpose 号,如 :0 drawing 与 :1 pin)也要一起核对:层号相同、purpose 不同本应是两条合法记录,先确认 map 里不是把同一对 layer/purpose 写了两遍,再决定改层号还是改 purpose。
一个容易误判的情形:多 PDK deck 混 source。 上述单类问题都排干净仍有零星重复,查 INCLUDE 链里是否同时挂了两套 PDK 根目录——例如老工程的绝对路径还指向上一版工艺目录,新变量又指向新版,两套 stack.svrf 各带一批同名规则。判据是展开序列里同一逻辑段出现两条不同绝对路径。处置不是逐条例外,而是全工程统一锚定一个 PDK_DIR,老路径整体废弃。
五、预防与纪律
- 公共 deck 段一律带守卫:工艺厂文件改不了,就在团队自有的所有公共段统一加
#ifndefinclude guard,新段照模板写。 - INCLUDE 只有一个入口:runset 只 INCLUDE 顶层 deck,自定义 overlay 挂在 deck 预留的开关上,不在 runset 里二次 INCLUDE 工艺公共文件。
- PDK 只锚定一套根目录:所有路径走同一个
PDK_DIR变量,禁止新旧两套 deck 目录同时出现在 INCLUDE 链里。 - 入站数据先做重名检查:GDS/OASIS 进 run 目录前列一次 cell 清单,网表拼接后过一道
grep .SUBCKT | sort -u对拍,把重复挡在 Calibre 启动之前。 - 干净目录复验:修完删掉本轮 run 目录重跑,确认 transcript 里 0 Error 且重复类 Warning 全部消失——Warning 被覆盖时结果静默错误,比报错更危险。
这一篇在知识体系里的位置
本篇是 EDA 排错速查簇的一员,总入口见 开源 EDA 报错排错中心;机制背景在 Calibre SVRF rule deck 解剖 与 Calibre 物理验证实操,语义对照阅读见数字综合侧的 Design Compiler 重复定义速查,反面「找不到定义」见 Calibre 模块/单元找不到。
一句话总结
Calibre 报「重复定义」先按名字分家:rule/VARIABLE 名重复是 deck 被 INCLUDE 多次,用 grep -rn INCLUDE 找重复入口、给公共段加 #ifndef 守卫、展开 deck 核对加载顺序;cell/subckt/layer 名重复是输入数据层问题,分别回查 GDS 多版本来源、网表清单去重、layer map 唯一映射;记住 Warning 级是后定义静默覆盖先定义,必须干净目录重跑到重复 Warning 全部消失,签核结果才可信。