-----------------------------------------------------------------------------------------------------
--File: diplayoutput
--Author: 	Robert Ross (c) 2004
--Purpose: 	Outputs the integers over 8 7-segment displays
--Inputs:	
--	clk1MHz:	A 1Mhz Clock input
--	LEDDsp1: 	MSD integer to display normally hoursMSD
--	LEDDsp2: 	integer to display normally hoursLSD
--	LEDDsp3: 	integer to display normally MinutesMSD (ON display board)
--	LEDDsp4: 	integer to display normally minutesLSD (ON display board)
--	LEDDsp5: 	integer to display normally secondsMSD (ON display board)
--	LEDDsp6: 	integer to display normally secondsLSD (ON display board)
--	LEDDsp7: 	integer to display normally ms MSD 	   (ON display board)
--	LEDDsp8:  	LSD integer to display normally ms LSD (ON display board)
--	LEDOn: 	  	8 bits each symoblising a Digit. if 1 then digit is lit up
--	LEDFlash:	8 bits each symoblising a Digit. if 1 then digit will flash
--Outputs:	
--	LEDDsp1Out: the output directly for the MSD on the normal board
--	LEDDsp2Out: the output directly for the LSD on the normal board
--	clkOut: This is the output clock for displaying data to the display board
--	dataOut: This provides the data for the display board
-----------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity displayOutput is port(
	clk1MHz: in std_logic;							--should be a 1Mhz Clock
	LEDDsp1: in integer range 0 to 9;				--normally hoursMSD
	LEDDsp2: in integer range 0 to 9;				--normally hoursLSD
	LEDDsp3: in integer range 0 to 9;				--normally MinutesMSD
	LEDDsp4: in integer range 0 to 9;				--normally minutesLSD
	LEDDsp5: in integer range 0 to 9;				--normally secondsMSD
	LEDDsp6: in integer range 0 to 9;				--normally secondsLSD
	LEDDsp7: in integer range 0 to 9;				--normally ms MSD
	LEDDsp8: in integer range 0 to 9;				--normally ms LSD
	LEDOn: 	 in std_logic_vector(7 downto 0); 		--8 bits each symoblising a Digit. if 1 then digit is lit up
	LEDFlash: in std_logic_vector(7 downto 0);		--8 bits each symoblising a Digit. if 1 then digit will flash
	LEDDsp1Out: out std_logic_vector(7 downto 0);	--the first display (not on expansion board)
	LEDDsp2Out: out std_logic_vector(7 downto 0);	--the second display (not on expansion board)
	strobeOut: out std_logic_vector(5 downto 0);	-- 0 is MSD
	dataOut: out std_logic_vector(7 downto 0));  	-- 0 is the decimal point
end displayOutput;

architecture arch of displayOutput is
	signal mod18Counter: integer range 0 to 17;
	signal tempDataOut: std_logic_vector(7 downto 0);
	signal dp: std_logic;
	signal tempInput: integer range 0 to 9; -- 0 to 9 are normal values, when 10 is input nothing should be displayed
	signal dpPara: std_logic;
	signal LEDDsp1Temp: integer range 0 to 10;	
	signal LEDDsp2Temp: integer range 0 to 10;
	signal flashCount: integer range 0 to 100000;
component int2display port(
	int		:	in integer range 0 to 9;
	decimalP:	in std_logic;
	display	:	out std_logic_vector(7 downto 0));
end component;

begin
--cycle through all 18 counts of the counter
	runCounter:process(clk1MHz)
	begin
		if (clk1MHz'event and clk1MHz = '1') then
			if (flashCount > 80000) then
				if (flashCount /= 100000) then
					flashCount <= flashCount + 1;
				else
					flashCount <= 0;
				end if;
				if (LEDOn(7) = '1' AND LEDFlash(7) = '0') then LEDDsp1Temp <= LEDDsp1; else LEDDsp1Temp <= 10; end if;
				if (LEDOn(6) = '1' AND LEDFlash(6) = '0') then LEDDsp2Temp <= LEDDsp2; else LEDDsp2Temp <= 10; end if;
				case mod18Counter is
					when 2 => dp <= '0'; if (LEDOn(4) = '1' AND LEDFlash(4) = '0') then tempInput <= LEDDsp4; else tempInput <= 10; end if; --will make sure the display shows nothing if required.
					when 5 => dp <= '1'; if (LEDOn(3) = '1' AND LEDFlash(3) = '0') then tempInput <= LEDDsp5; else tempInput <= 10; end if;
					when 8 => dp <= '0'; if (LEDOn(2) = '1' AND LEDFlash(2) = '0') then tempInput <= LEDDsp6; else tempInput <= 10; end if;
					when 11 => dp <= '1'; if (LEDOn(1) = '1' AND LEDFlash(1) = '0') then tempInput <= LEDDsp7; else tempInput <= 10; end if;
					when 14 => dp <= '0'; if (LEDOn(0) = '1' AND LEDFlash(0) = '0') then tempInput <= LEDDsp8; else tempInput <= 10; end if;
					when 16 => dp <= '1'; if (LEDOn(5) = '1' AND LEDFlash(5) = '0') then tempInput <= LEDDsp3; else tempInput <= 10; end if;
					when others => dp <= dp;
				end case;
			else
				flashCount <= flashCount + 1;
				if (LEDOn(7) = '1') then LEDDsp1Temp <= LEDDsp1; else LEDDsp1Temp <= 10; end if;
				if (LEDOn(6) = '1') then LEDDsp2Temp <= LEDDsp2; else LEDDsp2Temp <= 10; end if;
				case mod18Counter is
					when 2 => dp <= '0'; if (LEDOn(4) = '1') then tempInput <= LEDDsp4; else tempInput <= 10; end if; --will make sure the display shows nothing if required.
					when 5 => dp <= '1'; if (LEDOn(3) = '1') then tempInput <= LEDDsp5; else tempInput <= 10; end if;
					when 8 => dp <= '0'; if (LEDOn(2) = '1') then tempInput <= LEDDsp6; else tempInput <= 10; end if;
					when 11 => dp <= '1'; if (LEDOn(1) = '1') then tempInput <= LEDDsp7; else tempInput <= 10; end if;
					when 14 => dp <= '0'; if (LEDOn(0) = '1') then tempInput <= LEDDsp8; else tempInput <= 10; end if;
					when 16 => dp <= '1'; if (LEDOn(5) = '1') then tempInput <= LEDDsp3; else tempInput <= 10; end if;
					when others => dp <= dp;
			  	end case;
			end if;
		dpPara <= '0';
			if (mod18Counter = 17) then
				mod18Counter <= 1;
			else
				mod18Counter <= mod18Counter + 1;
			end if;
		end if;
	end process;

--load the tempInput value for several different counts
--	runCounter1:process(clk1MHz)
--	begin
--		if (clk1MHz'event and clk1MHz = '1') then
			
--			case mod18Counter is
--				when 2 => dp <= '0'; if (LEDOn(4) = '1') then tempInput <= LEDDsp4; else tempInput <= 10; end if; --will make sure the display shows nothing if required.
--				when 5 => dp <= '1'; if (LEDOn(3) = '1') then tempInput <= LEDDsp5; else tempInput <= 10; end if;
--				when 8 => dp <= '0'; if (LEDOn(2) = '1') then tempInput <= LEDDsp6; else tempInput <= 10; end if;
--				when 11 => dp <= '1'; if (LEDOn(1) = '1') then tempInput <= LEDDsp7; else tempInput <= 10; end if;
--				when 14 => dp <= '0'; if (LEDOn(0) = '1') then tempInput <= LEDDsp8; else tempInput <= 10; end if;
--				when 16 => dp <= '1'; if (LEDOn(5) = '1') then tempInput <= LEDDsp3; else tempInput <= 10; end if;
--				when others => dp <= dp;
--		  	end case;
--			
--		dpPara <= '0';
--		end if;
--	end process;


	P1: int2display port map(tempInput, dp, tempDataOut);
	P2: int2display port map(LEDDsp1Temp, dpPara, LEDDsp1Out);-- the MSD on normal board
	P3: int2display port map(LEDDsp2Temp, dpPara, LEDDsp2Out);-- the LSD on normal board

dataOut <= tempDataOut; -- put the data to be displayed onto the data lines

--activate the strobe in sequence to display each of the digits
with mod18Counter select
	strobeOut <=	"100000" when 1,--ON output hourMSB	--show 0 for hourMSB
					"000000" when 2,--OFF
	  				"010000" when 4,--ON output hourLSB
					"000000" when 5,--OFf
					"001000" when 7,--ON ouput minuteMSB
					"000000" when 8,--OFF
					"000100" when 10,--ON ouput minuteLSB
					"000000" when 11,--OFF
					"000010" when 13,--ON ouput secondMSB
					"000000" when 14,--OFF
					"000001" when 16,--ON ouput secondLSB
					"000000" when 17,--OFF
					"000000" when others;
end arch;
