Skip to content

VHDL · Chapter 12.4 · Generics

Generics with Generate Statements

Generics set sizes, and generate statements turn those sizes into structure. A for-generate whose bound is a generic replicates that many instances, building an N-stage pipeline, an array of processing elements, or a structural datapath, all from one body. An if-generate, and in VHDL-2008 a case-generate, conditionally includes logic based on a generic, giving you an optional output register when requested, a different implementation per mode, or special handling at the first or last index of a replicated array. Together, generic-driven generate is how you build designs whose very shape, meaning how many blocks and which blocks exist, becomes a parameter fixed at elaboration. This lesson combines generics with for-generate and if-generate to produce structurally parameterized hardware from a single source.

Foundation14 min readVHDLGenericsGenerateReplicationPipelineStructural

1. Engineering intuition — let a number decide the structure

So far a generic changed how wide a block is. Generate lets a generic change how many blocks there are and which blocks exist. Think of a pipeline with STAGES stages: you do not want to copy a stage STAGES times by hand — you want to say "make one of these for each stage" and let a generic set the count. That is for-generate. And sometimes a piece of logic should exist only in certain configurations — an output register only when requested, boundary handling only at the ends — which is if-generate. Generic-driven generate is how a single source describes a family of differently-shaped circuits.

2. Formal explanation — for-generate and if-generate driven by generics

generate_with_generics.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- FOR-GENERATE: replicate N instances, N from a generic. Each iteration is elaborated structurally.
gen_stages : for i in 0 to STAGES-1 generate
  u_stage : entity work.stage
    generic map ( WIDTH => DATA_W )
    port map ( clk => clk, d => pipe(i), q => pipe(i+1) );   -- index the array of signals
end generate;
 
-- IF-GENERATE: include logic only when a generic condition holds (e.g. optional output register).
gen_reg : if REG_OUT generate
  process (clk) begin
    if rising_edge(clk) then q <= y; end if;                 -- present only when REG_OUT = true
  end process;
end generate;
gen_comb : if not REG_OUT generate
  q <= y;                                                    -- otherwise combinational pass-through
end generate;

A for-generate elaborates its body once per index over a range that can come from a generic — structural replication, with the index used to wire an array of instances/signals. An if-generate (and 2008 case-generate) elaborates its body only when a generic-based condition holds, conditionally including or omitting logic. Both are resolved at elaboration.

3. Production usage — an N-stage pipeline from a generic

n_stage_pipeline.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
entity delay_line is
  generic ( STAGES : positive := 4; DATA_W : positive := 8 );
  port ( clk : in std_logic;
         d   : in  std_logic_vector(DATA_W-1 downto 0);
         q   : out std_logic_vector(DATA_W-1 downto 0) );
end entity;
architecture rtl of delay_line is
  type slv_arr is array (0 to STAGES) of std_logic_vector(DATA_W-1 downto 0);
  signal pipe : slv_arr;                       -- STAGES+1 taps
begin
  pipe(0) <= d;
  gen : for i in 0 to STAGES-1 generate        -- STAGES registers, count from the generic
    process (clk) begin
      if rising_edge(clk) then pipe(i+1) <= pipe(i); end if;
    end process;
  end generate;
  q <= pipe(STAGES);
end architecture;

What hardware does this become? STAGES => 4 elaborates four register stages chained d → … → q (a 4-cycle delay line); STAGES => 16 elaborates sixteen. The for-generate produces real, distinct flip-flop stages — one per index — wired through the pipe array. The number of stages is fixed at elaboration by the generic, so the structure (how many registers) is parameterized while each stage is identical hardware.

4. Structural interpretation — a generic builds N stages

for-generate replicating N pipeline stages whose count comes from the STAGES genericfor-generategeneric STAGESsets the countstage 0pipe(0)→pipe(1)stage 1pipe(1)→pipe(2)replicatedstage N-1pipe(N-1)→pipe(N)12
A generic-driven for-generate turns a count into structure. The STAGES generic sets how many stage instances the for-generate elaborates, each wired to the next through an indexed signal array to form an N-stage pipeline; STAGES=4 builds four register stages, STAGES=16 builds sixteen, from one body. An if-generate would additionally include or omit logic (like an optional output register) based on a generic condition. Generate is resolved at elaboration, producing real replicated hardware. This is a structural replication, captured by a diagram rather than a waveform.

5. Why this is structural, not timing

Generic-driven generate is structural replication and conditional inclusion resolved at elaboration — it decides how many blocks and which blocks exist before any simulation — so a structure diagram, not a waveform, captures it. Once elaborated, the result is ordinary hardware (a 4-stage pipeline behaves like four chained registers, whose timing you already know); generate itself adds nothing at run time. The parameterization is in the shape of the netlist, a static property, which is precisely why it is shown as structure.

6. Debugging example — the generate that built the wrong shape

Expected: N stages wired in a chain. Observed: an index-out-of-range error, stages not connected, or logic that should have been optional appearing/missing. Root cause: the signal array bounds did not match the generate range (e.g. pipe declared 0 to STAGES-1 but indexed pipe(i+1) up to STAGES), the for-generate range was off-by-one, or an if-generate condition was based on a value not known at elaboration. Fix: size the connecting array to cover every index the loop uses (0 to STAGES for STAGES stages with taps), keep the generate range consistent, and base if-generate conditions on generics/constants (elaboration-time), never runtime signals. Engineering takeaway: generate replicates structurally at elaboration — get the array bounds and loop range consistent, and gate if-generate on compile-time generics, not runtime values.

bounds_must_match.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- BUG: array too small for the indices the generate uses → index out of range.
-- type a is array (0 to STAGES-1) of ...;  -- but loop writes pipe(i+1) up to STAGES
-- FIX: size the array to cover every tap (0 .. STAGES).
type a is array (0 to STAGES) of std_logic_vector(DATA_W-1 downto 0);

7. Common mistakes & what to watch for

  • Off-by-one bounds. Match the connecting array size to the generate range (an N-stage chain needs N+1 taps); mismatches cause index errors.
  • if-generate on a runtime value. Conditions must be elaboration-time (generics/constants); you cannot conditionally generate hardware from a signal.
  • Forgetting generate labels. Generate statements and their inner instances need labels; they form part of the hierarchical name.
  • Expecting a runtime-variable count. The number of generated instances is fixed at elaboration by the generic; it cannot change while running.
  • Replicating instead of looping for pure logic. For simple per-bit logic a vectorized expression may be cleaner than a for-generate; use generate for instances/structure.

8. Engineering insight & continuity

Generic-driven generate makes a design's shape a parameter: a for-generate replicates N instances where N is a generic (pipelines, PE arrays, structural datapaths), and an if/case-generate includes or omits logic by a generic condition (optional registers, mode/boundary handling) — all resolved at elaboration into real hardware. Combined with width generics, you can now parameterize both size and structure from one source. The next lesson widens what a generic can be: beyond integers, Constant and Type Generics — passing configuration constants and even types as generics for still more flexible, reusable components.