----------------------------------------------------------------------------------
-- Company: CNRS
-- Engineer: CC
-- 
-- Create Date:    17:27:50 05/05/2015 
-- Design Name: 
-- Module Name:    udp_top - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Revision 0.02 - double FIFO, use WR FIFO
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

-- UDP/IP library
use work.data_IO.all;
use work.ipv4_types.all;

--WR library
use work.wr_fabric_pkg.all;
use work.genram_pkg.all;

entity udp_top is
	generic( 
			g_data_tx_width  		: natural := 16;
			g_add_data_tx_width 	: natural := 16;
			g_nb_data_packed 		: natural := 20;
			g_data_rx_width  		: natural := 16
			);
    Port ( 
			clk_sys_i : in std_logic;
			rst_n_i   : in std_logic;
					
      -- Endpoint/WRC interface - packet source
			src_i : in  t_wrf_source_in;
			src_o : out t_wrf_source_out;
			
		-- Endpoint/WRC interface - packet sink
			snk_i : in  t_wrf_sink_in;
			snk_o : out t_wrf_sink_out;
			
    ---------------------------------------------------------------------------
    -- User interface
    ---------------------------------------------------------------------------
		-----TX
		 -- Data word to be sent. 
         tx_data_i 			: in  STD_LOGIC_VECTOR (g_data_tx_width-1 downto 0);
		 -- 1 indicates that the tx_data_i contains a valid data word.
         tx_data_ready_i 	: in  STD_LOGIC;
		--additionnal information sent once with bunch
			add_tx_data_i		: in  STD_LOGIC_VECTOR (g_add_data_tx_width-1 downto 0);			
			
		----RX
		-- Data word received. 
         rx_data_o 			: out  STD_LOGIC_VECTOR (g_data_rx_width-1 downto 0);
		 -- 1 indicates that the rx_data_o contains a valid data word.
         rx_data_ready_o 	: out  STD_LOGIC;

			---------------------------------------------------------------------------
    -- Configuration
    ---------------------------------------------------------------------------

		-- Local MAC address. Leave at 0 when using with the WR MAC/Core, it will
		-- insert its own source MAC.
			cfg_mac_local_i : in std_logic_vector(47 downto 0) := x"000000000000";
		-- Destination MAC address.
			cfg_mac_target_i : in std_logic_vector(47 downto 0);
		--IP address. .
			cfg_ip_local_i  : in std_logic_vector(31 downto 0) := x"C0A80064"; 		--IP src 192.168.0.100
			cfg_ip_target_i : in std_logic_vector(31 downto 0) := x"C0A8000A";  		--IP dst 192.168.0.10		 
		--Port
			cfg_port_i : in std_logic_vector (15 downto 0)  := x"D6D8";	--port 55000
			
			-- Tx FIFO signals
			--reset_fifo_i		: in std_logic;
			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 udp_top;

architecture Behavioral of udp_top is

 type t_pipe is record
    dvalid : std_logic;
    dreq   : std_logic;
    sof    : std_logic;
    eof    : std_logic;
    error  : std_logic;
    data   : std_logic_vector(15 downto 0);
  end record;
  
--------------------------------------------
-- UDP/IP stack without MAC, use WR core MAC
--------------------------------------------
	component UDP_Complete_nomac is
    port (
			-- UDP TX signals
			udp_tx_start			: in std_logic;							-- indicates req to tx UDP
			udp_txi					: in udp_tx_type;							-- UDP tx cxns
			udp_tx_result			: out std_logic_vector (1 downto 0);-- tx status (changes during transmission)
			udp_tx_data_out_ready: out std_logic;							-- indicates udp_tx is ready to take data
			-- UDP RX signals
			udp_rx_start			: out std_logic;							-- indicates receipt of udp header
			udp_rxo					: out udp_rx_type;
			-- IP RX signals
			ip_rx_hdr				: out ipv4_rx_header_type;
			-- system signals
			rx_clk					: in  STD_LOGIC;
			tx_clk					: in  STD_LOGIC;
			reset 					: in  STD_LOGIC;
			our_ip_address 		: in STD_LOGIC_VECTOR (31 downto 0);
			our_mac_address 		: in std_logic_vector (47 downto 0);
			dst_mac_address    	: in  std_logic_vector (47 downto 0);
--			control					: in udp_control_type;
			-- status signals
			ip_pkt_count			: out STD_LOGIC_VECTOR(7 downto 0);			-- number of IP pkts received for us
			-- MAC Transmitter
			mac_tx_tdata         : out  std_logic_vector(15 downto 0);	-- data byte to tx
			mac_tx_tvalid        : out  std_logic;							-- tdata is valid
			mac_tx_tready        : in std_logic;							-- mac is ready to accept data
			mac_tx_tfirst        : out  std_logic;							-- indicates first byte of frame
			mac_tx_tlast         : out  std_logic;							-- indicates last byte of frame
			-- MAC Receiver
			mac_rx_tdata         : in std_logic_vector(15 downto 0);	-- data byte received
			mac_rx_tvalid        : in std_logic;							-- indicates tdata is valid
			mac_rx_tready        : out  std_logic;							-- tells mac that we are ready to take data
			mac_rx_tlast         : in std_logic;								-- indicates last byte of the trame
			-- Stored source MAC address
			mac_src_o : out std_logic_vector(47 downto 0)
--			src_addr_o 				: out src_addr_type
			----debug----
--			TRIG0 : 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;
	
	component xwb_fabric_source
    port (
      clk_i     : in  std_logic;
      rst_n_i   : in  std_logic;
      src_i     : in  t_wrf_source_in;
      src_o     : out t_wrf_source_out;
      addr_i    : in  std_logic_vector(1 downto 0);
      data_i    : in  std_logic_vector(15 downto 0);
      dvalid_i  : in  std_logic;
      sof_i     : in  std_logic;
      eof_i     : in  std_logic;
      error_i   : in  std_logic;
      bytesel_i : in  std_logic;
      dreq_o    : out std_logic);
	end component;
	
	component xwb_fabric_sink 
	  port (
		 clk_i   	: in std_logic;
		 rst_n_i 	: in std_logic;
		 snk_i 		: in  t_wrf_sink_in;
		 snk_o 		: out t_wrf_sink_out;
		 addr_o    	: out std_logic_vector(1 downto 0);
		 data_o    	: out std_logic_vector(15 downto 0);
		 dvalid_o  	: out std_logic;
		 sof_o     	: out std_logic;
		 eof_o     	: out std_logic;
		 error_o  	: out std_logic;
		 bytesel_o 	: out std_logic;
		 dreq_i    	: in  std_logic);
	end component;

COMPONENT udp_tx_fsm
	generic(
		 g_data_tx_width  	: natural := 16;
		 g_nb_data_packed 	: natural := 20;		--number of data packets in one UDP frame
		 g_add_data_tx_width : natural := 16;
		 g_udp_cmd_width 		: natural := 16	-- UDP command width
		 );
    Port (
		clk_i							: in std_logic;
		rst_i							: in std_logic;
		--- configuration
		port_dstsrc_i 				: in std_logic_vector(15 downto 0);
		cfg_ip_target_i 			: in std_logic_vector(31 downto 0) := x"C0A80010";  			--IP dst 192.168.0.10
		-- Destination MAC address for data
		cfg_mac_target_i : in std_logic_vector(47 downto 0);
		-- Destination MAC address for ack
		mac_target_ack_i : in std_logic_vector(47 downto 0);
		-- Destination MAC address
		mac_target_o : out std_logic_vector(47 downto 0);
		-- UDP TX 
		udp_tx_start				: out std_logic;								-- indicates req to tx UDP
		udp_tx_o						: out udp_tx_type;							-- UDP tx cxns
		udp_tx_result				: in std_logic_vector(1 downto 0);		-- tx status (changes during transmission)
		udp_tx_data_out_ready	: in std_logic;								-- indicates udp_tx is ready to take data		
		busy_o						: out std_logic;	
		add_tx_data_i				: in std_logic_vector(g_add_data_tx_width-1 downto 0);
		-- UDP RX header 
		udp_rx_hdr_i				: in udp_rx_header_type;		--udp_rx_type;
		-- UDP command ack
		udp_ack_i					: in std_logic :='0';
		udp_cmd_ack_i				: in std_logic_vector (g_udp_cmd_width-1 downto 0);
		--addr_ack_i 					: in src_addr_type;
		udp_ack_done_o				: out std_logic;		
		--- FIFO interface	
		data4tx_i					: in std_logic_vector(g_data_tx_width-1 downto 0);     -- data for tx
		rd_en_o						: out std_logic;	
		data_cnt_i  				: in std_logic_vector(f_log2_size(2*g_nb_data_packed)-1 downto 0);
		almost_full_i  			: in std_logic;
		tx_timeout_hit_i			: in std_logic;
		fifo_mux_o 					: out std_logic
		--------Debug-----
--		TRIG0 : out std_logic_vector(31 downto 0);
--		TRIG1 : out std_logic_vector(31 downto 0)
	 );
END COMPONENT;

--FIFO multiplexer to shift FIFO when read
COMPONENT fifo_mux
	generic(
		 g_tx_timeout : natural := 655000 --	~10ms
		 );
	PORT(
		clk_i 				: in std_logic;
		rst_i 				: in std_logic;
		fifo_mux_i			: in  STD_LOGIC;
		wr_en_i 				: in std_logic;
		rd_en_i 				: in std_logic;
		almost_full1_i 	: in std_logic;
		almost_full2_i 	: in std_logic;
		almost_empty1_i	: in std_logic;
      almost_empty2_i	: in std_logic;
--		tx_timeout_hit_i	: in std_logic;
		empty1_i				: in std_logic;
		empty2_i				: in std_logic;
		data_cnt1_i			: in std_logic_vector(5 downto 0);
		data_cnt2_i			: in std_logic_vector(5 downto 0);
		wr_data_i 			: in std_logic_vector(95 downto 0);
		rd_data1_i			: in std_logic_vector(95 downto 0);
      rd_data2_i			: in std_logic_vector(95 downto 0);
		wr_en1_o 			: out std_logic;
		rd_en1_o				: out std_logic;
		wr_en2_o 			: out std_logic;
		rd_en2_o 			: out std_logic;          
		almost_full_o 		: out std_logic;
		almost_empty_o 	: out std_logic;
		tx_timeout_hit_o	: out STD_LOGIC;
		data_cnt_o			: out std_logic_vector(5 downto 0);
		wr_data1_o 			: out std_logic_vector(95 downto 0);
		wr_data2_o 			: out std_logic_vector(95 downto 0);
		rd_data_o 			: out std_logic_vector(95 downto 0)
		);
	END COMPONENT;

--COMPONENT tx_fifo	
--  PORT (
--    rst : in STD_LOGIC;
--    wr_clk : in STD_LOGIC;
--    rd_clk : in STD_LOGIC;
--    din : in STD_LOGIC_VECTOR(95 DOWNTO 0);
--    wr_en : in STD_LOGIC;
--    rd_en : in STD_LOGIC;
--    dout : out STD_LOGIC_VECTOR(95 DOWNTO 0);
--    full : out STD_LOGIC;
--    empty : out STD_LOGIC;
--    almost_empty : out STD_LOGIC;
--    rd_data_count : out STD_LOGIC_VECTOR(5 DOWNTO 0);
--    prog_full : out STD_LOGIC
--  );
--END COMPONENT;


--	COMPONENT tx_fifo
--  PORT (
--    clk : in STD_LOGIC;
--    rst : in STD_LOGIC;
--    din : in STD_LOGIC_VECTOR(95 DOWNTO 0);
--    wr_en : in STD_LOGIC;
--    rd_en : in STD_LOGIC;
--    dout : out STD_LOGIC_VECTOR(95 DOWNTO 0);
--    full : out STD_LOGIC;
--    empty : out STD_LOGIC;
--    almost_empty : out STD_LOGIC;
--    data_count : out STD_LOGIC_VECTOR(5 DOWNTO 0);
--	 prog_full : out STD_LOGIC
--  );
--END COMPONENT;

	component udp_rx_fsm
		generic(
			g_data_rx_width  : natural := 16
			);
		 port(
			rst_i 			: in std_logic;
			clk_i 			: in std_logic;
			udp_rx_start_i : in std_logic;
			udp_rx_i 		: in udp_rx_type;  
			-- Stored source addresses
			src_addr_i 		: out src_addr_type;
			udp_rx_data_o 	: out STD_LOGIC_VECTOR (g_data_rx_width-1 downto 0);
			data_valid_o 	: out std_logic;
			-- checked source addresses
			src_addr_o 				: out src_addr_type
		);
	end component;
	
	signal fab_src, fab_snk   	: t_pipe;
	signal udp_src_i 				: t_wrf_source_in;
   signal udp_src_o 				: t_wrf_source_out;
	signal rst_p, delay_eof		: std_logic;
	signal data_fifo2udptx, wr_data1, wr_data2, rd_data1, rd_data2	: std_logic_vector(g_data_tx_width-1 downto 0);
	
	--FIFO Tx signals
	signal  busy, tx_rd_en, tx_rd_en1, tx_rd_en2, tx_almost_empty1, tx_almost_empty2, tx_almost_full, tx_almost_full1, tx_almost_full2 : std_logic;		--tx_almost_empty,
	signal datatx_count, datatx_count1,  datatx_count2 : std_logic_vector(f_log2_size(2*g_nb_data_packed)-1 downto 0);	
	signal tx_timeout_hit: std_logic;
	signal tx_almost_empty, tx_empty1, tx_empty2: std_logic;
	signal stop_trig, fifo_mux_s, wr_en_fifo1, wr_en_fifo2 : std_logic;	
--	signal rst_n_fifo : std_logic;
	signal mac_target : std_logic_vector(47 downto 0);
	signal mac_src_ack 	:  std_logic_vector(47 downto 0);
	---RX signals 
	signal rx_data, udp_cmd_buf   : std_logic_vector(g_data_rx_width-1 downto 0);
	signal rx_data_ready 			: std_logic;
	signal udp_ack_done, udp_ack  : std_logic;
	signal src_addr, addr_ack 		: src_addr_type;
-- UDP signals
	signal udp_tx_result 	: std_logic_vector(1 downto 0);
	signal udp_txi				: udp_tx_type;
	signal udp_rx				: udp_rx_type;
--	signal control_udp		: udp_control_type;
	signal ip_pkt_count : std_logic_vector(7 downto 0);
	signal udp_tx_start, udp_rx_start, udp_tx_data_out_ready		: std_logic;
	
begin
	
	  --------active high reset----
	rst_p <= not rst_n_i; 		-- !!!! Active high reset on UDP ip !!!!!
	
	udp_src_i 			<= src_i;
	src_o 				<= udp_src_o;
	rx_data_o 			<= rx_data;
	rx_data_ready_o 	<= rx_data_ready;
	tx_almost_empty_o	<= tx_almost_empty;
	tx_almost_full_o 	<= tx_almost_full;

	UDP_Complete_nomac_i : UDP_Complete_nomac	
	port map (
		-- UDP TX signals
		udp_tx_start				=>	udp_tx_start,				-- indicates req to tx UDP
		udp_txi						=>	udp_txi,
		udp_tx_result				=> udp_tx_result,				-- tx status (changes during transmission)
		udp_tx_data_out_ready	=> udp_tx_data_out_ready,	-- indicates udp_tx is ready to take data
		-- UDP RX signals
		udp_rx_start				=> udp_rx_start,				-- indicates receipt of udp header
		udp_rxo						=> udp_rx,
		-- IP RX signals
		ip_rx_hdr					=> open,
		-- system signals
		rx_clk						=>	clk_sys_i,			--62,5MHZ				--Clk_125_Mhz,
		tx_clk						=>	clk_sys_i,			--62,5MHZ				--Clk_125_Mhz,
		reset 						=> rst_p,
		our_ip_address 			=>	cfg_ip_local_i, 					
		our_mac_address 			=>	cfg_mac_local_i,	
		dst_mac_address			=>	mac_target,							--cfg_mac_target_i,
--		control						=> control_udp,
		-- status signals
		ip_pkt_count				=> ip_pkt_count,		-- number of IP pkts received for us
		-- MAC Transmitter
		mac_tx_tdata         	=> fab_src.data,		-- data to tx
		mac_tx_tvalid        	=> fab_src.dvalid,	-- tdata is valid
		mac_tx_tready        	=>	fab_src.dreq,		-- mac is ready to accept data
		mac_tx_tfirst        	=> fab_src.sof,		-- indicates first byte of frame
		mac_tx_tlast         	=> fab_src.eof,		--delay_eof,		-- indicates last byte of frame
		-- MAC Receiver
		mac_rx_tdata         	=>	fab_snk.data,		-- data byte received
		mac_rx_tvalid        	=>	fab_snk.dvalid,	-- indicates tdata is valid
		mac_rx_tready        	=> fab_snk.dreq,		-- tells mac that we are ready to take data
		mac_rx_tlast         	=> fab_snk.eof,			-- indicates last byte of the trame
		-- Stored source MAC address
		mac_src_o 					=> mac_src_ack
--		src_addr_o 					=> src_addr
--		TRIG2 						=> TRIG2,
--		TRIG3 						=> TRIG3
		);
			
			
	U_Fab_Source : xwb_fabric_source
    port map(
      clk_i     => clk_sys_i,
      rst_n_i   => rst_n_i,
      src_i     => udp_src_i,
      src_o     => udp_src_o,
      addr_i    => c_WRF_DATA,		-- "00"
      data_i    => fab_src.data, 	-- 16bits
      dvalid_i  => fab_src.dvalid,
      sof_i     => fab_src.sof,
      eof_i     => fab_src.eof,
      error_i   => '0',
      bytesel_i => '0',
      dreq_o    => fab_src.dreq
		);
		
		
	U_Fab_Sink : xwb_fabric_sink 
	  port map(
		 clk_i     => clk_sys_i,
       rst_n_i   => rst_n_i,
		 snk_i 	  => snk_i,
		 snk_o 	  => snk_o,
		 addr_o    => open,
		 data_o    => fab_snk.data,
		 dvalid_o  => fab_snk.dvalid,
		 sof_o     => open,
		 eof_o     => fab_snk.eof,
		 error_o   => open,
		 bytesel_o => open,
		 dreq_i    => fab_snk.dreq);	
		 
--------- Tx ----
	
	U_udp_tx_fsm : udp_tx_fsm 
	generic map(
		 g_data_tx_width  	=> g_data_tx_width,
		 g_add_data_tx_width => g_add_data_tx_width,
		 g_nb_data_packed 	=> g_nb_data_packed, --number of g_data_tx_width data packed in one UDP frame 
		 g_udp_cmd_width		=> g_data_rx_width 	-- UDP command width for ack
		 )	
    port map(
		clk_i					=> clk_sys_i,
		rst_i					=>  rst_p,
		--- configuration
		port_dstsrc_i 		=> cfg_port_i,
		cfg_ip_target_i 	=> cfg_ip_target_i,
		cfg_mac_target_i 	=> cfg_mac_target_i,
		-- Destination MAC address for ack
		mac_target_ack_i  => mac_src_ack,
		-- Destination MAC address
		mac_target_o		=> mac_target,
		-- UDP TX 
		udp_tx_start				=>	udp_tx_start,				-- indicates req to tx UDP
		udp_tx_o						=> udp_txi,						-- UDP tx cxns
		udp_tx_result				=> udp_tx_result,				-- tx status (changes during transmission)
		udp_tx_data_out_ready	=> udp_tx_data_out_ready,	-- indicates udp_tx is ready to take data		
		busy_o						=> busy,	
		add_tx_data_i				=> add_tx_data_i,
		-- UDP RX header 
		udp_rx_hdr_i				=> udp_rx.hdr,
		-- UDP command ack
		udp_ack_i					=> udp_ack,
		udp_cmd_ack_i				=> udp_cmd_buf,
--		addr_ack_i 					=> addr_ack,
		udp_ack_done_o				=> udp_ack_done,
		--- FIFO interface	
		data4tx_i			=> data_fifo2udptx,    -- data for tx
		rd_en_o				=> tx_rd_en,
		fifo_mux_o			=> fifo_mux_s,
		tx_timeout_hit_i	=> tx_timeout_hit,
		data_cnt_i 			=> datatx_count,
		almost_full_i  	=> tx_almost_full 		
		--------Debug-----
--		TRIG0 => TRIG0,
--		TRIG1 => TRIG1
	 );
	
	U_fifo_mux: fifo_mux 
	generic map (
			g_tx_timeout 			=> 6550000 -- ~100ms --13100000	-- 200ms	--3275000
			)
	PORT MAP(
		clk_i 				=> clk_sys_i,
		rst_i 				=> rst_p,		--not rst_n_fifo, 
		fifo_mux_i			=> fifo_mux_s,		--udp_txi.data.data_out_last,
		wr_en_i 				=> tx_data_ready_i,
		rd_en_i 				=> tx_rd_en,
		data_cnt1_i			=> datatx_count1,
		data_cnt2_i			=> datatx_count2,
		almost_full1_i 	=> tx_almost_full1,
		almost_full2_i 	=> tx_almost_full2,
		almost_empty1_i	=> tx_almost_empty1,
		almost_empty2_i	=> tx_almost_empty2,
		empty1_i				=> tx_empty1,
		empty2_i				=> tx_empty2,
		wr_data_i 			=> tx_data_i,
		rd_data1_i 			=> rd_data1,
		rd_data2_i 			=> rd_data2,
		wr_en1_o 			=> wr_en_fifo1,
		rd_en1_o 			=> tx_rd_en1,
		wr_en2_o 			=> wr_en_fifo2,
		rd_en2_o 			=> tx_rd_en2,
		almost_full_o 		=> tx_almost_full,
		almost_empty_o		=> tx_almost_empty,
		tx_timeout_hit_o	=> tx_timeout_hit,
		data_cnt_o			=> datatx_count,
		wr_data1_o 			=> wr_data1,
		wr_data2_o 			=> wr_data2,
		rd_data_o 			=> data_fifo2udptx
	);		

U_TX_Buffer1 : generic_sync_fifo
    generic map (
      g_data_width             => g_data_tx_width,
      g_size                   => 2*g_nb_data_packed,
      g_with_almost_full       => true,
		g_with_almost_empty      => true,
      g_almost_empty_threshold => 1,
      g_almost_full_threshold  => g_nb_data_packed,
		g_with_count        	 	 => true,
      g_show_ahead         	 => true
		)
    port map (
      rst_n_i        => rst_n_i,
      clk_i          => clk_sys_i,
      d_i            => wr_data1,
      we_i           => wr_en_fifo1,
      q_o            => rd_data1,				--data_fifo2udptx1,
      rd_i           => tx_rd_en1,
      empty_o        => tx_empty1,
      full_o         => open,
      almost_empty_o => tx_almost_empty1,
      almost_full_o  => tx_almost_full1,
		count_o			=> datatx_count1
      );
		 
 U_TX_Buffer2 : generic_sync_fifo
    generic map (
      g_data_width             => g_data_tx_width,
      g_size                   => 2*g_nb_data_packed,
      g_with_almost_full       => true,
		g_with_almost_empty      => true,
      g_almost_empty_threshold => 1,
      g_almost_full_threshold  => g_nb_data_packed,
		g_with_count        	 	 => true,
      g_show_ahead         	 => true
		)
    port map (
      rst_n_i        => rst_n_i,
      clk_i          => clk_sys_i,
      d_i            => wr_data2,
      we_i           => wr_en_fifo2,
      q_o            => rd_data2, 					--data_fifo2udptx2,
      rd_i           => tx_rd_en2,
      empty_o        => tx_empty2,
      full_o         => open,
      almost_empty_o => tx_almost_empty2,
      almost_full_o  => tx_almost_full2,
		count_o			=> datatx_count2
      );

--------------End Tx ------------------------- 
		 
--- Extract RXdata -------- 
	U_udp_rx_fsm: udp_rx_fsm 
	generic map(
		g_data_rx_width => g_data_rx_width) 
	port map(
		rst_i 			=> rst_p,
		clk_i 			=> clk_sys_i,
		udp_rx_start_i => udp_rx_start,
		udp_rx_i 		=> udp_rx,
		src_addr_i		=> src_addr,
		udp_rx_data_o 	=> rx_data,
		data_valid_o 	=> rx_data_ready, 
		src_addr_o		=> addr_ack
	);
	
	--- UDP command buffer -----
	process (clk_sys_i)
	begin
	if rising_edge(clk_sys_i)then
		if (rst_p = '1') then	
			udp_ack		<= '0';
			udp_cmd_buf <= (others => '0');
		elsif (rx_data_ready = '1') then
			udp_ack		<= '1';
			udp_cmd_buf	<= rx_data; 			--x"FEDCBA9876543210";
		elsif (udp_ack_done = '1') then
			udp_ack		<= '0';
--			udp_cmd_buf	<= (others => '0');
		end if;
	end if;
	end process;	

	
	-----DEBUG-----
--	TRIG0(31)				<= rx_data_ready;	
--	TRIG0(30 downto 0)	<= rx_data(30 downto 0);		--event counter
--	TRIG0(22)				<= tx_almost_empty;
--	TRIG0(21)				<= tx_rd_en;
--	TRIG0(20)				<= tx_data_ready_i;
--	TRIG0(19)				<= fifo_mux_s;
--	TRIG0(18)				<= tx_timeout_hit;
--	TRIG0(17)				<= tx_almost_full2;
--	TRIG0(16)				<= tx_almost_full1;
--	TRIG0(15 downto 10)	<= datatx_count1;
--	TRIG0(9 downto 4)		<= datatx_count2;
--	TRIG0(3)	<= tx_rd_en1;
--	TRIG0(2)	<= tx_rd_en2;
--	TRIG0(1)	<= wr_en_fifo1;
--	TRIG0(0)	<= wr_en_fifo2;
--	TRIG0(15 downto 0)	<= data_fifo2udptx;	
	
--	TRIG1(31 downto 20)	<= tx_data_i(91 downto 80); 	--SPI data trigger counter
--	TRIG1(19 downto 12)	<= tx_data_i(79 downto 72);		--event counter
--	TRIG1(11 downto 5)	<= tx_data_i(70 downto 64);		--busy counter
--	TRIG1(4)					<= tx_data_ready_i;
--	TRIG1(3)					<= tx_timeout_hit;
--	TRIG1(2)					<= tx_almost_full2;
--	TRIG1(1)					<= tx_almost_full1;
--	TRIG1(0)					<= fifo_mux_s;
--	
--	--TRIG2(31 downto 25) 	<= rd_datatx_count;
--	TRIG2(24 downto 9) 	<= udp_txi.hdr.data_length; 
--	
--	TRIG1(22) 				<= udp_src_i.ack;
--	TRIG1(23) 				<= udp_src_i.err;
--	TRIG1(24) 				<= udp_src_i.stall;
	
--	TRIG1(15 downto 0) 	<= udp_txi.data.data_out;
--	TRIG1(30) 				<= udp_tx_start;
--	TRIG1(31) 				<= udp_tx_data_out_ready;
--	TRIG2(15 downto 0) 	<= fab_src.data;
--	TRIG2(28) 				<= fab_src.dreq;
--	TRIG2(29) 				<= fab_src.dvalid;
--	TRIG2(30) 				<= fab_src.eof;
--	TRIG2(31) 				<= fab_src.sof;
--	TRIG3(15 downto 0) 	<= udp_txi.hdr.data_length;
--	TRIG3(31 downto 16) 	<= udp_txi.hdr.dst_ip_addr(31 downto 16);
		
end Behavioral;
