VHDL coding tips and tricks: A 3 bit Magnitude Comparator using logic gates

Sunday, October 3, 2010

A 3 bit Magnitude Comparator using logic gates

   I have been getting lot of requests asking for VHDL code for digital comparators. In this post I have shared a 3 bit comparator which is designed using basic logic gates such as XNOR, OR, AND etc. The code was tested using  a testbench code which tested the design for all the 81 combinations of inputs.

See the code below:

library IEEE;

entity comparator is
port( a,b : in unsigned(2 downto 0);  --3 bit numbers to be compared
        a_eq_b : out std_logic;  --a equals b
        a_le_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

signal temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9 : std_logic := '0';


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_le_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;

The testbench code for testing the design is given below:

USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

END tb;

   signal a : unsigned(2 downto 0) := (others => '0');
   signal b : unsigned(2 downto 0) := (others => '0');
   signal a_eq_b : std_logic;
   signal a_le_b : std_logic;
   signal a_gt_b : std_logic;

    signal i,j : integer;


    -- Instantiate the Unit Under Test (UUT)
   uut: entity work.comparator PORT MAP (
          a => a,
          b => b,
          a_eq_b => a_eq_b,
          a_le_b => a_le_b,
          a_gt_b => a_gt_b

   -- Stimulus process
   stim_proc: process
        for i in 0 to 8 loop
            for j in 0 to 8 loop
                a <= to_unsigned(i,3); --integer to unsigned type conversion
                b <= to_unsigned(j,3);
                wait for 10 ns;
            end loop;
        end loop;  
   end process;


A part of the simulation waveform is given below:

Note:- For viewing the full results simulate the program yourself. The code was tested using Xilinx ISE 12.1 version. But it will work with almost all the compilers.The code is also synthesisable.


  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.

  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.

  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';
    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;

  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

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

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