Pipelining

The basic idea behind pipelining is that we can have a different instruction use a different part of the data path at every point in time. The figure above shows how three instructions could be overlapped in a pipelined implementation. A pipelined datapath would require that each stage remember the instruction it is supposed to be executing since the previous stage can not provide that information; it is busy working on the subsequent instruction. The pipelined datapath is essentialy the same to the single-cycle CPU datapath but had buffers between every stage that record the information necessary to drive the subsequent stage of the pipeline. The contents of these buffers get forwarded across the pipeline stages with each clock tick.

Data Hazards

In an ideal world using a pipeline should allow a program to run as many times faster as is the depth of the pipeline. However it is possible for an instruction to try and use a register that is being modified by a previous instruction. If the previous instruction has not yet completed then the current instruction may read stale register values. The easiest solution to data hazards is to stall instructions that have dependencies on previous instruction until these dependencies have been resolved (i.e. the previous instruction have completed execution). Alternatively one can try and bypass some of the pipeline stages and feed results from executing instruction directly into the ALU where dependent instructions can use them. This is called data forwarding.

Control Hazards

Another problem with pipelines happens with branch instructions. Since when we decode the instruction we do not know whether the branch will be taken or not we do not know where to fetch the next instruction from. One solution is to stop fetching instruction until the branch has been resolved and we know the new PC address. An alternative is to guess which way the branch will go and start fetching from that address. If the guess is wrong we then need to kill these instruction and start fetching from the correct address.

Exceptions and Pipelines

Exceptions are detected the same way they were detected for the single-cycle CPU implementation. However when an exception is detected we need to make sure that no instruction that follows the offending instruction is executed. This is accomplished using the same mechanism used for dealing with Control Hazards; killing the instructions in the pipeline that follow the offending instruction and starting to fetch from the address where the exception handler resides.