As with ports, named association is preferred. It avoids mistakes when the order changes.
for ... generate
for ... generate instantiates several copies of the same block at elaboration.
entity reg_bank is generic ( g_WIDTH : positive := 8 ); port ( i_clk : in std_logic; i_d : in std_logic_vector(g_WIDTH - 1 downto 0); o_q : out std_logic_vector(g_WIDTH - 1 downto 0) );end entity reg_bank;architecture rtl of reg_bank isbegin g_bits : for i in 0 to g_WIDTH - 1 generate p_bit : process(i_clk) begin if rising_edge(i_clk) then o_q(i) <= i_d(i); end if; end process p_bit; end generate g_bits;end architecture rtl;
This is not a runtime loop. The synthesizer creates g_WIDTH real structures.
if ... generate
if ... generate makes a block optional.
entity pipeline_stage is generic ( g_REGISTER_OUTPUT : boolean := true ); port ( i_clk : in std_logic; i_a : in unsigned(7 downto 0); i_b : in unsigned(7 downto 0); o_y : out unsigned(8 downto 0) );end entity pipeline_stage;architecture rtl of pipeline_stage is signal w_sum : unsigned(8 downto 0); signal r_y : unsigned(8 downto 0);begin w_sum <= resize(i_a, w_sum'length) + resize(i_b, w_sum'length); g_registered : if g_REGISTER_OUTPUT generate p_reg : process(i_clk) begin if rising_edge(i_clk) then r_y <= w_sum; end if; end process p_reg; o_y <= r_y; end generate g_registered; g_comb : if not g_REGISTER_OUTPUT generate o_y <= w_sum; end generate g_comb;end architecture rtl;
If g_REGISTER_OUTPUT = false, the register is absent from the netlist.
Best practices
Give every generic a reasonable default.
Use positive or natural when a free integer is not needed.
Prefer g_WIDTH to WIDTH to distinguish parameters.
Do not use a generic for a value that must change while the circuit runs.
Label generate blocks, especially in structural designs.
VHDL-2008: more advanced generics
VHDL-2008 also allows type, subprogram and package generics. This is powerful, but not required at the beginning.
Example intent:
generic ( type t_data);
This style is used to create very generic blocks, for example a FIFO that can store different types. For a classic FPGA path, width, depth and feature-enable generics are already enough.