Thursday, June 6, 2013

Step 2: Designing Combinatorial Circuit for Magnitude Comparator of two 4-bit numbers

I wrote code for 4 bit magnitude comparator today in VHDL and ran it through simulation. The VHDL code is straight forward and it a combinatorial circuit.

The equation for this taken from Morris Mano

magcomp.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity magcomp is
port 
(
  A : in std_logic_vector(3 downto 0);
  B : in std_logic_vector(3 downto 0);
  greater : out std_logic
);
end magcomp;

architecture Behavioral of magcomp is
  signal a3 : std_logic;
  signal x3 : std_logic;
  signal a2 : std_logic;
  signal x2 : std_logic;
  signal a1 : std_logic;
  signal x1 : std_logic;
  signal a0 : std_logic;
  signal x0 : std_logic;
begin

 a3 <= A(3) and not B(3);
 a2 <= A(2) and not B(2);
 a1 <= A(1) and not B(1);
 a0 <= A(0) and not B(0);
 
 x3 <= (a(3) and b(3)) or (not a(3) and not b(3));
 x2 <= (a(2) and b(2)) or (not a(2) and not b(2));
 x1 <= (a(1) and b(1)) or (not a(1) and not b(1));
 x0 <= (a(0) and b(0)) or (not a(0) and not b(0));
 
 greater <= a3 or (x3 and a2) or (x3 and x2 and a1) or (x3 and x2 and x1 and a0);

end Behavioral;



tb_magcomp.vhd
library ieee;
use ieee.std_logic_1164.all;
use IEEE.Std_Logic_Unsigned.all ;
use IEEE.Std_Logic_Arith.all;
use ieee.numeric_std;

use work.magcomp_pkg.all;
entity tb_magcomp is
end tb_magcomp;

architecture Test of tb_magcomp is
-- Declare/Import DUT

-- Declare Internal Signals which act as Input and Output to DUT
  signal clk : std_logic;     --- clock driver signal
  signal A : std_logic_vector(3 downto 0):=(others => '0');
  signal B : std_logic_vector(3 downto 0):=(others => '0');
  signal greater : std_logic:='0';
  signal expout: std_logic;
  constant period : time := 10 ns;
  constant update : time := 1 ns;

--Start of Test Bench
begin

-- Define the Clock required for simulation --

testbenchclk : process
  
begin
  clk <= '0';
  wait for period / 2;
  clk <= '1';
  wait for period / 2;
end process testbenchclk;

-- Instantiate DUT -----
dut:component magcomp
  port map(A       => A,
         B       => B,
         greater => greater);
-- Create Stimulus Signal  ---
stim : process

begin
wait for 0 ns;
for i in 0 to 15 loop
  A<= CONV_STD_LOGIC_VECTOR(i,4);
  for j in 0 to 15 loop
    B <= CONV_STD_LOGIC_VECTOR(j,4);
    wait for 0 ns;
        
    if (a>b) then
      expout <= '1';
      else
      expout <= '0';
    end if;
    wait for update;
    assert(greater = expout) report "incorrect answer" &"A="& integer'image(CONV_INTEGER(unsigned(a)))&"and B=" &integer'image(CONV_INTEGER(unsigned(a))) severity error;
    wait for period;
  end loop;
end loop;
wait;
--test
end process stim;

--End of Test Bench --
end architecture Test;


Note: 

a) Delta Clock Cycle:
wait for 0 ns in the loop. Wait statement is when all the concurrent signals will be updated by the simulator. This is called delta cycle. If you want values to be updated instantaneously inside the process, use variables instead of concurrent assignments when possible. without wait for 0ns, (a>b) will use old a,b values and will result in mismatch between expected result and output result

b) std_logic vector to string: 
It was very hard to print the actual values of std_logic_vector whenever there was a failure. std_logic_vector had to be converted to integer and then converted to string using image. In upcoming exercises, I plan to create a testbench_packages which will have functions to convert std_logic_vector to strings. There were lots of examples on the web and I plan to combine them into package.

No comments:

Post a Comment