1. Formality等价验证工程导入

在数字集成电路设计流程中,RTL代码经过综合、优化、扫描链插入、时钟树综合、布局布线等一系列变换后,最终生成的网表在功能上是否仍与原始RTL保持一致,是每个项目都必须回答的问题。Synopsys Formality正是为解决这一问题而生的等价性检查(Equivalence Checking,EC)工具。它通过形式化方法,对两个设计(通常称为参考设计与实现设计)进行数学上的功能等价证明,而不是依靠仿真向量去"碰运气"。本课程的目标,是让读者从零开始,建立一套可落地、可复现的Formality等价验证工程能力。

一、课程目标与验证对象

本课程围绕"工程化"三个字展开,而不是停留在工具命令的罗列。学完之后,读者应当能够独立完成以下工作:为不同来源的设计(RTL对RTL、RTL对综合网表、网表对网表)搭建正确的验证环境;编写并调试Formality的配置脚本;读懂匹配报告与失败点报告,定位不匹配的根因;在遇到扫描链、时钟门控、寄存器重命名、边界优化等常见障碍时,选择合适的解决方案。

Formality的验证对象是"两个设计之间的功能等价性"。这两个设计在工具中分别称为参考设计(Reference)和实现设计(Implementation)。参考设计通常是可信的、作为黄金标准的一方,例如原始RTL;实现设计是需要被验证的一方,例如综合后的门级网表。工具并不关心两者的内部结构是否相同,只关心对于所有可能的输入序列,两者的输出和内部状态是否始终一致。这一点非常关键:等价验证证明的是"功能等价",而不是"结构相同"。

需要特别强调的是,Formality的验证边界由用户通过配置来界定。哪些引脚是主输入、哪些是主输出、哪些是时钟、哪些是复位、哪些是扫描使能,都需要在脚本中明确声明。如果边界定义错误,即使设计本身完全等价,工具也可能报出大量失败点。因此,理解"验证对象"不仅是理解两个设计,更是理解如何把设计正确地"喂"给工具。

二、工程流程全景

一个完整的Formality等价验证工程,可以概括为"准备—读入—匹配—比较—分析"五个阶段,但每个阶段内部都有大量工程细节。下面这张图给出了流程全景与关键数据流,它同时标出了各阶段的主要输入、工具动作和输出产物,便于读者建立整体认知。

Formality 等价验证工程流程全景 ① 准备阶段 RTL / 网表 / .lib SVF / 约束文件 ② 读入与建模 read_verilog / read_db link_design ③ 匹配阶段 match / 名称映射 SVF 引导匹配 ④ 比较阶段 verify 等价点求解 ⑤ 分析与调试 report_failing_points diagnose / 根因定位 迭代修正 关键产物与判断依据 匹配报告 matched / unmatched unmatched points 列表 等价结果 Succeeded / Failed passing / failing points 失败点详情 compare point 类型 输入锥 / 状态差异 SVF 日志 guide 命令记录 优化映射依据

从图中可以看到,流程并非单向直线。当比较阶段出现失败点时,需要回到准备或匹配阶段进行修正,例如补充SVF文件、调整时钟定义、修正扫描链配置,然后重新执行。这种"迭代修正"是等价验证工程的常态,也是本课程重点训练的能力。

三、学习路径与工程习惯

本课程的学习路径遵循"先建立框架,再深入细节,最后综合实战"的原则。前几章会先讲清楚Formality的基本概念、工作模式(Setup Mode与Verification Mode的区别)、设计读入与链接的方法;随后进入匹配与比较的核心机制,包括名称匹配、SVF引导、比较点类型;再往后会覆盖综合、DFT、时钟门控、低功耗等真实场景下的等价验证问题;最后通过一个完整的工程案例,把前面所有知识串联起来。

在学习过程中,建议读者养成三个工程习惯。第一,始终保留完整的脚本和日志。Formality的调试高度依赖日志中的匹配信息和失败点详情,随手记录可以避免重复劳动。第二,先保证边界定义正确,再追求匹配率。很多初学者一上来就盯着失败点,却忽略了时钟、复位、扫描使能是否声明正确,结果越调越乱。第三,理解SVF的作用。SVF(Setup Verification File)记录了综合工具在优化过程中对设计所做的名称变更、寄存器合并、边界优化等操作,是Formality能够正确匹配的关键依据。没有SVF,很多经过优化的网表将无法与RTL匹配。

在实际项目中,建议把Formality脚本纳入版本管理,并与综合脚本放在同一目录下。这样当综合策略调整时,可以快速定位到对应的等价验证配置,减少环境不一致带来的问题。

下面给出一个最小可运行的Formality脚本框架,读者可以先建立直观印象,后续章节会逐行展开讲解每个命令的含义与配置要点。

# formality.tcl —— 最小工程框架示例
set_app_var synopsys_auto_setup true
set_app_var verification_clock_gate_hold_mode any

# 读入参考设计(RTL)
read_verilog -container r -libname WORK -01 {./rtl/top.v ./rtl/sub.v}
set_top r:/WORK/top

# 读入实现设计(综合网表)
read_verilog -container i -libname WORK -01 {./netlist/top_syn.v}
set_top i:/WORK/top

# 读入工艺库
read_db -container r {./lib/slow.db}
read_db -container i {./lib/slow.db}

# 读入 SVF 引导文件
set_svf ./svf/top.svf

# 执行匹配与验证
match
verify

# 输出报告
report_unmatched_points > ./rpt/unmatched.rpt
report_failing_points  > ./rpt/failing.rpt
report_passing_points  > ./rpt/passing.rpt

这段脚本虽然简短,但已经包含了等价验证工程的骨架:容器划分、设计读入、顶层设定、库文件加载、SVF引导、匹配、验证、报告输出。后续章节会围绕其中每一个环节,讲解常见错误、调试方法和工程最佳实践。

最后需要明确的是,Formality等价验证不是"跑一次就完事"的流程。在真实项目中,它往往与综合、DFT、低功耗流程紧密耦合,需要随着设计迭代反复执行。掌握这套工程方法,意味着你能够在设计变换的每一个关键节点,用形式化手段给出可信的功能一致性结论,而不是依赖覆盖率有限的仿真。这正是本课程希望帮助读者建立的核心能力。