type your search

Tuesday, January 10, 2012

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. 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.
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.

No comments:

Post a Comment