This article is about the two major type of modeling available in VHDL - Gate Level and Behavior level.
In gate level modeling the module is implemented in terms of logic gates and interconnections between these gates.Design at this level is similar to describing a circuit in terms of a gate level logic diagram.
In Behavior level(Algorithmic level) modeling a module is implemented in terms of the desired design algorithm without the concern for the hardware circuit elements.Designing at this level is the highest abstraction level provided by VHDL.
For understanding the difference between the two models I have designed a PISO(Parallel In Serial Out) in both the models. See the behavioral level code below:
If you check the code above then you can see that the code is written using some if..else.. statements. We havent used any digital circuit elements like flip-flops,gates,registers etc. The code describes the working in a language similar to a high level language like C (but there are lot of difference between C and VHDL, and they are not even comparable).
Now let us check the Gate level code:
In the above code you can notice the following features of Gate level code:
1)We have used VHDL gate level primitives like not,and,or etc in the program.
2)The flip flop required for implementing the 4 bit register was instantiated separately. The flip flop code was taken from one of my earlier post and it is another example of behavior level modeling.Check the flip flop code here.
3)We havent used a "process" statement in the program.
4)The above code is also an example of Structural level modeling where we use a hierarchy of modules.For example the D flip flop is considered as a black box from the PISO module's point of view.Once the flip flop (or generally any other module) is designed and verified we can use it any number of times any where in a bigger design.This type of design is called structural level design. Some more examples can be found here : 4 bit synchronous UP counter.
5)You can find more example codes for gate level modeling here : 3 to 8 decoder using basic logic gates and 4 bit ripple carry adder.
I have written the following testbench code for verifying my design.You can edit and check for more input combination for learning purpose.
The simulation result is shown below:
In gate level modeling the module is implemented in terms of logic gates and interconnections between these gates.Design at this level is similar to describing a circuit in terms of a gate level logic diagram.
In Behavior level(Algorithmic level) modeling a module is implemented in terms of the desired design algorithm without the concern for the hardware circuit elements.Designing at this level is the highest abstraction level provided by VHDL.
For understanding the difference between the two models I have designed a PISO(Parallel In Serial Out) in both the models. See the behavioral level code below:
--Library declaration.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity piso is
PORT(
Serial_out : OUT std_logic;
Parallel_In : IN std_logic_vector(3 downto 0);
Load : IN std_logic;
Clk : IN std_logic
);
end piso;
architecture Behavioral of piso is
signal Load_value : std_logic_vector(3 downto 0):="0000";
begin
process(Clk)
begin
if(rising_edge(Clk)) then
if( Load ='0' ) then --Do the serial right shifting here.
Serial_Out <= Load_value(3);
Load_value(3) <= Load_value(2);
Load_value(2) <= Load_value(1);
Load_value(1) <= Load_value(0);
Load_value(0) <= '0';
else --Load the registers with a new value to shift.
Load_value <= Parallel_In;
end if;
end if;
end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity piso is
PORT(
Serial_out : OUT std_logic;
Parallel_In : IN std_logic_vector(3 downto 0);
Load : IN std_logic;
Clk : IN std_logic
);
end piso;
architecture Behavioral of piso is
signal Load_value : std_logic_vector(3 downto 0):="0000";
begin
process(Clk)
begin
if(rising_edge(Clk)) then
if( Load ='0' ) then --Do the serial right shifting here.
Serial_Out <= Load_value(3);
Load_value(3) <= Load_value(2);
Load_value(2) <= Load_value(1);
Load_value(1) <= Load_value(0);
Load_value(0) <= '0';
else --Load the registers with a new value to shift.
Load_value <= Parallel_In;
end if;
end if;
end process;
end Behavioral;
If you check the code above then you can see that the code is written using some if..else.. statements. We havent used any digital circuit elements like flip-flops,gates,registers etc. The code describes the working in a language similar to a high level language like C (but there are lot of difference between C and VHDL, and they are not even comparable).
Now let us check the Gate level code:
--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 D1,D2,D3,D4,Q1,Q2,Q3,Q4 : std_logic :='0';
signal Load_value : std_logic_vector(3 downto 0):="0000";
begin
Load_value <= Parallel_In;
Serial_out <= Q4;
--entity instantiation of the D flipflop.It is instantiated 4 times to make 4 bit register.
FDRSE1 : entity work.example_FDRSE --MSB
port map (
Q => Q1,
CLK => Clk,
CE => '1',
RESET => '0',
D => D1,
SET => '0'
);
FDRSE2 : entity work.example_FDRSE
port map (
Q => Q2,
CLK => Clk,
CE => '1',
RESET => '0',
D => D2,
SET => '0'
);
FDRSE3 : entity work.example_FDRSE
port map (
Q => Q3,
CLK => Clk,
CE => '1',
RESET => '0',
D => D3,
SET => '0'
);
FDRSE4 : entity work.example_FDRSE --LSB
port map (
Q => Q4,
CLK => Clk,
CE => '1',
RESET => '0',
D => D4,
SET => '0'
);
--The D inputs of the flip flops are controlled with the load input.
--Two AND gates with a OR gate is used for this.
D1 <= Load_value(3) and Load;
D2 <= (Load_value(2) and Load) or (Q1 and not(Load));
D3 <= (Load_value(1) and Load) or (Q2 and not(Load));
D4 <= (Load_value(0) and Load) or (Q3 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 D1,D2,D3,D4,Q1,Q2,Q3,Q4 : std_logic :='0';
signal Load_value : std_logic_vector(3 downto 0):="0000";
begin
Load_value <= Parallel_In;
Serial_out <= Q4;
--entity instantiation of the D flipflop.It is instantiated 4 times to make 4 bit register.
FDRSE1 : entity work.example_FDRSE --MSB
port map (
Q => Q1,
CLK => Clk,
CE => '1',
RESET => '0',
D => D1,
SET => '0'
);
FDRSE2 : entity work.example_FDRSE
port map (
Q => Q2,
CLK => Clk,
CE => '1',
RESET => '0',
D => D2,
SET => '0'
);
FDRSE3 : entity work.example_FDRSE
port map (
Q => Q3,
CLK => Clk,
CE => '1',
RESET => '0',
D => D3,
SET => '0'
);
FDRSE4 : entity work.example_FDRSE --LSB
port map (
Q => Q4,
CLK => Clk,
CE => '1',
RESET => '0',
D => D4,
SET => '0'
);
--The D inputs of the flip flops are controlled with the load input.
--Two AND gates with a OR gate is used for this.
D1 <= Load_value(3) and Load;
D2 <= (Load_value(2) and Load) or (Q1 and not(Load));
D3 <= (Load_value(1) and Load) or (Q2 and not(Load));
D4 <= (Load_value(0) and Load) or (Q3 and not(Load));
end gate_level;
In the above code you can notice the following features of Gate level code:
1)We have used VHDL gate level primitives like not,and,or etc in the program.
2)The flip flop required for implementing the 4 bit register was instantiated separately. The flip flop code was taken from one of my earlier post and it is another example of behavior level modeling.Check the flip flop code here.
3)We havent used a "process" statement in the program.
4)The above code is also an example of Structural level modeling where we use a hierarchy of modules.For example the D flip flop is considered as a black box from the PISO module's point of view.Once the flip flop (or generally any other module) is designed and verified we can use it any number of times any where in a bigger design.This type of design is called structural level design. Some more examples can be found here : 4 bit synchronous UP counter.
5)You can find more example codes for gate level modeling here : 3 to 8 decoder using basic logic gates and 4 bit ripple carry adder.
I have written the following testbench code for verifying my design.You can edit and check for more input combination for learning purpose.
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
--Inputs
signal Parallel_In : std_logic_vector(3 downto 0) := (others => '0');
signal Load : std_logic := '0';
signal Clk : std_logic := '0';
--Outputs
signal Serial_out : std_logic;
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.PISO PORT MAP (
Serial_out => Serial_out,
Parallel_In => Parallel_In,
Load => Load,
Clk => Clk
);
-- Clock process definitions
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 25 ns;
load <= '1';
parallel_in <= "1011";
wait for 10 ns;
load<='0';
wait for 60 ns;
load <= '1';
parallel_in <= "1101";
wait for 10 ns;
load<='0';
wait;
end process;
END;
USE ieee.std_logic_1164.ALL;
ENTITY tb IS
END tb;
ARCHITECTURE behavior OF tb IS
--Inputs
signal Parallel_In : std_logic_vector(3 downto 0) := (others => '0');
signal Load : std_logic := '0';
signal Clk : std_logic := '0';
--Outputs
signal Serial_out : std_logic;
-- Clock period definitions
constant Clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.PISO PORT MAP (
Serial_out => Serial_out,
Parallel_In => Parallel_In,
Load => Load,
Clk => Clk
);
-- Clock process definitions
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 25 ns;
load <= '1';
parallel_in <= "1011";
wait for 10 ns;
load<='0';
wait for 60 ns;
load <= '1';
parallel_in <= "1101";
wait for 10 ns;
load<='0';
wait;
end process;
END;
The simulation result is shown below:
No comments:
Post a Comment