VHDL coding tips and tricks: VHDL: 3 bit Magnitude Comparator With Testbench (Gate level Modeling)

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. 


6 comments:

  1. This is very academic. I am not a fan of design at this level. For FPGA's its actually detrimental. In any useful design, the user would just use:
    x <= '1' when (unsigned(a) < unsigned(b)) else '0';

    This scales well, even beyond the 31b limit of integers.

    ReplyDelete
  2. @Chris : yes you are right Chris. I wrote this code from a academic point of view. In real project no body will write separate module for just a comparison. This post was for VHDL beginners for learning gate level modeling.

    ReplyDelete
  3. HELLO friend ,
    i have also coded for 3 bit magnitude comparator but its showing error . i am posting the code and i will next post the error. please check and make corrections .thanks in advance.
    architecture Behavioral of bit_3 is
    signal x0,x1,x2:STD_LOGIC:='0';
    begin
    x0<=not(a(0) xor b(0)) ;
    x1<=not(a(1) xor b(1));
    x2<=not(a(2) xor b(2));
    a_gr_b<=(a and (not b)) or (x2 and a and (not b)) or (x2 and x1 and a and (not b));--a>b
    a_le_b<=(b and (not a)) or (x2 and b and (not a)) or (x2 and x1 and b and (not a));--a<b
    a_eq_b<=x2 and x1 and x0;
    end Behavioral;

    ReplyDelete
  4. Line 45. and can not have such operands in this context.
    and this error in three lines . in a_gr_b and a_le_b and a_eq_b

    ReplyDelete
  5. its showing error in line of a_gr_b and a_le_b that" and can not have such operands in this context".

    ReplyDelete
  6. why we are using the below line?
    signal temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9 : std_logic := '0';

    ReplyDelete