-------------------------------------------------------------------------------
--	FILE:			BASYS_7_seg.vhd
--
--	DESCRIPTION:	This design is used to control the 7 segment display on  
--					the BASYS 2 or 3 FPGA development board.
--
-- 	ENGINEER:		Jordan Christman
-------------------------------------------------------------------------------
-- Libraries
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Entity
entity BASYS_7_seg is
generic(
	input_clk_freq	: integer := 100000000;	-- Input clock rate in Hz
	refresh_rate 	: integer := 50000);    -- Refresh rate in Hz
port(
	-- 7 Segment Display Output
	seg 			: out std_logic_vector(6 downto 0);	
	-- 7 Segment Display Decimal Point
	dp				: out std_logic;
    -- Selects Digit	
	an				: out std_logic_vector(3 downto 0);
	-- Input segments 0 through 3
	seg0 			: in std_logic_vector(6 downto 0);
	seg1 			: in std_logic_vector(6 downto 0);
	seg2 			: in std_logic_vector(6 downto 0);
	seg3 			: in std_logic_vector(6 downto 0);
	-- Input decimal points
	in_dp			: in std_logic_vector(3 downto 0);
	-- Input Clock
	clk				: in std_logic);
end BASYS_7_seg;

architecture behavior of BASYS_7_seg is
-------------------------------------------------------------------------------
-- 								Constants
-------------------------------------------------------------------------------
-- 7 Seg display counter mulitply by 4 to take the 4 segments in account
constant maxcount	: integer := (input_clk_freq / refresh_rate) * 4;	

-------------------------------------------------------------------------------
-- 								Signals
-------------------------------------------------------------------------------
-- A 27-bit counter is required to count to 100000000 (100 million/ 100 MHz)
-- we will be counting to 200,000 to achieve a 500Hz refresh rate 
signal counter	: unsigned(26 downto 0) := to_unsigned(0, 27);

-- toggle is used to select which segment is currently being displayed
signal toggle	: std_logic_vector(3 downto 0) := "0111";

-------------------------------------------------------------------------------
-- 					BASYS (2/3) 7 SEGMENT DISPLAY ARCHITECTURE
-------------------------------------------------------------------------------
begin
	-- Anode segment drivers
	an <= toggle;
	
	---------------------------------------------------------------------------
	-- 							COUNTER PROCESS
	---------------------------------------------------------------------------
	-- Counter to create desired multiplexed rate and shift toggle bits
	counter_proc: process(clk)
	begin
		if(rising_edge(clk)) then
			if(counter = maxcount) then
				counter <= (others => '0');
				toggle(0) <= toggle(3);
				toggle(1) <= toggle(0);
				toggle(2) <= toggle(1);
				toggle(3) <= toggle(2);
			else
				counter <= counter + 1;
			end if;
		end if;
	end process counter_proc;	
	
	---------------------------------------------------------------------------
	-- 							TOGGLE PROCESS
	---------------------------------------------------------------------------
	-- Toggle the seven segment displays by selecting the next segments display
	toggle_proc: process(toggle)
	begin
		if(toggle(0) = '0') then
			seg <= seg0;
			dp <= in_dp(0);
		elsif(toggle(1) = '0') then
			seg <= seg1;
			dp <= in_dp(1);
		elsif(toggle(2) = '0') then
			seg <= seg2;
			dp <= in_dp(2);
		else
			seg <= seg3;
			dp <= in_dp(3);
		end if;
	end process toggle_proc;
end behavior;