You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

151 lines
4.4 KiB

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;