验证工程师与芯片验证(三)

本文

芯片验证系列文章主要分为三部分:验证工程师与芯片验证、SV学习笔记、UVM学习笔记。此为 验证工程师与芯片验证 部分第三篇,主要介绍计划的概述、计划的内容、计划的实现、计划的进程评估。

版本 说明
0.1 初版发布

参考

名称 作者 来源
《芯片验证漫游指南》 刘斌 书籍
《全面的功能验证:完整的工业流程》 Bruce Wile , John C. Goss , Wolfgang 书籍

专业术语与缩略语

缩写 全称 说明
FSM Finite state machine 有限状态机

计划的概述

验证计划是什么

  • 选择验证方法和构建验证环境前,首先需要知道验证计划是什么。
  • 展开设计之前,设计人员和验证人员都会阅读功能描述文档,以理解设计的各项功能为前提,考虑如何实现和验证它。
  • 实际项目执行中,功能描述文档和设计会不断更新,验证工程师要做好相应验证计划的更新。
  • 验证计划在设计启动之前就已经诞生,且伴随着整个设计周期。

计划的步骤

  • 创建验证计划
  • 选择验证方法
  • 人力资源调配
  • 构建验证平台和环境组件
  • 开发测试用例

收集的材料

  • 结构功能描述
  • 设计的各种操作使用模式
  • 正常输入和错误输入场景下设计的行为
  • 设计的接口
  • 边界场景下设计的行为
  • 设计在实际使用中的场景描述

计划的好处

  • 使得设计和验证人员对于功能描述文档的理解保持一致。
  • 将自然语言描述的功能通过可测试性语言来描述。
  • 可以更合理的评估出工作量、人力安排和进度节点。
  • 为验证人员提供明确的验证目标、任务和进度安排。
  • 为功能文档提供反馈,修改文档中不明确、有歧义的描述。

影响计划的因素

  • 验证计划是团队协作的产物,需要系统、设计、验证共同参与制定。
  • 需要更新成百上千的测试用例,并且与计划中待测试功能一一对应。
  • 考虑选择不同的验证方法,针对不同的设计,需要考虑使用模拟仿真、形式化验证或硬件加速验证,如需使用多平台验证,还要考虑如何实现技术平台上的兼容和跨越式复用。
  • 添加新的设计需求,需要更新验证计划。新添加功能,要考虑额外的人力和进度影响。
  • 多组参与验证,需要团队合作协调,以及测试用例的复用。

计划的内容

写在前面

  • 技术角度考虑,需要有验证的功能点、验证的层次、测试用例、验证方法和覆盖率要求。
  • 项目角度考虑,需要有使用工具、人力安排、进度安排和风险评估。

验证的功能

  • 基本功能: 时钟、电源、复位、寄存器访问和基本功能特性,这些可以在模块级完成验证。
  • 交互功能: 与其他模块交互的特性,需要在更高层次的子系统级或系统级完成验证。
  • 次要功能: 这些会在项目后期完成验证,比如性能验证,即便没有达到要求但是不会存在致命影响,所以风险较低,放在最好验证。

验证的层次

  • 结合验证功能点,需要清楚该功能点在何层次验证。
  • 从验证效率和激励自由度来看,应该尽量在较低层次验证更多功能点。
  • 在较高层次,应该侧重于系统集成测试。

验证的方法

  • 方法: 模拟仿真 or 形式化验证 or 硬件加速验证。
  • 透明度: 黑盒 or 白盒 or 灰盒(建议尽可能使用黑盒)。
  • 激励: 定向激励 or 随机约束激励。

验证的用例

选择:

  • 更随机的测试方法,尽可能遍历可能的状态空间。
  • 适中的随机约束,倾向于更贴近实际场景的随机激励。
  • 采用定向测试,针对一些边界情况可以更有效的收集覆盖率。

建议:

  • 验证初期,应该只发送一些基本的测试数据,约束范围尽可能窄。
  • 验证中期,由于设计基本稳定,可扩大约束范围,以此更有效地完成验证。
  • 验证后期,有一些边界场景通过随机约束激励无法有效收集覆盖率,需要采用定向用例。

覆盖率的要求

  • 覆盖率是衡量激励生成质量和功能点验证的量化指标。
  • 无论何种验证,都需要采用覆盖率来确保给出了足够的激励,遍历设计可能的状态。
  • 覆盖率可以分为代码覆盖率、功能覆盖率和断言覆盖率。
  • 除了给出合法的激励之外,也要考虑给出错误的激励,来测试设计的稳定性和纠错能力。

工具的选择

  • 模拟仿真工具
  • 形式化验证工具
  • 验证IP(如商用接口协议的验证IP)
  • 断言IP
  • 调试工具
  • 硬件加速器
  • 高层次验证语言

人力安排

  • 不同验证方法对人力安排存在明显差别,除了考虑个人的实际经验外,也需要考虑他们是否熟悉该模块,也就是验证人员的知识和技术背景越贴合,越倾向于选择这样的验证人员,这对于人力成本和验证风险都可以降低。
  • 推荐一个完整的项目周期内,固定人员跟踪同一个设计模块,从搭建环境、用例编写、覆盖率收集,以及模块级、子系统级、系统级整个验证过程,这样安排项目风险较低,人员成长较快。

进度安排

  • 首先进度往往是从上向下传达的,项目有时间进度,验证师会有一个大概的进度要求。
  • 工作量 = 人力 X 时间。
  • 验证经常会处于人力不够充分或时间不够宽松的境地。时间往往是固定的,做好任务的安排和动态的人力分配,实现高效的资源配置是关键。
  • 时间进度可修改吗? 这无法回答,如果能更细致的量化和评估时间和人力安排,delay的风险会较低。

风险评估

  • 芯片结构不稳定: 添加或修改新的功能,会增加新的工作量。
  • 工具的不稳定: 新的版本工具会增加新的特性,有可能提高工作效率,但是也会存在适应期。同时新的工具会面临环境流程更新、技术培训等问题。
  • 人力不稳定: 处于各种原因导致验证人员被临时替换,会加大验证风险。
  • 设计交付时间的不稳定: 设计的delay会直接影响到验证。

计划的实现

写在前面

  • 一份细致的验证计划也包括项目动向、更新内容和工程进度,清晰的计划更能保证时间和人力的平衡。
  • 验证计划需要时常保持更新,给出合理的安排,从计划到实践的反馈,再到计划修改。

如何制定验证计划

  • 邀请相关人员参加会议(设计、验证、系统等)。
  • 开会讨论验证方案。
  • 确定测试场景。
  • 创建验证环境。

邀请人员

项目角色 关注角度 期望验证点
设计人员 设计实践 设计内部时序、状态机、内部逻辑
硅后测试人员 硅后模块功能测试 硅前测试用例移植到硅后测试
软件人员 模块在系统中的应用 软件正确的配置序列被测试
系统人员 结构和性能要求 设计框架符合要求,性能和效能可以早期测试
验证经理 进度、人力和优先级 给出合理安排,定期更新计划
验证人员 验证方法和环境 综合衡量其他角色意见,给出统一的解决方案

开会讨论

作为会议组织者,首先明确开会的目的和议题:

  • 报告验证计划的内容。
  • 确定验证功能点。
  • 确定验证方案和时间节点。

一份验证计划的模板应该包含以下内容:

  • 设计功能简要概述。
  • 硬件实现结构框图。
  • 待验证的功能点。
  • 验证环境结构。
  • 测试用例构成。
  • 编译脚本和回归测试。
  • 覆盖率分析。
  • 风险评估。

确定测试场景

  • 电源开关。
  • 复位测试。
  • 常规场景。
  • 边缘场景。
  • 错误场景。
  • 性能压力测试。
  • 选择验证层次和验证方法。

创建验证环境

  • 搭建环境时,依据设计结构创建不同的接口信号和激励组件来构建场景。
  • 是否可复用验证资源,以及可用的vip。
  • 监测组件收集数据,确定采样时序和事件,捕捉有效信号。
  • 构建参考模型,模拟DUT行为。
  • 检查组件比对结果,输出报告信息。

计划的进程评估

写在前面

在验证过程中,需要不断更新验证进度,从 各项参数综合评估验证的完备性

  • 回归测试通过率(regressioin pass rate)
  • 代码覆盖率(code coverage)
  • 断言覆盖率(assertion coverage)
  • 功能覆盖率(function coverage)
  • bug曲线(bug curve)

回归测试通过率

  • 一份 回归测试表 是将测试设计所有功能点的用例合并为一个测试集。
  • 回归测试表的主要功能是用来在设计bug修复后或性能优化后,验证原有的功能是否正常。
  • 回归测试不仅确保设计修改不影响原功能,且不影响其他模块功能。
  • 回归测试表中的测试用例,需要确保可以复现激励场景。这对于定向测试是容易实现的,而对于随机约束测试,需要保存随机种子,方便复现激励场景。
  • 如果某层次回归测试通过,可向上迁移到新的验证层次,展开新的回归测试流程。
  • 不同层次、不同设计规模、不同测试场景的复杂度,都会影响测试用例的仿真时间。
  • 回归测试中,对验证平台的优化(运算资源和运算效率)的要求更高。
  • 如果系统级回归测试发现bug,修复后需要从模块级回归测试开始运行。

代码覆盖率

  • 代码覆盖率是用来衡量 RTL代码是否被充分运行 的指标。
  • 通过工具开关可自动收集代码覆盖率,且可以将不同批次回归测试覆盖率数据进行合并。

常见的代码覆盖率:

  • 语句 覆盖率(statement coverage): 程序每一行代码是否执行过。
  • 条件 覆盖率(condition coverage): 每个判断条件中的操作数被覆盖情况。
  • 分支 覆盖率(branch coverage): if、case、while、repeat、for等语句中各个分支执行情况。
  • 事件 覆盖率(event coverage): 记录某个事件被触发的次数。
  • 翻转 覆盖率(toggle coverage): 记录信号数据位 0->1 和 1->0 的翻转情况。
  • 状态机 覆盖率(FSM coverage): 记录状态机各个状态的进入次数,以及状态间的跳转情况。

断言覆盖率

  • 仿真过程中,会判断断言的先决条件是否被触发,以及判断语句的成功与否。
  • 依据仿真工具不同,断言覆盖率可分为动态仿真和形式化验证两种。

功能覆盖率

功能覆盖率衡量设计的各项功能是否实现。功能覆盖率会关注设计的输入、输出和内部状态。

  • 输入: 检测数据端的输入和命令组合类型,以及控制信号与数据传输的组合情况。
  • 输出: 检测是否有完整的数据传输类别,以及各种场景的反馈时序。
  • 设计内部: 检查信号与功能点相对应,通过单一覆盖、交叉覆盖或时序覆盖来检查功能场景是否被触发。

注意: 功能覆盖率的收集需要依据功能点文档编写covergroup,且fail用例的覆盖率数据不能合并到回归测试的覆盖率数据中。

bug曲线

  • 验证过程中要记录和统计bug,bug管理工具一般具有提交、修改、完成、挂起四个状态。
  • 每周统计新增bug数量和修复bug数量,绘制bug曲线。
  • 依据bug曲线,如果能尽早的收敛,意味着后期发现bug的数量和可能性就越小,是设计稳定性的有效指标。
  • 注意: 如果验证后期发现一个基本功能的严重bug,意味着我们很可能在之前验证过程中遗漏了一些重要场景的测试。

文章原创,可能存在部分错误,欢迎指正,联系邮箱 cao_arvin@163.com。