1

我正在准备测试并有这样的例子。以下代码:

1: SLL $1, $1, 2
2: LW $2, 1000($1)
3: BEQL $2, $0, END
4: ADDI $3, $2, 1
5: MULT $3, $2
6: MFLO $4
END:
7: J QUIT
...
QUIT:
100: NOP

在 RISC 处理器(带有准 MIPS 指令集)上执行

  • 五级管道
  • 绕过
  • 没有动态调度
  • 分支延迟槽
  • 另外我们知道,该分支不会被占用

我的任务是了解分支延迟槽在这种情况下如何工作并构建正确的管道图。

我有一个官方的解决方案,它给出了下图,没有任何解释:

1: SLL $1, $1, 2         IDEMW  
2: LW $2, 1000($1)        I---DEMW  
3: BEQL $2, $0, END           I---DEMW  
4: ADDI $3, $2, 1                 IDx
5: MULT $3, $2                       IDEMW
6: MFLO $4                            I---DEMW

据我了解,ADDI 在分支延迟槽中执行,并在处理器理解后停止,该分支没有被采用,这导致我们得到错误的结果。我的问题是

  • 我对吗?
  • 如果是,为什么ADDI在Branch Delay Slot中执行而不是Jump?
4

1 回答 1

4

CPU 继续按顺序读取指令,即在执行期间(已经获取、解码并且正在处理剩余阶段,我不知道您的确切阶段,所以这只是一般描述)beql它将获得管道的另一部分可以自由获取下一条指令,但分支尚未完成,因此PC仍然指向分支后的下一条指令 -> 那是“分支延迟槽”。

在经典 MIPS 上,这条下一条指令被获取、解码和执行,同时分支可能会也可能不会将 PC 修改为分支目标,因此每次都会执行分支延迟槽指令。只有在没有发生分支时才执行它之后的下一条指令,即PC依次在“分支延迟槽”位置之后继续执行。如果分支确实修改了PC, fetch+decode 将注意到并解码来自新目的地的下一条指令,因此在经典 MIPS 上,分支延迟槽只有 1 条指令“大”(我不知道更复杂的 MIPS CPU 是否可以有更多阶段和更多延迟槽可用,技术上具有 5 级管道,甚至 5 条指令延迟听起来硬件可能,但实际使用可能非常困难,听起来它会产生比帮助更多的问题)。

BEQL更复杂的指令,如果分支条件失败,则在执行中途终止延迟槽指令。

有关. _ _BEQL

所以“NullifyCurrentInstruction()”可能就是图中的那个“x”。图中剩下的东西,我只是猜测,因为我没有研究你的 5 阶段细节,但是LW在获取和解码之后(?)发现它依赖于$1,所以它在依赖阶段等待前一个指令W阶段。等等...TheADDI不依赖于任何东西,所以它几乎平行于 执行BEQL,并在最后被杀死。

但我不明白为什么每次“I”阶段被释放时都没有“I”阶段,看起来“I”在等待某些东西,最后你最多有2条指令同时进行。

无论如何,如果不研究您问题中使用的 CPU 的技术细节,这是非常难以理解的,而且我不想研究它,我什至不确定您拥有什么样的 CPU,以及从哪里获得它的技术文档。


编辑:我也会在这里尝试提取pdf的相关部分,以使这个答案不仅仅是“链接”,而是复制pdf可能会很棘手......

BEQLMIPS IV CPU 的指令文档:

说明: if ( rs= rt) then branch_likely
一个 18 位有符号偏移(16 位偏移字段左移 2 位)被添加到分支之后的指令地址(不是分支本身),在分支延迟槽中,形成一个PC相对的有效目标地址。
如果 GPRrs和 GPR的内容rt相等,则在延迟槽中的指令执行完毕后跳转到目标地址。如果不采取分支,则不执行延迟槽中的指令。

操作:
I:
  tgt_offset ← sign_extend(offset || 0 2 )
  条件← (GPR[rs] = GPR[rt])
I+1:
if condition then
  PC ← PC + tgt_offset
else
  NullifyCurrentInstruction()
endif

于 2018-02-06T22:48:19.290 回答