type
status
date
slug
summary
tags
category
icon
password
前言
本篇文章将通过对 OpenXiangShan 项目的 Difftest 接口的分析总结 Difftest 的原理和一些实现上拓展思路。
Difftest 分析总结
Difftest 是一种差分测试框架,是通过将新实现的逻辑与一个标准的参考模型的执行结果进行对比,从而验证新实现正确性的验证方法。在 XiangShan 项目中,给出了 Difftest 在 chisel 中的实现方式,由很强的参考意义。所以本文后面的分析也都将基于这一版 Difftest 的实现。
1 Difftest 接口原理与实现
Difftest 将 CPU 核的 RTL 实现与 RISC-V 官方提供的模拟器进行差分测试, 验证当前 CPU 的正确性。所以本质上就是要从 CPU 核内引出关键信号的线路并将其与参考模型中的信号进行对比,这样就需要 Difftest 架起 RTL 和其他编程语言的桥梁,将需要的信号传递给 Difftest。
1.1 DPI-C 机制
System Verilog DPI (Direct Programming Interface)是 SystemVerilog 与外部标称语言的接口,特别是 C 语言。通过 DPI 接口我们可以轻松的实现在 C 中调用 SystemVerilog 的函数以及在 SystemVerilog 中调用 C 的函数。
在 SystemVerilog 中通过
import "DPI-C"
声明我们就可以调用 C 中实现的函数,可以将其称为导入函数。相应的,在 SystemVerilog 中通过 export "DPI-C"
声明我们就可以在 C 中调用 SystemVerilog 的函数,可以称为导出函数。写一个简单的示例代码段:
需要注意的一点是在 在 C++ 中,要把
v_add
函数声明成 C 函数,即当在两种编程语言间构建通道时最重要的就是数据类型的转换,这里有一张数据类型映射的表格可供参考:
SV type | C type (Input) | C type (output) |
byte | char | char* |
shortint | short int | short int* |
int | int | int * |
longint | long long int | long int* |
shortreal | float | float |
real | double | double |
string | const char* | char** |
string[N] | const char* | char** |
bit | svBit | svBit* |
logic, reg | svLogic | svLogic |
bit[N:0] | svBitVecVal* | svBitVecVal* |
reg[N:0] or logic[N:0] | svLogicVecVal* | svLogicVecVal* |
open array[] | svOpenArrayHandle | svOpenArrayHandle |
chandle | void* | void* |
表中提到的 svBitVecVal 等数据结构在 C/C++ 中其实是一个数组。
1.2 Difftest 接口
通过上述的 DPI-C 机制,我们可以将核内的某些信号,比如 Reg 的值,在发生变化时向 C 代码中同步,并由 C 代码对比这时的参考模型的值,如果不同就报错退出,证明当前这条指令的执行出现了问题。
用简略的代码简单举例一下(示例的赋值比较愚蠢,可使用数组和循环替代),我们在 RTL 的 Reg 模块中添加 DPI-C 函数:
上述代码就可以完成简单的寄存器检查功能。
按照类似的格式我们可以根据自己核的模块,关心的节点,设计一些特定的接口,将信号引出到 difftest 中。
2 Difftest 的问题与解决思路
问题:仿真性能问题
Difftest 是存在性能问题的,尤其是在设计增大,架构变复杂,需要检查的接口和信号越来越多。软件运行的速度就会变慢,而这时如果将 RTL 实现放在加速器等高速硬件设备上时,就会浪费硬件设备的性能,因为他会始终等待 Difftest 的对比结果,对此,有几种解决方案。
- 保持在线对比,合并传输信息。而合并传输信息有两个方面
- 一是抓住主要矛盾,在设备的传输位宽对时间的影响大于传输次数影响时,优先精简端口信息。在设备的传输次数对时间的影响大于传输位宽影响时,优先将多个端口合并成一个,在 Difftest 一侧进行解码即可。
- 二是可以进行时间戳同步,即硬件先跑一段时间,如果 Difftest 没有跟上,则进行一段时间的等待。这种方案需要在软硬件之间维护一个 buffer,有一定复杂度,不如直接用离线对比。
- 使用离线对比,使用固定格式的 Log 文件,硬件和软件都进行输出,这样 Difftest 就不需要被等待,只需要在 Log 中对比其与 参考模型的差异即可。
- 作者:Light-ly
- 链接:notion.light-liuyi.top/article/difftest-analysis-and-think
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。