-1

我想知道为什么在流水线 RiscV 上执行此汇编代码时 - 不会自动停止 - 通过转发(内部寄存器文件 WB->DEC 转发除外)我们需要在第三个命令之后立即放置两个 NOP 命令,不会一个 NOP 就够了吗?

addi t0, x0, 0
addi t1, x0, 5
addi s1, x0, 0x200 //why are two NOPS required after this command?
beq t1, t0, finish

这是我的思路 - 在一个 nop 之后,第一个命令完成编译,我们可以将 t1 从第二个命令的 WB 转发到 beq 的 EXE。我哪里错了?

4

2 回答 2

0

正如 Erik 所说,应该不需要NOP指令。CPU 实现应该处理依赖关系并在需要时停止流水线。如果由于某种原因,实现没有这样做(我将其称为 BUG),则有一些解决方法可以在稍后阶段修复它,编译器在检测依赖项时注入 nop 等。

如果 CPU 支持转发,如您在传统的 5 级流水线 CPU 上所说,则不需要NOP. 当BEQ指令到达 CPU 解码阶段时,t0已经写入寄存器文件,同时t1可以转发。

于 2021-11-23T10:49:17.523 回答
0

因此,在研究了几个小时之后,解决方案如下:需要两个关键事实:

  • Beq 只能从 WB 转发到,因为它的分支条件是由分支比较器计算的,并且转发只存在于 ALU 中。
  • 根据问题说明,我们不能从 WB->DEC 转发,所以本质上我们不能转发到 Beq。让我们编写阶段并“运行程序”:
IF DEC EXE MEM WB 
1
2   1
3   2   1
4   3   2   1 
    4   3   2  1
  • 注意我们不能执行 4 (beq t1, t0, finish),因为它依赖于指令 2 中 t1 的值。我们必须等待 t1 的值。MEM->DEC 转发不存在。我们只能在 DEC 阶段获取一个新的 t1,因为所有到 EXE 的转发都链接到 ALU,并且我们在 Comperator 计算我们无法影响的分支条件,因此我们必须等待并放置一个 NOP。让我们继续。
IF DEC EXE MEM WB
    4  NOP  3  2 
  • 请注意我们仍然无能为力 - 我们正在等待 t1 但我们没有 WB->DEC 转发(如问题中所述),所以我们必须等待 2 完成它在 DEC 的 WB 阶段所以我们可以获取 t1 的更新值,因此我们必须放置另一个 NOP。让我们继续。
IF DEC EXE MEM WB
    4  NOP NOP 3 - notice 2 has finished, we can now continue with the correct t1.
        4  NOP NOP
            4  NOP
                4
DONE.

于 2021-11-23T18:13:51.803 回答