3. 验证计划制定:验证目标定义、功能分解、覆盖率规划、资源与时间估算
好,咱们进入正题。验证计划,说白了就是整个验证工程的“作战地图”。没有它,你就是在黑灯瞎火里乱撞。我见过太多团队,上来就写代码,写到一半发现功能漏了,或者覆盖率死活跑不上去,最后只能延期。嗯,这步省不了。
3.1 验证目标定义:你到底要验证什么?
很多人觉得验证目标就是“让芯片跑起来”。这太模糊了。我个人习惯,第一步是把规格书里的每一条功能点,翻译成可验证的“目标陈述”。
举个例子,规格书说“支持AXI突发传输”。那验证目标就不能只写“验证AXI”。你得拆开:
- 验证所有支持的突发长度(1, 4, 8, 16)
- 验证地址递增、回绕、固定三种模式
- 验证读写交错场景
- 验证异常终止和重试机制
我在项目中遇到过,有人把目标写成“验证DMA功能正常”。结果评审时被架构师怼了:“什么叫正常?你告诉我正常的标准是什么?” 从那以后,我要求团队每个目标都必须带一个通过/失败判据。
3.2 功能分解:把大象装进冰箱需要几步?
功能分解,就是把一个复杂的芯片功能,拆成一个个独立的、可验证的小单元。你想想看,一个SoC可能有几十个IP,每个IP又有几十个功能点。不拆开,你根本没法下手。
我常用的方法是层次化分解:
- 第一层:模块级 —— 比如UART、SPI、DMA各自的功能
- 第二层:子系统级 —— 比如DMA+Memory Controller的交互
- 第三层:系统级 —— 比如CPU通过DMA搬运数据到DDR
每个层级再往下拆。比如UART模块,可以拆成:
- 波特率发生器
- 发送FIFO控制
- 接收FIFO控制
- 中断产生逻辑
- 流控信号处理
3.3 覆盖率规划:别等到流片前才发现没测到
覆盖率,是验证质量的“体检报告”。但很多人把它当成了KPI来刷,这是本末倒置。
我个人习惯把覆盖率分成三类:
| 类型 | 说明 | 我的经验 |
|---|---|---|
| 代码覆盖率 | 行、条件、分支、状态机、翻转 | 这是底线,但别迷信。我见过代码覆盖率100%,功能照样挂的案例。 |
| 功能覆盖率 | 你关心的场景是否都跑到了 | 这才是核心。用SystemVerilog的covergroup来定义。 |
| 断言覆盖率 | 你写的assertion是否被触发了 | 很多人忘了这个。没被触发的断言,等于没写。 |
规划覆盖率时,我建议你反过来想:哪些场景漏掉了会出大事? 比如:
- FIFO满/空边界
- 跨时钟域同步
- 复位释放后的第一个操作
- 多个中断同时到达
3.4 资源与时间估算:别拍脑袋,要拍数据
这是项目经理最关心,也是工程师最头疼的部分。我见过太多人拍脑袋说“这个模块两周搞定”,结果搞了两个月。
我的估算方法,基于历史数据 + 复杂度系数:
- 先算基准:回顾上一个类似项目,每个功能点平均花了多少天?比如,一个AXI Slave的验证,我们团队历史数据是5人天。
- 再调系数:新模块比旧模块复杂多少?接口多不多?有没有新协议?系数从0.8到2.0不等。
- 最后加buffer:我个人习惯加30%的buffer。为什么?因为总有你没想到的bug,总有环境要调试,总有评审要改。
举个例子:
功能点:验证DMA的链表模式
历史基准:8人天
复杂度系数:1.5(因为这次支持二维链表)
调整后:8 * 1.5 = 12人天
加buffer:12 * 1.3 = 15.6人天 → 取整16人天
- 环境搭建:20% 时间
- 测试用例开发:40% 时间
- 调试与回归:30% 时间
- 覆盖率分析与收敛:10% 时间
嗯,这里要注意。很多人把环境搭建时间压得太短,结果后面调试时发现环境有bug,返工更浪费时间。我建议环境搭建至少留足20%,而且要做冒烟测试——先跑几个最简单的用例,确保环境基本通路是通的。
最后,时间估算一定要分阶段。别只给一个总时间。我习惯分成:
- M1:环境就绪,冒烟通过
- M2:所有功能用例开发完成
- M3:代码覆盖率达标(比如90%)
- M4:功能覆盖率达标(比如95%)
- M5:回归通过,验证报告发布
每个阶段设一个检查点。这样,如果某个阶段延期了,你还有机会调整后面的计划。而不是等到最后一天才发现完蛋了。