这是一个轻量级、高性能的 RISC-V 32位全系统模拟器,支持 RV32IMAB 指令集,并集成了基于 Spike 的差异化测试 (Difftest) 以及 SimPoint 分析功能。
确保您的系统中已安装 g++ 和 zlib 开发库,然后直接运行:
make -j$(nproc)最简单的运行方式,加载二进制镜像并开始执行:
./a.out --image path/to/your/image.bin| 参数 | 说明 | 示例 |
|---|---|---|
--image <file> |
必选。指定要加载的二进制镜像文件。 | --image linux.bin |
--mode <mode> |
运行模式选择。可选:normal, bbv, ckpt, restore。 |
--mode normal |
--diff |
开启 Difftest 模式。与 Spike 逐条指令对比架构状态(仅在 normal 模式下可用)。 | --diff |
--out-bbv <file> |
在 bbv 模式下,指定产生的 BBV 文件路径。 |
--out-bbv test.bbv |
--points <file> |
在 ckpt 模式下,指定输入的 SimPoint 结果文件。 |
--points test.points |
--ckpt-dir <dir> |
指定保存 Checkpoint 文件的目录。 | --ckpt-dir ./checkpoint |
--restore-file <file> |
指定要恢复的 Checkpoint 文件路径。 | --restore-file ckpt.gz |
--max-insts <num> |
运行的最大指令条数(主要用于 restore 模式采样)。 |
--max-insts 100000000 |
此模式下,模拟器会与 Spike 进行严格的 GPR 和 CSR 校验,任何逻辑偏差都会立即停止。
./a.out --image ../image/linux.bin --diff恢复之前保存的状态,并限制运行 1 亿条指令后自动退出并统计。
./a.out --image linux.bin --mode restore --restore-file checkpoint/ckpt_sp0.gz --max-insts 100000000当前实现采用“1GB 连续 RAM + 离散 IO word 存储”的方式:
- 物理地址窗口:
0x80000000 - 0xBFFFFFFF(1GB) - 仅该范围使用连续数组分配,用于镜像加载和正常内存访问
- 超出
0xBFFFFFFF会触发越界错误并退出
0x00000000附近:启动 stub(启动阶段写入)0x00001000附近:Boot ROM stub(启动阶段写入)0x10000000 - 0x100000ff:UART(tree.dts对应reg size = 0x100)0x10000004:OpenSBI 兼容寄存器(初始化写0x00006000)0x0c000000 - 0x0c20ffff:PLIC(tree.dts对应reg size = 0x210000)0x0c201004:PLIC 中断相关寄存器(UART/PLIC 联动逻辑会访问)0x1fd0e000:Timer 寄存器(读取返回sim_time)0x1fd0e004:Timer 高位寄存器(当前返回 0)
说明:
- 低地址和外设地址不再占用连续大内存,而是按
word_addr -> word_data离散存储。 - 读未初始化的离散 IO word 默认返回
0。
Checkpoint 使用 zlib gzip(写模式 wb1,文件后缀通常为 .gz),按如下顺序写入:
header(固定 16 字节)CPU_state(POD 原样二进制)interval_inst_count(uint64_t)RAM原始字节流(固定ram_size字节,当前为 1GB)io_ranges + io_data(重复io_range_count次):io_range:两个uint32_t(base,size)io_data:紧随其后的size字节原始数据
header字段顺序为:magic:"Rem\0"(4 字节)version:当前为2ram_size:字节数(当前为 1GB)io_range_count
CPU_state当前大小:236字节(0xEC)interval_inst_count大小:8字节RAM大小:0x40000000字节(1GB)io_range_count当前为4,顺序固定为:BOOT -> UART -> PLIC -> TIMER
| 区段 | 起始偏移 | 结束偏移 | 大小 |
|---|---|---|---|
| Header | 0x00000000 |
0x0000000F |
0x10 |
| CPU_state | 0x00000010 |
0x000000FB |
0xEC |
| interval_inst_count | 0x000000FC |
0x00000103 |
0x08 |
| RAM | 0x00000104 |
0x40000103 |
0x40000000 |
BOOT range descriptor (base,size) |
0x40000104 |
0x4000010B |
0x08 |
BOOT data (base=0x00000000,size=0x2000) |
0x4000010C |
0x4000210B |
0x2000 |
UART range descriptor (base,size) |
0x4000210C |
0x40002113 |
0x08 |
UART data (base=0x10000000,size=0x100) |
0x40002114 |
0x40002213 |
0x100 |
PLIC range descriptor (base,size) |
0x40002214 |
0x4000221B |
0x08 |
PLIC data (base=0x0c000000,size=0x210000) |
0x4000221C |
0x4021221B |
0x210000 |
TIMER range descriptor (base,size) |
0x4021221C |
0x40212223 |
0x08 |
TIMER data (base=0x1fd0e000,size=0x8) |
0x40212224 |
0x4021222B |
0x08 |
总逻辑大小(未压缩)为 0x4021222C 字节(1,075,913,260 字节)。实际文件大小会因 gzip 压缩而变小。
- 当前恢复逻辑只支持新格式(含
header、io_ranges、io_data),不兼容旧格式。
./a.out --image linux.bin --mode restore --restore-file path/to/ckpt.gz --max-insts 100000000恢复流程:
- 先通过
init()分配 1GB RAM,并完成默认 Boot/IO 初始化 - 读取并校验
header(magic/version/ram_size) restore_checkpoint()覆盖CPU_state和interval_inst_count- 覆盖整个 1GB RAM 内容
- 读取并校验 IO 布局(base+size)是否与当前模拟器配置一致
- 读取每个 range 的
io_data并恢复 IO 内容
若需要自己读取文件,按“Checkpoint 格式”中的顺序使用 gzread 逐段解析即可。关键点:
- 必须先校验
magic="Rem\0"与version=2 - 必须使用与当前程序一致的
CPU_state结构体布局(同编译器/ABI 假设) - RAM 字节数必须与运行配置一致(当前固定 1GB)
- 最后按
io_ranges顺序读取并校验,再读取对应io_data
init(reset_pc, image, size): 初始化处理器状态,分配内存并加载 binary 镜像到指定的 DRAM 基地址。exec(config): 仿真主循环。根据SimConfig决定运行模式、处理周期计数、触发 Difftest 同步及处理检测点。RISCV(): 取指、译码和分发的核心。处理取指异常,并根据 Opcode 调用不同的子执行函数。RV32IM() / RV32A() / RV32CSR(): 分类处理整数、原子操作及 CSR 相关指令的执行逻辑。save_checkpoint() / restore_checkpoint(): 使用zlib对CPU_state以及整个物理内存进行压缩序列化/反序列化。
step(n): 驱动 Spike 内部核心向前执行n条指令。reg_check(state, priv): 比对 DUT 传入的状态(PC, GPR, CSR)与 Spike 内部状态。sync_state(state, priv): 强制将 DUT 的所有架构上下文同步给 Spike(用于启动和中断对齐)。sync_reg_from_dut(idx, val): 手术级同步。仅同步特定的通用寄存器(通常用于 I/O 读取后)。
include/: 所有的头文件,定义了指令集掩码、CSR 地址及类接口。exec.cpp: 包含主要的指令执行逻辑以及硬件外设(如 UART/PLIC)的简易模拟。simpoint.cpp: 负责 BBV 生成及 Checkpoint 的保存与恢复。spike_ref.h: 处理与 Spike (libriscv) 的集成及状态对比。