【问题标题】:Why traps Rocket Chip on FPGA after code execution in DRAM为什么在 DRAM 中执行代码后将 Rocket Chip 困在 FPGA 上
【发布时间】:2019-12-14 22:13:34
【问题描述】:

我尝试在 Nexys4 DDR 板上启动并运行 Rocket Chip 版本。到目前为止,我设法生成了verilog,综合了设计并附加了一个jtag探针(segger jlink)。可以通过 openocd 和 gdb 访问寄存器和内存。加载一小段 asm 的 sn-p 后,内核开始执行,但在第一条执行指令之后直接跳转到 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>

【问题讨论】:

    标签: verilog fpga chisel jtag rocket-chip


    【解决方案1】:

    最近在 DDR4、GDB 和 SiFive RISC 芯片上遇到了类似的问题。在将代码加载到 DDR4 并尝试从复位向量跳出后,RISCV 将立即跳转到 0x00000000。在使用 Xilinx ILA 进行调试后,我们发现虽然我们使用 GDB 对 DDR4 内存空间进行编程,但 RISCV 在内部缓存了一些代码,并且只是偶尔将一些代码推送到 DDR4。从 RISCV 的角度来看,这被认为是可以的,因为当您执行步骤时,它将决定使用缓存(如果可用),否则它将从 DDR4 检索代码。但是,假设您的 CPU 需要大量的代码来提高效率,因此需要大量的 DDR 访问。如果您的程序真的很小,那么一些大块代码可能是空白空间,它们不会被编程,因此 ECC 计算不正确。

    跳转到0x00000000后检查机器原因寄存器。看是否表示0x2,非法指令。在我的情况下,我看到这个是因为总线观察到“总线错误”,这是由 ECC 故障对半编程 DDR 突发造成的。

    解决此问题的一种方法可能是在 ELF 末尾用一堆额外的零填充,这样大小将强制缓存刷新到内存。一旦 DDR 被真正编程,并且 ECC 正确,您就不会再看到无效指令了。让我知道这是否适合您。

    【讨论】:

    • 非常感谢您的回答:) 几天后,我又回到了问题上,并在您的提示的帮助下找到了原因。我在跳转到 0x0000000 后检查了 mcause 寄存器,是的,它显示 0x2 是无效指令。我用一个小的 BRAM 块切换了 DRAM,但一切都保持不变。之后,我用 ILA 监视内存端口并锁定在内核发出的指令读取。事实证明,vivado 使用 32 位接口而不是 64 位来封装内核。这样,高 32 位总是为零,因此作为指令无效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-03
    • 2018-10-15
    • 2013-04-17
    相关资源
    最近更新 更多