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

Saturday, December 5, 2020

Generic VHDL Code for Binary to Gray and Gray to Binary converter

    Few years back I had written a 4 bit converter for conversion between Gray and Binary codes. After receiving much positive response I decided to write a generic version of the same.

Let me share the codes...

Binary to Gray Code Converter:


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity bin2gray is
    generic(N : integer := 4);
port(   bin : in std_logic_vector(N-1 downto 0);  --binary input
        G : out std_logic_vector(N-1 downto 0)  --gray code output
        );
end bin2gray;

architecture gate_level of bin2gray is 

begin

G(N-1) <= bin(N-1);
--generate xor gates.
xor_gates : for i in N-2 downto 0 generate
    G(i) <= bin(i+1xor bin(i);
end generate;    

end;


Gray Code to Binary Converter:


LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity gray2bin is
    generic(N : integer := 4);
port(   G : in std_logic_vector(N-1 downto 0);    --gray code input
        bin : out std_logic_vector(N-1 downto 0)  --binary output
        );
end gray2bin;

architecture gate_level of gray2bin is 

signal temp : std_logic_vector(N-1 downto 0);

begin

temp(N-1) <= G(N-1);
--generate xor gates.
xor_gates : for i in N-2 downto 0 generate
    temp(i) <= temp(i+1xor G(i);
end generate;    

bin <= temp;

end;

Testbench:


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity tb is
end tb;
 
architecture behavior of tb is 
 
    -- component declaration for the unit under test's (uut) 
component bin2gray is
    generic(N : integer := 4);
port(   bin : in std_logic_vector(N-1 downto 0);  --binary input
        G : out std_logic_vector(N-1 downto 0)  --gray code output
        );
end component;

component gray2bin is
    generic(N : integer := 4);
port(   G : in std_logic_vector(N-1 downto 0);    --gray code input
        bin : out std_logic_vector(N-1 downto 0)  --binary output
        );
end component;

constant N : integer := 16;  --Change this to control the number of bits in the input/output.
signal bin,g,bin_out : std_logic_vector(N-1 downto 0) := (others => '0');
signal error : integer := 0
begin
    -- Both the converters are connected back to back to see the binary input going to the
    --first entity is the same as the output coming out of the second entity.
   uut1: bin2gray generic map (N => N) port map (
          bin => bin,
          g => g
        );
 
   uut2: gray2bin generic map (N => N) port map (
          g => g,
          bin => bin_out
        );
          
   -- stimulus process
   --this tests for all the input combinations.
   stim_proc: process
   begin        
        for i in 0 to 2**N-1 loop   --loop through all the  available inputs 
            bin <= std_logic_vector(to_unsigned(i,N)); --convert integer to std_logic_vector.
            wait for 5 ns;
             --Count the number of errors. Should be zero at the end of simulation.
            if(bin /= bin_out) then 
                error <= error + 1;
            end if;
            wait for 5 ns;
        end loop;    
        wait;
   end process;

end;


The codes were tested using Modelsim 10.4a version. Simply change the value of the constant 'N' in the testbench to test for different sized converters.


Saturday, October 28, 2017

4 bit Binary to Gray code and Gray code to Binary converter in VHDL


UPDATE : A GENERIC VERSION OF THE CODE IS AVAILABLE HERE!



Gray codes are non-weighted codes, where two successive values differ only on one bit. Through this post, I want to share two simple gate level VHDL codes for converting binary number to Gray and vice versa.

Logic circuit for 4 bit Binary to Gray code converter:


Logic circuit for 4 bit Gray code to Binary converter:


VHDL Code for Binary to Gray code conversion:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity bin2gray is
port(   bin : in std_logic_vector(3 downto 0);  --binary input
        G : out std_logic_vector(3 downto 0)  --gray code output
        );
end bin2gray;

architecture gate_level of bin2gray is 

begin

--xor gates.
G(3) <= bin(3);
G(2) <= bin(3) xor bin(2);
G(1) <= bin(2) xor bin(1);
G(0) <= bin(1) xor bin(0);

end;

VHDL Code for Gray code to Binary conversion:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

entity gray2bin is
port(   G : in std_logic_vector(3 downto 0);    --gray code input
        bin : out std_logic_vector(3 downto 0)  --binary output
        );
end gray2bin;

architecture gate_level of gray2bin is 

begin

--xor gates.
bin(3) <= G(3);
bin(2) <= G(3) xor G(2);
bin(1) <= G(3) xor G(2) xor G(1);
bin(0) <= G(3) xor G(2) xor G(1) xor G(0);

end;

Single Testbench for both the designs:

library ieee;
use ieee.std_logic_1164.all;
 
entity tb is
end tb;
 
architecture behavior of tb is 
 
    -- component declaration for the unit under test's (uut) 
component bin2gray is
    port(   bin : in std_logic_vector(3 downto 0);
            g : out std_logic_vector(3 downto 0)
            );
end component;

component gray2bin is
port(   g : in std_logic_vector(3 downto 0);
        bin : out std_logic_vector(3 downto 0)
        );
end component;

signal bin,g,bin_out : std_logic_vector(3 downto 0) := (others => '0');
 
begin
    -- instantiate the unit under test's (uut)
   uut1: bin2gray port map (
          bin => bin,
          g => g
        );
 
   uut2: gray2bin port map (
          g => g,
          bin => bin_out
        );
          
   -- stimulus process
   stim_proc: process
   begin        
        bin <= "0000";    wait for 10 ns;
        bin <= "0001";  wait for 10 ns;
        bin <= "0010";  wait for 10 ns;
        bin <= "0011";  wait for 10 ns;
        bin <= "0100";    wait for 10 ns;
        bin <= "0101";  wait for 10 ns;
        bin <= "0110";  wait for 10 ns;
        bin <= "0111";  wait for 10 ns;
        bin <= "1000";    wait for 10 ns;
        bin <= "1001";  wait for 10 ns;
        bin <= "1010";  wait for 10 ns;
        bin <= "1011";  wait for 10 ns;
        bin <= "1100";    wait for 10 ns;
        bin <= "1101";  wait for 10 ns;
        bin <= "1110";  wait for 10 ns;
        bin <= "1111";  wait for 10 ns;     
      wait;
   end process;

end;

Simulation Waveform:

The code was simulated using Xilinx ISE 14.6 tool. The following waveform verifies the correctness of both the designs. The output of binary to gray entity is connected as input of gray to binary converter. As you can see the bin and bin_out signals are the same. This verifies that the codes are working well.


Do you notice a pattern in how the output bits are calculated. What do you think of of an n-bit converter? For learning purposes, try implementing an n-bit version of the above designs.