Title image Fall 2019

Lab 4: Connecting components in VHDL

The purpose of this lab is to get you working with multiple VHDL files and connecting them without using a BDF file. You should not create any BDF design files this week.

In the lab, you will design a circuit that acts as a simple ALU (arithmetic login unit). In the project, you will design a more complicated state machine that creates a light show. It's behavior will be similar to a player piano that executes a series of operations in a fixed sequence. The main difference is that this circuit contains a memory that can be modified by the operations.


  1. Setup

    Start Quartus. Follow the new project wizard and create a new directory for lab 4. Call your project calc. This is the name of the project and the top level entity, but it will not be the only design file you create and use.

    Select File->New and create a new VHDL file. Use the following as a template for your file. The template defines the inputs and outputs, but has an empty architecture.

    -- simple template
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    entity calc is
        a      : in unsigned  (3 downto 0);
        b      : in unsigned  (3 downto 0);
        c      : in std_logic_vector (1 downto 0);
        result : out unsigned (4 downto 0)
    end entity;
    architecture rtl of calc is
    end rtl;

    Save the file as calc.vhd and add it to your project.

  2. Design a simple ALU

    The next task is to write a simple ALU VHDL design and then incorporate it into to the calc VHDL design. The process of incorporating VHDL design A into VHDL design B requires adding a component statement and a port map statement into design B. The component statement defines the interface to design A, and the port map specifies exactly what signals in design B are mapped to the inputs and outputs of design A. A component is analogous to a function prototype or function signature. A port map is analogous to a function call.

    1. Start a second VHDL design

      Create a second VHDL file called alu.vhd. Use exactly the same template as above, but change the entity name to alu in both the entity and architecture statements. Change the parameter names to d, e, f, and q. Save the file and add it to your project.

    2. Make a process with a case statement

      Make a process statement in the architecture body that is sensitive to signals d, e, and f. Then make a case statement on f which has the cases "00", "01", "10", and others. Have case "00" assign to q the sum of d and e. Have case "01" assign to q the difference of d and e. Have case "10" assign to q the bitwise AND of d and e. Have case "11" (others) assign to q the bitwise OR of d and e. Note that you'll need to pad the 4-bit numbers to convert them to 5-bit numbers. For example:

      q <= ('0' & a) + ('0' & b));
    3. Write the component statement

      Go back to the calc.vhd file. Use the following component declaration template. Put it in the declaration section of the architecture.

      component <entity>
          <port statement>
      end component;

      Copy the port statement from alu.vhd into the component statement. Replace <entity> with alu.

    4. Port map the alu and connect the inputs and outputs

      In the body of your architecture, make an instance of the alu component. To make an instance of another circuit--like adding a component to a BDF diagram--you use the port map statement. A port map statement needs a unique name, the name of the component, then port map and the argument list. The code below is how you would create one instance of the ALU.

        alu1: alu
          port map( d => a, e => b, f => c, q => result ); 

      In the argument list, the first symbol is the parameter name and the second symbol is the local variable you are connecting to it.

    5. Test your code

      Compile your files to check the syntax (Analyze File).

      Download the file calcbench.vhd, which is a test file for the calc circuit. Then open a new terminal, cd to your working directory, and execute the following commands in a terminal in order to simulate and test the circuit.

      ghdl -a calcbench.vhd calc.vhd alu.vhd
      ghdl -e calcbench
      ghdl -r calcbench --vcd=calcbench.vcd
      gtkwave calcbench.vcd &

      If you insert all of the signals into the view window, it should look like the following. Note that you can make the signals somewhat easier to read by right-clicking on a signal name and then selecting Data Format::Decimal. By default, bit vectors are displayed as either bits or hex digits.

      GTKwave output

When you have completed the lab assignment, go ahead and get started on the current project.