芯片验证之验证策略
1. 前言
验证策略是在高层次上对项目验证的整体规划,属于战略层面。它需要讲清楚项目验证对象是什么?如何确保验证对象的完备性?还涉及工作流程、进度安排和使用工具等方面的内容。这篇文章纯文字,可能会看得比较累。
2. 验证对象和完备性
为了做好验证,最重要的是从完备性、高效性和复用性上入手。先说完备性吧,如果验证对象是什么都没有搞清楚,那肯定是谈不上做好完备性了。因此对于验证对象,至少要了解清楚:
- 验证对象有哪些输入输出;
- 验证对象由哪些模块、子系统组成;
- 验证对象哪些逻辑是IP;哪些逻辑有改动,改动量多少;哪些逻辑是新开发的;
- 验证对象的整体功能要求和性能要求;
- 验证对象的相关规格文档有哪些,哪些可以作为验证的输入件;
2.1 完备性
知道了验证对象,那进一步就要谈怎么验证它,保证验证的完备性。
2.1.1 验证环境拆解
为了验证效率,通常会把大的验证对象拆解为合适大小的功能模块和子系统,然后使用不同层次的验证环境去验证,具体有模块级验证、子系统级验证和系统级验证。这些验证层次的激励、检查方式和验证侧重点都不一样。
- 模块级验证的激励易于控制,更能全面的覆盖功能点。如果一个功能点能在模块级完全覆盖,就不要在高层次上验证。模块级验证的侧重点在于模块的内部功能,比如状态机、FIFO和仲裁器等;当有些功能无法在模块级完全验证时,一定要提给更上游的验证。
- 子系统级验证主要是侧重于模块间的交互,信号连接、功能交互、流控等。子系统级通常对外有稳定的标准接口,比如AMBA接口。因此在激励构造上比较简单,而且可以真正验证到模块之间有无配合问题。
- 系统级验证侧重于不同子系统之间的信号连接、功能交互,以及实现更贴近实际场景的用例。它有使用EDA仿真工具进行的,也有使用FPGA或Emulation进行的,前者通常仿真速度慢,但方便调试,后者仿真速度快,但不方便调试。因此,使用EDA仿真工具的系统级验证通常运行系统软件层面场景的某一切片,而使用FPGA和Emulation的则可以运行比较大的软件程序,比如Linux。
在规划好哪些验证环境以及各自负责的功能点后,就是要确定验证环境采用的验证方法是什么。
2.1.2 验证方法
验证方法主要有直接验证、随机约束验证、形式验证和原型验证等,大部分验证环境会用上几种方法。而且根据验证激励产生方式和检查的功能点分布也将验证手段划分为黑盒验证、白盒验证和灰盒验证。验证方法和验证手段是可以交叉组合使用的,只要能解决问题,怎么组合都可以。在每个验证级别上要高层次描述所使用的验证方法、手段、激励产生方式、如何检查功能、使用哪些特殊的工具来验证以及覆盖率要求等。
- 模块级验证主要是采用随机约束验证、形式验证。早期调试环境和后期收集覆盖率的时候,会引入直接验证,用定向激励去产生特定的场景。验证手段通常也是灰盒验证或白盒验证,对激励的灵活性(可拓展和可控)要求高,也需要撰写比较贴近RTL功能的检查器,以便RTL某个功能点有问题时,能及时定位到。在这一层级也会使用较多的断言去做一些形式验证。
- 子系统级验证主要是采用随机约束验证和直接验证。系统规模的增大,形式验证很难证明收敛。验证手段通常使用灰盒验证和黑盒验证。对激励的要求稍微低些,主要这一层的接口大多数是标准接口,有可能直接使用VIP来产生激励,而且该层次的检查方式大多是在验证用例中self-check,可能也会复用模块级的检查器。子系统中通常也会引入一些商用的工具来辅助验证子系统功能的兼容性,比如ARM的ACK工具。
- 系统级验证主要是采用直接验证和原型验证。验证手段通常是黑盒验证。这层的验证激励直接就是实际软件场景的某个片段,通常也是在验证用例中完成检查。像CPU的话,一般都是要启动RTOS或Linux等OS了。
在规划好哪些验证环境、各自负责的功能点以及验证方法后,就是确定每个验证环境完成的标准是什么。
2.1.3 验收标准
整个验证周期会切割成多个关键节点,每个节点都需要定义一套验收标准,包括环境开发程度、回归通过率、覆盖率以及验证流程规范中必须召集的检视、头脑风暴等会议是否完成。不同级别的验证的验收标准也不一致,这个得需要根据总得验证目的拆解到每个级别的验证后,在当前验证级别上根据关键节点继续拆解成小的验收表单。
总得来说,验证策略要规划好有几个验证环境,每个验证环境主要负责哪些功能点的验证、验证方法是什么以及验证完成的标准是什么,通过这几个验证环境的总和来确保验证对象的完备性。
2.2 高效性
上面对验证对象使用几种类型的验证环境就是提高效率的一种。如果直接对一个系统级芯片验证,那么问题会多到我们无从下手,因此我们需要从模块级验证到子系统级验证再到系统级验证,验证范围由小变大,先把底层问题扫清,再去扫高层问题,层层递进。
另外就是验证功能要有轻重缓急之分,不是对所有的RTL代码都要花费一样的精力。比如IP或当前项目无修改的功能,对它们的验证可以优先级低一些。重点先把精力放在修改的地方、新增特性或场景的地方、芯片主要应用场景的地方。把重点对象都搞定好之后,再去完善低优先级的功能验证。
在分析验证环境时,要注重当前验证环境是否可以从其它环境继承过来,或者某些模块是否可以拿现成的修改点就行。
验证人员的能力匹配和积极性也是高效性必不可少的。需要和各成员沟通下,尽量确保大家都对当前所做的事情满意,不要硬塞。
2.3 复用性
如果某些功能组件可以复用其它项目的,那最好不过了。如果没有的话,那么可以想下是否可以由某个验证人员开发,然后各个验证环境都共享。或者有些组件可能会比较通用,那么可以在当前项目中把它做成标准化的组件,方便后续项目复用。
2.4 经验借鉴、风险和依赖
以史为鉴,历史有类似项目的问题清单和教训一定要拿过来分析,据此完善验证方案,查缺补漏。另外设计人员关心或担心的功能点,也要多方论证,保证能得到充足的验证。
验证过程中可能会有什么资源依赖、风险都要阐述出来,最好可以用问题跟踪系统,比如jira,去确保问题及时得到解决。
3. 工作流程
上节讲述了在策略层面上如何充分且高效地完成验证,这节谈一下在策略层面上需要规划的工作流程。
3.1 进度安排
明确的进度安排可以让各个验证人员清楚地了解到什么时间点该做完什么事,方便大家安排事情的优先级。而且这个进度安排一旦确定了,就不要随意变动,否则容易造成团队的不信任感。策略层面可以定一些大方面的进度规划,比如到某个时间点,有哪些功能是必须交付的,然后各个验证小组根据这个要求,在计划层面上把这些功能细化成更小的交付节点,方便量化进度。
3.2 问题跟踪
在策略层面要讲清楚什么类型的问题需要跟踪,原则上会影响到最终芯片的问题都要跟踪。故在验证过程中发现的问题、存在分歧点的地方、待办事项或重要的决定和权衡,都需要记录起来,以便跟踪和推进这些问题的解决,日后查看和反思。
问题跟踪系统工具有很多,比如Jira。问题跟踪系统工具所必需的功能必须要有:问题汇报者、当前问题处理者、抄送者、问题描述、问题出现的版本和时间、问题的解决过程记录以及最终解决方案。另外系统最好也可以导出特定格式的图形或数据,方便分析问题种类、趋势、紧急程度和之后对问题的举一反三、头脑风暴等。
3.3 代码跟踪
确定项目中代码管理规范和集成方式,比如采用GIT或SVN去协同代码开发,使用Gerrit和Jenkins来确保上传的代码是否符合要求。
以git为例,git上有master和branch之分,master是主流版本,上传到master的代码要经过严格的审查,防止破坏掉代码库。如果有个功能点需要多个人协同,一般需要创建branch分支,在分支上完成全部开发后,再合并回master上。Git master上也可以打tag标记,这样验证人员或后端人员可以基于特定的tag标记版本进行操作。
3.4 文档存放
在项目进行过程中,每个验证环境肯定会输出一些文件、记录等,需要确定文档存放的目录、格式。而且规定哪些文件是项目验收必须要有的,这些文档的撰写需要遵循什么规范,让大家心理有个数,随着验证开发过程中,逐步添加需要的文档内容。
3.5 代码规范
一个项目遵循统一的代码规范还是很必要的,既方便维护,也方便检视。而且当底层验证环境的组件复用到高层验证环境中,一致的代码风格也方便集成。但人总是会自由发挥的,这需要各个管理者和成员基于此,共同努力去强制遵守。
写验证策略的人需要和各团队商量好,制定一份通用的代码规范。比如文件命名方式、目录结构、注释等。
3.6 使用的工具
项目中使用的工具及其版本、平台等都必须一致,才能说明验证的一致性,而且也方便统一管理。验证策略里必须要确定验证使用的工具,每个验证环境的验证计划只需遵守就行了。要切换工具的话,那么全体验证环境都必须一起切换。
因此,选择工具及其版本必须要谨慎,最好选择稳定的版本,否则容易造成某些工具功能有缺陷,又得切换版本,浪费时间人力。
3.7 验收材料
项目验收需要充足材料和数据支撑,表明验证已经做好了。不同公司要求不一致,但至少应该包含以下材料:
- 每个验证环境的验证报告;
- 总的验证报告;
- 测试点完全反标且覆盖;
- 覆盖率100%实现和100%覆盖;
- 验证流程里各个环节的会议都完成且遗留问题都清理干净;
- 问题缺陷分析文档;
- 波形检视文档;
- Checklist检查完毕;
- 用例回归到一定周期数未发现新的bug;
- 所有代码实现完全且都上传到库上完毕;
上述这些材料都需要和架构、设计人员对齐,且无任何新增意见。
4. 总结
总得来说,验证策略是约束当前项目中全部验证人员的做事规范,也是验证人员必须熟知和遵守的指南。它在高层次上指导了整个验证的进行,验证计划据此衍生出更为详细的验证安排。