library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

---------------------------------------------------------------------------------------------------------
--                              INPUT / OUTPUT
---------------------------------------------------------------------------------------------------------
entity LiFi_Receiver_Top is
generic(
    INFREQ          :       integer := 100_000_000;
    samplesPerHalf  :       integer := 1;
    LiFiFreq        :       integer := 3_000 -- 3 kHz
);
Port (
    clk             :IN     STD_LOGIC;
    RX              :IN     STD_LOGIC;
    
    DataReady       :OUT    STD_LOGIC;
    Data            :OUT    STD_LOGIC_VECTOR(31 downto 0)
);
end LiFi_Receiver_Top;

architecture Behavioral of LiFi_Receiver_Top is
---------------------------------------------------------------------------------------------------------
--                              Components
---------------------------------------------------------------------------------------------------------
component Receiver
generic(
    samplesPerHalf  :     integer := 1
);
Port (
    clk         :IN     STD_LOGIC;
    clkLiFi     :IN     STD_LOGIC;
    RX          :IN     STD_LOGIC;
    
    ResetTmr    :OUT    STD_LOGIC;
    DataReady   :OUT    STD_LOGIC;
    Data        :OUT    STD_LOGIC_VECTOR(31 downto 0)
);
end component;


component clk_div_reset
generic (
    INFREQ                : integer := INFREQ;
    -- In one LiFi clock period, the RX line will be samples 2*samplesPerHalf
    -- and an additional 2 samples are not used (line changes)
    OUTFREQ               : integer := LiFiFreq
);	
Port (
    clk             :IN     STD_LOGIC;
    reset           :IN     STD_LOGIC;
    reset_seen      :OUT    STD_LOGIC;
    clkOut          :OUT    STD_LOGIC
);
end component;

---------------------------------------------------------------------------------------------------------
--                              Signals 
---------------------------------------------------------------------------------------------------------
signal clkLiFi          : STD_LOGIC;
signal clkLiFiInvert    : STD_LOGIC;
signal resetDivider     : STD_LOGIC;

begin


clkLiFiInvert <= not clkLiFi;

decoder: Receiver
Port map(
    clk         => clk,
    clkLiFi     => clkLiFiInvert,
    RX          => RX,
    
    ResetTmr    => resetDivider,
    DataReady   => DataReady,
    Data        => Data
);

clockGenerator: clk_div_reset
Port map(
    clk             => clk,
    reset           => resetDivider,
    reset_seen      => open,
    clkOut          => clkLiFi
);

end Behavioral;
