
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.NUMERIC_STD.all;

use work.gencores_pkg.all;
use work.wrcore_pkg.all;
use work.wr_fabric_pkg.all;
use work.wr_xilinx_pkg.all;
use work.etherbone_pkg.all;

library UNISIM;
use UNISIM.vcomponents.all;

--library work;
use work.wishbone_pkg.all;


entity ticks_fmc is
  generic
    (
	 -- data format version 3msb=major, 3lsb=minor
     -- read_out event seconds in tailer
		g_dataformat_version		: unsigned(7 downto 0) := x"06"; 
     -- firmware version number 3msb=major, 3lsb=minor   
	 -- data_out fsm, throttler, timeout for SPI data, double FIFO, new cmd & ack, 
      g_fw_version				: unsigned(7 downto 0) := x"09";
		g_with_trigger_throttler 	: boolean := true
      );
  port
    (
      -- Global ports
      clk_20m_vcxo_i : in std_logic;    -- 20MHz VCXO clock

      clk_125m_pllref_p_i : in std_logic;  -- 125 MHz PLL reference
      clk_125m_pllref_n_i : in std_logic;

      fpga_pll_ref_clk_101_p_i : in std_logic;  -- Dedicated clock for Xilinx GTP transceiver
      fpga_pll_ref_clk_101_n_i : in std_logic;

      -- Font panel LEDs
      LED_RED   : out std_logic;
      LED_GREEN : out std_logic;

      dac_sclk_o  : out std_logic;
      dac_din_o   : out std_logic;
      dac_clr_n_o : out std_logic;
      dac_cs1_n_o : out std_logic;
      dac_cs2_n_o : out std_logic;

      fpga_scl_b : inout std_logic;
      fpga_sda_b : inout std_logic;
      
      spi_sclk_o : out std_logic;
      spi_ncs_o  : out std_logic;
      spi_mosi_o : out std_logic;
      spi_miso_i : in  std_logic := 'L';

      thermo_id : inout std_logic;      -- 1-Wire interface to DS18B20, get MAC address

      -------------------------------------------------------------------------
      -- SFP pins
      -------------------------------------------------------------------------

      sfp_txp_o : out std_logic;
      sfp_txn_o : out std_logic;

      sfp_rxp_i : in std_logic;
      sfp_rxn_i : in std_logic;

      sfp_mod_def0_b    : in    std_logic;  -- sfp detect
      sfp_mod_def1_b    : inout std_logic;  -- scl
      sfp_mod_def2_b    : inout std_logic;  -- sda
      sfp_rate_select_b : inout std_logic;
      sfp_tx_fault_i    : in    std_logic;
      sfp_tx_disable_o  : out   std_logic;
      sfp_los_i         : in    std_logic;

      -----------------------------------------
      --UART
      -----------------------------------------
      uart_rxd_i : in  std_logic;
      uart_txd_o : out std_logic;

      ----------------------------------------------------
		----- Digital I/O FMC RJ45 (LVDS) ------------------
		----------------------------------------------------
		
		----- SPI TIB ---
		spi_data_p_i	: in    std_logic; 
		spi_data_n_i	: in    std_logic;
		spi_clk_p_i		: in    std_logic;
		spi_clk_n_i		: in    std_logic;
		spi_ssel_p_i	: in    std_logic;
		spi_ssel_n_i	: in    std_logic;
		
		--- Triggers ----
		busy_trig_p_i	: in    std_logic;
		busy_trig_n_i	: in    std_logic;
		event_trig_p_i	: in    std_logic;
		event_trig_n_i	: in    std_logic;
		ext_trig_p_o	: out   std_logic;
		ext_trig_n_o	: out   std_logic;
		
		---clock & PPS
		pps_p_o			: out   std_logic;
		pps_n_o			: out   std_logic;
		pps_cal_p_o		: out   std_logic;
		pps_cal_n_o		: out   std_logic;
		clk_sync_p_o	: out   std_logic;
		clk_sync_n_o	: out   std_logic
      );

end ticks_fmc;

architecture rtl of ticks_fmc is

  ------------------------------------------------------------------------------
  -- Components declaration
  ------------------------------------------------------------------------------

	component powerup_reset_gen is
	  port (
		 clk_sys_i : in std_logic;
		 rst_n_o   : out std_logic
		 );
	end component;
  
------ DEBUG -----
--  component chipscope_ila
--    port (
--      CONTROL : inout std_logic_vector(35 downto 0);
--      CLK     : in    std_logic;
--      TRIG0   : in    std_logic_vector(31 downto 0);
--      TRIG1   : in    std_logic_vector(31 downto 0);
--      TRIG2   : in    std_logic_vector(31 downto 0);
--      TRIG3   : in    std_logic_vector(31 downto 0));
--  end component;
--
--  signal CONTROL : std_logic_vector(35 downto 0);
--  signal CLK     : std_logic;
--  signal TRIG0   : std_logic_vector(31 downto 0);
--  signal TRIG1   : std_logic_vector(31 downto 0);
--  signal TRIG2   : std_logic_vector(31 downto 0);
--  signal TRIG3   : std_logic_vector(31 downto 0);
----
--  component chipscope_icon
--    port (
--      CONTROL0 : inout std_logic_vector (35 downto 0));
--  end component;
  
  -----------------------------------------------------------------------------
  -- IP configuration
  -----------------------------------------------------------------------------	  
component ip_wb_config is
port(
    clk_sys_i        	: in std_logic;
    rst_i          		: in std_logic;
	 set_dst_port_i		: in std_logic := '0';
	 set_dst_ip_addr_i	: in std_logic;
	 dst_port_i 	 		: in std_logic_vector (15 downto 0);
	 dst_ip_addr_i 		: in std_logic_vector(31 downto 0);
    our_ip_addr_o 		: out std_logic_vector(31 downto 0);
    dst_ip_addr_o 		: out std_logic_vector(31 downto 0);
    dst_port_o       	: out std_logic_vector(15 downto 0);
    ip_config_done_o 	: out std_logic;
    ----
    wb_o             	: out t_wishbone_master_out;
    wb_i             	: in  t_wishbone_master_in
);
end component;

-----------------------------------
-------------- TDC -------------
component pulse_stamper
    generic (
      g_ref_clk_rate : integer);
    port (
      clk_ref_i       : in  std_logic;
      clk_sys_i       : in  std_logic;
      rst_n_i         : in  std_logic;
      pulse_a_i       : in  std_logic;
      tm_time_valid_i : in  std_logic;
      tm_tai_i        : in  std_logic_vector(39 downto 0);
      tm_cycles_i     : in  std_logic_vector(27 downto 0);
      tag_tai_o       : out std_logic_vector(39 downto 0);
      tag_cycles_o    : out std_logic_vector(27 downto 0);
      tag_valid_o     : out std_logic);
  end component;
  
  	COMPONENT tdcx2
	PORT(
		reset 		: in std_logic;
		clk_i 		: in std_logic;
--		tdc_en_i		: in std_logic;			-- event tdc clock enabble-- busy tdc clock enable
		data1_i 		: in std_logic;
		data2_i 		: in std_logic;          
		ready_o 		: out std_logic;
		data1_o 		: out std_logic_vector(7 downto 0);
		data2_o 		: out std_logic_vector(7 downto 0);
		strobe1_o 	: out std_logic;
		strobe2_o 	: out std_logic;
		fine_time_stamp1_o : out std_logic_vector(2 downto 0);
		fine_time_stamp2_o : out std_logic_vector(2 downto 0)
		);
	END COMPONENT;
-------- end TDC ---------------

-------- UDP stack -------------

  COMPONENT udp_top
   generic( g_data_tx_width   	: natural := 16;
				g_add_data_tx_width 	: natural := 16;
				g_data_rx_width  		: natural := 16;
				g_nb_data_packed 		: natural := 20);	
	PORT(
		clk_sys_i 			: in std_logic;
		rst_n_i 				: in std_logic;
      tx_data_i 			: in std_logic_vector (g_data_tx_width-1 downto 0);
      tx_data_ready_i 	: in std_logic;
		add_tx_data_i		: in std_logic_vector (g_add_data_tx_width-1 downto 0);
		rx_data_o 			: out std_logic_vector (g_data_rx_width-1 downto 0);
		rx_data_ready_o 	: out std_logic;
		src_i 				: in t_wrf_source_in;
		snk_i 				: in t_wrf_sink_in;
		cfg_mac_local_i 	: in std_logic_vector(47 downto 0);
		cfg_mac_target_i 	: in std_logic_vector(47 downto 0);
		cfg_ip_local_i 	: in std_logic_vector(31 downto 0);
		cfg_ip_target_i 	: in std_logic_vector(31 downto 0);
		cfg_port_i 			: in std_logic_vector(15 downto 0);          
		src_o 				: out t_wrf_source_out;
		snk_o 				: out t_wrf_sink_out;	
		tx_almost_empty_o	: out  std_logic;
		tx_almost_full_o  : out  std_logic
			--------Debug-----
--      TRIG0 : out std_logic_vector(31 downto 0)
--      TRIG1 : out std_logic_vector(31 downto 0)
--      TRIG2 : out std_logic_vector(31 downto 0)
--      TRIG3 : out std_logic_vector(31 downto 0)
		);
	END COMPONENT;
	
	--- decode Rx data	
	component command_decoder is
		generic(
			g_data_rx_width  	: natural := 16
		 );
		Port ( 
			clk_i 					: in  std_logic;
		   command_i				: in  std_logic_vector (g_data_rx_width-1 downto 0);
		   data_valid_i			: in  std_logic;
			cnt_en_o					: out std_logic;
			ext_trig_en_o			: out std_logic;
			set_throttle_val_o 	: out std_logic;
			set_dst_ip_addr_o		: out STD_LOGIC;
			spi_en_o 				: out STD_LOGIC;
			set_dst_port_o			: out STD_LOGIC := '0';
			dst_port_o 	 		   : out STD_LOGIC_VECTOR (15 downto 0);
			dst_mac_addr_o 	 	: out std_logic_vector (47 downto 0);
			ext_trig_date_o 		: out std_logic_vector (52 downto 0);
			throttle_val_o  		: out std_logic_vector (15 downto 0);
			dst_ip_addr_o			: out STD_LOGIC_VECTOR (31 downto 0)
           );
	end component;
	
	----- Limit Tx rate --------
	COMPONENT trigger_throttler
    Port ( clk_i 					: in  std_logic;
           rst_i 					: in  std_logic;
			  throttle_val_i		: in  std_logic_vector(15 downto 0);
           set_throttle_val_i	: in  std_logic;		  
			  tx_almost_empty_i 	: in  std_logic;
           tx_almost_full_i 	: in  std_logic;
           stop_wr_o 			: out  std_logic
				);
	END COMPONENT;
	
	--generate an external trigger 
	COMPONENT ext_trig_gen
	PORT(
		clk_i 			 : in std_logic;
		clk_ref_i 		 : in std_logic;
		rst_i 			 : in std_logic;
		ext_trig_en_i   : in std_logic;
		tm_seconds_i 	 : in std_logic_vector(24 downto 0);
		tm_cycles_i 	 : in std_logic_vector(27 downto 0);
		ext_trig_date_i : in std_logic_vector(52 downto 0);          
		ext_trig_o 		 : out std_logic
		);
	END COMPONENT;

--------- counters --------------

COMPONENT counters 
  port(
     clk_i 			 		: in std_logic;
	  clk_ref_i 	 		: in std_logic;
     rst_i 		 	 		: in std_logic;
	  clk_sync_i	 		: in std_logic;
     busy_trig_i 	 		: in std_logic;
     event_trig_i  		: in std_logic;
     cnt_en_i		 		: in std_logic;
	  pps_csync_i 	 		: in std_logic;
     pps_i			 		: in std_logic;
	  cnt_en_ack_o			: out std_logic;
	  tdc_rst_o		 		: out std_logic;
     ext_trig_o 	 		: out std_logic;
	  event_flag_o	 		: out std_logic;
	  busy_flag_o	 		: out std_logic;
     pps_cnt_o		 		: out std_logic_vector(15 downto 0);
     busy_cnt_o 	 		: out std_logic_vector(31 downto 0);
     event_cnt_o 	 		: out std_logic_vector(31 downto 0);
     clk_cnt_o		 		: out std_logic_vector(25 downto 0)
	  ---- debug ----
	 -- TRIG0 			 : out std_logic_vector(31 downto 0)
    );
END COMPONENT;

--- SPI slave --------------
	COMPONENT spi_slave
	Generic (   
	  N : positive := 32;                                             -- 32bit serial word length is default
	  CPOL : std_logic := '0';                                        -- SPI mode selection (mode 0 default)
	  CPHA : std_logic := '0';                                        -- CPOL = clock polarity, CPHA = clock phase.
	  PREFETCH : positive := 3);
	PORT(
		clk_i 			: in std_logic;
		spi_ssel_i		: in std_logic;
		spi_sck_i 		: in std_logic;
		spi_mosi_i 		: in std_logic;
		di_i 				: in std_logic_vector(N-1 downto 0);
		wren_i 			: in std_logic;          
		spi_miso_o 		: out std_logic;
		di_req_o 		: out std_logic;
		wr_ack_o 		: out std_logic;
		do_valid_o 		: out std_logic;
		do_o 				: out std_logic_vector(N-1 downto 0);
		do_transfer_o 	: out std_logic;
		wren_o 			: out std_logic;
		rx_bit_next_o 	: out std_logic;
		state_dbg_o 	: out std_logic_vector(3 downto 0);
		sh_reg_dbg_o 	: out std_logic_vector(N-1 downto 0)
		);
	END COMPONENT;
	
	
	-- format data to be sent through UDP
	COMPONENT data_out_nofsm is

	generic( g_spi_timeout_val : natural := 50);	--	~800ns @ 62.5MHz enough ?? 

    Port ( clk_i 						: in  std_logic;
			  clk_125m_pllref_i		: in  std_logic;
           rst_i 						: in  std_logic;
			  event_flag_i				: in  std_logic;
			  busy_flag_i				: in  std_logic;
			  spi_en_i					: in  STD_LOGIC;
			  event_cnt_i				: in  std_logic_vector(7 downto 0);		--event counter 8bits lsb
			  busy_cnt_i				: in  std_logic_vector(7 downto 0);		--busy trigger counter 8bits lsb
			  pps_cnt_i					: in  std_logic_vector(1 downto 0);		--PPS counter 2bits lsb
			  clk_cnt_i					: in  std_logic_vector(25 downto 0);	--clock counter 26bits
			  tx_tag_tai_evt_i		: in  STD_LOGIC_VECTOR(1 downto 0);		--seconds 2bits lsb
			  tx_tag_cycles_evt_i 	: in  STD_LOGIC_VECTOR(27 downto 0);	---8ns tag 28bits
			  tx_tag_tai_bsy_i		: in  STD_LOGIC_VECTOR(1 downto 0);		--seconds 2bits lsb
			  tx_tag_cycles_bsy_i 	: in  STD_LOGIC_VECTOR(27 downto 0);
			  tdc_data_evt_i			: in  std_logic_vector(2 downto 0);		-- 1ns timestamp 3bits event trigger
			  tdc_data_bsy_i			: in  std_logic_vector(2 downto 0);		-- 1ns timestamp 3bits busy trigger
			  data_rx_spi_i			: in  std_logic_vector(15 downto 0);	-- Rx SPI data
			  tdc_evt_rdy_i			: in  std_logic;
			  tdc_bsy_rdy_i			: in  std_logic;
			  tm_time_valid_i			: in  std_logic;
			  tx_tag_valid_evt_i		: in  STD_LOGIC;	
			  tx_tag_valid_bsy_i		: in  STD_LOGIC;		
           data_r_spi_i 			: in  std_logic;
			  tx_data_o					: out  std_logic_vector(95 downto 0);
           tx_ready_o 				: out std_logic
--			  tdc_en_o 					: out std_logic
			  --TRIG0 : out std_logic_vector(31 downto 0)
			 );
	END COMPONENT;

	-- generate a 10MHz clock sync to PPS
	COMPONENT ppsclock_sync
	PORT(
		clk_i : in std_logic;
		rst_i : in std_logic;
		pps_i : in std_logic;          
		clk_o : out std_logic
		);
	END COMPONENT;

  ------------------------------------------------------------------------------
  -- Constants declaration
  ------------------------------------------------------------------------------
  constant c_BAR0_APERTURE     : integer := 20;
  constant c_CSR_WB_SLAVES_NB  : integer := 1;
  constant c_DMA_WB_SLAVES_NB  : integer := 1;
  constant c_DMA_WB_ADDR_WIDTH : integer := 26;
  
  constant c_diag_ro_size : integer := 8;
  constant c_diag_rw_size : integer := 0;

  ------------------------------------------------------------------------------
  -- Signals declaration
  ------------------------------------------------------------------------------

  -- Dedicated clock for GTP transceiver
  signal gtp_dedicated_clk : std_logic;

  -- Reset
  signal rst   : std_logic;

--  signal ram_we      : std_logic_vector(0 downto 0);
--  signal ddr_dma_adr : std_logic_vector(29 downto 0);

  -- SPI
--  signal spi_slave_select : std_logic_vector(7 downto 0);


  signal pllout_clk_sys       : std_logic;
  signal pllout_clk_dmtd      : std_logic;
  signal pllout_clk_fb_pllref : std_logic;
  signal pllout_clk_fb_dmtd   : std_logic; 
    --clk sync PLL
  signal pllout_clk_sync      	: std_logic;
  signal pllout_clk_fb_pllref2, buf_clk_fb_pllref2	: std_logic;
--  signal pllout_clk200M				: std_logic;

  signal clk_20m_vcxo_buf : std_logic;
  signal clk_125m_pllref  : std_logic;
  signal clk_sys          : std_logic;
  signal clk_dmtd         : std_logic;
  signal dac_rst_n        : std_logic;

  signal wrc_scl_o : std_logic;
  signal wrc_scl_i : std_logic;
  signal wrc_sda_o : std_logic;
  signal wrc_sda_i : std_logic;
  signal sfp_scl_o : std_logic;
  signal sfp_scl_i : std_logic;
  signal sfp_sda_o : std_logic;
  signal sfp_sda_i : std_logic;
  signal dio       : std_logic_vector(3 downto 0);

  signal dac_hpll_load_p1 : std_logic;
  signal dac_dpll_load_p1 : std_logic;
  signal dac_hpll_data    : std_logic_vector(15 downto 0);
  signal dac_dpll_data    : std_logic_vector(15 downto 0);

  signal pps     : std_logic;
  signal pps_led : std_logic;

  signal phy_tx_data      : std_logic_vector(7 downto 0);
  signal phy_tx_k         : std_logic_vector(0 downto 0);
  signal phy_tx_disparity : std_logic;
  signal phy_tx_enc_err   : std_logic;
  signal phy_rx_data      : std_logic_vector(7 downto 0);
  signal phy_rx_rbclk     : std_logic;
  signal phy_rx_k         : std_logic_vector(0 downto 0);
  signal phy_rx_enc_err   : std_logic;
  signal phy_rx_bitslide  : std_logic_vector(3 downto 0);
  signal phy_rst          : std_logic;
  signal phy_loopen       : std_logic;
  signal phy_loopen_vec   : std_logic_vector(2 downto 0);
  signal phy_prbs_sel     : std_logic_vector(2 downto 0);
  signal phy_rdy          : std_logic;
  
  signal pps_out : std_logic; 
  signal pps_csync : std_logic; 
--  attribute iob: string;
----  attribute iob of pps_out: signal is "true";
--  attribute iob of clk_sync_out: signal is "true";

 -- Aux WB interface
--  signal aux_master_out : t_wishbone_master_out;
--  signal aux_master_in  : t_wishbone_master_in;
--  signal aux_rst_n      : std_logic;
  
  -- WR SNMP
  signal aux_diag_in  : t_generic_word_array(c_diag_ro_size-1 downto 0);
  signal aux_diag_out : t_generic_word_array(c_diag_rw_size-1 downto 0);

  signal local_reset_n  : std_logic := '1';

  signal ip_cfg_wb_out  : t_wishbone_master_out;
  signal ip_cfg_wb_in   : t_wishbone_master_in;

  signal wrc_slave_i : t_wishbone_slave_in;
  signal wrc_slave_o : t_wishbone_slave_out;

  signal owr_en : std_logic_vector(1 downto 0);
  signal owr_i  : std_logic_vector(1 downto 0);

  signal wb_adr : std_logic_vector(31 downto 0);  --c_BAR0_APERTURE-priv_log2_ceil(c_CSR_WB_SLAVES_NB+1)-1 downto 0);

  signal etherbone_rst_n   : std_logic;
  signal etherbone_src_out : t_wrf_source_out;
  signal etherbone_src_in  : t_wrf_source_in;
  signal etherbone_snk_out : t_wrf_sink_out;
  signal etherbone_snk_in  : t_wrf_sink_in;
  signal etherbone_wb_out  : t_wishbone_master_out;
  signal etherbone_wb_in   : t_wishbone_master_in;
  signal etherbone_cfg_in  : t_wishbone_slave_in;
  signal etherbone_cfg_out : t_wishbone_slave_out;

  signal ext_pll_reset : std_logic;
  signal clk_ref_div2               : std_logic;

--  -- Timecode output
  signal tm_time_valid : std_logic;
  signal time_valid_detect : std_logic_vector(1 downto 0) :="11";
  signal tm_seconds    : std_logic_vector(39 downto 0);
  signal tm_cycles     : std_logic_vector(27 downto 0);
  
--  -- TX signals
  signal tx_tag_tai_evt, tx_tag_tai_bsy       : std_logic_vector(39 downto 0);
  signal tx_tag_cycles_evt, tx_tag_cycles_bsy : std_logic_vector(27 downto 0);
  signal tx_tag_valid_evt, tx_tag_valid_bsy   : std_logic;
  signal tx_data           : std_logic_vector(95 downto 0);
  signal tx_add_info       : std_logic_vector(127 downto 0);
  signal tx_sc        		: std_logic_vector(15 downto 0);
  signal tx_valid, tx_dreq, tag2tx : std_logic;
  signal tx_data_ready, stop_wr_fifo : std_logic :='0';
 
  --- RX signals
  signal rx_data   : std_logic_vector(63 downto 0);
  signal rx_valid	 : std_logic;
  
--  Network configuration signals
  signal our_mac_addr	: std_logic_vector(47 downto 0);
  signal dst_mac_addr	: std_logic_vector(47 downto 0);
  signal our_ip_addr 	: std_logic_vector(31 downto 0);
  signal dst_ip_addr, dst_ip_addr_cmd 		: std_logic_vector(31 downto 0);
  signal dst_port, dst_port_cmd       		: std_logic_vector(15 downto 0);
  signal set_dst_ip_addr	: std_logic;
  signal set_dst_port		: std_logic;
  signal ip_config_done 	: std_logic;
  
  -------TDC -------
  signal tdc_data2tx : std_logic_vector(2 downto 0);
  signal tdc_data_r1, tdc_data_r2 	: std_logic;
  signal tdc_buf, tdc_data_evt, tdc_data_busy : std_logic_vector(2 downto 0);
  signal clk_1G, clk_1G_pll	: std_logic;
  signal pll_locked 		: std_logic;
  signal tdc_rst			: std_logic;
--  signal tdc_en			: std_logic := '1';
  
    ---PPS  & event counters
  signal pps_detect 	: std_logic;
  signal pps_cnt		: std_logic_vector(15 downto 0):=(others => '0');
  signal event_cnt 	: std_logic_vector(31 downto 0):=(others => '0');
  signal busy_cnt		: std_logic_vector(31 downto 0):=(others => '0');
  signal clk_cnt		: std_logic_vector(25 downto 0):=(others => '0');
  signal cnt_en_ack 	: std_logic;
  signal rst_cnt_cmd	: std_logic;
  signal busy_flag, ack_busy_flag, ack_event_flag, event_flag	: std_logic;
   
  
  --- clock sync ----
  signal clk_sync_out, clk_sync,clk_sync1, clk_sync2, clk_200M : std_logic;
  signal reset_pll : std_logic;
  signal resetpll_cnt   : unsigned(15 downto 0) := x"0000";
  
  ---SPI from TIB---
  signal spi_sck,spi_data, spi_ssel : std_logic;
  signal pllout_spi_clk, spi_clk 	: std_logic;  
  signal data_r_spi						: std_logic;
  signal data_rx_spi, data_buf_spi  : std_logic_vector(15 downto 0):=(others => '0');
  
  --Triggers
  signal busy_trig, event_trig, ext_trig : std_logic;
  signal ext_trig_rst, trig_en : std_logic;
  
--  command signals
  signal cnt_cmd 	 		: std_logic;
  signal ext_trig_en 	: std_logic;
  signal ext_trig_date  : std_logic_vector(52 downto 0);
  signal tx_almost_empty 	: std_logic;
  signal tx_almost_full 	: std_logic;
  signal set_throttle_val	: std_logic;
  signal throttle_val		: std_logic_vector(15 downto 0) := x"30D3";		-- 200us with clk_sys (62.5MHz)
  signal spi_en				: std_logic;
  
     ------------------------
  -- to wr-core's fabric
  ------------------------	
  signal ext_src_out : t_wrf_source_out;
  signal ext_src_in  : t_wrf_source_in;
  signal ext_snk_out : t_wrf_sink_out;
  signal ext_snk_in  : t_wrf_sink_in;
  
begin

--	aux_master_out    <= cc_dummy_master_out;
--	aux_master_in    <= cc_dummy_master_in;
	
	U_Reset_Gen : powerup_reset_gen
    port map (
      clk_sys_i  => clk_sys,
      rst_n_o    => local_reset_n
		);		

  cmp_sys_clk_pll : PLL_BASE
    generic map (
      BANDWIDTH          => "OPTIMIZED",
      CLK_FEEDBACK       => "CLKFBOUT",
      COMPENSATION       => "INTERNAL",
      DIVCLK_DIVIDE      => 1,
      CLKFBOUT_MULT      => 8,
      CLKFBOUT_PHASE     => 0.000,
      CLKOUT0_DIVIDE     => 16,         -- 62.5 MHz
      CLKOUT0_PHASE      => 0.000,
      CLKOUT0_DUTY_CYCLE => 0.500,
      CLKOUT1_DIVIDE     => 16,         -- 125 MHz
      CLKOUT1_PHASE      => 0.000,
      CLKOUT1_DUTY_CYCLE => 0.500,
      CLKOUT2_DIVIDE     => 16,
      CLKOUT2_PHASE      => 0.000,
      CLKOUT2_DUTY_CYCLE => 0.500,
      CLKIN_PERIOD       => 8.0,
      REF_JITTER         => 0.016)
    port map (
      CLKFBOUT => pllout_clk_fb_pllref,
      CLKOUT0  => pllout_clk_sys,
      CLKOUT1  => open,
      CLKOUT2  => open,
      CLKOUT3  => open,
      CLKOUT4  => open,
      CLKOUT5  => open,
      LOCKED   => open,
      RST      => '0',
      CLKFBIN  => pllout_clk_fb_pllref,
      CLKIN    => clk_125m_pllref);

  cmp_dmtd_clk_pll : PLL_BASE
    generic map (
      BANDWIDTH          => "OPTIMIZED",
      CLK_FEEDBACK       => "CLKFBOUT",
      COMPENSATION       => "INTERNAL",
      DIVCLK_DIVIDE      => 1,
      CLKFBOUT_MULT      => 50,
      CLKFBOUT_PHASE     => 0.000,
      CLKOUT0_DIVIDE     => 16,         -- 62.5 MHz
      CLKOUT0_PHASE      => 0.000,
      CLKOUT0_DUTY_CYCLE => 0.500,
      CLKOUT1_DIVIDE     => 16,         -- 62.5 MHz
      CLKOUT1_PHASE      => 0.000,
      CLKOUT1_DUTY_CYCLE => 0.500,
      CLKOUT2_DIVIDE     => 8,
      CLKOUT2_PHASE      => 0.000,
      CLKOUT2_DUTY_CYCLE => 0.500,
      CLKIN_PERIOD       => 50.0,
      REF_JITTER         => 0.016)
    port map (
      CLKFBOUT => pllout_clk_fb_dmtd,
      CLKOUT0  => pllout_clk_dmtd,
      CLKOUT1  => open,
      CLKOUT2  => open,
      CLKOUT3  => open,
      CLKOUT4  => open,
      CLKOUT5  => open,
      LOCKED   => open,
      RST      => '0',
      CLKFBIN  => pllout_clk_fb_dmtd,
      CLKIN    => clk_20m_vcxo_buf);
		
	----PLL for clock sync out & TDC clock ------
		cmp_sync_clk_pll : PLL_BASE
    generic map (
      BANDWIDTH          => "OPTIMIZED",
      CLK_FEEDBACK       => "CLKFBOUT",
      COMPENSATION       => "INTERNAL",			--"SYSTEM_SYNCHRONOUS",
      DIVCLK_DIVIDE      => 1,
      CLKFBOUT_MULT      => 8,
      CLKFBOUT_PHASE     => 0.000,
      CLKOUT0_DIVIDE     => 5,       --200MHz clock to generate 10MHz aligned --100 10MHz 
      CLKOUT0_PHASE      => 0.0,			--phase 10MHz/PPS adjustment hardcoded
      CLKOUT0_DUTY_CYCLE => 0.500,
      CLKOUT1_DIVIDE     => 1,         
      CLKOUT1_PHASE      => 0.0,
      CLKOUT1_DUTY_CYCLE => 0.500,
      CLKIN_PERIOD       => 8.0,
      REF_JITTER         => 0.016)
    port map (
      CLKFBOUT => pllout_clk_fb_pllref2,
      CLKOUT0  => clk_200M,	
      CLKOUT1  =>	open, 				
      LOCKED   => pll_locked,
      RST      => '0',
      CLKFBIN  => pllout_clk_fb_pllref2,								
      CLKIN    => clk_125m_pllref);     -- 125 MHz		
		
		
	clk_sync2 <= not clk_sync1;
		
	ODDR2_inst : ODDR2
	generic map(
		DDR_ALIGNMENT => "NONE", -- Sets output alignment to "NONE", "C0", "C1"
		INIT 	 => '0', -- Sets initial state of the Q output to '0' or '1'
		SRTYPE => "SYNC") -- Specifies "SYNC" or "ASYNC" set/reset
	port map (
		Q  => clk_sync_out, -- 1-bit output data
		C0 => clk_sync1, -- 1-bit clock input
		C1 => clk_sync2, -- 1-bit clock input		--10MHz inverted clock
		CE => '1', 	-- 1-bit clock enable input
		D0 => '1',	-- 1-bit data input (associated with C0)
		D1 => '0',	-- 1-bit data input (associated with C1)
		R  => '0',	-- 1-bit reset input
		S  => '0'		-- 1-bit set input
	);
	-- End of ODDR2_inst instantiation
			
  	cmp_clk_10M_buf_i : BUFG
	  port map (
		 O => clk_sync,
		 I => clk_sync1);

  cmp_clk_sys_buf : BUFG
    port map (
      O => clk_sys,
      I => pllout_clk_sys);
	
	cmp_clk_ref_buf : BUFG
    port map (
      O => buf_clk_fb_pllref2,
      I => pllout_clk_fb_pllref2);
		
  cmp_clk_dmtd_buf : BUFG
    port map (
      O => clk_dmtd,
      I => pllout_clk_dmtd);

  cmp_clk_vcxo : BUFG
    port map (
      O => clk_20m_vcxo_buf,
      I => clk_20m_vcxo_i);

  cmp_pllrefclk_buf : IBUFGDS
    generic map (
      DIFF_TERM    => true,           -- Differential Termination
      IBUF_LOW_PWR => true, 	 	-- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
      IOSTANDARD   => "DEFAULT")
    port map (
      O  => clk_125m_pllref,            -- Buffer output
      I  => clk_125m_pllref_p_i,  -- Diff_p buffer input (connect directly to top-level port)
      IB => clk_125m_pllref_n_i  -- Diff_n buffer input (connect directly to top-level port)
      );


  ------------------------------------------------------------------------------
  -- Dedicated clock for GTP
  ------------------------------------------------------------------------------
  cmp_gtp_dedicated_clk_buf : IBUFGDS
    generic map(
      DIFF_TERM    => true,
      IBUF_LOW_PWR => true,
      IOSTANDARD   => "DEFAULT")
    port map (
      O  => gtp_dedicated_clk,
      I  => fpga_pll_ref_clk_101_p_i,
      IB => fpga_pll_ref_clk_101_n_i
      );


  ------------------------------------------------------------------------------
  -- Active high reset
  ------------------------------------------------------------------------------
  rst <= not(local_reset_n); 

  fpga_scl_b <= '0' when wrc_scl_o = '0' else 'Z';
  fpga_sda_b <= '0' when wrc_sda_o = '0' else 'Z';
  wrc_scl_i  <= fpga_scl_b;
  wrc_sda_i  <= fpga_sda_b;

  sfp_mod_def1_b <= '0' when sfp_scl_o = '0' else 'Z';
  sfp_mod_def2_b <= '0' when sfp_sda_o = '0' else 'Z';
  sfp_scl_i      <= sfp_mod_def1_b;
  sfp_sda_i      <= sfp_mod_def2_b;

  thermo_id <= '0' when owr_en(0) = '1' else 'Z';
  owr_i(0)  <= thermo_id;

  U_WR_CORE : xwr_core
    generic map (
      g_simulation                => 0,
      g_with_external_clock_input => false,
      --
      g_phys_uart                 => true,
      g_virtual_uart              => false,		
      g_aux_clks                  => 0,
      g_ep_rxbuf_size             => 1024,
      g_tx_runt_padding           => true,
      g_pcs_16bit                 => false,
      g_dpram_initf               => "../../bin/wrpc/wrc_phy8.bram", 		--"wrc.ram",  --"../../../bin/wrpc/wrc_test.bram", --"../../../bin/wrpc/wrc_phy8.bram",
      g_aux_sdb                   => c_etherbone_sdb,
      g_dpram_size                => 131072/4,
      g_interface_mode            => PIPELINED,
      g_address_granularity       => BYTE,
		g_diag_id                   => 1,
      g_diag_ver                  => 1,
      g_diag_ro_size              => c_diag_ro_size,
      g_diag_rw_size              => c_diag_rw_size
		)
    port map (
      clk_sys_i     			=> clk_sys,
      clk_dmtd_i    			=> clk_dmtd,
      clk_ref_i     			=> clk_125m_pllref,
      clk_aux_i    			=> (others => '0'),
      clk_ext_i     			=> '0',				
      clk_ext_mul_i 			=> '0',				
      clk_ext_mul_locked_i => '0', 				
      clk_ext_stopped_i    =>'0',				
      clk_ext_rst_o        => open, 		
      pps_ext_i     			=> '0',
      rst_n_i      		 	=> local_reset_n,

      dac_hpll_load_p1_o => dac_hpll_load_p1,
      dac_hpll_data_o    => dac_hpll_data,
      dac_dpll_load_p1_o => dac_dpll_load_p1,
      dac_dpll_data_o    => dac_dpll_data,

      phy_ref_clk_i      => clk_125m_pllref,
      phy_tx_data_o      => phy_tx_data,
      phy_tx_k_o         => phy_tx_k,
      phy_tx_disparity_i => phy_tx_disparity,
      phy_tx_enc_err_i   => phy_tx_enc_err,
      phy_rx_data_i      => phy_rx_data,
      phy_rx_rbclk_i     => phy_rx_rbclk,
      phy_rx_k_i         => phy_rx_k,
      phy_rx_enc_err_i   => phy_rx_enc_err,
      phy_rx_bitslide_i  => phy_rx_bitslide,
      phy_rst_o          => phy_rst,
      phy_loopen_o       => phy_loopen,
      phy_loopen_vec_o   => phy_loopen_vec,
      phy_rdy_i          => phy_rdy,
      phy_sfp_tx_fault_i => sfp_tx_fault_i,
      phy_sfp_los_i      => sfp_los_i,
      phy_sfp_tx_disable_o => sfp_tx_disable_o,
      phy_tx_prbs_sel_o  =>  phy_prbs_sel,

      led_act_o  => LED_RED,
      led_link_o => LED_GREEN,
      scl_o      => wrc_scl_o,
      scl_i      => wrc_scl_i,
      sda_o      => wrc_sda_o,
      sda_i      => wrc_sda_i,
      sfp_scl_o  => sfp_scl_o,
      sfp_scl_i  => sfp_scl_i,
      sfp_sda_o  => sfp_sda_o,
      sfp_sda_i  => sfp_sda_i,
      sfp_det_i  => sfp_mod_def0_b,
      spi_sclk_o  => spi_sclk_o,
      spi_ncs_o   => spi_ncs_o,
      spi_mosi_o  => spi_mosi_o,
      spi_miso_i  => spi_miso_i,

      uart_rxd_i => uart_rxd_i,
      uart_txd_o => uart_txd_o,

      owr_en_o => owr_en,
      owr_i    => owr_i,

      slave_i => wrc_slave_i,
      slave_o => wrc_slave_o,

      aux_master_o => etherbone_cfg_in,		--aux_master_out,
      aux_master_i => etherbone_cfg_out,		--aux_master_in,
		
		eb_snk_i  => etherbone_src_out,  
		eb_snk_o  => etherbone_src_in,
		eb_src_i  => etherbone_snk_out,
		eb_src_o  => etherbone_snk_in,

		wrf_src_o => ext_snk_in,
      wrf_src_i => ext_snk_out,
      wrf_snk_o => ext_src_in,
      wrf_snk_i => ext_src_out,
		
      tm_dac_value_o       => open,
      tm_dac_wr_o          => open,
      tm_clk_aux_lock_en_i => (others => '0'),
      tm_clk_aux_locked_o  => open,
      tm_time_valid_o      => tm_time_valid,
      tm_tai_o             => tm_seconds,
      tm_cycles_o          => tm_cycles,
      pps_p_o              => pps_out,
      pps_led_o            => pps_led,
		pps_csync_o 			=> pps_csync,		-- Single-pulse PPS output for counters
      rst_aux_n_o 			=> etherbone_rst_n,
		
--		link_ok_o => link_ok_o,

      aux_diag_i => aux_diag_in,  			--(others=>(others=>'0')),
      aux_diag_o => aux_diag_out 			--open
      );

  Etherbone : eb_slave_core
    generic map (
      g_sdb_address => x"0000000000030000")
    port map (
      clk_i       => clk_sys,
      nRst_i      => etherbone_rst_n,
      src_o       => etherbone_src_out,		 
      src_i       => etherbone_src_in,			
      snk_o       => etherbone_snk_out,		
      snk_i       => etherbone_snk_in,		
      cfg_slave_o => etherbone_cfg_out,
      cfg_slave_i => etherbone_cfg_in,
      master_o    => etherbone_wb_out,
      master_i    => etherbone_wb_in);

  ---------------------
  masterbar : xwb_crossbar
    generic map (
      g_num_masters => 2,
      g_num_slaves  => 1,
      g_registered  => false,
      g_address     => (0 => x"00000000"),
      g_mask        => (0 => x"00000000"))
    port map (
      clk_sys_i   => clk_sys,
      rst_n_i     => local_reset_n,
      slave_i(0)  => ip_cfg_wb_out, 				
      slave_i(1)  => etherbone_wb_out,
      slave_o(0)  => ip_cfg_wb_in,       		
      slave_o(1)  => etherbone_wb_in,
      master_i(0) => wrc_slave_o,
      master_o(0) => wrc_slave_i);

  -------------------
  
    ---------------------
--  masterbar : xwb_crossbar
--    generic map (
--      g_num_masters => 1,
--      g_num_slaves  => 1,
--      g_registered  => false,
--      g_address     => (0 => x"00000000"),
--      g_mask        => (0 => x"00000000"))
--    port map (
--      clk_sys_i   => clk_sys,
--      rst_n_i     => local_reset_n,
--      slave_i(0)  => ip_cfg_wb_out, 				
--      slave_o(0)  => ip_cfg_wb_in,       		
--      master_i(0) => wrc_slave_o,
--      master_o(0) => wrc_slave_i);

  ---------------------

  U_GTP : wr_gtp_phy_spartan6
    generic map (
      g_enable_ch0 => 0,
      g_enable_ch1 => 1,
      g_simulation => 0)
    port map (
      gtp_clk_i 			 => gtp_dedicated_clk,

      ch0_ref_clk_i      => clk_125m_pllref,
      ch0_tx_data_i      => x"00",
      ch0_tx_k_i         => '0',
      ch0_tx_disparity_o => open,
      ch0_tx_enc_err_o   => open,
      ch0_rx_rbclk_o     => open,
      ch0_rx_data_o      => open,
      ch0_rx_k_o         => open,
      ch0_rx_enc_err_o   => open,
      ch0_rx_bitslide_o  => open,
      ch0_rst_i          => '1',
      ch0_loopen_i       => '0',
      ch0_rdy_o          => open,

      ch1_ref_clk_i      => clk_125m_pllref,
      ch1_tx_data_i      => phy_tx_data,
      ch1_tx_k_i         => phy_tx_k(0),
      ch1_tx_disparity_o => phy_tx_disparity,
      ch1_tx_enc_err_o   => phy_tx_enc_err,
      ch1_rx_data_o      => phy_rx_data,
      ch1_rx_rbclk_o     => phy_rx_rbclk,
      ch1_rx_k_o         => phy_rx_k(0),
      ch1_rx_enc_err_o   => phy_rx_enc_err,
      ch1_rx_bitslide_o  => phy_rx_bitslide,
      ch1_rst_i          => phy_rst,
      ch1_loopen_i       => phy_loopen,
      ch1_loopen_vec_i   => phy_loopen_vec,
      ch1_tx_prbs_sel_i  => phy_prbs_sel,
      ch1_rdy_o          => phy_rdy,
      pad_txn0_o         => open,
      pad_txp0_o         => open,
      pad_rxn0_i         => '0',
      pad_rxp0_i         => '0',
      pad_txn1_o         => sfp_txn_o,
      pad_txp1_o         => sfp_txp_o,
      pad_rxn1_i         => sfp_rxn_i,
      pad_rxp1_i         => sfp_rxp_i);

  
  U_DAC_ARB : spec_serial_dac_arb
    generic map (
      g_invert_sclk    => false,
      g_num_extra_bits => 8)

    port map (
      clk_i   => clk_sys, 
      rst_n_i => local_reset_n,

      val1_i  => dac_dpll_data,
      load1_i => dac_dpll_load_p1,

      val2_i  => dac_hpll_data,
      load2_i => dac_hpll_load_p1,

      dac_cs_n_o(0) => dac_cs1_n_o,
      dac_cs_n_o(1) => dac_cs2_n_o,
      dac_clr_n_o   => dac_clr_n_o,
      dac_sclk_o    => dac_sclk_o,
      dac_din_o     => dac_din_o);

	---------------------------------
	---I/O FMC RJ45----
	---------------------------------
	---SPI clock from master--
  spi_clk_lvds : IBUFDS 
  generic map (
        DIFF_TERM => true)
  port map(
    O  => spi_sck, -- Buffer output
    I  => spi_clk_p_i,
    IB => spi_clk_n_i
  );
	
	spi_data_lvds : IBUFDS
	generic map (
	  DIFF_TERM => true)
  port map(
    O  => spi_data, -- Buffer output
    I  => spi_data_p_i,
    IB => spi_data_n_i
  );
	
	spi_ssel_lvds : IBUFDS
	generic map (
        DIFF_TERM => true)	
  port map(
    O  => spi_ssel, -- Buffer output
    I  => spi_ssel_p_i,
    IB => spi_ssel_n_i
  );
  
  ---Trigger---
   busy_trig_lvds : IBUFDS
	generic map (
        DIFF_TERM => true)	
  port map(
    O  => busy_trig, -- Buffer output
    I  => busy_trig_p_i,
    IB => busy_trig_n_i
  );
  
  event_trig_lvds : IBUFDS 
  generic map (
        DIFF_TERM => true,
		  IBUF_LOW_PWR => false -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
		  )
  port map(
    O  => event_trig, -- Buffer output
    I  => event_trig_p_i,
    IB => event_trig_n_i
  );
 					
  ext_trig_lvds : OBUFDS
	port map (
	  I  => ext_trig or ext_trig_rst,
	  O  => ext_trig_p_o,
	  OB => ext_trig_n_o
	  );
  
  cmp_obuf_pps : OBUFDS
	port map (
	  I  => pps_out,
	  O  => pps_p_o,
	  OB => pps_n_o
	  );
	 
	-- calibration PPS 	 
	cmp_obuf_pps_cal : OBUFDS
	port map (
	  I  => pps_out,
	  O  => pps_cal_p_o,
	  OB => pps_cal_n_o
	  );
	  
	--sync clock output  
  cmp_obuf_clk : OBUFDS
	port map (
	  I  => clk_sync_out,		
	  O  => clk_sync_p_o,
	  OB => clk_sync_n_o
	  );
	

  -----------------------------------------------------------------------------
  -- IP configuration, get IP destination and source from DHCP through whisbone registers 
  -----------------------------------------------------------------------------	  
U_IP_cfg : ip_wb_config 
port map(
    clk_sys_i        	=> clk_sys,
	 rst_i 					=> rst,
	 set_dst_port_i		=> set_dst_port,
	 dst_port_i 	 		=> dst_port_cmd,
	 set_dst_ip_addr_i	=> set_dst_ip_addr,
	 dst_ip_addr_i 		=> dst_ip_addr_cmd,
    our_ip_addr_o 		=> our_ip_addr,
    dst_ip_addr_o 		=> dst_ip_addr,
    dst_port_o       	=> dst_port,
    ip_config_done_o 	=> open,						--ip_config_done,
    wb_o             	=> ip_cfg_wb_out,
    wb_i             	=> ip_cfg_wb_in
);

  -----------------------------------------------------------------------------
  -- UDP stack, TX & RX
  -----------------------------------------------------------------------------
  
  U_UDP_stack: udp_top 
  generic map( g_data_tx_width  		=> 96,	--number of bits,
					g_add_data_tx_width 	=> 128,  --number of bits,
					g_data_rx_width 		=> 64,	--number of bits
					g_nb_data_packed 		=> 24		--number of data packets in one UDP frame
					)		
  port map (
		clk_sys_i 			=> clk_sys,
		rst_n_i 				=> local_reset_n,				
		tx_data_i 			=> tx_data,
      tx_data_ready_i	=> tx_data_ready and (not stop_wr_fifo),				---tx_tag_valid,	
		add_tx_data_i		=> tx_add_info, 			--additionnal information sent once with bunch
		rx_data_o 			=> rx_data,
		rx_data_ready_o	=> rx_valid,
		src_i 				=> ext_src_in,				
		src_o 				=> ext_src_out,			
		snk_i 				=> ext_snk_in,				
		snk_o 				=> ext_snk_out,			
		cfg_mac_local_i 	=> x"000000000000",			
		cfg_mac_target_i	=> dst_mac_addr,			
		cfg_ip_local_i 	=> our_ip_addr,				
		cfg_ip_target_i 	=>	dst_ip_addr,					
		cfg_port_i 			=>	dst_port				
		---debug----
--		TRIG0   => TRIG0
--      TRIG1   => TRIG1
--      TRIG2   => TRIG2
--      TRIG3   => TRIG3
	);
  
--- decode commands received through UDP ----
	U_command_decoder : command_decoder 
		generic map(g_data_rx_width  => 64)
		port map ( 
			clk_i 					=> clk_sys,
		   command_i				=> rx_data,
		   data_valid_i			=> rx_valid,
			cnt_en_o					=> cnt_cmd,
			ext_trig_en_o			=> ext_trig_en,
			spi_en_o					=>	spi_en,
			set_dst_port_o			=> set_dst_port,
			dst_port_o 	 		   => dst_port_cmd,
			set_throttle_val_o 	=> set_throttle_val,
			set_dst_ip_addr_o		=> set_dst_ip_addr,
         dst_mac_addr_o 	 	=> dst_mac_addr,
			ext_trig_date_o		=> ext_trig_date,
			throttle_val_o			=> throttle_val,
			dst_ip_addr_o			=> dst_ip_addr_cmd
           );
	
	gen_with_trigger_throttler : if(g_with_trigger_throttler) generate
	---- Limit Tx rate if bunch rate is too high  >200us default ----
 U_Trigger_throttler : trigger_throttler
    Port map ( 
		clk_i 					=> clk_sys,
      rst_i 					=> rst,
		throttle_val_i			=> throttle_val,
      set_throttle_val_i	=> set_throttle_val,	
		tx_almost_empty_i 	=> tx_almost_empty,
      tx_almost_full_i 		=> tx_almost_full,
      stop_wr_o  				=> stop_wr_fifo
--		TRIG0   					=> TRIG0		
		);		  			  
  end generate gen_with_trigger_throttler;
  
  
  -- generate an external trigger at a date received through UDP
  U_ext_trig: ext_trig_gen 
  PORT MAP(
		clk_i 			 => clk_sys,
		clk_ref_i 		 => clk_125m_pllref,
		rst_i 			 => rst,
		ext_trig_en_i   => ext_trig_en,
		tm_seconds_i 	 => tm_seconds(24 downto 0),
		tm_cycles_i 	 => tm_cycles,
		ext_trig_date_i => ext_trig_date,
		ext_trig_o 		 => ext_trig
	);

----------------------------------------------------------------
  
  ----- double coarse WR timestamping  ----------
  U_Pulse_Stamper_evt : pulse_stamper
    generic map (
      g_ref_clk_rate => 125000000)
    port map (
      clk_ref_i 		 => clk_125m_pllref,
      clk_sys_i 		 => clk_sys,
      rst_n_i   		 => local_reset_n,
      pulse_a_i 		 => tdc_data_r1,  		-- time stamp fine TDC output ready: event trigger
      tm_time_valid_i => tm_time_valid,  		-- timing ports of the WR Core
      tm_tai_i        => tm_seconds,
      tm_cycles_i     => tm_cycles,
	-- time tag of the latest pulse
      tag_tai_o    	 => tx_tag_tai_evt,     ---seconds  
      tag_cycles_o 	 => tx_tag_cycles_evt,	---8ns tag
      tag_valid_o  	 => tx_tag_valid_evt
		);
	
	U_Pulse_Stamper_bsy : pulse_stamper
    generic map (
      g_ref_clk_rate => 125000000)
    port map (
      clk_ref_i 		 => clk_125m_pllref,
      clk_sys_i 		 => clk_sys,
      rst_n_i   		 => local_reset_n,
      pulse_a_i 		 => tdc_data_r2,  		-- time stamp fine TDC output ready: busy trigger
      tm_time_valid_i => tm_time_valid,  		-- timing ports of the WR Core
      tm_tai_i        => tm_seconds,
      tm_cycles_i     => tm_cycles,
	-- time tag of the latest pulse
      tag_tai_o    	 => tx_tag_tai_bsy,     ---seconds  
      tag_cycles_o 	 => tx_tag_cycles_bsy,	---8ns tag
      tag_valid_o  	 => tx_tag_valid_bsy
		);
	
  U_tdcx2: tdcx2 
	PORT MAP(
		reset 					=> rst or tdc_rst,
		clk_i 					=> clk_125m_pllref,		-- 125 MHz
--		tdc_en_i					=> tdc_en, 				-- event tdc clock enable--busy tdc clock enable
		ready_o 					=> open, 
		data1_i 					=> event_trig,		-- event input	
		data2_i 					=> busy_trig,		-- busy input	
		data1_o 					=> open,
		data2_o 					=> open,
		strobe1_o 				=> tdc_data_r1,
		strobe2_o 				=> tdc_data_r2,
		fine_time_stamp1_o 	=> tdc_data_evt,
		fine_time_stamp2_o 	=> tdc_data_busy
	);		
	
	U_counters : counters 
  port map(
     clk_i 				 => clk_sys,
	  clk_ref_i 		 => clk_125m_pllref,
     rst_i 		 		 => rst,
	  clk_sync_i		 => clk_sync,		
     busy_trig_i  	 => busy_trig,
     event_trig_i  	 => event_trig,
     cnt_en_i			 => cnt_cmd,
	  pps_csync_i	 	 => pps_csync,			-- Single-pulse PPS output for counters
     pps_i			 	 => pps_out,
	  cnt_en_ack_o 	 => cnt_en_ack,
     ext_trig_o 		 => ext_trig_rst,
	  event_flag_o	 	 => event_flag,
	  busy_flag_o	 	 => busy_flag, 
	  tdc_rst_o			 => tdc_rst,
     pps_cnt_o			 => pps_cnt,
     busy_cnt_o 	 	 => busy_cnt,
     event_cnt_o 	 	 => event_cnt,
     clk_cnt_o		 	 => clk_cnt
    );
	  
			--------- SPI slave -----------
	U_spi_slave : spi_slave 
	--generic map(N => g_spi_width)
	generic map(N => 16)
--- modification to solve problem with TIB interface 
--	generic map(N => 16,
--					CPOL => '1')
	PORT MAP(
		clk_i 		  => clk_sys,				--62,5MHz											--
		spi_ssel_i 	  => spi_ssel,			
		spi_sck_i	  => spi_sck,				
		spi_mosi_i 	  => spi_data,			 
		spi_miso_o 	  => open,
		di_req_o 	  => open,
		di_i 			  => (others => 'X'),
		wren_i 		  => 'X',
		wr_ack_o 	  => open,
		do_valid_o 	  => data_r_spi,
		do_o 			  => data_rx_spi,
		do_transfer_o => open,
		wren_o 		  => open,
		rx_bit_next_o => open,
		state_dbg_o   => open,
		sh_reg_dbg_o  => open
	);  
	
	-- pack data to be sent through UDP
	U_data_out_nofsm : data_out_nofsm 
	generic map( g_spi_timeout_val => 31)		--31 = 496ns @ 62.5MHz 
    Port map ( clk_i 				=> clk_sys,					--62,5MHz
			  clk_125m_pllref_i		=> clk_125m_pllref,		-- 125 MHz
           rst_i 						=> rst or (not cnt_en_ack),		--rst,
			  event_flag_i				=> event_flag,
			  busy_flag_i				=> busy_flag,
			  spi_en_i					=>	spi_en,
			  event_cnt_i				=> event_cnt(7 downto 0),			--event counter 8bits lsb
			  busy_cnt_i				=>	busy_cnt(7 downto 0),			--busy trigger counter 8bits lsb
			  pps_cnt_i					=> pps_cnt(1 downto 0),				--PPS counter	2bits lsb
			  clk_cnt_i					=> clk_cnt,								--clock counter 26bits
			  tx_tag_tai_evt_i		=> tx_tag_tai_evt(1 downto 0),			--seconds 2bits lsb
			  tx_tag_cycles_evt_i 	=> tx_tag_cycles_evt,				---8ns tag 28bits
			  tx_tag_tai_bsy_i		=> tx_tag_tai_bsy(1 downto 0),			--seconds 2bits lsb
			  tx_tag_cycles_bsy_i 	=> tx_tag_cycles_bsy,
			  tdc_data_evt_i			=> tdc_data_evt,					--1ns timestamp 3bits event trigger
			  tdc_data_bsy_i			=> tdc_data_busy,					--1ns timestamp 3bits busy trigger
			  data_rx_spi_i			=> data_rx_spi,					--Rx SPI data
			  tdc_evt_rdy_i			=> tdc_data_r1,
			  tdc_bsy_rdy_i			=> tdc_data_r2,
			  tm_time_valid_i			=> tm_time_valid,
			  tx_tag_valid_evt_i		=>	tx_tag_valid_evt,
			  tx_tag_valid_bsy_i		=>	tx_tag_valid_bsy,	
           data_r_spi_i 			=> data_r_spi,
			  tx_data_o					=> tx_data,
           tx_ready_o 				=> tx_data_ready
--			  tdc_en_o 					=> tdc_en
			 );


	U_ppsclock_sync: ppsclock_sync 
	PORT MAP(
		clk_i => clk_200M,
		rst_i => not tm_time_valid,		--reset if WR time is not valid
		pps_i => pps_out,
		clk_o => clk_sync1
	);


tailer_proc: PROCESS (event_cnt, busy_cnt,pps_cnt,tm_time_valid, cnt_en_ack, spi_en)
      BEGIN	  
			
		tx_add_info <= event_cnt & busy_cnt & pps_cnt & tx_tag_tai_evt(31 downto 0) &
						tm_time_valid & cnt_en_ack & '0' & x"0" & spi_en & std_logic_vector(g_dataformat_version);
  end process;
  
  
						
----------- aux diag registers-----------

	aux_diag_in(0)						<= dst_ip_addr;
	aux_diag_in(1)						<= dst_mac_addr(47 downto 16);
	aux_diag_in(2)(31 downto 16)	<= dst_mac_addr(15 downto 0);	
	aux_diag_in(3)(15 downto 0)	<= dst_port;
	aux_diag_in(4)						<= event_cnt;
	aux_diag_in(5)						<= busy_cnt;
	aux_diag_in(6)(7 downto 0)		<= std_logic_vector(g_dataformat_version);
	aux_diag_in(6)(23 downto 8)	<= throttle_val;
	aux_diag_in(6)(24)				<= '1' when g_with_trigger_throttler = TRUE else '0';
	aux_diag_in(6)(25)				<= tm_time_valid;
	aux_diag_in(6)(26)				<= spi_en;
	aux_diag_in(7)(7 downto 0)	   <= std_logic_vector(g_fw_version);
	
	
--	aux_diag_in(3)(8)				<= tm_time_valid;
--	aux_diag_in(3)(9)				<= cnt_en_ack;
--	aux_diag_in(3)(10)			<= spi_en;
--	aux_diag_in(3)(11)			<= stop_wr_fifo;
--	
--------------------------------

end rtl;


