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)。这正是仿真最难覆盖的部分。
二、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 覆盖率、状态空间覆盖 | 关键功能点均有属性覆盖 |
四、与仿真、静态检查的协同关系
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 在复位后首拍行为未定义,需要在属性中增加复位后首拍的排除条件。
总结来说,VC Formal 在 Synopsys 验证生态中的定位是:以属性为中心、以数学证明为手段、覆盖仿真难以穷尽的状态空间。它与仿真、静态检查、等价性检查各司其职,在 RTL 初版到签核前的各个阶段持续介入,交付的是可回归、可审计的属性资产与证明报告。理解这一定位,是后续学习 VC Formal 具体应用与工程方法的基础。