The mapping of ports in a component can be described in one of two ways. The simplest method (and the method used in the preceding example) is called positional association. Positional association simply maps signals in the architecture (the actuals) to corresponding ports in the lower-level entity declaration (the formals) by their position in the port list. When using positional association, you must provide exactly the same number and types of ports as are declared for the lower-level entity.

 

Positional association is quick and easy to use, and it is tempting to use this method almost exclusively. However, there are potential problems with positional association. The most troublesome problem is the lack of error checking. It is quite easy, for example, to inadvertently reverse the order of two ports in the list. The result is a circuit that may compile with no errors, but fail to simulate properly. After the first few times you accidentally swap the reset and clock lines to one of your lower-level components, you may decide that it is worth the extra typing to provide a more complete specification of your port mappings. The method you will use in this case is called named association.

 

Named association is an alternate form of port mapping that includes both the actual and formal port names in the port map of a component instantiation. (Named association can also be used in other places, such as in the parameter lists for generics and subprograms.)

 

We could modify the previous 4-bit adder example to use named association as follows:

 

architecture structure of adder4 is

        component half_adder

             port (A, B: in std_logic; Sum, Carry: out std_logic);

        end component;

        component full_adder

             port (A, B, Cin: in std_logic; Sum, Carry: out std_logic);

        end component;

        signal C: std_logic_vector(0 to 2);

begin

 

        A0: half_adder port map(A => A(0), B => B(0), Sum => S(0), Carry => C(0));

        A1: full_adder port map(A => A(1), B => B(1), Cin => C(0), Sum => S(1), Carry => C(1));

        A2: full_adder port map(A => A(2), B => B(2), Cin => C(1), Sum => S(2), Carry => C(2));

        A3: full_adder port map(A => A(3), B => B(3), Cin => C(2), Sum => S(3), Carry => Cout);

 

end structure;

 

When you specify port mappings using named association, lower-level names (the formal ports of the component) are written on the left side of the => operator, while the top-level names (the actuals) are written on the right.

 

The benefits of named association go beyond simple error checking. Because named association removes the requirement for any particular order of the ports, you can enter them in whatever order you want. You can even leave one or more ports unconnected if you have provided default values in the lower-level component specification.

 

Because named association is so much more flexible (and less error prone) than positional association, we strongly recommend that you get in the habit of typing in the few extra characters required to use named association.

 

Generic Mapping

If the lower-level entity being referenced includes generics (described in more detail in Chapter 8, Partitioning Your Design), you can specify a generic map in addition to the port map to pass actual generic parameters to the lower-level entity:

 

architecture timing of adder4 is

        component half_adder

             port (A, B: in std_logic; Sum, Carry: out std_logic);

        end component;

        component full_adder

             port (A, B, Cin: in std_logic; Sum, Carry: out std_logic);

        end component;

        signal C: std_logic_vector(0 to 2);

    begin

 

        A0: half_adder

                generic map(tRise => 1 ns, tFall => 1 ns);

                port map(A => A(0), B => B(0), Sum => S(0), Carry => C(0));          A1: full_adder

                generic map(tRise => 1 ns, tFall => 1 ns);

                port map(A => A(1), B => B(1), Cin => C(0), Sum => S(1), Carry => C(1));

        A2: full_adder

                generic map(tRise => 1 ns, tFall => 1 ns);

                port map(A => A(2), B => B(2), Cin => C(1), Sum => S(2), Carry => C(2));

        A3: full_adder

                generic map(tRise => 1 ns, tFall => 1 ns);

                port map(A => A(3), B => B(3), Cin => C(2), Sum => S(3), Carry => Cout);

 

    end timing;

 

Just as with port maps, generic maps can be written using either positional or named association.

 

Note: The rules of VHDL allow you to mix positional and named association in the same port, generic or parameter list.  Doing so has little or no benefit, however, and it may confuse other potential users of your design description.