From 929fbe5c808d1eb7e4555c7a91307016b261cb3b Mon Sep 17 00:00:00 2001 From: Greek Date: Sun, 6 Dec 2020 18:25:19 +0100 Subject: [PATCH] * Update rtps_builtin_endpoint_test7 - Add participant Announcement check * bug Fix in rtps_config_package - Fix Participant Announcement Generation --- src/TODO.txt | 10 +- .../Level_1/rtps_builtin_endpoint_test7.vhd | 53 ++++++- src/rtps_builtin_endpoint.vhd | 2 +- src/rtps_config_package.vhd | 141 +++++++++--------- src/rtps_package.vhd | 2 + src/rtps_test_package.vhd | 24 +-- 6 files changed, 144 insertions(+), 88 deletions(-) diff --git a/src/TODO.txt b/src/TODO.txt index 9c7e9dd..ce9fe36 100644 --- a/src/TODO.txt +++ b/src/TODO.txt @@ -85,7 +85,15 @@ Does this invalidate the Submessage? Does 8.3.4.1 apply (Invalidate rest of Message)? - 9.4.5.1.3 octetsToNextHeader Similarly to "9.4.2.11" state that this is always a multiple of four. - + - 9.6.2.2.2 Table 9.14 + States that the builtinEndpointQos has no Default value, but according to + 8.4.13.3 + If the ParticipantProxy::builtinEndpointQos is included in the SPDPdiscoveredParticipantData, then the + BuiltinParticipantMessageWriter shall treat the BuiltinParticipantMessageReader as indicated by the flags. If + the ParticipantProxy::builtinEndpointQos is not included then the BuiltinParticipantMessageWriter shall treat + the BuiltinParticipantMessageReader as if it is configured with RELIABLE_RELIABILITY_QOS. + which means that the default value is 0. + * DDS 1.4 ISSUES - 2.2.3 Supported QoS Partition is marked as RxO=No, but should be RxO=Yes? Or not? diff --git a/src/Tests/Level_1/rtps_builtin_endpoint_test7.vhd b/src/Tests/Level_1/rtps_builtin_endpoint_test7.vhd index 6bfd30c..f4a2d7b 100644 --- a/src/Tests/Level_1/rtps_builtin_endpoint_test7.vhd +++ b/src/Tests/Level_1/rtps_builtin_endpoint_test7.vhd @@ -10,7 +10,7 @@ use work.user_config.all; use work.rtps_config_package.all; use work.rtps_test_package.all; --- This testbench tests the rtps output of the builtin endpoint. +-- This testbench tests the rtps output of the builtin endpoint (Local Liveliness Assertion, Local Heartbeat Generation, Local Participant Announcement, Remote HEARTBEAT Response, Remote ACKNACK Response). -- This test is a Level 1 Test (Meaning the input/output is not connected directly to the uut) in order to have output in the msae format as the input of the system and allow us to compare using existing data generators. -- The testflow is as follows: -- * 0s @@ -68,6 +68,8 @@ use work.rtps_test_package.all; -- * 3.000s -- - Local HEARTBEAT generation -- - Liveliness Assertion (Manual & Auto) + + entity rtps_builtin_endpoint_test7 is end entity; @@ -115,7 +117,7 @@ architecture testbench of rtps_builtin_endpoint_test7 is variable output : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; begin -- NOTE: Ha to be made sure uut used same Locator - OUT_HEADER := (dest => get_loc(participant, TRUE), src => DEST_LOC.meta.locator(1)); + OUT_HEADER := (dest => get_loc(participant, TRUE), src => DEST_LOC.meta.locator(3)); -- OUTPUT HEADER gen_output_header(OUT_HEADER, output); @@ -157,6 +159,38 @@ architecture testbench of rtps_builtin_endpoint_test7 is end loop; end procedure; + procedure gen_announcement is + variable sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable OUT_HEADER : OUTPUT_HEADER_TYPE := DEFAULT_OUTPUT_HEADER; + variable rtps_header: RTPS_HEADER_TYPE := DEFAULT_RTPS_HEADER; + variable output : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; + begin + -- NOTE: Ha to be made sure uut used same Locator + OUT_HEADER := (dest => DEST_LOC.meta.locator(0), src => DEST_LOC.meta.locator(3)); + + -- OUTPUT HEADER + gen_output_header(OUT_HEADER, output); + -- RTPS HEADER + rtps_header := DEFAULT_RTPS_HEADER; + rtps_header.guidPrefix := GUIDPREFIX; + gen_rtps_header(rtps_header, output); + -- PARTICIPANT DATA + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_DATA; + sub.writerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; + sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; + sub.writerSN := gen_sn(1); + sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + gen_participant_data(THIS_PARTICIPANT_DATA, sub.data); + gen_sentinel(sub.data); + gen_rtps_submessage(sub, output); + fix_output_packet(output); + + for i in 0 to output.length-1 loop + SB_out.Push(output.data(i)); + end loop; + end procedure; + procedure gen_heartbeat(participant : in PARTICIPANT_DATA_TYPE; count : in natural; man_sn : in SEQUENCENUMBER_TYPE; auto_sn : in SEQUENCENUMBER_TYPE) is variable sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; variable OUT_HEADER : OUTPUT_HEADER_TYPE := DEFAULT_OUTPUT_HEADER; @@ -164,7 +198,7 @@ architecture testbench of rtps_builtin_endpoint_test7 is variable output : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; begin -- NOTE: Has to be made sure uut used same Locator - OUT_HEADER := (dest => get_loc(participant, TRUE), src => DEST_LOC.meta.locator(1)); + OUT_HEADER := (dest => get_loc(participant, TRUE), src => DEST_LOC.meta.locator(3)); -- OUTPUT HEADER gen_output_header(OUT_HEADER, output); @@ -238,7 +272,7 @@ architecture testbench of rtps_builtin_endpoint_test7 is variable output : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; begin -- NOTE: Ha to be made sure uut used same Locator - OUT_HEADER := (dest => get_loc(participant, TRUE), src => DEST_LOC.meta.locator(1)); + OUT_HEADER := (dest => get_loc(participant, TRUE), src => DEST_LOC.meta.locator(3)); -- *PUBLISHERS* if (pub) then @@ -895,6 +929,15 @@ begin wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + Log("Current Time: 31s", INFO); + test_time <= gen_duration(31,0); + + gen_announcement; + gen_heartbeat(p0, 6, gen_sn(6), gen_sn(8)); + + wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + wait on mem_op_done until rising_edge(mem_op_done) and stale_check = '1'; + TranscriptOpen(RESULTS_FILE, APPEND_MODE); SetTranscriptMirror; stim_done <= '1'; @@ -917,6 +960,7 @@ begin in_empty_prc : process begin in_empty <= '0'; + wait; -- TODO: Remove wait until rd_sig = '1'; wait until rising_edge(clk); in_empty <= '1'; @@ -926,6 +970,7 @@ begin endpoint_full_prc : process begin full <= '0'; + wait; -- TODO: Remove wait until wr_sig = '1'; wait until rising_edge(clk); full <= '1'; diff --git a/src/rtps_builtin_endpoint.vhd b/src/rtps_builtin_endpoint.vhd index 9dead6d..8c55aeb 100644 --- a/src/rtps_builtin_endpoint.vhd +++ b/src/rtps_builtin_endpoint.vhd @@ -2478,7 +2478,7 @@ begin -- OUTPUT HEADER -- Src IPv4 Address when 0 => - data_out <= DEFAULT_IPv4_META_ADDRESS; + data_out <= DEFAULT_IPv4_ADDRESS; -- Dest IPv4 Address when 1 => -- Set Default Multicast Announce Address if Participant Announcement diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index cd359a8..0195e2c 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -691,175 +691,174 @@ package body rtps_config_package is function gen_participant_data return OUTPUT_DATA_TYPE is variable ret : OUTPUT_DATA_TYPE := (data => (others => (others => '0')), length => 0); - variable ind : natural := 0; variable len : natural := 0; variable tmp : natural := 0; begin ret.data := (others => (others => '0')); ret.length := 0; len := 0; - ind := 0; -- RTPS DATA SUBMESSAGE -- RTPS Submessage Header - ret.data(ind) := SID_DATA & "00000100" & x"0000"; + ret.data(len) := SID_DATA & "00000100" & x"0000"; -- DATA Header (extraFlags, octetsToInlineQoS) len := len + 1; - ret.data(ind+len) := x"0000" & std_logic_vector(to_unsigned(16, 16)); + ret.data(len) := x"0000" & std_logic_vector(to_unsigned(16, 16)); -- DATA Header (Reader Entity ID) len := len + 1; - ret.data(ind+len) := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; + ret.data(len) := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; -- DATA Header (Writer Entity ID) len := len + 1; - ret.data(ind+len) := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; + ret.data(len) := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; -- DATA Header (Sequence Number) len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); -- DATA Header (Sequence Number) len := len + 1; - ret.data(ind+len) := std_logic_vector(to_unsigned(1, ret.data(ind+len)'length)); + ret.data(len) := std_logic_vector(to_unsigned(1, ret.data(len)'length)); -- Serialized Payload Header len := len + 1; - ret.data(ind+len) := PL_CDR_BE & x"0000"; + ret.data(len) := PL_CDR_BE & x"0000"; -- Serialized Payload BEGIN -- GUID len := len + 1; - ret.data(ind+len):= PID_PARTICIPANT_GUID & std_logic_vector(to_unsigned(16, 16)); + ret.data(len):= PID_PARTICIPANT_GUID & std_logic_vector(to_unsigned(16, 16)); len := len + 1; - ret.data(ind+len) := GUIDPREFIX(0); + ret.data(len) := GUIDPREFIX(0); len := len + 1; - ret.data(ind+len) := GUIDPREFIX(1); + ret.data(len) := GUIDPREFIX(1); len := len + 1; - ret.data(ind+len) := GUIDPREFIX(2); + ret.data(len) := GUIDPREFIX(2); len := len + 1; - ret.data(ind+len) := ENTITYID_PARTICIPANT; + ret.data(len) := ENTITYID_PARTICIPANT; -- DOMAIN ID len := len + 1; - ret.data(ind+len):= PID_DOMAIN_ID & std_logic_vector(to_unsigned(4, 16)); + ret.data(len):= PID_DOMAIN_ID & std_logic_vector(to_unsigned(4, 16)); len := len + 1; - ret.data(ind+len):= DOMAIN_ID; + ret.data(len):= DOMAIN_ID; -- DOMAIN TAG if (DOMAIN_TAG /= DEFAULT_DOMAIN_TAG) then tmp := string_len(DOMAIN_TAG); len := len + 1; - ret.data(ind+len) := PID_DOMAIN_TAG & std_logic_vector(to_unsigned((round_div(tmp,4)+1)*4, 16)); + ret.data(len) := PID_DOMAIN_TAG & std_logic_vector(to_unsigned((round_div(tmp,4)+1)*4, 16)); len := len + 1; - ret.data(ind+len) := std_logic_vector(to_unsigned(tmp, 32)); + ret.data(len) := std_logic_vector(to_unsigned(tmp, 32)); for j in 0 to round_div(tmp,4)-1 loop len := len + 1; - ret.data(ind+len) := DOMAIN_TAG(j); + ret.data(len) := DOMAIN_TAG(j); end loop; end if; -- PROTOCOL VERSION len := len + 1; - ret.data(ind+len) := PID_PROTOCOL_VERSION & std_logic_vector(to_unsigned(4, 16)); + ret.data(len) := PID_PROTOCOL_VERSION & std_logic_vector(to_unsigned(4, 16)); len := len + 1; - ret.data(ind+len) := (others => '0'); - ret.data(ind+len)(31 downto 16) := PROTOCOLVERSION_2_4; + ret.data(len) := (others => '0'); + ret.data(len)(31 downto 16) := PROTOCOLVERSION_2_4; -- VENDORID len := len + 1; - ret.data(ind+len) := PID_VENDORID & std_logic_vector(to_unsigned(4, 16)); + ret.data(len) := PID_VENDORID & std_logic_vector(to_unsigned(4, 16)); len := len + 1; - ret.data(ind+len) := (others => '0'); - ret.data(ind+len)(31 downto 16) := VENDORID; + ret.data(len) := (others => '0'); + ret.data(len)(31 downto 16) := VENDORID; -- TODO: Expects inline QoS of Participant -- METATRAFFIC MULTICAST LOCATOR len := len + 1; - ret.data(ind+len) := PID_METATRAFFIC_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); + ret.data(len) := PID_METATRAFFIC_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); len := len + 1; - ret.data(ind+len) := LOCATOR_KIND_UDPv4; + ret.data(len) := LOCATOR_KIND_UDPv4; len := len + 1; - ret.data(ind+len) := (others => '0'); - ret.data(ind+len)(15 downto 0) := META_IPv4_MULTICAST_PORT; + ret.data(len) := (others => '0'); + ret.data(len)(15 downto 0) := META_IPv4_MULTICAST_PORT; len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := DEFAULT_IPv4_ADDRESS; + ret.data(len) := DEFAULT_IPv4_ADDRESS; -- METATRAFFIC UNICAST LOCATOR len := len + 1; - ret.data(ind+len) := PID_METATRAFFIC_UNICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); + ret.data(len) := PID_METATRAFFIC_UNICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); len := len + 1; - ret.data(ind+len) := LOCATOR_KIND_UDPv4; + ret.data(len) := LOCATOR_KIND_UDPv4; len := len + 1; - ret.data(ind+len) := (others => '0'); - ret.data(ind+len)(15 downto 0) := META_IPv4_UNICAST_PORT; + ret.data(len) := (others => '0'); + ret.data(len)(15 downto 0) := META_IPv4_UNICAST_PORT; len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := DEFAULT_IPv4_ADDRESS; + ret.data(len) := DEFAULT_IPv4_ADDRESS; -- DEFAULT MULTICAST LOCATOR len := len + 1; - ret.data(ind+len) := PID_DEFAULT_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); + ret.data(len) := PID_DEFAULT_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); len := len + 1; - ret.data(ind+len) := LOCATOR_KIND_UDPv4; + ret.data(len) := LOCATOR_KIND_UDPv4; len := len + 1; - ret.data(ind+len) := (others => '0'); - ret.data(ind+len)(15 downto 0) := USER_IPv4_MULTICAST_PORT; + ret.data(len) := (others => '0'); + ret.data(len)(15 downto 0) := USER_IPv4_MULTICAST_PORT; len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := DEFAULT_IPv4_ADDRESS; + ret.data(len) := DEFAULT_IPv4_ADDRESS; -- DEFAULT UNICAST LOCATOR len := len + 1; - ret.data(ind+len) := PID_DEFAULT_UNICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); + ret.data(len) := PID_DEFAULT_UNICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16)); len := len + 1; - ret.data(ind+len) := LOCATOR_KIND_UDPv4; + ret.data(len) := LOCATOR_KIND_UDPv4; len := len + 1; - ret.data(ind+len) := (others => '0'); - ret.data(ind+len)(15 downto 0) := USER_IPv4_UNICAST_PORT; + ret.data(len) := (others => '0'); + ret.data(len)(15 downto 0) := USER_IPv4_UNICAST_PORT; len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); len := len + 1; - ret.data(ind+len) := DEFAULT_IPv4_ADDRESS; + ret.data(len) := DEFAULT_IPv4_ADDRESS; -- LEASE DURATION if (PARTICIPANT_LEASE_DURATION /= DEFAULT_PARTICIPANT_LEASE_DURATION) then len := len + 1; - ret.data(ind+len) := PID_PARTICIPANT_LEASE_DURATION & std_logic_vector(to_unsigned(8, 16)); + ret.data(len) := PID_PARTICIPANT_LEASE_DURATION & std_logic_vector(to_unsigned(8, 16)); len := len + 1; - ret.data(ind+len) := std_logic_vector(PARTICIPANT_LEASE_DURATION(0)); + ret.data(len) := std_logic_vector(PARTICIPANT_LEASE_DURATION(0)); len := len + 1; - ret.data(ind+len) := std_logic_vector(PARTICIPANT_LEASE_DURATION(1)); + ret.data(len) := std_logic_vector(PARTICIPANT_LEASE_DURATION(1)); end if; -- AVAILABLE ENDPOINTS len := len + 1; - ret.data(ind+len) := PID_BUILTIN_ENDPOINT_SET & std_logic_vector(to_unsigned(4, 16)); + ret.data(len) := PID_BUILTIN_ENDPOINT_SET & std_logic_vector(to_unsigned(4, 16)); len := len + 1; - ret.data(ind+len) := (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'); + ret.data(len) := (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'); if (NUM_READERS > 0) then - ret.data(ind+len)(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; - ret.data(ind+len)(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + ret.data(len)(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + ret.data(len)(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; end if; if (NUM_WRITERS > 0) then - ret.data(ind+len)(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; - ret.data(ind+len)(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + ret.data(len)(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + ret.data(len)(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; end if; -- MANUAL LIVELINESS COUNT len := len + 1; - ret.data(ind+len) := PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT & std_logic_vector(to_unsigned(4, 16)); + ret.data(len) := PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT & std_logic_vector(to_unsigned(4, 16)); len := len + 1; - ret.data(ind+len) := (others => '0'); + ret.data(len) := (others => '0'); -- SENTINEL len := len + 1; - ret.data(ind+len) := PID_SENTINEL & std_logic_vector(to_unsigned(0, 16)); - + ret.data(len) := PID_SENTINEL & std_logic_vector(to_unsigned(0, 16)); + -- Fix Submessage Length + ret.data(0)(15 downto 0) := std_logic_vector(to_unsigned(len*4, 16)); -- Store Length - ret.length := ind + len + 1; + ret.length := len + 1; return ret; end function; diff --git a/src/rtps_package.vhd b/src/rtps_package.vhd index 0508682..f62b6c4 100644 --- a/src/rtps_package.vhd +++ b/src/rtps_package.vhd @@ -299,6 +299,8 @@ package rtps_package is 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; diff --git a/src/rtps_test_package.vhd b/src/rtps_test_package.vhd index cf9f5ac..044fa68 100644 --- a/src/rtps_test_package.vhd +++ b/src/rtps_test_package.vhd @@ -1229,17 +1229,19 @@ package body rtps_test_package is output.length := output.length + offset; end if; -- BUILTIN ENDPOINT QOS - if (pid = PID_BUILTIN_ENDPOINT_QOS) then - assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; - output.data(output.length) := PID_BUILTIN_ENDPOINT_QOS & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); - else - output.data(output.length) := PID_BUILTIN_ENDPOINT_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); - end if; - output.length := output.length + 1; - output.data(output.length) := endian_swap(ref.littleEndian, ref.builtinEndpointQoS); - output.length := output.length + 1; - if (pid = PID_BUILTIN_ENDPOINT_QOS) then - output.length := output.length + offset; + if (ref.builtinEndpointQoS /= DEFAULT_BUILTIN_ENDPOINT_QOS or pid = PID_BUILTIN_ENDPOINT_QOS) then + if (pid = PID_BUILTIN_ENDPOINT_QOS) then + assert (4+(offset*4) >= 0) report "Parameter Length < 0" severity FAILURE; + output.data(output.length) := PID_BUILTIN_ENDPOINT_QOS & endian_swap(ref.littleEndian, int(4+(offset*4),PARAMETER_LENGTH_WIDTH)); + else + output.data(output.length) := PID_BUILTIN_ENDPOINT_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + end if; + output.length := output.length + 1; + output.data(output.length) := endian_swap(ref.littleEndian, ref.builtinEndpointQoS); + output.length := output.length + 1; + if (pid = PID_BUILTIN_ENDPOINT_QOS) then + output.length := output.length + offset; + end if; end if; -- MANUAL LIVELINESS COUNT if (pid = PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT) then