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.
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:
So as you can see from the examples using "generate" keyword makes your design simple to understand and saves your time.
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;
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;
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