library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library UNISIM;
use UNISIM.Vcomponents.ALL;

use work.wishbone_pkg.all;

entity svec_wr2rf_rftrigger is
   
   port (
      --  System clock (125Mhz or 62.5Mhz)
      clk_sys_i         : in     std_logic;
      --  Systen reset clock (> 50ns)
      rst_sys_i         : in     std_logic;

      --  Reference clock for io delays
      clk_refclk_200m_i : in     std_logic;

      --  Wishbone interface, uses clk_sys.
      wb_i              : in     t_wishbone_slave_in;
      wb_o              : out    t_wishbone_slave_out;

      --  Pulse from the Reset/sync logic.
      rf_t1_sync_i      : in     std_logic;
      -- rf_sync_p_o     : inout  std_logic;
      -- rf_sync_n_o     : inout  std_logic;

      rf_t1_clk_p_i     : in     std_logic;
      rf_t1_clk_n_i     : in     std_logic;
      rf_t1_o           : out    std_logic;
--      rf_t1_p_o         : inout  std_logic;
--      rf_t1_n_o         : inout  std_logic;
      rf_t1_rst_p_o     : out    std_logic;
      rf_t1_rst_n_o     : out    std_logic;
      rf_t1_start_i     : in     std_logic; --  Asynchronous tmg inputs.
      rf_t1_stop_i      : in     std_logic; --  Asynchronous tmg inputs.

      rf_t2_sync_i      : in     std_logic;      
      rf_t2_clk_p_i     : in     std_logic; 
      rf_t2_clk_n_i     : in     std_logic; 
--      rf_t2_p_o         : inout  std_logic;
--      rf_t2_n_o         : inout  std_logic;
      rf_t2_o           : out    std_logic;
      rf_t2_rst_p_o     : out    std_logic;
      rf_t2_rst_n_o     : out    std_logic;
      rf_t2_start_i     : in     std_logic; --  Asynchronous tmg inputs.
      rf_t2_stop_i      : in     std_logic; --  Asynchronous tmg inputs.

      rf_clk_bufg_o     : out    std_logic );
      
end entity;

architecture rtl of svec_wr2rf_rftrigger is

   signal rf_t1_clk                : std_logic;
--   signal rf_t1_clk_bufg         : std_logic;
   signal rf_t1_clk_bufio     : std_logic;
    
   signal rf_t1_clk_div            : std_logic;
   signal rf_t1_clk_div_bufg       : std_logic;
   signal rf_t1_clk_div_bufio      : std_logic;   
   signal rf_t1_serdesstrobe  : std_logic;
 
   signal rf_t1_in                 : std_logic_vector(0 downto 0);
   signal rf_t1_in_by8             : std_logic_vector(7 downto 0);
   signal rf_t1_out                : std_logic_vector(0 downto 0);
   signal rf_t1_fb                 : std_logic;
   signal rf_t1_stop_r             : std_logic;
   signal rf_t1_stop_h             : std_logic;
   signal rf_t1_start_r            : std_logic;
   signal rf_t1_start_h            : std_logic;   
   signal rf_t1_stopped            : std_logic;
   signal rf_t1_stopped_r          : std_logic;
   signal rf_t1_stop_start         : std_logic_vector(7 downto 0);

   signal rf_t2_clk                : std_logic;
   signal rf_t2_clk_bufg           : std_logic;
   signal rf_t2_clk_bufio          : std_logic;   
   signal rf_t2_clk_div            : std_logic;
   signal rf_t2_clk_div_bufg       : std_logic;
   signal rf_t2_clk_div_bufio      : std_logic;   
   signal rf_t2_serdesstrobe       : std_logic;          
   signal rf_t2_in                 : std_logic_vector(0 downto 0);   
   signal rf_t2_in_by8             : std_logic_vector(7 downto 0);
   signal rf_t2_out                : std_logic_vector(0 downto 0);   
   signal rf_t2_stop_r             : std_logic;
   signal rf_t2_stop_h             : std_logic;
   signal rf_t2_start_r            : std_logic;
   signal rf_t2_start_h            : std_logic;   
   signal rf_t2_stopped            : std_logic;
   signal rf_t2_stopped_r          : std_logic;
   signal rf_t2_stop_start         : std_logic_vector(7 downto 0);   
   
begin

   -- rf_t1_clk structure
   rf_t1_clk_ibufds_i: ibufds
      port map(
         O   => rf_t1_clk, 
         I   => rf_t1_clk_p_i,
         IB  => rf_t1_clk_n_i );

   -- Set up the clock for use in the serdes
   rf_t1_right_bufio2_i : bufio2
      generic map (
         DIVIDE_BYPASS => FALSE,
         I_INVERT      => FALSE,
         USE_DOUBLER   => FALSE,
         DIVIDE        => 8 )
      port map (
         DIVCLK       => rf_t1_clk_div_bufio,
         IOCLK        => rf_t1_clk_bufio,
         SERDESSTROBE => rf_t1_serdesstrobe,
         I            => rf_t1_clk );

   -- Buffer up the divided clock
   rf_t1_clk_div_bufg_i : bufg
      port map (
         I => rf_t1_clk_div_bufio,
         O => rf_t1_clk_div_bufg );
   
   rf_t1_in(0) <= rf_t1_sync_i;   
   rf_t1_clk_iserdes_i : entity work.rf_iserdes_1to8
      port map (
         data_in_from_pins_i    => rf_t1_in,
         data_in_to_device_o    => rf_t1_in_by8,
         clk_in_i               => rf_t1_clk_bufio,
         clk_div_i              => rf_t1_clk_div_bufg,
         serdesstrobe_i         => rf_t1_serdesstrobe,
         io_reset_i             => '0' );

   rf_t1_stopped    <= '1'             when rf_t1_stop_h  = '1' else
                       '0'             when rf_t1_start_h = '1' else rf_t1_stopped_r;  
   rf_t1_stop_start <= (others => '0') when rf_t1_stopped = '1' else rf_t1_in_by8;
                       
   rf_t1_oserdes_i     : entity work.rf_oserdes_8to1
      port map (
         data_out_from_device_i => rf_t1_stop_start,
         data_out_to_pins_o     => rf_t1_out,
         clk_in_i               => rf_t1_clk_bufio,
         clk_div_i              => rf_t1_clk_div_bufg,
         serdesstrobe_i         => rf_t1_serdesstrobe,
         io_reset_i             => '0' );   

   process (rf_t1_clk_div_bufg) is
   begin
      if rising_edge(rf_t1_clk_div_bufg) then
         rf_t1_stop_r    <= rf_t1_stop_i;
         rf_t1_stop_h    <= rf_t1_stop_r;
         rf_t1_start_r   <= rf_t1_start_i;
         rf_t1_start_h   <= rf_t1_start_r;         
         rf_t1_stopped_r <= rf_t1_stopped;
      end if;
   end process;

   -- outputs t1
   rf_t1_o <= rf_t1_out(0);

   -- CHAIN !
   rf_t2_in(0) <= rf_t2_sync_i;      
   
   -- second channel.
   rf_t2_clk_ibufds_i: ibufds
      port map(
         O   => rf_t2_clk, 
         I   => rf_t2_clk_p_i,
         IB  => rf_t2_clk_n_i );

   -- Set up the clock for use in the serdes
   rf_t2_bufio2_i : bufio2
      generic map (
         DIVIDE_BYPASS => FALSE,
         I_INVERT      => FALSE,
         USE_DOUBLER   => FALSE,
         DIVIDE        => 8 )
      port map (
         DIVCLK       => rf_t2_clk_div_bufio,
         IOCLK        => rf_t2_clk_bufio,
         SERDESSTROBE => rf_t2_serdesstrobe,
         I            => rf_t2_clk );

   -- Buffer up the divided clock
   rf_t2_clk_div_bufg_i : bufg
      port map (
         I => rf_t2_clk_div_bufio,
         O => rf_t2_clk_div_bufg );
      
   rf_t2_clk_iserdes_i : entity work.rf_iserdes_1to8
      port map (
         data_in_from_pins_i    => rf_t2_in,
         data_in_to_device_o    => rf_t2_in_by8,
         clk_in_i               => rf_t2_clk_bufio,
         clk_div_i              => rf_t2_clk_div_bufg,
         serdesstrobe_i         => rf_t2_serdesstrobe,
         io_reset_i             => '0' );

   rf_t2_stopped    <= '1'             when rf_t2_stop_h  = '1' else
                       '0'             when rf_t2_start_h = '1' else rf_t2_stopped_r;  
   rf_t2_stop_start <= (others => '0') when rf_t2_stopped = '1' else rf_t2_in_by8;

   process (rf_t2_clk_div_bufg) is
   begin
      if rising_edge(rf_t2_clk_div_bufg) then
         rf_t2_stop_r    <= rf_t2_stop_i;
         rf_t2_stop_h    <= rf_t2_stop_r;
         rf_t2_start_r   <= rf_t2_start_i;
         rf_t2_start_h   <= rf_t2_start_r;         
         rf_t2_stopped_r <= rf_t2_stopped;
      end if;
   end process;
                                
   rf_t2_oserdes_i     : entity work.rf_oserdes_8to1
      port map (
         data_out_from_device_i => rf_t2_stop_start,
         data_out_to_pins_o     => rf_t2_out,
         clk_in_i               => rf_t2_clk_bufio,
         clk_div_i              => rf_t2_clk_div_bufg,
         serdesstrobe_i         => rf_t2_serdesstrobe,
         io_reset_i             => '0' );

   -- outputs t2
   rf_t2_o       <= rf_t2_out(0);
   rf_clk_bufg_o <= rf_t1_clk_div_bufg;

end architecture;
