第三章:DRC进阶——层次化检查、并行加速与Runset开发入门

各位同学,欢迎来到DRC进阶环节。说实话,很多工程师做了好几年物理验证,对DRC的理解还停留在“跑个命令、看个结果”的阶段。但真正遇到大芯片、复杂工艺时,那些基础操作根本不够用。今天我就把压箱底的东西掏出来,跟大家聊聊层次化DRC、并行加速,还有Runset开发的门道。

3.1 层次化DRC检查:为什么需要它?

先问大家一个问题:一个10亿晶体管的芯片,如果做扁平化DRC,需要多久?我见过最夸张的项目,跑了整整两周。你想想看,两周时间就为了等一个检查结果,项目进度早就黄了。

层次化DRC的核心思想很简单——重复利用。芯片里有很多重复的模块,比如SRAM、标准单元、DSP核。这些模块内部的结构完全一样,只是摆放位置不同。扁平化检查会把每个模块都重新算一遍,而层次化检查只算一次,然后复用结果。

层次化DRC的关键概念:

  • Cell(单元):设计的基本组成单位,比如一个AND门、一个触发器
  • Instance(实例):Cell在芯片中的具体摆放
  • Hierarchy(层次):Cell之间的包含关系,顶层调用底层
  • Abstraction(抽象):对底层Cell进行简化,只保留边界信息

我在项目中遇到过这样的情况:一个SoC芯片,顶层有200多个SRAM宏单元。扁平化跑DRC,每个SRAM都要重新检查一遍,光SRAM的检查就占了总时间的70%。后来改成层次化模式,只检查一个SRAM的“代表”,其他直接复用结果,整个流程从3天缩短到6小时。嗯,这就是层次化的威力。

3.2 层次化DRC的三种模式

根据我的经验,层次化DRC主要分三种模式,每种都有自己的适用场景:

模式 原理 适用场景 我踩过的坑
Flat模式 全部展开,无层次 小模块、顶层少量金属层 大芯片跑Flat,内存直接爆掉
Hierarchical模式 保留层次,逐级检查 标准单元库、SRAM编译器 层次边界容易漏检
In-Place模式 在原有层次上增量检查 ECO修改、局部改动 增量结果有时不准,需要全量验证

我个人习惯是:前期用Hierarchical模式快速迭代,最终签核时用Flat模式兜底。为什么?因为层次化模式在Cell边界处可能会漏掉一些跨层次的违例,比如两个不同Cell之间的间距问题。Flat模式虽然慢,但最保险。

注意:层次化DRC不是万能的。我曾经在一个项目里,因为底层Cell的抽象做得太粗糙,导致顶层金属线穿过Cell内部时,跟内部走线产生了短路,但层次化检查根本没报出来。那次教训让我养成了一个习惯——每次做层次化抽象后,一定要跑一个“边界完整性检查”。

3.3 并行DRC加速技术

说完了层次化,咱们聊聊并行加速。现在的芯片动辄几百平方毫米,单核跑DRC简直是折磨。并行加速说白了就是把一个大任务拆成多个小任务,同时跑。

主流工具(Calibre、ICV、PVS)都支持并行,但实现方式不太一样:

  • Calibre:使用-nthreads参数,支持多线程并行。我一般设成物理核数的80%,留点余量给系统
  • ICV:通过-distributed选项,支持分布式并行,可以跨多台机器
  • PVS:使用-q选项,支持队列式并行,适合集群环境

这里有个坑要提醒大家:并行不是线程越多越快。我见过有人把-nthreads设成64,结果因为内存带宽瓶颈,速度反而比32线程还慢。你想想看,每个线程都要读写同一块数据,CPU都在等内存,那不就白搭了吗?

我的经验值:

  • 小模块(< 100万门):4-8线程就够了
  • 中等模块(100万-1000万门):16-32线程
  • 大芯片(> 1000万门):32-64线程,配合分布式

另外,记得把DRC区域拆分成多个小块,每个块独立检查,最后合并结果。这叫“空间分区”,比单纯加线程有效得多。

3.4 DRC Runset开发入门

好,接下来是重头戏——Runset开发。说白了,Runset就是告诉DRC工具“你要检查什么”的规则文件。大部分工程师只会用现成的Runset,但如果你想做定制化检查、或者开发新的工艺节点,就必须自己写。

Runset主要用两种语言:SVRF(Standard Verification Rule Format)和TCL(Tool Command Language)。Calibre用SVRF,ICV和PVS更偏向TCL。但说实话,现在很多工具都支持混合编程了。

3.5 SVRF语法基础

SVRF的语法其实不复杂,核心就几个概念:

// SVRF基本结构
LAYOUT PATH "design.gds"   // 指定输入版图
PRIMARY "top"              // 指定顶层cell

// 定义层次
HIERARCHY SEPARATOR "/"

// 定义层
LAYER M1 10                // 金属1层,GDS编号10
LAYER V1 11                // 通孔1层,GDS编号11
LAYER M2 12                // 金属2层,GDS编号12

// 规则检查:M1最小宽度
M1_WIDTH = INT M1          // 提取M1的内边
M1_WIDTH_ERROR = M1_WIDTH < 0.1  // 宽度小于0.1um报错

// 输出结果
OUTPUT M1_WIDTH_ERROR "M1 minimum width violation"

我个人习惯把Runset分成三个部分:定义区(层定义、参数定义)、检查区(各种DRC规则)、输出区(错误报告格式)。这样结构清晰,后期维护也方便。

SVRF常用操作符:

  • INT:提取内边(用于检查宽度)
  • EXT:提取外边(用于检查间距)
  • AND:逻辑与(两个层重叠的部分)
  • OR:逻辑或(两个层合并)
  • NOT:逻辑非(减去某个层)
  • GROW:扩张(把图形扩大一定尺寸)
  • SHRINK:收缩(把图形缩小一定尺寸)

3.6 TCL在DRC中的应用

TCL比SVRF更灵活,可以做条件判断、循环、变量运算。ICV和PVS的Runset大量使用TCL。来看个例子:

# TCL风格的DRC规则
set min_width 0.1
set min_space 0.12

# 定义层
define_layer M1 10
define_layer V1 11

# 检查M1宽度
set m1_width [int M1]
set m1_width_error [filter $m1_width {value < $min_width}]
report_error $m1_width_error "M1 width < ${min_width}um"

# 检查M1间距
set m1_space [ext M1]
set m1_space_error [filter $m1_space {value < $min_space}]
report_error $m1_space_error "M1 space < ${min_space}um"

你看,TCL可以用变量$min_width,改规则时只需要改一个地方。SVRF虽然也能用变量,但TCL的变量处理更强大,支持数组、字典、甚至正则表达式。

我的建议:如果你是新手,先从SVRF入手,因为它的语法更直观,跟版图操作的对应关系更清晰。等你把SVRF玩熟了,再学TCL的灵活用法。我自己就是先啃了两年SVRF,后来才转TCL的。

3.7 一个完整的DRC Runset示例

咱们写一个简单的金属层间距检查Runset,把刚才学的知识串起来:

// 金属间距检查 - 完整示例
LAYOUT PATH "test.gds"
PRIMARY "top"
HIERARCHY SEPARATOR "/"

// 层定义
LAYER M1 10
LAYER M2 12
LAYER V1 11

// 参数定义
MIN_M1_WIDTH = 0.1
MIN_M1_SPACE = 0.12
MIN_M2_WIDTH = 0.1
MIN_M2_SPACE = 0.14
MIN_V1_SIZE = 0.08

// M1宽度检查
M1_INT = INT M1
M1_WIDTH_ERR = M1_INT < MIN_M1_WIDTH
OUTPUT M1_WIDTH_ERR "M1 width violation: less than 0.1um"

// M1间距检查
M1_EXT = EXT M1
M1_SPACE_ERR = M1_EXT < MIN_M1_SPACE
OUTPUT M1_SPACE_ERR "M1 space violation: less than 0.12um"

// V1覆盖检查(通孔必须被上下金属完全覆盖)
V1_COVER = V1 NOT (M1 GROW 0.02)
V1_COVER_ERR = V1_COVER NOT (M2 GROW 0.02)
OUTPUT V1_COVER_ERR "V1 not fully covered by M1 and M2"

这个例子虽然简单,但包含了Runset的核心要素:层定义、参数化、几何操作、条件判断、结果输出。你把这个框架掌握了,写复杂的Runset就是往上堆规则而已。

避坑指南:我曾经写过一个Runset,里面有个规则用了GROW 0.1,但没注意单位是微米还是纳米。结果在0.18um工艺上跑出来一堆假错,排查了两天才发现是单位问题。所以,写Runset时一定要确认单位,最好在文件头部加注释说明。

3.8 知识体系总览

为了让大家更直观地理解本章的知识结构,我画了一张图:

DRC进阶知识体系 层次化DRC检查 • Cell/Instance概念 • 层次抽象原理 • 三种模式对比 • 边界完整性检查 • 复用与增量检查 • 内存优化技巧 并行DRC加速 • 多线程并行 • 分布式并行 • 空间分区技术 • 线程数优化 • 内存带宽考量 • 结果合并策略 Runset开发入门 • SVRF语法基础 • TCL灵活编程 • 层定义与操作 • 几何运算函数 • 条件判断与循环 • 结果输出格式 三者结合:层次化减少数据量 + 并行加速计算 + Runset定制规则

这张图把本章的三个核心模块串起来了。你想想看,层次化DRC解决的是“数据太多”的问题,并行加速解决的是“算得太慢”的问题,Runset开发解决的是“规则定制”的问题。三者结合,才能应对现代芯片的物理验证挑战。

好了,这一章的内容就到这儿。DRC进阶不是一蹴而就的,我做了十五年,每次遇到新工艺、新工具,还是能学到新东西。希望大家把基础打牢,多动手写Runset,多尝试不同的并行策略。遇到问题别怕,每个坑都是成长的台阶。

可可精品资料库