Lecture: 3
Code
  • genericAdder.vhd
  • genericMux2x1.vhd
  • genericComparator.vhd
  • Class ObjectivesCombinational Basic Building Blocks, Component instantiation, Generics

    Basic Building Blocks

    While digital design has AND/OR/NOT gates at its foundation, in practice, we rarely use individual gates to design practical systems. Rather you will use pre-configured units of gates as the building blocks for your designs. Hence, we will call these pre-configured units, basic building blocks. All our basic building blocks will have the general structured shown below.


    The relationship between the signals in a basic building block is given as follows: A basic building block transforms the data input into data output. The transformation performed is specified by the control input. The status output indicates if any exceptional events occurred during this transformation. You can find a list of the most common building blocks in Table 8.1 on page 181 of my textbook linked on the front page. The password for this pdf is spr20Digital. If you are foggy how these building blocks work, it's reviewing the combinational building blocks in chapter 4.

    In order to better understand how we might use these building blocks, it's worthwhile to look closely at one of the building blocks the generic 2:1 multiplexer.

    Generic 2:1 Multiplexer

    A multiplexer is a data routing device which sends one of the two inputs to the output depending on the value of the 1-bit select signal. The following table provides the specific names and widths of the signal used in our multiplexer.
    Data input 2 N-bit vectors y1 and y0
    Data output N-bit vector f
    Control input 1-bit select
    Status output None
    Behavior f = y1 when select = 1, else f = y0
    If you haven't already noticed, we are not providing a specific width the data input and output vectors. Rather, we will allow the person who uses the multiplexer, you, to specify the width of the data input and output when they use the mux. This is why we call this a "generic" mux. Let's see how this name comes about.

    Look closely at the VHDL definition of the entity and architecture of the generic 2:1 multiplexer.
    entity genericMux2x1 is
        generic(N: integer := 4);
        port(y1,y0:	 in std_logic_vector(N-1 downto 0);
    	 select: in std_logic;
    	 f:      out std_logic_vector(N-1 downto 0) );
    end genericMux2x1;
    
    architecture behavior of genericMux2x1 is
    begin
        f <= y1 when s='1' else y0;
    end behavior;
    
    
    The entity contains the declaration generic(N: integer := 4). Let's unpack this statement. Note that the data inputs and outputs are defined as std_logic_vector(N-1 downto 0), the "N" in "N-1" is the value you will provide when you use the multiplexer. Since we are indexing the bits from 0, then the index of the Nth bit is N-1. The rest of the generic 2:1 multiplexer definition is pretty unremarkable.

    Let's turn to the elephant in the room, how do you "use" the genericMux2x1? Great question!

    Component Instantiation

    I've been gritting my teeth while I wrote the previous paragraphs because every time that I used the expression "use a multiplexer" what I really wanted to say was "instantiate a multiplexer". I refrained because I wanted to fully cover the concept of generics before diving into instantation.

    When you instantiate a component in VHDL, you create a physical copy of the component that is placed on the FPGA that operates concurrent with all the other hardware in your design. You can make multiple instances of the same component, each is a unique, individual, and separate from the other instances.

    The ability to instantiate components leads naturally to the idea of hierarchical design - the ability to include a component inside components inside components, etc... This ability to nest components allows us to hide unnecessary details inside a component and only show the "high level" behavior externally. In other words, hierarchical design allows you to abstract away the details of a design.

    So let's try instantiating some components.

    Min/Max Circuit

    Let's flex our ability to describe digital designs using the basic building blocks template.
    Data input 2 N-bit vectors x and y
    Data output 2 N-bit vectors min and max
    Control input None
    Status output None
    Behavior min equals the smaller of x and y.
    max equals the larger of x and y
    I've chosen to implement this circuit using the arrangement of building blocks shown below. Note the G output from the comparator goes to the s input of the left and right mux. This is the reason for the gray line through the left mux - the signal is going "under" the left mux.


    The role of the comparator in this design is to assert a logic 1 on its greater than output, G, when the x input is greater than y. When G equals 1, the left 2:1 mux will output x onto the max output and the right 2:1 mux will output y on the min output. I hope that this is a straight forward analysis.

    Let's look at the VHDL code for the minMax circuit that will instantiate a comparator and two multiplexers.
    ----------------------------------------------------------------------------------
    -- Comments start with two dashes
    -- You should always have the following
    --		lines in all of your code
    ----------------------------------------------------------------------------------
    -- Name:	Prof Chris Coulston
    -- Date:	Fall 2022
    -- Course: 	EENG 498 
    -- File: 	mod10Counter
    -- Purp:	Classic mod 10 counter from EENg 294 Lab #8
    --
    -- Doc:	
    -- 		
    -- 	
    -- Academic Integrity Statement: I certify that, while others may have 
    -- assisted me in brain storming, debugging and validating this program, 
    -- the program itself is my own work. I understand that submitting code 
    -- which is the work of other individuals is a violation of the honor   
    -- code.  I also understand that if I knowingly give my original work to 
    -- another individual is also a violation of the honor code. 
    ----------------------------------------------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use work.basicBuildingBlocks_package.ALL;
    
    entity minMax is
        port ( x, y : in STD_LOGIC_VECTOR(7 downto 0);    
               min, max : out STD_LOGIC_VECTOR (7 downto 0));
    end minMax;
    
    architecture structure of minMax is
    
        signal xGreaterY : STD_LOGIC;
    
    begin
    
        comp_inst : genericCompare
            GENERIC MAP(8)
            PORT MAP(x => x, y => y, g => xGreaterY, l => open, e => open);
    
        max_mux: genericMux2x1
            GENERIC MAP(8)
            PORT MAP(y1 => x, y0 => y, s => xGreaterY, f => max);
    
    
        min_mux: genericMux2x1
            GENERIC MAP(8)
            PORT MAP(y1 => y, y0 => x, s => xGreaterY, f => min);
            
    end structure;
    
    Let's look at close look at the first multiplex instantation, the one that starts with max_mux. There are a couple of other important points that you may have overlooked:

    Verification

    How should we go about showing that the VHDL code given above actually performs the correct min and max operations? Well, we will need a testbench, a topic that we will dive into during our next lecture. In preparation for that lecture, I created a testbench for he minMax circuit and generated the following timing diagram. Look it over and see if our design correctly performs the min max function.