CDL网表与LVS实战:从语法到版图提取的避坑指南
简介电路描述语言CDL教学演示文稿围绕C17基准电路系统讲解如何用该语言描述电路结构、连接关系和逻辑功能面向数字电路课程学习者、EDA入门者及需要完成电路描述实验报告的学生。内容先梳理语法规则将语句分为函数连接语句、说明语句和继续语句三类解释第一列空格、星号、等号的含义及标号长度限制再重点讲解与、或、与非、或非、异或、非等逻辑门语句以及扇出、输入、输出、电源、接地、结束等语句的书写格式。课件以C17电路为完整实例结合十七个结点、五个原始输入、两个原始输出、三个扇出点和六个扇出分支演示从输入管脚到输出管脚逐条编写的过程。同时介绍日本奈良大学用C语言编写的编译器说明它如何将描述转换为电路内部结构表包括元素表、前驱后继扩展表等要点。资源仅含一个PPT演示文稿文件压缩包约一百九十六KB便于下载后直接浏览目前已有七百五十八人学习下载适合作为课件补充或考前复习材料。1. 电路描述语言CDL一份能直接落地的网表语言电路描述语言CDL第一次见到它通常是一份后缀为.cdl的文本里面是一段一段的.SUBCKT写着M管、R、C和一堆节点名。它不是用来写逻辑的硬件描述语言也不是仿真脚本本职是把电路拓扑变成机器可以比较的文本——原理图导出一份版图提取出一份两份CDL放到一起做LVS一致性对比。后端验证、模拟设计、版图工程师都在跟它打交道。标题里带PPT意思是这套内容可以直接铺成一次内部技术分享的讲稿先看懂语法再走提取流程接着调参数把高频坑过一遍基本就能自己上手。2. CDL语法骨架从电路图到网表的映射规则CDL可以看成Spice家族里的一个方言子集但它比Spice仿真网表更“老实”不需要声明复杂的器件模型参数也通常不带寄生电阻电容只保留连接关系与几何尺寸。原理图上的一个MOS管、一节导线、一个端口在CDL里被映射成一行文本整个电路的层级关系被映射成子电路的嵌套。这个映射规则是所有后续工作的地基看不懂它后面LVS报的每一条错误都像天书。2.1 节点、器件与子电路CDL的三层结构先看一个最小电路CMOS反相器的CDL网表* CDL netlist for circuit INV1 .SUBCKT INV1 IN VDD VSS OUT M0 OUT IN VSS VSS NCH L0.18U W1.20U M1 M1 OUT IN VDD VDD PCH L0.18U W2.40U M1 .ENDS INV1第一行的*是注释符供人读不参与对比。.SUBCKT声明一个子电路后面第一个字段是子电路名从第二个字段开始就是端口列表IN、VDD、VSS、OUT。端口顺序很重要LVS做端口匹配时按位对应四个端口的排列一变对比结果就是另一回事。M0行是MOS管描述第一个节点是漏端OUT第二个是栅端IN第三个是源端VSS第四个是衬底VSS再往后是模型名NCH和几何参数L、W、M。M1是P管漏源栅衬底的顺序与M0一致只是衬底接VDD。这里的节点名不是坐标而是电学网络名。写反了连接关系CDL文本看起来合法LVS也能跑起来但对比结果全是错的。我见过有人把源漏对调后直接提交LVS报错上千条最后发现只是网表这一处笔误。M参数表示并联的器件数M0的W1.20U M1意味着这个管就是单指如果版图上画了四个并联等尺寸管提取出来的CDL经常合并写成一个M4的行目的是减小对比规模。LVS时M值合并开与不开直接影响对比粒度和后续仿真这个坑放到第5章细说。2.2 无源器件、控制语句与层级封装CDL不只描述MOS管带电阻电容的电路照样能写.SUBCKT RC_DRIVER IN OUT VDD VSS M0 OUT IN VSS VSS NCH L0.18U W1.20U M1 M1 OUT IN VDD VDD PCH L0.18U W2.40U M1 R0 OUT VDD 5.6K C0 OUT VSS 1.2P .ENDS RC_DRIVERR0是电阻实例节点顺序是正端、负端、阻值5.6K写成数字加单位后缀提取工具和LVS工具都能解析。C0同理OUT到VSS跨接一个1.2pF电容。无源器件的CDL写法比MOS管更宽松因为没有衬底节点也不一定有L/W信息提取时更多的是靠版图层次识别结果回填数值。原理图导出的CDL里电阻电容值是原理图符号上的标称值版图提取的CDL里这两个值是从几何图形算出来的。同一个电路两份文件数值略有差异很正常LVS对无源器件通常允许一定百分比容差这个容差在对比规则里单独配。除了器件行还有几个控制语句要认。.PARAM用来定义参数化几何比如.PARAM LMIN0.18U后面器件行就能写成LLMIN整个文件只改一处。.GLOBAL声明全局网络最常见的写法是.GLOBAL VDD VSS声明之后所有子电路里叫VDD的点都视为同一个电源网络不需要在每个.SUBCKT里重复定义。这句话不写有些工具会把不同层级的VDD当成两个孤立网络直接导致电源连接错误。.ENDS必须有任何一个.SUBCKT打开的括号都要闭合漏写会让解析器把后面所有内容都吞进上一个子电路里。层级封装是CDL里最容易被新人忽略的部分。一个真实的模拟IP不是扁平结构顶层电路会引用多个子电路子电路里还可能再套子电路。比如运放分成偏置电路、输入级、输出级每一级都是一个.SUBCKT块顶层只写实例引用。这种做法的直接好处是LVS支持hcell对比完全相同的子电路只比对一次剩下的是引用关系核对速度和资源占用都大幅下降。反过来如果网表全部摊平几百个相同单元逐个对比跑不动不说错误报告也难读。所以导网表之前先确认顶层层级是否保留这个开关通常在导出命令里叫hierarchy或者flatten选项具体叫法看环境。再补一个容易踩的概念混淆。CDL不是仿真网表它默认不带寄生参数也没有温度、工艺角属性直接拿去做spice仿真是缺材料的。很多仿真环境提供的“从版图提取后仿网表”是在CDL基础上补齐了模型参数和寄生RC而不是CDL本身。把两者分开记能省去不少拍脑袋查错的时间。3. 从版图和原理图产出CDL提取流程与最小命令有了语法基础接下来要解决最实际的问题两份CDL从哪里来。原理图侧通常由设计环境直接导出只需要点导出命令选格式版图侧则需要经历“导入版图数据、识别器件、提取连接、写出网表”四个阶段。流程里的命令名称和参数在不同环境差异很大但工作逻辑一致下面的命令都是示意写法实际使用时以你手上的工具命令为准。整个流程走顺之后LVS对比才有意义。3.1 原理图网表导出先解决端口一致性原理图导CDL是相对简单的动作常见的导出命令长得像这样# 导出原理图网表示意命令实际以当前环境命令为准 export_netlist -lib analog_lib -cell INV1 -view schematic \ -format cdl -out ./inv1_sch.cdl \ -hierarchy on -preserve_case yes -bus_bracket -lib、-cell、-view三个参数定位到具体的原理图对象-format cdl指定输出格式-out写输出路径-hierarchy on保留子电路层级尽量别关-preserve_case yes让大小写保持原样-bus_bracket 规定总线符号用什么括号。这些参数里最容易埋雷的是大小写和总线括号。某些环境默认会把节点名统一成大写或者把总线从7:0改成[7:0]一次导出后整个文件风格改变。如果版图侧提取时用的参数和这里一致问题不大不一致LVS就会报出大量看起来莫名其妙的net不匹配。导完第一件事不是直接拿去跑LVS而是打开文件看头部。一个合格的反相器CDL应该能看到.SUBCKT INV1 IN VDD VSS OUT端口顺序和你预期的原理图引脚顺序一致。我习惯顺手数一遍器件行数量和原理图里器件个数对照对不上就先查导出环节别把错误带到下一步。端口顺序在原理图符号和网表之间经常出现“视图不同导致顺序翻转”的问题符号左边画输入、右边画输出但正文里的端口列表如果按引脚创建顺序排列VDD可能排在IN前面。LVS对比时端口按位匹配顺序不一致就是满屏的connectivity error。3.2 版图提取与LVS最小流程从GDS到.cdl版图侧提取CDL是重头戏示意流程如下# 版图提取CDL示意命令实际以物理验证平台为准 extract -design ./inv1.gds -topcell INV1 \ -layermap ./rule/layermap.map \ -devicemap ./rule/device.map \ -out ./inv1_lay.cdl \ -mode LVS -extract_rc no-design指定版图数据源GDS是常见格式-topcell指定顶层单元名-layermap把GDS里的层号映射成工艺层名-devicemap决定哪些几何图形组合会被识别成MOS管、电阻、电容-mode LVS表示只提取连接拓扑和器件尺寸不输出寄生参数-extract_rc no顺手关掉RC提取跑LVS对比时不需要这些寄生值开着只会拖慢速度。提取出来的文件就是inv1_lay.cdl。拿到两份文件接着跑LVS对比# LVS对比示意命令 lvs -sch ./inv1_sch.cdl -lay ./inv1_lay.cdl \ -rule ./rule/lvs_rule.rules \ -out ./lvs_result.txt对比结果的报告文件里第一优先看两个数字connectivity errors和property errors。前者说明连接关系不一致器件连错、端口对不上、net名漂移都会归到这里后者说明连接一致但尺寸或参数数值超出容差比如W、L、M值对不上。连接错误全部清零之后再看property错误。很多新人看到connectivity errors为零就宣布通过结果忽略了一排property errors最后流片回来测出的电流和仿真差一大截回头查才发现是版图里某个管子的W比原理图小了0.02微米LVS报告里写得清清楚楚。整个提取流程依赖一张完整的文件清单缺一个都跑不起来。常见的最小集合包括版图数据文件、层映射表、器件映射表、LVS规则文件。层映射表解决“版图层号与工艺层名的对应”器件映射表解决“什么图形组合算一个器件”LVS规则文件里则写了电源地名称、对比容差、合并选项。这三类文件通常由工艺库提供后端工程师只是调用但拿到手先确认版本配套。工艺库更新后沿用旧映射表是最常见的一类“提不出来”事故原因不是命令错了而是表没跟上工艺版本。4. CDL参数怎么设命名、位序、映射与合并选项提取和对比过程中的几个关键参数决定LVS能不能一次通过也决定通过之后的结果是否可信。参数表看起来零散背后其实是同一个问题两份网表要用同一种语言说话。命名规则不一致对比时名字对不上位序不一致总线内部张冠李戴器件映射不一致同一个图形在这边是NMOS、在那边是空图形合并选项不一致拓扑看着一样但细节丢了。下面按影响面从大到小逐个说。4.1 命名规则大小写、特殊字符与总线位序的连锁反应CDL里的节点名就是文本串LVS对比本质上靠文本串做连接关系的等式匹配。等式匹配严格到什么程度取决于参数。大小写是最先翻车的地方。有的环境导出的网表统一把端口名转成大写VDD还是VDD但一个叫NetA的节点变成NETA原理图侧保持大小写混合两边立刻对不上。更隐蔽的是特殊字符节点名里的点号、斜杠、反引号在不同解析器眼里含义不同。比如用层次路径当节点名时A/B/C在某些工具里被解释为路径分隔另一些工具当成普通字符提取结果完全两样。.所以导出前把preserve_case明确设为yes并且规定整个项目统一用字母数字和下划线命名节点不引入特殊符号能从源头消除一批错误。总线位序的规则稍微复杂同一根总线两种写法可能指向完全不同的一束线d7:0 * 高位在前d7是最高位 d[0:7] * 低位在前d0配到低位bus_bracket参数决定用尖括号还是方括号位序声明决定MSB和LSB的排布方向。原理图侧和版图侧如果用了不同的约定提取出来的网表里同一根总线会被拆成两套名字LVS报错时你会看到一堆类似d[7]和d7的提示看着像同一条线实际是两个不同文本串。解决方式也很机械项目开始前定一个命名规范文档导出命令里的括号和位序选项全部按规范填不靠个人喜好。4.2 器件映射与合并选项直接决定对比粒度器件映射和合并参数是LVS结果可信度的关键列举一组最常用的参数及影响参数项常见选项主要影响推荐做法preserve_caseyes / no节点大小写是否保留固定yes统一规范bus_bracket / [ ]总线括号解析与项目规范一致hierarchy / flattenon / off子电路层级是否保留对比用on提速靠hcellmerge_by_Mon / off并联器件是否合并成M行LVS用on后仿校准用offextract_rcno / rc是否提取寄生RCLVS对比用nopower_netsVDD / AVDD 等识别全局电源地按工艺库定义填写device_tolerance百分比无源器件容差范围按流片方差留余量merge_by_M值得单独说明。开启后四个完全同尺寸的并联管会被合并成一行M4LVS对比速度快、报告简短适合日常快速检查。但合并操作会丢失每个管子的独立实例信息如果你要做后仿校准或者分析电流失配必须关掉这个选项保留四条独立器件行。我一般做法是LVS快速验证阶段开M合并进入后仿和可靠性检查阶段关掉重跑一遍两份报告都看。extract_rc在LVS时务必关掉否则提取器会把大量寄生电阻写进网表LVS对比对象从“纯拓扑”变成“带寄生的拓扑”对比结果容易被无谓的数值偏差干扰。等LVS拓扑确认无误再单独跑一次带RC的提取供后仿使用。hcell相关选项也归到这一组。开启hierarchy后多个相同子电路只对比一次LVS报告里会写“compared as hcell”速度提升明显。要注意hcell对比成功的前提是子电路内部完全一致器件尺寸、器件类型、内部net名全部一致。只要有一个管子的尺寸偏了0.01微米该子电路就会退出hcell优化被展开成独立电路重新对比。排查LVS速度突然变慢时先查报告里hcell命中率命中率低的通常是某个子电路被改动过却没同步到另一侧。5. CDL使用中的避坑指南五条高频踩坑记录CDL流程跑得越多越发现大部分报错不是逻辑难题而是约定不一致和文件版本错位。下面五条是实际工作中反复出现的情况按现象、原因、解决三段记录给同样被这类问题卡住的人一个排查顺序。5.1 端口顺序被翻转LVS报出一整片connection error现象原理图侧和版图侧都顺利导出了CDLLVS跑完connectivity errors上千条报告里几乎每个net都标着不匹配。单独看原理图网表和版图网表都“没错”可放一起就是全错。原因端口顺序不一致最常见的版本是原理图符号按照引脚创建顺序导出端口而版图顶层单元的端口顺序按物理位置排列两个顺序不同LVS按位匹配时第一对就错位后面全部连锁反应。解决解析两份CDL的.SUBCKT行人工核对端口列表。发现顺序不同在导出命令里指定端口顺序或者用文本工具调整其中一个文件把端口排成一致再跑。习惯性做法是在LVS规则里启用“端口按名字匹配”而不是按位置匹配能彻底免疫这类问题。5.2 M值合并让LVS通过后仿电流却对不上现象LVS报告通过connectivity和property都是零错误。拿提取网表去做后仿电流和预期差了百分之二三十怎么检查电路图都找不出原因。原因提取时把四个并联管合并成了M4LVS对比逻辑认为这没问题但后仿环境对待M4的器件模型与四个独立器件实例存在数值差异尤其是匹配敏感结构和靠近边界的器件这种差异会被放大。解决后仿前用merge_by_M off重新提取一版CDL确认四条独立器件行都在再转成仿真网表。LVS通过只代表拓扑一致不代表后仿网表保留了足够的细节两件事要分开验证。5.3 电阻被识别成孤立图形报unmapped device现象版图提取的CDL里电阻缺失LVS报告提示存在无法识别的图形。版图上电阻区域看得很清楚提取器就是不认。原因器件映射表里电阻识别条件没有配全。常见的是少配了阻值层或者传感器层例如扩散电阻缺少silicide block层标记提取器不知道这段图形是电阻直接当成普通连接图形处理。解决翻器件映射表对照工艺文档补齐电阻的识别条件和阻值计算层。改完重新提取前先跑一个小规模测试单元确认电阻被正确识别再整芯片提取避免反复跑大版图浪费时间。5.4 版图看着没搭上LVS却报short现象版图上两条走线隔着空隙视觉上没有任何接触LVS却报这两个net short。放大到局部层看还是找不到连接点。原因连接层的定义比视觉更宽。某些情况下同一层金属图形确实没有直接相交但通孔层提取时把上下两层金属的接触区域判定为连接而这两层金属分属不同net更多的case是layer map里把两层不该合并的层映射成了同一个工艺层名提取器自然认为它们是一体的。解决先查层映射表确认所有涉及连接和通孔的层都一一对应没有误合并。再查LVS规则里的连接层定义确认哪些层被视为“连接层”。改完以后重新提取并跑一次小范围对比确认short消失再上全芯片。5.5 层映射表没更新整个cell被当成空器件现象版图数据更新到新版工艺后提取出来的CDL里部分cell器件数为零或者器件的L、W数值异常LVS报告显示一堆尺寸错误。原因层映射表还停留在旧版工艺。新版工艺改了层次划分比如新增了某层做注入阻挡旧映射表不认识这个新层号导致器件识别区域被错误裁剪出现“该识别成管的图形没识别到”。解决从工艺库重新获取当前版本的层映射表和器件映射表替换旧文件后重跑提取。排查时先看提取日志里的warning凡是提示“layer number not mapped”都要处理不能忽略着往下跑。6. 把CDL用到更深处脚本体检与一份可复用的讲解稿流程跑顺之后可以做一点自动化来兜底。这里给一个极简的CDL体检脚本用来快速核对两份网表的端口集合和器件数量适合在每次LVS前当“冒烟测试”跑一遍# check_cdl_diff.py 用法: # python check_cdl_diff.py inv1_sch.cdl inv1_lay.cdl import sys, re def parse(path): ports, devices [], [] in_sub False for line in open(path, errorsignore): line line.split(*)[0].strip() if line.startswith(.SUBCKT): in_sub True ports line.split()[1:] continue if line.startswith(.ENDS): in_sub False continue if in_sub and line: dev line.split()[0] if re.match(r^[MCRLQD]$, dev): devices.append(dev) return set(ports), devices p1, d1 parse(sys.argv[1]) p2, d2 parse(sys.argv[2]) print(端口差异-仅原理图侧:, p1 - p2) print(端口差异-仅版图侧:, p2 - p1) print(原理图器件数:, len(d1), 版图器件数:, len(d2))parse函数按行处理遇到.开头的行先拆掉注释再判断.SUBCKT行取第一个字段后面的所有内容作为端口集合器件行只认M、C、R、L、Q、D这几种首字母。脚本不能替代正式LVS但能在几秒内发现端口或数量的明显偏差省去直接跑大LVS排错的等待。参数就是两个CDL文件路径顺序无所谓。标题既然带着PPT最后给一份可以直接铺成讲稿的内容分配建议语法部分占两成挑一个.SUBCKT当场拆解提取流程占四成最值得现场演示的是“同一份版图开和关merge_by_M两次提取结果的差异”参数设置占两成重点讲命名规则和位序高频坑占两成挑本笔记里端口翻转和M值合并两条讲听众最有共鸣。每讲完一节就放一次真实报告截图比纯讲概念有效得多。我做这件事早期吃过一个亏原理图网表和版图网表一起报错上千条排查了一下午才发现是电源地端口顺序颠倒了。那次之后养成了习惯拿到任何CDL先看.SUBCKT行再数器件个数最后才跑对比。这个三步检查法至今受用。希望帮到你。本文还有配套的精品资源点击获取