When an instruction stalls in a pipeline, it is held at a particular stage until an earlier instruction completes an action that will eliminate the stall condition. Hazards that cause stalls come in three classes: structural, data, and control.
Structural hazards occur when the processor doesn't have enough resources to handle a particular combination of instructions. For example, on the M1, Cyrix has included write buffers between the execution units and the cache, and a separate instruction cache between prefetch and the cache, to minimize those instances when simultaneous cache accesses (reads, writes, prefetches, flushes, and fills) overwhelm the two I/O ports the cache possesses. In dealing with structural hazards, a designer must decide whether the frequency of a particular instruction combination merits the extra transistors that would be r
equired to handle the hazard condition.
Control hazards can occur when a branch instruction executes. If the branch goes to an address that isn't in the on-chip caches, the execution pipelines will stall for as long as it takes for the proper follow-on instructions to be retrieved from off-chip. The most difficult branches to deal with are conditional ones, where the branch is taken based on the condition of a flag or the value of a memory location or register, which usually isn't calculated until just before the conditional branch instruction executes.
In a data hazard, one instruction is dependent on a preceding instruction. For example, if the first instruction writes its results to register BX, the second instruction can't read from BX until the first finishes the Writeback stage. Because registers are read in Address Calculation 2, this introduces a bubble where the Execute stage is empty for a cycle. This is an example of a RAW (read-after-write) dependency; if the second instruction were
to read BX before the first wrote to it, the second instruction would be using an incorrect value, destroying the integrity of the program logic.
Other data hazards are a WAR (write-after-read) and a WAW (write-after-write). A WAR occurs when a follow-on instruction tries to write to a register before a preceding one reads it. A WAW occurs when a follow-on instruction writes to a register before a preceding one.