library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
    
entity gray_counter is
    generic (
        counter_width		: integer := 4
    );
    port (       
		clock_in      		: in	std_logic; 	
        reset_in      		: in	std_logic;
        enable_in     		: in	std_logic; 		   
		binary_count_out	: out	std_logic_vector (counter_width - 1 downto 0);
        gray_count_out		: out	std_logic_vector (counter_width - 1 downto 0)  
    );
end entity gray_counter;

architecture synthesis of gray_counter is
	signal binary_count	: std_logic_vector (counter_width - 1 downto 0);	   
	
	function binary_to_gray( x : std_logic_vector ) return std_logic_vector is
		variable y : std_logic_vector( x'range );  
	begin
		for j in x'range loop
	  		if j = x'left then
	 			y(j) := x(j);
	  		else         
				y(j) := x(j) xor x(j+1);
	  		end if;
		end loop;
		return  y;
	end function binary_to_gray;

begin																	   

    counter : process (clock_in) 
	begin
        if (rising_edge(clock_in)) then
            if (reset_in = '1') then
                binary_count	<= (others => '0');  
                gray_count_out	<= (others => '0');
            elsif (enable_in = '1') then
                binary_count   	<= binary_count + 1;
                gray_count_out 	<= binary_to_gray(binary_count + 1);
            end if;
        end if;
    end process counter;	
	
	binary_count_out <= binary_count;
    
end architecture;
