I'm having a bit of difficulty understanding pipeline hazards, especially data hazards and how we can use stall cycles and data forwarding to resolve these hazards. Here's an example of a MIPS assembly code with data and load-use hazards (pointed out):
B0: sll $t2, $a0, 2
B1: add $t1, $a0, $a1
B2: lw $t0, 4($t1) #data hazard $t1
B3: slt $v0, $t1, $a1 #data hazard $t1
B4: sub $v1, $v0, $t3 #data hazard $v0
B5: addi $t0, $t0, 4
B6: lw $t1,8($t0) #data hazard $t0
B7: sll $t1, $a1, 1
B8: add $t2, $t1, $v0 #data hazard $t1
B9: lw $v0, 0($t2) #data hazard $t2
B10: lw $t3, 0($v0) #load-use hazard $v0
B11: and $v0, $t3, $a2 #data hazard $t3
B12: sll $a1, $t3, 1 #data hazard $t3
For this code we got a pipeline "diagram", where we have to fill in the stall cycles and data forwards. Since the diagram has 20
cycles I will only show the first 5
cycles and the data forwards in those 5
cycles.
Pipeline Cycle - First 5 cycles with data forwarding.
In the diagram you can see that from BO
we forward from EX
to EX
in B1
, but why? Since we don't need any of the two registers from B0
in either B1
or B2
, there is no data hazard regarding $t2
or $a0
, thus no need for a data forward.
Additionally, how do I know if I have to forward from EX
or MEM
, because at times I'm not sure if I have to go from EX
to EX
, EX
to MEM
, MEM
to EX
or MEM
to EX
. I would like some clarification on this.