From 1a6e9b83eb5018a519008af91682a3154e7798f8 Mon Sep 17 00:00:00 2001 From: Greek Date: Sat, 28 Nov 2020 14:28:35 +0100 Subject: [PATCH] * rtps_builtin_endpoint in-memory fromat change - Do not store local endpoint mask of remote endpoints - Send MATCH/UNMATCH Frames to all local Endpoinst (Not only previously matched) --- src/REF.txt | 4 - src/TODO.txt | 8 + .../Level_0/rtps_builtin_endpoint_test2.vhd | 50 +++- src/rtps_builtin_endpoint.vhd | 220 +++++------------- src/rtps_config_package.vhd | 5 +- 5 files changed, 107 insertions(+), 180 deletions(-) diff --git a/src/REF.txt b/src/REF.txt index 49af26b..d7d7628 100644 --- a/src/REF.txt +++ b/src/REF.txt @@ -235,10 +235,6 @@ ENDPOINT DATA + + 03| | +-------------------------------------------------------------+ -04| | - ~ ENDPOINT_BITMASK ~ -**| | - +-------------------------------------------------------------+ ENDPOINT MATCH FRAME ==================== diff --git a/src/TODO.txt b/src/TODO.txt index af6bfad..d998a1b 100644 --- a/src/TODO.txt +++ b/src/TODO.txt @@ -117,6 +117,14 @@ DESIGN DECISIONS Use the lowest bit of the Heartbeat/Acknack Deadline stored in the Participant Data to differentiate between Delay and Suppression. This reduces the resolution from 0.23 ns to 0.47 ns +* Originally we stored the mask of local matching endpoints in the memory frame of the remote endpoint in order + to be able to send MATCH frames only to new matches, and UNMATCH frames only to previously matched local endpoints. + This decision was reverted, and we just sent MATCH frames to the currently matched local endpoints (non depending on if they are already matched) + and UNMATCH frames to the rest of the local endpoints (non depending on if they were previously matched). + So we basically push the responsibility to the local endpoints, which have to handle this situations accordingly. + Since META traffic is not supposed to be generated as often , this should not produce any significant overhead. + As optimization, on new matched remote endpoints UNMATCH frames can be ignored. + PROTOCOL UNCOMPLIANCE ===================== * Partition QoS diff --git a/src/Tests/Level_0/rtps_builtin_endpoint_test2.vhd b/src/Tests/Level_0/rtps_builtin_endpoint_test2.vhd index 1a3272d..a1be380 100644 --- a/src/Tests/Level_0/rtps_builtin_endpoint_test2.vhd +++ b/src/Tests/Level_0/rtps_builtin_endpoint_test2.vhd @@ -495,7 +495,9 @@ begin endpoint.match := UNMATCH; gen_match_frame(endpoint, reference); wr_sig := gen_wr(i, FALSE); + -- If Endpoint was previously matched, unmatch if (or wr_sig = '1') then + wr_sig := (others => '1'); push_reference; end if; reference := EMPTY_TEST_PACKET; @@ -507,7 +509,9 @@ begin endpoint.match := UNMATCH; gen_match_frame(endpoint, reference); wr_sig := gen_wr(i, TRUE); + -- If Endpoint was previously matched, unmatch if (or wr_sig = '1') then + wr_sig := (others => '1'); push_reference; end if; reference := EMPTY_TEST_PACKET; @@ -778,9 +782,18 @@ begin gen_endpoint_data(e1, sub_p.data); gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, e1, stimulus); + -- UNMATCH + e1.match := UNMATCH; gen_match_frame(e1, reference); wr_sig := (0 => '1', 9 => '1', 10 => '1', 15 => '1', others => '0'); + wr_sig := not wr_sig; push_reference; + reference := EMPTY_TEST_PACKET; + -- MATCH + e1.match := MATCH; + gen_match_frame(e1, reference); + wr_sig := not wr_sig; + push_reference; start_test; wait_on_complete; stimulus := EMPTY_TEST_PACKET; @@ -797,8 +810,17 @@ begin gen_endpoint_data(e2, sub_s.data); gen_sentinel(sub_s.data); gen_rtps_handler_out(sub_s, e2, stimulus); + -- UNMATCH + e2.match := UNMATCH; gen_match_frame(e2, reference); wr_sig := (NUM_READERS => '1', NUM_READERS+4 => '1', NUM_READERS+5 => '1', NUM_READERS+7 => '1', others => '0'); + wr_sig := not wr_sig; + push_reference; + reference := EMPTY_TEST_PACKET; + -- MATCH + e2.match := MATCH; + gen_match_frame(e2, reference); + wr_sig := not wr_sig; push_reference; start_test; wait_on_complete; @@ -813,15 +835,17 @@ begin gen_endpoint_data(e1, sub_p.data); gen_sentinel(sub_p.data); gen_rtps_handler_out(sub_p, e1, stimulus); - -- MATCH - gen_match_frame(e1, reference); - wr_sig := (15 => '1', others => '0'); - push_reference; - reference := EMPTY_TEST_PACKET; -- UNMATCH e1.match := UNMATCH; gen_match_frame(e1, reference); - wr_sig := (0 => '1', 9 => '1', 10 => '1', others => '0'); + wr_sig := (15 => '1', others => '0'); + wr_sig := not wr_sig; + push_reference; + reference := EMPTY_TEST_PACKET; + -- MATCH + e1.match := MATCH; + gen_match_frame(e1, reference); + wr_sig := not wr_sig; push_reference; start_test; wait_on_complete; @@ -837,15 +861,17 @@ begin gen_endpoint_data(e2, sub_s.data); gen_sentinel(sub_s.data); gen_rtps_handler_out(sub_s, e2, stimulus); - -- MATCH - gen_match_frame(e2, reference); - wr_sig := (NUM_READERS+2 => '1', others => '0'); - push_reference; - reference := EMPTY_TEST_PACKET; -- UNMATCH e2.match := UNMATCH; gen_match_frame(e2, reference); - wr_sig := (NUM_READERS => '1', NUM_READERS+4 => '1', NUM_READERS+5 => '1', NUM_READERS+7 => '1', others => '0'); + wr_sig := (NUM_READERS+2 => '1', others => '0'); + wr_sig := not wr_sig; + push_reference; + reference := EMPTY_TEST_PACKET; + -- MATCH + e2.match := MATCH; + gen_match_frame(e2, reference); + wr_sig := not wr_sig; push_reference; start_test; wait_on_complete; diff --git a/src/rtps_builtin_endpoint.vhd b/src/rtps_builtin_endpoint.vhd index 8113146..e5e6532 100644 --- a/src/rtps_builtin_endpoint.vhd +++ b/src/rtps_builtin_endpoint.vhd @@ -11,7 +11,6 @@ use work.rtps_config_package.all; -- TODO: Skip Packet while we are waiting for memory operation to complete -- TODO: add_res is still valid after removal. So we could continue searching the next orphan endpoint from that address on -- TODO: is it really necessary to process Sequence Numbers in sequence? Could we not just accept any higher Sequence Number? --- TODO: Remove the Endpoint Bitmask from Memory and just always send MATCH/UNMATCH Frames entity rtps_builtin_endpoint is port ( @@ -72,8 +71,8 @@ architecture arch of rtps_builtin_endpoint is SEND_PARTICIPANT_ANNOUNCEMENT, SEND_PUB_DATA, SEND_SUB_DATA, SEND_MES_MAN_LIVE, SEND_MES_GAP, SEND_MES_AUTO_LIVE, LIVELINESS_UPDATE, SKIP_PARAMETER, SKIP_PACKET); -- Memory FSM states. Explained below in detail - type MEM_STAGE_TYPE is (IDLE, SEARCH_PARTICIPANT, GET_PARTICIPANT_DATA, SEARCH_ENDPOINT, GET_ENDPOINT_MASK, REMOVE_PARTICIPANT, - REMOVE_ENDPOINT, UPDATE_ENDPOINT, FIND_PARTICIPANT_SLOT, INSERT_PARTICIPANT, FIND_ENDPOINT_SLOT, INSERT_ENDPOINT, + type MEM_STAGE_TYPE is (IDLE, SEARCH_PARTICIPANT, GET_PARTICIPANT_DATA, SEARCH_ENDPOINT, REMOVE_PARTICIPANT, + REMOVE_ENDPOINT, FIND_PARTICIPANT_SLOT, INSERT_PARTICIPANT, FIND_ENDPOINT_SLOT, INSERT_ENDPOINT, FIND_NEXT_PARTICIPANT, FIND_STALE_PARTICIPANT, UPDATE_PARTICIPANT); -- Memory FSM Opcodes -- OPCODE DESCRIPTION @@ -98,7 +97,7 @@ architecture arch of rtps_builtin_endpoint is -- FIND_NEXT_PARTICIPANT Find next occupied Participant Entry in memory from the Participant Entry pointed by "addr_res". -- Set "addr_res" signal to Base Address of found Participant Entry or MAX Address if nothing found. type MEM_OPCODE_TYPE is (NOP, SEARCH_PARTICIPANT, SEARCH_ENDPOINT, INSERT_PARTICIPANT, INSERT_ENDPOINT, UPDATE_PARTICIPANT, - UPDATE_ENDPOINT, REMOVE_PARTICIPANT, REMOVE_ENDPOINT, FIND_STALE_PARTICIPANT, FIND_FIRST_PATICIPANT, FIND_NEXT_PARTICIPANT); + REMOVE_PARTICIPANT, REMOVE_ENDPOINT, FIND_STALE_PARTICIPANT, FIND_FIRST_PATICIPANT, FIND_NEXT_PARTICIPANT); -- RTPS Data Submessage Content: -- * PDP Simple Participant Discovery Protocol Data -- * EDP Simple Endpoint Discovery Protocol Data @@ -246,12 +245,6 @@ architecture arch of rtps_builtin_endpoint is signal compare_length, compare_length_next : unsigned(WORD_WIDTH-3 downto 0) := (others => '0'); -- Bitmask of local Endpoint Matches signal endpoint_mask, endpoint_mask_next : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); - -- Bitmask of new local Endpoint Matches - signal endpoint_match, endpoint_match_next : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); - -- Bitmask of local Endpoint unmatches - signal endpoint_unmatch, endpoint_unmatch_next : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); - -- Bitmask of local Endpoint Matches stored in Memory - signal endpoint_mask_array, endpoint_mask_array_next : ENDPOINT_BITMASK_ARRAY_TYPE := (others => (others => '0')); -- Signifies if the source of the Participant Data is compatible with our Participant signal participant_match, participant_match_next : std_logic := '0'; -- Signifies if the Packet is comming from a Subscriber Endpoint @@ -292,7 +285,7 @@ architecture arch of rtps_builtin_endpoint is -- Memory Read and Write Enable Signals signal mem_rd, mem_wr : std_logic := '0'; -- General Purpose Counter (Memory FSM) - signal mem_cnt, mem_cnt_next : natural range 0 to max(22, ENDPOINT_BITMASK_SIZE-1) := 0; + signal mem_cnt, mem_cnt_next : natural range 0 to 22 := 0; -- Contains the Sequence Number stored in the Buffer of the current relevant Message Type (Participant/Publisher/Subscriber/Message Data) signal mem_seq_nr, mem_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0')); -- Signifies the next expected Sequence Number of the current relevant Message Type (Participant/Publisher/Subscriber/Message Data) @@ -389,37 +382,6 @@ architecture arch of rtps_builtin_endpoint is alias payload_flag : std_logic is flags(4); --*****FUNCTION DECLARATION***** - - -- Converts std_logic_vector to ENDPOINT_BITMASK_ARRAY - function convert_to_bitmask_array (bitmask : std_logic_vector) return ENDPOINT_BITMASK_ARRAY_TYPE is - variable ret : ENDPOINT_BITMASK_ARRAY_TYPE := (others => (others => '0')); - begin - ret := (others => (others => '0')); - for i in 0 to ENDPOINT_BITMASK_ARRAY_TYPE'length-1 loop - if (i /= ENDPOINT_BITMASK_ARRAY_TYPE'length-1) then - ret(i) := bitmask(i*32 to i*32+31); - else - ret(i)(0 to (bitmask'length mod 32)-1) := bitmask(i*32 to i*32+(bitmask'length mod 32)-1); - end if; - end loop; - return ret; - end function; - - -- Converts ENDPOINT_BITMASK_ARRAY to std_logic_vector - function convert_from_bitmask_array (bitmask : ENDPOINT_BITMASK_ARRAY_TYPE; len : natural) return std_logic_vector is - variable ret : std_logic_vector(0 to len-1) := (others => '0'); - begin - ret := (others => '0'); - for i in 0 to ENDPOINT_BITMASK_ARRAY_TYPE'length-1 loop - if (i /= ENDPOINT_BITMASK_ARRAY_TYPE'length-1) then - ret(i*32 to i*32+31) := bitmask(i); - else - ret(i*32 to i*32+(len mod 32)-1) := bitmask(i)(0 to (len mod 32)-1); - end if; - end loop; - return ret; - end function; - begin --*****COMPONENT INSTANTIATION***** @@ -512,11 +474,11 @@ begin case (stage) is when INFORM_ENDPOINTS_MATCH => if (wr_sig = '1') then - endpoint_wr <= endpoint_match; + endpoint_wr <= endpoint_mask; end if; when INFORM_ENDPOINTS_UNMATCH => if (wr_sig = '1') then - endpoint_wr <= endpoint_unmatch; + endpoint_wr <= not endpoint_mask; end if; when LIVELINESS_UPDATE => if (wr_sig = '1') then @@ -610,8 +572,6 @@ begin string_length_next <= string_length; compare_length_next <= compare_length; endpoint_mask_next <= endpoint_mask; - endpoint_match_next <= endpoint_match; - endpoint_unmatch_next <= endpoint_unmatch; participant_match_next <= participant_match; is_subscriber_next <= is_subscriber; lease_duration_next <= lease_duration; @@ -1558,9 +1518,8 @@ begin mem_op_start <= '1'; -- Latch Orphan Entity ID guid_next(3) <= mem_guid(3); - -- Mark UNMATCHES - endpoint_match_next <= (others => '0'); - endpoint_unmatch_next <= convert_from_bitmask_array(endpoint_mask_array, NUM_ENDPOINTS); + -- Mark All UNMATCHES + endpoint_mask_next <= (others => '0'); -- Propagate Unmatches to local Endpoints stage_next <= INFORM_ENDPOINTS_UNMATCH; cnt_next <= 0; @@ -2479,9 +2438,6 @@ begin -- Add Endpoint in buffer mem_opcode <= INSERT_ENDPOINT; mem_op_start <= '1'; - -- Mark MATCHES - endpoint_match_next <= endpoint_mask; - endpoint_unmatch_next <= (others => '0'); -- Propagate Matches to local Endpoints stage_next <= INFORM_ENDPOINTS_MATCH; cnt_next <= 0; @@ -2494,38 +2450,65 @@ begin else -- At least one local Endpoint match if (endpoint_mask /= (endpoint_mask'range => '0')) then - -- Mark Endpoint match changes - tmp_endpoint_mask := convert_from_bitmask_array(endpoint_mask_array, NUM_ENDPOINTS) xor endpoint_mask; - -- Mark UNMATCHES - endpoint_unmatch_next <= tmp_endpoint_mask and convert_from_bitmask_array(endpoint_mask_array, NUM_ENDPOINTS); - -- Mark NEW MATCHES - -- NOTE: Mark all matches and resent the Endpoint Match Frame also to already Matched Endpoints, - -- in order to propagate possible data updates (e.g. new Locator) - --endpoint_match_next <= tmp_endpoint_mask and endpoint_mask; - endpoint_match_next <= endpoint_mask; - -- Update endpoint in buffer - mem_opcode <= UPDATE_ENDPOINT; - mem_op_start <= '1'; -- Propagate Match Changes to local Endpoints - stage_next <= INFORM_ENDPOINTS_MATCH; + stage_next <= INFORM_ENDPOINTS_UNMATCH; cnt_next <= 0; -- No local Endpoint match else -- Remove endpoint from buffer mem_opcode <= REMOVE_ENDPOINT; mem_op_start <= '1'; - -- Mark UNMATCHES - endpoint_match_next <= (others => '0'); - endpoint_unmatch_next <= convert_from_bitmask_array(endpoint_mask_array, NUM_ENDPOINTS); + -- Mark All UNMATCHES + endpoint_mask_next <= (others => '0'); -- Propagate Unmatches to local Endpoints stage_next <= INFORM_ENDPOINTS_UNMATCH; cnt_next <= 0; end if; end if; end if; + when INFORM_ENDPOINTS_UNMATCH => + -- Output FIFO Guard + if (((not endpoint_mask) and endpoint_full) = (endpoint_full'range => '0')) then + wr_sig <= '1'; + cnt_next <= cnt + 1; + + case (cnt) is + -- Match Opcode + when 0 => + data_out <= OPCODE_UNMATCH; + -- GUID Prefix 1/3 + when 1 => + data_out <= guid(0); + -- GUID Prefix 2/3 + when 2 => + data_out <= guid(1); + -- GUID Prefix 3/3 + when 3 => + data_out <= guid(2); + -- Entity ID + when 4 => + data_out <= guid(3); + last_word_out <= '1'; + -- If we are in the middle of an Orphan Purge Process, return to the search stage + if (is_orphan_search = '1') then + stage_next <= FIND_ORPHAN_ENDPOINT; + else + -- If there are Endpoints to match, inform them + if (endpoint_mask /= (endpoint_mask'range => '0')) then + stage_next <= INFORM_ENDPOINTS_MATCH; + cnt_next <= 0; + else + -- DONE + stage_next <= SKIP_PACKET; + end if; + end if; + when others => + null; + end case; + end if; when INFORM_ENDPOINTS_MATCH => -- Output FIFO Guard - if ((endpoint_match and endpoint_full) = (endpoint_full'range => '0')) then + if ((endpoint_mask and endpoint_full) = (endpoint_full'range => '0')) then wr_sig <= '1'; cnt_next <= cnt + 1; @@ -2575,48 +2558,8 @@ begin data_out(0) <= DEFAULT_EXPECTS_INLINE_QOS; end if; - -- If there are Endpoints to unmatch, inform them - if (endpoint_unmatch /= (endpoint_unmatch'range => '0')) then - stage_next <= INFORM_ENDPOINTS_UNMATCH; - cnt_next <= 0; - else - -- DONE - stage_next <= SKIP_PACKET; - end if; - when others => - null; - end case; - end if; - when INFORM_ENDPOINTS_UNMATCH => - -- Output FIFO Guard - if ((endpoint_unmatch and endpoint_full) = (endpoint_full'range => '0')) then - wr_sig <= '1'; - cnt_next <= cnt + 1; - - case (cnt) is - -- Match Opcode - when 0 => - data_out <= OPCODE_UNMATCH; - -- GUID Prefix 1/3 - when 1 => - data_out <= guid(0); - -- GUID Prefix 2/3 - when 2 => - data_out <= guid(1); - -- GUID Prefix 3/3 - when 3 => - data_out <= guid(2); - -- Entity ID - when 4 => - data_out <= guid(3); - last_word_out <= '1'; - -- If we are in the middle of an Orphan Purge Process, return to the search stage - if (is_orphan_search = '1') then - stage_next <= FIND_ORPHAN_ENDPOINT; - else - -- DONE - stage_next <= SKIP_PACKET; - end if; + -- DONE + stage_next <= SKIP_PACKET; when others => null; end case; @@ -3175,11 +3118,10 @@ begin last_addr_next <= last_addr; mem_participant_data_next <= mem_participant_data; is_heartbeat_res_next <= is_heartbeat_res; - endpoint_mask_array_next <= endpoint_mask_array; max_participant_addr_next <= max_participant_addr; max_endpoint_addr_next <= max_endpoint_addr; reset_max_pointer_next <= reset_max_pointer; - mem_guid_next <= mem_guid; + mem_guid_next <= mem_guid; -- DEFAULT Unregistered mem_write_data <= (others => '0'); mem_op_done <= '0'; @@ -3241,11 +3183,6 @@ begin mem_addr_next <= addr_res + 17; mem_cnt_next <= 14; end if; - when UPDATE_ENDPOINT => - mem_addr_next <= addr_res + 4; - endpoint_mask_array_next <= convert_to_bitmask_array(endpoint_mask); - mem_stage_next <= UPDATE_ENDPOINT; - mem_cnt_next <= 0; when REMOVE_PARTICIPANT => mem_addr_next <= addr_res; mem_stage_next <= REMOVE_PARTICIPANT; @@ -3386,8 +3323,7 @@ begin -- Match Found else addr_res_next <= mem_addr_base; - mem_stage_next <= GET_ENDPOINT_MASK; - mem_cnt_next <= 0; + mem_stage_next <= IDLE; end if; when others => null; @@ -3467,19 +3403,6 @@ begin when others => null; end case; - when GET_ENDPOINT_MASK => - mem_rd <= '1'; - mem_cnt_next <= mem_cnt + 1; - mem_addr_next <= mem_addr + 1; - - -- Latch Endpoint Bitmask - endpoint_mask_array_next(mem_cnt) <= mem_read_data; - - -- Exit Condition - if (mem_cnt = ENDPOINT_BITMASK_SIZE-1) then - -- DONE - mem_stage_next <= IDLE; - end if; when INSERT_PARTICIPANT => mem_wr <= '1'; mem_addr_next <= mem_addr + 1; @@ -3579,11 +3502,8 @@ begin -- GUIDPrefix 3/3 when 3 => mem_write_data <= guid(2); - - -- Write Endpoint bitmask via update method - endpoint_mask_array_next <= convert_to_bitmask_array(endpoint_mask); - mem_stage_next <= UPDATE_ENDPOINT; - mem_cnt_next <= 0; + -- DONE + mem_stage_next <= IDLE; when others => null; end case; @@ -3743,20 +3663,6 @@ begin when others => null; end case; - when UPDATE_ENDPOINT => - mem_wr <= '1'; - mem_addr_next <= mem_addr + 1; - mem_cnt_next <= mem_cnt + 1; - - -- TODO: Use dedicated counter - -- Store new Endpoint Bitmask - mem_write_data <= endpoint_mask_array(mem_cnt); - - -- Exit Condition - if (mem_cnt = ENDPOINT_BITMASK_SIZE-1) then - -- DONE - mem_stage_next <= IDLE; - end if; when REMOVE_PARTICIPANT => mem_addr_next <= mem_addr + 1; mem_cnt_next <= mem_cnt + 1; @@ -4196,8 +4102,6 @@ begin string_length <= (others => '0'); compare_length <= (others => '0'); endpoint_mask <= (others => '0'); - endpoint_match <= (others => '0'); - endpoint_unmatch <= (others => '0'); def_addr <= (others => '0'); meta_addr <= (others => '0'); def_port <= (others => '0'); @@ -4214,8 +4118,7 @@ begin max_participant_addr <= FIRST_PARTICIPANT_ADDRESS; max_endpoint_addr <= FIRST_ENDPOINT_ADDRESS; guid <= (others => (others => '0')); - mem_guid <= (others => (others => '0')); - endpoint_mask_array <= (others => (others => '0')); + mem_guid <= (others => (others => '0')); lease_duration <= (others => (others => '0')); deadline <= (others => (others => '0')); announcement_time <= (others => (others => '0')); @@ -4262,8 +4165,6 @@ begin string_length <= string_length_next; compare_length <= compare_length_next; endpoint_mask <= endpoint_mask_next; - endpoint_match <= endpoint_match_next; - endpoint_unmatch <= endpoint_unmatch_next; def_addr <= def_addr_next; meta_addr <= meta_addr_next; def_port <= def_port_next; @@ -4280,8 +4181,7 @@ begin max_participant_addr <= max_participant_addr_next; max_endpoint_addr <= max_endpoint_addr_next; guid <= guid_next; - mem_guid <= mem_guid_next; - endpoint_mask_array <= endpoint_mask_array_next; + mem_guid <= mem_guid_next; lease_duration <= lease_duration_next; deadline <= deadline_next; announcement_time <= announcement_time_next; diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index 1b2d14f..6142956 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -39,11 +39,8 @@ package rtps_config_package is -- 4-Byte Word Size of a Participant Entry in Memory constant PARTICIPANT_FRAME_SIZE : natural := 23; - -- 4-Byte Word Size of Endpoint Bitmask in Memory - constant ENDPOINT_BITMASK_SIZE : natural := round_div(NUM_ENDPOINTS, 32); - type ENDPOINT_BITMASK_ARRAY_TYPE is array (0 to ENDPOINT_BITMASK_SIZE-1) of std_logic_vector(0 to WORD_WIDTH-1); -- 4-Byte Word Size of a Endpoint Entry in Memory - constant ENDPOINT_FRAME_SIZE : natural := 4 + ENDPOINT_BITMASK_SIZE; + constant ENDPOINT_FRAME_SIZE : natural := 4; -- Built-in Endpoint Memory Buffer 4-Byte Word Size constant BUILTIN_BUFFER_SIZE : natural := MAX_REMOTE_PARTICIPANTS*PARTICIPANT_FRAME_SIZE;