☰
PrimeTime生成.lib时PG引脚丢失与pg_type错误排查实战
2026/10/2 8:02:35 网站建设 项目流程

上周接到一个“小活”:用PrimeTime给顶层交付一个SRAM宏单元的.lib模型。原以为只是跑一遍write_lib的简单工序,结果生成的.lib文件里,PG引脚部分出了问题——这里的PG是Power/Ground,也就是电源和地引脚。下游Voltus功耗分析直接报错,MVRC检查也弹出一堆“missing power pin”。排查到最后才发现,问题既不在reference库,也不在网表里,恰恰藏在PrimeTime自己“生成.lib时往文件里添加PG引脚定义”的逻辑中。

这篇把完整过程记录下来,给同样在用PrimeTime产出.lib的兄弟团队一个参考。不管你是做库特征化、IP集成,还是给顶层提供时序模型,只要你的单元带多电源域、backup电源、内部电源,尤其是要输出Liberty文件供其他工具解析的,建议把这篇看完。这个坑的触发概率,远比我原来以为的高得多。

1. 交付一个SRAM宏单元.lib,活不大坑不小

1.1 什么场景会用PrimeTime直接输出.lib

按教科书流程,.lib应该是库特征化工具的产物,SiliconSmart、Liberate、NCX这些工具才负责把SPICE网表变成包含时序、功耗、约束信息的库文件。但实际后端流程里,有几种情况会贪图方便直接用PrimeTime来生成.lib:

  • 宏单元快速建模:SRAM、PLL、DDR PHY这类大宏在PR完成后,为了给顶层提供足够的时序精度又不想暴露内部结构,常用extract_model提取接口时序,再通过write_lib输出成标准.lib。
  • 库格式互转:手上只有编译过的.db,下游某个工具却非要文本.lib不可,很多人会直接用PT读回.db再写出去,图个省事。
  • 时序签核附带的模型交付:PT做STA签核的同时,顺手给顶层或封装/硅后验证导出一份库参考模型。

这些场景的共同点是:我们并不期望PT去做特征化,只是让PT把它已经“知道”的东西按Liberty语法转述出来。麻烦就出在这里——PT是一个时序引擎,它最擅长的是延迟计算,PG信息对它是“附属品”,是转述的、代理的,而这条转述链路里,恰恰藏着Bug。

1.2 任务背景:一个带三组电源引脚的SRAM宏单元

我这次的SRAM宏单元,电压域设计如下:

引脚名电压域预期pg_type说明
VDD0.9V 核心primary_power逻辑供电
VDDM0.72V 阵列internal_power存储阵列/位线供电
VDDPST1.8V IObackup_power快速唤醒备份域
VSS0Vprimary_ground地

宏单元在reference lib里的PG定义是完整的,netlist也通过UPF做了供电端口映射。我当时操作路径很简单:读入网表和SRAM宏单元的reference .db库,用extract_model提取接口时序模型,最后用write_lib -format lib导出供顶层的Voltus和MVRC使用。

三步操作,看起来十分钟能交差。结果恰恰就在第三步出了幺蛾子。

2. 生成的.lib有两个“典型病例”:PG引脚消失和电源类型认亲错误

2.1 病例一:backup电源引脚在文本里直接蒸发

第一版.lib交给验证组,很快就收到MVRC的一堆“missing power pin”报错。我打开生成的.lib文件去核,发现了一个诡异现象:文件里VDD、VSS都好好写着,但VDDPST的PG定义整个不见了。更离谱的是,它不是被简单地漏掉,而是被写到了一个完全错误的层级——挂到了某个leaf cell底下,而不是宏单元顶层端口上。

我立刻反查reference lib里的db信息,SRAM宏单元的端口列表里VDDPST明明存在。也就是说,PT在write_lib的“PG添加”阶段,把宏单元顶层这组PG端口漏掉了,或者错放到了子模块下。当时第一反应是怀疑自己命令写错了,反复检查extract_model的边界设置和write_lib的选项,都没问题。

2.2 病例二:pg_type张冠李戴,Voltus把VDDM当主电源

修完引脚“蒸发”的问题后复查,又发现更隐蔽的第二问题:VDDM的pg_type被写成了primary_power,而不是它应有的internal_power;VDDPST则被标成了primary_power,而不是backup_power。

这个错误的危害比引脚丢失还大。Voltus识别电源域靠的就是pg_type和voltage_name。当.lib里出现两个primary_power时,IR drop分析会认为VDD和VDDPST属于同一电压域,导致:

  • 把1.8V的IO电源和0.9V核心电源的网络合并计算;
  • 对power mesh做错误的电流密度分配;
  • Multi-domain检查时报“multiple primary power”错误。

用户层面看到的结果,就是功耗分析数据要么离谱地好(漏报真正的压降瓶颈),要么离谱地差(把backup电源压降全算到核心域上)。这种东西一旦流片前才被发现,那就不是加两天班能解决的事。

2.3 下游工具的连锁反应清单

把这两类问题的实际影响完整列一下,方便各位对照自己的场景:

下游工具症状根因
MVRC / LQA“Missing PG pin” / “Duplicate pg_type”PG引脚丢失 / pg_type写错
Voltus电源域映射错误 / IR drop异常primary_power重复
顶层UPF连接connect_supply_net无法绑定引脚lib端口缺失或名称不匹配
布局布线工具读入电源引脚连接自动悬空PG端口缺失
自家脚本解析Liberty解析器报错PG语法/层级异常

只要是带多电源域的宏单元,上面任何一项都足以让交付延期。而且这类错误往往不在第一时间暴露——时序仿真是能过的,逻辑功能也是对的,一直到功耗分析或者顶层UPF连接阶段才会爆出来,定位成本和修改成本都翻倍。

3. 根因排查:从质疑reference库开始,最后锤到PT自己的write_lib逻辑

3.1 先排掉reference库和db编译的嫌疑

按照标准排查流程,先做排除法。第一步是确认reference .db本身没有丢信息。我在PT里直接检查SRAM宏单元的PG引脚:

# 检查reference库里SRAM宏单元的PG引脚定义 foreach_in_collection cell [get_lib_cells sram_lib/SRAM_CORE] { set pg_pins [get_lib_pins $cell/* -quiet -filter "pg_type!=\"\""] if {[sizeof_collection $pg_pins] > 0} { puts "cell: [get_object_name $cell]" foreach_in_collection pin $pg_pins { puts " pin: [get_object_name $pin] pg_type: [get_attribute $pin pg_type]" } } }

输出结果让人放心:VDD、VDDM、VDDPST、VSS四个端口的pg_type、voltage_name、related_power_pin、related_ground_pin全部正确,连is_pad、leakage_power这类边角属性都在。说明reference库不是犯人。

接着我用Library Compiler把原始.lib文本重新编译成db再反解回来,PG信息依然完整。这一步证明db编译环节也没有丢数据。

3.2 最小化实验复现:一个Inverter就能触发

到这里,我已经基本排除“我的宏单元特殊”这个假设。于是构造了最小测试环境:一个只含inverter单元的网表,inverter端口带VDD和VSS两个PG pin,reference库里的定义完全标准。

跑同样的 read_netlist → link → write_lib 流程,问题居然复现了。inverter的VSS在生成库中直接“消失”,或者pg_type整体错乱。这非常关键——说明这不是SRAM宏单元特殊结构造成的偶发,而是PT在基础单元上就能触发的通用路径Bug。

我把这个案例丢给搭环境时用的临时脚本,反复改了几次UPF写法、网表连接顺序,问题依旧。到这一步,我的怀疑对象已经从“我的流程配置”彻底转向“工具本身的write_lib行为”。

3.3 write_lib的PG添加逻辑:理解工具在做什么、错在哪里

在进一步调参数之前,值得花点时间把PT生成.lib时的PG信息来源讲清楚。这个理解很重要,因为很多人踩坑后第一反应是去改网表、改UPF,改几版都没用,就是因为对工具的“转述”机制没有概念。

PT在write_lib时,PG信息的来源主要有三条:

  1. 直接继承:reference .db里已有的pg_type、voltage_name等定义。理论上PT应该原样透传;
  2. 网表推断:当reference库里PG定义不完整(有些时序库确实不写PG),PT会根据网表的supply net连接关系、UPF供电端口定义去“补”PG信息;
  3. 内部默认兜底:对完全无PG信息的设计,PT用内部默认规则生成一套PG引脚。

我的案例里,PG信息属于第1条来源,理论上应该无损透传。但实际输出却错了,说明PT在write_lib内部还有一个“PG信息规整”阶段:它把各种来源的PG信息统一成内部表,再按照目标Liberty版本规则生成文本。这个规整逻辑对单电源引脚单元没问题,但对多电源引脚数量超过两个、且引脚命名不符合VDD/VSS惯例的单元,会在排序和去重阶段把引脚错误合并或错误标记。

VDDM、VDDPST这类名字一旦被内部规则按“VDD开头就归入主电源域”来处理,pg_type就被强行改写成了primary_power;某些引脚则会因为命名空间的冲突,在这个阶段被直接丢弃,于是出现我看到的“蒸发”现象。

p.s. 由于PT不允许用户在write_lib时手动指定每个引脚的pg_type,这个规整阶段一旦出错,你几乎没有干预的余地。这也是我最后选择脚本兜底的直接原因。

3.4 关底:在release note里找到了对应的known issue

完成最小复现后,我查了手头PT版本(2022.06)的release note,果然在Known Issues部分找到了对应记录,大意是:当write_lib输出包含多电源域单元的库文件时,PG引脚定义可能丢失或被错误标记,受影响的是Liberty 2018+语法输出路径。

另外发现一个关键细节:这个问题只在较新的Liberty语法路径下触发。当我们把输出语法强制回退到2009.12版本时,PG信息一切正常。这个线索直接奠定了后面的应急方案。

4. 画一下雷区:哪些lib生成流程最容易踩中

4.1 多电源域/backup域的宏单元模型导出

最容易踩中的就是本文场景:宏单元带着多套电压域,PG引脚数量超过两组,且命名不是标准的VDD/VSS。SRAM、寄存器堆、带IO PAD的接口宏、含有DVFS单元的block,都属于高危对象。

这些单元几乎绕不开PT,因为顶层集成通常只信任PT生成的时序模型。而且越是大宏,PG引脚越多,命名越花哨(比如VDD_CORE、VDDIO_MEM、VDDM_A、VSS_IO),越容易触发内部规整逻辑的误判。

4.2 用write_lib把.db“转回”文本.lib的运维操作

第二个高危流程是库格式互转。很多团队会习惯性地把PT当成“免费的lib转文本工具”:拿到一个.db,read_db然后write_lib -format lib,以为拿到了等价文本库。

在单电源域库上,这个操作问题不大。但一旦库里出现backup电源、内部电源、nwell_power这类非主域PG,转出来的文本就有很大概率在PG段出现上述Bug。最麻烦的是转完没人抽查,等下游流片前用MVRC审查时才发现,波及面已经铺开。

4.3 ETM模型导出和UPF感知的lib生成

第三个雷区是extract_model提ETM再导出.lib的场景。ETM本身关心的是接口时序,但导出文本.lib时PT会把PG信息一并生成。如果原设计有UPF定义的多域供电,而ETM提取的边界又恰好切在某个电源域中间,PG添加逻辑更容易“想当然”地帮你补一组错误的域定义。

ETM交付给顶层后,顶层做UPF连接时会报找不到引脚或电压域不匹配。这个场景比前两种更隐蔽,因为ETM的时序验证可能全绿,问题只会在顶层功耗分析阶段炸出来。

5. 绕坑实战:三套能落地的规避方案

5.1 应急:强制Liberty语法版本回退,绕开新语法路径

既然是Liberty新语法路径上的Bug,最快的应急方案就是让PT输出旧版Liberty语法。对PT来说,write_lib对语法版本的控制选项一般是-version:

# 输出Liberty 2009.12语法,PG引脚使用传统pin + pg_type块 write_lib -format lib -version 2009.12 -output ./sram_model_old.lib

输出后检查一下PG段,应该能看到传统的:

pin (VDDM) { direction : inout; pg_type : internal_power; voltage_name : "VDDM"; related_power_pin : VDD; related_ground_pin : VSS; }

而不是出问题的pg_pin块写法。注意,不同PT版本对-version的选项名称和支持范围有差异,执行前先write_lib -help确认一下。

这个方案成本最低,但不要过于乐观。如果你的下游工具强制要求Liberty 2018+语法,这条应急路径就不够用,得走脚本修复方案。

5.2 兜底:脚本自动修复pg_type与related_pin映射

如果格式版本不能妥协,那就上脚本。核心思路是:以reference lib的PG定义作为黄金标准,用脚本对比并修正生成lib的PG部分。我用的Python脚本骨架如下:

import re # 黄金标准:pin_name -> (pg_type, related_power, related_ground) GOLDEN = { 'VDD': ('primary_power', 'VDD', 'VSS'), 'VDDM': ('internal_power', 'VDD', 'VSS'), 'VDDPST': ('backup_power', 'VDDPST', 'VSS'), 'VSS': ('primary_ground', 'VDD', 'VSS'), } def fix_pg_section(lib_text: str) -> str: # 按cell块切分,对每个块内的PG引脚覆写pg_type和related_*字段 # 省略逐块解析细节,核心逻辑是按名字匹配GOLDEN表后覆写 for pin_name, (pg_type, related_power, related_ground) in GOLDEN.items(): # 在lib文本中找到对应pin块并替换pg_type等属性 pass return lib_text if __name__ == '__main__': with open('sram_bug.lib', 'r') as f: fixed = fix_pg_section(f.read()) with open('sram_fixed.lib', 'w') as f: f.write(fixed)

实际实现时不要真用这个精简版,建议对文本做块级正则替换,替换前先定位每个cell块的边界,避免误伤同名字的信号引脚。替换后做一轮二次校验:解析每个cell块的PG引脚数量,和GOLDEN表数量比对,即使顺序错乱也没关系,按名字匹配后覆写字段即可。

我自己的习惯是修正后不着急交付,先用reference lib对PG部分做一次结构化diff,确认没有多写、漏写,再往下游送。这一步五分钟能完成,但能挡住绝大多数二次事故。

5.3 彻底:该走特征化工具的流程不要省

最后说点劝退的话。如果你发现“用PT生成.lib”不是偶发一次的应急动作,而是反复出现的需求,那我强烈建议把正规特征化工具(SiliconSmart / Liberate / NCX)纳入流程。

PT生成.lib只是附带能力,用户没法精细控制PG语法细节,出了问题只能绕。而特征化工具生来就是管这事儿的,PG引脚定义、电压域映射、QA报告都是围绕.lib交付设计的。受控、可回归、可批量。省下的那点license时间,远不够填一次PG漏配导致的IR drop重跑成本。

6. 这次踩坑换来的几条后端经验

6.1 lib交付前,PG冒烟检查必须做

这次事故以后,我给自己组的lib交付流程强制加了PG冒烟检查。检查内容不多,就三件事:

  1. 单元端口数 = lib中PG引脚数 + 信号引脚数;
  2. 每组PG引脚的pg_type与UPF里的供电域定义一一对应;
  3. voltage_name和库文档里的工作电压一致。

三件事用脚本自动化,耗时不超过五分钟,但能在第一时间把这类工具Bug挡在交付线外。上次踩坑时,我还抱着“PT转写不会错”的侥幸心理,省了这一步,结果赔了整整两个工作日。

6.2 EDA工具版本行为会漂移,升级后要回归

这条经验可能比PG Bug本身更重要。我这次用的PT是从老版本升上来的,升级前同样一条命令产出的.lib没有任何问题,升级后就突然翻车。EDA工具在小版本升级里改行为、改默认值、改语法兼容策略,是常有的事。

凡是交付物高度依赖工具“默认行为”的环节,工具升级后必须做一轮回归,不能只看时序结果没变就放行。我现在的习惯是:每次工具版本变更后,抽一个代表单元重新走一遍.lib生成流程,和旧版本输出做diff,PG信息有没有变化一眼就能看清。

6.3 库文本里的PG信息,是全流程的“电源宪法”

最后说一个认知层面的收获:.lib文本里的PG信息在数字后端全流程里是“电源宪法”级别的存在。综合工具靠它识别电源引脚,布局布线靠它连接pg net,功耗分析靠它划分电压域,MVRC靠它做一致性审查。

而恰恰是这个关键字段,在PT这类时序工具的“转述”链路上最容易出问题。它错得越晚暴露,修复成本越高。凡是经过PT、LC等工具二次转述出来的.lib,PG部分一定要拿reference库做对照,别默认“工具转写不会错”。

最后再分享一个小技巧:检查PG信息时,别只看lib文件里PG引脚的名称在不在,还要用get_lib_pins -filter "pg_type!= \"\""把每个引脚的pg_type、related_power_pin、related_ground_pin三个字段全部打出来和对一遍。名称和类型有一项对不上,后面的功耗分析都是在给定时炸弹倒计时。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询