VHDL coding tips and tricks: How to use "generate" keyword for multiple instantiation?

Tuesday, September 14, 2010

How to use "generate" keyword for multiple instantiation?

   Generate statement is a concurrent statement used in VHDL to describe repetitive structures.You can use generate statement in your design to instantiate multiple modules in two ways: the FOR-way and the IF-way.
   FOR-way is explained through a PISO(parallel in serial out) register example I have discussed earlier.The original post can be accessed here. I have modified the Gate level modeling code available in that post using "generate" statement.

--Library declaration.
library ieee;
use ieee.std_logic_1164.all;
--4 bit Parallel In Serial Out shift register(LSB is out first)
entity PISO is
port ( Serial_out : out std_logic;
       Parallel_In : in std_logic_vector(3 downto 0);
       --Load=1 means register is loaded parallely and Load=0 means right shift by one bit.
       Load : in std_logic;
       Clk : in std_logic
     );
end PISO;
architecture gate_level of PISO is
signal D,Q,Load_value : std_logic_vector(3 downto 0):="0000";
signal i : integer := 0;
begin
Load_value <= Parallel_In;
Serial_out <= Q(3);

--entity instantiation of the D flipflop using "generate".
F :  --label name
   for i in 0 to 3 generate   --D FF is instantiated 4 times.
    begin  --"begin" statement for "generate"
        FDRSE_inst : entity work.example_FDRSE port map   --usual port mapping
          (Q => Q(i),
          CLK => Clk,
          CE => '1',
          RESET => '0',
          D => D(i),
          SET => '0');
   end generate F;  --end "generate" block.
--The D inputs of the flip flops are controlled with the load input.
--Two AND gates with a OR gate is used for this.
D(0) <= Load_value(3) and Load;
D(1) <= (Load_value(2) and Load) or (Q(0) and not(Load));
D(2) <= (Load_value(1) and Load) or (Q(1) and not(Load));
D(3) <= (Load_value(0) and Load) or (Q(2) and not(Load));
end gate_level; 

I hope the above code is self explanatory.The for loop is used to instantiate as many number of modules as we want to instantiate.Next I will give an example on the IF-way using a Johnson counter example. The Johnson counter is explained with the help of VHDL code in one of my previous posts.Check it out here.I have modified the code using flip-flops available in this post.
The modified code is given below:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity johnson_counter is
port (
        DAT_O : out unsigned(3 downto 0);
        RST_I : in std_logic;
        CLK_I : in std_logic
        );
end johnson_counter;
architecture Behavioral of johnson_counter is
signal D,Q : unsigned(3 downto 0):="0000";
signal not_Q4 : std_logic:='0';
begin
not_Q4 <= not Q(3);
DAT_O <= Q;
F : for i in 0 to 3 generate
    begin
        F0 : if ( i = 0 ) generate  --The IF condition to for the "first" FF only.
            begin U1 : entity work.example_FDRSE port map --usual port mapping        
            (Q => Q(0),
          CLK => CLK_I,
          CE => '1',
          RESET => RST_I,
          D => not_Q4,
          SET => '0');
             end generate F0;
        F1 : if ( i /= 0 ) generate --generating the rest of the three FF's.
            begin U2 : entity work.example_FDRSE port map   --usual port mapping
         (Q => Q(i),
          CLK => CLK_I,
          CE => '1',
          RESET => RST_I,
          D => Q(i-1),
          SET => '0');
             end generate F1;
    end generate F;    
   
end Behavioral;


   So as you can see from the examples using "generate" keyword makes your design simple to understand  and saves your time.

2 comments:

  1. Thanks by this tutorial !
    I need create this sequence of blocks in VHDL 1,2,3,4,4,5,6,7,8,9,10,11,12,13,13,14,15,,,,40,40,,j,...
    You know or have a idea of the correct way to do this sequence?
    Thanks again

    ReplyDelete
  2. if(valueYouWant = i) generate
    for j in 0 to howManyTimes generate
    ...

    ReplyDelete