MIPS,流水线和分支延迟槽的示例

时间:2018-02-06 19:14:03

标签: assembly mips pipeline risc

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

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在Branch Delay Slot中执行并被停止 在处理器理解之后,该分支未被采用,导致我们错误的结果。我的问题是

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

1 个答案:

答案 0 :(得分:3)

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

在经典MIPS上,下一条指令被取,解码和执行,同时分支可能会也可能不会将PC修改为分支目标,因此每次都会执行分支延迟槽指令。仅在没有发生分支时执行下一条指令,即PC在“分支延迟时隙”位置之后顺序继续。如果分支确实修改了PC,则fetch + decode将注意并解码来自新目的地的下一条指令,因此在经典MIPS上,分支延迟槽只有1条指令“大”(我不知道是否更复杂的MIPS CPU可以有更多的阶段和更多的延迟槽可用,技术上有5级流水线甚至5条指令延迟声音HW可能,但它可能很难实际使用,听起来像它会产生更多问题而不是帮助)。 / p>

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

有关BEQL的详细说明,请参阅http://math-atlas.sourceforge.net/devel/assembly/mips-iv.pdf第45页。

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

但我不明白为什么每次“我”阶段被释放时都没有“我”阶段,看起来像“我”等待某事,最后你最多只有两条指令在同一时间。

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

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

MIPS IV CPU的

BEQL指令文档:

  

描述:   if(rs = rt)然后branch_likely
  在分支延迟时隙中,将18位有符号偏移(16位偏移字段向左移位2位)添加到分支(不是分支本身)之后的指令的地址,以形成PC相对有效目标地址。
  如果GPR rs和GPR rt的内容相等,则在执行延迟时隙中的指令后跳转到目标地址。如果未采用分支,则不执行延迟槽中的指令。

     

操作:
  我:
  tgt_offset←sign_extend(offset || 0 2
  条件←(GPR [rs] = GPR [rt])
  I + 1:
  如果条件那么   PC←PC + tgt_offset
  否则
  NullifyCurrentInstruction()
  ENDIF