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;
|
|
|