Skip to content

VHDL · Chapter 4.7 · Concurrent Statements

Port Maps — Named and Positional

Instantiation places a sub-block, and the port map wires it. A port map connects each of the instance's ports, called the formals, to a signal or port in the parent, called the actuals. There are two ways to write the connection. Named association states each link explicitly and does not depend on order, while positional association matches by declaration order alone. Named is the professional default because it is self-documenting and immune to reordering, whereas positional is terse but dangerously fragile. This lesson covers both styles, how to leave an unused output open, and why a positional mismatch with the right types but the wrong order is among the hardest structural bugs to spot, since everything compiles cleanly yet the wires go to the wrong places.

Foundation13 min readVHDLPort MapNamed AssociationPositionalStructuralConnectivity

1. Engineering intuition — soldering the pins

If instantiation is placing a chip, the port map is soldering its pins to the board's nets. Each pin (port/formal) must reach the right net (signal/actual). You can solder by name — "connect pin clk to net sys_clk" — or by position — "connect the pins in the order they are listed." Naming each connection is slower to type but impossible to get subtly wrong; soldering by position is fast but a single reordering silently miswires everything.

2. Formal explanation — named vs positional association

named_vs_positional.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- entity adder has ports, in this order: a, b, cin, sum, cout
 
-- NAMED association: 'formal => actual', any order, explicit:
u1 : entity work.adder
  port map ( a => x, b => y, cin => '0', sum => s, cout => carry );
 
-- POSITIONAL association: actuals in the EXACT order of the entity's ports:
u2 : entity work.adder
  port map ( x, y, '0', s, carry );          -- a<=x, b<=y, cin<='0', sum=>s, cout=>carry

In named association each formal port is paired with its actual explicitly (formal => actual), so the order is irrelevant and the intent is on the page. In positional association the actuals are matched to formals strictly by the entity's port declaration order — get the order wrong and the tool happily connects the wrong nets if the types line up. In both cases each connection's direction, type, and width must match the port.

3. Production-quality RTL — named maps and open

named_port_map_with_open.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library ieee; use ieee.std_logic_1164.all;
-- Named association is self-documenting and reorder-proof:
u_fifo : entity work.fifo
  port map ( clk    => sys_clk,
             rst    => sys_rst,
             wr_en  => push,
             din    => wdata,
             rd_en  => pop,
             dout   => rdata,
             full   => fifo_full,
             empty  => open );          -- output we don't use → 'open'

What hardware does this become? A FIFO instance with each pin wired to the named net; the unused empty output is left unconnected (open). Naming every connection means this map is readable as a wiring list and survives any future reordering of the entity's ports. Only outputs may be left open; an input generally needs a driver (or a default), or it floats to 'U'.

4. Hardware interpretation — formals, actuals, and the binding

port map binding formals to actuals, named versus positionalbinds by namebinds by positionactuals (parent)sys_clk, wdata, …named: formal =>actualexplicit, order-independentpositional: by ordermatches entity port order —fragileformals (instanceports)clk, din, …12
A port map binds each formal (the instance's port) to an actual (a parent signal or port). Named association states each binding explicitly (clk => sys_clk), so position is irrelevant and the wiring is self-documenting. Positional association binds purely by the entity's declared port order, so a reordering silently rewires the instance. Direction, type, and width must match on each binding. The binding is the physical connection between the sub-block's pin and the board's net.

5. Structural interpretation — no new timing, just connectivity

A port map introduces no behaviour of its own; it is pure connectivity resolved at elaboration (lesson 4.6), when each formal is tied to its actual net. Because nothing here is about timing — the instance's behaviour over time is whatever the sub-block does — a structural binding diagram (above) is the right visualization, not a waveform. The only run-time consequence is that the instance now sees the parent's signals on its inputs and drives the parent's signals from its outputs.

elaboration pairing each formal with its actual and checking direction/type/widthPair formal ↔ actualby name or by positionCheckdirection/type/widthmismatch → elaborationerrorUnused output → openinputs must be drivenInstance wired toparent netsreads inputs, drivesoutputs12
Elaboration-time resolution of a port map. For each port, the elaborator pairs the formal (instance pin) with its actual (parent net) — by name for named association, by order for positional — and checks direction, type, and width. After binding, the instance's input ports read those nets and its output ports drive them. An unconnected output is bound to 'open'; an unconnected input would float, so it must be driven.

6. Debugging example — the silent positional swap

Expected: a sub-block behaves correctly. Observed: it elaborates with no error, but its function is wrong — outputs look like inputs were swapped. Root cause: a positional port map listed two same-type actuals in the wrong order (e.g. b and a, or two control bits), so the tool bound them silently because the types matched — no error, just miswired nets. Fix: switch the instance to named association so every connection is explicit and a swap is impossible to miss. Engineering takeaway: positional maps fail silently whenever same-type ports are reordered; named association turns that whole class of bug into a visible, self-checking wiring list.

positional_swap_bug.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- entity sub has ports in order: sel_a, sel_b (both std_logic)
-- WRONG: positional — actuals swapped, but types match, so NO error and wrong behaviour:
u : entity work.sub port map ( ctrl_b, ctrl_a );      -- sel_a<=ctrl_b, sel_b<=ctrl_a (swapped!)
-- RIGHT: named — the binding is explicit and the swap is impossible to make by accident:
u : entity work.sub port map ( sel_a => ctrl_a, sel_b => ctrl_b );

7. Common mistakes & what to watch for

  • Positional maps on real sub-blocks. A reorder silently miswires same-type ports. Use named association for anything beyond a trivial, stable interface.
  • Leaving an input open. Only outputs may be open; an unconnected input floats to 'U'. Drive every input (or give it a deliberate constant).
  • Direction/type/width mismatch. Each binding must match the port exactly; mismatches are elaboration errors (or, worse with positional, silent miswires when types happen to match).
  • Connecting an out port to read it internally. Read from the driving signal, not the out port, unless using buffer/inout deliberately (lesson 1.6 on modes).
  • Mixing named and positional carelessly. It is allowed in a limited way but error-prone; pick named and stay consistent.

8. Engineering insight

The port map is where structural correctness is won or lost, and the choice of association style is a real reliability decision. Named association costs a few extra characters and buys immunity to the single most insidious structural bug — the silent same-type swap — while doubling as documentation: the map reads as a labelled wiring list that survives port reordering and refactoring. Treat named association as the default for every non-trivial instance, reserve open for outputs you genuinely ignore, and let the direction/type/width checks catch the rest at elaboration. Reliable hierarchy is built on explicit, checkable connections.

9. Summary

A port map binds an instance's formals (ports) to the parent's actuals (signals). Named association (formal => actual) is explicit, order-independent, and self-documenting; positional association matches by declaration order and fails silently on same-type reorders. Each binding's direction, type, and width must match, only outputs may be left open, and named association is the professional default.

10. Learning continuity

You can place a sub-block and wire it precisely. The last structural tool replicates them: the next lesson, Generate Statements, uses for … generate and if … generate to instantiate arrays of logic and conditionally include hardware — building regular structures like bit-sliced datapaths and register files from a single parametric description, all still concurrent.