VHDL coding tips and tricks: GENERIC's in VHDL - Construction of parametrized components

Wednesday, March 10, 2010

GENERIC's in VHDL - Construction of parametrized components

     Generics allow a design entity to be described so that,for each use of that component,its structure and behavior can be changed by generic values.In general they are used to construct parameterized hardware components.Generics can be of any type.
Let us understand the use of "generic" with an example.

--The top module has two instantiations- a 8 bit PISO(parallel in serial out) register and a 4 bit PISO.
--Without the use of generics these two components need a seperate .vhd  file.
--But I have used "generic" keyword to solve this problem.
entity piso is
    generic ( width : integer := 7 );             --default value is 7
port  (  clk : in std_logic;
            load : in std_logic;
            in1 : in std_logic_vector(width downto 0);
            out1 : out std_logic
end piso;
architecture Behavioral of piso is
signal temp: std_logic_vector (width downto 0) := (others => '0');  --initialize to zero
if (load = '0') then  -- load the register
temp <= in1;
elsif (clk'event and clk = '1') then
--shift the register elements and output a single bit.
out1 <= temp(width);
temp(width downto 1) <= temp(width-1 downto 0);
end if;
end process;
end Behavioral;

--Now the instantiation of this component in top module is shown below:
entity test is
end test;
architecture behavior of test is
component piso
     generic ( width : integer := 7 );
port  (  clk : in std_logic;
            load : in std_logic;
            in1 : in std_logic_vector(width downto 0);
            out1 : out std_logic
end component;
--signal declarations
signal in1 : std_logic_vector(7 downto 0):="10000110";
signal in2 : std_logic_vector(3 downto 0):="1001";
signal load1,load2 : std_logic :='0';
--Note down the next two lines.
--This is how you pass generic parameters to the instantiated components.
piso1 : piso generic map (width => 7) port map(clk,load1,in1,o1);
piso2 : piso generic map (width => 3) port map(clk,load2,in2,o2);
--change the input signals as you want.
end behavior;
      "generic map (width => 7)" is used to pass the generic parameter to the component.Thus,without writing any extra code you were able to complete your design.

Note1 :- "GENERIC" is a great asset when you use your design at many places with slight change in the register sizes,input sizes etc.But if the design is very unique then,you need not have generic parameters.
Note2 :- Generic's are synthesizable.


  1. This is an example of poor coding style. This would actually make a good interview question. in fact, it generally is.

    There are three things wrong with the code. Remember that synthesizable doesn't mean "working" or "good".

    The first mistake is that you don't define "out1" for the async "load" case. This infers extra logic, as now there is a priority logic with load and clk.

    The second mistake is that your async load sets "temp" to a non-constant value. why is this bad? well, now the logic needs to set the value on the output, independent of the clock. FURTHER, if load is deasserted before the next clock edge, this value must be latched.

    lastly, the sim won't match the code. in fact, the .syr report will give this as a warning. notice that if load is asserted, it should be async. but load isn't in the sensitivity list, so it will only get counted if there is a clk'event. XST will ignore this, but simulators generally won't.

    other, less important notes -- in almost all languages constants are ALL_CAPS. generics usually follow this standard by most coders.

    its advisable to never instantiate components by port-order. doing such should cause you physical pain. not only does it make the code unreadable, it leads to all types of errors.

    1. its not an async load, since load does not appear in the sensitivity list of the process. This means the process only executes on clk changes. In fact, it kind of is implying that load happens on both rising and falling edge of clk.

  2. @Chris : Thanks for making a through analysis of most of my posts.It helped me learning a lot.
    Anyway I agree my bad coding style, but this post was mainly for learning the usage of "generics".I think I have succeeded in that.

  3. Definately, though one large advantage to VHDL over Verilog2001 is with the richness of generics. for example, you can pass an array of integers, or an array of arrays of vectors, or records, or strings as a generic. While not commonly used, this flexibility can be helpful.

  4. This comment has been removed by a blog administrator.

  5. Hello,
    nice example,
    Just a remark about your parameter width, it must be 8 (or 4), as it is the number of bits that you have and not 7 (or 3). And when you use them as width-1 for the upper boundary.

    Best regards.


  6. i tried a generic MUX........but when i give the width 7....it shows me

    Fatal: (vsim-3738) (vopt-1152) Index value 7 is out of index range 6 downto 0 of ieee.std_logic_1164.std_logic_vector

    i cant fix it