验证方法论基础:定向测试与随机测试、覆盖率驱动验证(CDV)、断言验证(SVA)

各位同学,今天我们来聊聊验证方法论的几个核心概念。说实话,我刚入行那会儿,验证就是对着波形一条条看,觉得能跑通就完事了。后来被现实狠狠教育过几次,才明白方法论这东西,真不是纸上谈兵。

定向测试:指哪打哪,但别太依赖

定向测试,说白了就是你想测什么,就写什么。比如你要验证一个加法器,就写个测试用例:输入A=3,B=5,检查输出是不是8。简单直接,对吧?

我在项目中遇到过这样的情况:一个模块的定向测试用例写了200多个,覆盖率报告看着也挺漂亮。结果换了个随机种子,立马翻车。为什么?因为定向测试只能覆盖你想到的场景,而芯片里的bug往往藏在你没想到的地方。

定向测试的适用场景:

  • 验证复位时序、初始化流程等确定性行为
  • 回归测试中的冒烟测试(smoke test)
  • 复现已发现的bug

我个人习惯:定向测试只占整个验证计划的20%左右。剩下的,交给随机。

随机测试:让芯片替你找bug

随机测试,就是让验证环境自动生成各种合法的、非法的、边界的输入组合。你想想看,一个32位的加法器,定向测试你能把2^64种输入组合全测完吗?不可能。但随机测试可以在一秒内生成几万个随机组合,效率完全不在一个量级。

不过要注意,随机不是瞎随机。我见过有人把随机约束写得跟没写一样,结果99%的测试都在测同一个场景。嗯,这里要强调:约束随机才是关键。

// 一个简单的约束随机示例
class packet;
  rand bit [7:0] length;
  rand bit [31:0] data;
  
  // 约束:长度必须在16到64之间
  constraint c_length {
    length inside {[16:64]};
  }
  
  // 约束:数据不能全为0
  constraint c_data {
    data != 0;
  }
endclass

我曾经踩过的坑:随机约束写得太松,导致大量无效测试。比如一个FIFO的深度只有16,我却允许随机生成深度为100的写操作。结果跑了一晚上,全是溢出错误,真正的功能bug一个没抓到。

覆盖率驱动验证(CDV):用数据说话

覆盖率驱动验证,说白了就是:别猜,用数据告诉你测够了没有。我刚开始做验证时,总觉得跑了几万个测试应该够了吧?后来学会看覆盖率报告,才发现有些关键路径一次都没走到过。

覆盖率主要分几种:

覆盖率类型 含义 我常用的检查点
代码覆盖率 RTL代码被执行了多少 行覆盖、分支覆盖、条件覆盖
功能覆盖率 设计功能点被覆盖了多少 状态机跳转、FIFO满空、协议握手
断言覆盖率 断言被触发了多少次 每个断言至少触发一次

CDV的核心流程:

  1. 制定验证计划,明确要测哪些功能点
  2. 编写约束随机测试,生成大量测试用例
  3. 收集覆盖率数据
  4. 分析覆盖率盲区,补充定向测试
  5. 重复2-4步,直到覆盖率达标

你可能会问:覆盖率100%就代表验证完了吗?当然不是。覆盖率只能告诉你测了什么,不能告诉你没测什么。我见过一个项目,代码覆盖率99%,功能覆盖率95%,结果流片回来还是挂了。为什么?因为有个跨时钟域的问题,覆盖率工具根本测不出来。

断言验证(SVA):给芯片装个监控

断言验证,你可以理解成给芯片装了个监控摄像头。它实时盯着关键信号,一旦出现异常就立刻报警。比如你要求"写使能有效时,数据必须有效",写个断言,仿真时自动检查。

我个人觉得,SVA是验证里性价比最高的手段之一。为什么?因为很多bug在波形上可能一闪而过,肉眼根本看不出来。但断言可以精确到纳秒级,而且能给出详细的错误信息。

// 一个简单的SVA示例
// 检查:当valid为高时,ready必须在3个时钟内拉高
property p_ready_within_3;
  @(posedge clk)
  valid |-> ##[1:3] ready;
endproperty

assert property (p_ready_within_3)
  else $error("valid asserted but ready not ready within 3 cycles");

我的经验:断言最好在设计阶段就开始写。等RTL写完了再补断言,效果会差很多。因为设计者最清楚哪些时序关系是关键的,等验证工程师来写,往往需要花更多时间理解设计。

三种方法怎么配合?

其实这三种方法不是互斥的,而是互补的。我一般这样安排:

  • 前期:写几个定向测试,确保基本功能没问题
  • 中期:大量跑约束随机测试,同时收集覆盖率
  • 全程:断言一直开着,随时抓异常

注意:不要为了凑覆盖率而写无意义的断言。我曾经见过有人写了100多个断言,结果全是"clk在每个周期都会翻转"这种废话。这种断言除了让报告好看,一点用都没有。

好了,今天的内容就到这里。记住:验证不是跑通就完事了,而是要用科学的方法证明你的设计是对的。定向测试、随机测试、CDV、SVA,这四个工具用好了,你的验证效率至少能翻一倍。