1. 形式验证工程全景

在 Synopsys 的验证工具链中,VC Formal 并不是一个"替代仿真"的工具,而是一个以数学证明为手段、以属性为中心的验证引擎。理解它的第一步,是把它放回整个验证生态里,看清它与仿真、静态检查、等价性检查各自负责什么、边界在哪里,以及在真实项目中应该在什么时机介入、交付什么。

一、四类验证手段的分工与边界

数字芯片验证通常由四种手段共同覆盖:动态仿真(VCS 等)、静态检查(SpyGlass、VC SpyGlass Lint/CDC 等)、形式验证(VC Formal)、等价性检查(Formality)。它们不是竞争关系,而是从不同维度逼近"设计正确"这一目标。

动态仿真通过施加激励、观察波形来验证行为。它的优势是能覆盖复杂场景、可复用 UVM 环境、能验证性能与协议交互;局限在于激励只能覆盖有限的状态空间,深层的边界条件、罕见的并发冲突、复位序列的极端组合往往难以穷尽。

静态检查不施加激励,直接分析 RTL 结构:Lint 检查编码规范与可综合性,CDC/RDC 检查跨时钟域同步结构,这些是"结构正确性"层面的把关,不证明功能。

等价性检查解决的是"两个设计是否功能一致"的问题,典型场景是 RTL 与综合后网表、ECO 前后网表的比对。它不关心设计本身对不对,只关心变换前后是否等价。

VC Formal 则回答"设计是否在所有可能输入和所有可能时序下都满足某条属性"。它用形式化算法穷尽状态空间,要么给出数学证明(Proven),要么给出反例波形(Falsified),要么因状态空间过大而无法收敛(Inconclusive)。这正是仿真最难覆盖的部分。

Synopsys 验证生态中的四类手段与 VC Formal 定位 动态仿真 VCS + UVM 激励驱动 · 波形观察 覆盖有限状态空间 擅长场景与性能 静态检查 SpyGlass / VC SpyGlass Lint · CDC · RDC 结构正确性把关 不证明功能行为 等价性检查 Formality RTL ↔ 网表比对 ECO 前后一致性 只问等价,不问对错 VC Formal 形式验证引擎 属性驱动 · 数学证明 穷尽状态空间 Proven / Falsified VC Formal 内部应用(App) FV Assertion SVA 属性证明 核心功能验证 FV Connectivity 连接性检查 端口/寄存器映射 FV X-Prop X 传播分析 复位/初始化检查 FV Sec / Reg 安全属性 / 寄存器 自动生成属性 典型项目中的介入时机 RTL 初版 Lint/CDC 接口属性 模块级 FV Assertion X-Prop 子系统集成 Connectivity 协议属性 签核前 回归收敛 覆盖率签核

二、VC Formal 的介入时机

形式验证不是"最后补一刀",而是贯穿 RTL 开发到签核的持续活动。典型项目中,介入时机大致分四个阶段:

  • RTL 初版阶段:此时设计结构尚不稳定,但接口协议、复位行为、关键控制寄存器的属性已经可以开始写。这一阶段用 FV Assertion 验证接口握手、状态机不可达状态、FIFO 溢出等,配合 Lint/CDC 一起做早期把关。
  • 模块级阶段:模块功能基本定型,是形式验证投入产出比最高的阶段。针对仲裁器、FIFO、状态机、计数器、握手协议等编写 SVA 属性,用 VC Formal 穷尽证明。同时用 FV X-Prop 检查复位释放后的 X 传播,用 FV Connectivity 检查端口与内部寄存器的映射关系。
  • 子系统集成阶段:多个模块互联后,连接性错误、协议不匹配、跨模块握手死锁是主要风险。此时 FV Connectivity 和协议属性证明能快速定位集成问题,比仿真更早暴露。
  • 签核前阶段:形式验证作为回归的一部分持续运行,属性覆盖率(Proven 比例)作为签核指标之一。未收敛的属性需要分析是设计问题还是约束不足。

三、交付物与工程闭环

形式验证工程的交付物不是"跑完一次工具",而是一套可复用、可回归、可审计的资产。典型交付物包括:

交付物内容说明验收标准
属性文件(.sva / .fv)按模块组织的 SVA 属性、假设、约束属性可读、可维护、有注释
约束文件(.tcl / .sdc)时钟、复位、输入约束、环境假设约束合理,不过约束也不过松
VC Formal 脚本编译、elaborate、证明、报告生成可一键回归,结果可复现
证明报告Proven / Falsified / Inconclusive 统计Proven 比例达标,反例已分析
反例波形Falsified 属性的波形与根因分析每个反例有结论:设计 bug 或约束缺失
覆盖率报告属性覆盖率、COI 覆盖率、状态空间覆盖关键功能点均有属性覆盖
工程提示:形式验证的"收敛"不等于"证明通过"。Inconclusive 的属性需要区分是设计复杂度过高、约束不足,还是属性本身不可证。实践中常用方法是先加约束缩小状态空间,再逐步放宽,观察证明结果的变化。

四、与仿真、静态检查的协同关系

VC Formal 与仿真不是替代关系,而是互补。仿真擅长验证数据通路、性能、协议交互等"有明确激励场景"的功能;形式验证擅长验证控制逻辑、边界条件、并发冲突、复位序列等"激励难以穷尽"的场景。一个典型的协同模式是:仿真发现 bug 后,把该场景抽象成 SVA 属性,用 VC Formal 证明同类问题不再出现;形式验证发现反例后,把反例波形转成仿真激励,在 UVM 环境中复现并回归。

与静态检查的关系则更清晰:Lint/CDC 检查结构规范,VC Formal 检查功能属性。两者在 RTL 初版阶段并行介入,前者保证"写得规范",后者保证"行为正确"。

五、一个可执行的最小工程示例

以一个 4 位同步 FIFO 为例,说明形式验证工程的最小闭环。假设参数:深度 16,位宽 8,读写时钟同源。关键属性包括:

// 1. 空标志正确性:空时不能读
property p_empty_no_read;
  @(posedge clk) disable iff (!rst_n)
  (empty |-> !rd_en);
endproperty

// 2. 满标志正确性:满时不能写
property p_full_no_write;
  @(posedge clk) disable iff (!rst_n)
  (full |-> !wr_en);
endproperty

// 3. 数据顺序:先入先出
property p_fifo_order;
  @(posedge clk) disable iff (!rst_n)
  (wr_en && !full) |=> (dout == $past(din));
endproperty

// 4. 计数器一致性:count 与 empty/full 关系
property p_count_consistency;
  @(posedge clk) disable iff (!rst_n)
  (count == 0) |-> empty;
endproperty

在 VC Formal 中,通过 analyze -format sva 读入属性,elaborate 后 prove。若某条属性 Falsified,工具会给出反例波形,工程师据此判断是设计 bug 还是约束缺失。例如 p_fifo_order 若失败,常见原因是读写指针复位值不一致或 $past 在复位后首拍行为未定义,需要在属性中增加复位后首拍的排除条件。

常见误区:把形式验证当成"跑一遍工具看结果"。实际上,属性质量、约束合理性、反例分析深度才是决定形式验证价值的关键。一条写得过松的属性可能永远 Proven,但毫无验证意义;一条约束过紧的属性可能掩盖真实 bug。

总结来说,VC Formal 在 Synopsys 验证生态中的定位是:以属性为中心、以数学证明为手段、覆盖仿真难以穷尽的状态空间。它与仿真、静态检查、等价性检查各司其职,在 RTL 初版到签核前的各个阶段持续介入,交付的是可回归、可审计的属性资产与证明报告。理解这一定位,是后续学习 VC Formal 具体应用与工程方法的基础。