CS 232: Lab 4

Title image Fall 2026

Lab 4: Connecting components in VHDL

The purpose of this lab is to increase your comfort level with VHDL. We will connecting components using VHDL code only. Even if you are using Quartus, 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 logic unit). In the project, you will design a 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.

The lab will use 3 VHDL files, as illustrated below

Lab 4 Design


Tasks

  1. Setup
    • Make the project: In Quartus, follow the new project wizard and create a new directory called calc. 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. Calc.vhd will be the top-level file from the perspective of Quartus. When we simulate, calcbench.vhd is the top-level file.

      + (more detail)

      Why is calc.vhd the top-level file in Quartus? This appears contrary to the diagram, which clearly shows that calcbench.vhd is the top-level file. The answer is easiest to explain in terms of the previous lab. The top-level file from the perspective of Quartus was bright.vhd. When we ran it on the board, we used just bright.vhd, assigning pins based on the ports in bright.vhd. On the other hand, when we used ghdl to simulate the circuit, we had to add another file - brighttest.vhd. brighttest simulated the changes in inputs (because we didn't have key buttons without a board). Now, back to this project. calcbench is analagous to brighttest. and calc is analogous to bright. But calc is more sophisticated, because it has alu as a component.
    • Make calc.vhd. 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
        port 
        (
          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
        -- definitions go here
      
      begin
        -- assignments and processes go here
      
      end rtl;

      Save the file as calc.vhd (and , if you are using Quartus, 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. This means we will make and entity named alu in alu.vhd and we will include a component declaration for the ALU in calc.vhd.

    + (more detail)

    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 via simulation with ghdl

      We will use ghdl to run the simulation. But you can check your syntax in Quartus, if you are using it - just select 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. Also, note that in the upper left corner, the entity hierarchy is shown in a tree. We can select signals from any of the components. Here, I show all signals, and we see that bench_b in calcbench, b in calc, and e in alu are the same. This makes sense because they are connected directly to each other.

      GTKwave output

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