library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;


--xc9500xl has 5 volt tolerant inputs

entity counta is

--TODO: figure out how to get XSTALIN as GCK (see also fitter report (text))
  PORT( XSTALIN  : in  STD_LOGIC; -- semi colons
        HZIN     : in  STD_LOGIC; -- here
        LED      : out STD_LOGIC_VECTOR(7 downto 0); -- commas in instance       
        TX       : out STD_LOGIC --last one, no semi colon
		 
                  );
end counta;

architecture Behavioral of counta is

-- 2 to the power of 20 is about 1million
-- gives me 600KHz resolution. Good enough.
-- any more would run into limitations of cpld.
-- EDIT: ran into limits
-- now trying 12 + 1 bits, or about upper limit of 6,000
   --signal 
	signal clkcounta        : STD_LOGIC_VECTOR(12 DOWNTO 0) := (others => '0');
   --signal testhzctr        : STD_LOGIC_VECTOR(9 downto 0) := (others => '0');
   signal storecounta      : STD_LOGIC_VECTOR(18 DOWNTO 0) := (others => '0');
	signal alreadystoredcnt : STD_LOGIC_VECTOR(0 downto 0)  := "0";
	signal uartnow          : STD_LOGIC_VECTOR(0 downto 0)  := "0";
	signal uartctr          : STD_LOGIC_VECTOR(4 downto 0)  := "00000";
	signal waitnow          : STD_LOGIC_VECTOR(0 downto 0)  := "0";
	signal resetclk         : STD_LOGIC_VECTOR(0 downto 0)  := "0";
	signal uartskip         : STD_LOGIC_VECTOR(0 downto 0)  := "0";
	signal ORvalforstore    : STD_LOGIC_VECTOR(2 downto 0)  := "111";
begin


--outside of process



TX <= storecounta(0);

LED(5 downto 0) <= storecounta(12 downto 7);
LED(6) <= uartnow(0);
LED(7) <= waitnow(0);
--sanity check that leds / switch is working
--LED(7) <= switch;

mycounta: process (XSTALIN)
        begin
        if rising_edge(XSTALIN) then
		  
  clkcounta <= clkcounta + 1;
  
  --testing clock
  --EDIT: below not necessary, as register is already 
  -- wrapping around after getting to 255/256
--  if clkcounta > 250 then
--     clkcounta <= (others => '0');
--  
--  end if;

--MAIN

	--shift value out via uart
	--(because this is a 6KHz clock, won't be too fast)
	if uartnow(0) = '1' then
	  storecounta <= '1' & storecounta(18 downto 1); --should be down to 1, not 0
		--NOTE: because this goes down to 1, 0 is always low
		--which in uart would be start bit, I THINK........
	end if;
		
		--upon 1hz trigger, and not stored val yet
		-- (1hz trigger, is 1hz square wave)
		
  if HZIN = '1' and alreadystoredcnt(0) = '0' then  
	   --store clk val in register
		storecounta(15 downto 3) <= clkcounta;
	   --don't store it again
	   alreadystoredcnt(0) <= '1';
		--reset counter
		resetclk(0) <= '1';
		--remember, everything in if statement happens all at once
  elsif resetclk(0) = '1' then
      clkcounta <= (others => '0');
		resetclk(0) <= '0';
		--frame bits to identify where i am
      storecounta(18) <= '0';
		storecounta(17) <= '0';
      storecounta(16) <= '1';
		--data goes from 3 - 15, 3,4,5,6,7, 8,9,10,11,12, 13,14,15
		--12+1 bits
		storecounta(0) <= '0';
		storecounta(1) <= '0';
      storecounta(2) <= '1';
  elsif alreadystoredcnt(0) = '1' and waitnow(0) = '0' and uartskip(0) = '0' then
      --enable uart
      uartnow(0) <= '1';
		--without this skip, otherwise we get stuck here
		uartskip(0) <= '1';
		
  elsif uartnow(0) = '1' and uartctr(4 downto 0) = "11111" then
      --disable uart
		uartnow(0) <= '0';
		uartctr <= (others => '0');
		--don't do this and don't enable uart above, and don't count
		waitnow(0) <= '1';
		
  elsif alreadystoredcnt(0) = '1' and waitnow(0) = '0' and uartskip(0) = '1' and uartnow(0) = '1'then
		uartctr <= uartctr + 1;
		--this must be after the above, otherwise we get stuck in it
		
  elsif HZIN = '0' and alreadystoredcnt(0) = '1' and waitnow(0) = '1' and uartskip(0) = '1' and uartnow(0) = '0' then
      --reset storedcounter
		alreadystoredcnt(0) <= '0';
	   --only do this once
		storecounta <= (others => '1'); --idle high in uart
		waitnow(0) <= '0';
		uartskip(0) <= '0';
		

  end if;

  
--using 6MHz clk
--count as far as possible, every 1 second pulse
--from 60hz divider
--at pulse, display count, then start over
 -- if HZIN = '1' and hzinhighflag(0) = '0' then
	   --display value on leds
		--todo
		
		--start counter over
	--	clkcounta <= (others => '0');
		--don't do anything until hz is low
	--	hzinhighflag(0)  <= '1';
	  --end if;
  --end if;
--EDIT: cpld has limitations, therefore lowering register sizes
  


end if; --  main rising clk process end
        end process;
		  
end Behavioral;

