为什么在 DRAM 中执行代码后将 Rocket Chip 困在 FPGA 上
Why traps Rocket Chip on FPGA after code execution in DRAM
我尝试在 Nexys4 DDR 板上安装一个 Rocket Chip 版本 运行。到目前为止,我设法生成了 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>
最近 运行 遇到与 DDR4、GDB 和 SiFive RISC 芯片类似的问题。将代码加载到 DDR4 并尝试从复位向量步进后,RISCV 会立即跳转到 0x00000000。在使用 Xilinx ILA 进行调试后,我们发现虽然我们使用 GDB 对 DDR4 内存 space 进行编程,但 RISCV 会在内部缓存一些代码,并且只是偶尔将一些代码推送到 DDR4。从 RISCV 的角度来看,这被认为是可以的,因为当您执行步骤时,它将决定使用缓存(如果可用),否则它将从 DDR4 中检索代码。但是假设您的 CPU 拉动了几次 DDR 访问,因为它需要大量代码来提高效率。如果您的程序真的很小,那么大块代码中的一些可能是空的 space,将不会被编程,因此 ECC 计算不正确。
跳转到0x00000000后查看机器原因寄存器。看是不是提示0x2,非法指令。在我的例子中,我看到这个是因为总线观察到 "bus error",这是由 ECC 故障引起的,对半编程的 DDR 突发。
解决此问题的一种方法可能是在您的 ELF 末尾添加一堆额外的零,这样大小将强制缓存刷新到内存中。一旦对 DDR 进行了真正的编程,并且 ECC 正确无误,您就不会再看到无效指令了。让我知道这是否适合您。
我尝试在 Nexys4 DDR 板上安装一个 Rocket Chip 版本 运行。到目前为止,我设法生成了 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>
最近 运行 遇到与 DDR4、GDB 和 SiFive RISC 芯片类似的问题。将代码加载到 DDR4 并尝试从复位向量步进后,RISCV 会立即跳转到 0x00000000。在使用 Xilinx ILA 进行调试后,我们发现虽然我们使用 GDB 对 DDR4 内存 space 进行编程,但 RISCV 会在内部缓存一些代码,并且只是偶尔将一些代码推送到 DDR4。从 RISCV 的角度来看,这被认为是可以的,因为当您执行步骤时,它将决定使用缓存(如果可用),否则它将从 DDR4 中检索代码。但是假设您的 CPU 拉动了几次 DDR 访问,因为它需要大量代码来提高效率。如果您的程序真的很小,那么大块代码中的一些可能是空的 space,将不会被编程,因此 ECC 计算不正确。
跳转到0x00000000后查看机器原因寄存器。看是不是提示0x2,非法指令。在我的例子中,我看到这个是因为总线观察到 "bus error",这是由 ECC 故障引起的,对半编程的 DDR 突发。
解决此问题的一种方法可能是在您的 ELF 末尾添加一堆额外的零,这样大小将强制缓存刷新到内存中。一旦对 DDR 进行了真正的编程,并且 ECC 正确无误,您就不会再看到无效指令了。让我知道这是否适合您。