Here is a problem (C.1.c) from the famous Hennessey & Patterson book I'm struggling with. The following code fragment should be scheduled on a five-stage MIPS CPU with "full forwarding and bypassinging hardware" and branches handled by stalling:
Loop: ld x1,0(x2)
addi x1,x1,1
sd x1,0(x2)
addi x2,x2,4
sub x4,x3,x2
bnez x4,Loop
The solution provided is:
Clearly, the pipeline has to stall until x1
is read into memory. But
what is the reason for bnez
stalling? Why can't it proceed to decode
(D) immediately?
I got an answer that was then deleted that I think was on the right track. The book actually discusses this issue in detail on pages C-39 to C-42:
In MIPS, the branches (BEQ and BNE) require testing a register for equality to another register, which may be R0. If we consider only the cases of BEQZ and BNEZ, which require a zero test, it is possible to complete this decision by the end of the ID cycle by moving the zero test into that cycle. To take advantage of an early decision on whether the branch is taken, both PCs (taken and untaken) must be computed early. [...] Figure C.28 shows the revised pipelined data path. With the separate adder and a branch decision made during ID, there is only a 1-clock-cycle stall on branches. Although this reduces the branch delay to 1 cycle, it means that an ALU instruction followed by a branch on the result of the instruction will incur a data hazard stall.
However, it is not clear how this stall signal is computed nor whether this setup is the one intended in the problem. Since the branch is already predicted as not taken stalling seem counterproductive.