3. 规则文件骨架与执行顺序
一个可维护的 Calibre nmDRC 规则文件,不是把若干 DRC 检查语句堆在一起,而是有明确骨架的“程序”。骨架决定了单位与精度如何统一、版图层如何命名、变量如何参数化、条件编译如何裁剪、include 如何组织文件,以及规则按什么顺序执行。理解这些机制,才能在调试时快速定位“为什么这条规则没跑”“为什么结果和预期差一个数量级”。
一、单位与精度:所有数值的基准
Calibre 规则文件中最先要确定的不是规则本身,而是 LAYOUT PATH、LAYOUT PRIMARY、LAYOUT SYSTEM 以及单位与精度设置。版图数据库通常以 GDSII 或 OASIS 存储,其内部坐标是整数数据库单位(DBU)。规则文件中的 LAYOUT SYSTEM GDSII 配合 LAYOUT PATH 指定输入,而 PRECISION 决定 Calibre 在内部把用户单位换算成数据库单位时的精度。
关键关系是:用户单位(如微米)→ 数据库单位(DBU)→ 规则中的数值。例如 PRECISION 1000 表示 1 微米 = 1000 个数据库单位,即 1 DBU = 1 nm。若版图实际以 0.001 微米为网格,而规则里写 PRECISION 100,则 1 DBU = 10 nm,规则中的 0.1 微米会被解释为 10 个 DBU,与版图网格不一致,导致间距判断出现系统性偏差。因此,PRECISION 必须与版图数据实际精度匹配,且全文所有尺寸、间距、面积、角度都基于同一精度体系。
PRECISION 与版图 DBU 是否一致,而不是逐条改规则。二、布局层定义:把工艺层映射为可引用的名字
版图数据中的层是“层号 + 数据类型”(如 1/0、2/0),而规则中需要的是可读的名字。Calibre 用 LAYER 语句建立映射:
LAYER METAL1 1
LAYER METAL1_PIN 1 2
LAYER VIA1 2
LAYER POLY 3
LAYER NWELL 4
其中 LAYER METAL1 1 表示层号 1、数据类型 0;LAYER METAL1_PIN 1 2 表示层号 1、数据类型 2。定义之后,后续规则统一使用 METAL1、VIA1 等名字,而不是直接写数字。这样做的好处是:工艺层号变化时只改定义处,规则主体不动。此外,还可以用 LAYER 的派生形式定义组合层,例如 LAYER M1_ALL = METAL1 OR METAL1_PIN,把同一物理层的不同数据类型合并,避免规则中反复写 OR。
三、变量与条件编译:让规则可参数化、可裁剪
变量用 VARIABLE 定义,例如:
VARIABLE M1_MIN_WIDTH 0.10
VARIABLE M1_MIN_SPACE 0.10
VARIABLE VIA1_MIN_SIZE 0.10
VARIABLE CHECK_M1_PIN YES
规则中直接引用变量名,如 INTERNAL METAL1 < M1_MIN_WIDTH。变量使同一套规则可以适配不同工艺节点或不同产品要求,只需在文件头部或通过命令行覆盖变量值。条件编译用 #IFDEF / #IFNDEF / #ELSE / #ENDIF 实现,例如:
#IFDEF CHECK_M1_PIN
DRC CHECK METAL1_PIN ...
#ENDIF
条件编译在规则解析阶段生效,未满足条件的语句不会进入执行队列。它常用于区分不同金属层数、不同封装形式或不同测试模式,避免为每个变体维护独立文件。
四、include 机制:文件组织与作用域
大型规则文件通常拆分为多个 .inc 文件,用 INCLUDE 引入:
INCLUDE "layers.inc"
INCLUDE "variables.inc"
INCLUDE "metal_rules.inc"
INCLUDE "via_rules.inc"
include 是文本级展开,被包含文件的内容在当前位置插入。因此顺序很重要:layers.inc 必须在引用层的规则之前,variables.inc 必须在引用变量的规则之前。若被包含文件重复定义同名层或变量,后定义会覆盖先定义,可能造成难以察觉的错误。建议每个 include 文件只负责一类内容,并在文件头注释其依赖。
五、规则执行顺序:从解析到运行
Calibre 处理规则文件分为两个阶段:解析阶段和执行阶段。解析阶段完成 include 展开、变量替换、条件编译裁剪、层定义建立;执行阶段按规则在文件中的出现顺序依次执行 DRC 检查。规则之间的顺序会影响结果,尤其是当后续规则引用前面规则产生的派生层时。
例如,先定义 LAYER M1_ALL = METAL1 OR METAL1_PIN,再写 INTERNAL M1_ALL < M1_MIN_WIDTH,顺序正确;若反过来,M1_ALL 尚未定义,规则会报错或产生空结果。此外,DRC RESULTS DATABASE、DRC SUMMARY REPORT 等输出语句通常放在规则末尾,确保所有检查结果都被收集。
六、骨架顺序对结果的影响:一个可复现的示例
假设我们要检查 METAL1 最小宽度 0.10 微米、最小间距 0.10 微米,并统计 METAL1 与 METAL1_PIN 合并后的总图形数。一个正确的骨架顺序如下:
LAYOUT PATH "chip.gds"
LAYOUT PRIMARY "top"
LAYOUT SYSTEM GDSII
PRECISION 1000
LAYER METAL1 1
LAYER METAL1_PIN 1 2
LAYER M1_ALL = METAL1 OR METAL1_PIN
VARIABLE M1_MIN_WIDTH 0.10
VARIABLE M1_MIN_SPACE 0.10
#IFDEF CHECK_M1
INTERNAL METAL1 < M1_MIN_WIDTH
EXTERNAL METAL1 < M1_MIN_SPACE
#ENDIF
DRC RESULTS DATABASE "drc_results.db" ASCII
DRC SUMMARY REPORT "drc_summary.rpt"
如果把 LAYER M1_ALL 放到 INTERNAL 之后,或者把 PRECISION 写成 100,结果都会偏离预期。调试时可以用 -drc 选项运行并查看 summary report 中的规则条数和错误数,若某条规则未出现在报告中,说明它被条件编译裁掉或解析阶段出错。
七、调试检查清单
- 确认
PRECISION与版图 DBU 一致,全文单位统一。 - 确认所有
LAYER定义在引用之前,派生层先定义后使用。 - 确认
VARIABLE在规则引用前已定义,且未被后续 include 覆盖。 - 确认
#IFDEF条件与命令行变量一致,避免规则被意外裁剪。 - 确认
INCLUDE顺序满足依赖,输出语句位于规则末尾。 - 运行后检查 summary report 中规则条数与预期是否一致。
掌握骨架与执行顺序后,后续编写具体 DRC 规则时,就能把精力集中在规则逻辑本身,而不是被单位、层名、变量或文件顺序问题反复干扰。