数学基础:命题逻辑、谓词逻辑、集合论基础、布尔代数

各位同学好,我是你们的芯片验证讲师。今天咱们聊聊形式化验证的数学基础。说实话,很多工程师一听「数学」两个字就头疼,觉得跟实际工作脱节。但我做了十几年验证,可以负责任地告诉你:这些数学工具,就是形式化验证的「螺丝刀」和「万用表」。

你想想看,形式化验证本质上在干什么?就是把你的设计意图,用一种精确的数学语言描述出来,然后让计算机去证明它是对的。没有这些数学基础,你连「描述」这一步都做不了。

命题逻辑:最基础的「是与非」

命题逻辑,说白了就是研究「真」和「假」的学问。一个命题,要么真,要么假,没有中间状态。比如「信号A在时钟上升沿为高电平」——这就是一个命题。

我在项目中遇到过这样一个坑:一个同事写断言时,把 a && b 和 a || b 搞混了,结果仿真跑了一周才发现问题。嗯,这就是命题逻辑的基本功没打牢。

命题逻辑有五个基本连接词:

  • 非(¬):取反。¬P 表示「P 不成立」
  • 与(∧):两者同时成立。P ∧ Q 表示「P 且 Q」
  • 或(∨):至少一个成立。P ∨ Q 表示「P 或 Q」
  • 蕴含(→):如果 P 则 Q。P → Q 等价于 ¬P ∨ Q
  • 等价(↔):P 和 Q 同真同假

避坑指南:我曾经在写 SVA 断言时,把蕴含关系写反了。本来想表达「如果复位有效,则输出为0」,结果写成了「输出为0蕴含复位有效」。这俩逻辑上完全不等价,查了三天才找到原因。

谓词逻辑:给命题加上「变量」

命题逻辑有个局限——它只能处理完整的、没有变量的陈述句。比如「x > 5」就不是一个命题,因为 x 没确定。这时候就需要谓词逻辑了。

谓词逻辑引入了两个重要的东西:

  • 量词:∀(任意)和 ∃(存在)
  • 谓词:比如 P(x) 表示「x 具有性质 P」

举个例子:∀x (x > 0 → x² > 0) 表示「对所有大于0的数,它的平方也大于0」。这在验证中太常用了——比如你要验证「所有合法的输入序列都不会导致死锁」,这就是一个 ∀ 语句。

个人经验:我习惯在写形式化规约时,先用自然语言把要验证的性质写出来,再翻译成谓词逻辑。比如「任何两个写操作之间必须至少间隔3个时钟周期」——翻译成 ∀t1,t2 (write(t1) ∧ write(t2) ∧ t1 < t2 → t2 - t1 ≥ 3)。这样不容易漏掉边界条件。

集合论基础:把东西「装起来」

集合论,说白了就是研究「一堆东西」的数学。在形式化验证中,我们经常需要描述「所有可能的状态」、「所有合法的输入」、「所有需要覆盖的路径」——这些都是集合。

集合的基本操作就三个:

操作 符号 含义 验证中的应用
并集 A ∪ B 属于A或属于B 合并两个状态空间
交集 A ∩ B 同时属于A和B 寻找共同满足的条件
补集 Ac 不属于A 描述非法状态

我记得有一次做覆盖率分析,需要计算「所有未被覆盖的状态」。说白了就是全集减去已覆盖的集合——这就是补集运算。用集合论的语言,一句话就说清楚了。

布尔代数:数字电路的语言

布尔代数,就是数字电路的数学基础。0和1,与或非,这些你每天都在用。但形式化验证中,布尔代数的作用远不止于此。

布尔代数的核心定律:

  • 交换律:A ∧ B = B ∧ A,A ∨ B = B ∨ A
  • 结合律:(A ∧ B) ∧ C = A ∧ (B ∧ C)
  • 分配律:A ∧ (B ∨ C) = (A ∧ B) ∨ (A ∧ C)
  • 德摩根律:¬(A ∧ B) = ¬A ∨ ¬B,¬(A ∨ B) = ¬A ∧ ¬B
  • 吸收律:A ∧ (A ∨ B) = A,A ∨ (A ∧ B) = A

注意:布尔代数中的分配律和普通代数不一样。普通代数中乘法对加法分配,但加法对乘法不分配。布尔代数中两者都成立。我曾经在化简一个复杂的断言表达式时,就是因为忘了这个区别,多花了半天时间。

在形式化验证工具中,布尔表达式是核心数据结构。比如 BDD(二叉决策图)就是用来高效表示和操作布尔函数的。你写的每一个断言,最终都会被转换成布尔表达式,然后交给求解器去处理。

知识体系总览

下面这张图,是我自己总结的本章知识体系。你可以把它当作一张「地图」,学完后再回来看,会更有感觉。

形式化验证数学基础 命题逻辑 基本连接词 ¬ ∧ ∨ → ↔ 真值表、逻辑等价 谓词逻辑 量词 ∀ ∃ 谓词与函数符号 一阶逻辑公式 集合论基础 集合运算 ∪ ∩ 补 子集、幂集 笛卡尔积 布尔代数 布尔函数化简 德摩根律 BDD、SAT求解 应用:断言编写、模型检验、等价性验证

这四个部分不是孤立的。命题逻辑是基础,谓词逻辑在命题逻辑上加了量词,集合论提供了「容器」,布尔代数则是把这些逻辑运算落实到电路层面。你学形式化验证,这四个工具缺一不可。

我的建议:刚开始学的时候,别急着啃理论。先拿一个简单的 RTL 模块,试着用命题逻辑写几个断言。比如「当 valid 为高时,data 不能为 X」。写出来,跑一下,看看工具怎么报错。实践出真知,这话在验证领域尤其对。

好了,数学基础就聊到这儿。这些东西看着抽象,但用起来其实很顺手。关键是别怕,多练几次就熟了。

可可精品资料库