RISC-V32内嵌汇编C程序在Basys3板运行异常:仿真与硬件结果不符
RISC-V32内嵌汇编在Basys3上运行异常排查
我在C程序里用RISC-V32内嵌汇编读取指定内存地址0x10000400的值,通过LiteX在Vivado生成bin文件后,仿真阶段完全正常——该地址确实存着0x40(对应十进制64),变量key能正确拿到这个值。但把BIOS替换成自己的bin文件在Digilent Basys3开发板上跑时,key的值变成了0。另外试过不用内嵌汇编的代码,key拿到256,但这个值和0x10000400地址无关,而且两块块存储器都没初始化。
1. 仿真与硬件的内存映射不匹配
- 仿真里的
0x10000400只是虚拟映射,实际Basys3硬件上这个地址可能没绑定到你要读的块存储器。去查LiteX的配置脚本(比如targets/basys3.py),看看内存基地址、块存储器的地址分配是不是和仿真一致,有没有被其他外设占了这个地址。
2. 块存储器没做硬件初始化
- 仿真时会默认给块存储器塞初始化数据,但LiteX生成的硬件不会自动干这事,除非你在配置里指定了初始化文件。
- 检查有没有在LiteX配置里给块存储器指定
.mem初始化文件,把0x40写到0x10000400对应的偏移位置; - 不用内嵌汇编时拿到的256就是未初始化内存的随机值,实锤硬件上块存储器没被正确初始化。
- 检查有没有在LiteX配置里给块存储器指定
3. 内嵌汇编的指令兼容性问题
- 你用的LiteX软核(比如VexRiscv)可能没开启你汇编里用的指令扩展,导致指令执行出错,返回0。检查汇编语法是不是符合软核的指令集支持。
- 比如读取内存的汇编是不是这么写的?有没有编译器优化把变量搞乱了:
li t0, 0x10000400 lw a0, 0(t0)
4. 替换BIOS后缺硬件初始化流程
- LiteX的BIOS会帮你初始化内存、外设这些硬件环境,换成自己的bin文件后,这些活得自己干:比如设栈指针、初始化内存控制器、配置块存储器的访问模式。跳过这些的话,内存访问根本没就绪,读出来自然是0或随机值。
- 对比BIOS的初始化代码,看看有没有漏了块存储器使能、时钟配置这些步骤。
内容的提问来源于stack exchange,提问作者KabiLink
相关产品推荐
相关产品推荐

