diff --git a/src/rtps_builtin_endpoint.vhd b/src/rtps_builtin_endpoint.vhd index 8b96cf6..ffd7c0f 100644 --- a/src/rtps_builtin_endpoint.vhd +++ b/src/rtps_builtin_endpoint.vhd @@ -522,20 +522,20 @@ begin when ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR => -- SANITY CHECK: Ignore if no Readers if (NUM_READERS /= 0) then - -- Only HEARTBEATs and DATA are relevant (GAPs irrelevant, since depth is 1) + message_type_next <= EDP; + -- QoS is publisher-offered + is_subscriber_next <= '0'; + -- Only HEARTBEATs, GAPs and DATA are relevant case (opcode) is when SID_HEARTBEAT => - message_type_next <= EDP; stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing - -- Initialise counter + cnt_next <= 0; + when SID_GAP => + stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; when SID_DATA => - message_type_next <= EDP; stage_next <= LATCH_SEQ_NR; -- DATA Processing - -- Initialise counter cnt_next <= 0; - -- QoS is publisher-offered - is_subscriber_next <= '0'; -- Reset Endpoint Mask (ALL READERS) endpoint_mask_next <= (others => '0'); endpoint_mask_next(0 to NUM_READERS-1) <= (others => '1'); @@ -553,20 +553,20 @@ begin when ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR => -- SANITY CHECK: Ignore if no Writers if (NUM_WRITERS /= 0) then - -- Only HEARTBEATs and DATA are relevant (GAPs irrelevant, since depth is 1) + message_type_next <= EDP; + -- QoS is subscriber-requested + is_subscriber_next <= '1'; + -- Only HEARTBEATs, GAPs and DATA are relevant case (opcode) is when SID_HEARTBEAT => - message_type_next <= EDP; stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing - -- Initialise counter + cnt_next <= 0; + when SID_GAP => + stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; when SID_DATA => - message_type_next <= EDP; stage_next <= LATCH_SEQ_NR; -- DATA Processing - -- Initialise counter cnt_next <= 0; - -- QoS is subscriber-requested - is_subscriber_next <= '1'; -- Reset Endpoint Mask (ALL WRITERS) endpoint_mask_next <= (others => '0'); endpoint_mask_next(NUM_READERS to NUM_READERS+NUM_WRITERS-1) <= (others => '1'); @@ -586,17 +586,17 @@ begin when ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER => -- SANITY CHECK: Ignore if no Readers if (NUM_READERS /= 0) then - -- Only HEARTBEATs and DATA are relevant (GAPs irrelevant, since depth is 1) + message_type_next <= MESSAGE; + -- Only HEARTBEATs, GAPs and DATA are relevant case (opcode) is when SID_HEARTBEAT => - message_type_next <= MESSAGE; stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing - -- Initialise counter + cnt_next <= 0; + when SID_GAP => + stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; when SID_DATA => - message_type_next <= MESSAGE; stage_next <= LATCH_SEQ_NR; -- DATA Processing - -- Initialise counter cnt_next <= 0; -- Reset Endpoint Mask (ALL READERS) endpoint_mask_next <= (others => '0'); @@ -637,20 +637,20 @@ begin when ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER => -- SANITY CHECK: Ignore if no Readers if (NUM_READERS /= 0) then - -- Only HEARTBEATs and DATA are relevant (GAPs irrelevant, since depth is 1) + message_type_next <= EDP; + -- QoS is publisher-offered + is_subscriber_next <= '0'; + -- Only HEARTBEATs, GAPs and DATA are relevant case (opcode) is when SID_HEARTBEAT => - message_type_next <= EDP; stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing - -- Initialise counter + cnt_next <= 0; + when SID_GAP => + stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; when SID_DATA => - message_type_next <= EDP; stage_next <= LATCH_SEQ_NR; -- DATA Processing - -- Initialise counter cnt_next <= 0; - -- QoS is publisher-offered - is_subscriber_next <= '0'; -- Reset Endpoint Mask (ALL READERS) endpoint_mask_next <= (others => '0'); endpoint_mask_next(0 to NUM_READERS-1) <= (others => '1'); @@ -668,20 +668,21 @@ begin when ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER => -- SANITY CHECK: Ignore if no Writers if (NUM_WRITERS /= 0) then - -- Only HEARTBEATs and DATA are relevant (GAPs irrelevant, since depth is 1) + message_type_next <= EDP; + -- QoS is subscriber-requested + is_subscriber_next <= '1'; + -- Only HEARTBEATs, GAPs and DATA are relevant case (opcode) is when SID_HEARTBEAT => - message_type_next <= EDP; + stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing - -- Initialise counter + cnt_next <= 0; + when SID_GAP => + stage_next <= PROCESS_GAP; -- GAP Processing cnt_next <= 0; when SID_DATA => - message_type_next <= EDP; stage_next <= LATCH_SEQ_NR; -- DATA Processing - -- Initialise counter cnt_next <= 0; - -- QoS is subscriber-requested - is_subscriber_next <= '1'; -- Reset Endpoint Mask (ALL WRITERS) endpoint_mask_next <= (others => '0'); endpoint_mask_next(NUM_READERS to NUM_READERS+NUM_WRITERS-1) <= (others => '1'); @@ -701,18 +702,19 @@ begin when ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER => -- SANITY CHECK: Ignore if no Readers if (NUM_READERS /= 0) then - -- Only HEARTBEATs and DATA are relevant (GAPs irrelevant, since depth is 1) + message_type_next <= MESSAGE; + -- Only HEARTBEATs, GAPs and DATA are relevant case (opcode) is when SID_HEARTBEAT => - message_type_next <= MESSAGE; - stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing - -- Initialise counter - cnt_next <= 0; + stage_next <= PROCESS_HEARTBEAT; -- HEARTBEAT Processing + cnt_next <= 0; + when SID_GAP => + stage_next <= PROCESS_GAP; -- GAP Processing + cnt_next <= 0; when SID_DATA => - message_type_next <= MESSAGE; - stage_next <= LATCH_SEQ_NR; -- DATA Processing + stage_next <= LATCH_SEQ_NR; -- DATA Processing -- Initialise counter - cnt_next <= 0; + cnt_next <= 0; -- Reset Endpoint Mask (ALL READERS) endpoint_mask_next <= (others => '0'); endpoint_mask_next(0 to NUM_READERS-1) <= (others => '1'); @@ -827,6 +829,40 @@ begin end case; end case; end if; + when PROCESS_GAP => + if (empty = '0') then + rd_sig <= '1'; + -- Increment Counter + cnt_next <= cnt + 1; + -- Latch Sequence Numbers + case (cnt) is + when 0 => + first_seq_nr_next(0) <= data_in; + when 1 => + first_seq_nr_next(1) <= data_in; + when 2 => + last_seq_nr_next(0) <= data_in; + when 3 => + last_seq_nr_next(1) <= data_in; + stage_next <= PROCESS_GAP_SEQUENCE_NUMBERS; + end case; + end if; + when PROCESS_GAP_SEQUENCE_NUMBERS => + -- Wait for Sequence Number to be fetched from buffer + if (mem_done = '1' and seq_prc_done = '1') then + -- XXX: This logic relies on the sender marking continuous GAPs with the GAP Start Sequence Number and GAP End Sequence Number Set Base (i.e. the first bit in the bitmask should be 0/not in GAP) + -- It also relies on the sender starting the GAP from the next expected/requested sequence number (Not Begining the GAP from an already ACKed sequence number) + -- GAP only relevant if GAP start is the next expected sequence number + if (first_seq_nr = next_seq_nr) then + -- Store GAP end as last sequence number + seq_nr_next <= last_seq_nr; + mem_opcode <= UPDATE_PARTICIPANT; + update_participant_flags_next <= (EDP_SEQ_NR_FLAG => '1', others => '0'); + start_mem_op <= '1'; + end if; + -- Done + stage_next <= SKIP_PACKET; + end if; when PROCESS_PL => if (empty = '0') then rd_sig <= '1';