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;