第二章 验证计划制定:如何根据芯片规格书提取验证点,制定覆盖率目标

说实话,我刚入行那会儿,拿到一份几百页的芯片规格书,第一反应就是——头大。密密麻麻的功能描述、时序图、寄存器表格,根本不知道从哪里下手。后来带我的老工程师跟我说了一句话,我到现在都记得:“验证计划不是写出来的,是从规格书里挖出来的。”

这一章,我就跟你聊聊怎么挖这些“宝藏”。

2.1 规格书里到底藏着什么?

芯片规格书(Spec),说白了就是芯片的“宪法”。它定义了芯片该干什么、不该干什么、能干得多快、功耗多少等等。但问题在于,规格书是写给设计工程师看的,不是写给验证工程师看的。

所以,我们得学会“翻译”。

核心原则:每个功能描述,至少对应一个验证点;每个时序参数,至少对应一个覆盖率目标。

我个人习惯把规格书分成三类信息来读:

  • 功能描述:芯片支持哪些模式、协议、操作流程
  • 时序参数:时钟频率、建立保持时间、延迟要求
  • 寄存器定义:哪些寄存器可读可写、复位值、位域含义

举个例子,规格书里写“支持SPI模式0和模式3”,那验证点至少包括:模式0下的读写、模式3下的读写、两种模式切换、以及非法模式下的行为。

2.2 提取验证点的“三步法”

我总结了一个方法,叫“三步法”。你试试看,应该能帮你理清思路。

第一步:功能分解

把芯片的顶层功能拆成子功能。比如一个USB控制器,可以拆成:

  • 设备枚举
  • 数据传输(控制传输、批量传输、中断传输、同步传输)
  • 电源管理
  • 错误处理

每个子功能再继续拆,直到拆到不可再拆的“原子功能”。

第二步:边界识别

每个原子功能,都有它的边界条件。比如:

  • 数据包长度的最大值/最小值
  • 时钟频率的上限/下限
  • 寄存器地址的合法范围/非法范围
  • 状态机的合法状态/非法状态

我曾经在一个项目中,漏掉了FIFO半满标志的边界测试。结果芯片在量产时,某些批次刚好卡在半满阈值附近,导致数据丢失。嗯,从那以后,我对边界条件格外敏感。

第三步:覆盖率映射

每个验证点,都要对应一个或多个覆盖率目标。我习惯用一张表格来管理:

验证点 功能描述 覆盖率类型 目标值
SPI模式0写操作 CPOL=0, CPHA=0下的数据写入 代码覆盖率 100%
SPI模式切换 从模式0切换到模式3 功能覆盖率 覆盖所有合法切换路径
FIFO满标志 FIFO写满时满标志置位 断言覆盖率 100%
非法地址访问 访问未定义的寄存器地址 功能覆盖率 覆盖所有非法地址区间

2.3 覆盖率目标的制定原则

你可能会问:覆盖率目标定多少合适?100%吗?

说实话,100%的覆盖率在现实中几乎不可能。我见过一些团队,为了追求100%的代码覆盖率,写了大量无意义的测试用例,结果功能覆盖率反而很低。

我的建议:代码覆盖率目标定在95%-98%,功能覆盖率定在90%-95%,断言覆盖率争取100%。

为什么断言覆盖率要100%?因为断言是“硬约束”,它直接反映了设计是否违反了规格书的要求。如果断言没覆盖到,那这个bug很可能就漏掉了。

2.4 一个实战案例:I2C控制器

咱们拿一个简单的I2C控制器来练练手。规格书里写了这么几条:

  • 支持标准模式(100kHz)和快速模式(400kHz)
  • 支持7位地址和10位地址
  • 支持主模式和从模式
  • 支持时钟拉伸(Clock Stretching)

按照三步法,我们先做功能分解:

I2C控制器
├── 模式选择
│   ├── 标准模式
│   ├── 快速模式
│   └── 模式切换
├── 地址模式
│   ├── 7位地址
│   ├── 10位地址
│   └── 地址匹配
├── 工作模式
│   ├── 主模式发送
│   ├── 主模式接收
│   ├── 从模式发送
│   └── 从模式接收
└── 特殊功能
    ├── 时钟拉伸
    ├── 仲裁丢失
    └── 错误处理(NACK、超时)

然后识别边界条件:

  • 时钟频率:100kHz ±10%,400kHz ±10%
  • 地址范围:7位地址 0x00~0x7F,10位地址 0x000~0x3FF
  • 数据长度:1字节~256字节(取决于具体实现)
  • 时钟拉伸时间:最大35ms(标准模式)

最后映射覆盖率目标。这里我画了一张图,帮你理解整个流程:

验证点提取与覆盖率映射流程 芯片规格书 功能分解(拆成原子功能) 边界识别(找极值、非法值) 覆盖率映射(代码/功能/断言) 验证计划 + 覆盖率目标 每个原子功能 至少一个验证点 每个边界条件 至少一个覆盖率目标

2.5 避坑指南

做验证计划这么多年,我踩过不少坑。挑几个典型的跟你说说:

我曾经犯过的错:

  • 过度依赖代码覆盖率:代码覆盖率只能告诉你“这段代码被执行了”,但不能告诉你“这段代码执行的结果对不对”。功能覆盖率才是王道。
  • 忽略交叉覆盖:比如I2C的地址模式和时钟模式组合起来,可能有4种情况。如果只测了其中2种,那另外2种就是盲区。
  • 太晚开始规划覆盖率:我见过一个项目,验证都做了一半了,才想起来要定覆盖率目标。结果发现很多场景根本来不及补测。

我的小技巧:在写验证计划的时候,就把覆盖率目标写进去。每个验证点旁边,直接标注“代码覆盖率目标:XX%”、“功能覆盖率目标:XX%”。这样后期做覆盖率分析时,直接对照计划检查,一目了然。

2.6 总结一下

验证计划制定,说白了就是“从规格书里挖验证点,再给每个验证点定个覆盖率目标”。这个过程没有捷径,但有方法:

  • 功能分解要彻底,拆到原子功能为止
  • 边界识别要全面,合法非法都要考虑
  • 覆盖率映射要具体,每个验证点都要有对应的覆盖率类型和目标值

嗯,这一章就到这里。下一章咱们聊聊怎么搭建验证环境,让这些验证点真正跑起来。


专注资料整理