----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    16:29:18 05/02/2021 
-- Design Name: 
-- Module Name:    pn_test - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity pn_test is
    Port ( clk 		: in  STD_LOGIC;		-- zdrojom je TCXO oscilator
           pps 		: in  STD_LOGIC;		-- pulse per second z GNSS prijmacu
			  pps_out	: out	STD_LOGIC;		-- testovaci vystup
           output 	: out STD_LOGIC);		-- výstupný datový tok
end pn_test;



architecture Behavioral of pn_test is

signal div_p					: std_logic := '0';			-- použité pre delenie kmitoctu
signal div_n					: std_logic := '0';			-- použité pre delenie kmitoctu

signal pn 						: std_logic_vector(31 downto 0) := "01010111011000111110011010010000"; -- predpripravena PN postupnosť
signal msg_cnt					: std_logic_vector(4 downto 0) := "00000";		-- urcuje ktory bit sa posiela
signal cycle_step				: std_logic_vector(6 downto 0) := "0000000";		-- je rovny trvaniu 2 us
signal cycle_cnt				: std_logic_vector(8 downto 0) := "000000000";	-- pocita cycle_step, 500 = 1 ms
signal sec_cnt					: std_logic_vector(9 downto 0) := "0000000000";	-- pocita milisekundy do 1000, tj. do jednej sekundy
signal pps_on 					: std_logic	:= '0';			-- pomocna logika proti zacykleniu
signal pps_off					: std_logic	:= '0';			-- pomocna logika proti zacykleniu
signal cor						: std_logic_vector(6 downto 0) := "0100000";		-- premenna pre korekciu kmitoctovej odchylky a driftu
signal corr_switch			: std_logic;					-- pomocna logika proti zacykleniu

begin

process(clk, pps)
begin

if(clk'event and clk = '1') then
	if(div_p = '1') then
		div_p <= not div_p;
	else
		div_p <= not div_p;
	if(pps_on = '1') then
		cycle_cnt <= "000000000";
		sec_cnt <= "0000000000";
		corr_switch <= '1';
		if(unsigned(cycle_step) > 24) then	-- počet taktov na jednu/2 us 
			if(unsigned(cor) < 47) then		-- počet taktov na dve/2 us - 1
				cor <= cor + 1;
			end if;
			cycle_step <= "0000000";
		else
			if(unsigned(cor) > 0) then
				cor <= cor - 1;
			end if;
			
			cycle_step <= "0000000";
		end if;
	elsif(unsigned(cycle_step) =  47) then	-- počet taktov na dve/2 us - 1
		cycle_step <= "0000000";
		if(unsigned(cycle_cnt) = 499) then
			corr_switch <= '1';
			cycle_cnt <= "000000000";
			if(unsigned(sec_cnt) = 999) then
				pps_out <= '1';
				sec_cnt <= "0000000000";
			else
				sec_cnt <= sec_cnt + 1;
			end if;
		else
			if((unsigned(cycle_cnt) > 200) and (unsigned(cycle_cnt) < 233)) then
				cycle_cnt <= cycle_cnt + 1;
				output <= pn(to_integer(unsigned(msg_cnt)));
			elsif((unsigned(cycle_cnt) > 232) and (unsigned(cycle_cnt) < 243)) then
				cycle_cnt <= cycle_cnt + 1;
				output <= sec_cnt(to_integer(unsigned(msg_cnt)));
			else
				cycle_cnt <= cycle_cnt + 1;
				output <= '0';
			end if;
		end if;
	elsif((unsigned(cycle_step) = 12) and (unsigned(cycle_cnt) = 499) and (unsigned(sec_cnt) = 499) and (corr_switch = '1')) then
		cycle_step(5 downto 0) <= cor(5 downto 0);
		pps_out <= '0';
		corr_switch <= '0';
	else
		cycle_step <= cycle_step + 1;
	end if;
	
	end if;
end if;

if(clk'event and clk = '0') then
	if(div_n = '1') then
		div_n <= not div_n;
	else
		div_n <= not div_n;
	if(unsigned(cycle_step) = 0) then
		if((unsigned(cycle_cnt) = 0) or (unsigned(cycle_cnt) = 233)) then
			msg_cnt <= "00000";
		elsif((unsigned(cycle_cnt) > 201) and (unsigned(cycle_cnt) < 233)) then
			msg_cnt <= msg_cnt + 1;
		elsif((unsigned(cycle_cnt) > 233) and (unsigned(cycle_cnt) < 243)) then
			msg_cnt <= msg_cnt + 1;
		end if;
	end if;
	
	if((pps = '1') and (pps_on = '0') and (pps_off = '1')) then
		pps_on <= '1';
		pps_off <= '0';
	elsif(pps = '0') then
		pps_off <= '1';
	else
		pps_on <= '0';
	end if;
	end if;
end if;


end process;
end Behavioral;

