Lab 2B) Event-Driven Simulation of the DLX ALU

In this exercise we'll be modifying the original DLX design to follow common guidelines and for successfull synthesis results. We'll use the  simulator to verify our work.

Prerequisites:

Important Concepts:

Outline

  1. Architecture Behavioral - Arithmetic ADD/SUB Operations
  2. Architecture Behavioral - Logic SHIFT Operations
  3. Architecture Behavioral - The Status Ports ZERO_RESULT/NEGATIVE/OVERFLOW

    Entity ALU

    Prepare a file called alu.vhdl in your ~/vhdl_class/vhdlsrc directory that describes an entity for the alu. 

    You may want to refer to the original alu design source

    There are changes required to this design which will be introduced in subsequent sections.

    Coding Discussion

    Organizing VHDL Files
    The first significant change consists of combining entity and architectures into a single file. While it's not - strictly speaking - necessary, it's commonly accepted practice. The VHDL LRM does not specify any particular arrangement however VHDL analyzers work on a file at a time so however you arrange your VHDL into files each file must be considered syntactically complete. Thoughout the following exercises we'll instruct you to combine entity and architecture(s) in a single file and name files according to this simple guideline:
  1. <entity_name>.vhdl

  2. Instructions:

     Continue working in the lab2 directory.


    Architecture Behavioral - Implimenting Arithmetic ADD/SUB Operations

    We'll now undertake the implimentation of more complicated arithmetic operations.

    Coding Discussion

    The ability to take an abstract HDL descruption containing a plus "+" operator and construct a hardware adder is a pretty recent phenomenen in the system design world. Every simulator can execute the code and calculate the results but synthesis tools differ on their exact policies.

    Description of IEEE_EXTD.std_1164_vector_arithmetic package

    The first point is that arithmetic operations are grouped into 2 classes with fundamentally different behavior: signed and unsigned. Both are based on a vectored base type of 0 to some maximum width. Bit 0 being the MSB and the last bit the LSB.
    Signed
    Operations treat the MSB as an indication the sign ( +/- ) of the number represented so the range available for arithmetic operations is 2**(word length -1).
    Unsigned
    Operations utilize the full width of the word for arithmetic operations and can not represent values < 0.
    The designer should always be aware of what is appropriate for the application and select the proper base types. Our DLX processor provides both classes of instructions so we'll consider both. After careful examination of the origonal DLX ALU we determine that it impliments 32 bit arithmetic operations with an additional overflow bit. We'll use these functions from the IEEE_EXTD.std1164_vector_arithmetic package:
    ----------------------------------------------------------------
      -- Signed addition with overflow detection
      ----------------------------------------------------------------
      procedure sv_add (sv1, sv2  : in  std_logic_vector;
                        sv_result : out std_logic_vector;
                        overflow  : out std_logic);

      ----------------------------------------------------------------
      -- Signed addition without overflow detection
      ----------------------------------------------------------------
      procedure sv_add (sv1, sv2  : in  std_logic_vector;
                        sv_result : out std_logic_vector);

      ----------------------------------------------------------------
      -- Unsigned addition with overflow detection
      ----------------------------------------------------------------
      procedure sv_addu (sv1, sv2  : in  std_logic_vector;
                         sv_result : out std_logic_vector;
                         overflow  : out std_logic);

    Instructions

    Now we're ready to add our instructions to the alu design. We want to modify the vhdlsrc/alu.vhdl file to add a dependency on Library ieee_extd.std1164_vector_arithmetic.all and expose the arithmetic support discussed earlier. Next, we'll tackle the simplest form - the unsigned add operation.

    Unsigned Addition/Subtraction - Next we'll assign these variables
    from their respective ports. Finally we'll add a leg to the case statement
    for alu_addu and assign the temp_result.

  signal stored_s1, stored_s2 : dlx_word;

 
  alu_op: process (stored_s1, stored_s2, func)
    variable tmp_res : dlx_word;
    variable tmp_ovl : std_logic;
  begin
    ...
sv_addu(stored_s1, stored_s2, tmp_res, tmp_ovl);

             Signed Addition/Subtraction -
     
                sv_add(stored_s1, stored_s2, tmp_res, tmp_ovl);
             
     

Logic SHIFT Operations

              sv_sll(stored_s1, tmp_res, stored_s2(27 to 31));



    Architecture Behavioral - Implimenting The Status Ports ZERO_RESULT/NEGATIVE/OVERFLOW

    The hardest part is over. These status bits are derived by comparing and testing the value of temp_result

      if tmp_res = X"0000_0000" then
          zero <= '1' after tpd_out;
        else
          zero <= '0' after tpd_out;
        end if;
        negative <= tmp_res(0) after tpd_out;
        overflow <= tmp_ovl after tpd_out;