VHDL · Chapter 12.3 · Generics
Generic Maps and Instantiation
Writing a generic entity is half the story, and instantiating it is the other half. The generic map clause, placed just before the port map, supplies each instance's generic values with the same association rules as ports, either positional in declared order or named for clarity, which is the production habit, with defaults filling in any generic you omit. The real power appears in hierarchy, because a parent entity can pass its own generics straight down to child instances, so one top-level parameter configures an entire subtree consistently. Generic values can also be expressions computed at elaboration, such as a derived address width from a depth. This lesson covers generic-map association, defaults, expressions, and how generics propagate down through a design hierarchy.
Foundation14 min readVHDLGenericsGeneric MapInstantiationHierarchyReuse
1. Engineering intuition — set the knobs at the point of use
A generic is a knob on the entity; the generic map is where each instance turns it. You set the knobs at the
point of use, exactly where you know what this instance should be — 8 bits here, 32 there. And because a parent
design has knobs of its own, it can wire its knob straight through to its children: turn the top-level DATA_W
and every block beneath it that was given WIDTH => DATA_W follows. That propagation is what lets a single
parameter at the top reshape an entire hierarchy at build time, without editing any of the blocks inside.
2. Formal explanation — generic map association and defaults
-- generic map(...) comes BEFORE port map(...). Same association styles as ports.
-- POSITIONAL: values in declared generic order.
u1 : entity work.reg generic map (32) port map (clk => clk, d => d, q => q);
-- NAMED (preferred): order-independent, self-documenting; omitted generics take their defaults.
u2 : entity work.fifo
generic map ( WIDTH => 16, DEPTH => 64 ) -- any generic with a default may be omitted
port map ( clk => clk, /* ... */ );
-- EXPRESSIONS are allowed (evaluated at elaboration):
u3 : entity work.ram
generic map ( DATA_W => 32, ADDR_W => clog2(1024) ) -- derived width from a computed value
port map ( /* ... */ );The generic map associates values to generics by position or by name; named association is
preferred beyond one or two generics for clarity and to skip defaulted ones. Values may be constants,
generics, or expressions evaluated at elaboration — including derived sizes like clog2(...).
3. Production usage — propagating a generic through hierarchy
-- A parent passes ITS OWN generic down to children → one top-level knob configures the subtree.
entity datapath is
generic ( DATA_W : positive := 32 );
port ( clk : in std_logic; /* ... */ );
end entity;
architecture rtl of datapath is
begin
u_add : entity work.adder
generic map ( WIDTH => DATA_W ) -- parent's generic flows to the child
port map ( /* ... */ );
u_reg : entity work.reg
generic map ( WIDTH => DATA_W ) -- same parameter → consistent width across the subtree
port map ( /* ... */ );
end architecture;
-- Top level sets DATA_W once: entity work.datapath generic map (DATA_W => 16) port map (...);What hardware does this become? At elaboration the tool resolves DATA_W top-down: set it to 16 at the top
and both u_add and u_reg elaborate as 16-bit blocks; set it to 64 and the whole datapath becomes 64-bit — all
from one parameter. The generic map adds no hardware; it is pure build-time wiring of configuration. The
result is a hierarchy whose size is controlled by a single knob, with every level guaranteed consistent because
they share the same propagated value.
4. Structural interpretation — one parameter down the hierarchy
5. Why this is structural, not timing
The generic map is build-time configuration wiring — it associates values to generics and propagates them down the hierarchy at elaboration — so a structural diagram, not a waveform, is the right picture. It contributes no logic and no delay; once elaboration resolves every generic, the design is concrete sized hardware whose behaviour you have already seen at each width. All the action is in how configuration flows, which is a static, structural property of the instantiation, not anything that varies over simulation time.
6. Debugging example — the unset or mis-associated generic
Expected: an instance built at the intended width. Observed: an elaboration error that a generic has no
value, or an instance that is the wrong size, or a positional generic map that silently set the wrong parameter.
Root cause: a generic with no default was not supplied in the generic map, or positional
association passed values in the wrong order, or a parent forgot to propagate its generic so the child fell
back to its default. Fix: use named association so each value lands on the right generic and intent is
explicit; supply every non-defaulted generic; and pass the parent's generic down where the child should track it.
Engineering takeaway: prefer named generic association and always supply or propagate values — positional maps
and missing values are the usual cause of wrong-size or unelaboratable instances.
-- BUG: positional map sets the wrong generic; child not propagated → wrong/ default width.
-- u : entity work.fifo generic map (64, 16) port map (...); -- which is WIDTH? which DEPTH?
-- FIX: named association + propagate the parent generic.
u : entity work.fifo generic map (WIDTH => DATA_W, DEPTH => 64) port map (...);7. Common mistakes & what to watch for
- Positional generic maps on multi-generic components. Easy to transpose; use named association
(
WIDTH => ...) for clarity and safety. - Missing a non-defaulted generic. Elaboration fails; supply every generic without a default.
- Forgetting to propagate. A child keeps its default unless the parent passes its generic down via the generic map.
- Assuming the generic map adds hardware. It is build-time configuration only; the logic comes from the entity, sized by the resolved generics.
- Illegal generic expressions. Generic-map expressions must be resolvable at elaboration (constants,
generics,
clog2, etc.) — not runtime signals.
8. Engineering insight & continuity
The generic map is where parameterization is applied: named (preferred) or positional association sets each
instance's generics, defaults fill the rest, expressions like clog2(DEPTH) derive values, and — most powerfully
— a parent propagates its generics to children so one top-level knob configures a whole hierarchy
consistently. With entities, width-generic design, and instantiation covered, the next lesson combines generics
with structural replication: Generics with Generate Statements — using a generic count to instantiate an
array of blocks or conditionally include logic.