ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

LEF/DEF 5.8 精读:抽象边界、实例快照与回读排错

LEF/DEF 5.8 精读:抽象边界、实例快照与回读排错

简介:《LEF/DEF 5.8 Language Reference》是 Cadence 官方发布的 LEF 与 DEF 集成电路描述语言参考手册,面向 IC 物理设计、EDA 工具开发及版图验证相关工程师与高年级学生,用于厘清工艺技术定义、单元模型库与设计布局布线信息在工具间的交换规范。手册系统说明 LEF 对金属层、多晶硅层、接触层等工艺层及电气特性、单元几何尺寸、间距规则、填充隔离区域和宏模型的描述方式,也覆盖 DEF 中的模块位置与方向、网络连接、DRC/LVS/ERC 约束、物理分区和电源地等物理属性。压缩包仅含 1 个 PDF 文件,大小约 2.48MB,便于随查随用。已有 2177 人学习,适合在物理综合、布局规划和验证阶段对照查阅;5.8 版发布于 2017 年,对约束管理、物理描述精度及先进工艺节点支持有所更新,可帮助读者理解 LEF/DEF 语法细节与跨工具流程的一致性要求。

1. 被误读的 LEF/DEF:两套语言其实是同一份物理事实的两次投影

多数人第一次翻开这份 LEF/DEF 5.8 语言参考,是带着“查语法”的目的:LAYER 有哪些字段、MACRO 怎么写、COMPONENTS 的坐标用什么单位。查完就以为懂了——LEF 是单元库,DEF 是设计数据,EDA 工具读进去,布局布线跑起来。可真正卡住流程的,往往不是某个关键字拼错,而是没意识到这两套语言在设计之初就做了一次刻意的信息切割:LEF 只回答“什么东西可以被摆、摆的时候要守什么规矩”,DEF 只回答“这一次具体摆成了什么样”。前者是抽象层,后者是实例层,边界画在哪里,决定了工具能做什么、debug 时该翻哪一侧。搞懂这条边界,比背完全部语法有用得多。

2. LEF 的抽象边界:工艺和单元是怎么被削成布线器吃得下的形状

LEF 的原始动机很朴素:版图数据太完整了。一个标准单元在完整版图里是上千个多边形,布线器其实只关心三件事——这个单元占多大矩形、它的引脚落在哪个可连接的矩形里、它内部哪些区域不能穿线。把这三件事抽出来,剩下的全部砍掉,就得到了 Macro。工艺信息同理:制造工艺真正能被布线算法消费的,是每层的方向、线宽、间距、厚度和单位长度的电阻电容,于是有了 Layer (Routing)。

这种“够用即止”的抽象不是偷懒,而是性能约束下的必然。一个百万实例的设计,如果每个实例都带上完整几何,任何工具都吃不下。LEF 的设计哲学用一句话概括就是:把版图压缩成布线器需要的最少信息,且保证压缩过程可逆到“能回读验证”的程度。

2.1 从完整版图到 Macro:被砍掉的是什么,被留下的是什么

看一个标准单元在 LEF 里的典型写法:

MACRO NAND2X1 CLASS CORE ; ORIGIN 0 0 ; FOREIGN NAND2X1 0 0 ; SIZE 1.38 BY 2.72 ; SYMMETRY X Y ; SITE core_site ; PIN A DIRECTION INPUT ; USE SIGNAL ; PORT LAYER M1 ; RECT 0.205 1.005 0.375 1.175 ; END END A OBS LAYER M1 ; RECT 0.585 0.205 1.175 2.515 ; END END NAND2X1

这段里每一个字段都在回答布线器的一个具体问题。SIZE是外形包络,布局器用它算面积、做合法性检查;SITE声明这个单元只能坐在哪种 row 上;SYMMETRY X Y告诉摆放器它可以沿 X 或 Y 轴镜像,镜像后引脚位置由工具自己算;PIN下的PORT是引脚的可连接几何,布线器只认这块矩形,其他区域即使电气上连着也进不去;OBS是内部障碍,布线器必须绕开,但完全不需要知道里面是晶体管还是电阻。

CLASS CORE和FOREIGN这两个字段经常被忽略。CLASS决定工具把这个 Macro 当什么用——CORE 是标准单元,BLOCK 是硬宏,PAD 是 IO,RING 是环。一个硬宏被误标成 CORE,布局器会尝试把它塞进标准单元 row,结果就是摆放阶段直接失败。FOREIGN记录的是完整版图里的原始引用名,做 LEF 与版图交叉验证(LVS 前的一致性检查)时靠它对齐。

这里有一条血泪经验:OBS的矩形集合如果写漏了一块,布线器就敢从那里穿过去,最后 DRC 报出一堆短路,而你在 LEF 里翻半天也看不出问题,因为语法完全合法。抽象层丢信息的代价不是报错,是沉默。

2.2 Site 与 Row 的咬合:名字错一个字符,legalization 就会失败

Site 是 LEF 里最不起眼、却最容易让流程失败的定义:

SITE core_site CLASS CORE ; SYMMETRY Y ; SIZE 1.38 BY 2.72 ; END core_site

Site 定义的是一个“座位”的宽度、高度和对称性。DEF 里的ROW就是按某个 Site 沿 X 方向铺出来的一排座位。Macro 的SITE字段必须和 Row 引用的 Site 同名、同尺寸,否则摆放器会认为这个单元无处安放。

失败时的现象很有欺骗性:报错通常不会写“site mismatch”,而是走到更下游的 legalization 阶段才炸,提示类似“cannot legalize instance”。这就是黑匣子感的来源——错误在 A 处埋下,在 C 处爆发。我一般会这么自查:先grep出 DEF 里所有ROW用到的 Site 名,再去 LEF 里逐个确认是否存在、尺寸是否与 Macro 的SIZE成整数倍关系。单元高度不是 Site 高度整数倍的 Macro,即使名字对上了,也放不整齐。

2.3 Units 与 DBU:这个数据库里没有浮点数这回事

LEF 的UNITS段是整个体系的度量地基:

UNITS TIME NANOSECONDS 1 ; CAPACITANCE PICOFARADS 1 ; RESISTANCE OHMS 1 ; DATABASE MICRONS 1000 ; MANUFACTURINGGRID 0.005 ; END UNITS

DATABASE MICRONS 1000的意思是 1 微米等于 1000 个数据库单位(DBU)。此后文件里所有坐标、线宽、间距全部写成整数。MANUFACTURINGGRID 0.005表示工艺能制造出来的最小步进是 5 纳米。

这两个数是完全不同的东西,混淆它们是最经典的翻车方式。DBU 是“数据库能表达的精度”,Manufacturing Grid 是“工艺能造出来的精度”。一个坐标是 DBU 的整数倍,只说明它能被存储;只有当它同时是 Manufacturing Grid 的整数倍,才说明它能被造出来。布线器在收尾阶段会做一次坐标对齐,把落在 grid 外的点吸附到最近的合法位置,这个动作会改变线长,进而改变时序——所以有些人发现自己时序结果和预期对不上,追到最后发现是 grid 吸附吃掉了余量。

为什么坚决不用浮点?因为一个百万级实例的设计,坐标要做上亿次加法和相等比较。浮点累加会漂移,两个本该相等的坐标会差 1e-15,合法性检查就判不出来重叠;而整数运算下,重叠判断就是四次大小比较。这是一次用表达能力换确定性的取舍,代价是你必须自己管理精度。

提示:LEF 和 DEF 各有一份UNITS,回读时必须兼容。LEF 写 1000、DEF 写 2000,工具不会报错,而是把所有坐标按比例缩放,结果就是整个设计看起来“整体偏了一点”,非常难查。

2.4 Nondefault Rule 与 Via Rule:把规则从常量变成变量

每层的默认布线规则只有一组WIDTH和SPACING。但真实设计里总有一部分网络要走宽线、双倍间距或者被屏蔽线包住,于是有了 Nondefault Rule:

NONDEFAULTRULE Wide2x LAYER M1 WIDTH 0.28 SPACING 0.28 ; LAYER M2 WIDTH 0.28 SPACING 0.28 ; VIA V12 DEFAULT ; END Wide2x

定义好之后,DEF 里的网络用+ NONDEFAULTRULE Wide2x引用它,布线器就会按这套加宽的规则走这根线。关键点在于:规则是挂在网络上的,不是挂在层上的。同一个 M2 层,普通信号走默认间距,时钟和电源走加宽间距,两者共存。

Via Rule Generate 是同一思路的延伸。一个 via 阵列理论上要枚举每一个 cut 的位置,但工艺上它是有规律的,于是用一条规则描述“cut 从哪开始、间距多少、重复几次”,让工具自己生成。这样 LEF 文件体积能小一到两个数量级,对几十层金属的先进工艺来说这不是优化,是必须。

3. DEF 的实例快照:布局布线结果为什么必须写成能被原样读回的清单

LEF 描述的是“可能性空间”,DEF 描述的是“这一次的选择”。这两者的关系不是上下游,而是投影:同一个 LEF 库,可以投影出无数个 DEF。理解 DEF 的关键在于它必须满足一个硬性要求——工具 A 写出来的 DEF,工具 B 读进去之后,物理状态必须完全一致。这不是文档里的措辞,是整个格式设计的目标函数。

所以 DEF 里的每一项都必须是“事实”而不是“建议”。PLACED意味着这个坐标是确定的,回读时就摆在这里;ROUTED意味着这条线的拓扑是确定的,回读时不能重新走。一旦某个字段带上了“工具可以自由发挥”的语义,跨工具的一致性就断了。

3.1 Components 与 Rows:位置是事实,方向是位运算

COMPONENTS 3 ; - u_core/u_alu/U12 NAND2X1 + PLACED ( 13800 27200 ) N ; - u_core/u_alu/U13 NAND2X1 + FIXED ( 15180 27200 ) FS ; - u_core/u_alu/U14 BUFX2 + UNPLACED ; END COMPONENTS

每行的结构是:实例名、引用的 Macro 名、摆放状态、坐标、方向。坐标是 DBU 整数,这里 13800 在 DBU=1000 时等于 13.8 微米。方向有八个取值:N/S/E/W 是四个基本朝向,FN/FS/FE/FW 是在对应朝向上再镜像一次。

这八个方向不是随意枚举的,它对应的是坐标变换的组合:先绕原点旋转 0/90/180/270 度,再决定是否沿 Y 轴翻转。工具内部通常用三个比特表示,摆放合法性检查和引脚位置计算都靠这三位做查表。这也解释了一个常见困惑:为什么手动改 DEF 里的方向字母,引脚位置会突然跑到单元外面去——因为引脚的相对坐标要经过这套变换,方向改错,几何就飞了。

PLACED和FIXED的区别经常被误用。PLACED是可动的,优化阶段工具可以挪;FIXED是不可动的,任何阶段都不许碰。把本该 FIXED 的宏写成 PLACED,优化器会好心地把你的模拟 IP 挪到别处,最后时序和信号完整性一起崩。反过来,把大量标准单元写成 FIXED,优化空间被锁死,收敛时间翻倍。

3.2 Nets 与 Special Nets:为什么电源和信号要两套语法

信号网络用NETS,走线写成 routing point 序列:

NETS 1 ; - clk_core ( u_core/U12 A ) ( u_core/U13 A ) + ROUTED M2 ( 12000 27000 ) ( 12000 30000 ) NEW M3 ( 12000 30000 ) ( 15000 30000 ) ; END NETS

电源和地网络用SPECIALNETS:

SPECIALNETS 1 ; - VDD ( * VDD ) + USE POWER + ROUTED M5 2000 ( 0 0 ) ( 0 50000 ) ( 100000 50000 ) NEW M5 2000 ( 100000 0 ) ( 100000 50000 ) ; END SPECIALNETS

分开的原因不是历史包袱,而是优化目标根本不同。信号线追求时序、串扰、拥塞的平衡,拓扑是点对点的;电源网络是一棵从 pad 出发、覆盖全芯片的树,追求的是 IR drop 和电迁移裕量,规则上要求宽线、多 via 并联、甚至用SHIELD包一层屏蔽。把两者塞进同一套语法,工具在解析阶段就得先分类,反而更慢。

SPECIALNETS支持POLYGON和RECT这类面状几何,是因为电源环和电源条带本来就是面,不是线。NEW关键字表示开始一条新的 path,同一个网络下可以有多条不连通的 path,工具靠这个区分树的不同分支。

3.3 Pins、Blockages、Tracks、Regions:约束的四种载体

PINS是顶层端口在物理世界的落地:DIRECTION说明输入输出,USE说明是信号还是电源,PORT下挂LAYER和形状。一个常见的错误是把PINS当成纯逻辑信息,只写名字不写几何,结果顶层布线器找不到可连接的位置,只能报“pin not accessible”。

BLOCKAGES分两类:placement blockage 是“这块区域不许放单元”,routing blockage 是“这块区域不许走线”。两者的作用域完全不同,混用会导致优化器在一个本该留空的区域里塞满单元。

TRACKS是布线器的车道定义,形如TRACKS M1 0 DO 100 STEP 1 ;,含义是从坐标 0 开始,每隔 1 个 DBU 画一条,共 100 条。布线器的所有走线中心必须落在 track 上,track 的间距和偏移直接决定了可布线资源。把 track 偏移写错,布线器会报告大量 off-track 违规,而语法完全合法。

REGIONS是物理区域,GROUPS是把一组实例绑到某个区域上。这两个是布局规划阶段的产物,用来约束模块的相对位置。

3.4 Scan Chains:测试拓扑为什么也进了物理文件

SCANCHAINS 1 ; - chain1 + START u_core/U1 ( OUT ) + ORDERED u_core/U2 ( IN ) ( OUT ) + ORDERED u_core/U3 ( IN ) ( OUT ) + STOP u_core/U4 ( IN ) ; END SCANCHAINS

扫描链的段结构是START、FLOATING、ORDERED、STOP。这是一条逻辑链在物理世界里的顺序声明。放在 DEF 里而不是网表里,是因为链的物理顺序会直接影响布线长度和测试功耗——链走得越绕,测试时的翻转功耗越大。DFT 工具和物理实现工具需要共享同一份顺序事实,DEF 就是那个交汇点。

4. 语法层的隐形契约:语句顺序、ALIAS 和 Extensions 为什么不能随便改

语法参考里有一类内容特别容易被跳过:语句顺序、字符约定、扩展块。它们看起来是“写法规范”,实际上是解析器的实现约束外显出来的结果。不理解这一层,写出来的文件可能语法全对、语义全错。

4.1 顺序敏感:单遍流式解析器的代价

LEF 的合法顺序大致是:VERSION→UNITS→LAYER→VIA→SITE→MACRO。DEF 的顺序是:VERSION→UNITS→DESIGN→DIEAREA→ROWS→TRACKS→BLOCKAGES→COMPONENTS→PINS→NETS→SPECIALNETS。

这个顺序不是审美选择,是单遍解析的必然。解析器从文件头读到文件尾,读到MACRO里引用某个SITE时,那个SITE必须已经在内存里了;读到COMPONENTS里引用某个MACRO时,LEF 必须已经加载完。为了处理动辄几个 GB 的文件,解析器不会把整个文件建成语法树再二次遍历,而是边读边建对象,读完就释放文本。这就锁死了顺序。

顺序颠倒的后果很微妙。把COMPONENTS放到ROWS前面,语法上每一条都合法,但解析器在处理COMPONENTS时还不知道 row 的分布,legalization 的信息就缺失了;有些工具会缓存下来延后处理,有些工具直接按“无 row”处理,结果就是所有单元被判定为非法位置。

我一般会这么理解:语句顺序是这份格式暴露给使用者的“内存布局”。想改顺序,等于要求解析器做两遍扫描,性能代价没人愿意付。

4.2 ALIAS 与 Extensions:扩展性的两条正交路径

ALIAS是文本级的宏替换:

ALIAS myMetal M3 ; # 此后文件里出现 myMetal,等价于 M3

它在词法阶段就展开,纯粹是书写便利,不产生任何语义。用它的场景通常是工艺层名很长、或者同一份 LEF 要在多个命名习惯不同的团队间流转。

Extensions是完全不同的一条路:

BEGINEXT "vendorA 1.0" VENDOROPTION 42 ; VENDORFLAG TRUE ; ENDEXT

BEGINEXT和ENDEXT之间可以放任意非标准语句。规范要求:不认识的工具必须整块跳过,认识的工具可以解析并保留。这就形成了一个“合法的私有通道”——工具可以把自家特有的信息写进 DEF,其他工具读进来再写出去,这些块原样保留。

为什么不用注释实现同样的目的?因为注释在解析时就被丢弃了,往返一次信息就没了。扩展块的设计目标恰恰是“往返保真”,这是它能承载工具间私有约定的根本原因。

注意:扩展块里的内容一旦被某个工具丢弃,下游工具就可能读到不完整的状态。跨工具链排查诡异问题时,先确认扩展块有没有在某一环被吞掉。

4.3 Bus Bit Characters 与 Divider Character:名字里也有语法

BUSBITCHARS [ ] ; DIVIDERCHAR "/" ;

BUSBITCHARS声明总线索引用什么括号包裹,DIVIDERCHAR声明层次分隔符。这两条语句决定了data[0]、u_core/u_alu/U12这种名字怎么被切成基础名和索引、怎么被切成层次路径。

它们之所以在文件头就要声明,是因为解析器需要在读名字之前就知道切分规则,否则遇到a[0]无法判断这是总线第一位还是一个名叫a[0]的普通标识符。如果设计里的命名习惯和文件头声明不一致,现象是总线被拆错、或者层次路径匹配不上,报错信息往往只说“instance not found”,很难联想到是字符约定。

4.4 Clearance Measure 与 FIXEDMASK:判定基准和掩膜锁定

CLEARANCE MEASURE决定间距的计算方式。EUCLIDEAN表示按两点间欧氏距离算,MAXXY表示按 X、Y 投影距离的最大值算。同一个几何布局,两种基准下 DRC 结论可能不同。这在斜线走线和 45 度角区域尤其明显——欧氏距离会给出更严格的约束。

FIXEDMASK表示某个 shape 的掩膜是固定的,工具不能自行分配。这在多重曝光工艺下很关键:多个 shape 共享同一掩膜时,必须显式声明,否则工具会按自己的算法分配,导致制造端对不上。

5. 排查清单:LEF/DEF 回读时最容易翻车的五个地方

这一章记录的是实际调试中最常见的五类问题。它们的共同特征是:语法检查全过,工具也能跑,但结果就是不对。

5.1 五条踩坑记录

一、整体偏移:所有单元都往同一个方向错了一点

现象:回读后打开版图,所有单元整齐地偏移了一个固定距离,布局看起来完全正常,只是位置不对。

原因:LEF 和 DEF 的UNITS不一致。LEF 声明DATABASE MICRONS 1000,DEF 声明 2000,工具在合并两份数据时按比例换算坐标,产生整体缩放或偏移。因为偏移是线性的,视觉上察觉不到“错”,只会觉得“和预期不一样”。

解决:把两份文件的UNITS打印出来逐字段比对,尤其是DATABASE MICRONS和MANUFACTURINGGRID。跨工具流转时,统一由一端生成、另一端只读,不要各写各的。

二、off-grid 违规刷屏:布线器抱怨坐标不在格点上

现象:布线阶段报告大量 off-track 或 off-grid 违规,但检查 DEF 里的坐标,看起来都是整数。

原因:坐标是 DBU 整数,但不是MANUFACTURINGGRID的整数倍。比如 DBU 是 1 纳米、grid 是 5 纳米,坐标 13803 在数据库里合法,在工艺上非法。

解决:在写 DEF 之前做一次全局对齐,把所有坐标吸附到 grid 的整数倍。注意对齐会改变线长,时序结果需要重跑,不能只改文件不复核。

三、legalization 失败:单元放不进 row

现象:布局阶段报“cannot legalize”,日志里没有更多信息。

原因:三种可能——Macro 的SITE名和ROW用的 Site 名不一致;Macro 高度不是 Site 高度的整数倍;ROW的起始坐标不是 Site 宽度的整数倍。

解决:按“Site 名 → Macro 尺寸 → Row 起点”的顺序逐项核对。最省事的做法是写一段脚本,把所有 Macro 的SIZE对 Site 尺寸取模,非零的直接列出来。

四、总线名错位:网络连到了错误的位上

现象:LVS 报出大量不匹配,检查发现data[3]连到了data[5]。

原因:BUSBITCHARS声明的括号和设计里实际使用的字符不一致,解析器切分索引时错位。也可能是DIVIDERCHAR与网表里的层次分隔符不同,导致同名不同路径的实例被合并。

解决:在文件头统一声明字符约定,并确保网表导出、DEF 生成、后端读取三个环节用的是同一套约定。

五、Nondefault Rule 不生效:加宽规则形同虚设

现象:明明定义了宽线规则,电源网络还是按默认宽度走。

原因:规则名拼写不一致,或者网络定义里漏了+ NONDEFAULTRULE引用。另一种情况是规则定义在NETS之后,虽然语法合法,但部分工具在单遍解析时拿不到。

解决:先确认规则定义在NETS之前,再确认每个网络的引用字符串与定义完全一致(包括大小写),最后从布线结果的线宽反查是否真的应用了规则。

5.2 一套可复用的自检流程

把上面五类问题串起来,能形成一条固定的检查顺序,我一般按这个走:先比对两份文件的UNITS和MANUFACTURINGGRID,这是所有几何问题的基础;再核对SITE与MACRO的尺寸咬合,这决定布局能否收敛;然后检查字符约定,这决定名字解析是否正确;最后验证规则的引用链是否完整。

这个顺序的道理是从“全局几何”到“局部几何”再到“命名”最后到“语义规则”,前面错了后面全是噪声。跳过前两步直接查布线问题,通常会在一堆无关报错里迷失。

6. 写在规范背后的取舍:LEF 写松还是写紧,天线效应怎么算这笔账

规范的最后一部分专门讨论怎么为布局布线优化 LEF 工艺文件,这一节的标题里藏着一个很少被点破的事实:LEF 不是“描述工艺”,而是“为布线算法调参”。同一个工艺,可以写出宽严不同的 LEF,收敛速度和最终质量会差出一大截。

几个关键取舍点。Routing Pitch 决定可布线资源的密度,pitch 写得比工艺允许的更紧,布线器会尝试走更密的线,拥塞缓解但串扰风险上升;写得松,时序干净但面积浪费。Wide Metal Spacing 处理宽线相邻的间距规则,工艺上宽线需要更大间距,如果在 LEF 里直接给一个保守值,布线器会绕得很远,正确做法是用 Nondefault Rule 分层描述。Wire Extension at Vias 和 Default Vias 影响的是 via 附近的几何余量,余量给足能减少后仿真的意外,代价是面积。

Straight Vias Stack(同一网络上下层 via 叠放)与 Samenet Spacing 是一组典型的权衡:允许叠放能节省面积,但增加了制造风险和寄生耦合;禁止叠放则面积膨胀。

参数写紧的后果写松的后果
Routing Pitch拥塞缓解,串扰风险上升时序干净,面积浪费
Wide Metal Spacing绕线变长,DRC 通过率高面积节省,短路风险上升
Via 处线延伸面积增加,后仿稳定面积节省,via 附近余量不足
Samenet 间距面积膨胀,耦合低面积节省,制造风险上升

天线效应是另一个必须算进这笔账的机制。工艺过程中,长金属线像天线一样收集等离子体电荷,电荷积累到一定程度会击穿栅氧。判断依据是天线比:金属面积除以栅面积。规范里给出了在 LEF 和 DEF 中声明天线相关关键字的方法,让工具能在布线阶段就计算这个比值,而不是等流片前才发现。修复手段通常是跳层(把长线在高层和低层之间切换,打断积累)或者加二极管。选择哪种,取决于你在布线阶段预留了多少自由度——这也是 LEF 写松写紧的直接后果。

我的习惯是:每次拿到一份新的工艺 LEF,先不看它写了什么,而是反推它的意图——pitch 是不是偏紧、wide metal 规则是不是用 Nondefault Rule 分层的、via 附近有没有留延伸。反推的过程本身就是一次对布线器行为的预判。有一年我在一个模拟项目上偷懒,直接沿用了上一版工艺的 LEF,结果布线收敛得很漂亮,流片前的天线检查却报出成片的违规,返工两周。从那以后我每次换工艺,都强制走一遍“反推 LEF 意图 + 天线比预计算”这两步,不再相信“能跑通就是对的”。

希望这些能帮到你,少走一点我走过的弯路。

本文还有配套的精品资源,点击获取

返回列表