一、激励生成概述

什么是测试激励

测试激励,说白了就是喂给DUT(待测设计)的输入信号。

你想想看,验证一个芯片模块,总得给它一些输入吧?

比如一个加法器,你得给它两个加数。一个FIFO,你得给它写数据和写使能。这些输入信号,就是测试激励。

我个人习惯把测试激励分成三类:

  • 合法激励:符合协议规范的正常输入
  • 边界激励:刚好在合法范围边缘的输入
  • 异常激励:故意构造的非法或极端输入

我在项目中遇到过最典型的例子——一个AHB总线桥,正常读写都没问题。但当我构造了一个「地址刚好对齐、长度刚好4字节、burst类型为INCR4」的激励时,竟然触发了内部状态机死锁。这就是边界激励的价值。

核心要点:测试激励不是随便给几个波形就完事了。好的激励,要能覆盖功能点、触发边界条件、暴露设计缺陷。

为什么需要自动生成

手动写激励?我刚开始做验证时就是这么干的。

一个简单的UART模块,手动写了200多个测试用例。结果呢?

  • 花了整整两周时间
  • 漏掉了两个关键边界场景
  • 回归测试时改一个参数,所有用例都要手动调

为什么会这样?因为手动激励有几个硬伤:

痛点 手动方式 自动生成
覆盖率 依赖工程师经验,容易遗漏 可系统化覆盖所有组合
效率 一个复杂场景写半天 几秒钟生成上千条
可维护性 改需求等于重写 改约束即可
随机性 基本固定套路 可引入随机,发现意外bug

嗯,这里要注意——自动生成不是要完全替代手动。而是把工程师从重复劳动中解放出来,去关注更复杂的验证策略。

自动生成的核心挑战

自动生成听起来很美好,但做起来坑不少。

我曾经在一个PCIe项目里,写了一个自动激励生成器。结果跑了一晚上,生成了100万条激励。第二天一看——90%都是重复场景,真正的边界情况一个都没覆盖到。

这就是第一个挑战:有效覆盖率。

自动生成容易陷入「量大但无用」的陷阱。你想想看,如果生成器只是机械地组合所有输入,那大概率会产出大量无意义的激励。

第二个挑战:约束的准确性。

我记得有一次,一个同事写的约束里有个笔误——地址范围写反了。结果生成的所有激励都是非法的,跑了一周仿真全白费。约束错了,生成的东西就是垃圾。

第三个挑战:可复现性。

随机生成好是好,但出了问题怎么复现?我习惯的做法是:每次生成时记录随机种子。这样即使生成了100万条,也能精确回放某一条出错的激励。

避坑指南:我曾经在一个项目里,自动生成器跑出来的激励在仿真器里通过率只有60%。排查了两天才发现——生成器没有考虑时序窗口。有些激励在功能上合法,但时序上根本不可能出现。所以,自动生成一定要加上时序合理性检查。

自动生成的收益

说了这么多挑战,那自动生成到底值不值得做?

我的答案是:值得,但要有策略。

收益主要体现在三个方面:

  1. 人力解放:一个需要3人周的激励编写工作,自动生成可能只需要1人天来配置约束
  2. 覆盖深度:手动很难想到的极端组合,自动生成可以系统化探索
  3. 回归效率:设计改了,只需要重新生成一次,不用手动改几百个用例

我参与过一个SoC项目,验证周期原本计划6个月。后来我们搭建了一套自动激励生成框架,把常规激励的编写时间压缩了80%。最终验证周期缩短到4个月,还多覆盖了30%的边界场景。

个人经验:自动生成不是银弹。我建议从最耗时的模块开始试点,比如协议类模块(AHB、AXI、PCIe),这类模块激励模式固定但组合爆炸,自动生成收益最明显。

知识体系总览

下面这张图,是我对激励生成整体知识结构的理解:

测试激励自动生成知识体系 核心目标:高效发现设计缺陷 覆盖率驱动 约束随机化 可复现性 覆盖率驱动方法 功能覆盖点定义 交叉覆盖 & 自动补全 约束随机化技术 SystemVerilog约束 权重分配 & 动态约束 可复现机制 随机种子 波形回放 输出:合法激励 | 边界激励 | 异常激励 | 随机激励 最终收益:缩短验证周期 × 提升覆盖质量 人力解放 | 深度覆盖 | 高效回归

这张图展示了我对激励自动生成的整体理解。从核心目标出发,三大支柱支撑起整个方法论,最终落到具体的输出产物和收益上。

嗯,这一章就到这里。记住一句话:自动生成不是目的,高效发现bug才是。

可可精品资料库