DLX Pipelined Implementation: Due March 25 at Class Time



Introduction

The goal of this simulation is to expose the student to the issues of data hazards in the pipelined implementation discussed in the textbook. This lab will be worth 200 pts.

Set Up

Copy the file '~reese/vhdl.tar.Z.pipe' from my ECE acccount to your local directory. Unpack this compressed tar file by doing:


   % cat vhdl.tar.Z.pipe | zcat | tar xf -

This will create the directory development tree like the one you used for previous VHDL simulation assignments( You will need to delete the directory tree used previously). For PC users, the file you need is called 'pipe.zip'.

Inside of the 'vhdl/src/' directory, you will see three assembly source files:


 pipe_test.s
 hazard_nostall.s
 hazardnop_nostall.s

The 'hazard_nostall.s' is a file that has instruction sequences which test the data hazards discussed in class. The 'hazardnop_nostall.s' is the same instruction sequnce as 'hazard_nostall.s' with NOPS placed between the instructions to avoid data hazards. In the 'hazardnop_nostall.s' there are NOPs placed after each 'load' instruction to avoid load stalls; we will not implement the logic for load stalls.

The VHDL code which you have been given will successfully excute the 'hazardnop_nostall.s' code. To test this, do:

 cp hazardnop_nostall.obj pipe_test.obj
 qhsim -lib ../obj/qhdl/dlxpipe cfg_pipe_test
The 'cfg_pipe_test' VHDL code uses the 'pipe_test.obj' file; you must copy any '.obj' file you wish to test to the 'pipe_test.obj' file. The register values at the end of the simulation will match those found in the 'hazardnop_nostall.s' file.

What You Have To Do

Your job will be to add the forwarding logic discussed in the textbook so that the VHDL model will successfully execute the 'hazard_nostall.s' code.

Model Structure

I have tried to structure the model to match the implementation found in Figures 6.13, 6.24. The pipeline registers between stages are implemented by the 'decode.vhd' (IF/ID), 'exe.vhd' (ID/EXE), 'mem.vhd'(EX/MEM), and 'wb.vhd' (MEM/WB). models. The 'control' block shown in Figure '6.24' is implemented in 'control.vhd'. The 'dlx.vhd' model ties everything together.

Control Signals

In the models, I have tried to follow a consistent naming scheme for control signals to reduce confusion. For example, the 'MemToReg' signal is generated by the 'control.vhd' model and needs to be passed all of the way to the writeback stage. In the pipeline register models 'exe', 'mem', and 'wb', I have defined ports called 'MemToReg_in' and 'MemToReg_out' for the input/output signals respectively. In 'dlx.vhd' I declared the signals:

  MemToReg_dec   - MemToReg signal generated by the 'control' block in
                   the decode stage (drives 'MemtoReg_in' of 
	           the 'exe' model).
  MemToReg_exe   - MemToReg signal in execute stage
 	           (driven by 'MemtoReg_out' of the 'exe' model)
 	           (drives 'MemtoReg_in' of the 'mem' model)
  MemToReg_mem   - MemToReg signal in mem stage
 	           (driven by 'MemtoReg_out' of the 'mem' model)
 	           (drives 'MemtoReg_in' of the 'wb' model)
  MemToReg_wb    - MemToReg signal in writeback stage
 	           (driven by 'MemtoReg_out' of the 'wb' model)

To do this lab, you will have to add one or more extra control signals which will have to be passed down the various pipeline stages. You should try to follow a similar naming scheme for your control signals and add them to the models in the same way as the other control signals are added.

dlxcomps.vhd

To reduce the size of the 'dlx.vhd' file, I have put all component declarations in a file called 'dlxcomps.vhd'. If you add a port to a model, you will have edit a minimum of three files:

  1. Add the port to the original entity declaration (i.e., adding a port to 'control.vhd' requires you to edit 'control.vhd'.)
  2. Add the port to the component declaration in 'dlxcomps.vhd' (i.e., modify the component declaration for 'control' in 'dlxcomps.vhd').
  3. Add the port to the component instantiation in 'dlx.vhd' (i.e., add the new port for 'control' to the 'ct0' instance in 'dlx.vhd' and connect it to some internal signal).

dlx.vhd

I have tried to arrange the code in 'dlx.vhd' so that everything associated with one pipeline stage is grouped together and delimited by comments. Try to follow the same style when you are adding new code.

forward.vhd

I have added a model called 'forward.vhd' where you can add your forwarding logic (see figure 6.44). I have put some ports on 'forward.vhd' as hints but this list is incomplete; feel free to add/delete ports as necessary. If you add input ports, BE SURE to add the signal to the sensitivity list of the process in 'forward.vhd'.

Tips

The following signals in 'dlx.vhd' are very important to the forwarding logic and forwarding in general:


Control signals :::

ReadReg1_exe, ReadReg2_exe:  register numbers of the two operands for
'R' type instructions in the execute stage. 

WriteReg_mem:  destination register number of result in MEM stage
WriteReg_wb:  destination register number of result in WB stage

ALUSrc_exe: if '1', then operand #2 is an immediate

Data values :::

ReadData1_exe:  data read from register file for operand#1 of the ALU
ReadData2_exe:  data read from register file for operand#2 of the ALU
immediate_exe:  Immediate data for operand#2 of the ALU if immediate
type instruction.

result_mem: data value to be forwarded from MEM stage.
RegWriteData : data value to be forwarded from WB stage

There are two distinct forwarding cases to be solved:
  1. Forwarding of results from the MEM and WB stage to the ALU operands. Involves adding a mux to each ALU side to choose ALU operands. This is the easiest to solve; the first few instructions in the 'hazard_nostall.s' check these cases.
  2. Forwarding of results from the MEM and WB stage for the 'store' instruction. The value to be stored to memory is passed from the EXE stage to the MEM stage via the 'smdr_in' port on the 'mem' model. Currently, the 'smdr_in' port on the 'mem' model is driven by 'ReadData2_exe'; you will have to add a mux to choose the correct value for the 'smdr_in' port.
Some things you need to think about when writing the forwarding code:
  1. If the 2nd ALU operand is an immediate, there is no need for forwarding.
  2. If the result in the MEM or WB has a register destination equal to '0', there is no need for forwarding.
  3. The ALU result of a load or store instruction is the address of the memory operand; there is never a need to forward this anywhere.
  4. Forwarding of results from the MEM stage takes precedence over the WB stage.
  5. LOAD Stall logic is not implemented so there will always be a NOP after a load instruction.

Also read Section 6.6 of the book for hints on the forwarding logic. To solve some of these problems you may have to add extra signals generated by the control logic and passed to subsequent pipeline stages.

To Turn In

You must turn in a short, typed report that discusses the changes you made to implement the forwarding logic. It is not necessary to turn in hardcopy of your code. You must also perform the following submission procedure for your code:

  1. Create a directory called 'sim5'.
  2. Copy ONLY the vhdl files which you have modified to this directory.
  3. Put a README file in the 'sim5' directory which tells me the status of your simulation (working or not working, if not working, then describe what is broken).
  4. Execute the script '~reese/bin/submit_sim5.sh' from the directory ABOVE the 'sim5' directory (from the current directory, you should be able to see 'sim5' as a subdirectory). This will pack up the contents of the 'sim5' directory and email them to me.
It will NOT be necessary to demo your code to me; I will check it. If I have problems with your code I will contact you.