DLX Single Cycle Implementation



Introduction

This lab features a VHDL model for the DLX single cycle implementation discussed in class. You will be provided with an incomplete model for the DLX single cycle implementation; the lab assignment involves completing the model so that a target program is executed correctly. We will use the Mentor Quick VHDL environment to compile/execute/debug the model.

Set Up

Setting up the VHDL development directories

Copy the file '~reese/vhdl.tar.Z.sim1' to your local directory. Unpack this compressed tar file by doing:

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

This will create a directory tree that looks like:
   vhdl/
        /src -- all VHDL source files under
          /dlxsimple   -- VHDL files for single cycle implementation  
          /Makefiles   -- Makefiles to compile VHDL files
          /dw01        -- support library
          /utils       -- support library

       /obj  -- all VHDL compiled object code under this tree

You will be editing files in the 'vhdl/src/dlxsimple' directory; you will be invoking the VHDL simulator from the 'vhdl/src' directory.

Setting the UNIX environment

Modify your .cshrc file and add the lines

swsetup mgc
set path (~reese/bin $path)

Log off, then log back on and do:
which qhsim
which dlx2obj.branch
This should return pathnames to the 'qhsim' (VHDL simulation) and 'dlx2obj.branch' (utility script) programs.

DLX Single Cycle Implementation

The files in the 'vhdl/src/dlxsimple' directory implement the single cycle implementation. The most important files are:

Other files in this directory form lower levels of the heirarchy; you will not need to be concerned with these files. For this exercise, you will only need to modify the 'control.vhd' file. This file is incomplete; key assertion statements for control lines have been removed. You will need to complete this file and verify that it executes a target program correctly. The 'control.vhd' as provided only executes the R-type ADD/ADDU/SUB/SUBU instructions correctly. You will need to modify the file so that the BEQZ/BNEZ/ADDI/ADDUI/SUBI/SUBUI/LW/SW instructions can be executed.

Edit/Compile/Execute/Debug for VHDL


VHDL Compilation

If you have edited any files in the 'vhdl/src/dlxsimple' directory, you will need to compile them by doing:

  make -f Makefiles/Makefile.dlxsimple TOOLSET=qhdl

from the 'vhdl/src' directory. This Makefile will recompile any files that have been edited and will compile any files that depend on the changed files.

Input Program for the 'dlxsimple' Simulation

Before starting the VHDL simulator, we need to prepare an assembly language program that our dlx single cycle implementation will execute. The simulation has been set up such that the program in the file 'acid_test.s' will be the one loaded into the instruction memory modeled within the VHDL simulator. The VHDL memory model cannot read this assembly source file directly; instead, the source file must be 'assembled' into a psuedo object code file. This can be done via:

 dlx2obj.branch acid_test.s

This will produce a new file called 'acid_test.obj'. The 'acid_test.obj' file should already be present; if you modify 'acid_test.s' for some reason then you will need to rerun 'dlx2obj.branch'. It is important that the entry point of your assembly language program be labeled as '_main'. One of the actions which 'dlx2obj.branch' does is place a:
 beqz r0, _main
at location '0' in the instruction memory (it is placed at location '0' because the program counter value is set to '0' on simulator startup). This causes an unconditional jump to the location defined by the '_main' label in your assembly program. This also means that the FIRST dlx instruction that will be executed by the VHDL model is the 'beqz' instruction -- this is the first instruction that you have to get working correctly.

Running the VHDL Simulation

To start up the VHDL simulator, change to the 'vhdl/src' directory and do:


qhsim -lib ../obj/qhdl/dlxsimple cfg_acid_test

You should see the main 'qhsim' window pop up; it is labeled QuickHDL VHDL/Verilog.



You should see a bunch of 'loading' messages as VHDL object code modules are loaded. From within this window, type:
 view *
This will cause MANY windows to pop up; do not be intimidated by the number of windows. The windows and their functions are as follows: The most useful windows will be the 'source', 'variables', 'signals', and 'wave' windows; you can terminate the rest of the windows by clicking right on their top edge and selecting 'quit' from the pop-up menu.

We will need to display some signals in the 'wave' window. I have prepared a command file to add signals to this window; the file is called 'wave.do' and is in the 'vhdl/src' directory. To execute this command file, type:

 do wave.do
in the main simulation window. Click on the 'wave' window and see what signals got added. You should recognize many of the signals as being named very similarly to the signals described in the textbook for the dlx single cycle implementation. You will also note that current register values are also displayed in the 'wave' window. To run the simulation for a period of time, type:
 run 600 ns
The clock cycle length is set at 100 ns; this causes the simulation to run for 6 clock cycles. Examining the simulation window reveals what instruction is initially fetched, and how that instruction is executed:



Note that the `iaddrbus' (Instruction memory address bus) starts out at '00000000' (PC = 0x0), and that the first instruction fetched has the value '0x1000010C'. If you disassemble this instruction, you will find that this is a 'bnez r0, _main'. The label '_main' has an address of '0x00000110' so this is where the next instruction should be fetch from. However, the branch instruction does not get executed correctly because of the broken 'control.vhd'; the next 'iaddrbus' value is '0x00000004'. In fact, the PC just keeps getting incremented by 4.

If you fix 'control.vhd' so that the 'bnez' is executed correctly, then the correct simulation should look like:



Note that the second instruction is fetched from location '0x00000110'; the instruction is '0x20001008'. This corresponds to 'add r1,r0, #8' which is the instruction at the '_main' label in the 'acid_test.s' file.

Debugging the VHDL Simulation

All of the traces in the waveform window are important, the ones you will probably watch the most are:

  1. The register values, not that a register does not get its new value until the rising edge of the current clock cycle. The register file implementation in this simulation is actually level sensitive; the values are read during the low portion of the clock, the result written during the high portion of the clock. This is different from the textbook which used a falling edge triggered register file; the end result is the same.
  2. The 'opcode' trace which defines the opcode of the current instruction (look in the 'define.vhd' file for the opcode definitions).
  3. The 'aluopcode' trace which is the current ALU operation (see 'define.vhd').
  4. 'data_a', 'data_b' which are the current operands into the ALU; 'alu_result' which is the current output of the alu.
IMPORTANT!!!! You CANNOT debug the simulation UNLESS you know what the value of every control line and every data bus is SUPPOSED to be at each point during the simulation. What you should do is simulate for a clock cycle, and check the value of each waveform and see if it corresponds to what you expect it to be according to how you modified the 'control.vhd' file. At the point where the waveforms diverge from what you expect, track down the driving signal and try to understand why it should not be that value and what you can do to make it be the correct value.

If the simulation is running, and you change the 'control.vhd' file and recompile, then you can load in the changed object file by executing 'File->Load New Design' from the main simulation window (you do not have to exit the simulator). If you just want to restart the current simulation from time zero, use the 'File->Restart' menu choice.



You can also set a breakpoint and single step through your 'control.vhd' code by clicking in the 'structure' window on the 'control' component:



This will cause the control code to appear in the source window. Scroll down through the code and click on the source line where you want the breakpoint to occur. The next 'run' command will cause the breakpoint to be hit; the 'Step Over' button can be used to step through the code. The 'variables' and 'signals' windows will display the current variable/signal values. To remove the breakpoint, click on the source line with the breakpoint and it will be removed.

Exiting the VHDL Simulation

Type 'quit' in the main simulation window to exit the simulation.

To Turn In

The simulation is due on Tuesday, February 4th, at class time. You MUST demo your simulation to me and convince me that it is correct. Hand in a printout your final 'control.vhd' file.

The last word...

If your simulation runs correctly for 'acid_test.s', then the opcodes, alu opcodes, register values should sequence like: