library ieee;
use ieee.std_logic_1164.all;

library fifo_related;

entity xilly_userlogiccmp_wrapper is
  port (
		i_clk : in std_logic;
		i_rst : in std_logic;
		
		user_r_control_r_rden : in std_logic;
		user_r_control_r_empty : out std_logic := '1';
		user_r_control_r_data : out std_logic_vector(31 DOWNTO 0) := ( others => '0' );
		
		user_w_control_w_wren : in std_logic;
		user_w_control_w_full : out std_logic := '0';
		user_w_control_w_data : in std_logic_vector(31 DOWNTO 0);
		
		user_r_data1_r_rden : in std_logic;
		user_r_data1_r_empty : out std_logic := '1';
		user_r_data1_r_data : out std_logic_vector(31 DOWNTO 0) := ( others => '0' );
		
		user_w_data1_w_wren : in std_logic;
		user_w_data1_w_full : out std_logic := '0';
		user_w_data1_w_data : in std_logic_vector(31 DOWNTO 0);
		
		user_r_data2_r_rden : in std_logic;
		user_r_data2_r_empty : out std_logic := '1';
		user_r_data2_r_data : out std_logic_vector(31 DOWNTO 0) := ( others => '0' );
		
		user_w_data2_w_wren : in std_logic;
		user_w_data2_w_full : out std_logic := '0';
		user_w_data2_w_data : in std_logic_vector(31 DOWNTO 0)
	);
end entity;

architecture behavioral of xilly_userlogiccmp_wrapper is

	component user_logic_cmp
		port (
			i_clk : in std_logic;
			i_rst : in std_logic;
			
			-- data1 interface:
			i_data1in_data		: in std_logic_vector( 31 downto 0 );
			i_data1in_valid   : in std_logic;
			o_data1in_enable	: out std_logic;
			o_data1out_data  	: out std_logic_vector( 31 downto 0 );
			o_data1out_valid	: out std_logic;
			i_data1out_enable	: in std_logic;
			
			-- data2 interface:
			i_data2in_data		: in std_logic_vector( 31 downto 0 );
			i_data2in_valid   : in std_logic;
			o_data2in_enable	: out std_logic := '1';
			o_data2out_data  	: out std_logic_vector( 31 downto 0 );
			o_data2out_valid	: out std_logic := '0';
			i_data2out_enable	: in std_logic;
			
			-- control interface:
			i_controlin_data		: in std_logic_vector( 31 downto 0 );
			i_controlin_valid   : in std_logic;
			o_controlin_enable	: out std_logic := '1';
			o_controlout_data  	: out std_logic_vector( 31 downto 0 );
			o_controlout_valid	: out std_logic := '0';
			i_controlout_enable	: in std_logic
		);
	end component;
	
  component fifo_32x512
    port (
      clk: IN std_logic;
      srst: IN std_logic;
      din: IN std_logic_vector(31 downto 0) := ( others => '0' );
      wr_en: IN std_logic := '0';
      rd_en: IN std_logic;
      dout: OUT std_logic_vector(31 downto 0);
			valid: OUT std_logic;
      full: OUT std_logic;
      empty: OUT std_logic
		);
  end component;

	-- data1 signals
	signal s_data1_ffin2fte_data : std_logic_vector( 31 downto 0 );
	signal s_data1_ffin2fte_rden : std_logic;
	signal s_data1_ffin2fte_empty : std_logic;
		
	signal s_data1_fte2ul_data : std_logic_vector( 31 downto 0 );
	signal s_data1_fte2ul_valid : std_logic;
	signal s_data1_fte2ul_enable : std_logic;
	
	signal s_data1_ul2ffout_data : std_logic_vector( 31 downto 0 );
	signal s_data1_ul2ffout_valid : std_logic;
	signal s_data1_ul2ffout_enable : std_logic;
	signal s_data1_ul2ffout_full : std_logic;
	
	-- data2 signals
	signal s_data2_ffin2fte_data : std_logic_vector( 31 downto 0 );
	signal s_data2_ffin2fte_rden : std_logic;
	signal s_data2_ffin2fte_empty : std_logic;
		
	signal s_data2_fte2ul_data : std_logic_vector( 31 downto 0 );
	signal s_data2_fte2ul_valid : std_logic;
	signal s_data2_fte2ul_enable : std_logic;
	
	signal s_data2_ul2ffout_data : std_logic_vector( 31 downto 0 );
	signal s_data2_ul2ffout_valid : std_logic;
	signal s_data2_ul2ffout_enable : std_logic;
	signal s_data2_ul2ffout_full : std_logic;
	
	-- control signals
	signal s_control_ffin2fte_data : std_logic_vector( 31 downto 0 );
	signal s_control_ffin2fte_rden : std_logic;
	signal s_control_ffin2fte_empty : std_logic;
		
	signal s_control_fte2ul_data : std_logic_vector( 31 downto 0 );
	signal s_control_fte2ul_valid : std_logic;
	signal s_control_fte2ul_enable : std_logic;
	
	signal s_control_ul2ffout_data : std_logic_vector( 31 downto 0 );
	signal s_control_ul2ffout_valid : std_logic;
	signal s_control_ul2ffout_enable : std_logic;
	signal s_control_ul2ffout_full : std_logic;
		
begin
	
	------------------------------------------------------

	--data1_gen : if( C_USES_DATA1_INTERFACE = '1' ) generate
	-- FIFO_IN instantiation:
	data1_fifo_in_inst : fifo_32x512
		port map (
			clk => i_clk, srst => i_rst,
			din => user_w_data1_w_data, wr_en => user_w_data1_w_wren, full => user_w_data1_w_full,
			dout => s_data1_ffin2fte_data, rd_en => s_data1_ffin2fte_rden, empty => s_data1_ffin2fte_empty,
			valid => open );
				
	-- FIFO_to_enable instantiation:
	data1_fifo_to_enable_inst : entity fifo_related.fifo_to_enable
		port map (
			clk => i_clk, reset => i_rst,
			din => s_data1_ffin2fte_data, rden => s_data1_ffin2fte_rden, empty => s_data1_ffin2fte_empty,
			data => s_data1_fte2ul_data, valid => s_data1_fte2ul_valid, enable => s_data1_fte2ul_enable );
		
	-- FIFO_OUT instantiation:
	data1_fifo_out_inst : fifo_32x512
		port map (
			clk => i_clk, srst => i_rst,
			din => s_data1_ul2ffout_data, wr_en => s_data1_ul2ffout_valid, full => s_data1_ul2ffout_full,
			dout => user_r_data1_r_data, rd_en => user_r_data1_r_rden, empty => user_r_data1_r_empty,
			valid => open );
	s_data1_ul2ffout_enable <= not s_data1_ul2ffout_full;
	
	-- generate;
	
	------------------------------------------------------
	
	--data2_gen : if( C_USES_DATA2_INTERFACE = '1' ) generate
	-- FIFO_IN instantiation:
	data2_fifo_in_inst : fifo_32x512
		port map (
			clk => i_clk, srst => i_rst,
			din => user_w_data2_w_data, wr_en => user_w_data2_w_wren, full => user_w_data2_w_full,
			dout => s_data2_ffin2fte_data, rd_en => s_data2_ffin2fte_rden, empty => s_data2_ffin2fte_empty,
			valid => open );
		
	-- FIFO_to_enable instantiation:
	data2_fifo_to_enable_inst : entity fifo_related.fifo_to_enable
		port map (
			clk => i_clk, reset => i_rst,
			din => s_data2_ffin2fte_data, rden => s_data2_ffin2fte_rden, empty => s_data2_ffin2fte_empty,
			data => s_data2_fte2ul_data, valid => s_data2_fte2ul_valid, enable => s_data2_fte2ul_enable );
		
	-- FIFO_OUT instantiation:
	data2_fifo_out_inst : fifo_32x512
		port map (
			clk => i_clk, srst => i_rst,
			din => s_data2_ul2ffout_data, wr_en => s_data2_ul2ffout_valid, full => s_data2_ul2ffout_full,
			dout => user_r_data2_r_data, rd_en => user_r_data2_r_rden, empty => user_r_data2_r_empty,
			valid => open );
	s_data2_ul2ffout_enable <= not s_data2_ul2ffout_full;

	--end generate;
	
	----------------------------------------------------------
	
	--control_gen : if( C_USES_CONTROL_INTERFACE = '1' ) generate
	-- FIFO_IN instantiation:
	control_fifo_in_inst : fifo_32x512
		port map (
			clk => i_clk, srst => i_rst,
			din => user_w_control_w_data, wr_en => user_w_control_w_wren, full => user_w_control_w_full,
			dout => s_control_ffin2fte_data, rd_en => s_control_ffin2fte_rden, empty => s_control_ffin2fte_empty,
			valid => open );
		
	-- FIFO_to_enable instantiation:
	control_fifo_to_enable_inst : entity fifo_related.fifo_to_enable
		port map (
			clk => i_clk, reset => i_rst,
			din => s_control_ffin2fte_data, rden => s_control_ffin2fte_rden, empty => s_control_ffin2fte_empty,
			data => s_control_fte2ul_data, valid => s_control_fte2ul_valid, enable => s_control_fte2ul_enable );
		
	-- FIFO_OUT instantiation:
	control_fifo_out_inst : fifo_32x512
		port map (
			clk => i_clk, srst => i_rst,
			din => s_control_ul2ffout_data, wr_en => s_control_ul2ffout_valid, full => s_control_ul2ffout_full,
			dout => user_r_control_r_data, rd_en => user_r_control_r_rden, empty => user_r_control_r_empty,
			valid => open );
	s_control_ul2ffout_enable <= not s_control_ul2ffout_full;
	
	--end generate;
	
	--------------------------------------------------------------
	
	-- user logic:
	user_logic_cmp_inst : user_logic_cmp
		port map (
			i_clk => i_clk,
			i_rst => i_rst,
			
			-- data1 interface:
			i_data1in_data		=> s_data1_fte2ul_data,
			i_data1in_valid   => s_data1_fte2ul_valid,
			o_data1in_enable	=> s_data1_fte2ul_enable,
			o_data1out_data  	=> s_data1_ul2ffout_data,
			o_data1out_valid	=> s_data1_ul2ffout_valid,
			i_data1out_enable	=> s_data1_ul2ffout_enable,
			
			-- data2 interface:
			i_data2in_data		=> s_data2_fte2ul_data,
			i_data2in_valid   => s_data2_fte2ul_valid,
			o_data2in_enable	=> s_data2_fte2ul_enable,
			o_data2out_data  	=> s_data2_ul2ffout_data,
			o_data2out_valid	=> s_data2_ul2ffout_valid,
			i_data2out_enable	=> s_data2_ul2ffout_enable,
			
			-- control interface:
			i_controlin_data		=> s_control_fte2ul_data,
			i_controlin_valid   => s_control_fte2ul_valid,
			o_controlin_enable	=> s_control_fte2ul_enable,
			o_controlout_data  	=> s_control_ul2ffout_data,
			o_controlout_valid	=> s_control_ul2ffout_valid,
			i_controlout_enable	=> s_control_ul2ffout_enable
		);

end architecture;
