本文记录的相关源工程和文件为:
core-v RISCV 核功能验证工程:https://github.com/openhwgroup/core-v-verif
core-v 验证策略:https://core-v-docs-verif-strat.readthedocs.io/en/latest/#
core-v 系列核 cva6 工程:https://github.com/openhwgroup/cva6
core-v 系列核 cv32e40p 工程:https://github.com/openhwgroup/cv32e40p
LowRISCV Ibex 核工程:https://github.com/lowRISC/ibex
core-v RISCV 核相关说明文档:https://github.com/openhwgroup/core-v-docs
RISCV ISA 指令流(instruction stream)生成器:https://github.com/openhwgroup/force-riscv
core-v 系列指令流(instruction stream)生成器:https://github.com/openhwgroup/core-v-isg
sail 语言介绍:https://www.cl.cam.ac.uk/~pes20/sail/
REMS 的 sail RISCV 开源项目:https://github.com/rems-project/sail-riscv
openHW 全称为 open-source hardware,是一个支持开源软件和硬件的非盈利组织。该组织开源的内容包括开源 CPU 核、相关 IP、工具和软件等。
- 指令集验证
指令集验证的需求
能够使用操作数产生合法的基本整数运算指令
在指令执行完成后能够检查通用寄存器的状态
指令执行完成后能检查副效应,例如溢出等。
指令集验证内容
指令集的验证需要验证工程师思考该指令需要测试的特征是什么,为了确保指令的正确执行需要检查的内容是什么,为了确保该特征被测试需要进行哪些激励和配置等。验证的充不充分取决于验证人员对 CPU 微架构的理解和风险应对能力。
(1)RISCV 基本指令定向测试
设计出来的 CPU 首先需要兼容 RISCV 基本指令,即需要满足 RISCV 基本整数指令及相关标准指令集。
主要测试的内容有:
溢出检测及相关标志位
下溢检测及相关标志位
无指令执行的副效应,比如异常的通用处理寄存器变化,异常的条件代码
使用 x0-x31 作为 rs1/rs2
使用 x0-x31 作为 rd
x0 寄存器的值始终为 0
set/clear 所有立即数的比特位
set/clear 源寄存器 rs1/rs2 的比特位
根据 7/8 两条 set/clear 目的寄存器 rd 的比特位
(2)自定义扩展指令定向测试
对于自定义扩展指令集的验证,该验证需要修改相关的工具链并通过相关测试验证工具链的修改成功,再进行(1)中的测试。
(3)随机约束测试
对进行大量的随机指令测试
指令集验证激励的种类
指令集测试激励分为自检(self-checking)和预存(pre-existing)两种。
自检测试激励运行时按照源文件中指令顺序依次,并同时将指令执行结果和参考值作检查,若出错则程序跳转到 fail,打断正常执行顺序,立即执行完成。类似的测试集有 riscv-tests、riscv-compilance-tests 等
预存测试激励运行时不会打断执行顺序,执行的结果会和指令集模拟器(ISS)的结果作对比,最终统计对比的结果。类似的测试集有 riscv-dv 等
指令集验证 pass/fail 的标志
测试的 pass/fail 与上述激励的种类有关
self checking:自检性质的测试激励在每条指令执行时就会同时将结果和参考值作对比,若失败则跳转到 fail
signature check:特征检查,相对自检来说更加复杂深入。测试的结果将被用来计算该指令的某个特征,这将会和预先确定好的较标准特征作对比。采用该检查的为 riscv-complience-tests。
check against ISS:与指令集模拟器对比检查。该情况下,testcase 并不知道测试的参考值,仅仅给 DUT 提供激励,testbench 会对比 DUT 和 ISS 的输出结果确定测试的 pass/fail。该检查较被经常使用,因为它是的 testcase 更加简单。采用该检查的如 riscv-dv
check against RM:与参考模型对比检查,该检查方式与第三点类似,但相对 ISS 更加通用。通常用作 ISS 检测的补充。
assertion check:通过断言判断是否执行出错。
- 相关 CPU 核的验证工程
- cv32e40p
CV32E40P (原先 PULP 开发的 RI5CY) 是一个 32bit 的 4 级流水线核,支持整数运算指令、乘法除法指令、单浮点运算指令、压缩指令以及 DSP 扩展指令(包括硬件循环、SIMD 扩展、位操作和增量指令)
该核的验证环境有两套,一套是专门的 core testbench;一套是 UVM 环境搭建的 testbench,该环境下 testcase 的产生是可以基于 UVM 环境的(这种方式类似于 Ibex 核验证环境)。两套环境均由 systemverilog 编写。均包含了指令集验证、中断验证、CSR 寄存器验证、异常验证、debug 验证等。
1 core testbench
该工程是 PULP 遗留下的产物,OpenHW 做了一定修改并持续维护。验证环境中已集成了指令集模拟器。
该工程的测试集激励包含指令兼容性测试(偏定向测试,如 riscv-tests 和 riscv-compilance-tests)和随机约束(google riscv-dv),和其他的一些 fireware 测试用例。
测试环境结构如下:
该 testbench 简单,运行较快,通过 verilator 运行,但是有额外的开销且不能获取覆盖率。
2 UVM 验证环境(uvmt_cv32)
cv32 核的 UVM 验证环境已搭建完成,在 DSIM(Metrics)运行也很稳定。验证环境中已集成了指令集模拟器。
uvm 验证环境的 testcase 均是由 uvm 相关类生成,同时该环境还集成了 riscv-dv,但具体的激励生成还需要再分析。
具体验证环境结构
UVM 内部组件关系
debug、interrupt、control/status 均通过 UVM_agent 组件产生,且通过 uvm_sequence 组件输入激励。
UVM 运行流程
采用 UVM 搭环境的优势
a) 便于验证环境的结构建模
b) UVM 环境类支持完全的 UVM 运行流程和 log 服务
c) 使用 UVM sequence-item 类可以产生随即约束激励
d) 使用内建于验证环境中的参考模型预测执行的结果。(imperas 有现成的开源 ISS)
e) scoreboard 可以比较参考模型和 RTL 的结果。
f) 功能覆盖率和代码覆盖率确保验证的完全性。
且 UVM 测试环境可复用性较高,也可以用在 CVA6 核上。
- CVA6
CVA6(ariane) 是一个 6 级流水线、单发射、顺序执行的 RV32GC 或 RV64GC 核,支持 M/U/S 三种模式,支持 linux 操作系统。
该核现存的验证环境尚未成熟,但同样可以构建 UVM 的验证环境。
该工程的指令集测试激励包括 riscv 官方测试套件(即 riscv-tests)。
- Ibex
Ibex 不是 openHW 的 core-v 系列,而是 lowRISC 持续维护的较为成熟的一款核,验证环境也较为成熟,其结构和运行非常类似于 CV32E 和 CVA6 的激励随机约束。
该验证环境激励的产生同样是基于 GOOGLE 的随机指令生成器
验证环境特征
运行有效性
testcase 在验证环境中会持续运行完成,除非激励运行出错
方便调试
能够增加功能覆盖率
能够对比检查 RTL 运行的结果
- 指令集描述语言 ——sail
sail 是 REMS 构建的一种描述指令集的语言,可以认为是一种机器可读的形式化 ISA 模型。REMS 是英国的一家学术组织,该组织已构建出 RV32IMAC 和 RV64IMAC 指令集的 sail model,链接见上。
riscv 基金会有意用其来描述 RISCV 指令集。
初步来看,sail 可以用来形式化 testbench 断言的参考模型,这些 assertion 可以根据 sail spec 来验证基于 RISCV ISA 的某微架构。目前该领域 OneSpin GapFree 已经在 sail model 和 RTL 代码间做了可比性的 check,该公司仍在探索如何充分使用 sail model
该语言将持续关注。
评论 (0)