LEF/DEF语言参考:芯片物理设计交换格式与常见误区

简介:《LEF/DEF 5.8 语言参考》是 Cadence 于 2017 年发布的官方英文手册,面向数字后端物理设计、版图规划与 EDA 工具开发方向的工程师及高年级研究生,用于系统查证 LEF 与 DEF 两种集成电路描述语言的语法与语义。LEF 侧重工艺侧描述,涵盖金属层、多晶硅层等层次定义与电气特性、标准单元与宏模型的几何抽象,以及间距规则、填充与隔离区域;DEF 面向设计实现,记录模块布局与方向、信号与电源网络连接、DRC/LVS/ERC 约束、物理分区与过孔属性。两者同为 EDA 工具间交换设计信息的行业标准,是物理综合、布局布线与签核验证衔接的关键。资源包仅含 1 个 PDF 文件,约 2.48MB,带完整目录与章节索引,便于按关键字定位条目;目前已有 2177 人学习。读者可据此查证 5.8 版本的官方一手定义、约束管理增强与先进工艺节点支持细节,作为编写脚本、配置流程和排查工具报错时的对照依据。

1. 到底什么是 LEF 和 DEF:一张芯片版图的说明书加施工图

装修过房子的人都有体会,工人手里通常捏着两样东西。一份是建材和家具的规格册,写着每块砖多大、每扇门多宽、插座离地至少几厘米;另一份是这户人家的施工图,写着沙发摆在客厅东墙、水管从厨房穿到卫生间。芯片设计里的 LEF/DEF 语言参考,讲的就是这两样东西该怎么写。LEF 是 Library Exchange Format,管的是「规矩」——这块工艺上有几层金属、每层最细能画多宽、标准单元长什么模样;DEF 是 Design Exchange Format,管的是「现场」——这次设计里哪个单元摆在哪个坐标、线从哪儿连到哪儿。搞懂这一对格式,你就看懂了芯片从图纸走向硅片的那个交接环节:为什么工具之间能接得上,为什么换个软件不用把设计重画一遍,为什么一条看起来没问题的走线会被判违规。这份语言参考,本质上是给这两个文件立的一份「书写规范」,也是排查问题时最该翻的那本字典。

2. 为什么非得拆成两种格式:芯片设计流程里的「交接班」难题

2.1 从代码到硅片,中间要换好几拨工具

一颗芯片从一行行硬件描述代码,走到硅片上真实的晶体管,中间要过好几道手。综合工具先把逻辑门连成网表,布局工具决定每个门放在哪,布线工具决定线怎么走,再往后还有时序分析、功耗分析、物理验证、可制造性检查。这些环节用的工具往往来自不同厂商,内部数据结构差别很大。要是每换一个工具就把设计重新导一遍、重新认一遍,整个流程根本收敛不了。

打个比方,装修队进场,水电工、木工、瓦工各干各的。如果每个人用的图纸语言都不一样,水电工标的位置木工看不懂,木工留的洞瓦工对不上,最后只能砸墙重来。行业里解决这个问题的办法很朴素:定一套大家都能读写的中间图纸。LEF 和 DEF 就是芯片物理设计这一段路上被广泛接受的中间图纸。

关键在于,这套中间图纸不是一份,而是两份。为什么不能合成一份?因为芯片设计里有两类信息,它们的「保质期」完全不同。

2.2 一份管「规矩」,一份管「现场」

LEF 描述的是可复用的东西。某条工艺线上有几层金属、每层的间距规则是多少、标准单元库里每个门的外框尺寸和引脚位置——这些信息一次写清楚,可以喂给无数个不同的设计。它天然属于工艺厂和库提供方,一个库文件可能在几十上百个项目里被反复引用。

DEF 描述的是这一次的东西。这个设计里,编号 U1 的那个单元被摆在坐标 (2400, 0),朝向是 N;某根信号线从 U1 的 A 脚出发,经过两个通孔,落到 U2 的 Y 脚。这些信息只对一个设计成立,换个项目就完全作废。

举个更具体的例子。一个两输入与非门,内部可能由四个晶体管组成,但布局布线工具根本不需要知道这四个管子怎么连。它只需要知道:这个单元占地 1.2 微米乘 2.4 微米,左边有个输入引脚、右边有个输出引脚,中间那块区域是布线禁区。这种「只保留外部轮廓和接口」的表示方法,业内叫抽象视图,英文是 abstract。LEF 里的 MACRO 语句写的就是这个抽象视图。

提示:抽象视图这个词很容易被想复杂。它的核心就一句——够用就好。工具需要什么就给什么,多一个坐标都是浪费。

2.3 拆成两份,换来的是什么

拆开的好处很直接。库信息写一次,多个设计复用,改工艺规则时只改一处;设计数据每次只传自己那一份,文件体积小、传输快、版本管理也清楚。更实际的一点是,做库的人和做设计的人可以并行工作,互不阻塞。

代价也有,而且很具体。两份文件必须对得上:单位要对得上,名字要对得上,语言版本要对得上。LEF 里写数据库单位是一千分之一微米,DEF 里写的也得是同一个数,否则所有坐标整体错位,工具不会报语法错误,只会给你一堆莫名其妙的布局重叠。这种错最难查,因为它不吵不闹,只是安静地把结果搞坏。

这就是为什么需要一个专门的《语言参考》。它不教你怎么做设计,它告诉你这两个文件里每个关键字能吃什么样的值、值之间有什么约束、哪些语句有先后顺序。当你遇到「工具读进去了但结果不对」这类玄学问题时,答案通常就藏在这些约束里。

3. LEF 里究竟写了什么:工艺规矩和单元外形的那本字典

3.1 技术层定义:金属层、切割层、注入层各管什么

LEF 的第一大块是工艺描述,核心是各种 LAYER 语句。语言参考里按用途把层分成几类,每类的属性完全不同。

布线层(Layer Routing)是最常用的一类,描述金属走线。它要写清楚方向是水平还是垂直、布线间距是多少、最小线宽是多少、方块电阻和单位面积电容大概多少。这几个参数直接决定了布线工具能不能算准延迟、会不会违反规则。

切割层(Layer Cut)描述的是通孔所在的层,也就是连接上下两层金属的「电梯井」。它关心的是通孔的最小尺寸、通孔之间的最小间距、以及不同金属层叠起来时的 enclosure 要求。

还有两类不那么常被提起。主切片层或覆盖层(Masterslice 或 Overlap)在早期门阵列工艺里是主角,现在多用来描述衬底和阱这类不直接走线的结构。注入层(Implant)描述离子注入区域,影响器件的阈值电压,通常在模拟和特殊器件里才会细写。

为什么分这么细?因为它们在制造上是不同的掩膜,规则来源不同、失效模式也不同。金属层怕短路和电迁移,注入层怕对不准。把这些混在一个语句里写,规则检查工具就没法分别校验。

3.2 MACRO 与抽象视图:给每个单元建一张外形档案

LEF 的第二大块是单元库描述,主角是 MACRO。一个标准单元在 LEF 里大致长这样:先声明类别(是普通核心单元、焊盘还是大块的 IP 宏),再写原点、尺寸、对称性、所在的行站点,然后是若干 PIN 语句描述引脚,最后用 OBS 语句圈出布线禁区。

引脚这一段值得多说两句。每个 PIN 下面会有 DIRECTION 说明是输入输出还是双向,再往下是 PORT,PORT 里用 LAYER 加 RECT 的组合画出引脚在每一层上的实际形状。有的单元引脚在多层上都有形状,那是为了方便不同层的线接进来。

OBS 是很多人第一次看 LEF 时会忽略、但实际最要命的部分。它表示这块区域内工具不许布线。标准单元内部有大量的器件和内部连线,外面来的信号线穿进去就会短路。所以 OBS 相当于给布线工具划了一片禁飞区。某个单元如果 OBS 写小了,工具会欢快地把线布进去,然后在物理验证阶段炸出一堆短路错误——这就是典型的翻车现场,而且排查起来极费时间。

注意:OBS 写漏或写小,语法检查完全通得过,错误要到版图比对阶段才暴露。这类问题的排查成本远高于写的时候多花五分钟。

3.3 规则类语句:间距、轨道与非默认规则

除了层和单元,LEF 里还有一批专门管约束的语句,它们平时不显眼,出问题时却常常是根因。

SPACING 定的是同层图形之间的最小距离。但真实工艺里,线宽不同,要求也不同——宽线在制造时更容易出现缺陷,需要更大的间距。这时候就要用 SPACINGTABLE,按线宽分段给出不同的间距值。语言参考里对这张表的写法和查找顺序有明确说明,顺序写错,工具就可能取到偏小的那个值。

非默认规则(NONDEFFAULTRULE)是给特殊线准备的另一套参数。比如某几根电源线要走得特别宽,宽线的间距、通孔规则都和普通线不同,就可以单独定义一条规则,在布线时指定使用。这相当于给这几根线开了个「特殊通道」。

布轨(TRACKS)定义的是每层金属上可以走线的网格位置。工具不会随便找地方画线,它只在轨道上画。轨道间距和偏移写错,工具算出来的可用布线资源就是错的,表现出来就是「明明看着有空间却布不通」。

行站点(SITE)定义标准单元行的基本单位,也就是行高和行宽的最小粒度。所有标准单元的高度必须是站点高度的整数倍,否则排不成行。这条约束在库和设计之间必须一致,否则布局阶段会直接报错。

单位(UNITS)和制造网格(MANUFACTURINGGRID)是两个不起眼但要命的语句。前者定义数据库单位换算,后者定义所有坐标必须对齐的最小网格。坐标没对齐网格,有些工具会静默取整,有些会直接拒绝——行为不统一,是最容易让人怀疑人生的地方。

3.4 一段最小 LEF 长什么样

看一段简化的片段,比读十页描述管用。下面的数值只是为了说明结构,不代表任何真实工艺。

VERSION 5.8 ; UNITS DATABASE MICRONS 1000 ; # 数据库里 1000 个单位 = 1 微米 END UNITS LAYER M1 TYPE ROUTING ; # 这是一层金属走线层 DIRECTION HORIZONTAL ; # 只允许水平走线 PITCH 0.2 ; # 相邻轨道的间距 WIDTH 0.1 ; # 最小线宽 SPACING 0.1 ; # 同层最小间距 RESISTANCE RPERSQ 0.08 ; # 方块电阻,用于延迟估算 END M1 MACRO NAND2_X1 CLASS CORE ; # 普通核心单元 ORIGIN 0 0 ; SIZE 1.2 BY 2.4 ; # 外框尺寸,必须是站点尺寸的整数倍 SYMMETRY X Y ; # 允许镜像摆放的方向 SITE core_site ; PIN A DIRECTION INPUT ; PORT LAYER M1 ; RECT 0.15 0.6 0.35 0.9 ; # 引脚在 M1 上的矩形范围 END END A OBS LAYER M1 ; RECT 0.4 0.1 1.1 2.3 ; # 单元内部禁区,外部线不许进入 END END NAND2_X1

这段代码的逻辑顺序是有讲究的。VERSION 必须最先出现,告诉解析器按哪个版本的语法读;UNITS 紧随其后,因为后面所有的坐标数值都依赖这个换算比例;LAYER 定义要在 MACRO 之前,因为 MACRO 里的 PORT 和 OBS 会引用层名。语言参考里专门有一节讲语句顺序,顺序颠倒通常不是「警告」,而是直接解析失败。

参数上最值得盯的是三个:DATABASE MICRONS 决定全局比例,SIZE 必须是 SITE 的整数倍,OBS 的范围要覆盖单元内部所有不该被穿过的区域。这三处只要有一处不对,后面整条流程都会带着错误往下走,而且往往到很晚才被发现。

4. DEF 里究竟写了什么:设计落地之后的现场记录

4.1 组件、引脚与网络:住户、门牌和电线

DEF 的第一大块是设计内容本身,三条主线撑起了整个文件。

组件(COMPONENTS)记录设计里每一个实例。它写清楚这个实例叫什么名字、用的是哪个 MACRO、摆在哪个坐标、朝向是什么。朝向那几个缩写值得记一下:N、S、E、W 是四个基本方向,前面加 F 表示翻转,所以 FN、FS、FE、FW 是另外四种组合,一共八种摆放方式。有些单元还会用更细的掩膜偏移选项,用于光学邻近效应补偿,在先进工艺里越来越常见。

引脚(PINS)记录设计对外的接口。一个芯片最终要和封装、和外部世界连接,这些连接点就是引脚。DEF 里写清楚每个引脚的名字、方向、在哪个层上、形状多大。

网络(NETS)记录连接关系。它本质上是一组端点列表,告诉工具这些引脚和端口之间是电气相连的。至于具体怎么连——走哪条路径、打几个通孔——布线之前是空的,布线之后会被写入 DEF 的走线段。

这三者合起来,正好对应一个很生活化的场景:组件是楼里的住户,引脚是楼门和信箱的编号,网络是「谁家和谁家要通电话」的清单。清单本身不告诉你电话线怎么走,那是施工队的事。

4.2 行、站点、区域和阻塞:布局的地基与禁停区

标准单元不是随便乱放的,它们要排在整齐的行里。行(ROWS)语句定义的就是这些行的起点、重复次数、每一步的步长。每行的起点必须落在站点网格上,行高必须等于站点高度,否则单元放上去会悬空或重叠。

区域(REGIONS)用来把设计切块。某个模块要集中放在一片区域里、某个电源域要独立成片,都可以用区域语句圈定。这在多电压域设计里特别常用,因为不同电压域的单元不能随便混放。

阻塞(BLOCKAGES)是布局和布线的禁区。它可以按层来分,也可以在全局范围内生效。和 LEF 里的 OBS 有点像,但作用范围不同:OBS 是单元自带的、跟着单元走的;BLOCKAGES 是设计级的、由设计者主动加的。比如某块区域要留给模拟电路,或者某个位置要放大的 IP 宏,就可以先加一块阻塞把地方占住。

4.3 特殊网络与通孔:电源地怎么走

普通信号网络的走线通常在布线阶段由工具自动生成。但电源和地这类网络不一样,它们往往要用手工或半自动的方式规划,线宽大、结构规整、优先级高。DEF 里专门有一类特殊网络(SPECIALNETS)来记录这些内容,包括走线的路径、每段的宽度、使用的通孔类型。

通孔(VIAS)语句则定义具体的通孔结构。有些通孔是工艺库自带的,直接引用名字就行;有些是设计过程中临时生成的,需要在 DEF 里完整描述它的每一层形状。语言参考里对这两种写法都有说明,混用会导致工具读不进来。

还有一个容易被忽略的细节:特殊网络的走线常常要配合非默认规则使用。宽线用普通间距规则会判违规,得在 DEF 里指定它走哪条规则。这个对应关系如果断了,物理验证阶段会冒出一堆莫名其妙的间距错误。

4.4 一段最小 DEF 长什么样

同样看一段结构化的片段,理解它和 LEF 的呼应关系。

VERSION 5.8 ; DIVIDERCHAR "/" ; BUSBITCHARS "[]" ; DESIGN top ; UNITS DISTANCE MICRONS 1000 ; # 必须和 LEF 的单位一致 DIEAREA ( 0 0 ) ( 20000 20000 ) ; # 整个芯片的可用范围 ROW ROW_0 core_site 0 0 N DO 500 BY 1 STEP 1200 0 ; COMPONENTS 2 ; - U1 NAND2_X1 + PLACED ( 2400 0 ) N ; # 引用 LEF 里定义的 MACRO 名 - U2 NAND2_X1 + PLACED ( 3600 0 ) FS ; # FS 表示翻转后南北向摆放 END COMPONENTS NETS 1 ; - n1 ( U1 A ) ( U2 Y ) ; # 两个引脚之间的连接关系 END NETS END DESIGN

最关键的呼应点在第一行和最后一行之间。DEF 里的 UNITS DISTANCE MICRONS 必须和 LEF 里的 DATABASE MICRONS 取同一个值,否则 U1 的坐标 (2400, 0) 在两份文件里代表的位置根本不是一回事。这是跨工具交接时最经典的踩坑点,而且因为两边语法都合法,工具不会主动报错。

COMPONENTS 里的 NAND2_X1 这个名字,必须能在 LEF 的 MACRO 列表里找到。找不到就只有两种结果:工具拒绝读入,或者更糟——默默跳过这个实例,让设计悄悄少了一个门。后者在做形式验证时会被抓出来,但那时候你已经花了不少时间在别处排查。

ROW 语句里的 1200 是标准单元的宽度步长,对应 LEF 里 SITE 定义的那个数。这个数对不上,单元排不成行,布局工具会用一堆重叠告警把你淹没。

5. 易混与误区:LEF 和 DEF 到底差在哪,别再搞反

5.1 误区一:LEF 和 DEF 必须成对出现

这是最常见的误解。很多人第一次接触这两个格式,会以为它们是一份文件拆成了两半,缺一不可。实际情况是,LEF 完全可以独立存在。一个标准单元库交付给客户时,通常就是一堆 LEF 文件加配套的时序库,里面根本没有 DEF 的影子。因为库描述的是「可能被用到的东西」,跟具体哪个设计没关系。

DEF 则离不开 LEF。原因很直接:DEF 里的组件要引用 MACRO 名,坐标要依赖单位定义,层名要和 LEF 里的一致。没有 LEF,DEF 里那些名字全都指向空气。

区分方法很简单:问一句「这份数据换个项目还能用吗」。能用的是 LEF,不能用的是 DEF。库、工艺规则、单元外形,都归 LEF;某个具体设计里东西摆在哪,归 DEF。

5.2 误区二:LEF 只是「库文件」,跟工艺没关系

「LEF 是库文件」这个说法流传很广,但它只对了一半。LEF 里确实有一大块是 MACRO,属于库的范畴;但另一大块是 LAYER、SPACING、TRACKS、UNITS 这些,完完全全是工艺描述。语言参考开篇就写得很清楚,LEF 定义的是工艺技术的元素和相关的单元模型库,两件事并列。

把 LEF 纯粹当成库文件,后果是在排查工艺相关问题时想不起来去翻它。比如布线工具抱怨某层没有可用轨道,你会去查工具配置、查设计约束,绕一大圈,最后发现是 LEF 里 TRACKS 语句写漏了一层。这类错误在语法检查里是发现不了的,因为少写一条语句不构成语法错误。

区分方法:看内容。出现 LAYER、SPACING、TRACKS、UNITS 这些关键字的,是工艺部分;出现 MACRO、PIN、OBS 的,是库部分。同一个文件里两者都有,很正常。

5.3 误区三:DEF 里既然有技术段,就不需要 LEF 了

DEF 语言里确实存在一个技术(TECHNOLOGY)段,可以写一些层信息。有人看到这个就以为 DEF 能自给自足,把 LEF 省掉。这是个很危险的误解。

DEF 里的技术段主要作用是「把必要的技术信息带进设计文件」,让某些场景下工具能少读一个文件,或者让设计文件自带上下文。但它并不承担完整工艺规则的职责。间距表、非默认规则、完整的单元抽象视图,这些仍然在 LEF 里。语言参考对 DEF 技术段能写什么有明确边界,越界的内容写了也不会被识别。

区分方法:把 DEF 的技术段理解成一份「随身携带的摘要」,而不是「完整的规则手册」。真正要查规则细节,还是得回到 LEF。

5.4 误区四:抽象视图就是完整版图,只是格式不同

LEF 里的 MACRO 画出了单元的外框和引脚形状,看起来挺像那么回事。于是有人以为这就是单元的版图,只是换了个文件格式存。这个误解的代价可能很大。

抽象视图只有轮廓、引脚、禁区这三类信息。单元内部晶体管的实际图形、栅极的具体形状、注入区的边界,全都不在里面。拿 LEF 去做流片是绝对不行的,流片要的是完整版图数据,那是另一套格式的事。

区分方法:记住抽象视图的目的。它是给布局布线工具用的,工具只需要知道「占多大地方、从哪儿接线、哪儿不能碰」。它天生就不是给人看细节的,也不是给制造用的。

5.5 误区五:关键字和名字大小写随便写

LEF 和 DEF 的语法里,关键字是大写的,而用户自定义的名字——单元名、实例名、网络名、层名——是区分大小写的。这两条规则混起来,很容易写出「语法通过但语义错乱」的文件。

举个具体的:LEF 里定义了一个层叫 M1,DEF 里引用的时候写成 m1,某些工具会认为是两个不同的层,然后在检查时报「引用了未定义的层」;另一些工具可能做了大小写不敏感的兼容处理,让你以为没事。等换了个工具,问题突然冒出来,这时候再回头查,成本就高了。

区分方法:关键字照抄大写,自定义名字全程保持一致,最好在项目开始就定一个命名约定。这不是洁癖,是给自己省后悔药。

6. 什么时候该翻这份语言参考:边界判断与真实取舍

语言参考这类文档有个特点:平时用不上,用上的时候往往是出了事。所以真正的问题不是「要不要读」,而是「什么时候值得花时间深读,什么时候翻两页就够」。

先看一张简单的判断表。

场景建议
第一次接手一份陌生工艺的 LEF重点看 UNITS、LAYER、SITE 三段,其余可跳读
布线工具报出看不懂的间距违规精读 SPACINGTABLE 和 NONDEFFAULTRULE 两节
跨工具交接后布局整体错位先核对两边的单位定义,再查坐标网格
单元摆不进标准单元行查 SITE 高度和 MACRO 的 SIZE 是否成整数倍
只想跑通某个工具的默认流程先看工具自带文档,语言参考暂时不用
做库交付或工艺规则整理值得从头到尾过一遍,这是主战场

举个具体例子。某开发者做一个小模块的布局布线,工具反复报某几根宽线的间距违规,但他量了图上距离,明明大于最小间距。折腾半天后翻到语言参考里非默认规则那一节,才发现宽线走的是另一套间距值,比普通线大得多。他之前一直在按普通规则核对,自然对不上。这个错误的根因不在工具,也不在设计,而在于他不知道 LEF 里可以给同一层配多套规则。

反过来,也有不该硬啃的时候。如果只是想知道某个坐标代表什么、某个单元为什么摆在那儿,打开版图可视化工具看一眼比翻文档快得多。语言参考是查语法和约束的,不是查具体数值的。把它的定位搞对,能省下大量时间。

真正需要警惕的是「语法对但语义错」这一类问题。单位不一致、名字大小写不统一、OBS 范围写小、轨道漏定义,这些问题在解析阶段一路绿灯,要等到很晚才暴露。所以我自己的习惯是:拿到任何一份新的 LEF,先不看它写了什么,先核对三件事——数据库单位、层清单、站点高度。这三样对上了,后面的坑能少一大半。从那以后我每次接手跨团队的库文件,都强制走一遍这三项核对,宁可多花十分钟,也不想再体验那种查到凌晨三点发现是一个数字写错的感觉。

这份语言参考本身带使用授权说明,个人查阅、打印一份自用没问题,别拿去做二次分发或商用。它对应的是 5.8 版语言,文档标注时间是 2017 年,内容覆盖 LEF 语法、DEF 语法、别名语句、错误检查机制,以及工艺天线、布线优化这些专题附录。需要完整版本的时候,按下面的方式获取就行。希望帮到你。

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