Components are used to connect multiple VHDL design units (entity/architecture pairs) together to form a larger, hierarchical design. Using hierarchy can dramatically simplify your design description and can make it much easier to re-use portions of the design in other projects. Components are also useful when you want to make use of third-party design units, such as simulation models for standard parts, or synthesizable core models obtained from a company specializing in such models.

 

The following example describes the relationship between the three design units in the shift and compare example presented in the previous section:

 

architecture structure of shiftcomp is

 

    component compare

        port(A, B: in bit_vector(0 to 7); EQ: out bit);

    end component;

 

    component shift

        port(Clk, Rst, Load: in bit;

               Data: in bit_vector(0 to 7);

               Q: out bit_vector(0 to 7));

    end component;

 

    signal Q: bit_vector(0 to 7);

 

begin

 

    COMP1: compare port map (Q, Test, Limit);

    SHIFT1: shift port map (Clk, Rst, Load, Init, Q);

 

end structure;

 

In this example, the two lower-level components (shift and compare) were instantiated in the higher-level module (shiftcomp) to form a hierarchy of design units. Each component instantiation is represented by a component name that is unique within the architecture or block.

 

Component instantiations are concurrent statements and therefore have no order-dependency. A design unit (such as this one) that includes only component instantiation statements can be thought of as a netlist, such as might be written (or generated) to represent the connections on a schematic.

 

Mapping of Ports

The previous example of component instantiation used positional association to describe how signals at the higher level (in this case shiftcomp) are to be matched with (i.e., connected to) ports of the entities in the lower-level modules (shift and compare).

 

Positional association is a quick and convenient way to describe the mapping of signals to ports in a component instantiation, but it can be error-prone. Consider, for example, what would have happened if the component instantiation for the shift module had been written as follows:

 

SHIFT1: shift port map (Rst, Clk, Load, Init, Q);

 

Because the Rst and Clk signals are of the same type (std_logic), the simulator or synthesis tool would accept this port mapping without complaint, and it would connect the reset signal to the clock and connect the clock to the reset. The circuit would not operate as expected, and the problem might be difficult to debug.

 

For this reason, we generally recommend that you write component instantiations using an alternate form of port map called named association. Named association guarantees that the correct signals and ports are connected through the hierarchy, and it also gives you the ability to re-order the ports as needed.

 

The following example shows how the same component (a NAND gate) might be instanced using both positional and named association:

 

U1: nand2 port map (a, b, y);                              -- Positional association

U2: nand2 port map (a=>in1,b=>in2,y=>out1);    -- Named association

 

The special operator => indicates exactly which lower-level ports (a, b and y, in this case) are to be connected to which higher-level signals (in1, in2 and out1).

 

Named association also makes it possible to leave one or more lower-level ports unconnected using the keyword open, as shown below:

 

U2: count8 port map (C => Clk1, Rst => Clr, L => Load, D => Data,

                                  Q => , Cin => open);

 

Note: You might also consider placing each named association on a separate line. This simplifies debugging because the debugger will identify the exact line where an association error occurred.

 

Generics

It is possible to pass instance-specific information other than actual port connections to an entity using a feature called generics. Generics are very useful for making design units more general-purpose or for annotating information (such as timing specifications) to an entity at the time the design is analyzed for simulation or synthesis.

 

The following example shows how generics can be used to create a parameterizable model of a D-type flip-flop:

 

library ieee;

use ieee.std_logic_1164.all;

 

entity dffr is

    generic (wid: positive);

    port (Rst,Clk: in std_logic;

          signal D: in std_logic_vector(wid-1 downto 0);

          signal Q: out std_logic_vector(wid-1 downto 0));

end dffr;

 

architecture behavior of dffr is

begin

    process(Rst,Clk)

        variable Qreg: std_logic_vector(wid-1 downto 0);

    begin

        if Rst = '1' then

            Qreg := (others => '0');

        elsif Clk = '1' and Clk'event then

            for i in Qreg'range loop

                Qreg(i) := D(i);

            end loop;

        end if;

        Q <= Qreg;

    end process;

end behavior;

 

In this example, the dffr entity has a generic list in addition to a port list. This generic list contains one entry, a positive integer, that corresponds to the width of the D input and Q output. The architecture declaration uses a for loop in conjunction with the generic (wid) to describe the operation of the D-type flip-flops.

 

When instantiated in a higher-level design unit, a generic map must be provided in addition to the port map, as shown below:

 

architecture sample of reg is

 

    component dffr

        generic (wid: positive);

        port (Rst,Clk: in std_logic;

              signal D: in std_logic_vector(wid-1 downto 0);

              signal Q: out std_logic_vector(wid-1 downto 0));

    end component;

 

    constant WID8: positive := 8;

    constant WID16: positive := 16;

    constant WID32: positive := 32;

    signal D8,Q8: std_logic_vector(7 downto 0);

    signal D16,Q16: std_logic_vector(15 downto 0);

    signal D32,Q32: std_logic_vector(31 downto 0);

 

begin

 

    FF8:  dffr generic map(WID8)  port map(Rst,Clk,D8,Q8);

    FF16: dffr generic map(WID16) port map(Rst,Clk,D16,Q16);

    FF32: dffr generic map(WID32) port map(Rst,Clk,D32,Q32);

 

end sample;

 

The example shows how three instances of the dffr design unit can be created using different values for the generic.

 

See also

image\diamond.gif  Component Instantiations