我尝试在Nexys4 DDR板上安装并运行一个版本的火箭芯片。到目前为止,我成功地生成了verilog,综合了设计,并附加了一个jtag探针(segger jlink)。可以通过openocd和gdb访问寄存器和内存。在加载了一小段asm之后,内核开始执行,但是在第一条执行的指令之后直接跳到0x0000000。我假设它陷入了陷阱,由于陷阱向量没有初始化,所以核心结束于0。有人知道怎么解决这个问题吗?
核心的模拟工作在verilator和vcs上。在这两种情况下,内核都会毫无错误地执行这三条asm指令。
测试后的asm代码为:
.section .text
.global _start
_start:
add x0,x0,x0
add x0,x0,x0
j _start与此脚本链接:
SECTIONS
{
. = 0x80000000;
.text : { *(.text) }
}对象转储:
Disassembly of section .text:
0000000080000000 <_start>:
80000000: 00000033 add zero,zero,zero
80000004: 00000033 add zero,zero,zero
80000008: ff9ff06f j 80000000 <_start>发布于 2019-08-09 14:44:08
最近在DDR4,GDB和SiFive的RISC芯片上遇到了类似的问题。在将代码加载到DDR4上并尝试从重置向量中单步执行后,RISCV会立即跳转到0x00000000。在使用Xilinx ILA进行调试后,我们发现尽管我们使用GDB对DDR4内存空间进行编程,但RISCV在内部缓存了一些代码,并且只是偶尔将一些代码推送到DDR4。从RISCV的角度来看,这被认为是可以的,因为当你单步执行时,它将决定使用缓存(如果可用),否则它将从DDR4检索代码。但是假设您的CPU拉动了几次DDR访问,因为它需要大量的代码来提高效率。一些大代码块(如果您的程序非常小,这些代码块可能是空白空间)将不会被编程,因此ECC计算不正确。
跳转至0x00000000后,检查机器原因寄存器。查看是否指示0x2,非法指令。在我的例子中,我看到这一点是因为总线观察到“总线错误”,这是由ECC故障do到半编程DDR突发引起的。
解决这个问题的一种方法可能是在ELF的末尾填充一堆额外的零,这样大小将迫使缓存刷新到内存中。一旦DDR被真正编程,并且ECC是正确的,您应该不会再看到无效指令。让我知道这对你是否有效。
https://stackoverflow.com/questions/57391609
复制相似问题