0 votes
in VHDL by (240 points)

What are VHDL generics and how do you use them?

3 Answers

0 votes
by (1.8k points)

VHDL Generics

Quick Syntax

Here's how you declare generics at the top of your design source file:
entity data_bus is
generic(
ADDR_BIT_WIDTH : integer range 1 to 16 := 8;
DATA_BIT_WIDTH : integer range 1 to 32 := 32);
port(
clk : in std_logic;
reset : in std_logic;
addr : in std_logic_vector(ADDR_BIT_WIDTH-1 downto 0);
data : out std_logic_vector(DATA_BIT_WIDTH-1 downto 0));
end data_bus;

...........

signal data_buffer : std_logic_vector(DATA_BIT_WIDTH-1 downto 0);
And here is how you use generics when you instantiate your module in your top level:
BUS1 : entity work.data_bus
generic map (
ADDR_BIT_WIDTH => 16,
DATA_BIT_WIDTH => 16)
port map (
clk => clk,
reset => reset,
addr => bus1_addr,
data => bus1_data);

Purpose

Generics are a great way to create modular code that can be quickly changed to accomodate a wide variety of designs.

For example, you can use generics to set std_logic_vector bit widths for such things as addresses and data. Another example is using them to drive for generate loops to instantiate N number of modules.

By using generics, you can have one common design that you can use for almost any situation for a specific type of interface. As you are coding, you should always be thinking about how to make your source code more modular so that you can re-use it in the future for a similar design.

That way, as you advance as a coder, you are building a bigger and bigger library of your own modules that have already been simulated and proven out in hardware. It exponentially increases your speed and productivity in executing a design.

Generics are the main method to do this in VHDL.

Best Practices

1. Use generics to make your code modular so that you can design for re-use in mind. Consider the different sizes of signals that might occur in the future for similar designs and make your code where it can solve the problem for a wide variety of situations.

2. For generics that are integers, it's a good idea to set a range where if a top instantiation sets it out of range, the compile will fail. This way you can limit what the design source is used for based on what you have simulated and tested.

3. Always set your generics to a default value. That way if someone wants to use the defaults only, they can omit the generic map portion in the top level instantiation. If they want to change only a few, they only have to list the ones they want to over-ride in the generic map.
0 votes
by (500 points)

VHDL generics provide an ability to pass information into an entity during instantiation. They remain constant after compilation and are used for making a design more generalized.

Instead of writing :

entity some_entity is

generic
(
width_of_counter : positive
) ;

port
(
counter : in ( 3 downto 0 ) ; -- hard coded to be 4 bits long. ) ;

end entity some_entity ;
We can write :
entity some_entity is

generic
(
width_of_counter : positive
) ;

port
(
counter : in ( width_of_counter - 1 downto 0 ) ; -- can be any width ( the desired width will be passed during instantiation in the generic map ). ) ;

end entity some_entity ;
0 votes
by (500 points)

These are parameters. These parameters are constants in the scope of entity in which they are defined. It is used to parameterize a design: component configurations, ip-cores choice, data sizes, architecture's configurations, protocols used, etc. The simple example is to define a data bus width:

entity mul_generic is
generic (
width_multiplicand : integer := 15;
width_multiplier : integer := 14;
pipeline_width : integer := 2);
port (
clk_i : in std_logic;
nrst_i : in std_logic;
a : in std_logic_vector(width_multiplicand-1 downto 0);
b : in std_logic_vector(width_multiplier-1 downto 0);
p : out std_logic_vector(width_multiplicand+width_multiplier-1 downto 0) );
end entity;

phase_adders_inst: for i in 35 downto 0 generate
constant step : integer := 36/pipeline_width;
begin

cin_curr_bit_ff_gen: if i mod pipeline_width = 0 generate
cin(i) <= phase_carry_ff(i);
end generate;
cin_curr_bit_comb_gen: if i mod pipeline_width > 0 generate
cin(i) <= phase_carry(i);
end generate;
adder: entity work.adder3to2(rtl)
port map(
A=>increment_triangled(i),
B=>phase_sum_ff(i),
CIN=>cin(i),
C=>phase_sum(i),
COUT=>phase_carry(i+1));
end generate;
Hardware Coder Community

© 2022 by Hardware Coder. User contributions are licensed under cc by-sa 4.0 with attribution required. Attribution means a link to the question, answer, user, etc on this site.

This site is owned and operated by Hardware Coder in McKinney, Texas.

Send Us A Message
About Us

By using this site, you agree to the following:

Privacy Policy
Terms and Conditions
DMCA Policy
Earnings Disclaimer
Legal Disclaimer

...