我正准备进行测试,并有这样的例子。以下代码:
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中执行并被停止 在处理器理解之后,该分支未被采用,导致我们错误的结果。我的问题是
答案 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相对有效目标地址。
如果GPRrs
和GPRrt
的内容相等,则在执行延迟时隙中的指令后跳转到目标地址。如果未采用分支,则不执行延迟槽中的指令。操作:
我:
tgt_offset←sign_extend(offset || 0 2 )
条件←(GPR [rs] = GPR [rt])
I + 1:
如果条件那么 PC←PC + tgt_offset
否则
NullifyCurrentInstruction()
ENDIF