1. 验证导论
HVL拥有的典型性质:
- 受约束的随机激励产生
- 功能覆盖率
- 更高层次的结构,如面对对象
- 多线程及线程间的通信
- 支持HDL数据类型,例如0,1,x,z
- 集成事件仿真器,便于对设计加以控制
1.1 验证流程
验证并行于设计流程,验证必须阅读同样的硬件规范并拟定验证计划,然后按照计划创建测试来检查RTL代码是否准确实现了所有的特性。验证计划是与硬件的规范紧密联系的,它描述了需要什么样的验证特性以及采用了什么样的技术,如定向或随机的测试,断言,软硬件协同验证,硬件仿真,形成验证以及验证IP的使用等。
1.1.1 不同层次上的测试
代码块(block)层次上的bug是最容易检测的,例如ALU中的加法逻辑等。
代码边界也是漏洞出现的多发地带,原因在于不同设计者可能对于同一规范产生的不同解读,从而在硬件逻辑上产生争议。
在待测的最高层次上,整个系统均被测试,但是仿真会变简单。测试应该让所有的代码块尽可能并发活动。所有的输出和输入端口均被**,处理器处理数据,高速缓存载入数据,从而暴露出数据分配和时序上的bug。
永远也无法证明没有任何bug留下,因此需要不断尝试系的验证策略。
1.2 基本测试平台功能
- 产生激励
- 把激励施加到DUT上
- 捕捉响应
- 检验正确性
- 对照整个验证目标测算进展情况
1.3 方法学基础
采用如下原则:
- 受约束的随机激励
- 功能覆盖率
- 使用事务处理器的分层测试平台
- 对所有测试通用的测试平台
- 独立于测试平台外的个性化测试代码
随机测试能够找到预料不到的漏洞,使用随机测试时需要功能覆盖率来评估测验证的进展情况。但是整个系统的验证工作量巨大,一个分层的测试平台能把问题分解为容易处理的小块,有助于控制复杂度。事务处理器能够为小块提供有用的的模式。在适当的规划下,可以建立一个测试平台的基础设施,能在所有测试中通用并且不用经常性修改。只需要在特定地方放置“钩子”,以便测试能够在这些地方执行调整激励或者注入错误这样的特定操作。针对单一测试的个性化代码必须与测试平台分开,避免增加测试平台复杂度。
一开始使用随机化查找漏洞, 随着覆盖率提升,然后再使用定向测试寻找漏洞,如下图:
eg. 刚刚安装完操作系统,直接测试。测试结果会很好,但是安装完软件后,随着配置该变,就暴露出bug。
1.4.2 输入数据
选取一个总线写入的事务或ATM信元,然后把随机数填充到其中数据字段里。需要事先估计好所有分层协议和错误注入,以及记分板内容和功能覆盖率。
1.4.3 协议异常、错误和违例
死机大概率是内部逻辑遇到了错误无法恢复。大多数情况下,唯一办法就是关机重启。尝试用不当的命令去激励硬件同时,也应该捕捉出现问题。增加用于检验的代码帮忙找出问题,至少在出错的地方打印一个警告信息,如果能报告错误并停下来更好。使用断言可以追溯故障根源。
1.4.4 时延和同步
使用受约束的随机时延有助于捕捉协议上的漏洞。时延最短的测试运行速度最快,但它产生不了所有可能的激励。隐蔽的bug往往是引入间歇时延才发现的。
1.4.5 并行的随机测试
使用不同的种子运行同一个测试,可以得到多个不同的激励集合,这样可以增加覆盖率,也能减少工作量。
例如使用时间处理器型号温度等得到独一无二的种子,避免产生相同的种子。
1.5 功能覆盖率
需要知道哪些部分被验证过,才能对验证计划中的项目进行核对。要得到功能覆盖率,首先需要在测试平台中加入代码,用于监控进入设备的激励,以及对激励的反应,并确定哪些功能被访问过。运行多次仿真后,将结果合并到一个报告中,然后对结果分析,最后决定如果让新的激励来达到未测试的条件和逻辑。
使用随即事务和中止判断是有效的测试策略,运行时间越长,覆盖率越高。而且当时序改变时,这种灵活的激励也足以应对。可以在测试代码中加一个反馈循环检测已经产生的激励并根据情况调整约束的权重。这样能大量缩减完全覆盖的时间,而且只用很少的人工干预。
1.6 测试平台构件
仿真时,测试平台会将整个待测设计包围起来。测试平台与测试仪器都会产生激励并捕捉响应。不同点在于测试平台工作在一个宽泛的抽象层次上,同时创建事务和激励序列并最终转换成比特向量,而测试仪器只工作在比特级上。
测试平台构件有很多总线模型(BFM),例如USB,AMBA,PCI,SPI等。但是其只是遵循协议的高层次事务处理器,并不可综合。如果需要在FPGA上实现或是硬件仿真,这些模型必须是可综合的。
1.7 分层的测试平台
测试平台总共分为5层(从下至上)分别为信号层、命令层、功能层、场景层及测试层。
信号层包含待测设计和把待测设计连接到测试平台的信号。
命令层中,执行总线读写命令的驱动器驱动了待测设计的输入。待测设计输出与监视器相连,监视器负责检测信号变化,并将变化按照命令分组。断言穿过命令与信号层,负责监视独立的信号从而找寻穿越整个命令的信号变化。
功能层中,事务处理器(Agent)接收到上层的事务,将其分解为独立命令。同时这些命令也被送往预测事务的记分板,检验器负责比较监视器与记分板的命令。
场景层中的发生器驱动功能层。下载音乐需要很多步骤,例如前期准备时控制寄存器的读写、歌曲传输过程中DMA的多次写等。场景层负责组织协调完成预期任务的步骤,操作参数都采用受约束的随机值。
测试层为测试平台的最顶层。测试层包含了用于创建激励的约束。功能覆盖率可以衡量所有测试在满足验证计划方面要求的进展,随着测量标准的完成进度,覆盖率代码也在不断修改,所以其不作为测试环境的一部分。
日常设计中测试平台不一定要具有所有的层次。设计越复杂,测试平台就需要越完备。测试层是必须的,简单设计中场景层可以被整合到代理(Agent)中。
1.8 仿真环境的阶段
三个基本阶段是建立(build)、运行(run)和首尾(wrap-up)。
建立阶段:
- 生成配置: 把待测设计的配置和周围环境随机化
- 建立环境:基于配置来分配 和连接测试平台构件。
- 对待测设计进行复位
- 配置待测设计:基于第一步中生成的配置,载入待测设计的命令寄存器
运行阶段:
- 启动环境:运行测试平台构件
- 运行测试:启动测试然后等待测试完成。使用timeout检测确保待测设计或测试平台不出现死锁
收尾阶段:
- 清空:等待待测设计清空最后的事务
- 报告:一旦待测设计空闲下来,可以清空测试平台中的遗留数据。同时根据这些信息创建报告,说明测试通过或失败
1.9 测试平台代码重用及性能
随机测试的主要工作是构件平台,使受激励的随机激励包含所有较低的层:场景、功能、命令及信号。这个代码要有很好的通用性,使它能被所有的测试使用。测试平台中每多一行,就等于每个单独测试中都减少一行。
为了提高测试平台的性能,使用受约束的随机激励测试时非常必要的。创建随机测试的步骤为:
- 建立分层的测试平台,包括自检的部分。
- 按照验证计划中列举的目标创建激励。可以使用随机约束,也可以采用注入错误或协议违例等迂回方式
- 功能覆盖率。在环境中添加工具收集数据。根据数据判断是否满足目标要求