assemblymipspipelining

Data hazard in MIPS when performing ADD and SW with the same registers?


MIPs Datapath Im referring to Lets say we have MIPs Assembly program here with 5 stage pipelining IF/ID/EXE/MEM/WB without forwarding, and assume all instructions go through every stage even though it may produce no meaningful results:

...
add $t0, $s1, $s0
sw  $t0, 0($s2)
...

Is there a RAW data hazard? My current thought process is that since:
$t0 <- $s1 + $s0
mem[0 + $s2] <- $t0

Then it is a Read After Write because we first write to $t0 (at add) then we read $t0 to put it into memory. Furthermore, when SW is at ID, ADD is performing addition at the ALU/EXE stage. So the ID phase of SW regurgitates the value of $t0 before ADD can write-back the result.

I know there is a similar question: Is there an execute-store data hazard in MIPS?
but my case is very specific, and that didn't help me much because he assumed the instructions can execute without using some stages.


Solution

  • Yes of course there's a RAW hazard. One instruction reads the result of the previous instruction, separated by a lot less than the pipeline length. Wikipedia: https://en.wikipedia.org/wiki/Classic_RISC_pipeline#Data_hazards

    Data hazards occur when an instruction, scheduled blindly, would attempt to use data before the data is available in the register file.

    A classic commercial MIPS like R2000 has bypass forwarding and wouldn't have to stall, because its forwarding logic detects the hazard (which still exists) and forwards the EX result from add to the register-read muxer for sw. So going forward to the rest of the pipeline, that instruction has the forwarded value of $t0 and the register-file value of $s2. https://en.wikipedia.org/wiki/Classic_RISC_pipeline#Solution_A._Bypassing

    Without bypass forwarding, yes you'd have to actually stall. Assuming SW still reads both its input operands from the register file at the normal time, in the ID stage. IDK if it's plausible that you could let stores read their data register late (at the start of the MEM statge) to reduce the number of stall cycles by 1, but that might require an extra read port in the register file because the ID stage might also be reading 2 instructions.

    Your pipeline still needs to detect the hazard and be able to stall for it (https://en.wikipedia.org/wiki/Classic_RISC_pipeline#Solution_B._Pipeline_interlock). Having effective latency of simple ALU instructions worse than 1 cycle is pretty terrible, which is why all real-world RISC pipelines do forwarding instead of just detecting and stalling. Compilers have a hard enough time scheduling code to fill load-delay and branch-delay slots without having to hide latency for every simple ALU instruction!