VHDL coding tips and tricks: comparator
Showing posts with label comparator. Show all posts
Showing posts with label comparator. Show all posts

Sunday, October 3, 2010

VHDL: 3 bit Magnitude Comparator With Testbench (Gate level Modeling)

    In this post I want to share the VHDL code for a 3 bit comparator which is designed using basic logic gates such as XNOR, OR, AND etc. The code was tested using a self checking testbench which tested the design for all its 64 combinations of inputs.

3 bit Comparator Circuit Diagram:



VHDL code for 3 bit comparator:


library ieee;
use ieee.std_logic_1164.all;

entity comparator is
port(a,b : in std_logic_vector(2 downto 0);  --3 bit numbers to be compared
    a_eq_b : out std_logic;  --a equals b
    a_lt_b : out std_logic;  --a less than b
    a_gt_b : out std_logic   --a greater than b
    );    
end comparator;

architecture gate_level of comparator is

--declare internal signals used in the design
signal temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9 : std_logic := '0';

begin

temp1 <= not(a(2) xor b(2));  --XNOR gate with 2 inputs.
temp2 <= not(a(1) xor b(1));  --XNOR gate with 2 inputs.
temp3 <= not(a(0) xor b(0));  --XNOR gate with 2 inputs.
temp4 <= (not a(2)) and b(2);
temp5 <= (not a(1)) and b(1);
temp6 <= (not a(0)) and b(0);
temp7 <= a(2) and (not b(2));
temp8 <= a(1) and (not b(1));
temp9 <= a(0) and (not b(0));

a_eq_b <= temp1 and temp2 and temp3;  -- for a equals b.
a_lt_b <= temp4 or (temp1 and temp5) or (temp1 and temp2 and temp6); --for a less than b
a_gt_b <= temp7 or (temp1 and temp8) or (temp1 and temp2 and temp9); --for a greater than b

end gate_level;

Testbench for 3 bit Comparator:


library ieee;
use ieee.std_logic_1164.all;
--Note that I am using this library only in testbench. Generally its 
--advised to not use this library.
use ieee.std_logic_arith.all;

--testbench has empty entity
entity tb_comparator is
end entity tb_comparator;

architecture behavioral of tb_comparator is

signal a_eq_b,a_lt_b,a_gt_b : std_logic := '0';
signal a,b :std_logic_vector(2 downto 0) := "000";

begin

--entity instantiation with named association port mapping
comparator_uut: entity work.comparator
    port map(a => a,
        b => b,
        a_eq_b => a_eq_b,
        a_lt_b => a_lt_b,
        a_gt_b => a_gt_b);

--self checking testbench. 
--checks for all combinations of inputs.
stimulus: process
begin 
    for i in 0 to 7 loop
        for j in 0 to 7  loop
            --typecast integers to std_logic_vector.
            a <= conv_std_logic_vector(i,3);
            b <= conv_std_logic_vector(j,3);
            wait for 1 ns;
            --the below statements does the automatic verification
            if(a = b) then
                assert a_eq_b = '1';
            elsif(a < b) then
                assert a_lt_b = '1';
            elsif(a > b) then
                assert a_gt_b = '1';
            end if;
        end loop; 
    end loop; 
    wait;  --testing done. wait endlessly
end process;

end behavioral;

Simulation waveform from Modelsim:


3 bit comparator simulation waveform in vhdl modelsim



Post-Synthesis Schematic from Xilinx Vivado:


Post-Synthesis Schematic from Xilinx Vivado for comparator

    You can see that 3 LUT6's were used to implement this logic. As a little homework, why don't you write the behavioral level code for a 3 bit comparator and see if the amount of LUT's used are more or less compared to what we have now. If you do this experiment, let me know the results in the comment section.