资讯详情

资讯详情

JasperGold X-Propagation验证:从X态分类到工程落地

简介Cadence JasperGold X-Propagation Verification App官方用户指南2020.03版面向数字IC设计验证工程师与形式验证学习者针对数字电路中的X不定态传播问题提供系统化范例。X状态可能源自未定义条件、浮空输入、竞争条件或噪声导致的信号不稳定且会不受控地跨节点传播令系统行为难以预测。指南重点介绍如何利用JasperGold形式推理技术自动检测X-传播路径、完成深度分析与可视化并给出优化与修复建议弥补传统仿真难以触发的深层逻辑错误帮助工程师在设计早期完成验证、缩短迭代周期并降低修复成本。资源包内仅含1个PDF大小约2.6MB内容覆盖X-Propagation概念、检测流程、可视化分析及Cadence合规使用说明便于快速查阅上手。已有343人浏览学习适合芯片设计、IC验证及形式验证方向的工程与研究人员参考。1. 先讲清楚这本 user guide 要解决的是仿真与芯片行为分裂的问题X 态 bug 往往不是第一轮仿真能抓到的。一个漏了 default 的 case 分支、一组跨时钟域采样的控制位仿真跑三千个用例全绿网表仿真一开就开始出现不定态芯片回来之后功能直接翻车。jaspergold 的 xpropX-Propagation验证就是为这类问题准备的它用形式化引擎把未知值的传播路径一条条枚举出来直接回答「这个 X 到底无所谓还是致命」。这份 user guide 是整个方法的核心文档适合数字验证工程师、DFT 工程师和做 CDC 分析的人读验证工程师能把它变成回归里的一道关卡DFT 工程师能借它判断哪些 X 需要被 DFT 逻辑隔离。如果你还没碰过 xprop这篇笔记可以当作文档的导读帮你少走我踩过的弯路。2. X 态到底怎么毁掉流片后的你从 X 乐观到恶意 X2.1 仿真里看不到的 X为什么在芯片上变成 bugRTL 仿真用的是四值逻辑0、1、X、Z。X 表示未知仿真器在处理 X 时非常「乐观」。典型例子是assign out a b;当 a 是 X、b 是 0 时很多仿真器会直接把 out 计算成 0因为「与 0 相与结果肯定是 0」。这个结论在数学上成立但现实中一个处于不定态的驱动信号经过与门时输出可能是一个亚稳态窗口也可能在 0 和 1 之间来回抖并不是干净的 0。综合工具对待 X 的态度又是另一套。综合阶段 X 往往被当作 dont care工具在映射门级电路时会替你把 X 替换成具体的 0 或 1。于是同一个 RTL仿真时 X 被乐观吸收综合后 X 却变成一个物理确定的错误值。一旦这个值进入状态机跳转、FIFO 指针比较、中断产生逻辑功能就会跟仿真预期分裂。这种「仿真绿灯、流片红灯」的问题靠加用例很难复现因为用例里根本不会主动产生 X就算产生了镜像的路径也未必有敏感逻辑。xprop 的思路跟仿真完全不同。它不试图把 X 变成 0 或 1而是把 X 当作一种需要被穷举的输入X 的每一位既可能取 0也可能取 1xprop 用形式化引擎把所有取值组合都跑一遍。这样只要某条传播路径上存在「X 取 0 和取 1 导致下游行为不一致」的情况它就能给出一个确定的反例。这也是 JasperGold 做 xprop 验证和普通 lint 检查最本质的区别lint 看的是语法和结构化风险xprop 看的是语义级的不一致性。2.2 JasperGold xprop 的建模方式把 X 当作第三值穷举xprop 模式不是简单地把仿真器的四值逻辑照搬进形式化引擎。JasperGold 会把 RTL 里的每个信号建模成集合X 就是这个集合的上界包含 0 和 1 两种可能。接下来引擎会对 X 源做枚举每次枚举相当于给未知位赋一个确定的 0/1 值再跑一次布尔可满足性分析。如果所有赋值的组合下目标断言都成立这个 X 就是安全的只要存在一个组合让断言失败就产生一个 counterexample。为了让穷举可控xprop 引入了抽象机制。全芯片设计里的寄存器堆、存储器、大型数据通路如果全部当作 X 源组合空间会爆炸到没法收敛。常见做法是把这类结构抽象成黑盒或者把它们的输出当作经过约束的符号变量只保留控制路径上的 X 传播分析。这就是 user guide 里反复提到的 effort 设置低 effort 做快速筛选高 effort 做精确证明。后面我会专门讲 effort 三档怎么调这里先记住一个原则xprop 的结果质量取决于抽象边界抽象过头会漏报抽象不足会跑不动。2.3 良性 X 与恶意 X先学会分类再谈报错数量第一次跑 xprop 的人看到报告里几百条 X 传播路径第一反应往往是「设计是不是烂到根了」。其实一半以上的 X 是良性 X。良性 X 指的是不论这个未知位最终是 0 还是 1下游逻辑的功能表现完全一致。最典型的例子是数据总线上的 X 被寄存后只有当写使能有效时才会被采样写使能本身是确定的那么数据位上的 X 不会影响功能状态。恶意 X 正好相反X 的取值会改变下游分支走向。比如 FIFO 的满标志由读写指针比较得出而写指针来自一个没有完整复位的寄存器组X 会让满标志在「真满」和「未满」之间摇摆后续的写操作是否被阻塞也随之变化。这种 X 才需要真正动手修。user guide 里的严重级别字段就是在帮你做这个分类报告里 Name 或 Category 字段会标出 X 是来自数据路径还是控制路径。我一般建议团队把 xprop 的报错分成两个队列控制路径的恶意 X 必须本周清完数据路径的良性 X 可以进观察列表随版本慢慢消化。3. 把 xprop 跑起来的完整路径setup、约束与第一条报告3.1 拿一个 FIFO 控制器当靶子先写 RTL这里用一个简化的 FIFO 控制器做例子。它的写指针wptr在复位释放后正常递增读指针逻辑类似组合逻辑里根据wptr的 case 生成slot_count再用slot_count比较出full_flag。问题出在 case 分支缺了2b11的默认项一旦wptr出现 Xslot_count就落到缺省路径full_flag变成 X后续写使能逻辑就会跟着飘。module fifo_ctrl #( parameter DEPTH 4 ) ( input logic clk, input logic rst_n, input logic wr_en, input logic rd_en, output logic full_flag ); logic [1:0] wptr, rptr; always_ff (posedge clk or negedge rst_n) begin if (!rst_n) begin wptr 2b0; rptr 2b0; end else begin if (wr_en) wptr wptr 2b1; if (rd_en) rptr rptr 2b1; end end logic [2:0] slot_count; always_comb begin case (wptr) 2b00: slot_count 3d0; 2b01: slot_count 3d1; 2b10: slot_count 3d2; // 2b11 没有 defaultwptrX 时这里产生 X endcase full_flag (slot_count (DEPTH - 1)); end endmodule这个设计的意图是制造一个可复现的恶意 Xwptr本身是有复位目标的2b00 是复位后的初值所以正常情况下不会出现 X。但在 xprop 模式下引擎会刻意把wptr的每一位当作可枚举的未知源看看 X 一旦注入会不会影响full_flag。case 缺 default 的设计缺陷正好让这个 X 穿过组合逻辑最终表现在输出端口上。3.2 起 JasperGold 的 xprop 会话read、elaborate、prove下面是一个最小可跑的 tcl 脚本。注意不同版本的 JasperGold 对 xprop 引擎的调法略有差异有的版本用set_engine_mode xprop有的版本直接在prove命令上带-xprop开关user guide 的 Quick Start 章节一定会有当前版本的写法。# xprop_fifo.tcl 最小示例 project -new xprop_fifo # 读入 SystemVerilog 源文件-vcs 表示使用 VCS 兼容解析 read_file -format sverilog -vcs ./rtl/fifo_ctrl.sv # 例化顶层elaborate 完成编译和连接 elaborate -top fifo_ctrl # 切到 xprop 引擎模式 set_engine_mode xprop # 约束时钟与复位周期 10ns低有效复位 create_clock -name clk -period 10 {clk} create_reset -name rst_n -active low {rst_n} # 让复位在第一拍保持之后释放 assume -reset rst_n -phase 0 # 证明 full_flag 永远不会等于 X prove -property {assert property (full_flag ! 1bx);}脚本里每一行的作用要分清read_file是加载 RTL 源文件并指定解析格式elaborate负责建立层次连接这一步失败通常是语法或顶层名不匹配set_engine_mode xprop才会把引擎切到 X 传播分析不做这一步后面的prove只是普通形式化断言证明不会专门枚举 X 源。create_clock和create_reset是给引擎提供时间边界和复位行为没有复位约束所有寄存器初值都会被视为 X 源报告会多出成千上万条假路径。最后一行prove的目标是「full_flag 永远不是 X」。跑完以后引擎会返回三种状态之一Proven 表示断言在所有 X 组合下成立Falsified 表示找到了一个反例Bound not reached 表示在设定的时间边界内没跑完不能当作通过。第一次跑这个例子大概率是 Falsified因为wptr的 X 会通过缺省 case 传染到slot_count和full_flag。3.3 读懂第一份 xprop 报告三个字段决定下一步动作JasperGold 的 xprop 报告通常在 prove 完成后自动弹出命令行环境则输出到 log 文件。新手最容易在报告里迷失方向我只盯三个字段字段含义下一步动作X SourceX 被注入的起始信号判断是不是真实未知源Propagation DepthX 从源头到失败点的逻辑深度深度越浅越优先处理StatusProven / Falsified / Bound not reached只有 Falsified 才需要开反例排查X Source 字段最有价值。如果源头是wptr这类有完整复位的寄存器说明 X 是引擎刻意注入的「假设未知」你需要判断设计里是否真的存在让 wptr 变 X 的路径如果源头是一根来自未初始化存储器的读数据线那就是真实风险必须处理。Propagation Depth 帮你排优先级越靠近输出端口的 X 越危险深度只有几级的往往是被某个组合门直接放大的控制信号。3.4 约束怎么写时钟、复位、输入不动点约束是 xprop 工程里最容易出玄学问题的部分。时钟和复位只是基础真正的难点在输入约束。比如 FIFO 的读写使能不能同时有效这属于设计假设如果不在脚本里声明引擎会把wr_en和rd_en的所有组合都当作合法输入包括真实设计中永远不可能出现的场景从而报出荒谬的反例。# 输入约束读写使能互斥且复位期间不读写 assume -name exclusive_wr_rd { !(wr_en rd_en); } assume -name no_rw_in_reset { rst_n || (!wr_en !rd_en); }这两条约束的实际效果是收窄状态空间。第一条约掉同时读写的组合第二条保证复位窗口内没有数据操作。约束加得越紧证明越快但也要小心约束过头如果把真实设计中可能出现的问题场景也约束掉了xprop 就会漏报。user guide 里有一节专门讲 over-constraint 的副作用经验法则是每条约束都要能对应到 RTL 注释或设计文档里的一条假设写完约束后让不写验证的同事review一遍往往能捞出几条拍脑袋加的。4. 把 xprop 用深调试、覆盖率与产线化4.1 CDD 里追 X 传播路径从后级往前级定位当 prove 返回 Falsified 时JasperGold 会生成一个 counterexampleCDDConcurrent Design Debug是看反例的图形界面。我一般先用命令行把 CE 打开再在波形里做 backward trace。# 打开最近一个 falsified CE visualizer -open last_ce -mode xpropCDD 里有两个操作对 xprop 调试特别有用。第一个是把信号值显示设为 4 态X 在波形里显示为一个独立的未知值区间而不是随机 0/1第二个是 backward trace选中full_flag的 X 点让工具自动回溯所有驱动路径。回溯结果会显示wptr[1:0]的 X 经过 case 缺省分支传染到slot_count再经比较器到达full_flag。这个路径往往就是 RTL 修改的清单。4.2 用 cover property 量化 X 传播的覆盖prove 证明的是「没有恶意 X 存在」cover 性质则能告诉你「具备传播条件的 X 路径有没有被真正激活」。xprop 模式里可以单独覆盖某条 X 传播路径# 检查 X 是否能从 wptr 传播到 full_flag cover property (full_flag 1bx);如果这条 cover 返回 Falsified说明约束集合已经把 X 路径合法化掉了你需要回头检查是不是 over-constraint。如果 cover 返回 Proven说明确实存在至少一种 X 组合让full_flag变 X接下来再用 prove 去验证这条路径是否被下游逻辑吸收。cover 和 prove 配合起来才是一套完整的 X 风险评估cover 管「能不能发生」prove 管「发生了有没有影响」。4.3 xprop_effort 三档怎么选从抽丝到穷举xprop_effort 是 user guide 里出现频率很高的参数它控制引擎对 X 源的展开力度effort 档位行为适合阶段low只查 X 能否到达断言点抽象粗全芯片回归、快速筛选medium细化控制路径保留部分数据抽象block level 常规检查high基本不做数据路径抽象展开更彻底高风险模块、流片前确认low 的误报率最高但跑得快适合每天晚上全芯片过一遍high 跑得慢适合那些出过 X 事故的模块。我见过团队把 effort 拉到 high 跑全芯片跑了三天没收敛最后换回 medium 加关键模块单独 high才在两周内把问题清完。effort 不是越高越好抽象越少引擎要遍历的状态越多反而不如接受一点抽象、把精力放到约束准确性上。5. 避坑实录5 个让我白熬通宵的 X 假阳与漏报5.1 假阳第一来源复位约束没给全现象跑完 xprop 出了上千条 Falsified打开一看全部指向寄存器输出。原因create_reset只约束了顶层复位信号没有声明寄存器组的复位行为引擎把所有寄存器初值都当作自由 X。解决在脚本里补全复位假设如果设计里有异步复位、同步复位混用要分别声明同时用报告的 X Source 字段过滤掉复位相关源验证剩余项是否仍然 Falsified。5.2 case 缺省报恶意 X但功能根本走不到现象一个 case 分支缺 defaultxprop 报了恶意 X但 review 设计后发现所有可能取到的值都覆盖了缺省只是写代码时偷懒。原因xprop 只认语义不认「实际上走不到」。解决先看 X Source 是否来自可达状态比如wptr是否有非法编码如果只是防御性代码缺失加 default 分支比加约束更干净还能顺手消除综合时的 latch warning。5.3 24 小时没有反例就宣布验证完成现象xprop 跑了整整一天 log 里没有出现 Falsified团队直接签核换个 effort 之后三分钟就 dump 出反例。原因默认的 bound 设得太浅引擎在设定的 cycle 数内没有展开到 X 影响下游的那一步返回的是 Bound not reached只是没有 Falsified 罢了。解决签核前必须确认状态是 Proven 而不是 Bound not reached收紧时钟和复位约束能显著提高可达深度。5.4 和 SpyGlass CDC 的结果对不上怀疑工具坏了现象同一组跨时钟域寄存器JasperGold 报恶意 XSpyGlass CDC 的用户指南里说同步器结构没问题两边结论打架。原因两个工具的威胁模型不同。SpyGlass CDC 看的是结构化同步器、亚稳态传递、跨域路径完整性JasperGold xprop 看的是 X 枚举后的语义传播即使同步器结构合规X 依然可以通过组合路径逃逸到控制逻辑。解决把两份报告按模块合并结构化检查过的问题标记为「链路合规」语义级 X 问题标记为「行为风险」不互相充当判据。5.5 抽象过头把真问题压成了良性现象数据通路里的 X 全被抽象屏蔽报告显示零风险但流片后地址总线的错误拖垮了整块逻辑。原因全芯片验证为了跑完把存储器输出标成了 benign X而地址总线恰好来自存储器的未初始化区域。解决全芯片用 low effort 做筛选没问题但筛选出的良性 X 必须回 block level 用 high effort 复核宁可保留几条待定项也不要为了报告好看把风险压掉。6. 进阶把 xprop 沉淀成每晚自动跑的一条流水线xprop 最有价值的用法不是出问题时临时跑一次而是把它塞进 nightly 回归。我的做法是每个 block 维护一个独立的 tcl 脚本里面只包含该 block 的约束和断言晚上用一条总脚本批量起 jg把每个 block 的 log 汇总到统一文件。#!/bin/bash # nightly_xprop.sh 片段 for tb in fifo_ctrl dma_ctrl usb_phy; do jg -shell -tcl scripts/xprop_${tb}.tcl \ -log logs/${tb}_xprop.log 21 grep -E Falsified|Bound not reached \ logs/${tb}_xprop.log xprop_summary.txt done这个流水线有几个细节值得注意。每个 block 脚本里必须导入同一个约束库文件避免不同 block 对时钟复位的定义漂移grep 只筛 Falsified 和 Bound not reached漏掉这两个状态会误判通过。流水线跑起来后处置节奏也固定下来当天出现的 Falsified 开 CE 看路径确认是 RTL 问题就提单Bound not reached 不做签核依据只记录 state space 的增长趋势。user guide 我建议你重点读三块Quick Start 解决「怎么跑通」xprop Semantics 解决「工具到底在算什么」Constraint Debug 解决「为什么这个反例是错的」。X 验证的坑不在于工具不会用而在于我们总习惯用仿真的乐观心态去理解形式化结果觉得「看不到 X 就等于没有 X」。我现在的习惯是每次流片前把 xprop 报告里所有 Falsified 的 CE 截图放在设计评审里过一遍哪怕最后证明都是良性 X也让所有人知道这里存在过风险。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →