RISC-V核QuestaSim裸机仿真函数返回非法指令调试
RISC-V核QuestaSim仿真子函数返回非法指令异常问题
测试背景
- 运行环境:无FPGA的QuestaSim RTL仿真环境
- 测试对象:RISC-V核裸机程序
- 程序逻辑:主函数调用子函数
故障现象
子函数执行完毕准备返回主函数时触发非法指令异常,报错信息如下:
Error: Illegal instruction 0x00010413 at PC 0x00000004!
已开展排查工作
- 核运行跟踪日志分析:故障触发前,函数尾声用于返回主函数的jalr指令执行时,返回地址寄存器x1的值为0,相关跟踪日志如下:
78923501 78909 1c0023e6 00008067 jalr x0, x1, 0 x1:1c000a8e 78926501 78912 1c000a8e 00000493 addi x9, x0, 0 x9=00000000 78927501 78913 1c000a92 0060006f jal x0, 6 78929501 78915 1c000a98 01012d03 lw x26, 16(x2) x26=00000000 x2:100041b0 PA:100041c0 78930501 78916 1c000a9a 01412c83 lw x25, 20(x2) x25=00000000 x2:100041b0 PA:100041c4 78931501 78917 1c000a9c 01812c03 lw x24, 24(x2) x24=00000000 x2:100041b0 PA:100041c8 78932501 78918 1c000a9e 01c12b83 lw x23, 28(x2) x23=00000000 x2:100041b0 PA:100041cc 78950501 78936 1c000aa0 02012b03 lw x22, 32(x2) x22=00000000 x2:100041b0 PA:100041d0 78951501 78937 1c000aa2 02412a83 lw x21, 36(x2) x21=00000000 x2:100041b0 PA:100041d4 78952501 78938 1c000aa4 02812a03 lw x20, 40(x2) x20=00000000 x2:100041b0 PA:100041d8 78953501 78939 1c000aa6 02c12983 lw x19, 44(x2) x19=00000000 x2:100041b0 PA:100041dc 78954501 78940 1c000aa8 00900533 add x10, x0, x9 x10=00000000 x9:00000000 78955501 78941 1c000aac 03012903 lw x18, 48(x2) x18=00000000 x2:100041b0 PA:100041e0 78956501 78942 1c000aae 03412483 lw x9, 52(x2) x9=00000000 x2:100041b0 PA:100041e4 78974501 78960 1c000ab0 03812403 lw x8, 56(x2) x8=00000000 x2:100041b0 PA:100041e8 78975501 78961 1c000ab2 03c12083 lw x1, 60(x2) x1=00000000 x2:100041b0 PA:100041ec 78976501 78962 1c000ab4 04010113 addi x2, x2, 64 x2=100041f0 x2:100041b0 78978501 78964 1c000ab6 00008067 jalr x0, x1, 0 x1:00000000 79000501 78986 00000000 0fb12e27 sw x59, 252(x2) f27:00000000 x2:100041f0 PA:100042ec
- 反汇编代码核对:确认地址
1c000ab6处的指令为ret,是子函数的最后一条指令,功能为返回主函数,反汇编内容如下:
1c000ab6: 8082 ret
初步梳理的可能故障方向
- 结构体与函数指针实现问题:通过自定义结构体封装参数与函数指针模拟面向对象的类行为,暂不确定该实现是否完全符合规范(代码可正常执行到返回前位置)。相关实现示例如下:
void api_init(my_struct *_entity){ // -- init my function pointers _entity->init_streams = (void *)my_init; _entity->compute = (void *)my_compute;
实例化_entity后,通过如下方式调用函数:
(*_entity)->my_compute();
- 栈问题:程序中分配了较多指向内存缓冲区、函数的指针,已尝试在链接脚本中扩大栈空间,但暂未完全排除栈相关故障可能。
待解答问题
- 是否有开发者遇到过同类故障?
- 请提供可行的调试排查方法建议。
内容的提问来源于stack exchange,提问作者gb95
相关产品推荐
相关产品推荐

