3、形式化验证基础:数学逻辑基础、模型检测、等价性检查、属性规约语言(SVA/LTL)

各位同学好,今天我们来聊聊形式化验证的基础。说实话,我刚入行那会儿,觉得形式化验证是个特别玄乎的东西——又是数学逻辑,又是模型检测,听着就头大。但干久了你会发现,它其实就是一套严谨的数学方法,帮我们把芯片设计中的bug揪出来。

动态仿真大家都很熟悉了,给激励、看波形、比对结果。但有个问题——你给的激励够全面吗?覆盖率到了100%就真的没问题了吗?我遇到过不止一次,仿真覆盖率明明达标了,流片回来却出了低级错误。这时候,形式化验证的价值就体现出来了。

核心观点:形式化验证不是要取代动态仿真,而是两者互补。仿真负责"找bug",形式化负责"证明没bug"。

3.1 数学逻辑基础——形式化的"语法"

形式化验证的根基是数学逻辑。说白了,就是用数学语言来描述电路的行为。你想想看,Verilog代码是人写的,人写的就有歧义。但数学逻辑没有歧义,一是一、二是二。

常用的逻辑包括:

  • 命题逻辑:处理真/假值,比如"信号A为高且信号B为低"
  • 一阶逻辑:引入变量和量词,比如"对于所有时钟周期,信号req最终会被ack响应"
  • 时序逻辑:处理时间维度,比如LTL(线性时序逻辑)

我个人习惯把数学逻辑看作是形式化验证的"语法"。就像写代码要懂语法一样,做形式化验证也得懂这些逻辑。不过别怕,实际工作中你不需要成为数学家,理解基本概念就够了。

小技巧:刚开始接触时,可以把逻辑表达式想象成"电路中的断言"。比如 a & b 就是"a和b同时为高",!a 就是"a为低"。就这么简单。

3.2 模型检测——自动化的"穷举法"

模型检测,这个名字听着高大上,其实核心思想很朴素:遍历所有可能的状态,检查有没有违反属性。

我在项目中遇到过这样一个案例:一个复杂的仲裁器,仿真跑了上万个case,总觉得没问题。但用模型检测一跑,发现了一个极其隐蔽的死锁——两个请求同时到达时,在某些特定时序下会互相等待。这种bug,靠仿真几乎不可能发现。

模型检测的流程大致如下:

  1. 建立系统的状态机模型(从RTL代码提取)
  2. 定义要验证的属性(用SVA或LTL描述)
  3. 工具自动遍历所有可达状态
  4. 报告是否违反属性,并给出反例波形

嗯,这里要注意:模型检测虽然强大,但有个"状态爆炸"的问题。状态太多时,工具会跑不动。所以实际项目中,我们通常只对关键模块做模型检测,而不是整个芯片。

避坑指南:我曾经在一个项目中,把整个SoC拿去跑模型检测,结果跑了三天三夜没出结果。后来把问题拆解成几个小模块,每个模块单独验证,半天就搞定了。记住:分而治之是形式化验证的黄金法则。

3.3 等价性检查——"改对了没?"

等价性检查,说白了就是比较两个设计是否功能一致。最常见的场景是:RTL代码优化后,或者综合后,怎么保证功能没变?

等价性检查分为两类:

类型 比较对象 典型应用
组合等价性 两个组合逻辑电路 RTL优化前后对比
时序等价性 两个时序电路 RTL vs 门级网表

你想想看,综合工具把RTL变成了门级网表,中间做了多少优化?重定时、资源共享、状态机编码...这些优化会不会引入bug?等价性检查就是给你吃一颗定心丸。

我记得有一次,一个同事手动优化了一段代码,觉得没问题就直接提交了。我建议他跑一下等价性检查,结果发现了一个边界条件下的功能差异。从那以后,他再也不敢跳过这步了。

关键点:等价性检查不需要测试向量,不需要仿真环境。你只需要提供"参考设计"和"实现设计",工具自动比对。这是它比仿真高效的地方。

3.4 属性规约语言——SVA和LTL

属性规约语言,就是用来描述"电路应该满足什么性质"的语言。最常用的是SVA(SystemVerilog Assertion)和LTL(Linear Temporal Logic)。

SVA 是硬件验证工程师的标配。它嵌入在SystemVerilog中,可以直接写在RTL代码里。比如:

// 检查:req拉高后,必须在3个时钟周期内得到ack
property p_req_ack;
  @(posedge clk)
  req |=> ##[1:3] ack;
endproperty
assert property(p_req_ack);

LTL 更偏数学化,常用于模型检测工具。它的操作符包括:

  • G (Globally):总是成立
  • F (Finally):最终会成立
  • X (Next):下一个时钟周期成立
  • U (Until):一直成立直到某个条件满足

举个例子,用LTL描述"请求最终会被响应":G(req -> F ack)。翻译成人话就是:"任何时候,如果req为高,那么最终ack一定会为高。"

我的建议:刚开始学SVA时,别急着写复杂的断言。先从简单的"信号不能同时为高"、"状态机不能进入非法状态"开始。写多了自然就熟练了。我带的实习生,我都是让他们先写10个简单的断言,再慢慢加难度。

3.5 知识体系总览

下面这张图,是我自己总结的形式化验证知识体系。你可以把它当作一张"地图",学完这章后对照着看看自己掌握了哪些。

形式化验证知识体系 形式化验证 数学逻辑基础 模型检测 等价性检查 属性规约语言 命题逻辑 一阶逻辑 时序逻辑 状态机建模 状态遍历 反例分析 组合等价性 时序等价性 RTL vs 网表 SVA断言 LTL公式 属性覆盖率 核心思想:用数学证明替代"跑向量"

3.6 实践中的"避坑"经验

最后,分享几个我在实际项目中踩过的坑:

  • 别贪大求全:形式化验证不是万能的。状态爆炸是真实存在的,学会把大问题拆成小问题。
  • 属性要写对:我见过有人写了错误的属性,工具报"通过",结果芯片回来是坏的。属性本身也要验证!
  • 结合仿真一起用:形式化验证和动态仿真不是二选一。我的做法是:关键路径用形式化,其他用仿真。
  • 工具只是工具:再好的工具也替代不了人的思考。理解电路的行为,比学会操作工具重要得多。

好了,这一章的内容就到这里。形式化验证是个需要慢慢积累的领域,别指望一天就精通。多写断言、多跑工具、多分析反例,慢慢就有感觉了。

可可精品资料库