为RISC-V Spike添加自定义R型matmul指令遇非法指令错误排查
Spike自定义R型指令matmul触发非法指令错误的排查与解决
问题背景
- 自定义R型指令
matmul rd, rs1, rs2,采用CUSTOM_0 opcode(0x0b)、funct3=0b000、funct7=0b0000001,对应Spike的MATCH值为0x0200000b,MASK值为0xfe00707f - 已修改
riscv-binutils-gdb/opcodes/riscv-opc.c,汇编器可生成正确机器码,objdump -d验证测试二进制编码无误 - Spike已执行完整清理重建流程,标准指令如
add可正常运行,但自定义指令始终触发「非法指令」错误
关键调试发现
- 在Spike构建目录中搜索
0x0200000b及对应MASK值,未在processor.cc、insn_list.h等调度器生成文件中找到匹配条目,说明DECLARE_INSN(matmul, ...)未被构建系统处理并加入调度器 - 测试虚拟指令
myfoo复用add的MATCH/MASK值,复制add.h为myfoo.h并添加DECLARE_INSN(myfoo, MATCH_ADD, MASK_ADD),同样触发非法指令错误,且调度器文件中无关联记录 - 构建日志确认
matmul.o已编译成功,但指令逻辑未被纳入Spike的指令调度体系
核心原因分析
Spike的指令调度器依赖Python脚本自动生成,并非直接编译指令头文件即可完成注册,常见遗漏点包括:
DECLARE_INSN宏被错误的条件编译块包裹,导致生成脚本无法识别- 指令定义未被纳入调度器生成脚本的扫描范围
- 构建流程未触发调度器代码的重新生成
解决方案步骤
1. 修正encoding.h中的指令定义位置
Spike的scripts/insn_gen.py脚本会扫描riscv/encoding.h中的DECLARE_INSN条目,需确保指令定义在脚本可识别的全局区域:
// 放在riscv/encoding.h的全局范围,避免被额外#ifdef条件屏蔽 #define MATCH_MATMUL 0x0200000b #define MASK_MATMUL 0xfe00707f DECLARE_INSN(matmul, MATCH_MATMUL, MASK_MATMUL)
注意:不要将DECLARE_INSN放在仅编译时生效的条件块中(比如错误的#ifdef DECLARE_INSN自定义包裹)
2. 确认构建系统配置
- 检查
riscv/riscv.mk.in中的insn_h_files列表,确保已添加matmul.h,且构建日志中该文件被insn_gen.py处理 - 若使用自定义指令集扩展,需在
configure时通过--with-isa参数传递指令集信息(如--with-isa=rv64gc+custom0),确保脚本识别到自定义指令
3. 手动触发调度器代码生成
自动构建流程可能未触发脚本重新生成,可手动执行:
cd /opt/riscv-isa-sim/build python3 ../scripts/insn_gen.py --isa=rv64gc ../riscv/encoding.h > riscv/insn_list.h
执行完成后重新编译安装:
make -j$(nproc) && sudo make install
4. 验证生成结果
重新构建后,检查以下文件确认指令已注册:
build/riscv/insn_list.h中存在DECLARE_INSN(matmul, 0x0200000b, 0xfe00707f)build/riscv/processor.cc中包含matmul指令的调度逻辑
验证方法
- 重新编译测试二进制,运行Spike时添加
-d参数调试,确认指令被正确识别执行 - 使用
objdump -d再次验证机器码与MATCH/MASK的匹配性
内容的提问来源于stack exchange,提问作者Arjun Anand Mallya 23110039
相关产品推荐
相关产品推荐

