-- 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 ieee.math_real.CEIL;
use ieee.math_real.TRUNC;

package rtps_package is
    
    --*****DDSI-RTPS 2.3*****
    
    -- *WIDTHS*
    constant WORD_WIDTH                             : natural := 32;
    constant BYTE_WIDTH                             : natural := 8;
    constant UDP_PORT_WIDTH                         : natural := 16;
    constant IPv4_ADDRESS_WIDTH                     : natural := 32;
    constant UDP_HEADER_LENGTH_WIDTH                : natural := 16;
    -- IDL CDR ENCODING WIDTHS
    constant CDR_INT8_WIDTH                         : natural := 8;
    constant CDR_CHAR_WIDTH                         : natural := 8;
    constant CDR_OCTET_WIDTH                        : natural := 8;
    constant CDR_BOOLEAN_WIDTH                      : natural := 8;
    constant CDR_WCHAR_WIDTH                        : natural := 16;
    constant CDR_SHORT_WIDTH                        : natural := 16;
    constant CDR_ENUMERATION_SHORT_WIDTH            : natural := 16;
    constant CDR_LONG_WIDTH                         : natural := 32;
    constant CDR_FLOAT_WIDTH                        : natural := 32;
    constant CDR_ENUMERATION_WIDTH                  : natural := 32;
    type CDR_ENUMERATION_ARRAY_TYPE is array (natural range <>) of std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
    constant CDR_LONG_LONG_WIDTH                    : natural := 64;
    constant CDR_DOUBLE_WIDTH                       : natural := 64;
    constant CDR_LONG_DOUBLE_WIDTH                  : natural := 128;
    -- RTPS
    -- NOTE: Widths not defined with a CDR Width are defined as byte arrays (Same Endian representation)
    constant GUIDPREFIX_WIDTH                       : natural := 96;
    constant ENTITYID_WIDTH                         : natural := 32;
    constant GUID_WIDTH                             : natural := GUIDPREFIX_WIDTH + ENTITYID_WIDTH;
    constant PROTOCOL_WIDTH                         : natural := 32;
    constant PROTOCOLVERSION_WIDTH                  : natural := 16;
    constant VENDORID_WIDTH                         : natural := 16;
    constant SUBMESSAGE_ID_WIDTH                    : natural := CDR_OCTET_WIDTH;
    constant SUBMESSAGE_FLAGS_WIDTH                 : natural := CDR_OCTET_WIDTH;
    constant SUBMESSAGE_LENGTH_WIDTH                : natural := CDR_SHORT_WIDTH;
    constant DOMAIN_ID_WIDTH                        : natural := CDR_LONG_WIDTH;
    constant PARAMETER_ID_WIDTH                     : natural := CDR_SHORT_WIDTH;
    constant PARAMETER_LENGTH_WIDTH                 : natural := CDR_SHORT_WIDTH;
    constant PAYLOAD_REPRESENTATION_ID_WIDTH        : natural := 16;
    constant PAYLOAD_REPRESENTATION_OPTIONS_WIDTH   : natural := 16;
    constant PARTICIPANT_MESSAGE_KIND_WIDTH         : natural := 32;
    constant LOCATOR_KIND_WIDTH                     : natural := CDR_LONG_WIDTH;
    constant COUNT_WIDTH                            : natural := CDR_LONG_WIDTH;
    constant SUBMESSAGE_DATA_EXTRA_FLAGS_WIDTH      : natural := 16;
    constant MAX_BITMAP_WIDTH                       : natural := 256;
    constant KEY_HASH_WIDTH                         : natural := 128;
    constant STATUS_INFO_WIDTH                      : natural := 32;
    -- DDS
    constant RETURN_CODE_WIDTH                      : natural := CDR_LONG_WIDTH;
    type RETURN_CODE_ARRAY_TYPE is array (natural range <>) of std_logic_vector(RETURN_CODE_WIDTH-1 downto 0);
    constant STATUS_KIND_WIDTH                      : natural := CDR_LONG_WIDTH;
    type STATUS_KIND_ARRAY_TYPE is array (natural range <>) of std_logic_vector(STATUS_KIND_WIDTH-1 downto 0);
    constant SAMPLE_STATE_KIND_WIDTH                : natural := CDR_LONG_WIDTH;
    type SAMPLE_STATE_ARRAY_TYPE is array (natural range <>) of std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
    constant VIEW_STATE_KIND_WIDTH                  : natural := CDR_LONG_WIDTH;
    type VIEW_STATE_ARRAY_TYPE is array (natural range <>) of std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
    constant INSTANCE_STATE_KIND_WIDTH              : natural := CDR_LONG_WIDTH;
    type INSTANCE_STATE_ARRAY_TYPE is array (natural range <>) of std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
    constant QOS_POLICY_ID_WIDTH                    : natural := CDR_LONG_WIDTH;
    constant MAX_SAMPLES_WIDTH                      : natural := CDR_LONG_WIDTH;
    type MAX_SAMPLES_ARRAY_TYPE is array (natural range <>) of std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0);
    
    constant DISPOSED_GENERATION_COUNT_WIDTH        : natural := CDR_LONG_WIDTH;
    constant NO_WRITERS_GENERATION_COUNT_WIDTH      : natural := CDR_LONG_WIDTH;
    constant SAMPLE_RANK_WIDTH                      : natural := CDR_LONG_WIDTH;
    constant GENERATION_RANK_WIDTH                  : natural := CDR_LONG_WIDTH;
    constant ABSOLUTE_GENERATION_COUNT_WIDTH        : natural := CDR_LONG_WIDTH;
    
    constant INCONSISTENT_TOPIC_STATUS_COUNT_WIDTH  : natural := CDR_LONG_WIDTH;
    type INCONSISTENT_TOPIC_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(INCONSISTENT_TOPIC_STATUS_COUNT_WIDTH-1 downto 0);
    constant SAMPLE_LOST_STATUS_COUNT_WIDTH         : natural := CDR_LONG_WIDTH;
    type SAMPLE_LOST_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(SAMPLE_LOST_STATUS_COUNT_WIDTH-1 downto 0);
    constant SAMPLE_REJECTED_STATUS_COUNT_WIDTH     : natural := CDR_LONG_WIDTH;
    type SAMPLE_REJECTED_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(SAMPLE_REJECTED_STATUS_COUNT_WIDTH-1 downto 0);
    constant LIVELINESS_LOST_STATUS_COUNT_WIDTH     : natural := CDR_LONG_WIDTH;
    type LIVELINESS_LOST_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(LIVELINESS_LOST_STATUS_COUNT_WIDTH-1 downto 0);
    constant LIVELINESS_CHANGED_STATUS_COUNT_WIDTH  : natural := CDR_LONG_WIDTH;
    constant OFFERED_DEADLINE_MISSED_STATUS_COUNT_WIDTH     : natural := CDR_LONG_WIDTH;
    type OFFERED_DEADLINE_MISSED_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(OFFERED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0);
    constant REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH   : natural := CDR_LONG_WIDTH;
    type REQUESTED_DEADLINE_MISSED_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(REQUESTED_DEADLINE_MISSED_STATUS_COUNT_WIDTH-1 downto 0);
    constant OFFERED_INCOMPATIBLE_QOS_STATUS_COUNT_WIDTH    : natural := CDR_LONG_WIDTH;
    type OFFERED_INCOMPATIBLE_QOS_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(OFFERED_INCOMPATIBLE_QOS_STATUS_COUNT_WIDTH-1 downto 0);
    constant REQUESTED_INCOMPATIBLE_QOS_STATUS_COUNT_WIDTH  : natural := CDR_LONG_WIDTH;
    type REQUESTED_INCOMPATIBLE_QOS_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(REQUESTED_INCOMPATIBLE_QOS_STATUS_COUNT_WIDTH-1 downto 0);
    constant PUBLICATION_MATCHED_STATUS_COUNT_WIDTH     : natural := CDR_LONG_WIDTH;
    type PUBLICATION_MATCHED_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(PUBLICATION_MATCHED_STATUS_COUNT_WIDTH-1 downto 0);
    constant SUBSCRIPTION_MATCHED_STATUS_COUNT_WIDTH    : natural := CDR_LONG_WIDTH;
    type SUBSCRIPTION_MATCHED_STATUS_COUNT_ARRAY_TYPE is array (natural range <>) of std_logic_vector(SUBSCRIPTION_MATCHED_STATUS_COUNT_WIDTH-1 downto 0);
    
    
    
    
    -- *TYPES DEFINITION*
    -- Generic Types
    -- TODO: Define DOUBLE_WORD_ARRAY as subtype of WORD_ARRAY (Remove unsigned restriction)
    type DOUBLE_WORD_ARRAY is array (0 to 1) of unsigned(WORD_WIDTH-1 downto 0);
    -- RTPS
    subtype SEQUENCENUMBER_TYPE is DOUBLE_WORD_ARRAY;
    type SEQUENCENUMBER_ARRAY_TYPE is array (natural range <>) of SEQUENCENUMBER_TYPE;
    subtype DURATION_TYPE is DOUBLE_WORD_ARRAY;
    type DURATION_ARRAY_TYPE is array (natural range <>) of DURATION_TYPE;
    subtype TIME_TYPE is DOUBLE_WORD_ARRAY;
    type TIME_ARRAY_TYPE is array (natural range <>) of TIME_TYPE;
    type GUIDPREFIX_TYPE is array (0 to (GUIDPREFIX_WIDTH/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
    type GUID_TYPE is array (0 to (GUID_WIDTH/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
    type BITMAP_TYPE is array (0 to (MAX_BITMAP_WIDTH/WORD_WIDTH)-1) of std_logic_vector(0 to WORD_WIDTH-1);
    type KEY_HASH_TYPE is array (0 to (KEY_HASH_WIDTH/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
    type KEY_HASH_ARRAY_TYPE is array (natural range <>) of KEY_HASH_TYPE;
    -- DDS
    subtype INSTANCE_HANDLE_TYPE is KEY_HASH_TYPE;
    subtype INSTANCE_HANDLE_ARRAY_TYPE is KEY_HASH_ARRAY_TYPE;
    
    -- Helper Function
    function gen_duration(s,ns : integer) return DURATION_TYPE;
    function gen_duration(t : time) return DURATION_TYPE;
    
    -- *PREDEFINED VALUES*
    constant DEFAULT_IPv4_META_ADDRESS  : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := x"EFFF0001"; -- Default Multicast Ipv4 Address (239.255.0.1)
    constant DURATION_ZERO              : DURATION_TYPE := (others => (others => '0'));
    constant DURATION_INFINITE          : DURATION_TYPE := (x"7fffffff", x"ffffffff");
    constant TIME_ZERO                  : TIME_TYPE := (others => (others => '0'));
    constant TIME_INVALID               : TIME_TYPE := (others => (others => '1'));
    constant TIME_INFINITE              : TIME_TYPE := (x"ffffffff", x"fffffffe");
    constant FIRST_SEQUENCENUMBER       : SEQUENCENUMBER_TYPE := (x"00000000", x"00000001");
    constant SEQUENCENUMBER_UNKNOWN     : SEQUENCENUMBER_TYPE := (x"ffffffff", x"00000000");
    constant PROTOCOL_RTPS              : std_logic_vector(PROTOCOL_WIDTH-1 downto 0) := x"52545053"; -- 'RTPS' in Ascii code 
    constant PROTOCOLVERSION_1_0        : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0100";
    constant PROTOCOLVERSION_1_1        : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0101";
    constant PROTOCOLVERSION_2_0        : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0200";
    constant PROTOCOLVERSION_2_1        : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0201";
    constant PROTOCOLVERSION_2_2        : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0202";
    constant PROTOCOLVERSION_2_4        : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0204";
    constant VENDORID_UNKNOWN           : std_logic_vector(VENDORID_WIDTH-1 downto 0) := (others => '0');
    constant GUIDPREFIX_UNKNOWN         : GUIDPREFIX_TYPE := (others => (others => '0'));
    constant GUID_UNKNOWN               : GUID_TYPE := (others => (others => '0'));
    constant UDP_PORT_INVALID           : std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := (others => '0');
    constant IPv4_ADDRESS_INVALID       : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := (others => '0');
    constant LENGTH_UNLIMITED           : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH));
    -- DDS
    constant HANDLE_NIL                 : INSTANCE_HANDLE_TYPE := (others => (others => '0'));
    -- CUSTOM
    constant KEY_HASH_NIL               : KEY_HASH_TYPE := (others => (others => '0'));
    
    -- *RETURN CODES* (DDS)
    constant RETCODE_OK                     : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,RETURN_CODE_WIDTH));
    constant RETCODE_ERROR                  : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,RETURN_CODE_WIDTH));
    constant RETCODE_UNSUPPORTED            : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,RETURN_CODE_WIDTH));
    constant RETCODE_BAD_PARAMETER          : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(3,RETURN_CODE_WIDTH));
    constant RETCODE_PRECONDITION_NOT_MET   : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(4,RETURN_CODE_WIDTH));
    constant RETCODE_OUT_OF_RESOURCES       : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(5,RETURN_CODE_WIDTH));
    constant RETCODE_NOT_ENABLED            : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(6,RETURN_CODE_WIDTH));
    constant RETCODE_IMMUTABLE_POLICY       : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(7,RETURN_CODE_WIDTH));
    constant RETCODE_INCONSISTENT_POLICY    : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(8,RETURN_CODE_WIDTH));
    constant RETCODE_ALREADY_DELETED        : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(9,RETURN_CODE_WIDTH));
    constant RETCODE_TIMEOUT                : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(10,RETURN_CODE_WIDTH));
    constant RETCODE_NO_DATA                : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(11,RETURN_CODE_WIDTH));
    constant RETCODE_ILLEGAL_OPERATION      : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(12,RETURN_CODE_WIDTH));
    
    -- *STATUS KIND* (DDS)
    constant INCONSISTENT_TOPIC_STATUS          : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000001";
    constant OFFERED_DEADLINE_MISSED_STATUS     : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000002";
    constant REQUESTED_DEADLINE_MISSED_STATUS   : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000004";
    constant OFFERED_INCOMPATIBLE_QOS_STATUS    : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000020";
    constant REQUESTED_INCOMPATIBLE_QOS_STATUS  : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000040";
    constant SAMPLE_LOST_STATUS                 : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000080";
    constant SAMPLE_REJECTED_STATUS             : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000100";
    constant DATA_ON_READERS_STATUS             : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000200";
    constant DATA_AVAILABLE_STATUS              : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000400";
    constant LIVELINESS_LOST_STATUS             : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00000800";
    constant LIVELINESS_CHANGED_STATUS          : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00001000";
    constant PUBLICATION_MATCHED_STATUS         : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00002000";
    constant SUBSCRIPTION_MATCHED_STATUS        : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0) := x"00004000";
    
    -- *SAMPLE STATE KIND* (DDS)
    constant READ_SAMPLE_STATE      : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := x"00000001";
    constant NOT_READ_SAMPLE_STATE  : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := x"00000002";
    constant ANY_SAMPLE_STATE       : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0) := x"FFFFFFFF";
    
    -- *VIEW STATE KIND* (DDS)
    constant NEW_VIEW_STATE     : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := x"00000001";
    constant NOT_NEW_VIEW_STATE : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := x"00000002";
    constant ANY_VIEW_STATE     : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0) := x"FFFFFFFF";
    
    -- *INSTANCE STATE KIND* (DDS)
    constant ALIVE_INSTANCE_STATE                   : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := x"00000001";
    constant NOT_ALIVE_DISPOSED_INSTANCE_STATE      : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := x"00000002";
    constant NOT_ALIVE_NO_WRITERS_INSTANCE_STATE    : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := x"00000004";
    constant NOT_ALIVE_INSTANCE_STATE               : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := x"00000006";
    constant ANY_INSTANCE_STATE                     : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0) := x"FFFFFFFF";
    
    -- *SAMPLE REJECTED STATUS KIND* (DDS)
    constant NOT_REJECTED                           : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_WIDTH));
    constant REJECTED_BY_INSTANCES_LIMIT            : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant REJECTED_BY_SAMPLES_LIMIT              : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH));
    constant REJECTED_BY_SAMPLES_PER_INSTANCE_LIMIT : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(3,CDR_ENUMERATION_WIDTH));
    -- Extension
    constant REJECTED_BY_PAYLOAD_MEMORY_LIMIT       : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(255,CDR_ENUMERATION_WIDTH));
    constant REJECTED_BY_PENDING_SAMPLE_GENERATION  : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(256,CDR_ENUMERATION_WIDTH));
    
    -- *QOS POLICY ID* (DDS)
    constant INVALID_QOS_POLICY_ID              : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,QOS_POLICY_ID_WIDTH));
    constant USERDATA_QOS_POLICY_ID             : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,QOS_POLICY_ID_WIDTH));
    constant DURABILITY_QOS_POLICY_ID           : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,QOS_POLICY_ID_WIDTH));
    constant PRESENTATION_QOS_POLICY_ID         : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(3,QOS_POLICY_ID_WIDTH));
    constant DEADLINE_QOS_POLICY_ID             : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(4,QOS_POLICY_ID_WIDTH));
    constant LATENCYBUDGET_QOS_POLICY_ID        : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(5,QOS_POLICY_ID_WIDTH));
    constant OWNERSHIP_QOS_POLICY_ID            : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(6,QOS_POLICY_ID_WIDTH));
    constant OWNERSHIPSTRENGTH_QOS_POLICY_ID    : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(7,QOS_POLICY_ID_WIDTH));
    constant LIVELINESS_QOS_POLICY_ID           : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(8,QOS_POLICY_ID_WIDTH));
    constant TIMEBASEDFILTER_QOS_POLICY_ID      : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(9,QOS_POLICY_ID_WIDTH));
    constant PARTITION_QOS_POLICY_ID            : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(10,QOS_POLICY_ID_WIDTH));
    constant RELIABILITY_QOS_POLICY_ID          : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(11,QOS_POLICY_ID_WIDTH));
    constant DESTINATIONORDER_QOS_POLICY_ID     : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(12,QOS_POLICY_ID_WIDTH));
    constant HISTORY_QOS_POLICY_ID              : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(13,QOS_POLICY_ID_WIDTH));
    constant RESOURCELIMITS_QOS_POLICY_ID       : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(14,QOS_POLICY_ID_WIDTH));
    constant ENTITYFACTORY_QOS_POLICY_ID        : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(15,QOS_POLICY_ID_WIDTH));
    constant WRITERDATALIFECYCLE_QOS_POLICY_ID  : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(16,QOS_POLICY_ID_WIDTH));
    constant READERDATALIFECYCLE_QOS_POLICY_ID  : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(17,QOS_POLICY_ID_WIDTH));
    constant TOPICDATA_QOS_POLICY_ID            : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(18,QOS_POLICY_ID_WIDTH));
    constant GROUPDATA_QOS_POLICY_ID            : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(19,QOS_POLICY_ID_WIDTH));
    constant TRANSPORTPRIORITY_QOS_POLICY_ID    : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(20,QOS_POLICY_ID_WIDTH));
    constant LIFESPAN_QOS_POLICY_ID             : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(21,QOS_POLICY_ID_WIDTH));
    constant DURABILITYSERVICE_QOS_POLICY_ID    : std_logic_vector(QOS_POLICY_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(22,QOS_POLICY_ID_WIDTH));
    
    -- *STATUS INFO*
    constant STATUS_INFO_DISPOSED_FLAG      : natural := 0;
    constant STATUS_INFO_UNREGISTERED_FLAG  : natural := 1;
    constant STATUS_INFO_FILTERED_FLAG      : natural := 2;
    
    -- *SUBMESSAGE IDs*
    constant SID_PAD            : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"01";
    constant SID_ACKNACK        : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"06";
    constant SID_HEARTBEAT      : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"07";
    constant SID_GAP            : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"08";
    constant SID_INFO_TS        : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"09";
    constant SID_INFO_SRC       : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"0c";
    constant SID_INFO_REPLY_IP4 : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"0d";
    constant SID_INFO_DST       : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"0e";
    constant SID_INFO_REPLY     : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"0f";
    constant SID_NACK_FRAG      : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"12";
    constant SID_HEARTBEAT_FRAG : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"13";
    constant SID_DATA           : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"15";
    constant SID_DATA_FRAG      : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"16";
    
    -- *SUBMESSAGE FLAG POSITIONS*
    -- NOTE: The KEY and NON_STANDARD_PAYOAD Flags for the DATA_FRAG Submessage are off by one (-1) from this positions
    constant SUBMESSAGE_ENDIAN_FLAG_POS                 : natural := 0;
    constant SUBMESSAGE_FINAL_FLAG_POS                  : natural := 1;
    constant SUBMESSAGE_INLINE_QOS_FLAG_POS             : natural := 1;
    constant SUBMESSAGE_DATA_FLAG_POS                   : natural := 2;
    constant SUBMESSAGE_KEY_FLAG_POS                    : natural := 3;
    constant SUBMESSAGE_NON_STANDARD_PAYLOAD_FLAG_POS   : natural := 4;
    constant SUBMESSAGE_LIVELINESS_FLAG_POS             : natural := 2;
    constant SUBMESSAGE_MULTICAST_FLAG_POS              : natural := 1;
    constant SUBMESSAGE_INVALIDATE_FLAG_POS             : natural := 1;
    
    -- *PARAMETER IDs*
    constant PID_IMPL_EXTENSION_FLAG_POS                : natural := PARAMETER_ID_WIDTH-1;
    constant PID_MUST_UNDERSTAND_FLAG_POS               : natural := PARAMETER_ID_WIDTH-2;
    constant PID_PAD                                    : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0000";
    constant PID_SENTINEL                               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0001";
    constant PID_PARTICIPANT_LEASE_DURATION             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0002";
    constant PID_TIME_BASED_FILTER                      : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0004";
    constant PID_TOPIC_NAME                             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0005";
    constant PID_OWNERSHIP_STRENGTH                     : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0006";
    constant PID_TYPE_NAME                              : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0007";
    constant PID_DOMAIN_ID                              : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"000f";
    constant PID_DOMAIN_TAG                             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"4014";
    constant PID_PROTOCOL_VERSION                       : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0015";
    constant PID_VENDORID                               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0016";
    constant PID_RELIABILITY                            : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001a";
    constant PID_LIVELINESS                             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001b";
    constant PID_DURABILITY                             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001d";
    constant PID_DURABILITY_SERVICE                     : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001e";
    constant PID_OWNERSHIP                              : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001f";
    constant PID_PRESENTATION                           : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0021";
    constant PID_DEADLINE                               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0023";
    constant PID_DESTINATION_ORDER                      : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0025";
    constant PID_LATENCY_BUDGET                         : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0027";
    constant PID_PARTITION                              : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0029";
    constant PID_LIFESPAN                               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002b";
    constant PID_USER_DATA                              : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002c";
    constant PID_GROUP_DATA                             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002d";
    constant PID_TOPIC_DATA                             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002e";
    constant PID_UNICAST_LOCATOR                        : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002f";
    constant PID_MULTICAST_LOCATOR                      : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0030";
    constant PID_DEFAULT_UNICAST_LOCATOR                : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0031";
    constant PID_METATRAFFIC_UNICAST_LOCATOR            : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0032";
    constant PID_METATRAFFIC_MULTICAST_LOCATOR          : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0033";
    constant PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT    : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0034";
    constant PID_CONTENT_FILTER_PROPERTY                : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0035";
    constant PID_HISTORY                                : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0040";
    constant PID_RESOURCE_LIMITS                        : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0041";
    constant PID_EXPECTS_INLINE_QOS                     : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0043";
    constant PID_DEFAULT_MULTICAST_LOCATOR              : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0048";
    constant PID_TRANSPORT_PRIORITY                     : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0049";
    constant PID_PARTICIPANT_GUID                       : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0050";
    constant PID_GROUP_GUID                             : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0052";
    constant PID_BUILTIN_ENDPOINT_SET                   : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0058";
    constant PID_PROPERTY_LIST                          : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0059";
    constant PID_ENDPOINT_GUID                          : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"005a";
    constant PID_DATA_MAX_SIZE_SERIALIZED               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0060";
    constant PID_ENTITY_NAME                            : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0062";
    constant PID_BUILTIN_ENDPOINT_QOS                   : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0077";
    -- INLINE-QOS ONLY
    constant PID_CONTENT_FILTER_INFO                    : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0055";
    constant PID_COHERENT_SET                           : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0056";
    constant PID_DIRECTED_WRITE                         : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0057";
    constant PID_ORIGINAL_WRITER_INFO                   : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0061";
    constant PID_GROUP_COHERENT_SET                     : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0063";
    constant PID_GROUP_SEQ_NUM                          : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0064";
    constant PID_WRITER_GROUP_INFO                      : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0065";
    constant PID_SECURE_WRITER_GROUP_INFO               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0066";
    constant PID_KEY_HASH                               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0070";
    constant PID_STATUS_INFO                            : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0071";
    -- XTYPES 1.3
    constant PID_EXTENDED                               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"7F01";
    constant PID_LIST_END                               : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"7F02";
    constant PID_IGNORE                                 : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"3F03";

    -- *PAYLOAD REPRESENTATION IDENTIFIERS*
    constant CDR_BE     : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0000";
    constant CDR_LE     : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0001";
    constant PL_CDR_BE  : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0002";
    constant PL_CDR_LE  : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0003";
    constant XML        : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0004";
    constant CDR2_BE    : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0010";
    constant CDR2_LE    : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0011";
    constant PL_CDR2_BE : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0012";
    constant PL_CDR2_LE : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0013";
    constant D_CDR_BE   : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0014";
    constant D_CDR_LE   : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) := x"0015";

    -- *ENTITY ID*
    constant ENTITYID_UNKNOWN                               : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (others => '0');
    constant ENTITYID_PARTICIPANT                           : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000001c1");
    constant ENTITYID_SEDP_BUILTIN_TOPICS_ANNOUNCER         : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000002c2");
    constant ENTITYID_SEDP_BUILTIN_TOPICS_DETECTOR          : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000002c7");
    constant ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER   : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000003c2");
    constant ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR    : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000003c7");
    constant ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER  : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000004c2");
    constant ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR   : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000004c7");
    constant ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER    : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000100c2");
    constant ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR     : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000100c7");
    constant ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER: std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000200c2");
    constant ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER: std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000200c7");
    -- *ENTITY KIND* (Last Byte of Entity ID)
    subtype ENTITY_KIND_H_RANGE is natural range 7 downto 6;
    subtype ENTITY_KIND_L_RANGE is natural range 5 downto 0;
    --FOLLOWING MAP TO ENTITY_KIND_H
    constant USER_DEFINED_ENTITY    : std_logic_vector(ENTITY_KIND_H_RANGE) := "00";
    constant BUILT_IN_ENTITY        : std_logic_vector(ENTITY_KIND_H_RANGE) := "11";
    constant VENDOR_SPECIFIC_ENTITY : std_logic_vector(ENTITY_KIND_H_RANGE) := "01";
    --FOLLOWING MAP TO ENTITY_KIND_L
    constant UNKNOWN_KIND       : std_logic_vector(ENTITY_KIND_L_RANGE) := (others => '0');
    constant WRITER_WITH_KEY    : std_logic_vector(ENTITY_KIND_L_RANGE) := "000010";
    constant WRITER_NO_KEY      : std_logic_vector(ENTITY_KIND_L_RANGE) := "000011";
    constant READER_NO_KEY      : std_logic_vector(ENTITY_KIND_L_RANGE) := "000100";
    constant READER_WITH_KEY    : std_logic_vector(ENTITY_KIND_L_RANGE) := "000111";
    constant WRITER_GROUP       : std_logic_vector(ENTITY_KIND_L_RANGE) := "001000";
    constant READER_GROUP       : std_logic_vector(ENTITY_KIND_L_RANGE) := "001001";
    
    -- *LOCATOR KIND*
    constant LOCATOR_KIND_INVALID   : std_logic_vector := std_logic_vector(to_signed(-1,LOCATOR_KIND_WIDTH));
    constant LOCATOR_KIND_RESERVERD : std_logic_vector := std_logic_vector(to_signed(0,LOCATOR_KIND_WIDTH));
    constant LOCATOR_KIND_UDPv4     : std_logic_vector := std_logic_vector(to_signed(1,LOCATOR_KIND_WIDTH));
    constant LOCATOR_KIND_UDPv6     : std_logic_vector := std_logic_vector(to_signed(2,LOCATOR_KIND_WIDTH));
    
    -- *DDS QoS*
    -- DURABILITY
    constant VOLATILE_DURABILITY_QOS                            : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_WIDTH));
    constant TRANSIENT_LOCAL_DURABILITY_QOS                     : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant TRANSIENT_DURABILITY_QOS                           : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH));
    constant PERSISTENT_DURABILITY_QOS                          : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(3,CDR_ENUMERATION_WIDTH));
    constant DEFAULT_DURABILITY_QOS                             : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := VOLATILE_DURABILITY_QOS;
    -- PRESENTATION
    constant INSTANCE_PRESENTATION_QOS                          : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_WIDTH));
    constant TOPIC_PRESENTATION_QOS                             : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant GROUP_PRESENTATION_QOS                             : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH));
    constant DEFAULT_PRESENTATION_QOS                           : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := INSTANCE_PRESENTATION_QOS;
    -- COHERENT ACCESS (PRESENTATION)
    constant DEFAULT_COHERENT_ACCESS                            : boolean := FALSE;
    -- ORDERED ACCESS (PRESENTATION)
    constant DEFAULT_ORDERED_ACCESS                             : boolean := FALSE;
    -- DEADLINE
    constant DEFAULT_DEADLINE_QOS                               : DURATION_TYPE := DURATION_INFINITE;
    -- LATENCY BUDGET
    constant DEFAULT_LATENCY_BUDGET_QOS                         : DURATION_TYPE := DURATION_ZERO;
    -- OWNERSHIP
    constant SHARED_OWNERSHIP_QOS                               : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_WIDTH));
    constant EXCLUSIVE_OWNERSHIP_QOS                            : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant DEFAULT_OWNERSHIP_QOS                              : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := SHARED_OWNERSHIP_QOS;
    -- OWNERSHIP STRENGTH
    constant DEFAULT_OWNERSHIP_STRENGTH_QOS                     : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
    -- LIVELINESS
    constant AUTOMATIC_LIVELINESS_QOS                           : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_WIDTH));
    constant MANUAL_BY_PARTICIPANT_LIVELINESS_QOS               : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant MANUAL_BY_TOPIC_LIVELINESS_QOS                     : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH));
    constant DEFAULT_LIVELINESS_QOS                             : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := AUTOMATIC_LIVELINESS_QOS;
    -- LEASE DURATION (LIVELINESS)
    constant DEFAULT_LEASE_DURATION                             : DURATION_TYPE := DURATION_INFINITE;
    -- TIME_BASED_FILTER
    constant DEFAULT_TIME_BASED_FILTER_QOS                      : DURATION_TYPE := DURATION_ZERO;
    -- RELIABILITY
    constant BEST_EFFORT_RELIABILITY_QOS                        : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant RELIABLE_RELIABILITY_QOS                           : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH));
    constant DEFAULT_RELIABILITY_QOS_W                          : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := RELIABLE_RELIABILITY_QOS;
    constant DEFAULT_RELIABILITY_QOS_R                          : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := BEST_EFFORT_RELIABILITY_QOS;
    -- MAX BLOCKING TIME (RELIABILITY)
    constant DEFAULT_MAX_BLOCKING_TIME                          : DURATION_TYPE; --Deferred to Package Body (100 ms)
    -- TRANSPORT_PRIORITY
    constant DEFAULT_TRANSPORT_PRIORITY_QOS                     : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
    -- LIFESPAN
    constant DEFAULT_LIFESPAN_QOS                               : DURATION_TYPE := DURATION_INFINITE;
    -- DESTINATION ORDER
    constant BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS       : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_WIDTH));
    constant BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS          : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant DEFAULT_DESTINATION_ORDER_QOS                      : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS;
    -- HISTORY
    constant KEEP_LAST_HISTORY_QOS                              : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_WIDTH));
    constant KEEP_ALL_HISTORY_QOS                               : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_WIDTH));
    constant DEFAULT_HISTORY_QOS                                : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := KEEP_LAST_HISTORY_QOS;
    -- DEPTH (HISTORY)
    constant DEFAULT_HISTORY_DEPTH                              : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_LONG_WIDTH));
    -- RESOURCE_LIMITS
    constant DEFAULT_MAX_SAMPLES                                : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
    constant DEFAULT_MAX_INSTANCES                              : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
    constant DEFAULT_MAX_SAMPLES_PER_INSTANCE                   : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
    -- WRITER_DATA_LIFECYCLE
    constant DEFAULT_AUTODISPOSE_UNREGISTERED_INSTANCES         : boolean := TRUE;
    -- READER_DATA_LIFECYCLE
    constant DEFAULT_AUTOPURGE_NOWRITER_SAMPLES_DELAY           : DURATION_TYPE := DURATION_INFINITE;
    constant DEFAULT_AUTOPURGE_DISPOSED_SAMPLES_DELAY           : DURATION_TYPE := DURATION_INFINITE;
    -- TYPE_CONSISTENCY (DDS XTYPES 1.3)
    constant DISALLOW_TYPE_COERCION                             : std_logic_vector(CDR_ENUMERATION_SHORT_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,CDR_ENUMERATION_SHORT_WIDTH));
    constant ALLOW_TYPE_COERCION                                : std_logic_vector(CDR_ENUMERATION_SHORT_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_ENUMERATION_SHORT_WIDTH));
    -- DURABILITY SERVICE (DURABILITY)
    constant DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY           : DURATION_TYPE := DURATION_ZERO;
    constant DEFAULT_DURABILITY_SERVICE_HISTORY                 : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := KEEP_LAST_HISTORY_QOS;
    constant DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH           : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_LONG_WIDTH));
    constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES             : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
    constant DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES           : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
    constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE: std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
    
    constant DEFAULT_PARTICIPANT_LEASE_DURATION                 : DURATION_TYPE; -- Deferred to package Body (100 s)
    
    constant DEFAULT_EXPECTS_INLINE_QOS                         : std_logic := '0';
    
    constant DEFAULT_BUILTIN_ENDPOINT_QOS                       : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
    
    -- *BUILTIN ENDPOINT SET POSITIONS*
    constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER        : natural := 0;
    constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR         : natural := 1;
    constant DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER       : natural := 2;
    constant DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR        : natural := 3;
    constant DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER      : natural := 4;
    constant DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR       : natural := 5;
    constant BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER   : natural := 10;
    constant BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER   : natural := 11;
    constant DISC_BUILTIN_ENDPOINT_TOPICS_ANNOUNCER             : natural := 28;
    constant DISC_BUILTIN_ENDPOINT_TOPICS_DETECTOR              : natural := 29;
    
    -- *BUILTIN ENDPOINT QOS BITMASK*
    -- XXX: We use some of the unused bits of the 32-bit bitmask when stored in the buffer for internal purposes. (see "rtps_discovery_module" Entity)
    constant BEST_EFFORT_PARTICIPANT_MESSAGE_DATA_READER        : natural := 0;
    
    -- *PARTICIPANT MESSAGE KIND*
    constant PARTICIPANT_MESSAGE_DATA_KIND_UNKNOWN                      : std_logic_vector(PARTICIPANT_MESSAGE_KIND_WIDTH-1 downto 0) := (others => '0');
    constant PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE  : std_logic_vector(PARTICIPANT_MESSAGE_KIND_WIDTH-1 downto 0) := x"00000001";
    constant PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE     : std_logic_vector(PARTICIPANT_MESSAGE_KIND_WIDTH-1 downto 0) := x"00000002";
    
    --*DDS-XTYPES*
    constant MAX_ALIGN_OFFSET_WIDTH : natural := 3;
    type ALIGN_TYPE is (ALIGN_1, ALIGN_2, ALIGN_4, ALIGN_8);
    
    function check_align(offset : unsigned; align : ALIGN_TYPE) return boolean;
    
    --*CUSTOM TYPES*
    type ENTITYID_ARRAY_TYPE is array (natural range <>) of std_logic_vector(ENTITYID_WIDTH-1 downto 0);
    type CACHE_CHANGE_KIND_TYPE is (ALIVE, ALIVE_FILTERED, NOT_ALIVE_DISPOSED, NOT_ALIVE_UNREGISTERED);
    type CACHE_CHANGE_KIND_ARRAY_TYPE is array (natural range <>) of CACHE_CHANGE_KIND_TYPE;
    type USER_BOOLEAN_ARRAY_TYPE is array (natural range <>) of boolean;
    subtype USER_STRING_TYPE is string(1 to 256);
    type USER_STRING_ARRAY_TYPE is array (natural range <>) of USER_STRING_TYPE;
    type USER_DURATION_ARRAY_TYPE is array (natural range <>) of DURATION_TYPE;
    type USER_ENUMERATION_ARRAY_TYPE is array (natural range <>) of std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
    type USER_LONG_ARRAY_TYPE is array (natural range <>) of std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
    
    constant EMPTY_USER_STRING : USER_STRING_TYPE := (others => NUL);
    constant DEFAULT_USER_DOMAIN_TAG : USER_STRING_TYPE := EMPTY_USER_STRING;
    
    type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE, GET_CACHE_CHANGE, ACK_CACHE_CHANGE, NACK_CACHE_CHANGE, REMOVE_CACHE_CHANGE, REMOVE_WRITER, GET_MIN_SN, GET_MAX_SN);
    type HISTORY_CACHE_OPCODE_ARRAY_TYPE is array (natural range <>) of HISTORY_CACHE_OPCODE_TYPE;
    type KEY_HOLDER_OPCODE_TYPE is (NOP, PUSH_DATA, PUSH_SERIALIZED_KEY, READ_KEY_HASH, READ_SERIALIZED_KEY);
    type KEY_HOLDER_OPCODE_ARRAY_TYPE is array (natural range <>) of KEY_HOLDER_OPCODE_TYPE;
    type HISTORY_CACHE_RESPONSE_TYPE is (OK, REJECTED, INVALID, ERROR);
    type HISTORY_CACHE_RESPONSE_ARRAY_TYPE is array (natural range <>) of HISTORY_CACHE_RESPONSE_TYPE;
    type DDS_WRITER_OPCODE_TYPE is (NOP, REGISTER_INSTANCE, WRITE, DISPOSE, UNREGISTER_INSTANCE, LOOKUP_INSTANCE, WAIT_FOR_ACKNOWLEDGEMENTS, GET_OFFERED_DEADLINE_MISSED_STATUS, ASSERT_LIVELINESS, GET_LIVELINESS_LOST_STATUS);
    type DDS_WRITER_OPCODE_ARRAY_TYPE is array (natural range <>) of DDS_WRITER_OPCODE_TYPE;
    type DDS_READER_OPCODE_TYPE is (NOP, READ, TAKE, READ_NEXT_SAMPLE, TAKE_NEXT_SAMPLE, READ_INSTANCE, TAKE_INSTANCE, READ_NEXT_INSTANCE, TAKE_NEXT_INSTANCE, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS);
    type DDS_READER_OPCODE_ARRAY_TYPE is array (natural range <>) of DDS_READER_OPCODE_TYPE;
    
    function gen_user_string(input : string) return string;
    function string_len (str : string) return natural;
    function concat(A,B : string) return USER_STRING_TYPE;
    function substr(first : natural; last : natural; str : string) return USER_STRING_TYPE;
    
    type CONFIG_TYPE is record
        -- If Endpoint uses Keye Topics
        WITH_KEY                                    : boolean;
        -- If Writer pushes new Cache Changes/Samples immediately (without waiting for reader ACKNACK first)
        PUSH_MODE                                   : boolean; -- (only relevant to Writers)
        -- DDS Topicname
        TOPICNAME                                   : USER_STRING_TYPE;
        -- DDS Typename
        TYPENAME                                    : USER_STRING_TYPE;
        -- *RTPS Timing Characteristics*
        HEARTBEAT_PERIOD                            : DURATION_TYPE;
        HEARTBEAT_RESPONSE_DELAY                    : DURATION_TYPE;
        HEARTBEAT_SUPPRESSION_DELAY                 : DURATION_TYPE;
        ACKNACK_RESPONSE_DELAY                      : DURATION_TYPE;
        ACKNACK_SUPPRESSION_DELAY                   : DURATION_TYPE;
        -- *DDS QOS*
        -- DURABILITY QoS
        DURABILITY_QOS                              : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        -- DURABILITY SERVICE QoS
        DURABILITY_SERVICE_CLEANUP_DELAY            : DURATION_TYPE;
        DURABILITY_SERVICE_HISTORY                  : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        DURABILITY_SERVICE_HISTORY_DEPTH            : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        DURABILITY_SERVICE_MAX_SAMPLES              : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        DURABILITY_SERVICE_MAX_INSTANCES            : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- PRESENTATION QoS
        PRESENTATION_QOS                            : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        COHERENT_ACCESS                             : boolean;
        ORDERED_ACCESS                              : boolean;
        -- DEADLINE QoS
        DEADLINE_QOS                                : DURATION_TYPE;
        -- LATENCY_BUDGET QoS
        LATENCY_BUDGET_QOS                          : DURATION_TYPE;
        -- OWNERSHIP QoS
        OWNERSHIP_QOS                               : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        -- OWNERSHIP_STRENGTH QoS
        OWNERSHIP_STRENGTH_QOS                      : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); -- (Only relevant to Writers)
        -- LIVELINESS QoS
        LIVELINESS_QOS                              : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        LEASE_DURATION                              : DURATION_TYPE;
        -- TIME_BASED_FILTER QoS
        TIME_BASED_FILTER_QOS                       : DURATION_TYPE;
        -- XXX: PARTITION QoS Ignored
        -- RELIABILITY QoS
        RELIABILITY_QOS                             : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        MAX_BLOCKING_TIME                           : DURATION_TYPE; -- (Only relevant to Writers)
        -- LIFESPAN QoS
        LIFESPAN_QOS                                : DURATION_TYPE;
        -- DESTINATION_ORDER QoS
        DESTINATION_ORDER_QOS                       : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        -- HISTORY QoS
        HISTORY_QOS                                 : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        HISTORY_DEPTH                               : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- RESOURCE_LIMITS QoS
        MAX_SAMPLES                                 : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        MAX_INSTANCES                               : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        MAX_SAMPLES_PER_INSTANCE                    : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- XXX: ENTITY_FACTORY QoS Ignored
        -- WRITER_DATA_LIFECYCLE QoS
        AUTODISPOSE_UNREGISTERED_INSTANCES          : boolean; -- (Only relevant to Writers)
        -- READER_DATA_LIFECYCLE QoS
        AUTOPURGE_NOWRITER_SAMPLES_DELAY            : DURATION_TYPE; -- (Only relevant to Readers)
        AUTOPURGE_DISPOSED_SAMPLES_DELAY            : DURATION_TYPE; -- (Only relevant to Readers)
        MAX_PAYLOAD_SIZE                            : natural;
    end record;
    
    constant DEFAULT_READER_CONFIG : CONFIG_TYPE; -- Deferred to package Body
    constant DEFAULT_WRITER_CONFIG : CONFIG_TYPE; -- Deferred to package Body
    
    type CONFIG_ARRAY_TYPE is array (natural range <>) of CONFIG_TYPE;
    
    -- HACK: FIXME: Quartus Workaround
    --      Quartus cannot handle arrays of records containing subtypes of strings (USER_STRING_ARRAY_TYPE) in generics.
    --      We define a special record type that does not contain string subtypes (TOPIC and TYPE) and a conversion function as a workaround.
    type QUARTUS_CONFIG_TYPE is record
        -- If Endpoint uses Keye Topics
        WITH_KEY                                    : boolean;
        -- If Writer pushes new Cache Changes/Samples immediately (without waiting for reader ACKNACK first)
        PUSH_MODE                                   : boolean; -- (only relevant to Writers)
        -- *RTPS Timing Characteristics*
        HEARTBEAT_PERIOD                            : DURATION_TYPE;
        HEARTBEAT_RESPONSE_DELAY                    : DURATION_TYPE;
        HEARTBEAT_SUPPRESSION_DELAY                 : DURATION_TYPE;
        ACKNACK_RESPONSE_DELAY                      : DURATION_TYPE;
        ACKNACK_SUPPRESSION_DELAY                   : DURATION_TYPE;
        -- *DDS QOS*
        -- DURABILITY QoS
        DURABILITY_QOS                              : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        -- DURABILITY SERVICE QoS
        DURABILITY_SERVICE_CLEANUP_DELAY            : DURATION_TYPE;
        DURABILITY_SERVICE_HISTORY                  : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        DURABILITY_SERVICE_HISTORY_DEPTH            : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        DURABILITY_SERVICE_MAX_SAMPLES              : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        DURABILITY_SERVICE_MAX_INSTANCES            : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- PRESENTATION QoS
        PRESENTATION_QOS                            : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        COHERENT_ACCESS                             : boolean;
        ORDERED_ACCESS                              : boolean;
        -- DEADLINE QoS
        DEADLINE_QOS                                : DURATION_TYPE;
        -- LATENCY_BUDGET QoS
        LATENCY_BUDGET_QOS                          : DURATION_TYPE;
        -- OWNERSHIP QoS
        OWNERSHIP_QOS                               : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        -- OWNERSHIP_STRENGTH QoS
        OWNERSHIP_STRENGTH_QOS                      : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); -- (Only relevant to Writers)
        -- LIVELINESS QoS
        LIVELINESS_QOS                              : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        LEASE_DURATION                              : DURATION_TYPE;
        -- TIME_BASED_FILTER QoS
        TIME_BASED_FILTER_QOS                       : DURATION_TYPE;
        -- XXX: PARTITION QoS Ignored
        -- RELIABILITY QoS
        RELIABILITY_QOS                             : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        MAX_BLOCKING_TIME                           : DURATION_TYPE; -- (Only relevant to Writers)
        -- LIFESPAN QoS
        LIFESPAN_QOS                                : DURATION_TYPE;
        -- DESTINATION_ORDER QoS
        DESTINATION_ORDER_QOS                       : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        -- HISTORY QoS
        HISTORY_QOS                                 : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0);
        HISTORY_DEPTH                               : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- RESOURCE_LIMITS QoS
        MAX_SAMPLES                                 : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        MAX_INSTANCES                               : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        MAX_SAMPLES_PER_INSTANCE                    : std_logic_vector(CDR_LONG_WIDTH-1 downto 0);
        -- XXX: ENTITY_FACTORY QoS Ignored
        -- WRITER_DATA_LIFECYCLE QoS
        AUTODISPOSE_UNREGISTERED_INSTANCES          : boolean; -- (Only relevant to Writers)
        -- READER_DATA_LIFECYCLE QoS
        AUTOPURGE_NOWRITER_SAMPLES_DELAY            : DURATION_TYPE; -- (Only relevant to Readers)
        AUTOPURGE_DISPOSED_SAMPLES_DELAY            : DURATION_TYPE; -- (Only relevant to Readers)
        MAX_PAYLOAD_SIZE                            : natural;
    end record;
    type QUARTUS_CONFIG_ARRAY_TYPE is array (natural range <>) of QUARTUS_CONFIG_TYPE;
    function to_QUARTUS_CONFIG_TYPE(input : CONFIG_TYPE) return QUARTUS_CONFIG_TYPE;
    function to_QUARTUS_CONFIG_ARRAY_TYPE(input : CONFIG_ARRAY_TYPE) return QUARTUS_CONFIG_ARRAY_TYPE;
    
    type SAMPLE_INFO_TYPE is record
        sample_state                : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0);
        view_state                  : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0);
        instance_state              : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0);
        source_timestamp            : TIME_TYPE;
        instance_handle             : INSTANCE_HANDLE_TYPE;
        publication_handle          : INSTANCE_HANDLE_TYPE;
        disposed_generation_count   : std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0);
        no_writers_generation_count : std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0);
        sample_rank                 : std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0);
        generation_rank             : std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0);
        absolute_generation_rank    : std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0);
        valid_data                  : std_logic;
    end record;
    type SAMPLE_INFO_ARRAY_TYPE is array (natural range <>) of SAMPLE_INFO_TYPE;
    
    function to_guid(A : GUIDPREFIX_TYPE; B : std_logic_vector(ENTITYID_WIDTH-1 downto 0)) return GUID_TYPE;
    function to_guid(A : std_logic_vector) return GUID_TYPE;
    function to_key_hash(A : GUID_TYPE) return KEY_HASH_TYPE;
    function to_key_hash(A : std_logic_vector) return KEY_HASH_TYPE;
    
    -- *OVERLOAD FUNCTIONS*
    function to_unsigned (input: DOUBLE_WORD_ARRAY) return unsigned;
    function to_double_word (input: unsigned(63 downto 0)) return DOUBLE_WORD_ARRAY;
    function ">" (L,R: DOUBLE_WORD_ARRAY) return boolean;
    function ">" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean;
    function ">" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean;
    function "<" (L,R: DOUBLE_WORD_ARRAY) return boolean;
    function "<" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean;
    function "<" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean;
    function ">=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
    function ">=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean;
    function ">=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean;
    function "<=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
    function "<=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean;
    function "<=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean;
    function "=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
    function "=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean;
    function "=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean;
    function "/=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
    function "/=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean;
    function "/=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean;
    function "+" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
    function "+" (L: DOUBLE_WORD_ARRAY; R: natural) return DOUBLE_WORD_ARRAY;
    function "+" (L: natural; R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
    function "-" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
    function "-" (L: DOUBLE_WORD_ARRAY; R: natural) return DOUBLE_WORD_ARRAY;
    function "-" (L: natural; R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
    function min(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
    function max(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
    function to_integer(dw : DOUBLE_WORD_ARRAY) return integer;
    function to_unsigned(input : KEY_HASH_TYPE) return unsigned;
    function to_unsigned(input : GUID_TYPE) return unsigned;
    
    -- Indexing Function to extract sub-vectors from std_logic_vector signals
    -- input    SLV from which to extract a sub-vector
    -- index    The SLV is divided in width-sized sub-vectors. index states which sub-vector to extract (depending on invert)
    -- width    width of sub-vector (NOTE: SLV must have a length multiple to width)
    -- invert   If invert=TRUE, index 0 is the leftmost sub-vector, else the rightmost
    function get_sub_vector (input : std_logic_vector; index : natural; width : natural; invert : boolean) return std_logic_vector;
    -- Indexing Function to write sub-vectors to std_logic_vector signals
    -- input    SLV from to which to write a sub-vector
    -- sub      Sub-vector to write into the SLV
    -- index    The SLV is divided in sub-sized 'sub'-vectors. index states which sub-vector to write (depending on invert)
    -- invert   If invert=TRUE, index 0 is the leftmost sub-vector, else the rightmost
    function write_sub_vector(input : std_logic_vector; sub : std_logic_vector; index : natural; invert : boolean) return std_logic_vector;
end package;

package body rtps_package is
    
    function gen_duration(s,ns : integer) return DURATION_TYPE is
        variable ret : DURATION_TYPE := (others => (others => '0'));
        -- "unit" is the value of "ret(1)" equal to 1 nanosecond
        -- (1 / 2^-32) * 10^-9
        constant unit : real := 4.294967296;
        constant sec  : natural := 10**9;
        constant half_sec : natural := sec/2;
    begin
        assert (ns < sec) report "ns argument has to be less than a second" severity failure;
        ret(0) := to_unsigned(s, WORD_WIDTH);
        
        -- If Fraction Bit is >= 500 ms it cannot be represented as a natural (because naturals/integers are signed).
        -- So we handle that manualy
        if (ns >= half_sec) then
            ret(1) := to_unsigned(natural(CEIL(real(ns-half_sec)*unit)),WORD_WIDTH);
            ret(1)(31) := '1';
        else
            ret(1) := to_unsigned(natural(CEIL(real(ns)*unit)),WORD_WIDTH);
        end if;
        
        return ret;
    end function;
    
    function gen_duration(t : time) return DURATION_TYPE is
        variable seconds : natural;
        variable nanoseconds : natural;
    begin
        -- Extract Seconds
        seconds := t / sec;
        -- Extract Nanoseconds
        nanoseconds := (t - (seconds * sec)) / ns;
        
        return gen_duration(seconds, nanoseconds);
    end function;
    
    constant DEFAULT_MAX_BLOCKING_TIME          : DURATION_TYPE := gen_duration(100 ms);
    constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE := gen_duration(100 sec);
    
    function to_unsigned (input: DOUBLE_WORD_ARRAY) return unsigned is
        variable ret : unsigned(63 downto 0) := (others => '0');
    begin
        ret(63 downto 32)   := input(0);
        ret(31 downto 0)    := input(1);
        return ret;
    end function;
    
    function to_double_word (input: unsigned(63 downto 0)) return DOUBLE_WORD_ARRAY is
        variable ret : DOUBLE_WORD_ARRAY := (others => (others => '0'));
    begin
        ret(0)  :=  input(63 downto 32);
        ret(1)  :=  input(31 downto 0);
        return ret;
    end function;
    
    function ">" (L,R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return to_unsigned(L) > to_unsigned(R);
    end function;
    
    function ">" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean is
    begin
        return to_unsigned(L) > R;
    end function;
    
    function ">" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return L > to_unsigned(R);
    end function;
    
    function "<" (L,R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return to_unsigned(L) < to_unsigned(R);
    end function;
    
    function "<" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean is
    begin
        return to_unsigned(L) < R;
    end function;
    
    function "<" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return L < to_unsigned(R);
    end function;
    
    function ">=" (L,R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return to_unsigned(L) >= to_unsigned(R);
    end function;
    
    function ">=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean is
    begin
        return to_unsigned(L) >= R;
    end function;
    
    function ">=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return L >= to_unsigned(R);
    end function;
    
    function "<=" (L,R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return to_unsigned(L) <= to_unsigned(R);
    end function;
    
    function "<=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean is
    begin
        return to_unsigned(L) <= R;
    end function;
    
    function "<=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return L <= to_unsigned(R);
    end function;
    
    function "=" (L,R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return to_unsigned(L) = to_unsigned(R);
    end function;
    
    function "=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean is
    begin
        return to_unsigned(L) = R;
    end function;
    
    function "=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return L = to_unsigned(R);
    end function;
    
    function "/=" (L,R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return to_unsigned(L) /= to_unsigned(R);
    end function;
    
    function "/=" (L: DOUBLE_WORD_ARRAY; R: natural) return boolean is
    begin
        return to_unsigned(L) /= R;
    end function;
    
    function "/=" (L: natural; R: DOUBLE_WORD_ARRAY) return boolean is
    begin
        return L /= to_unsigned(R);
    end function;
    
    function "+" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
    begin
        return to_double_word(to_unsigned(L) + to_unsigned(R));
    end function;
    
    function "+" (L: DOUBLE_WORD_ARRAY; R: natural) return DOUBLE_WORD_ARRAY is
    begin
        return to_double_word(to_unsigned(L) + R);
    end function;
    
    function "+" (L: natural; R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
    begin
        return to_double_word(L + to_unsigned(R));
    end function;
    
    function "-" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
    begin
        return to_double_word(to_unsigned(L) - to_unsigned(R));
    end function;
    
    function "-" (L: DOUBLE_WORD_ARRAY; R: natural) return DOUBLE_WORD_ARRAY is
    begin
        return to_double_word(to_unsigned(L) - R);
    end function;
    
    function "-" (L: natural; R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
    begin
        return to_double_word(L - to_unsigned(R));
    end function;
    
    function min(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
        variable ret : DOUBLE_WORD_ARRAY;
    begin
        if L < R then
            ret := L;
        else
            ret := R;
        end if;
        return ret;
    end function;
    
    function max(L, R : DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
        variable ret : DOUBLE_WORD_ARRAY;
    begin
        if L > R then
            ret := L;
        else
            ret := R;
        end if;
        return ret;
    end function;
    
    function to_integer(dw : DOUBLE_WORD_ARRAY) return integer is
    begin
        return to_integer(dw(1));
    end function;
    
    function to_guid(A : GUIDPREFIX_TYPE; B : std_logic_vector(ENTITYID_WIDTH-1 downto 0)) return GUID_TYPE is
        variable ret : GUID_TYPE := GUID_UNKNOWN;
    begin
        for i in 0 to GUIDPREFIX_TYPE'length-1 loop
            ret(i) := A(i);
        end loop;
        ret(3) := B;
        return ret;
    end function;
    
    function to_key_hash (A : GUID_TYPE) return KEY_HASH_TYPE is
        variable ret : KEY_HASH_TYPE := HANDLE_NIL;
    begin
        assert (GUID_TYPE'length = KEY_HASH_TYPE'length) severity FAILURE;
        for i in 0 to GUID_TYPE'length-1 loop
            ret(i)  := A(i);
        end loop;
        return ret;
    end function;
    
    function to_key_hash (A : std_logic_vector) return KEY_HASH_TYPE is
        variable ret : KEY_HASH_TYPE := HANDLE_NIL;
    begin
        assert (A'length = KEY_HASH_WIDTH) severity FAILURE;
        for i in 0 to KEY_HASH_TYPE'length-1 loop
            ret(i)  := A(((i+1)*WORD_WIDTH)-1 downto i*WORD_WIDTH);
        end loop;
        return ret;
    end function;
    
    function to_unsigned(input : KEY_HASH_TYPE) return unsigned is
        variable ret : unsigned(KEY_HASH_WIDTH-1 downto 0) := (others => '0');
    begin
        
        for i in 0 to KEY_HASH_TYPE'length-1 loop
            ret(((KEY_HASH_TYPE'length-i)*WORD_WIDTH)-1 downto (KEY_HASH_TYPE'length-1-i)*WORD_WIDTH) := unsigned(input(i));
        end loop;
        return ret;
    end function;
    
    function to_unsigned(input : GUID_TYPE) return unsigned is
        variable ret : unsigned(GUID_WIDTH-1 downto 0) := (others => '0');
    begin
        for i in 0 to GUID_TYPE'length-1 loop
            ret(((GUID_TYPE'length-i)*WORD_WIDTH)-1 downto (GUID_TYPE'length-1-i)*WORD_WIDTH) := unsigned(input(i));
        end loop;
        return ret;
    end function;
    
    function check_align(offset : unsigned; align : ALIGN_TYPE) return boolean is
        variable ret : boolean := FALSE;
    begin
        assert (offset'length = MAX_ALIGN_OFFSET_WIDTH) severity FAILURE;
        
        case (align) is
            when ALIGN_1 =>
                ret := TRUE;
            when ALIGN_2 =>
                if (offset(0 downto 0) = "0") then
                    ret := TRUE;
                end if;
            when ALIGN_4 =>
                if (offset(1 downto 0) = "00") then
                    ret := TRUE;
                end if;
            when ALIGN_8 =>
                if (offset(2 downto 0) = "000") then
                    ret := TRUE;
                end if;
        end case;
        
        return ret;
    end function;
    
    function gen_user_string(input : string) return string is
        variable ret : string(1 to 256) := (others => NUL);
    begin
        assert (input'length <= 256) report "String has to be <= 256 Characters" severity FAILURE;
        
        for i in 1 to input'length loop
            ret(i) := input(i);
        end loop;
        return ret;
    end function;
    
    constant DEFAULT_READER_CONFIG : CONFIG_TYPE := (
        WITH_KEY                                    => FALSE,
        PUSH_MODE                                   => TRUE,
        TOPICNAME                                   => gen_user_string(""),
        TYPENAME                                    => gen_user_string(""),
        HEARTBEAT_PERIOD                            => gen_duration(1 sec),
        HEARTBEAT_RESPONSE_DELAY                    => gen_duration(500 ms),
        HEARTBEAT_SUPPRESSION_DELAY                 => gen_duration(0 ms),
        ACKNACK_RESPONSE_DELAY                      => gen_duration(200 ms),
        ACKNACK_SUPPRESSION_DELAY                   => gen_duration(0 ms),
        DURABILITY_QOS                              => DEFAULT_DURABILITY_QOS,
        DURABILITY_SERVICE_CLEANUP_DELAY            => DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY,
        DURABILITY_SERVICE_HISTORY                  => DEFAULT_DURABILITY_SERVICE_HISTORY,
        DURABILITY_SERVICE_HISTORY_DEPTH            => DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH,
        DURABILITY_SERVICE_MAX_SAMPLES              => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES,
        DURABILITY_SERVICE_MAX_INSTANCES            => DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES,
        DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE,
        PRESENTATION_QOS                            => DEFAULT_PRESENTATION_QOS,
        COHERENT_ACCESS                             => DEFAULT_COHERENT_ACCESS,
        ORDERED_ACCESS                              => DEFAULT_ORDERED_ACCESS,
        DEADLINE_QOS                                => DEFAULT_DEADLINE_QOS,
        LATENCY_BUDGET_QOS                          => DEFAULT_LATENCY_BUDGET_QOS,
        OWNERSHIP_QOS                               => DEFAULT_OWNERSHIP_QOS,
        OWNERSHIP_STRENGTH_QOS                      => DEFAULT_OWNERSHIP_STRENGTH_QOS,
        LIVELINESS_QOS                              => DEFAULT_LIVELINESS_QOS,
        LEASE_DURATION                              => DEFAULT_LEASE_DURATION,
        TIME_BASED_FILTER_QOS                       => DEFAULT_TIME_BASED_FILTER_QOS,
        RELIABILITY_QOS                             => DEFAULT_RELIABILITY_QOS_R,
        MAX_BLOCKING_TIME                           => DEFAULT_MAX_BLOCKING_TIME,
        LIFESPAN_QOS                                => DEFAULT_LIFESPAN_QOS,
        DESTINATION_ORDER_QOS                       => DEFAULT_DESTINATION_ORDER_QOS,
        HISTORY_QOS                                 => DEFAULT_HISTORY_QOS,
        HISTORY_DEPTH                               => DEFAULT_HISTORY_DEPTH,
        MAX_SAMPLES                                 => DEFAULT_MAX_SAMPLES,
        MAX_INSTANCES                               => DEFAULT_MAX_INSTANCES,
        MAX_SAMPLES_PER_INSTANCE                    => DEFAULT_MAX_SAMPLES_PER_INSTANCE,
        AUTODISPOSE_UNREGISTERED_INSTANCES          => DEFAULT_AUTODISPOSE_UNREGISTERED_INSTANCES,
        AUTOPURGE_NOWRITER_SAMPLES_DELAY            => DEFAULT_AUTOPURGE_NOWRITER_SAMPLES_DELAY,
        AUTOPURGE_DISPOSED_SAMPLES_DELAY            => DEFAULT_AUTOPURGE_DISPOSED_SAMPLES_DELAY,
        MAX_PAYLOAD_SIZE                            => 0
    );
    
    constant DEFAULT_WRITER_CONFIG : CONFIG_TYPE := (
        WITH_KEY                                    => FALSE,
        PUSH_MODE                                   => TRUE,
        TOPICNAME                                   => gen_user_string(""),
        TYPENAME                                    => gen_user_string(""),
        HEARTBEAT_PERIOD                            => gen_duration(1 sec),
        HEARTBEAT_RESPONSE_DELAY                    => gen_duration(500 ms),
        HEARTBEAT_SUPPRESSION_DELAY                 => gen_duration(0 ms),
        ACKNACK_RESPONSE_DELAY                      => gen_duration(200 ms),
        ACKNACK_SUPPRESSION_DELAY                   => gen_duration(0 ms),
        DURABILITY_QOS                              => DEFAULT_DURABILITY_QOS,
        DURABILITY_SERVICE_CLEANUP_DELAY            => DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY,
        DURABILITY_SERVICE_HISTORY                  => DEFAULT_DURABILITY_SERVICE_HISTORY,
        DURABILITY_SERVICE_HISTORY_DEPTH            => DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH,
        DURABILITY_SERVICE_MAX_SAMPLES              => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES,
        DURABILITY_SERVICE_MAX_INSTANCES            => DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES,
        DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE,
        PRESENTATION_QOS                            => DEFAULT_PRESENTATION_QOS,
        COHERENT_ACCESS                             => DEFAULT_COHERENT_ACCESS,
        ORDERED_ACCESS                              => DEFAULT_ORDERED_ACCESS,
        DEADLINE_QOS                                => DEFAULT_DEADLINE_QOS,
        LATENCY_BUDGET_QOS                          => DEFAULT_LATENCY_BUDGET_QOS,
        OWNERSHIP_QOS                               => DEFAULT_OWNERSHIP_QOS,
        OWNERSHIP_STRENGTH_QOS                      => DEFAULT_OWNERSHIP_STRENGTH_QOS,
        LIVELINESS_QOS                              => DEFAULT_LIVELINESS_QOS,
        LEASE_DURATION                              => DEFAULT_LEASE_DURATION,
        TIME_BASED_FILTER_QOS                       => DEFAULT_TIME_BASED_FILTER_QOS,
        RELIABILITY_QOS                             => DEFAULT_RELIABILITY_QOS_W,
        MAX_BLOCKING_TIME                           => DEFAULT_MAX_BLOCKING_TIME,
        LIFESPAN_QOS                                => DEFAULT_LIFESPAN_QOS,
        DESTINATION_ORDER_QOS                       => DEFAULT_DESTINATION_ORDER_QOS,
        HISTORY_QOS                                 => DEFAULT_HISTORY_QOS,
        HISTORY_DEPTH                               => DEFAULT_HISTORY_DEPTH,
        MAX_SAMPLES                                 => DEFAULT_MAX_SAMPLES,
        MAX_INSTANCES                               => DEFAULT_MAX_INSTANCES,
        MAX_SAMPLES_PER_INSTANCE                    => DEFAULT_MAX_SAMPLES_PER_INSTANCE,
        AUTODISPOSE_UNREGISTERED_INSTANCES          => DEFAULT_AUTODISPOSE_UNREGISTERED_INSTANCES,
        AUTOPURGE_NOWRITER_SAMPLES_DELAY            => DEFAULT_AUTOPURGE_NOWRITER_SAMPLES_DELAY,
        AUTOPURGE_DISPOSED_SAMPLES_DELAY            => DEFAULT_AUTOPURGE_DISPOSED_SAMPLES_DELAY,
        MAX_PAYLOAD_SIZE                            => 0
    );
    
    function string_len(str : string) return natural is
        variable ret    : natural;
    begin
        ret := 0;
        for i in 1 to str'length loop
            if (str(i) = NUL) then
                exit;
            end if;
            ret := ret + 1;
        end loop;
        return ret;
    end function;
    
    function concat(A,B : string) return USER_STRING_TYPE is
        variable ret : USER_STRING_TYPE;
        variable index : natural;
    begin
        assert (string_len(A) + string_len(B) <= USER_STRING_TYPE'length) report "Concatenated String exceeds USER_STRING_TYPE character limit" severity FAILURE;
        
        ret := EMPTY_USER_STRING;
        index := 1;
        for i in 1 to string_len(A) loop
            ret(index) := A(i);
            index := index + 1;
        end loop;
        for i in 1 to string_len(B) loop
            ret(index) := B(i);
            index := index + 1;
        end loop;
        return ret;
    end function;
    
    function substr(first : natural; last : natural; str : string) return USER_STRING_TYPE is
        variable ret : USER_STRING_TYPE;
    begin
        assert (last >= first) report "SUBSTR: Last index has to come after first index" severity FAILURE;
        assert (last <= string_len(str)) report "SUBSTR: Last index exceeds string length" severity FAILURE;
        
        ret := EMPTY_USER_STRING;
        for i in 1 to last-first+1 loop
            ret(i) := str(first+i);
        end loop;
        return ret;
    end function;
    
    function get_sub_vector (input : std_logic_vector; index : natural; width : natural; invert : boolean) return std_logic_vector is
        variable ret : std_logic_vector(width-1 downto 0) := (others => '0');
        variable input2 : std_logic_vector(input'length-1 downto 0) := (others => '0');
    begin
        assert(input'length mod width = 0) report "Input Length has to be multiple of width" severity FAILURE;
        assert(input'length / width > index) report "Index out of bounds" severity FAILURE;
        
        input2 := input; -- Force input to "downto" range
        
        if (invert = TRUE) then
            -- XXX: Synthesis Hack
            --ret := input(input'length-(index*width)-1 downto input'length-((index+1)*width));
            for i in 0 to (input'length/width)-1 loop
                if (index = i) then
                    ret := input2(input'length-(i*width)-1 downto input'length-((i+1)*width));
                end if;
            end loop;
        else
            -- XXX: Synthesis Hack
            --ret := input(((index+1)*width)-1 downto index*width);
            for i in 0 to (input'length/width)-1 loop
                if (index = i) then
                    ret := input2(((i+1)*width)-1 downto i*width);
                end if;
            end loop;
        end if;
        
        return ret;
    end function;
    
    function write_sub_vector(input : std_logic_vector; sub : std_logic_vector; index : natural; invert : boolean) return std_logic_vector is
        variable ret : std_logic_vector(input'length-1 downto 0) := (others => '0');
    begin
        assert(input'length mod sub'length = 0) report "Input Length has to be multiple of sub width" severity FAILURE;
        assert(input'length / sub'length > index) report "Index out of bounds" severity FAILURE;
        
        ret := input;
        
        if (invert = TRUE) then
            -- XXX: Synthesis Hack
            --ret(input'length-(index*sub'length)-1 downto input'length-((index+1)*sub'length))   := sub;
            for i in 0 to (input'length/sub'length)-1 loop
                if (index = i) then
                    ret(input'length-(i*sub'length)-1 downto input'length-((i+1)*sub'length))   := sub;
                end if;
            end loop;
        else
            -- XXX: Synthesis Hack
            --ret(((index+1)*sub'length)-1 downto index*sub'length)   := sub;
            for i in 0 to (input'length/sub'length)-1 loop
                if (index = i) then
                    ret(((i+1)*sub'length)-1 downto i*sub'length)   := sub;
                end if;
            end loop;
        end if;
        
        return ret;
    end function;
    
    function to_guid(A : std_logic_vector) return GUID_TYPE is
        variable ret : GUID_TYPE;
    begin
        assert (A'length = GUID_WIDTH) report "SLV Length missmatch" severity FAILURE;
        ret := GUID_UNKNOWN;
        for i in 0 to ret'length-1 loop
            ret(i) := get_sub_vector(A, i, ret(i)'length, TRUE);
        end loop;
        return ret;
    end function;
    
    function to_QUARTUS_CONFIG_TYPE(input : CONFIG_TYPE) return QUARTUS_CONFIG_TYPE is
        variable ret : QUARTUS_CONFIG_TYPE;
    begin
        ret.WITH_KEY                                    := input.WITH_KEY;
        ret.PUSH_MODE                                   := input.PUSH_MODE;
        ret.HEARTBEAT_PERIOD                            := input.HEARTBEAT_PERIOD;
        ret.HEARTBEAT_RESPONSE_DELAY                    := input.HEARTBEAT_RESPONSE_DELAY;
        ret.HEARTBEAT_SUPPRESSION_DELAY                 := input.HEARTBEAT_SUPPRESSION_DELAY;
        ret.ACKNACK_RESPONSE_DELAY                      := input.ACKNACK_RESPONSE_DELAY;
        ret.ACKNACK_SUPPRESSION_DELAY                   := input.ACKNACK_SUPPRESSION_DELAY;
        ret.DURABILITY_QOS                              := input.DURABILITY_QOS;
        ret.DURABILITY_SERVICE_CLEANUP_DELAY            := input.DURABILITY_SERVICE_CLEANUP_DELAY;
        ret.DURABILITY_SERVICE_HISTORY                  := input.DURABILITY_SERVICE_HISTORY;
        ret.DURABILITY_SERVICE_HISTORY_DEPTH            := input.DURABILITY_SERVICE_HISTORY_DEPTH;
        ret.DURABILITY_SERVICE_MAX_SAMPLES              := input.DURABILITY_SERVICE_MAX_SAMPLES;
        ret.DURABILITY_SERVICE_MAX_INSTANCES            := input.DURABILITY_SERVICE_MAX_INSTANCES;
        ret.DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE := input.DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE;
        ret.PRESENTATION_QOS                            := input.PRESENTATION_QOS;
        ret.COHERENT_ACCESS                             := input.COHERENT_ACCESS;
        ret.ORDERED_ACCESS                              := input.ORDERED_ACCESS;
        ret.DEADLINE_QOS                                := input.DEADLINE_QOS;
        ret.LATENCY_BUDGET_QOS                          := input.LATENCY_BUDGET_QOS;
        ret.OWNERSHIP_QOS                               := input.OWNERSHIP_QOS;
        ret.OWNERSHIP_STRENGTH_QOS                      := input.OWNERSHIP_STRENGTH_QOS;
        ret.LIVELINESS_QOS                              := input.LIVELINESS_QOS;
        ret.LEASE_DURATION                              := input.LEASE_DURATION;
        ret.TIME_BASED_FILTER_QOS                       := input.TIME_BASED_FILTER_QOS;
        ret.RELIABILITY_QOS                             := input.RELIABILITY_QOS;
        ret.MAX_BLOCKING_TIME                           := input.MAX_BLOCKING_TIME;
        ret.LIFESPAN_QOS                                := input.LIFESPAN_QOS;
        ret.DESTINATION_ORDER_QOS                       := input.DESTINATION_ORDER_QOS;
        ret.HISTORY_QOS                                 := input.HISTORY_QOS;
        ret.HISTORY_DEPTH                               := input.HISTORY_DEPTH;
        ret.MAX_SAMPLES                                 := input.MAX_SAMPLES;
        ret.MAX_INSTANCES                               := input.MAX_INSTANCES;
        ret.MAX_SAMPLES_PER_INSTANCE                    := input.MAX_SAMPLES_PER_INSTANCE;
        ret.AUTODISPOSE_UNREGISTERED_INSTANCES          := input.AUTODISPOSE_UNREGISTERED_INSTANCES;
        ret.AUTOPURGE_NOWRITER_SAMPLES_DELAY            := input.AUTOPURGE_NOWRITER_SAMPLES_DELAY;
        ret.AUTOPURGE_DISPOSED_SAMPLES_DELAY            := input.AUTOPURGE_DISPOSED_SAMPLES_DELAY;
        ret.MAX_PAYLOAD_SIZE                            := input.MAX_PAYLOAD_SIZE;
        return ret;
    end function;
    
    function to_QUARTUS_CONFIG_ARRAY_TYPE(input : CONFIG_ARRAY_TYPE) return QUARTUS_CONFIG_ARRAY_TYPE is
        variable ret : QUARTUS_CONFIG_ARRAY_TYPE(input'range);
    begin
        for i in input'range loop
            ret(i)  := to_QUARTUS_CONFIG_TYPE(input(i));
        end loop;
        return ret;
    end function;
    
end package body;
