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;