ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

SDF反标在数模混合仿真中的正确姿势:Cadence环境踩坑全记录

SDF反标在数模混合仿真中的正确姿势:Cadence环境踩坑全记录 做数模混合验证这几年我踩过最隐蔽的坑就是数字那半边时序。模拟模块在Spectre里跑得好好的数字控制逻辑在Xcelium里也叠得飞快可一旦把后端返给的门级网表和SDFStandard Delay Format反标进去整个系统的行为就全变了。前阵子一颗电源管理芯片客户反馈I2C配置时序和仿真对不上我翻遍测试bench才发现混仿环境里数字部分一直跑的是RTL行为级根本没有反标SDF仿真结果自然比实测乐观太多。这篇文章就围绕“Cadence数模混合仿真反标SDF”这个事把我在Virtuoso Xcelium AMS环境下做门级时序反标的完整流程、命令、参数和踩坑记录整理出来。适合正在做数字模拟混合信号验证、后端时序收敛核对或者被“为什么仿真时序和实测差那么多”折磨的工程师参考。1. 先搞懂SDF反标在数模混仿里解决什么问题1.1 SDF到底“标”了什么SDF全称Standard Delay Format是EDA行业通用的延迟标准格式文件。它本身不包含电路逻辑只描述延迟和时序约束信息靠仿真器在编译网表时把这些延迟“贴”到对应的单元和路径上。这个动作就是反标英文叫SDF annotation。打开一个后端给的SDF文件里面基本是三块内容。第一块是单元延迟典型的是IOPATH定义输入引脚到输出引脚的传播延迟比如数据从D端到Q端的clk-to-q时间第二块是互连线延迟INTERCONNECT定义网络中不同节点之间的RC延迟第三块是时序检查TIMINGCHECK包括setup、hold、width、recovery、removal这些约束。我拿一小段真实的SDF片段给你们感觉一下(DELAYFILE (SDFVERSION OVI 3.0) (DESIGN pmic_top) (TIMESCALE 1ns) (CELL (CELLTYPE AND2X1) (INSTANCE u_dig_top/u_glue/u_and1) (DELAY (ABSOLUTE (IOPATH a y (0.051:0.072:0.099) (0.056:0.081:0.128)) ) ) (TIMINGCHECK (SETUPHOLD data clk (0.012::0.015) (0.008::0.010)) ) ) )注意里面三组数字用冒号分隔分别对应最小、典型、最大三种工艺角下的延迟值。后面实操部分会讲怎么选这三组值这里先记住一个核心结论SDF反标的本质是把后端经过布局布线提取出来的真实时序信息注入到数字门级网表的仿真中。1.2 不反标的数字域仿真有多“理想”很多混仿验证工程师习惯在数字部分直接用RTL行为级模型。RTL本身没有门延迟一个always块里的组合逻辑在一个时间步内就全部算完时钟边沿一到所有信号瞬间翻转。这在功能验证阶段没问题但在做系统级数模混合仿真时会造成三个非常现实的失真。第一个失真是接口时序失真。数字模块和模拟模块交界处的使能信号、配置寄存器、状态机切换如果没有门延迟信号翻转看起来永远干净利落但真实芯片上组合逻辑和时钟树的延迟可能让某些信号在临界窗口内变化导致模拟模块误触发。第二个失真是竞争风险失真。RTL仿真里两个信号几乎同时到达但门级网表里可能因为布线延迟出现实际上的先后顺序不反标就永远看不到这种风险。第三个失真是功耗和电流评估失真。数字翻转太快太集中模拟模块看到的负载变化太理想化评估出来的电源噪声和地弹完全不真实。说到底SDF反标在数模混仿里的价值是让数字不再是“理想世界里的数字”而是能跟模拟一起反映真实硅片行为的数字。1.3 哪些场景必须反标哪些场景可以省不是所有混仿都要反标。按我的经验数字部分如果只是为了验证功能连接关系比如模拟模块上电顺序、寄存器读写通路是否正确跑RTL行为级完全足够速度还快。但如果要做下面这几类验证SDF反标躲不掉第一类是IO时序和接口协议验证。SPI、I2C、GPIO这类对外接口数字模块的输出延迟直接影响协议时序是否满足不反标就会出现仿真通过、实测失败。第二类是时钟域交互验证。芯片里有多个时钟源其中可能有来自模拟模块的PLL或RC振荡器时钟数字时钟树延迟不一致时跨时钟域的亚稳态风险必须靠反标后的仿真暴露。第三类是上下电时序和复位释放验证。PORPower-On Reset信号从模拟模块出来后数字逻辑需要在规定时间内完成复位释放这个时间窗和后端延迟强相关。当然也有不需要反标的情况。比如数字模块只是一个简单的I2C从机接口模拟模块验证重点在bandgap或LDO特性接口时序不是关注点那可以先不反标等系统级分析时再统一加。我做项目时习惯分两轮跑功能验证阶段跑RTL模型时序验收阶段再切到门级网表加SDF。2. 反标前的准备视图、库文件、SDF来源2.1 SDF文件从哪里来综合约束与STA导出拿到SDF文件前先搞清楚它是什么阶段生成的因为不同来源的SDF包含的信息差别很大。综合工具比如Design Compiler导出的SDF只有单元延迟和简单的互连估算没有实际布线的RC信息时序精度有限后端布局布线完成后通过Tempus或PrimeTime这类STA工具提取出来的SDF才包含真实的互连延迟和完整时序检查。我做混仿时基本只用PR后导出的SDF并且要求后端工程师同时给出三份最慢工艺角slow、最快工艺角fast和典型工艺角typ。默认情况下仿真器会取三组延迟中的中间值也就是典型值但如果你要验证特定场景比如低电压低温下的建立时间风险就要用慢速角对应的SDF这时需要在反标时明确指定max那一列。还有一个很多人忽略的点SDF文件里的DESIGN名称和CELLTYPE名称必须和数字门级网表以及标准单元库的仿真模型完全一致。如果后端用的是DC综合时的库名但网表里是另一套库名反标时大量cell对不上annotation比例会很难看。2.2 数字单元视图选错反标直接白做Candence Virtuoso环境里做混仿数字部分在config view里怎么选视图直接决定SDF能不能标进去。很多工程师在这里栽跟头。config view是数模混合仿真的层次配置中心它决定每个实例用哪个视图参与仿真。模拟模块一般用schematic或auCdl数字模块常见的选择有functional、verilogdigview、netlist等。如果你的数字模块选的是functional或者behavioral视图里面是行为级Verilog代码根本没有门单元SDF反标进去也找不到对应cell。正确做法是让数字模块引用后端的门级网表视图通常是verilog.netlist或者类似名字的视图这个视图里才是真正的标准单元实例。操作上在Virtuoso里打开config view选中数字模块所在行右键菜单里可以切换Cellview Type也可以直接在view列手动改成门级网表对应的视图名。改完之后一定要重新生成netlist并且检查config里数字模块前面的符号确保它确实被识别为数字网表而不是当成模拟子电路。2.3 connect module对时序边界的影响数模混仿中数字域和模拟域之间通过connect moduleUCMUnified Connect Module交换信号。模拟信号要通过a2d模块转成数字电平数字输出要通过d2a模块转成模拟电压。SDF反标之后数字域的延迟变大connect module能否跟上这个节奏是边界时序失真的隐藏风险。经验上有两个关系较大的设置。一个是a2d的阈值转换点如果模拟模块输出缓慢爬升connect module需要根据数字库定义的VIH/VIL阈值判断翻转时刻SDF引入后这个翻转时刻会进一步偏移可能造成数字逻辑采到的电平与预期不同。另一个是connect module本身也是有延迟的虽然通常很小但在精确分析接口时序时建议在connect module配置里显式关闭或设定其传播延迟避免和SDF延迟叠加产生误导。我习惯在做反标后的混仿时先把connect module的延迟设成0单独看数字门延迟的影响确认无误后再把真实延迟打开看整个环路的时序余量。2.4 库仿真模型必须支持反标这个坑很隐蔽。数字标准单元库交付的时候通常会附带仿真模型常见的有Verilog和VHDL两种。但不是所有库模型都支持SDF反标。支持反标的库模型内部每个cell都有specify块和$setup、$hold、$width这类时序检查系统任务仿真器通过specify路径和SDF里的IOPATH一一对应。如果库模型是简化版或者某些定制单元用了行为级描述SDF对应不上反标比例会下降。最典型的是PLL、SRAM、Flash控制器这类定制宏单元它们通常不在SDF覆盖范围内需要单独处理。碰到这种情况我有两个建议。第一反标前先检查日志里SDF annotation percentage如果低于95%一定要定位是哪部分cell没标上不能带病往下跑。第二对定制宏单元如果它有独立的时序模型文件通过SDF里的CELLTYPE或者反标映射单独指定如果没有至少保证宏单元周围的标准单元时序是正确的。3. 实操在Cadence环境里完成SDF反标3.1 路线选择命令行还是Virtuoso图形界面Cadence数模混仿现在主流是基于Xcelium AMS跑也就是xrun加上-ams开关把数字Verilog/VHDL和模拟Spectre网表联合起来仿真。实现SDF反标有两条路线一条是在xrun命令行里直接加SDF反标参数适合跑回归、做脚本化验证另一条是在Virtuoso ADE环境里通过config view和图形界面配置反标适合交互式调试和波形分析。这两条路线的本质一样都是往xrun命令里注入SDF反标指令只是形式和方便程度不同。命令行脚本化的优点是可重复、易纳入CI缺点是第一次配置要花时间理解层次路径图形界面优点是点一点就能看到效果缺点是版本不同菜单位置差异大而且不便于批量回归。我个人建议调试阶段用图形界面因为可以快速改配置看波形回归阶段用命令行因为要跑几十上百个case自动化才是王道。3.2 方法Axrun -ams命令行反标下面用一个简化过的PMIC芯片混仿场景举例。假设testbench顶层叫tb_pmic数字子系统实例叫u_dig_top后端给的SDF在./data/digital_typ.sdf。数字门级网表在filelist_digital.f里模拟网表在netlist.spi里。命令行可以这样组织xrun -ams \ -hal \ -v93 \ -f filelist_digital.f \ -f filelist_analog.f \ defineAMS \ sdf_file./data/digital_typ.sdftb_pmic.u_dig_top \ neg_tchk \ sdf_verbose \ -access rwc \ -status \ -run -q这里几个参数拆开说。-ams让xrun进入数模混合仿真模式-hal是允许混合抽象级别仿真数字部分和模拟部分可以用不同抽象级。最关键的是sdf_file./data/digital_typ.sdftb_pmic.u_dig_top这个参数做了两件事指定SDF文件路径同时指定从哪个层次开始反标也就是SDF内部INSTANCE路径的“根”。如果你的testbench层次里数字模块实例路径是tb_pmic.u_dig_top而SDF内部路径是从u_dig_top开始往下写的那这个映射就是对的。如果SDF内部的INSTANCE写成tb_pmic.u_dig_top.xxx那反标起点就要改成tb_pmic否则路径对不上。neg_tchk是允许负数时序检查。后端提取时序时有些cell的setup或hold计算出来是负值正常情况下仿真器会忽略负的timing check但这和真实硅片行为不符所以显式打开这个开关更贴近实际。sdf_verbose让仿真器把所有SDF反标细节打印出来建议第一次跑时务必加上后面排查问题全靠它。3.3 方法BVirtuoso ADE config view反标如果你的环境是拿Virtuoso画testbench用ADEXL跑混仿那我更推荐走图形界面方式。第一步在ADEXL里创建或打开config view。点左边窗口的config在这个界面里能看到所有数字模拟模块的配置行。第二步找到数字子系统那一行确认view列是否为门级网表视图。如果不是点右键选择Change Cellview Type或者手动把view改成netlist对应的名字。第三步在仿真的Setup里找到Xcelium相关的Options选项不同Cadence版本位置不太一样。以IC6.1.8加Xcelium 19.03为例我在ADEXL里通常是点Setup - Simulation Options在打开的窗口里找到Xcelium AMS选项卡里面有一个User Defined Arguments或者类似的输入框把SDF反标参数整行填进去sdf_file./data/digital_typ.sdftb_pmic.u_dig_top neg_tchk sdf_verbose填完之后保存启动仿真。这一步的本质和命令行完全一样只是xrun是后台启动的你写进User Defined Arguments的内容会被追加到xrun调用后面。如果版本较老的用ADE L路径则是Simulation - Options - Analog把参数写在Command Line Options里。关键是搞清楚你的版本里哪个入口能改xrun参数。3.4 怎么看反标日志和结果反标是不是成功不要听天由命要看日志。启动仿真后去仿真目录下找到xrun.log或者类似名字的日志文件搜几个关键词。第一个搜SDF File确认SDF文件被识别版本号是多少TIMESCALE是多少。第二个搜Annotation看完成的注解比例Cadence会打印类似这样的信息SDF Backannotation Report: SDF File: ./data/digital_typ.sdf Design: pmic_top Number of annotated cells: 128456 Annotation percentage: 99.98%如果annotation percentage在95%以下说明有大量cell没标上这种仿真结果不能用来做时序判断。第三个搜Warning或Error重点看有没有SDFNOP、SDFINF这类警告。SDFNOP表示SDF文件里有某个cell在网表中找不到对应实例基本可以断定是路径映射或者视图选错。除了日志还有一个有效验证手段反标后随便看一个关键路径的信号翻转时间。比如数字模块里某个分频器输出反标前时钟沿到输出沿几乎零延迟反标后应该能明显看到几纳秒甚至几十纳秒的翻转延迟这才符合门电路的物理特性。如果反标后波形和RTL仿真完全一样那基本可以确定SDF没标进去别匆忙往下跑。4. SDF反标参数、延迟选择与时序检查的坑4.1 实例路径映射最常见的失败原因SDF反标失败的案例里至少一半是实例路径映射不对。SDF文件内部记录的INSTANCE路径是后端工具在它的设计层次里写出来的通常是数字模块内部路径比如u_glue/u_and1。但混仿testbench关心的是这个数字模块被放在哪里外部层次可能还有tb_pmic.u_dig_top这个前缀。仿真器在反标时会把SDF内部路径和你指定的反标起点拼接起来形成最终查找路径。如果你指定的起点是tb_pmic.u_dig_top那仿真器就去tb_pmic.u_dig_top.u_glue.u_and1找对应cell。如果起点写错了比如写成了tb_pmic它会去找tb_pmic.u_glue.u_and1结果自然是找不到。排查路径问题时我建议先在门级网表里看几层实例名再和SDF文件里的INSTANCE路径对照。注意到一个细节Cadence和Synopsys的工具在层次分隔符上都是点号但有些第三方导出的SDF可能混用点号和斜杠这会导致反标失败。好在xrun对格式有一定的容错遇到这种情况可以先用脚本统一一下SDF里的分隔符再喂进去。4.2 时间单位和min:typ:max选择SDF文件头部有一个TIMESCALE它定义整个文件的延迟时间单位。常见的有1ns、100ps、1ps。如果SDF里TIMESCALE写的是1ns里面一个IOPATH延迟数值是0.072那实际延迟就是0.072纳秒也就是72皮秒。如果你的门级网表仿真时间精度设置不合适这个延迟可能被舍入成0反标等于没有效果。在做混仿时建议把数字域的仿真时间精度设置到皮秒级尤其当代工艺节点下标准单元延迟大量在几十皮秒这个量级。设置方法可以是在Verilog网表里加timescale指令或者在xrun启动参数里加相关选项统一控制。关于min:typ:max三组值默认仿真器取中间那组也就是典型延迟。如果需要验证极端场景比如做建立时间收敛分析可以用最慢角这时需要结合xrun支持的延迟选择开关。如果发现整个design的延迟都偏乐观先检查是不是三组值都取成了min列。4.3 负时序检查与recovery/removal误报SDF里TIMINGCHECK段的setup和hold数值在后端工具里算出来可能是负的比如hold time为-0.02ns。这种情况在先进工艺很常见意味着数据在时钟边沿后还能继续变化本质是因为时钟路径和数据路径的延迟差。仿真器默认对负的timing check比较保守要么忽略要么报warning。但为了真实复现硅片行为通常要打开负时序检查支持也就是前面命令行里的neg_tchk。不打开的话仿真器可能把一个本应通过的路径报成时序违例或者反过来不理睬真实违例。这里要特别提醒混仿场景的recovery和removal检查。当模拟模块产生POR信号、时钟使能信号时这些信号的翻转沿往往不是数字电路那种陡峭的边沿而是有一定上升时间的模拟波形。connect module把模拟波形转成数字电平后翻转时刻本身就带有不确定性这时SDF里的recovery/removal检查很容易误报。遇到这种情况我一般是先检查信号翻转质量再决定是否在验证方案上豁免这些检查。4.4 反标后仿真变慢怎么办SDF反标后仿真速度下降是必然的因为每个cell都带上了延迟和时序检查事件密度大幅增加。在数模混仿里模拟部分本来就有大量的事件数字门延迟再引入高频事件流整个仿真速度很容易掉一个数量级以上。应对思路有几种。第一对被验证场景无关的数字逻辑可以用较小的SDF子集只对相关路径反标。第二调整connect module的采样间隔防止高频翻转信号在数字和模拟域之间来回震荡。第三如果只需要验证功能而不需要精确延迟可以暂时关闭部分timing check留到最后做专门的时序分析。但这里有个原则反标SDF的目的是让仿真结果更可信如果为了速度把关键检查都关了那反标的初衷就没了。我建议先确认哪些路径是本次仿真真正关心的有选择地做优化。5. 常见报错与排查速查表5.1 反标比例显示0%先查视图和路径如果日志里的annotation percentage直接就是0%大概率不是SDF文件的问题而是数字模块视图没选对。门级网表没有参与仿真SDF自然无处可贴。先回config view里确认数字模块的view type是不是真正的netlist视图。确认无误后再看反标起点路径把日志里打印的反标起点和实际testbench层次对照。我之前有一次遇到反标比例0%就是因为config里数字block的view指向了一个空目录下的functional视图仿真器虽然编译了数字顶层但里面所有子模块都是空的SDF自然全部落空。5.2 SDF文件与网表CELLTYPE不匹配日志里大量报SDFNOP警告指定SDF文件中的单元在网表里找不到。这种情况通常有两种原因一是SDF和网表来自不同的设计版本后端改了网表但SDF没重出二是库名不一致比如网表里用的是金属层的物理库名SDF里用的是逻辑库名。处理方法是先做一次全量比对把SDF里出现过的CELLTYPE和网表里实例化过的module名做集合差集。如果差异非常大直接找后端重新导出一致版本。如果只是少数定制单元对不上可以在SDF反标时做单元映射xrun支持通过配置文件把SDF的celltype映射到实际网表module名。5.3 SDF的时间单位不一致导致延迟异常反标本身成功但波形里看到的延迟离谱比如一个与门延迟了100纳秒正常情况下应该只有0.1纳秒。这种场景绝大多数是时间单位不匹配。SDF里TIMESCALE是1ns数值0.1表示100ps但如果你在反标参数里强制了一个不合适的时间比例或者网表里的timescale和SDF的TIMESCALE冲突仿真器换算出来的实际时间就错了。排查方法是看日志里反标时的延迟缩放系数Cadence通常会打印类似Scale 0.001ns或者1ns的信息。我碰到过一次是SDF文件TIMESCALE写的是100ps但后端实际是按1ns算的导致所有延迟放大了10倍整个仿真时序一塌糊涂。5.4 混合仿真边界处出现X态或高阻反标后数字模块输出的延迟变大connect module在某些时刻可能采样到中间的模拟电压导致数字侧出现X态。尤其是在复位释放、使能切换这些瞬间模拟波形翻转比较慢数字门电路又要求电平必须超过阈值两者衔接不好就会出现X态。我的处理办法分两步走。第一步在connect module里增加一个滤波设置让它对毛刺有一定的容忍度避免把中间电平误判成有效翻转。第二步如果X态依然存在就必须在波形上查翻转沿和阈值交叉点确认是不是模拟模块驱动能力不足。有时候问题不在connect module而在模拟模块本身。5.5 问题速查表现象可能原因解决思路反标比例0%数字视图选错门级网表未参与仿真检查config中数字模块的view type反标比例低于95%SDF和网表CELLTYPE不匹配或实例路径映射不完整比对CELLTYPE清单修正反标起点反标成功但波形延迟异常SDF时间单位与网表不匹配延迟被错误缩放检查TIMESCALE和日志中的缩放系数仿真报SETUP/HOLD大量违例负时序检查未打开或时钟偏斜不真实加neg_tchk检查时钟树模型数字边界出现X态connect module采样问题或模拟驱动不足调整connect module配置检查模拟波形翻转反标后仿真速度过慢数字事件密度激增connect module振荡子集反标调整采样间隔写在最后的小经验SDF反标这件事在纯数字仿真里已经非常成熟但搬到数模混合里就会冒出一堆环境层面的问题。我个人的习惯是每次拿到新版本的SDF先不要直接跑全芯片而是抽一个小模块比如一个I2C从机加一个模拟比较器把反标路径、视图配置、时间单位这些要素先验证一遍。小模块跑通了再扩展到全芯片这样排查问题的时间能省一大半。另一个经验是反标日志一定要养成看的习惯。很多工程师跑仿真只看波形和通过标志不看SDF annotation summary结果整个回归跑下来SDF实际一个cell都没标进去所有时序结论全部失效。宁可多花两分钟确认日志也不要在错误的仿真结果上浪费时间。最后分享一个小技巧如果你的项目中模拟模块和数字模块数量很多可以在xrun命令里用一个独立的sdf_cmd文件集中管理反标路径而不是全部堆在命令行。这样版本的SDF对应哪个层次的数字模块一目了然后端更新文件时替换起来也方便。混仿做久了你会明白时序问题往往不在于算法多高深而在于每个环节是否严格对齐。
返回列表