-- altera vhdl_input_version vhdl_2008
-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html)

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.ros_package.all;
use work.ros_config.all;
use work.rtps_package.all;
use work.user_config.all;
use work.rtps_config_package.all;
use work.rtps_test_package.all;



entity L2_Testbench_ROS_Lib3 is
    port (
        -- SYSTEM
        clk             : in std_logic;
        reset           : in std_logic;
        time            : in TIME_TYPE;
        -- INPUT
        empty           : in std_logic;
        read            : out std_logic;
        data_in         : in std_logic_vector(WORD_WIDTH-1 downto 0);
        -- OUTPUT
        full            : in std_logic;
        write           : out std_logic;
        data_out        : out std_logic_vector(WORD_WIDTH-1 downto 0);
        
        -- SERVICE CLIENT
        start_c         : in std_logic;
        ack_c           : out std_logic;
        opcode_c        : in ROS_SERVICE_OPCODE_TYPE;
        service_info_c  : out SERVICE_INFO_TYPE;
        sequence_id_c   : out std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0);
        data_available_c: out std_logic;
        taken_c         : out std_logic;
        a_c             : in std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0);
        b_c             : in std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0);
        sum_c           : out std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0);
        done_c          : out std_logic;
        return_code_c   : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0)
    );
end entity;

architecture arch of L2_Testbench_ROS_Lib3 is
    
    type EARRAY_DATA_TYPE is array (0 to NUM_ENDPOINTS-1) of std_logic_vector(WORD_WIDTH downto 0);
    type HISTORY_CACHE_OPCODE_RARRAY_TYPE is array (0 to NUM_READERS-1) of HISTORY_CACHE_OPCODE_TYPE;
    type HISTORY_CACHE_OPCODE_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of HISTORY_CACHE_OPCODE_TYPE;
    type HISTORY_CACHE_RESPONSE_RARRAY_TYPE is array (0 to NUM_READERS-1) of HISTORY_CACHE_RESPONSE_TYPE;
    type HISTORY_CACHE_RESPONSE_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of HISTORY_CACHE_RESPONSE_TYPE;
    type RARRAY_DATA_TYPE is array (0 to NUM_READERS-1) of std_logic_vector(WORD_WIDTH downto 0);
    type WARRAY_DATA_TYPE is array (0 to NUM_WRITERS-1) of std_logic_vector(WORD_WIDTH downto 0);
    type SEQUENCENUMBER_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of SEQUENCENUMBER_TYPE;
    type INSTANCE_HANDLE_RARRAY_TYPE is array (0 to NUM_READERS-1) of INSTANCE_HANDLE_TYPE;
    type INSTANCE_HANDLE_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of INSTANCE_HANDLE_TYPE;
    type CACHE_CHANGE_KIND_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of CACHE_CHANGE_KIND_TYPE;
    type TIME_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of TIME_TYPE;
    type DDS_READER_OPCODE_RARRAY_TYPE is array (0 to NUM_READERS-1) of DDS_READER_OPCODE_TYPE;
    type DDS_WRITER_OPCODE_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of DDS_WRITER_OPCODE_TYPE;
    type INSTANCE_STATE_RARRAY_TYPE is array (0 to NUM_READERS-1) of std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
    type VIEW_STATE_RARRAY_TYPE is array (0 to NUM_READERS-1) of std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
    type SAMPLE_STATE_RARRAY_TYPE is array (0 to NUM_READERS-1) of std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
    type MAX_SAMPLES_RARRAY_TYPE is array (0 to NUM_READERS-1) of std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0);
    type RETURN_CODE_RARRAY_TYPE is array (0 to NUM_READERS-1) of std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
    type RETURN_CODE_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
    type STATUS_KIND_RARRAY_TYPE is array (0 to NUM_READERS-1) of std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
    type STATUS_KIND_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
    type DURATION_WARRAY_TYPE is array (0 to NUM_WRITERS-1) of DURATION_TYPE;
    type SAMPLE_INFO_RARRAY_TYPE is array (0 to NUM_READERS-1) of SAMPLE_INFO_TYPE;
    
    signal full_fire_rh, write_rh_fire : std_logic_vector(0 to NUM_ENDPOINTS-1);
    signal data_rh_fire, data_rh_fidm : std_logic_vector(WORD_WIDTH downto 0);
    signal full_fidm_rh, write_rh_fidm : std_logic;
    signal read_dm_fidm, empty_fidm_dm : std_logic;
    signal data_fidm_dm : std_logic_vector(WORD_WIDTH downto 0);
    signal read_re_fire, empty_fire_re : std_logic_vector(0 to NUM_ENDPOINTS);
    signal data_fire_re : EARRAY_DATA_TYPE;
    signal alive_re_dm, full_fdmre_re, write_dm_fdmre : std_logic_vector(0 to NUM_ENDPOINTS-1);
    signal data_dm_fdmre , data_dm_firo : std_logic_vector(WORD_WIDTH downto 0);
    signal full_firo_dm, write_dm_firo : std_logic;
    signal empty_fdmre_re, read_re_fdmre : std_logic_vector(0 to NUM_ENDPOINTS-1);
    signal data_fdmre_re : EARRAY_DATA_TYPE;
    signal full_firo_re, write_re_firo : std_logic_vector(0 to NUM_ENDPOINTS-1);
    signal data_re_firo : EARRAY_DATA_TYPE;
    signal start_rr_dr, ack_dr_rr, done_dr_rr, valid_rr_dr, ready_dr_rr : std_logic_vector(0 to NUM_READERS-1);
    signal opcode_rr_dr : HISTORY_CACHE_OPCODE_RARRAY_TYPE;
    signal ret_dr_rr : HISTORY_CACHE_RESPONSE_RARRAY_TYPE;
    signal data_rr_dr : RARRAY_DATA_TYPE;
    signal liveliness_assertion_dw_rw, data_available_dw_rw, start_rw_dw, ack_dw_rw, done_rw_dw, get_data_rw_dw, valid_dw_rw, ready_rw_dw : std_logic_vector(0 to NUM_WRITERS-1);
    signal opcode_rw_dw : HISTORY_CACHE_OPCODE_WARRAY_TYPE;
    signal seq_nr_rw_dw, cc_seq_nr_dw_rw : SEQUENCENUMBER_WARRAY_TYPE;
    signal ret_dw_rw : HISTORY_CACHE_RESPONSE_WARRAY_TYPE;
    signal data_dw_rw : WARRAY_DATA_TYPE;
    signal cc_instance_handle_dw_rw : INSTANCE_HANDLE_WARRAY_TYPE;
    signal cc_kind_dw_rw : CACHE_CHANGE_KIND_WARRAY_TYPE;
    signal cc_source_timestamp_dw_rw : TIME_WARRAY_TYPE;
    signal sample_info_dr_ri : SAMPLE_INFO_RARRAY_TYPE;
    signal start_ri_dr, ack_dr_ri, get_data_ri_dr, done_dr_ri, ready_ri_dr, valid_dr_ri, sample_info_valid_dr_ri, sample_info_ack_ri_dr, eoc_dr_ri : std_logic_vector(0 to NUM_READERS-1);
    signal opcode_ri_dr : DDS_READER_OPCODE_RARRAY_TYPE;
    signal instance_state_ri_dr : INSTANCE_STATE_RARRAY_TYPE;
    signal view_state_ri_dr : VIEW_STATE_RARRAY_TYPE;
    signal sample_state_ri_dr : SAMPLE_STATE_RARRAY_TYPE;
    signal instance_handle_ri_dr : INSTANCE_HANDLE_RARRAY_TYPE;
    signal max_samples_ri_dr : MAX_SAMPLES_RARRAY_TYPE;
    signal return_code_dr_ri : RETURN_CODE_RARRAY_TYPE;
    signal data_dr_ri : RARRAY_DATA_TYPE;
    signal status_dr_ri : STATUS_KIND_RARRAY_TYPE;
    signal start_wi_dw, ack_dw_wi, done_dw_wi, valid_wi_dw, valid_dw_wi, ready_wi_dw, ready_dw_wi : std_logic_vector(0 to NUM_WRITERS-1);
    signal opcode_wi_dw : DDS_WRITER_OPCODE_WARRAY_TYPE;
    signal instance_handle_wi_dw, instance_handle_dw_wi : INSTANCE_HANDLE_WARRAY_TYPE;
    signal source_ts_wi_dw : TIME_WARRAY_TYPE;
    signal max_wait_wi_dw : DURATION_WARRAY_TYPE;
    signal return_code_dw_wi : RETURN_CODE_WARRAY_TYPE;
    signal data_dw_wi, data_wi_dw : WARRAY_DATA_TYPE;
    signal status_dw_wi : STATUS_KIND_WARRAY_TYPE;
    signal empty_firo_ro, read_ro_firo, last_word_firo_ro : std_logic_vector(0 to NUM_ENDPOINTS);
    signal data_firo_ro : RTPS_OUT_DATA_TYPE;
    signal service_if : SERVICE_INTERFACE_ARRAY_TYPE(0 to NUM_SERVICES-1);
    -- ###GENERATED START###
        -- INTERFACE-USER SIGNALS
    -- ###GENERATED END###
    
begin
    
    
    rtps_handler_inst : entity work.rtps_handler(arch)
        port map (
            -- SYSTEM
            clk                 => clk,
            reset               => reset,
            -- INPUT
            empty               => empty,
            rd                  => read,
            data_in             => data_in,
            -- TO DISCOVERY MODULE
            full_dm             => full_fidm_rh,
            wr_dm               => write_rh_fidm,
            data_out_dm         => data_rh_fidm(WORD_WIDTH-1 downto 0),
            last_word_out_dm    => data_rh_fidm(WORD_WIDTH),
            -- TO USER ENDPOINTS
            full_rtps             => full_fire_rh,
            wr_rtps               => write_rh_fire,
            data_out_rtps         => data_rh_fire(WORD_WIDTH-1 downto 0),
            last_word_out_rtps    => data_rh_fire(WORD_WIDTH)
        );
    
    
    fifo_in_dm_inst : configuration work.FWFT_FIFO_cfg
            generic map (
                FIFO_DEPTH  => 2,
                DATA_WIDTH  => WORD_WIDTH+1
            )
            port map (
                -- SYSTEM
                reset       => reset,
                clk         => clk,
                -- INPUT
                full        => full_fidm_rh,
                write       => write_rh_fidm,
                data_in     => data_rh_fidm,
                -- OUTPUT
                empty       => empty_fidm_dm,
                read        => read_dm_fidm,
                data_out    => data_fidm_dm,
                -- MISC
                free        => open
            );
    
    
    fifo_in_re_gen : for i in 0 to NUM_ENDPOINTS-1 generate
        fifo_in_re_inst : configuration work.FWFT_FIFO_cfg
            generic map (
                FIFO_DEPTH  => 2,
                DATA_WIDTH  => WORD_WIDTH+1
            )
            port map (
                -- SYSTEM
                reset       => reset,
                clk         => clk,
                -- INPUT
                full        => full_fire_rh(i),
                write       => write_rh_fire(i),
                data_in     => data_rh_fire, -- Multicast
                -- OUTPUT
                empty       => empty_fire_re(i),
                read        => read_re_fire(i),
                data_out    => data_fire_re(i),
                -- MISC
                free        => open
            );
    end generate;
    
    
    rtps_discovery_module_inst : entity work.rtps_discovery_module(arch)
        generic map (
            MAX_REMOTE_PARTICIPANTS => MAX_REMOTE_PARTICIPANTS
        )
        port map (
            clk                 => clk,
            reset               => reset,
            time                => time,
            -- FROM RTPS HANDLER
            empty               => empty_fidm_dm,
            rd                  => read_dm_fidm,
            data_in             => data_fidm_dm(WORD_WIDTH-1 downto 0),
            last_word_in        => data_fidm_dm(WORD_WIDTH),
            -- FROM RTPS ENDPOINTS
            alive               => alive_re_dm,
            -- TO RTPS ENDPOINTS
            full_rtps           => full_fdmre_re,
            wr_rtps             => write_dm_fdmre,
            data_out_rtps       => data_dm_fdmre(WORD_WIDTH-1 downto 0),
            last_word_out_rtps  => data_dm_fdmre(WORD_WIDTH),
            -- TO RTPS OUT
            full_ro             => full_firo_dm,
            wr_ro               => write_dm_firo,
            data_out_ro         => data_dm_firo(WORD_WIDTH-1 downto 0),
            last_word_out_ro    => data_dm_firo(WORD_WIDTH)
        );
    
    
    fifo_dm_re_gen : for i in 0 to NUM_ENDPOINTS-1 generate
        fifo_dm_re_inst : configuration work.FWFT_FIFO_cfg
            generic map (
                FIFO_DEPTH  => 2,
                DATA_WIDTH  => WORD_WIDTH+1
            )
            port map (
                -- SYSTEM
                reset       => reset,
                clk         => clk,
                -- INPUT
                full        => full_fdmre_re(i),
                write       => write_dm_fdmre(i),
                data_in     => data_dm_fdmre, -- Multicast
                -- OUTPUT
                empty       => empty_fdmre_re(i),
                read        => read_re_fdmre(i),
                data_out    => data_fdmre_re(i),
                -- MISC
                free        => open
            );
    end generate;
    
    
    rtps_endpoint_gen : for i in 0 to NUM_ENDPOINTS-1 generate
        rtps_endpoint_if : if (i < NUM_READERS) generate
            rtps_reader_inst : entity work.rtps_reader(arch)
                generic map (
                    ENTITYID                    => ENTITYID(i),
                    RELIABILITY_QOS             => ENDPOINT_CONFIG(i).RELIABILITY_QOS,
                    LIVELINESS_QOS              => ENDPOINT_CONFIG(i).LIVELINESS_QOS,
                    DURABILITY_QOS              => ENDPOINT_CONFIG(i).DURABILITY_QOS,
                    HEARTBEAT_RESPONSE_DELAY    => ENDPOINT_CONFIG(i).HEARTBEAT_RESPONSE_DELAY,
                    HEARTBEAT_SUPPRESSION_DELAY => ENDPOINT_CONFIG(i).HEARTBEAT_SUPPRESSION_DELAY,
                    LEASE_DURATION              => ENDPOINT_CONFIG(i).LEASE_DURATION,
                    WITH_KEY                    => ENDPOINT_CONFIG(i).WITH_KEY,
                    MAX_REMOTE_ENDPOINTS        => MAX_REMOTE_ENDPOINTS
                )
                port map (
                    -- SYSTEM
                    clk                     => clk,
                    reset                   => reset,
                    time                    => time,
                    -- FROM RTPS_HANDLER (USER TRAFFIC)
                    empty_user              => empty_fire_re(i),
                    rd_user                 => read_re_fire(i),
                    data_in_user            => data_fire_re(i)(WORD_WIDTH-1 downto 0),
                    last_word_in_user       => data_fire_re(i)(WORD_WIDTH),
                    -- FROM DISCOVERY MODULE (META TRAFFIC)
                    empty_meta              => empty_fdmre_re(i),
                    rd_meta                 => read_re_fdmre(i),
                    data_in_meta            => data_fdmre_re(i)(WORD_WIDTH-1 downto 0),
                    last_word_in_meta       => data_fdmre_re(i)(WORD_WIDTH),
                    -- RTPS OUTPUT
                    full_ro                 => full_firo_re(i),
                    wr_ro                   => write_re_firo(i),
                    data_out_ro             => data_re_firo(i)(WORD_WIDTH-1 downto 0),
                    last_word_out_ro        => data_re_firo(i)(WORD_WIDTH),
                    -- TO HISTORY CACHE
                    start_hc                => start_rr_dr(i),
                    opcode_hc               => opcode_rr_dr(i),
                    ack_hc                  => ack_dr_rr(i),
                    done_hc                 => done_dr_rr(i),
                    ret_hc                  => ret_dr_rr(i),
                    valid_out_hc            => valid_rr_dr(i),
                    ready_out_hc            => ready_dr_rr(i),
                    data_out_hc             => data_rr_dr(i)(WORD_WIDTH-1 downto 0),
                    last_word_out_hc        => data_rr_dr(i)(WORD_WIDTH)
                );
            
            -- Set Alive Signals of Readers to Zero
            alive_re_dm(i) <= ('0');
        else generate
            rtps_writer_inst : entity work.rtps_writer(arch)
                generic map (
                    RELIABILITY_QOS             => ENDPOINT_CONFIG(i).RELIABILITY_QOS,
                    LIVELINESS_QOS              => ENDPOINT_CONFIG(i).LIVELINESS_QOS,
                    DURABILITY_QOS              => ENDPOINT_CONFIG(i).DURABILITY_QOS,
                    DESTINATION_ORDER_QOS       => ENDPOINT_CONFIG(i).DESTINATION_ORDER_QOS,
                    ACKNACK_RESPONSE_DELAY      => ENDPOINT_CONFIG(i).ACKNACK_RESPONSE_DELAY,
                    ACKNACK_SUPPRESSION_DELAY   => ENDPOINT_CONFIG(i).ACKNACK_SUPPRESSION_DELAY,
                    LEASE_DURATION              => ENDPOINT_CONFIG(i).LEASE_DURATION,
                    HEARTBEAT_PERIOD            => ENDPOINT_CONFIG(i).HEARTBEAT_PERIOD,
                    ENTITYID                    => ENTITYID(i),
                    WITH_KEY                    => ENDPOINT_CONFIG(i).WITH_KEY,
                    PUSH_MODE                   => ENDPOINT_CONFIG(i).PUSH_MODE,
                    INLINE_QOS                  => gen_inline_qos(i),
                    MAX_REMOTE_ENDPOINTS        => MAX_REMOTE_ENDPOINTS
                )
                port map (
                    -- SYSTEM
                    clk                     => clk,
                    reset                   => reset,
                    time                    => time,
                    -- FROM RTPS_HANDLER (USER TRAFFIC)
                    empty_user              => empty_fire_re(i),
                    rd_user                 => read_re_fire(i),
                    data_in_user            => data_fire_re(i)(WORD_WIDTH-1 downto 0),
                    last_word_in_user       => data_fire_re(i)(WORD_WIDTH),
                    -- FROM DISCOVERY MODULE (META TRAFFIC)
                    empty_meta              => empty_fdmre_re(i),
                    rd_meta                 => read_re_fdmre(i),
                    data_in_meta            => data_fdmre_re(i)(WORD_WIDTH-1 downto 0),
                    last_word_in_meta       => data_fdmre_re(i)(WORD_WIDTH),
                    -- TO DISCOVERY MODULE (META TRAFFIC)
                    alive_sig               => alive_re_dm(i),
                    -- RTPS OUTPUT
                    full_ro                 => full_firo_re(i),
                    wr_ro                   => write_re_firo(i),
                    data_out_ro             => data_re_firo(i)(WORD_WIDTH-1 downto 0),
                    last_word_out_ro        => data_re_firo(i)(WORD_WIDTH),
                    -- FROM HC
                    liveliness_assertion    => liveliness_assertion_dw_rw(i-NUM_READERS),
                    data_available          => data_available_dw_rw(i-NUM_READERS),
                    start_hc                => start_rw_dw(i-NUM_READERS),
                    opcode_hc               => opcode_rw_dw(i-NUM_READERS),
                    ack_hc                  => ack_dw_rw(i-NUM_READERS),
                    seq_nr_hc               => seq_nr_rw_dw(i-NUM_READERS),
                    done_hc                 => done_rw_dw(i-NUM_READERS),
                    ret_hc                  => ret_dw_rw(i-NUM_READERS),
                    get_data_hc             => get_data_rw_dw(i-NUM_READERS),
                    valid_in_hc             => valid_dw_rw(i-NUM_READERS),
                    ready_in_hc             => ready_rw_dw(i-NUM_READERS),
                    data_in_hc              => data_dw_rw(i-NUM_READERS)(WORD_WIDTH-1 downto 0),
                    last_word_in_hc         => data_dw_rw(i-NUM_READERS)(WORD_WIDTH),
                    cc_instance_handle      => cc_instance_handle_dw_rw(i-NUM_READERS),
                    cc_kind                 => cc_kind_dw_rw(i-NUM_READERS),
                    cc_source_timestamp     => cc_source_timestamp_dw_rw(i-NUM_READERS),
                    cc_seq_nr               => cc_seq_nr_dw_rw(i-NUM_READERS)
                );
        end generate;
    end generate;
    
    
    dds_endpoint_gen : for i in 0 to NUM_ENDPOINTS-2 generate
        dds_endpoint_if : if (i < NUM_READERS) generate
            dds_reader_inst : entity work.dds_reader(arch)
                generic map (
                    TIME_BASED_FILTER_QOS       => ENDPOINT_CONFIG(i).TIME_BASED_FILTER_QOS,
                    DEADLINE_QOS                => ENDPOINT_CONFIG(i).DEADLINE_QOS,
                    MAX_INSTANCES               => ENDPOINT_CONFIG(i).MAX_INSTANCES,
                    MAX_SAMPLES_PER_INSTANCE    => ENDPOINT_CONFIG(i).MAX_SAMPLES_PER_INSTANCE,
                    MAX_SAMPLES                 => ENDPOINT_CONFIG(i).MAX_SAMPLES,
                    HISTORY_QOS                 => ENDPOINT_CONFIG(i).HISTORY_QOS,
                    RELIABILITY_QOS             => ENDPOINT_CONFIG(i).RELIABILITY_QOS,
                    PRESENTATION_QOS            => ENDPOINT_CONFIG(i).PRESENTATION_QOS,
                    DESTINATION_ORDER_QOS       => ENDPOINT_CONFIG(i).DESTINATION_ORDER_QOS,
                    COHERENT_ACCESS             => ENDPOINT_CONFIG(i).COHERENT_ACCESS,
                    ORDERED_ACCESS              => ENDPOINT_CONFIG(i).ORDERED_ACCESS,
                    WITH_KEY                    => ENDPOINT_CONFIG(i).WITH_KEY,
                    PAYLOAD_FRAME_SIZE          => ENDPOINT_CONFIG(i).MAX_PAYLOAD_SIZE,
                    MAX_REMOTE_ENDPOINTS        => MAX_REMOTE_ENDPOINTS
                )
                port map (
                    -- SYSTEM
                    clk                             => clk,
                    reset                           => reset,
                    time                            => time,
                    -- FROM RTPS ENDPOINT
                    start_rtps                      => start_rr_dr(i),
                    opcode_rtps                     => opcode_rr_dr(i),
                    ack_rtps                        => ack_dr_rr(i),
                    done_rtps                       => done_dr_rr(i),
                    ret_rtps                        => ret_dr_rr(i),
                    valid_in_rtps                   => valid_rr_dr(i),
                    ready_in_rtps                   => ready_dr_rr(i),
                    data_in_rtps                    => data_rr_dr(i)(WORD_WIDTH-1 downto 0),
                    last_word_in_rtps               => data_rr_dr(i)(WORD_WIDTH),
                    -- TO USER ENTITY
                    start_dds                       => start_ri_dr(i),
                    ack_dds                         => ack_dr_ri(i),
                    opcode_dds                      => opcode_ri_dr(i),
                    instance_state_dds              => instance_state_ri_dr(i),
                    view_state_dds                  => view_state_ri_dr(i),
                    sample_state_dds                => sample_state_ri_dr(i),
                    instance_handle_dds             => instance_handle_ri_dr(i),
                    max_samples_dds                 => max_samples_ri_dr(i),
                    get_data_dds                    => get_data_ri_dr(i),
                    done_dds                        => done_dr_ri(i),
                    return_code_dds                 => return_code_dr_ri(i),
                    valid_out_dds                   => valid_dr_ri(i),
                    ready_out_dds                   => ready_ri_dr(i),
                    data_out_dds                    => data_dr_ri(i)(WORD_WIDTH-1 downto 0),
                    last_word_out_dds               => data_dr_ri(i)(WORD_WIDTH),
                    sample_info                     => sample_info_dr_ri(i),
                    sample_info_valid               => sample_info_valid_dr_ri(i),
                    sample_info_ack                 => sample_info_ack_ri_dr(i),
                    eoc                             => eoc_dr_ri(i),
                    -- Communication Status
                    status                          => status_dr_ri(i)
                );
        else generate
            dds_writer_inst : entity work.dds_writer(arch)
                generic map (
                    HISTORY_QOS                 => ENDPOINT_CONFIG(i).HISTORY_QOS,
                    DEADLINE_QOS                => ENDPOINT_CONFIG(i).DEADLINE_QOS,
                    LIFESPAN_QOS                => ENDPOINT_CONFIG(i).LIFESPAN_QOS,
                    LEASE_DURATION              => ENDPOINT_CONFIG(i).LEASE_DURATION,
                    WITH_KEY                    => ENDPOINT_CONFIG(i).WITH_KEY,
                    MAX_SAMPLES                 => ENDPOINT_CONFIG(i).MAX_SAMPLES,
                    MAX_INSTANCES               => ENDPOINT_CONFIG(i).MAX_INSTANCES,
                    MAX_SAMPLES_PER_INSTANCE    => ENDPOINT_CONFIG(i).MAX_SAMPLES_PER_INSTANCE,
                    PAYLOAD_FRAME_SIZE          => ENDPOINT_CONFIG(i).MAX_PAYLOAD_SIZE
                )
                port map (
                    -- SYSTEM
                    clk                     => clk,
                    reset                   => reset,
                    time                    => time,
                    -- TO/FROM RTPS ENDPOINT
                    start_rtps              => start_rw_dw(i-NUM_READERS),
                    opcode_rtps             => opcode_rw_dw(i-NUM_READERS),
                    ack_rtps                => ack_dw_rw(i-NUM_READERS),
                    done_rtps               => done_rw_dw(i-NUM_READERS),
                    ret_rtps                => ret_dw_rw(i-NUM_READERS),
                    seq_nr_rtps             => seq_nr_rw_dw(i-NUM_READERS),
                    get_data_rtps           => get_data_rw_dw(i-NUM_READERS),
                    valid_out_rtps          => valid_dw_rw(i-NUM_READERS),
                    ready_out_rtps          => ready_rw_dw(i-NUM_READERS),
                    data_out_rtps           => data_dw_rw(i-NUM_READERS)(WORD_WIDTH-1 downto 0),
                    last_word_out_rtps      => data_dw_rw(i-NUM_READERS)(WORD_WIDTH),
                    liveliness_assertion    => liveliness_assertion_dw_rw(i-NUM_READERS),
                    data_available          => data_available_dw_rw(i-NUM_READERS),
                    -- Cache Change
                    cc_instance_handle      => cc_instance_handle_dw_rw(i-NUM_READERS),
                    cc_kind                 => cc_kind_dw_rw(i-NUM_READERS),
                    cc_source_timestamp     => cc_source_timestamp_dw_rw(i-NUM_READERS),
                    cc_seq_nr               => cc_seq_nr_dw_rw(i-NUM_READERS),
                    -- TO/FROM USER ENTITY
                    start_dds               => start_wi_dw(i-NUM_READERS),
                    ack_dds                 => ack_dw_wi(i-NUM_READERS),
                    opcode_dds              => opcode_wi_dw(i-NUM_READERS),
                    instance_handle_in_dds  => instance_handle_wi_dw(i-NUM_READERS),
                    source_ts_dds           => source_ts_wi_dw(i-NUM_READERS),
                    max_wait_dds            => max_wait_wi_dw(i-NUM_READERS),
                    done_dds                => done_dw_wi(i-NUM_READERS),
                    return_code_dds         => return_code_dw_wi(i-NUM_READERS),
                    instance_handle_out_dds => instance_handle_dw_wi(i-NUM_READERS),
                    valid_in_dds            => valid_wi_dw(i-NUM_READERS),
                    ready_in_dds            => ready_dw_wi(i-NUM_READERS),
                    data_in_dds             => data_wi_dw(i-NUM_READERS)(WORD_WIDTH-1 downto 0),
                    last_word_in_dds        => data_wi_dw(i-NUM_READERS)(WORD_WIDTH),
                    valid_out_dds           => valid_dw_wi(i-NUM_READERS),
                    ready_out_dds           => ready_wi_dw(i-NUM_READERS),
                    data_out_dds            => data_dw_wi(i-NUM_READERS)(WORD_WIDTH-1 downto 0),
                    last_word_out_dds       => data_dw_wi(i-NUM_READERS)(WORD_WIDTH),
                    -- Communication Status
                    status                  => status_dw_wi(i-NUM_READERS)
                );
        end generate;
    end generate;
    
    ros_discovery_writer_inst : entity work.ros_static_discovery_writer(arch)
        port map (
            -- SYSTEM
            clk                     => clk,
            reset                   => reset,
            -- TO/FROM RTPS ENDPOINT
            start                   => start_rw_dw(NUM_WRITERS-1),
            opcode                  => opcode_rw_dw(NUM_WRITERS-1),
            ack                     => ack_dw_rw(NUM_WRITERS-1),
            done                    => done_rw_dw(NUM_WRITERS-1),
            ret                     => ret_dw_rw(NUM_WRITERS-1),
            seq_nr                  => seq_nr_rw_dw(NUM_WRITERS-1),
            get_data                => get_data_rw_dw(NUM_WRITERS-1),
            valid_out               => valid_dw_rw(NUM_WRITERS-1),
            ready_out               => ready_rw_dw(NUM_WRITERS-1),
            data_out                => data_dw_rw(NUM_WRITERS-1)(WORD_WIDTH-1 downto 0),
            last_word_out           => data_dw_rw(NUM_WRITERS-1)(WORD_WIDTH),
            liveliness_assertion    => liveliness_assertion_dw_rw(NUM_WRITERS-1),
            data_available          => data_available_dw_rw(NUM_WRITERS-1),
            -- Cache Change
            cc_instance_handle      => cc_instance_handle_dw_rw(NUM_WRITERS-1),
            cc_kind                 => cc_kind_dw_rw(NUM_WRITERS-1),
            cc_source_timestamp     => cc_source_timestamp_dw_rw(NUM_WRITERS-1),
            cc_seq_nr               => cc_seq_nr_dw_rw(NUM_WRITERS-1)
        );
    
    fifo_in_ro_gen : for i in 0 to NUM_ENDPOINTS generate
        fifo_in_ro_if : if (i = NUM_ENDPOINTS) generate
            fifo_in_ro_inst : configuration work.FWFT_FIFO_cfg
                generic map (
                    FIFO_DEPTH  => 2,
                    DATA_WIDTH  => WORD_WIDTH+1
                )
                port map (
                    -- SYSTEM
                    reset       => reset,
                    clk         => clk,
                    -- INPUT
                    full        => full_firo_dm,
                    write       => write_dm_firo,
                    data_in     => data_dm_firo,
                    -- OUTPUT
                    empty       => empty_firo_ro(i),
                    read        => read_ro_firo(i),
                    data_out(WORD_WIDTH)            => last_word_firo_ro(i),
                    data_out(WORD_WIDTH-1 downto 0) => data_firo_ro(i),
                    -- MISC
                    free        => open
                );
        else generate        
            fifo_in_ro_inst : configuration work.FWFT_FIFO_cfg
                generic map (
                    FIFO_DEPTH  => 2,
                    DATA_WIDTH  => WORD_WIDTH+1
                )
                port map (
                    -- SYSTEM
                    reset       => reset,
                    clk         => clk,
                    -- INPUT
                    full        => full_firo_re(i),
                    write       => write_re_firo(i),
                    data_in     => data_re_firo(i),
                    -- OUTPUT
                    empty       => empty_firo_ro(i),
                    read        => read_ro_firo(i),
                    data_out(WORD_WIDTH)            => last_word_firo_ro(i),
                    data_out(WORD_WIDTH-1 downto 0) => data_firo_ro(i),
                    -- MISC
                    free        => open
                );
        end generate;
    end generate;
    
    
    rtps_out_inst : entity work.rtps_out(arch)
        port map (
            -- SYSTEM
            clk             => clk,
            reset           => reset,
            -- INPUT
            empty           => empty_firo_ro,
            rd              => read_ro_firo,
            data_in         => data_firo_ro,
            last_word_in    => last_word_firo_ro,
            -- OUTPUT
            full            => full,
            wr              => write,
            data_out        => data_out
        );
    
    service_if_gen : for i in 0 to NUM_SERVICES-1 generate
        start_ri_dr(i)                                  <= service_if(i).start_r;
        service_if(i).ack_r                             <= ack_dr_ri(i);
        opcode_ri_dr(i)                                 <= service_if(i).opcode_r;
        instance_state_ri_dr(i)                         <= service_if(i).instance_state_r;
        view_state_ri_dr(i)                             <= service_if(i).view_state_r;
        sample_state_ri_dr(i)                           <= service_if(i).sample_state_r;
        instance_handle_ri_dr(i)                        <= service_if(i).instance_handle_r;
        max_samples_ri_dr(i)                            <= service_if(i).max_samples_r;
        get_data_ri_dr(i)                               <= service_if(i).get_data_r;
        service_if(i).done_r                            <= done_dr_ri(i);
        service_if(i).return_code_r                     <= return_code_dr_ri(i);
        service_if(i).valid_in_r                        <= valid_dr_ri(i);
        ready_ri_dr(i)                                  <= service_if(i).ready_in_r;
        service_if(i).data_in_r                         <= data_dr_ri(i)(WORD_WIDTH-1 downto 0);
        service_if(i).last_word_in_r                    <= data_dr_ri(i)(WORD_WIDTH);
        service_if(i).sample_info_r                     <= sample_info_dr_ri(i);
        service_if(i).sample_info_valid_r               <= sample_info_valid_dr_ri(i);
        sample_info_ack_ri_dr(i)                        <= service_if(i).sample_info_ack_r;
        service_if(i).eoc_r                             <= eoc_dr_ri(i);
        service_if(i).status_r                          <= status_dr_ri(i);
        start_wi_dw(i)                                  <= service_if(i).start_w;
        service_if(i).ack_w                             <= ack_dw_wi(i);
        opcode_wi_dw(i)                                 <= service_if(i).opcode_w;
        service_if(i).instance_handle_out_w             <= instance_handle_dw_wi(i);
        source_ts_wi_dw(i)                              <= service_if(i).source_ts_w;
        max_wait_wi_dw(i)                               <= service_if(i).max_wait_w;
        service_if(i).done_w                            <= done_dw_wi(i);
        service_if(i).return_code_w                     <= return_code_dw_wi(i);
        instance_handle_wi_dw(i)                        <= service_if(i).instance_handle_in_w;
        valid_wi_dw(i)                                  <= service_if(i).valid_out_w;
        service_if(i).ready_out_w                       <= ready_dw_wi(i);
        data_wi_dw(i)(WORD_WIDTH-1 downto 0)            <= service_if(i).data_out_w;
        data_wi_dw(i)(WORD_WIDTH)                       <= service_if(i).last_word_out_w;
        service_if(i).valid_in_w                        <= valid_dw_wi(i);
        ready_wi_dw(i)                                  <= service_if(i).ready_in_w;
        service_if(i).data_in_w                         <= data_dw_wi(i)(WORD_WIDTH-1 downto 0);
        service_if(i).last_word_in_w                    <= data_dw_wi(i)(WORD_WIDTH);
        service_if(i).status_w                          <= status_dw_wi(i);
    end generate;
    
    -- ######GENERATED START######
    
    AddTwoInts_ros_srv_client_inst : entity work.AddTwoInts_ros_srv_client(arch)
        port map (
            clk                                 => clk,
            reset                               => reset,
            start_r                             => service_if(0).start_r,
            ack_r                               => service_if(0).ack_r,
            opcode_r                            => service_if(0).opcode_r,
            instance_state_r                    => service_if(0).instance_state_r,
            view_state_r                        => service_if(0).view_state_r,
            sample_state_r                      => service_if(0).sample_state_r,
            instance_handle_r                   => service_if(0).instance_handle_r,
            max_samples_r                       => service_if(0).max_samples_r,
            get_data_r                          => service_if(0).get_data_r,
            done_r                              => service_if(0).done_r,
            return_code_r                       => service_if(0).return_code_r,
            valid_in_r                          => service_if(0).valid_in_r,
            ready_in_r                          => service_if(0).ready_in_r,
            data_in_r                           => service_if(0).data_in_r,
            last_word_in_r                      => service_if(0).last_word_in_r,
            sample_info_r                       => service_if(0).sample_info_r,
            sample_info_valid_r                 => service_if(0).sample_info_valid_r,
            sample_info_ack_r                   => service_if(0).sample_info_ack_r,
            eoc_r                               => service_if(0).eoc_r,
            status_r                            => service_if(0).status_r,
            start_w                             => service_if(0).start_w,
            ack_w                               => service_if(0).ack_w,
            opcode_w                            => service_if(0).opcode_w,
            instance_handle_out_w               => service_if(0).instance_handle_out_w,
            source_ts_w                         => service_if(0).source_ts_w,
            max_wait_w                          => service_if(0).max_wait_w,
            done_w                              => service_if(0).done_w,
            return_code_w                       => service_if(0).return_code_w,
            instance_handle_in_w                => service_if(0).instance_handle_in_w,
            valid_out_w                         => service_if(0).valid_out_w,
            ready_out_w                         => service_if(0).ready_out_w,
            data_out_w                          => service_if(0).data_out_w,
            last_word_out_w                     => service_if(0).last_word_out_w,
            valid_in_w                          => service_if(0).valid_in_w,
            ready_in_w                          => service_if(0).ready_in_w,
            data_in_w                           => service_if(0).data_in_w,
            last_word_in_w                      => service_if(0).last_word_in_w,
            status_w                            => service_if(0).status_w,
            
            start_user                          => start_c,
            ack_user                            => ack_c,
            opcode_user                         => opcode_c,
            service_info_user                   => service_info_c,
            sequence_id_user                    => sequence_id_c,
            taken_user                          => taken_c,
            data_available_user                 => data_available_c,
            a                                   => a_c,
            b                                   => b_c,
            sum                                 => sum_c,
            done_user                           => done_c,
            return_code_user                    => return_code_c
        );
    
    -- ######GENERATED END######
    
end architecture;
