A hazard is created whenever there is a dependence between instructions, and they are close enough that the overlap caused by pipelining would change the order of access to an operand. Our example hazards have all been with register operands, but it is also possible to create a dependence by writing and reading the same memory location. In DLX pipeline, however, memory references are always kept in order, preventing this type of hazard from arising.
All the data hazards discussed here involve registers within the CPU. By convention, the hazards are named by the ordering in the program that must be preserved by the pipeline.
RAW (read after write)
WAW (write after write)
WAR (write after read)
Consider two instructions i and j, with i occurring before j. The possible data hazards are:
RAW (read after write) - j tries to read a source before i writes it, so j incorrectly gets the old value.
This is the most common type of hazard and the kind that we use forwarding to overcome.
WAW (write after write) - j tries to write an operand before it is written by i. The writes end up being performed in the wrong order, leaving the value written by i rather than the value written by j in the destination.
This hazard is present only in pipelines that write in more than one pipe stage or allow an instruction to proceed even when a previous instruction is stalled. The DLX integer pipeline writes a register only in WB and avoids this class of hazards.
WAW hazards would be possible if we made the following two changes to the DLX pipeline:move write back for an ALU operation into the MEM stage, since the data value is available by then.Here is a sequence of two instructions showing the execution in this revised pipeline, highlighting the pipe stage that writes the result:
suppose that the data memory access took two pipe stages.
LW R1, 0(R2) IF ID EX MEM1 MEM2 WB ADD R1, R2, R3 IF ID EX WB
Unless this hazard is avoided, execution of this sequence on this revised pipeline will leave the result of the first write (the LW) in R1, rather than the result of the ADD.
Allowing writes in different pipe stages introduces other problems, since two instructions can try to write during the same clock cycle. The DLX FP pipeline , which has both writes in different stages and different pipeline lengths, will deal with both write conflicts and WAW hazards in detail.
WAR (write after read) - j tries to write a destination before it is read by i , so i incorrectly gets the new value.
This can not happen in our example pipeline because all reads are early (in ID) and all writes are late (in WB). This hazard occurs when there are some instructions that write results early in the instruction pipeline, and other instructions that read a source late in the pipeline.
Because of the natural structure of a pipeline, which typically reads values before it writes results, such hazards are rare. Pipelines for complex instruction sets that support autoincrement addressing and require operands to be read late in the pipeline could create a WAR hazards.
If we modified the DLX pipeline as in the above example and also read some operands late, such as the source value for a store instruction, a WAR hazard could occur. Here is the pipeline timing for such a potential hazard, highlighting the stage where the conflict occurs:
SW R1, 0(R2) IF ID EX MEM1 MEM2 WB ADD R2, R3, R4 IF ID EX WB
If the SW reads R2 during the second half of its MEM2 stage and the Add writes R2 during the first half of its WB stage, the SW will incorrectly read and store the value produced by the ADD.
RAR (read after read) - this case is not a hazard :).