library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library osvvm; -- Utility Library context osvvm.OsvvmContext; use work.math_pkg.all; use work.rtps_package.all; use work.user_config.all; use work.rtps_config_package.all; package rtps_test_package is constant DEFAULT_GUIDPREFIX : GUIDPREFIX_TYPE; -- Deferred to Package Body constant DEFAULT_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0); -- Deferred to Package Body type TEST_PACKET_TYPE is record -- Limit Packet Size to 2^16 (IPv4 size limit) data : WORD_ARRAY_TYPE(0 to (2**16)/4); length : natural; end record; constant LOCATOR_PORT_WIDTH : natural := CDR_LONG_WIDTH; constant LOCATOR_ADDR_WIDTH : natural := 4*CDR_LONG_WIDTH; type LOCATOR_TYPE is record kind : std_logic_vector(LOCATOR_KIND_WIDTH-1 downto 0); portn : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); addr : std_logic_vector(LOCATOR_ADDR_WIDTH-1 downto 0); end record; constant EMPTY_LOCATOR : LOCATOR_TYPE; -- Deferred to Package Body -- Limit Number of Locators to maximum number that fits in a maximum length RTPS Submessage type LOCATOR_TYPE_ARRAY is array (0 to ((2**16)/4)/6) of LOCATOR_TYPE; type LOCATOR_LIST_TYPE is record numLocators : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); locator : LOCATOR_TYPE_ARRAY; end record; constant EMPTY_LOCATOR_LIST : LOCATOR_LIST_TYPE; -- Deferred to Package Body type SEQUENCENUMBER_SET_TYPE is record base : SEQUENCENUMBER_TYPE; numBits : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); bitmap : std_logic_vector(0 to 255); end record; constant DEFAULT_SEQUENCENUMBER_SET : SEQUENCENUMBER_SET_TYPE; -- Deferred to package Body type FRAGMENTNUMBER_SET_TYPE is record base : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); numBits : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); bitmap : std_logic_vector(0 to 255); end record; constant DEFAULT_FRAGMENTNUMBER_SET : FRAGMENTNUMBER_SET_TYPE; -- Deferred to Package Body -- Valid Destination Locators type DEST_LOCATOR_LIST_TYPE is record meta : LOCATOR_LIST_TYPE; user : LOCATOR_LIST_TYPE; end record; constant DEST_LOC : DEST_LOCATOR_LIST_TYPE; -- Deferred to Package Body -- *UDP HEADER* type UDP_HEADER_TYPE is record src : LOCATOR_TYPE; dest : LOCATOR_TYPE; end record; constant DEFAULT_UDP_HEADER : UDP_HEADER_TYPE; -- Deferred to Package Body procedure gen_udp_header(ref : in UDP_HEADER_TYPE; output : inout TEST_PACKET_TYPE); procedure fix_udp_packet(output : inout TEST_PACKET_TYPE); -- *RTPS HEADER* type RTPS_HEADER_TYPE is record protocol : std_logic_vector(PROTOCOL_WIDTH-1 downto 0); version : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0); vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0); guidPrefix : GUIDPREFIX_TYPE; end record; constant DEFAULT_RTPS_HEADER : RTPS_HEADER_TYPE; -- Deferred to Package Body procedure gen_rtps_header( ref : in RTPS_HEADER_TYPE; output : inout TEST_PACKET_TYPE); -- *GENERIC RTPS SUBMESSAGE HEADER* type RTPS_SUBMESSAGE_TYPE is record submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); extraFlags : std_logic_vector(SUBMESSAGE_DATA_EXTRA_FLAGS_WIDTH-1 downto 0); octetsToInlineQos : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); readerSNState : SEQUENCENUMBER_SET_TYPE; count : std_logic_vector(COUNT_WIDTH-1 downto 0); writerSN : SEQUENCENUMBER_TYPE; fragmentNumberState : FRAGMENTNUMBER_SET_TYPE; data : TEST_PACKET_TYPE; fragmentStartingNumber : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); fragmentsInSubmessage : std_logic_vector(CDR_SHORT_WIDTH-1 downto 0); fragmentSize : std_logic_vector(CDR_SHORT_WIDTH-1 downto 0); sampleSize : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); gapStart : SEQUENCENUMBER_TYPE; gapList : SEQUENCENUMBER_SET_TYPE; firstSN : SEQUENCENUMBER_TYPE; lastSN : SEQUENCENUMBER_TYPE; lastFragmentNum : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); guidPrefix : GUIDPREFIX_TYPE; unicastLocatorList : LOCATOR_LIST_TYPE; multicastLocatorList : LOCATOR_LIST_TYPE; unicastLocator : LOCATOR_TYPE; multicastLocator : LOCATOR_TYPE; unused : std_logic_vector(31 downto 0); version : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0); vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0); timestamp : TIME_TYPE; end record; constant DEFAULT_RTPS_SUBMESSAGE : RTPS_SUBMESSAGE_TYPE; -- Deferred to Package Body procedure gen_rtps_submessage( ref : in RTPS_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; ts : in TIME_TYPE; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE); type PARTICIPANT_DATA_TYPE is record littleEndian : std_logic; domainId : std_logic_vector(DOMAIN_ID_WIDTH-1 downto 0); domainTag : STRING_WORD_ARRAY_TYPE; protocolVersion : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0); vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0); guidPrefix : GUIDPREFIX_TYPE; entityId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); expectsInlineQoS : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0); metatrafficUnicastLocatorList : LOCATOR_LIST_TYPE; metatrafficMulticastLocatorList : LOCATOR_LIST_TYPE; defaultUnicastLocatorList : LOCATOR_LIST_TYPE; defaultMulticastLocatorList : LOCATOR_LIST_TYPE; leaseDuration : DURATION_TYPE; manualLivelinessCount : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); builtinEndpointQoS : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); availableBuiltinEndpoints : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); end record; constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE; -- Deferred to Pckage Body procedure gen_participant_announcement( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE); type ENDPOINT_DATA_TYPE is record littleEndian : std_logic; participant : PARTICIPANT_DATA_TYPE; entityId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); topic_name : STRING_WORD_ARRAY_TYPE; type_name : STRING_WORD_ARRAY_TYPE; durability : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); 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_instances : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); presentation : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); coherent_access : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0); ordered_access : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0); deadline : DURATION_TYPE; latency_budget : DURATION_TYPE; ownership : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); ownership_strength : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); liveliness : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); leaseDuration : DURATION_TYPE; time_based_filter : DURATION_TYPE; reliability : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); max_blocking_time : DURATION_TYPE; transportnpriority : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); lifespan : DURATION_TYPE; destination_order : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); -- Represent Data as Strings (Ease of Use) user_data : STRING_WORD_ARRAY_TYPE; topic_data : STRING_WORD_ARRAY_TYPE; group_data : STRING_WORD_ARRAY_TYPE; expectsInlineQoS : std_logic_vector(CDR_BOOLEAN_WIDTH-1 downto 0); unicastLocatorList : LOCATOR_LIST_TYPE; multicastLocatorList : LOCATOR_LIST_TYPE; max_size_serialized : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); end record; constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE; -- Deferred to Package Body procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); procedure gen_rand_loc(RV : inout RandomPType; ret : out LOCATOR_TYPE); function int(n : integer; width : natural) return std_logic_vector; end package; package body rtps_test_package is -- *UTILITY FUNCTIONS* procedure gen_rand_loc(RV : inout RandomPType; ret : out LOCATOR_TYPE) is begin ret := EMPTY_LOCATOR; ret.kind := LOCATOR_KIND_UDPv4; ret.portn(UDP_PORT_WIDTH-1 downto 0) := RV.RandSlv(UDP_PORT_WIDTH); ret.addr(IPv4_ADDRESS_WIDTH-1 downto 0) := RV.RandSlv(IPv4_ADDRESS_WIDTH); end procedure; function int(n : integer; width : natural) return std_logic_vector is begin return std_logic_vector(to_signed(n, width)); end function; -- *DEFERRED DEFINITIONS* constant DEFAULT_GUIDPREFIX : GUIDPREFIX_TYPE := (0 => x"da27cc3c", 1 => x"687ddcde", 2 => x"88bce3d1"); constant DEFAULT_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := x"b9cbad8d"; constant EMPTY_LOCATOR : LOCATOR_TYPE := ( kind => LOCATOR_KIND_INVALID, portn => (others => '0'), addr => (others => '0') ); constant EMPTY_LOCATOR_LIST : LOCATOR_LIST_TYPE := ( numLocators => (others => '0'), locator => (others => EMPTY_LOCATOR) ); constant DEFAULT_SEQUENCENUMBER_SET : SEQUENCENUMBER_SET_TYPE := ( base => FIRST_SEQUENCENUMBER, numBits => (others => '0'), bitmap => (others => '0') ); constant DEFAULT_FRAGMENTNUMBER_SET : FRAGMENTNUMBER_SET_TYPE := ( base => int(1,CDR_LONG_WIDTH), numBits => (others => '0'), bitmap => (others => '0') ); constant DEST_LOC : DEST_LOCATOR_LIST_TYPE := ( meta => ( numLocators => int(4,CDR_LONG_WIDTH), locator => ( 0 => ( kind => LOCATOR_KIND_UDPv4, portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_MULTICAST_PORT, addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_META_ADDRESS ), 1 => ( kind => LOCATOR_KIND_UDPv4, portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_UNICAST_PORT, addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_META_ADDRESS ), 2 => ( kind => LOCATOR_KIND_UDPv4, portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_MULTICAST_PORT, addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS ), 3 => ( kind => LOCATOR_KIND_UDPv4, portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_UNICAST_PORT, addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS ), others => EMPTY_LOCATOR ) ), user => ( numLocators => int(2,CDR_LONG_WIDTH), locator => ( 0 => ( kind => LOCATOR_KIND_UDPv4, portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & USER_IPv4_MULTICAST_PORT, addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS ), 1 => ( kind => LOCATOR_KIND_UDPv4, portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & USER_IPv4_UNICAST_PORT, addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS ), others => EMPTY_LOCATOR ) ) ); constant DEFAULT_UDP_HEADER : UDP_HEADER_TYPE := ( src => EMPTY_LOCATOR, dest => EMPTY_LOCATOR ); constant DEFAULT_RTPS_HEADER : RTPS_HEADER_TYPE := ( protocol => PROTOCOL_RTPS, version => PROTOCOLVERSION_2_4, vendorId => VENDORID_UNKNOWN, guidPrefix => DEFAULT_GUIDPREFIX ); constant DEFAULT_RTPS_SUBMESSAGE : RTPS_SUBMESSAGE_TYPE := ( submessageID => (others => '0'), flags => (others => '0'), submessageLength => (others => '1'), readerId => ENTITYID_UNKNOWN, writerId => ENTITYID_UNKNOWN, readerSNState => DEFAULT_SEQUENCENUMBER_SET, count => int(1,COUNT_WIDTH), extraFlags => (others => '0'), octetsToInlineQos => int(16, SUBMESSAGE_LENGTH_WIDTH), writerSN => FIRST_SEQUENCENUMBER, fragmentNumberState => DEFAULT_FRAGMENTNUMBER_SET, data => (length => 0, data => (others => (others => '0'))), fragmentStartingNumber => int(1,CDR_LONG_WIDTH), fragmentsInSubmessage => int(1,CDR_SHORT_WIDTH), fragmentSize => (others => '0'), sampleSize => (others => '0'), gapStart => FIRST_SEQUENCENUMBER, gapList => DEFAULT_SEQUENCENUMBER_SET, firstSN => FIRST_SEQUENCENUMBER, lastSN => (others => (others => '0')), lastFragmentNum => int(1,CDR_LONG_WIDTH), guidPrefix => DEFAULT_GUIDPREFIX, unicastLocatorList => EMPTY_LOCATOR_LIST, multicastLocatorList => EMPTY_LOCATOR_LIST, unicastLocator => EMPTY_LOCATOR, multicastLocator => EMPTY_LOCATOR, unused => (others => '0'), version => PROTOCOLVERSION_2_4, vendorId => VENDORID_UNKNOWN, timestamp => TIME_ZERO ); constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := ( littleEndian => '0', domainId => (others => '0'), domainTag => (others => (others => '0')), protocolVersion => PROTOCOLVERSION_2_4, vendorId => VENDORID_UNKNOWN, guidPrefix => GUIDPREFIX_UNKNOWN, entityId => ENTITYID_PARTICIPANT, expectsInlineQoS => (others => '0'), metatrafficUnicastLocatorList => EMPTY_LOCATOR_LIST, metatrafficMulticastLocatorList => EMPTY_LOCATOR_LIST, defaultUnicastLocatorList => EMPTY_LOCATOR_LIST, -- NOTE: Has to be initialized defaultMulticastLocatorList => EMPTY_LOCATOR_LIST, leaseDuration => DEFAULT_PARTICIPANT_LEASE_DURATION, manualLivelinessCount => (others => '0'), builtinEndpointQoS => (others => '0'), availableBuiltinEndpoints => (DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER => '1', DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER => '1', others => '0') ); constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE := ( littleEndian => '0', participant => DEFAULT_PARTICIPANT_DATA, entityId => DEFAULT_ENTITYID, topic_name => EMPTY_STRING, type_name => EMPTY_STRING, durability => 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_instances => DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE, presentation => DEFAULT_PRESENTATION_QOS, coherent_access => (0 => boolean_to_std_logic(DEFAULT_COHERENT_ACCESS), others => '0'), ordered_access => (0 => boolean_to_std_logic(DEFAULT_ORDERED_ACCESS), others => '0'), deadline => DEFAULT_DEADLINE_QOS, latency_budget => DEFAULT_LATENCY_BUDGET_QOS, ownership => DEFAULT_OWNERSHIP_QOS, ownership_strength => DEFAULT_OWNERSHIP_STRENGTH_QOS, liveliness => DEFAULT_LIVELINESS_QOS, leaseDuration => DEFAULT_LEASE_DURATION, time_based_filter => DEFAULT_TIME_BASED_FILTER_QOS, reliability => DEFAULT_RELIABILTY_QOS, max_blocking_time => DEFAULT_MAX_BLOCKING_TIME, transportnpriority => DEFAULT_TRANSPORT_PRIORITY_QOS, lifespan => DEFAULT_LIFESPAN_QOS, destination_order => DEFAULT_DESTINATION_ORDER_QOS, user_data => EMPTY_STRING, topic_data => EMPTY_STRING, group_data => EMPTY_STRING, expectsInlineQoS => (others => '0'), unicastLocatorList => EMPTY_LOCATOR_LIST, multicastLocatorList => EMPTY_LOCATOR_LIST, max_size_serialized => (others => '0') ); -- *PACKAGE INTERNAL HELPER FUNCTIONS* procedure store_byte(in_off : in natural range 0 to 3; input : in std_logic_vector(WORD_WIDTH-1 downto 0); out_off : in natural range 0 to 3; output : inout TEST_PACKET_TYPE) is begin output.data(output.length)((BYTE_WIDTH*out_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*out_off)) := input((BYTE_WIDTH*in_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*in_off)); end procedure; procedure gen_udp_header(ref : in UDP_HEADER_TYPE; output : inout TEST_PACKET_TYPE) is begin -- IPv4 Source Address output.data(output.length) := ref.src.addr(IPv4_ADDRESS_WIDTH-1 downto 0); output.length := output.length + 1; -- IPv4 Destination Address output.data(output.length) := ref.dest.addr(IPv4_ADDRESS_WIDTH-1 downto 0); output.length := output.length + 1; -- Packet Length output.data(output.length) := (others => '0'); output.length := output.length + 1; -- Source Port & Destination Port output.data(output.length) := ref.src.portn(UDP_PORT_WIDTH-1 downto 0) & ref.dest.portn(UDP_PORT_WIDTH-1 downto 0); output.length := output.length + 1; -- Length & Checksum output.data(output.length) := (others => '0'); output.length := output.length + 1; end procedure; procedure fix_udp_packet(output : inout TEST_PACKET_TYPE) is begin assert (output.length < 2**UDP_PORT_WIDTH) report "Exceeded maximum UDP Packet Size" severity error; -- Fix Packet Length output.data(2) := int(output.length-3, WORD_WIDTH); -- Fix UDP Length output.data(4)(31 downto 16) := int((output.length-3)*4, UDP_HEADER_LENGTH_WIDTH); -- TODO: Calculate Checksum end procedure; procedure gen_rtps_header( ref : in RTPS_HEADER_TYPE; output : inout TEST_PACKET_TYPE) is begin -- Protocol output.data(output.length) := ref.protocol; output.length := output.length + 1; -- Protocol Version & Vendor ID output.data(output.length) := ref.version & ref.vendorId; output.length := output.length + 1; -- GUID Prefix output.data(output.length) := ref.guidPrefix(0); output.length := output.length + 1; output.data(output.length) := ref.guidPrefix(1); output.length := output.length + 1; output.data(output.length) := ref.guidPrefix(2); output.length := output.length + 1; end procedure; procedure write_sequence_ns(input : in SEQUENCENUMBER_SET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin -- Sequence Number State (Base) output.data(output.length) := endian_swap(littleEndian, std_logic_vector(input.base(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(littleEndian, std_logic_vector(input.base(1))); output.length := output.length + 1; -- Sequence Number State (NumBits) assert (unsigned(input.numBits) <= 256) report "SequenceNS.numbits is higher than 256." severity warning; output.data(output.length) := endian_swap(littleEndian, input.numBits); output.length := output.length + 1; -- Sequence Number State (Bitmap) for i in 0 to round_div(to_integer(unsigned(input.numBits)),WORD_WIDTH)-1 loop if (i < MAX_BITMAP_WIDTH/WORD_WIDTH) then output.data(output.length) := endian_swap(littleEndian, input.bitmap(i*32 to i*32+31)); output.length := output.length + 1; end if; end loop; end procedure; procedure write_fragment_ns(input : in FRAGMENTNUMBER_SET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin -- Sequence Number State (Base) output.data(output.length) := endian_swap(littleEndian, input.base); output.length := output.length + 1; -- Sequence Number State (NumBits) assert (unsigned(input.numBits) <= 256) report "SequenceNS.numbits is higher than 256." severity warning; output.data(output.length) := endian_swap(littleEndian, input.numBits); output.length := output.length + 1; -- Sequence Number State (Bitmap) for i in 0 to round_div(to_integer(unsigned(input.numBits)),WORD_WIDTH)-1 loop if (i < MAX_BITMAP_WIDTH/WORD_WIDTH) then output.data(output.length) := endian_swap(littleEndian, input.bitmap(i*32 to i*32+31)); output.length := output.length + 1; end if; end loop; end procedure; procedure write_locator_list(input : in LOCATOR_LIST_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin -- NumLocators output.data(output.length) := endian_swap(littleEndian, input.numLocators); output.length := output.length + 1; for i in 0 to to_integer(unsigned(input.numLocators))-1 loop -- Kind output.data(output.length) := endian_swap(littleEndian, input.locator(i).kind); output.length := output.length + 1; -- Port output.data(output.length) := endian_swap(littleEndian, input.locator(i).portn); output.length := output.length + 1; -- Address output.data(output.length) := input.locator(i).addr(127 downto 96); output.length := output.length + 1; output.data(output.length) := input.locator(i).addr(95 downto 64); output.length := output.length + 1; output.data(output.length) := input.locator(i).addr(63 downto 32); output.length := output.length + 1; output.data(output.length) := input.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end procedure; procedure gen_rtps_submessage( ref : in RTPS_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is variable start : natural := 0; variable tmp : natural := 0; begin -- *GENERAL* start := output.length; -- Submessage ID & Submessage Flags & Submessage Length output.data(output.length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); output.length := output.length + 1; -- *DATA/DATA_FRAG* if (ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then -- Extra Flags & octetsToInlineQos output.data(output.length) := ref.extraFlags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.octetsToInlineQos); output.length := output.length + 1; end if; -- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG/GAP/DATA/DATA_FRAG* if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_HEARTBEAT_FRAG or ref.submessageID = SID_GAP or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then -- Reader ID output.data(output.length) := ref.readerId; output.length := output.length + 1; -- Writer ID output.data(output.length) := ref.writerId; output.length := output.length + 1; end if; -- *NACK_FRAG/DATA/DATA_FRAG/HEARTBEAT_FRAG* if (ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG or ref.submessageID = SID_HEARTBEAT_FRAG) then output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(1))); output.length := output.length + 1; end if; -- *ACKNACK* if (ref.submessageID = SID_ACKNACK) then -- Reader State write_sequence_ns(ref.readerSNState, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); -- *NACK_FRAG* elsif (ref.submessageID = SID_NACK_FRAG) then -- Fragment Number State write_fragment_ns(ref.fragmentNumberState, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); -- *HEARTBEAT* elsif (ref.submessageID = SID_HEARTBEAT) then -- First Sequence Number output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(1))); output.length := output.length + 1; -- Last Sequence Number output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(1))); output.length := output.length + 1; -- *HEARTBEAT_FRAG* elsif (ref.submessageID = SID_HEARTBEAT_FRAG) then -- Last Fargment Number output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.lastFragmentNum); output.length := output.length + 1; end if; -- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG* if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT_FRAG) then output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.count); output.length := output.length + 1; end if; -- *GAP* if (ref.submessageID = SID_GAP) then -- Gap Start output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(1))); output.length := output.length + 1; -- Gap List write_sequence_ns(ref.gapList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); end if; -- *DATA_FRAG* if (ref.submessageID = SID_DATA_FRAG) then -- Fragment Number output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentStartingNumber); output.length := output.length + 1; -- FragmentsinSubmessage & FragmentSize output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentsInSubmessage) & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentSize); output.length := output.length + 1; -- Sample Size output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.sampleSize); output.length := output.length + 1; end if; -- *DATA/DATA_FRAG* if (ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then -- EXTRA HEADER tmp := to_integer(unsigned(ref.octetsToInlineQos)) - 16; if (tmp > 0) then for i in 0 to tmp-1 loop store_byte((i+1) mod 4, x"DEADBEEF", (i+1) mod 4, output); if (i mod 4 = 3) then output.length := output.length + 1; output.data(output.length) := (others => '0'); end if; end loop; end if; -- DATA if (ref.data.length > 0) then for i in 0 to (ref.data.length*4)-1 loop store_byte((i+tmp) mod 4, ref.data.data(i/4), i mod 4, output); if ((i+tmp) mod 4 = 3) then output.length := output.length + 1; output.data(output.length) := (others => '0'); end if; end loop; end if; -- Fix Alignement if ((tmp + (ref.data.length*4)) mod 4 /= 0) then output.length := output.length + 1; end if; end if; -- *INFO_SRC* if (ref.submessageID = SID_INFO_SRC) then -- UNUSED output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unused); output.length := output.length + 1; -- Protocol Version & Vendor ID output.data(output.length) := ref.version & ref.vendorId; output.length := output.length + 1; -- *INFO_REPLY* elsif (ref.submessageID = SID_INFO_REPLY) then write_locator_list(ref.unicastLocatorList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then write_locator_list(ref.multicastLocatorList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); end if; -- *INFO_REPLY_IP4* elsif (ref.submessageID = SID_INFO_REPLY_IP4) then -- Unicast Locator (Address) output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.addr(CDR_LONG_WIDTH-1 downto 0)); output.length := output.length + 1; -- Unicast Locator (Port) output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.portn); output.length := output.length + 1; if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then -- Multicast Locator (Address) output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.addr(CDR_LONG_WIDTH-1 downto 0)); output.length := output.length + 1; -- Multicast Locator (Port) output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.portn); output.length := output.length + 1; end if; -- *INFO_TS* elsif (ref.submessageID = SID_INFO_TS) then -- Timestamp if (ref.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) = '0') then output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(1))); output.length := output.length + 1; end if; end if; -- *INFO_DEST/INFO_SRC* if (ref.submessageID = SID_INFO_DST or ref.submessageID = SID_INFO_SRC) then -- GUID Prefix output.data(output.length) := ref.guidPrefix(0); output.length := output.length + 1; output.data(output.length) := ref.guidPrefix(1); output.length := output.length + 1; output.data(output.length) := ref.guidPrefix(2); output.length := output.length + 1; end if; -- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG/GAP/DATA/DATA_FRAG* if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_HEARTBEAT_FRAG or ref.submessageID = SID_GAP or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG or ref.submessageID = SID_INFO_TS or ref.submessageID = SID_INFO_SRC or ref.submessageID = SID_INFO_DST or ref.submessageID = SID_INFO_REPLY or ref.submessageID =SID_INFO_REPLY_IP4) then -- Fix Submessage Length if (ref.submessageLength = (ref.submessageLength'range => '1')) then output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int((output.length-start-1)*4,SUBMESSAGE_LENGTH_WIDTH)); -- Fix Packet Length else output.length := start + to_integer(unsigned(ref.submessageLength)); end if; -- *PAD/UKNOWN* else -- Padding tmp := to_integer(unsigned(ref.submessageLength)); assert (tmp mod 4 = 0) report "Padding Length has to be multiple of four" severity FAILURE; for i in 0 to (tmp/4)-1 loop output.data(output.length) := (others => '0'); output.length := output.length + 1; end loop; end if; end procedure; procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; ts : in TIME_TYPE; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE) is begin -- Opcode & Flags & Source Port output.data(output.length) := ref.submessageID & ref.flags & loc.portn(UDP_PORT_WIDTH-1 downto 0); output.length := output.length + 1; -- Source Address output.data(output.length) := loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); output.length := output.length + 1; -- Source Entity ID if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG) then output.data(output.length) := ref.readerId; output.length := output.length + 1; else output.data(output.length) := ref.writerId; output.length := output.length + 1; end if; -- Source GUID Prefix output.data(output.length) := src_guid(0); output.length := output.length + 1; output.data(output.length) := src_guid(1); output.length := output.length + 1; output.data(output.length) := src_guid(2); output.length := output.length + 1; -- Destination Enity ID if (is_meta) then if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG) then output.data(output.length) := ref.writerId; output.length := output.length + 1; else output.data(output.length) := ref.readerId; output.length := output.length + 1; end if; end if; -- *DATA* if (ref.submessageID = SID_DATA) then -- Sequence Number output.data(output.length) := std_logic_vector(ref.writerSN(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(ref.writerSN(1)); output.length := output.length + 1; -- Timestamp if (not is_meta) then output.data(output.length) := std_logic_vector(ts(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(ts(1)); output.length := output.length + 1; end if; -- DATA PAYLOAD if (ref.data.length > 0) then for i in 0 to ref.data.length-1 loop output.data(output.length) := ref.data.data(i); output.length := output.length + 1; end loop; end if; end if; -- *ACKNACK* if (ref.submessageID = SID_ACKNACK) then -- Reader State write_sequence_ns(ref.readerSNState, '0', output); -- *HEARTBEAT* elsif (ref.submessageID = SID_HEARTBEAT) then -- First Sequence Number output.data(output.length) := std_logic_vector(ref.firstSN(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(ref.firstSN(1)); output.length := output.length + 1; -- Last Sequence Number output.data(output.length) := std_logic_vector(ref.lastSN(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(ref.lastSN(1)); output.length := output.length + 1; end if; -- *ACKNACK/HEARTBEAT* if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_HEARTBEAT) then output.data(output.length) := ref.count; output.length := output.length + 1; end if; -- *GAP* if (ref.submessageID = SID_GAP) then -- Gap Start output.data(output.length) := std_logic_vector(ref.gapStart(0)); output.length := output.length + 1; output.data(output.length) := std_logic_vector(ref.gapStart(1)); output.length := output.length + 1; -- Gap List write_sequence_ns(ref.gapList, '0', output); end if; end procedure; procedure gen_participant_announcement( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is variable tmp : natural := 0; begin -- Representation Identifier & Representation Options if (ref.littleEndian = '0') then output.data(output.length) := PL_CDR_BE & x"0000"; else output.data(output.length) := PL_CDR_LE & x"0000"; end if; output.length := output.length + 1; -- GUID output.data(output.length) := PID_PARTICIPANT_GUID & endian_swap(ref.littleEndian, int(16, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := ref.guidPrefix(0); output.length := output.length + 1; output.data(output.length) := ref.guidPrefix(1); output.length := output.length + 1; output.data(output.length) := ref.guidPrefix(2); output.length := output.length + 1; output.data(output.length) := ref.entityId; output.length := output.length + 1; -- DOMAIN ID output.data(output.length) := PID_DOMAIN_ID & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.domainId); output.length := output.length + 1; -- DOMAIN TAG if (ref.domainTag /= EMPTY_STRING) then tmp := string_len(ref.domainTag); output.data(output.length) := PID_DOMAIN_TAG & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop output.data(output.length) := ref.domainTag(i); output.length := output.length + 1; end loop; end if; -- PROTOCOL VERSION output.data(output.length) := PID_PROTOCOL_VERSION & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := (others => '0'); output.data(output.length)(31 downto 16) := ref.protocolVersion; output.length := output.length + 1; -- VENDORID output.data(output.length) := PID_VENDORID & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := (others => '0'); output.data(output.length)(31 downto 16) := ref.vendorId; output.length := output.length + 1; -- EXPECTS IN-LINE QOS if (ref.expectsInlineQoS(0) /= '0') then output.data(output.length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := (others => '0'); output.data(output.length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap output.length := output.length + 1; end if; -- METATRAFFIC UNICAST LOCATOR if (ref.metatrafficUnicastLocatorList.numLocators /= (ref.metatrafficUnicastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.metatrafficUnicastLocatorList.numLocators)); output.data(output.length) := PID_METATRAFFIC_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).portn); output.length := output.length + 1; output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- METATRAFFIC MULTICAST LOCATOR if (ref.metatrafficMulticastLocatorList.numLocators /= (ref.metatrafficMulticastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.metatrafficMulticastLocatorList.numLocators)); output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).portn); output.length := output.length + 1; output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- DEFAULT UNICAST LOCATOR assert (unsigned(ref.defaultUnicastLocatorList.numLocators) > 0) report "PARTICIPANT_DATA: Participant needs to have at least one Default Unicast Locator." severity error; if (ref.defaultUnicastLocatorList.numLocators /= (ref.defaultUnicastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.defaultUnicastLocatorList.numLocators)); output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).portn); output.length := output.length + 1; output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- DEFAULT MULTICAST LOCATOR if (ref.defaultMulticastLocatorList.numLocators /= (ref.defaultMulticastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.defaultMulticastLocatorList.numLocators)); output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).portn); output.length := output.length + 1; output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- LEASE DURATION if (ref.leaseDuration /= DEFAULT_PARTICIPANT_LEASE_DURATION) then output.data(output.length) := PID_PARTICIPANT_LEASE_DURATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1))); output.length := output.length + 1; end if; -- AVAILABLE ENDPOINTS output.data(output.length) := PID_BUILTIN_ENDPOINT_SET & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.availableBuiltinEndpoints); output.length := output.length + 1; -- MANUAL LIVELINESS COUNT output.data(output.length) := PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.manualLivelinessCount); output.length := output.length + 1; end procedure; procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is variable tmp : natural := 0; begin -- GUID output.data(output.length) := PID_ENDPOINT_GUID & endian_swap(ref.littleEndian, int(16,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := ref.participant.guidPrefix(0); output.length := output.length + 1; output.data(output.length) := ref.participant.guidPrefix(1); output.length := output.length + 1; output.data(output.length) := ref.participant.guidPrefix(2); output.length := output.length + 1; output.data(output.length) := ref.entityId; output.length := output.length + 1; -- EXPECTS IN-LINE QOS if (ref.expectsInlineQoS(0) /= '0') then output.data(output.length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := (others => '0'); output.data(output.length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap output.length := output.length + 1; end if; -- TOPIC NAME tmp := string_len(ref.topic_name); output.data(output.length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop output.data(output.length) := ref.topic_name(i); output.length := output.length + 1; end loop; -- TYPE NAME tmp := string_len(ref.type_name); output.data(output.length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,CDR_LONG_WIDTH)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop output.data(output.length) := ref.type_name(i); output.length := output.length + 1; end loop; -- DURABILITY if (ref.durability /= DEFAULT_DURABILITY_QOS) then output.data(output.length) := PID_DURABILITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.durability); output.length := output.length + 1; end if; -- DURABILITY SERVICE if (ref.durability_service_cleanup_delay /= DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY or ref.durability_service_history /= DEFAULT_DURABILITY_SERVICE_HISTORY or ref.durability_service_history_depth /= DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH or ref.durability_service_max_samples /= DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES or ref.durability_service_max_instances /= DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES or ref.durability_service_max_samples_per_instances /= DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE) then output.data(output.length) := PID_DURABILITY_SERVICE & endian_swap(ref.littleEndian, int(28,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(1))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_history); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_history_depth); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_instances); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples_per_instances); output.length := output.length + 1; end if; -- PRESENTATION if (ref.presentation /= DEFAULT_PRESENTATION_QOS or ref.coherent_access(0) /= boolean_to_std_logic(DEFAULT_COHERENT_ACCESS) or ref.ordered_access(0) /= boolean_to_std_logic(DEFAULT_ORDERED_ACCESS)) then output.data(output.length) := PID_PRESENTATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.presentation); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.coherent_access) & endian_swap(ref.littleEndian, ref.ordered_access); output.length := output.length + 1; end if; -- DEADLINE if (ref.deadline /= DEFAULT_DEADLINE_QOS) then output.data(output.length) := PID_DEADLINE & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1))); output.length := output.length + 1; end if; -- LATENCY BUDGET if (ref.latency_budget /= DEFAULT_LATENCY_BUDGET_QOS) then output.data(output.length) := PID_LATENCY_BUDGET & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1))); output.length := output.length + 1; end if; -- OWNERSHIP if (ref.ownership /= DEFAULT_OWNERSHIP_QOS) then output.data(output.length) := PID_OWNERSHIP & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership); output.length := output.length + 1; end if; -- OWNERSHIP STRENGTH if (ref.ownership /= DEFAULT_OWNERSHIP_STRENGTH_QOS) then output.data(output.length) := PID_OWNERSHIP_STRENGTH & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership_strength); output.length := output.length + 1; end if; -- LIVELINESS if (ref.liveliness /= DEFAULT_LIVELINESS_QOS or ref.leaseDuration /= DEFAULT_LEASE_DURATION) then output.data(output.length) := PID_LIVELINESS & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.liveliness); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1))); output.length := output.length + 1; end if; -- TIME BASED FILTER if (ref.time_based_filter /= DEFAULT_TIME_BASED_FILTER_QOS) then output.data(output.length) := PID_TIME_BASED_FILTER & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(1))); output.length := output.length + 1; end if; -- RELIABILITY if (ref.reliability /= DEFAULT_RELIABILTY_QOS or ref.max_blocking_time /= DEFAULT_MAX_BLOCKING_TIME) then output.data(output.length) := PID_RELIABILITY & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.reliability); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(1))); output.length := output.length + 1; end if; -- TRANSPORT PRIORITY if (ref.transportnpriority /= DEFAULT_TRANSPORT_PRIORITY_QOS) then output.data(output.length) := PID_TRANSPORT_PRIORITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.transportnpriority); output.length := output.length + 1; end if; -- LIFESPAN if (ref.lifespan /= DEFAULT_LIFESPAN_QOS) then output.data(output.length) := PID_LIFESPAN & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(0))); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(1))); output.length := output.length + 1; end if; -- DESTINATION ORDER if (ref.destination_order /= DEFAULT_DESTINATION_ORDER_QOS) then output.data(output.length) := PID_DESTINATION_ORDER & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.destination_order); output.length := output.length + 1; end if; -- UNICAST LOCATORS if (unsigned(ref.unicastLocatorList.numLocators) > 0) then tmp := to_integer(unsigned(ref.unicastLocatorList.numLocators)); for i in 0 to tmp-1 loop output.data(output.length) := PID_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).portn); output.length := output.length + 1; output.data(output.length) := ref.unicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; output.data(output.length) := ref.unicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; output.data(output.length) := ref.unicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; output.data(output.length) := ref.unicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- MULTICAST LOCATORS if (unsigned(ref.multicastLocatorList.numLocators) > 0) then tmp := to_integer(unsigned(ref.multicastLocatorList.numLocators)); for i in 0 to tmp-1 loop output.data(output.length) := PID_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).portn); output.length := output.length + 1; output.data(output.length) := ref.multicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; output.data(output.length) := ref.multicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; output.data(output.length) := ref.multicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; output.data(output.length) := ref.multicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- USER DATA tmp := string_len(ref.user_data); if (tmp > 1) then output.data(output.length) := PID_USER_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, 32)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop output.data(output.length) := ref.user_data(i); output.length := output.length + 1; end loop; end if; -- TOPIC DATA tmp := string_len(ref.topic_data); if (tmp > 1) then output.data(output.length) := PID_TOPIC_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,32)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop output.data(output.length) := ref.topic_data(i); output.length := output.length + 1; end loop; end if; -- GROUP DATA tmp := string_len(ref.group_data); if (tmp > 1) then output.data(output.length) := PID_GROUP_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,32)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop output.data(output.length) := ref.group_data(i); output.length := output.length + 1; end loop; end if; -- MAX SIZE SERIALIZED if (unsigned(ref.max_size_serialized) /= 0) then output.data(output.length) := PID_DATA_MAX_SIZE_SERIALIZED & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.max_size_serialized); output.length := output.length + 1; end if; end procedure; end package body;