Backport GAP parsing logic to RTPS Builtin Endpoint
The GAP parsing logic was backported from RTPS Reader, so that the RTPS Builtin Endpoint can parse all kind of GAP without making assumptions. The Test 4 of the RTPS Builtin Endpoint was extended to test HAERTBEAT and GAP Handling of the RTPS Builting endpoint, and Test 2 of the RTPS Reader was extended with an additional Test (GAP with next expected SN not marked in bitmap)
This commit is contained in:
parent
293d89f083
commit
8cd1c29518
@ -12,7 +12,7 @@ use work.rtps_test_package.all;
|
||||
|
||||
-- This testbench tests the matching of remote endpoints. This is done by checking the Match/Unmatch Frame sent to the local endpoints.
|
||||
-- The local participant is configured with following endpoints (called "fixed" endpoints):
|
||||
-- NOTE: All Endpoints are configured with topic "TOPIC_1" and type "TYPE_1", except is explicitly stated otherwise.
|
||||
-- NOTE: All Endpoints are configured with topic "TOPIC_1" and type "TYPE_1", except if explicitly stated otherwise.
|
||||
-- WRITER 0
|
||||
-- * DEFAULT
|
||||
-- WRITER 1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -672,6 +672,20 @@ begin
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Endpoint 2 Heartbeat [GAP 21-22, 24]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
sub.submessageID := SID_GAP;
|
||||
sub.writerId := endpoint.entityid;
|
||||
sub.readerId := DEFAULT_READER_ENTITYID;
|
||||
sub.gapStart := gen_sn(21);
|
||||
sub.gapList := (base => gen_sn(22), numBits => int(3, CDR_LONG_WIDTH), bitmap => (0 => '1', 2 => '1', others => '0'));
|
||||
gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, src_ts, endpoint.participant.guidPrefix, stimulus_user);
|
||||
start_user_test;
|
||||
wait_on_user_sent;
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Accept Endpoint 2 sent DATA [SN 23]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
|
||||
@ -323,27 +323,27 @@ begin
|
||||
-- *HEARTBEAT HANDLING*
|
||||
Log("Test HEARTBEAT Handling", INFO);
|
||||
|
||||
Log("Endpoint 2 Heartbeat [First 11, Last 19]", INFO);
|
||||
Log("Endpoint 2 Heartbeat [First 11, Last 18]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
sub.submessageID := SID_HEARTBEAT;
|
||||
sub.writerId := endpoint.entityid;
|
||||
sub.readerId := DEFAULT_READER_ENTITYID;
|
||||
sub.firstSN := gen_sn(11);
|
||||
sub.lastSN := gen_sn(19);
|
||||
sub.lastSN := gen_sn(18);
|
||||
gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, src_ts, endpoint.participant.guidPrefix, stimulus_user);
|
||||
start_user_test;
|
||||
wait_on_user_sent;
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Ignore Endpoint 2 sent DATA [SN 19]", INFO);
|
||||
Log("Ignore Endpoint 2 sent DATA [SN 18]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
sub.submessageID := SID_DATA;
|
||||
sub.writerId := endpoint.entityid;
|
||||
sub.readerId := DEFAULT_READER_ENTITYID;
|
||||
sub.writerSN := gen_sn(19);
|
||||
sub.writerSN := gen_sn(18);
|
||||
sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1';
|
||||
sub.data := gen_payload;
|
||||
gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, src_ts, endpoint.participant.guidPrefix, stimulus_user);
|
||||
@ -653,6 +653,20 @@ begin
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Endpoint 2 Heartbeat [GAP 21-22, 24]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
sub.submessageID := SID_GAP;
|
||||
sub.writerId := endpoint.entityid;
|
||||
sub.readerId := DEFAULT_READER_ENTITYID;
|
||||
sub.gapStart := gen_sn(21);
|
||||
sub.gapList := (base => gen_sn(22), numBits => int(3, CDR_LONG_WIDTH), bitmap => (0 => '1', 2 => '1', others => '0'));
|
||||
gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, src_ts, endpoint.participant.guidPrefix, stimulus_user);
|
||||
start_user_test;
|
||||
wait_on_user_sent;
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Accept Endpoint 2 sent DATA [SN 23]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
|
||||
@ -653,6 +653,20 @@ begin
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Endpoint 2 Heartbeat [GAP 21-22, 24]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
sub.submessageID := SID_GAP;
|
||||
sub.writerId := endpoint.entityid;
|
||||
sub.readerId := DEFAULT_READER_ENTITYID;
|
||||
sub.gapStart := gen_sn(21);
|
||||
sub.gapList := (base => gen_sn(22), numBits => int(3, CDR_LONG_WIDTH), bitmap => (0 => '1', 2 => '1', others => '0'));
|
||||
gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, src_ts, endpoint.participant.guidPrefix, stimulus_user);
|
||||
start_user_test;
|
||||
wait_on_user_sent;
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Accept Endpoint 2 sent DATA [SN 23]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
|
||||
@ -668,6 +668,20 @@ begin
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Endpoint 2 Heartbeat [GAP 21-22, 24]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
sub.submessageID := SID_GAP;
|
||||
sub.writerId := endpoint.entityid;
|
||||
sub.readerId := DEFAULT_READER_ENTITYID;
|
||||
sub.gapStart := gen_sn(21);
|
||||
sub.gapList := (base => gen_sn(22), numBits => int(3, CDR_LONG_WIDTH), bitmap => (0 => '1', 2 => '1', others => '0'));
|
||||
gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, src_ts, endpoint.participant.guidPrefix, stimulus_user);
|
||||
start_user_test;
|
||||
wait_on_user_sent;
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Accept Endpoint 2 sent DATA [SN 23]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
|
||||
@ -668,6 +668,20 @@ begin
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Endpoint 2 Heartbeat [GAP 21-22, 24]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
sub.submessageID := SID_GAP;
|
||||
sub.writerId := endpoint.entityid;
|
||||
sub.readerId := DEFAULT_READER_ENTITYID;
|
||||
sub.gapStart := gen_sn(21);
|
||||
sub.gapList := (base => gen_sn(22), numBits => int(3, CDR_LONG_WIDTH), bitmap => (0 => '1', 2 => '1', others => '0'));
|
||||
gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, src_ts, endpoint.participant.guidPrefix, stimulus_user);
|
||||
start_user_test;
|
||||
wait_on_user_sent;
|
||||
stimulus_user := EMPTY_TEST_PACKET;
|
||||
reference := EMPTY_TEST_PACKET;
|
||||
|
||||
Log("Accept Endpoint 2 sent DATA [SN 23]", INFO);
|
||||
endpoint := e2;
|
||||
sub := DEFAULT_RTPS_SUBMESSAGE;
|
||||
|
||||
@ -124,8 +124,8 @@ architecture arch of rtps_builtin_endpoint is
|
||||
--*****TYPE DECLARATION*****
|
||||
-- FSM states. Explained below in detail
|
||||
type STAGE_TYPE is (IDLE, PACKET_HEADER, PACKET_SRC_ADDR, PACKET_SRC_ENTITYID, PACKET_SRC_GUIDPREFIX, PACKET_DEST_ENTITYID,
|
||||
CHECK_SRC_ENTITYID, LATCH_SEQ_NR, PROCESS_DATA, PROCESS_MESSAGE_SEQUENCE_NUMBERS, PROCESS_MESSAGE, PROCESS_GAP, PROCESS_GAP_SEQUENCE_NUMBERS, PROCESS_PL, CHECK_DEFAULT,
|
||||
LATCH_STRING_LENGTH, COMPARE_STRING, RXO_DURABILITY, RXO_DEADLINE, RXO_LIVELINESS, RXO_LEASE_DURATION, LATCH_LEASE_DURATION,
|
||||
CHECK_SRC_ENTITYID, LATCH_SEQ_NR, PROCESS_DATA, PROCESS_MESSAGE_SEQUENCE_NUMBERS, PROCESS_MESSAGE, PROCESS_GAP, PROCESS_GAP_SEQUENCE_NUMBERS, FIND_NEXT_VALID_IN_BITMAP,
|
||||
PROCESS_PL, CHECK_DEFAULT, LATCH_STRING_LENGTH, COMPARE_STRING, RXO_DURABILITY, RXO_DEADLINE, RXO_LIVELINESS, RXO_LEASE_DURATION, LATCH_LEASE_DURATION,
|
||||
RXO_RELIABILITY, RXO_DESTINATION_ORDER, RXO_OWNERSHIP, RXO_PRESENTATION, RXO_PARTITION, RXO_LATENCY_BUDGET, CHECK_MAX_SIZE_SERIALIZED,
|
||||
MATCH_DOMAIN_ID, MATCH_PROTOCOL_VERSION, LATCH_LOCATOR, LATCH_EXPECTS_INLINE_QOS, MATCH_GUID, CHECK_REMOTE_BUILTIN_ENDPOINTS,
|
||||
PARTICIPANT_MATCH_STAGE, INFORM_ENDPOINTS_MATCH, INFORM_ENDPOINTS_UNMATCH, INFORM_ENDPOINTS_PARTICIPANT_UNMATCH, PARTICIPANT_STALE_CHECK,
|
||||
@ -274,11 +274,13 @@ architecture arch of rtps_builtin_endpoint is
|
||||
-- Counter used to index the Subscriber Data
|
||||
signal subscriber_data_cnt, subscriber_data_cnt_next : natural range 0 to work.math_pkg.max(READER_ENDPOINT_DATA.length-1, 0) := 0;
|
||||
-- Signifies the next expected Sequence Number of the current relevant Message Type (Participant/Publisher/Subscriber/Message Data)
|
||||
signal next_seq_nr, next_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
|
||||
-- Latch used to store the first Sequence Number in ACKNACK/HEARTBEAT/GAP Messages
|
||||
signal first_seq_nr, first_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
|
||||
-- Latch used to store the last Sequence Number in HEARTBEAT/GAP Messages
|
||||
signal last_seq_nr, last_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
|
||||
signal next_seq_nr, next_seq_nr_next : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
|
||||
-- Generic Sequence Number Latch
|
||||
signal sn_latch_1, sn_latch_1_next : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
|
||||
-- Generic Sequence Number Latch
|
||||
signal sn_latch_2, sn_latch_2_next : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
|
||||
-- Generic Sequence Number Latch
|
||||
signal sn_latch_3, sn_latch_3_next : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
|
||||
-- Intermediate write enable signal.
|
||||
signal wr_sig : std_logic := '0';
|
||||
-- Signifies if a Stale Endpoint Check is in progress
|
||||
@ -302,6 +304,14 @@ architecture arch of rtps_builtin_endpoint is
|
||||
signal live_gap_start, live_gap_start_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
|
||||
-- Points to the first Sequence Number before "auto_live_seq_nr" (Signifies the end of the GAP between "man_live_seq_nr" and "auto_live_seq_nr")
|
||||
signal live_gap_end, live_gap_end_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
|
||||
-- Denotes the number of valid Bitmap longs (4-Byte words)
|
||||
signal bitmap_cnt, bitmap_cnt_next : unsigned(log2c(MAX_BITMAP_WIDTH/CDR_LONG_WIDTH)-1 downto 0) := (others => '0');
|
||||
-- NumberSet Bitmap Latch
|
||||
signal bitmap_latch, bitmap_latch_next : BITMAP_TYPE := (others => (others => '0'));
|
||||
-- Counter used to read out Bitmaps
|
||||
signal cnt2, cnt2_next : natural range 0 to BITMAP_TYPE'length := 0;
|
||||
-- Signal used to iterate through Bitmaps
|
||||
signal bitmap_pos, bitmap_pos_next : natural range 0 to MAX_BITMAP_WIDTH-1 := 0;
|
||||
-- Participant Announcement Timeout Time
|
||||
signal announcement_time, announcement_time_next : TIME_TYPE := (others => (others => '0'));
|
||||
-- Heartbeat/Liveliness Assertion Timeout Time
|
||||
@ -398,6 +408,18 @@ architecture arch of rtps_builtin_endpoint is
|
||||
alias key_flag : std_logic is flags(3);
|
||||
alias final_flag : std_logic is flags(1);
|
||||
alias payload_flag : std_logic is flags(4);
|
||||
-- HEARTBEAT
|
||||
alias first_seq_nr : SEQUENCENUMBER_TYPE is sn_latch_1;
|
||||
alias first_seq_nr_next : SEQUENCENUMBER_TYPE is sn_latch_1_next;
|
||||
alias last_seq_nr : SEQUENCENUMBER_TYPE is sn_latch_2;
|
||||
alias last_seq_nr_next : SEQUENCENUMBER_TYPE is sn_latch_2_next;
|
||||
-- GAP
|
||||
alias gap_start : SEQUENCENUMBER_TYPE is sn_latch_1;
|
||||
alias gap_start_next : SEQUENCENUMBER_TYPE is sn_latch_1_next;
|
||||
alias gap_list_base : SEQUENCENUMBER_TYPE is sn_latch_2;
|
||||
alias gap_list_base_next : SEQUENCENUMBER_TYPE is sn_latch_2_next;
|
||||
alias gap_list_end : SEQUENCENUMBER_TYPE is sn_latch_3;
|
||||
alias gap_list_end_next : SEQUENCENUMBER_TYPE is sn_latch_3_next;
|
||||
|
||||
--*****FUNCTION DECLARATION*****
|
||||
-- Return minimum of t1,t2,t3 or TIME_INVALID if t1,t2,t3 < t.
|
||||
@ -416,6 +438,16 @@ architecture arch of rtps_builtin_endpoint is
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
-- Helper function to convert BITMAP_TYPE to std_logic_vector
|
||||
function to_slv_bitmap (input : BITMAP_TYPE) return std_logic_vector is
|
||||
variable ret : std_logic_vector(0 to MAX_BITMAP_WIDTH-1) := (others => '0');
|
||||
begin
|
||||
for i in 0 to BITMAP_TYPE'length-1 loop
|
||||
ret(i*WORD_WIDTH to ((i+1)*WORD_WIDTH)-1) := input(i);
|
||||
end loop;
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
procedure assert_sn is
|
||||
begin
|
||||
if (message_type = EDP and is_subscriber = '0') then
|
||||
@ -519,6 +551,7 @@ begin
|
||||
-- LIVELINESS_UPDATE Propagate Liveliness Assertion of remote Participant to respective local Reader Endpoints
|
||||
-- PROCESS_GAP Parse RTPS GAP Submessage
|
||||
-- PROCESS_GAP_SEQUENCE_NUMBERS Process GAP Sequence Numbers. Update stored Sequence Numbers if necessary
|
||||
-- FIND_NEXT_VALID_IN_BITMAP Iterate through Bitmap and find the next valid Sequence Number.
|
||||
-- PROCESS_HEARTBEAT Parse RTPS HEARTBEAT Submessage
|
||||
-- PROCESS_HEARTBEAT_SEQUENCE_NUMBERS Process HEARTBEAT Sequence Numbers. Update stored Sequence Numbers if necessary. Set HEARTBEAT response timeout accordingly.
|
||||
-- PROCESS_ACKNACK Parse RTPS ACKNACK Submessage
|
||||
@ -568,6 +601,8 @@ begin
|
||||
variable tmp_default_qos_match : DEFAULT_QOS_MATCH_TYPE := READER_DEFAULT_QOS_MATCH;
|
||||
variable tmp_dw : DOUBLE_WORD_ARRAY := (others => (others => '0'));
|
||||
variable mem_seq_nr : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
|
||||
-- NOTE: We convert the bitamp to a slv to make operations easier (The tool should handle both cases equally)
|
||||
variable tmp_bitmap : std_logic_vector(0 to MAX_BITMAP_WIDTH-1) := (others => '0');
|
||||
begin
|
||||
--DEFAULT Registered
|
||||
stage_next <= stage;
|
||||
@ -595,8 +630,9 @@ begin
|
||||
cnt_next <= cnt;
|
||||
reader_flags_next <= reader_flags;
|
||||
stale_check_next <= stale_check;
|
||||
first_seq_nr_next <= first_seq_nr;
|
||||
last_seq_nr_next <= last_seq_nr;
|
||||
sn_latch_1_next <= sn_latch_1;
|
||||
sn_latch_2_next <= sn_latch_2;
|
||||
sn_latch_3_next <= sn_latch_3;
|
||||
auto_live_seq_nr_next <= auto_live_seq_nr;
|
||||
man_live_seq_nr_next <= man_live_seq_nr;
|
||||
live_gap_start_next <= live_gap_start;
|
||||
@ -615,6 +651,10 @@ begin
|
||||
long_latch_next <= long_latch;
|
||||
rcvd_next <= rcvd;
|
||||
check_time_next <= check_time;
|
||||
cnt2_next <= cnt2;
|
||||
bitmap_cnt_next <= bitmap_cnt;
|
||||
bitmap_latch_next <= bitmap_latch;
|
||||
bitmap_pos_next <= bitmap_pos;
|
||||
-- DEFAULT Unregistered
|
||||
rd_sig <= '0';
|
||||
rd_guard := '0';
|
||||
@ -1349,18 +1389,37 @@ begin
|
||||
rd_guard := '1';
|
||||
cnt_next <= cnt + 1;
|
||||
|
||||
-- Latch Sequence Numbers
|
||||
case (cnt) is
|
||||
-- GapStart Sequence Number 1/2
|
||||
when 0 =>
|
||||
first_seq_nr_next(0) <= unsigned(data_in_swapped);
|
||||
gap_start_next(0) <= unsigned(data_in_swapped);
|
||||
-- GapStart Sequence Number 2/2
|
||||
when 1 =>
|
||||
first_seq_nr_next(1) <= unsigned(data_in_swapped);
|
||||
gap_start_next(1) <= unsigned(data_in_swapped);
|
||||
-- GapList.Base 1/2
|
||||
when 2 =>
|
||||
last_seq_nr_next(0) <= unsigned(data_in_swapped);
|
||||
gap_list_base_next(0) <= unsigned(data_in_swapped);
|
||||
-- GapList.Base 2/2
|
||||
when 3 =>
|
||||
last_seq_nr_next(1) <= unsigned(data_in_swapped);
|
||||
-- NOTE: Rest of GAP Message is ignored
|
||||
gap_list_base_next(1) <= unsigned(data_in_swapped);
|
||||
-- GapList.NumBits
|
||||
when 4 =>
|
||||
gap_list_end_next <= gap_list_base + to_integer(unsigned(data_in_swapped));
|
||||
bitmap_cnt_next <= unsigned(round_slv(data_in_swapped(log2c(MAX_BITMAP_WIDTH)-1 downto 0),bitmap_cnt'length));
|
||||
cnt2_next <= 0;
|
||||
-- GapList.Bitmap
|
||||
when 5 =>
|
||||
-- Read Bitmap
|
||||
if (cnt2 < bitmap_cnt) then
|
||||
cnt2_next <= cnt2 + 1;
|
||||
|
||||
bitmap_latch_next(cnt2) <= data_in_swapped;
|
||||
|
||||
-- Keep Sub-State
|
||||
cnt_next <= cnt;
|
||||
else
|
||||
stage_next <= PROCESS_GAP_SEQUENCE_NUMBERS;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -1371,12 +1430,34 @@ begin
|
||||
|
||||
-- Wait for Sequence Number to be fetched from buffer
|
||||
if (mem_op_done = '1') then
|
||||
-- DEFAULT
|
||||
stage_next <= SKIP_PACKET;
|
||||
|
||||
-- Sender known
|
||||
if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) 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)
|
||||
-- GAP only relevant if next expected sequence number in GAP
|
||||
if (first_seq_nr <= mem_seq_nr and last_seq_nr >= mem_seq_nr) then
|
||||
-- Store GAP end as last sequence number
|
||||
-- GAP is relevant
|
||||
if (gap_start <= mem_seq_nr and mem_seq_nr <= gap_list_end) then
|
||||
-- Next Expected is in GAP List
|
||||
if (gap_list_base <= mem_seq_nr) then
|
||||
-- Begin searching next valid SN from the current expected in the bitmap list
|
||||
bitmap_pos_next <= to_integer(next_seq_nr - gap_list_base);
|
||||
else
|
||||
-- Begin searching next valid SN from the beginning of the bitmap list
|
||||
next_seq_nr_next <= gap_list_base;
|
||||
bitmap_pos_next <= 0;
|
||||
end if;
|
||||
stage_next <= FIND_NEXT_VALID_IN_BITMAP;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
when FIND_NEXT_VALID_IN_BITMAP =>
|
||||
-- Memory Operation Guard
|
||||
if (mem_op_done = '1') then
|
||||
tmp_bitmap := to_slv_bitmap(bitmap_latch);
|
||||
|
||||
-- First valid sequence number found
|
||||
if (tmp_bitmap(bitmap_pos) = '0') then
|
||||
-- Update next sequence number
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= UPDATE_PARTICIPANT;
|
||||
if (message_type = EDP and is_subscriber = '0') then
|
||||
@ -1386,11 +1467,13 @@ begin
|
||||
else -- message_type = MESSAGE
|
||||
mem_field_flags <= PMF_MES_SEQ_NR_FLAG;
|
||||
end if;
|
||||
next_seq_nr_next <= last_seq_nr + 1;
|
||||
end if;
|
||||
end if;
|
||||
-- DONE
|
||||
stage_next <= SKIP_PACKET;
|
||||
else
|
||||
-- Continue search
|
||||
bitmap_pos_next <= bitmap_pos + 1;
|
||||
next_seq_nr_next <= next_seq_nr + 1;
|
||||
end if;
|
||||
end if;
|
||||
when PROCESS_HEARTBEAT =>
|
||||
-- Input FIFO Guard
|
||||
@ -1425,10 +1508,11 @@ begin
|
||||
-- No scheduled Heartbeat Response
|
||||
if (participant_data.heartbeat_res_time = TIME_INVALID) then
|
||||
-- If current Sequence Number obsolete (removed from source history cache)
|
||||
if (first_seq_nr > mem_seq_nr and first_seq_nr <= last_seq_nr) then
|
||||
if (first_seq_nr > mem_seq_nr) then
|
||||
-- Store new expected Sequence Number and set Response Dealy
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= UPDATE_PARTICIPANT;
|
||||
next_seq_nr_next <= first_seq_nr;
|
||||
if (message_type = EDP and is_subscriber = '0') then
|
||||
mem_field_flags <= PMF_PUB_SEQ_NR_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG;
|
||||
elsif (message_type = EDP and is_subscriber = '1') then
|
||||
@ -1436,8 +1520,8 @@ begin
|
||||
else -- message_type = MESSAGE
|
||||
mem_field_flags <= PMF_MES_SEQ_NR_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG;
|
||||
end if;
|
||||
next_seq_nr_next <= first_seq_nr;
|
||||
if (PARTICIPANT_HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE) then
|
||||
-- NOTE: Only response with ACKNACK if SN is available (Or no Final Flag)
|
||||
if (PARTICIPANT_HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE and (first_seq_nr <= last_seq_nr or final_flag = '0')) then
|
||||
tmp_dw := time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY;
|
||||
res_time <= tmp_dw;
|
||||
-- NOTE: Last Bit denotes if this is Response or Suppression Delay
|
||||
@ -1451,11 +1535,12 @@ begin
|
||||
res_time <= TIME_INVALID;
|
||||
end if;
|
||||
-- If new Sequence Number is available or Writer expects ACKNACK
|
||||
elsif (PARTICIPANT_HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE and (last_seq_nr >= mem_seq_nr or final_flag = '0')) then
|
||||
elsif (last_seq_nr >= mem_seq_nr or final_flag = '0') then
|
||||
-- Set Response Delay
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= UPDATE_PARTICIPANT;
|
||||
mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG;
|
||||
if (PARTICIPANT_HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE) then
|
||||
tmp_dw := time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY;
|
||||
res_time <= tmp_dw;
|
||||
-- NOTE: Last Bit denotes if this is Response or Suppression Delay
|
||||
@ -1465,14 +1550,18 @@ begin
|
||||
if (tmp_dw < check_time) then
|
||||
check_time_next <= tmp_dw;
|
||||
end if;
|
||||
else
|
||||
res_time <= TIME_INVALID;
|
||||
end if;
|
||||
end if;
|
||||
-- Currently in Heartbeat Response Delay
|
||||
elsif (participant_data.heartbeat_res_time(1)(0) = '0') then
|
||||
-- If current Sequence Number obsolete (removed from source history cache)
|
||||
if (first_seq_nr > mem_seq_nr and first_seq_nr <= last_seq_nr) then
|
||||
if (first_seq_nr > mem_seq_nr) then
|
||||
-- Store new expected Sequence Number
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= UPDATE_PARTICIPANT;
|
||||
next_seq_nr_next <= first_seq_nr;
|
||||
if (message_type = EDP and is_subscriber = '0') then
|
||||
mem_field_flags <= PMF_PUB_SEQ_NR_FLAG;
|
||||
elsif (message_type = EDP and is_subscriber = '1') then
|
||||
@ -1480,7 +1569,6 @@ begin
|
||||
else -- message_type = MESSAGE
|
||||
mem_field_flags <= PMF_MES_SEQ_NR_FLAG;
|
||||
end if;
|
||||
next_seq_nr_next <= first_seq_nr;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@ -5635,8 +5723,9 @@ begin
|
||||
mem_prev_addr_base <= PARTICIPANT_MEMORY_MAX_ADDRESS;
|
||||
seq_nr <= SEQUENCENUMBER_UNKNOWN;
|
||||
next_seq_nr <= SEQUENCENUMBER_UNKNOWN;
|
||||
first_seq_nr <= SEQUENCENUMBER_UNKNOWN;
|
||||
last_seq_nr <= SEQUENCENUMBER_UNKNOWN;
|
||||
sn_latch_1 <= SEQUENCENUMBER_UNKNOWN;
|
||||
sn_latch_2 <= SEQUENCENUMBER_UNKNOWN;
|
||||
sn_latch_3 <= SEQUENCENUMBER_UNKNOWN;
|
||||
auto_live_seq_nr <= convert_to_double_word(to_unsigned(2, 64));
|
||||
man_live_seq_nr <= FIRST_SEQUENCENUMBER;
|
||||
live_gap_start <= convert_to_double_word(to_unsigned(2, 64));
|
||||
@ -5648,6 +5737,8 @@ begin
|
||||
participant_data <= ZERO_PARTICIPANT_DATA;
|
||||
participant_latch_data <= ZERO_PARTICIPANT_LATCH_DATA;
|
||||
cnt <= 0;
|
||||
cnt2 <= 0;
|
||||
bitmap_pos <= 0;
|
||||
mem_cnt <= 0;
|
||||
participant_data_cnt <= 0;
|
||||
publisher_data_cnt <= 0;
|
||||
@ -5669,6 +5760,8 @@ begin
|
||||
rcvd <= (others => '0');
|
||||
reader_flags <= (others => '0');
|
||||
current_pmf <= (others => '0');
|
||||
bitmap_cnt <= (others => '0');
|
||||
bitmap_latch <= (others => (others => '0'));
|
||||
else
|
||||
stage <= stage_next;
|
||||
return_stage <= return_stage_next;
|
||||
@ -5691,8 +5784,9 @@ begin
|
||||
mem_prev_addr_base <= mem_prev_addr_base_next;
|
||||
seq_nr <= seq_nr_next;
|
||||
next_seq_nr <= next_seq_nr_next;
|
||||
first_seq_nr <= first_seq_nr_next;
|
||||
last_seq_nr <= last_seq_nr_next;
|
||||
sn_latch_1 <= sn_latch_1_next;
|
||||
sn_latch_2 <= sn_latch_2_next;
|
||||
sn_latch_3 <= sn_latch_3_next;
|
||||
auto_live_seq_nr <= auto_live_seq_nr_next;
|
||||
man_live_seq_nr <= man_live_seq_nr_next;
|
||||
live_gap_start <= live_gap_start_next;
|
||||
@ -5704,6 +5798,8 @@ begin
|
||||
participant_data <= participant_data_next;
|
||||
participant_latch_data <= participant_latch_data_next;
|
||||
cnt <= cnt_next;
|
||||
cnt2 <= cnt2_next;
|
||||
bitmap_pos <= bitmap_pos_next;
|
||||
mem_cnt <= mem_cnt_next;
|
||||
participant_data_cnt <= participant_data_cnt_next;
|
||||
publisher_data_cnt <= publisher_data_cnt_next;
|
||||
@ -5725,6 +5821,8 @@ begin
|
||||
rcvd <= rcvd_next;
|
||||
reader_flags <= reader_flags_next;
|
||||
current_pmf <= current_pmf_next;
|
||||
bitmap_cnt <= bitmap_cnt_next;
|
||||
bitmap_latch <= bitmap_latch_next;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user