LIBRARY IEEE;
USE  IEEE.STD_LOGIC_1164.all;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY GrayCounter IS
PORT(	clock, pb1, pb2		: IN std_logic;
		seg_a1, seg_b1, seg_c1, seg_d1, seg_e1, 
		seg_f1, seg_g1 : OUT std_logic;
		code_out			: OUT std_logic_vector(3 DOWNTO 0)
	);
END GrayCounter;

ARCHITECTURE Moore OF GrayCounter IS
	TYPE STATE_TYPE IS (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);

	attribute syn_encoding : string;
	attribute syn_encoding of STATE_TYPE : type is "gray";
	
	SIGNAL state						: STATE_TYPE;
	SIGNAL pb12							: std_logic_vector(1 DOWNTO 0);
	SIGNAL ctrl_clock, slow_clock		: std_logic;
	SIGNAL code							: std_logic_vector(3 DOWNTO 0);

COMPONENT CLK_DIV
PORT(	
	clock_50Mhz				: IN	STD_LOGIC;
	clock_1MHz				: OUT	STD_LOGIC;
	clock_100KHz			: OUT	STD_LOGIC;
	clock_10KHz				: OUT	STD_LOGIC;
	clock_1KHz				: OUT	STD_LOGIC;
	clock_100Hz				: OUT	STD_LOGIC;
	clock_10Hz				: OUT	STD_LOGIC;
	clock_1Hz				: OUT	STD_LOGIC);
END COMPONENT;


COMPONENT dec_7seg 
	PORT(hex_digit				: IN	STD_LOGIC_VECTOR(3 downto 0);
		 segment_a, segment_b, segment_c, segment_d, segment_e, 
		 segment_f, segment_g 	: OUT	std_logic);
END COMPONENT;

BEGIN

-- disable this when doing simulation
clk1: CLK_DIV
port map( clock_50Mhz => clock, clock_1Hz => ctrl_clock);

-- enable this when doing simulation
-- ctrl_clock <= clock;

display: dec_7seg
port map( hex_digit => code, segment_a => seg_a1, segment_b => seg_b1, 
		segment_c => seg_c1, segment_d => seg_d1, segment_e => seg_e1, 
		segment_f => seg_f1, segment_g => seg_g1);

	PROCESS (ctrl_clock)
	BEGIN

		pb12 <= pb1 & pb2;
						
		IF ctrl_clock'EVENT AND ctrl_clock = '1' THEN
			-- Case statement to determine next state
			-- This is what you want to edit. We have left you two states to 
			-- get started. The rest you must figure out. 
			CASE state IS
				WHEN A =>
					CASE pb12 IS
						WHEN "01" => state <= B; -- Up
						WHEN "00" => state <= P; -- Down
						WHEN OTHERS => state <= A;
					END CASE;
				
				WHEN B =>
					CASE pb12 IS
						WHEN "01" => state <= C; -- Up
						WHEN "00" => state <= A; -- Down
						WHEN OTHERS => state <= B;
					END CASE;
				
				-- Complete the remaining state transitions here

			END CASE;
		END IF;
	END PROCESS;

	-- Outputs that depend on state

	WITH state SELECT
		code	<=	"0000"	WHEN A,
					"0001"	WHEN B,

            		-- Complete the remaining output here

	code_out <= code;
		
END Moore;
