LEF/DEF 5.8语法参考与PR避坑:从UNITS到天线检查

发布时间:2026/10/31 8:20:01
LEF/DEF 5.8语法参考与PR避坑:从UNITS到天线检查 简介Cadence《LEF/DEF 5.8 Language Reference》官方语言参考手册面向数字IC物理设计工程师、EDA工具开发者及布局布线相关人员用于系统查阅LEF与DEF两种IC描述语言的语法、语义和版本约束。压缩包仅含1个PDF文件大小约2.48MB便于随查随用内容围绕LEF的工艺层定义、单元模型、间距规则、宏模型以及DEF的模块布局、网络连接、DRC/LVS/ERC约束、物理分区与物理属性展开并涉及5.8版本在约束管理与先进工艺节点支持方面的更新。已有2177人学习适合作为后端流程中工具输入输出对照与格式排错的案头参考也能帮助读者理解LEF/DEF在物理综合、布局规划和验证环节的桥梁作用。1. LEF/DEF 5.8 语言参考一句 UNITS 写错PR 里能偏出三个 site搜 lefdefeda 一路找过来的人多半不是想读语法科普而是手里正躺着一份读不进去的 LEF 或 DEF工具只丢一句line 4213 unexpected token剩下的全靠猜。这份 5.8 版参考手册就是那个“最终解释权”它把 LEF 里的工艺层、单元宏、通孔规则和 DEF 里的布局、连线、扫描链逐条语句、逐个参数、逐种取值范围写死正文按 LEF 语法、ALIAS、LEF 工作流、DEF 语法、示例、PR 优化、天线违例七块展开四百页出头。它适合三类人刚接手库文件、需要自己改 LEF 的后端新人要写脚本解析或生成 DEF 的工具开发以及被“工具能读、结果不对”折腾过的流程工程师。它不教你布线怎么布得漂亮只负责告诉你文件里每个字符该长什么样。2. LEF 侧的技术层与单元模型从 LAYER 到 MACRO 的读写顺序LEF 是给工具看的“工艺 单元”抽象不是版图数据的搬运工。一份 LEF 通常只描述两件事这一层工艺长什么样线宽、间距、方向、通孔规则以及这个单元的外形和引脚开口在哪。手册第 9 页起的 LEF Syntax 把这两件事拆成 LAYER、VIA、VIARULE、MACRO、SITE、UNITS 几个主语句语句内部的子属性加起来上百个。真正让人翻车的往往不是没见过的属性而是顺序和单位——工具解析器大多按固定顺序做状态机前一个语句没闭合后面的内容会被整段吞掉。2.1 语句顺序为什么不能随手调手册第 12 页有一节 Order of LEF Statements写明VERSION必须打头BUSBITCHARS、DIVIDERCHAR、UNITS这类全局设置要在大批LAYER、MACRO之前出现END LIBRARY收尾。我见过有人为了“看着整齐”把所有SITE挪到文件末尾结果工具读到MACRO里的SITE core_site时符号表里还没有这个 site直接报未定义。更隐蔽的是UNITS放晚了有的解析器在遇到第一条带长度的语句时就把数据库单位锁定后面再写UNITS DATABASE MICRONS 2000会被忽略或者告警于是整份文件的尺寸按默认 1000 解释面积直接差一倍。常见做法是固定一个头部模板所有人往里填内容而不是各自发挥VERSION 5.8 ; BUSBITCHARS [] ; DIVIDERCHAR / ; UNITS DATABASE MICRONS 1000 ; END UNITS MANUFACTURINGGRID 0.005 ;DATABASE MICRONS 1000的意思是 1 微米等于 1000 个数据库单位LEF 内部长度仍用微米浮点写这个数主要影响与 DEF 的对接。MANUFACTURINGGRID写的是制造网格所有坐标理论上要落在这个网格上后面对 DEF 的整数坐标做合法性检查时它就是标尺。这两条一旦定下来整个项目不要中途改改了就要同步所有库和所有历史 DEF。2.2 LAYER 段怎么写才不会被判成“不可布线”布线层用LAYER name TYPE ROUTING起头必须给的三件套是DIRECTION、WIDTH、PITCH。DIRECTION只有 HORIZONTAL、VERTICAL、DIAGONAL 几种取值它决定布线器把这一层当横还是当竖用PITCH是轨道间距布线器靠它铺 track写小了密、写大了浪费。真正影响 DRC 的是SPACING、MINWIDTH、AREA以及宽度相关的SPACINGTABLE——宽线间距规则没法用一条常数表达时就得靠 PRL 和 SPACINGTABLE 描述。LAYER Metal2 TYPE ROUTING ; DIRECTION VERTICAL ; PITCH 0.20 ; WIDTH 0.10 ; SPACING 0.10 ; MINWIDTH 0.10 ; AREA 0.05 ; THICKNESS 0.35 ; EDGECAPACITANCE 3.5e-05 ; RESISTANCE 0.08 ; END Metal2这里每个数都要跟工艺文件对得上。WIDTH是默认线宽MINWIDTH是最小可画线宽两者不同时布线器在没有非默认规则NONDEFAULTRULE的情况下会优先用WIDTH。AREA是最小面积很多短线段单独看宽度够、长度不够就是被这一条判掉的。THICKNESS、RESISTANCE、EDGECAPACITANCE不进 DRC但抽取和时序估算会读填错了会让 RC 结果系统性偏属于“工具不报错但数字不对”的那类问题。切割层TYPE CUT要配SPACING和RESISTANCE如果是通孔阵列还涉及ARRAYSPACING。手册第 15 页起把 cut 层的每个属性单独列了一节看的时候别跳通孔间距规则是最容易被抄错的地方。2.3 MACRO 与 PIN给工具看的抽象视图不是版图MACRO是一个单元的外部轮廓定义必备要素是CLASS、ORIGIN、SIZE、SITE标准单元必须、SYMMETRY然后是PIN和OBS。CLASS CORE表示标准单元CLASS BLOCK表示硬宏CLASS PAD是 IO选错 class 会让布局器把宏当单元塞进 row 里。SIZE x BY y的单位是微米ORIGIN是单元内部坐标原点相对左下角的偏移这两个数不对摆出来的单元会整体漂移。MACRO NAND2X1 CLASS CORE ; ORIGIN 0 0 ; SIZE 1.2 BY 2.4 ; SYMMETRY X Y ; SITE core_site ; PIN A DIRECTION INPUT ; PORT LAYER Metal1 ; RECT 0.1 0.6 0.3 0.8 ; END END A OBS LAYER Metal1 ; RECT 0.4 0.2 0.8 2.2 ; END END NAND2X1PORT下面的RECT是引脚的可用布线开口工具只认这几块矩形你写漏一个这个引脚就“无孔可入”。OBS是不能布线的阻挡区标准单元里通常把内部走线遮掉只留引脚。新手常见的做法是把OBS整块盖住单元结果引脚也被挡布线器只能绕远路时序自然难看。SYMMETRY X Y表示单元可以在 X、Y 方向镜像摆放漏写的话布局器会少一半合法朝向。2.4 三行命令做一次 LEF 体检拿到别人给的 LEF先别急着往流程里塞。先用几条命令看结构完整性语句是否成对、每个 MACRO 是否闭合、有没有重复定义。# 统计顶层语句出现次数END LIBRARY 缺一不可 grep -Eo ^[[:space:]]*(VERSION|UNITS|LAYER|MACRO|SITE|VIA|VIARULE|NONDEFAULTRULE|END LIBRARY) tech.lef \ | awk {print $1} | sort | uniq -c | sort -rn # MACRO 数量与 END 数量是否对得上END 后跟宏名的情况要排除 grep -c ^[[:space:]]*MACRO tech.lef grep -c ^END [A-Za-z0-9_]*$ tech.lef第一条按行首关键字统计MACRO与END LIBRARY的数量关系能快速暴露截断文件第二条用来核对宏块闭合如果MACRO有 512 个而结尾只有 400 个END说明文件在传输或合并时被切了。这种截断在多个库拼合的场景特别常见工具报的却是“找不到某个单元”很误导。更细的检查可以交给一段几十行的 Python把每个 MACRO 的SIZE和它所有RECT的坐标收集起来看引脚矩形有没有超出边界矩形坐标是不是上下、左右写反import re pattern_macro re.compile(rMACRO\s(\S)(.*?)END\s\1, re.S) pattern_size re.compile(rSIZE\s([\d.])\sBY\s([\d.])) pattern_rect re.compile(rRECT\s([-\d.])\s([-\d.])\s([-\d.])\s([-\d.])) for name, body in pattern_macro.findall(open(tech.lef, encodingutf-8).read()): m pattern_size.search(body) if not m: print(f{name}: 缺 SIZE) continue w, h float(m.group(1)), float(m.group(2)) for rect in pattern_rect.findall(body): x1, y1, x2, y2 map(float, rect) if x2 x1 or y2 y1: print(f{name}: RECT 方向写反 {rect}) if min(x1, y1) 0 or max(x2, y2) max(w, h) 1e-6: print(f{name}: RECT 越界 {rect} (SIZE {w}x{h}))pattern_macro用后向引用确保END后跟的是同名宏避免跨块误匹配pattern_rect把四个坐标转成浮点后做两个判断——先后顺序和边界。这段脚本不追求覆盖全部语法只用来筛出明显写错的手工编辑痕迹。跑完如果输出为空至少几何层面是干净的剩下的交给工具的语法检查器。3. DEF 侧的设计描述UNITS、DIEAREA 与 COMPONENTS 的对齐DEF 描述的是“这一版设计现在长什么样”坐标全部是数据库单位整数这跟 LEF 用微米浮点正好相反。手册第 225 页起的 DEF Syntax 里UNITS DISTANCE MICRONS是全书最该先记住的一句它决定了后面所有整数怎么解释。DEF 的段落顺序同样有规定DESIGN在最前UNITS、DIEAREA、TRACKS要早于COMPONENTS、PINS、NETSEND DESIGN收尾。顺序错了不一定报错但可能出现“前面引用的东西后面才定义”的悬空。3.1 整数坐标背后的换算VERSION 5.8 ; DIVIDERCHAR / ; BUSBITCHARS [] ; DESIGN top ; UNITS DISTANCE MICRONS 1000 ; DIEAREA ( 0 0 ) ( 120000 120000 ) ;DIEAREA里的 120000 不是微米是 120000 个数据库单位在 1000 的倍率下等于 120 微米。如果 LEF 的头写的是DATABASE MICRONS 2000DEF 写的是 1000两份文件对接时工具会做一次缩放换算某些工具会直接告警并退出另一些默默按 DEF 的倍率解释于是单元尺寸翻倍、布局重叠。我一般会在读入前先把两份文件的UNITS行抓出来对齐比对这一步比看任何错误日志都直接。DBU 1000 # 与 UNITS DISTANCE MICRONS / DATABASE MICRONS 保持一致 def dbu2um(v: int) - float: return v / DBU def um2dbu(v: float) - int: # 必须四舍五入到整数直接 int() 截断会累积半个单位的漂移 return int(round(v * DBU)) print(dbu2um(120000)) # 120.0 print(um2dbu(0.135)) # 135um2dbu里用round而不是int是因为 LEF 里的浮点尺寸转 DEF 坐标时经常出现0.135 * 1000 134.99999这种浮点表示误差截断会变成 134一个单元少一个单位几万个单元叠起来就是肉眼可见的缝隙。3.2 COMPONENTS 的放置语法与 orientation 边界COMPONENTS 2 ; - u_core/u_alu/U12 NAND2X1 PLACED ( 34000 56000 ) N ; - u_core/u_alu/U13 NAND2X1 FIXED ( 35000 56000 ) FS ; END COMPONENTS实例名可以带层次分隔符 PLACED表示已放置但可移动 FIXED表示锁定 COVER表示覆盖且可移动。括号里是左下角坐标后面的N、S、E、W、FN、FS、FE、FW是八种朝向。手册在 Components 一节把每个朝向的变换矩阵含义都写了实际含义是N不翻转S绕 X 轴翻FN是镜像FS是旋转 180 度。写错朝向不会报错但引脚位置全错布线器绕线时找不到开口最后表现成“这个单元的所有网络都绕远”。一个可以立刻用的检查FIXED 的实例数量异常多时先怀疑是布局工具导出时把未放置的单元也标成了 FIXED。这类 DEF 送回布线器后优化空间为零时序怎么都收敛不了。3.3 SPECIALNETS、PINS 与 NET 的配套关系SPECIALNETS描述电源地这类特殊网络允许用 SHAPE、 FIXEDRULE、 USE POWER之类的属性走的是宽线或布线层上的条带NETS描述普通信号。两者都引用引脚和实例端口写法上SPECIALNETS用( inst pin )形式NETS也用同样形式但可以带 ROUTED走线路径。手工改 DEF 时最容易犯的错是在NETS里删掉了一个实例但SPECIALNETS里还留着它的电源连接工具读入时找不到实例报的是“未定义组件”可你翻遍COMPONENTS也找不到问题因为要删的是另一段。PINS段定义顶层端口每个 pin 的 NET名必须能和NETS或SPECIALNETS里的名字对上 DIRECTION与 USE也要和 LEF 里对应 MACRO 的 PIN 方向一致。方向对不上时时序分析会把输入当输出算这种错误往往要等到静态时序报告出现“所有路径都是 0”才被发现。3.4 增量 DEF 与 SCANCHAINS 的使用时机手册第 219 页的 Incremental LEF 和第 300 页的 Scan Chains 是两块容易被忽略但很实用的内容。增量 LEF 允许你只写发生变化的部分用END LIBRARY收尾后交给工具合并适合库更新时只补几个单元的引脚。它的边界是只能新增或覆盖不能删除已存在的定义删除必须回全量文件里做。SCANCHAINS段用来描述扫描链的连接顺序包含 START、 FLOATING、 ORDERED、 STOP这些关键字。手工写扫描链几乎不可维护常见做法是让工具导出后做局部调整调整时只动ORDERED后面的实例顺序不要动START和STOP的引脚引用否则链的入口会断开测试覆盖率报告里会出现整条链被跳过。SCANCHAINS 1 ; - chain1 START u_core/sin FLOATING u_core/U100 ( OUT ) ( IN ) u_core/U101 ( OUT ) ( IN ) STOP u_core/sout COMMONSCANPINS ( IN sin ) ( OUT sout ) ; END SCANCHAINS FLOATING表示这段顺序可以自由重排 ORDERED则是强制顺序。想让工具帮你优化链长就用 FLOATING想固定某几个相邻实例就用 ORDERED混着用是正常做法。4. 避坑与排查五条血泪记录这一章全部来自实际翻车现场每条按现象、原因、解决写。顺序大致按“越早发现越省钱”排。4.1 所有器件整体偏移一个固定量现象DEF 读进去后所有实例相对预期位置统一偏移几十个数据库单位DRC 报出大量间距违例但相对关系是对的。原因LEF 里 MACRO 的ORIGIN不是 0 0而导出 DEF 的脚本默认按左下角算坐标没有减去 ORIGIN。或者反过来LEF 更新了 ORIGIN历史 DEF 没跟着重算。解决先核对 LEF 中该宏的ORIGIN值再抽查一个实例的PLACED坐标与版图实际位置是否一致。批量修的话用脚本读 LEF 建立宏名到 ORIGIN 的映射对 DEF 的每个 COMPONENTS 行做坐标补偿改完重新跑一次 LVS确认连接关系没被破坏。从那以后我要求所有库的ORIGIN一律写 0 0除非工艺有强约束。4.2 读入报 unknown layer但 LAYER 明明存在现象工具报某个 LAYER 未定义去 LEF 里搜名字确实存在。原因大小写或者多余空格。LEF 的标识符对某些解析器是大小写敏感的Metal1和metal1会被当两个东西另一种情况是 LAYER 名后面跟了制表符工具把制表符也算进名字里。解决用grep -n Metal1和grep -nP Metal1\s两种模式交叉比对确认没有不可见字符。统一规范是层名全小写、后面只跟一个空格再接TYPE脚本生成时用strip()清理。4.3 NONDEFAULTRULE 在 DEF 里引用不到现象DEF 里 NONDEFAULTRULE wide2x报未定义LEF 里确实写了NONDEFAULTRULE wide2x。原因非默认规则的可见范围受文件加载顺序影响。如果工具先读 DEF 再读 LEF或者 LEF 只加载了部分规则就找不到。另一种原因是规则名超过了工具允许的字符长度被截断。解决确认加载顺序是 LEF 在前、DEF 在后把规则名控制在 32 字符以内加载后立刻在工具里查一次规则表确认条数与 LEF 中定义的数量一致不一致就说明有规则没进去。4.4 天线违例到 signoff 才爆出来现象布线阶段报告干净signoff 阶段突然出现成片天线违例返工成本极高。原因布线阶段读的 LEF 里没有ANTENNA*相关属性或者ANTENNAGATEAREA、ANTENNADIFFAREARATIO这些关键字写在了 MACRO 层而不是 PIN 层工具按缺省值处理等于没检查。解决在库交付前用脚本统计ANTENNA关键字出现次数与 PIN 数量做比值明显偏低就说明漏写。更进一步把天线比例检查前移到布线前的规则检查里别等 signoff。4.5 ALIAS 展开后行号全错现象LEF 里用了ALIAS做宏替换工具报错的行号指向展开后的逻辑行跟你手上的文件行号完全对不上排查全靠猜。原因ALIAS 是文本级展开手册第 215 页那一章明确写了展开规则。解析器在展开后才做语法分析报的行号自然是展开后的。解决临时把 ALIAS 全部展开成原始语句再排查定位到具体语句后再回到带 ALIAS 的版本改。长期做法是只在确实重复度极高的规则块上用 ALIAS别拿它当宏语言使。5. 天线效应与 PR 友好写法把附录变成可执行检查手册第 389 页起的那一章专讲工艺天线违例核心是几个比值连接到栅氧的金属面积与栅面积之比超过阈值就可能在等离子刻蚀阶段击穿栅氧。文档给的是计算口径和关键字定义落到流程里需要自己搭检查。5.1 天线比例的计算口径基本原则是分层累计从某个 PIN 出发沿着网络统计每一层金属连接到该 PIN 的总面积除以该 PIN 的栅面积得到这一层的天线比。多层的做法是逐层累加因为刻蚀是逐层进行的第 N 层刻蚀时下面所有已存在的金属都参与导电。手册里对应的关键字有ANTENNAGATEAREA、ANTENNAAREARATIO、ANTENNADIFFAREARATIO、ANTENNACUMAREARATIO、ANTENNAMAXAREACAR、ANTENNASIDEAREARATIO等分得比较细原因是不同工艺阶段对面积和侧壁面积的敏感度不同。关键字作用对象常见用途ANTENNAGATEAREAPIN给出栅面积基准ANTENNAAREARATIOPIN 或 LAYER金属面积比上限ANTENNADIFFAREARATIOPIN扩散区面积比上限ANTENNACUMAREARATIOPIN累计面积比上限ANTENNASIDEAREARATIOPIN侧壁面积比上限ANTENNAMAXAREACARPIN绝对面积上限这些属性写在 LEF 的 PIN 段里由库提供DEF 侧则在 PIN 或 COMPONENT 上引用ANTENNAMODEL等关键字标注模型。检查脚本要做的就是把两侧的属性读出来按层累加后跟阈值比。我一般会在库里加一条硬规则任何 PIN 如果没有ANTENNAGATEAREA直接判库不合格不进入流程。5.2 让 LEF 对 PR 友好的四个写法手册第 371 页的 Optimizing LEF Technology for Place and Route 给了几条很实在的建议翻译成可执行动作是四件事。第一布线 pitch 要与轨道对齐。PITCH如果不是MANUFACTURINGGRID的整数倍布线器铺出来的 track 会落在非网格点上DRC 阶段成片报错。第二宽金属间距用SPACINGTABLE表达别用一条常数糊弄宽线规则在小间距下会失效。第三通孔处的线延伸要写清楚手册里叫 wire extension at vias缺这个定义布线器会在 via 附近留出过短的线尾。第四默认通孔要定义完整VIARULE ... GENERATE里的层对、尺寸、间距三组参数缺一不可缺了工具会自己生成一套跟你预期的不一样。VIARULE via1_gen GENERATE LAYER Metal1 ; ENCLOSURE 0.05 0.02 ; LAYER via1 ; RECT -0.03 -0.03 0.03 0.03 ; LAYER Metal2 ; ENCLOSURE 0.02 0.05 ; END via1_genENCLOSURE是金属对通孔的包边两个数分别是水平、垂直方向。写反了不会报错但 DRC 会在某个方向上判包边不足而且只在特定朝向的走线上出现排查起来很费时间。5.3 一份可以照着勾的检查表交付前逐项过一遍比事后救火便宜得多。检查项判据失败后果UNITS 一致性LEF 与 DEF 倍率相同整体缩放、布局重叠语句闭合MACRO/VIA 数量与 END 匹配单元丢失坐标网格所有 RECT 落在 MANUFACTURINGGRIDDRC 批量违例PIN 覆盖每个 PIN 至少一个 PORT RECT引脚不可布非默认规则DEF 引用的规则名在 LEF 中存在读入中断天线属性每个 PIN 有 ANTENNAGATEAREAsignoff 阶段爆雷检查表本身不值钱值钱的是把它脚本化并挂到库发布的流水线上。人工勾选在第三个月一定会漏。6. 把参考手册变成团队基线一次 diff 抵十次排查手册读到后面会发现最有用的不是某条语法而是“哪些东西一旦变了就必须重新验证”这个判断力。我的做法是给每个库和每个关键 DEF 建一份基线快照只抽结构信息不存全文LEF 抽VERSION、UNITS、所有LAYER名与WIDTH/PITCH/SPACING、所有MACRO名与SIZEDEF 抽UNITS、DIEAREA、COMPONENTS行数与SPECIALNETS条数。每次库更新先跑一次 diff把变化项打出来再决定要不要全量回归。# 抽取 LEF 结构指纹用于版本间比对 awk /^[[:space:]]*(VERSION|UNITS|LAYER|MACRO|SITE)/ {print} /^[[:space:]]*(WIDTH|PITCH|SPACING|SIZE)/ {print} tech.lef tech.lef.fp diff -u baseline/tech.lef.fp tech.lef.fp | head -80awk只保留带关键属性的行输出体积能压到原文件的百分之几diff 结果人眼可读。head -80是防止一次改太多把终端刷爆真出现几百行差异说明这次更新不该按小版本处理。这个习惯来自一次教训某次只改了一个SPACING全量回归跑了六个小时才发现问题是它而有指纹比对的话五分钟就能定位到唯一变化项。从那以后我每次收库都强制走一遍指纹 diff哪怕对方说“只改了一个注释”。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询