
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.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 leaf cells in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity si5332_wrapper is
  port( 
    clk_100_in                            : in  std_logic;                   
    clk_100_areset_in                     : in  std_logic;  

    sda_in                                : in  std_logic;
    sda_out                               : out std_logic;
    sda_t_out                             : out std_logic;

    scl_in                                : in  std_logic;
    scl_out                               : out std_logic;
    scl_t_out                             : out std_logic;

    qsfp2_clk_in                          : in  std_logic;
    qsfp3_clk_in                          : in  std_logic

  );
end entity si5332_wrapper;

architecture imp of si5332_wrapper is

  signal tick_1ms                         : std_logic;

  signal i2c_mux_access_ok                : std_logic;
  signal si5341_access_ok                 : std_logic;
  signal si5341_config_done               : std_logic;
  signal si5341_config_error              : std_logic;

  signal man_clk_gen_en                   : std_logic;
  signal man_clk_gen_cfg_reset            : std_logic;


  signal clk_100_tick_1ms_r               : std_logic_vector(0 to 2) := (others => '0');
  signal clk_100_freq_r                   : std_logic_vector(31 downto 0) := (others => '0');
  signal clk_100_cnt_r                    : std_logic_vector(31 downto 0) := (others => '0');

  signal qsfp2_tick_1ms_r                 : std_logic_vector(0 to 2) := (others => '0');
  signal qsfp2_freq_r                     : std_logic_vector(31 downto 0) := (others => '0');
  signal qsfp2_cnt_r                      : std_logic_vector(31 downto 0) := (others => '0');

  signal qsfp3_tick_1ms_r                 : std_logic_vector(0 to 2) := (others => '0');
  signal qsfp3_freq_r                     : std_logic_vector(31 downto 0) := (others => '0');
  signal qsfp3_cnt_r                      : std_logic_vector(31 downto 0) := (others => '0');



begin


-----------------------------------
  i_si5341_clk_conf : entity work.si5341_clk_configurator 
    port map (   
      sys_clk100_in                          => clk_100_in,
      tick_1ms_in                            => tick_1ms,      

      sda_in                                 => sda_in,                
      sda_out                                => sda_out,                
      sda_t_out                              => sda_t_out,                
                                                                      
      scl_in                                 => scl_in,
      scl_out                                => scl_out,
      scl_t_out                              => scl_t_out,     

      i2c_mux_access_ok_out                  => i2c_mux_access_ok, 
      si5341_access_ok_out                   => si5341_access_ok, 
      si5341_config_done_out                 => si5341_config_done, 
      si5341_config_error_out                => si5341_config_error, 

      man_clk_gen_en_in                      => man_clk_gen_en,
      man_clk_gen_cfg_reset_in               => man_clk_gen_cfg_reset,
      reset_in                               => clk_100_areset_in
    );

  i_tick_gen : entity work.tick_gen
    generic map (
      CLOCK_SPEED_MHZ                       => 100
      ) 
    port map (
      clk_in                                => clk_100_in,

      tick_1us_out                          => open,
      tick_1ms_out                          => tick_1ms,
      tick_500ms_out                        => open,
      tick_750ms_out                        => open,
      tick_1s_out                           => open,

      prog_us_tick_rate_in                  => x"0000_0000",
      prog_us_tick_out                      => open,  

      reset_in                              => clk_100_areset_in   
      );


  i_vio_3 : entity work.vio_3
    port map (
      clk                         => clk_100_in,
      probe_in0(0)                => i2c_mux_access_ok,       -- 1
      probe_in1(0)                => si5341_access_ok,        -- 1
      probe_in2(0)                => si5341_config_done,      -- 1
      probe_in3(0)                => si5341_config_error,     -- 1
      probe_in4                   => clk_100_freq_r,          -- 32
      probe_in5                   => clk_100_cnt_r,           -- 32
      probe_in6                   => qsfp2_freq_r,            -- 32
      probe_in7                   => qsfp2_cnt_r,             -- 32
      probe_in8                   => qsfp3_freq_r,            -- 32
      probe_in9                   => qsfp3_cnt_r,             -- 32

      probe_out0(0)               => man_clk_gen_en,          -- 1                                   
      probe_out1(0)               => man_clk_gen_cfg_reset    -- 1                                                                                                                         
    );
      
  process(clk_100_in)
  begin
    if (rising_edge(clk_100_in)) then
      clk_100_tick_1ms_r      <= clk_100_tick_1ms_r(1 to 2) & tick_1ms;
      if (clk_100_tick_1ms_r(0 to 1) = "01") then 
        clk_100_freq_r        <= clk_100_cnt_r;
        clk_100_cnt_r         <= (others => '0');
      else
        clk_100_cnt_r         <= clk_100_cnt_r + 1;
      end if;
    end if;
  end process;
      
  process(qsfp2_clk_in)
  begin
    if (rising_edge(qsfp2_clk_in)) then
      qsfp2_tick_1ms_r      <= qsfp2_tick_1ms_r(1 to 2) & tick_1ms;
      if (qsfp2_tick_1ms_r(0 to 1) = "01") then 
        qsfp2_freq_r        <= qsfp2_cnt_r;
        qsfp2_cnt_r         <= (others => '0');
      else
        qsfp2_cnt_r         <= qsfp2_cnt_r + 1;
      end if;
    end if;
  end process;
      
  process(qsfp3_clk_in)
  begin
    if (rising_edge(qsfp3_clk_in)) then
      qsfp3_tick_1ms_r      <= qsfp3_tick_1ms_r(1 to 2) & tick_1ms;
      if (qsfp3_tick_1ms_r(0 to 1) = "01") then 
        qsfp3_freq_r        <= qsfp3_cnt_r;
        qsfp3_cnt_r         <= (others => '0');
      else
        qsfp3_cnt_r         <= qsfp3_cnt_r + 1;
      end if;
    end if;
  end process;
      

end architecture imp;
