Support MANUAL_BY_TOPIC Liveliness and various fixes in RTPS Reader

This commit is contained in:
Greek 2021-02-02 23:51:10 +01:00
parent 5b8206d539
commit d3fb1cc176

View File

@ -48,7 +48,7 @@ entity rtps_reader is
dds_data_out : in std_logic_vector(WORD_WIDTH-1 downto 0);
dds_valid_out : in std_logic;
dds_ready_out : out std_logic;
dds_last_word_out: in std_logic
dds_last_word_out : in std_logic
);
end entity;
@ -67,7 +67,7 @@ architecture arch of rtps_reader is
-- Address pointing to the beginning of the first Endpoint Data Frame
constant FIRST_ENDPOINT_ADDRESS : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
-- *ENDPOINT MEMORY FORMAT FIELD FLAGS*
-- *ENDPOINT MEMORY FORMAT FORMAT FLAGS*
-- Flags mapping to the respective Endpoint Memory Frame Fields
constant EMF_FLAG_WIDTH : natural := 7;
constant EMF_ENTITYID_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (0 => 1, others => '0');
@ -95,7 +95,7 @@ architecture arch of rtps_reader is
LATCH_EXTRA_DATA, LATCH_HEARTBEAT, PROCESS_HEARTBEAT, LATCH_GAP, PROCESS_GAP, FIND_NEXT_VALID_IN_BITMAP, PROCESS_INLINE_QOS, LATCH_LIFESPAN,
LATCH_KEY_HASH, LATCH_STATUS_INFO, INITIATE_ADD_CACHE_CHANGE_REQUEST, ADD_CACHE_CHANGE, PUSH_PAYLOAD, FINALIZE_ADD_CACHE_CHANGE_REQUEST,
ENDPOINT_STALE_CHECK, SEND_HEADER, SEND_ACKNACK, SKIP_PARAMETER, SKIP_PACKET);
-- Memory FSM states. Explaine below in detail
-- Memory FSM states. Explained below in detail
type MEM_STAGE_TYPE is (IDLE, SEARCH_ENDPOINT, GET_ENDPOINT_DATA, INSERT_ENDPOINT, UPDATE_ENDPOINT, REMOVE_ENDPOINT, FIND_EMPTY_SLOT,
RESET_MAX_POINTER, GET_NEXT_ENDPOINT);
-- *Memory FSM Opcodes*
@ -132,7 +132,8 @@ architecture arch of rtps_reader is
guid : GUID_TYPE;
addr : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0);
portn : std_logic_vector(UDP_PORT_WIDTH-1 downto 0);
deadline : TIME_TYPE;
lease_deadline : TIME_TYPE;
res_time : TIME_TYPE;
next_seq_nr : SEQUENCENUMBER_TYPE;
field_flag : std_logic_vector(0 to EMF_FLAG_WIDTH-1);
end record;
@ -141,7 +142,8 @@ architecture arch of rtps_reader is
guid => GUID_UNKNOWN,
addr => IPv4_ADDRESS_INVALID,
portn => UDP_PORT_INVALID,
deadline => TIME_INVALID,
lease_deadline => TIME_INVALID,
res_time => TIME_INVALID,
next_seq_nr => SEQUENCENUMBER_UNKNOWN,
field_flag => (others => '0')
);
@ -197,7 +199,7 @@ architecture arch of rtps_reader is
signal sn_latch_3, sn_latch_3_next : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
-- Toggle latching the "last_word_in" signal until reset
signal last_word_in_latch, last_word_in_latch_next : std_logic := '0';
-- Time until next Stale Endpoint Check
-- Time of next Stale Endpoint Check
signal check_time, check_time_next : TIME_TYPE := TIME_INVALID;
-- Signifies if a Stale Endpoint Check is in progress
signal stale_check, stale_check_next : std_logic := '0';
@ -221,8 +223,10 @@ architecture arch of rtps_reader is
signal mem_op_done : std_logic := '0';
-- Signal containing the relevant Endpoint Memory Format Fields of the Memory Operation
signal mem_field_flags : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (others => '0');
-- General signal used to pass TIMEs from main to memory process
signal deadline : TIME_TYPE := TIME_INVALID;
-- Signal used to pass Lease Deadlines from main to memory process
signal lease_deadline : TIME_TYPE := TIME_INVALID;
-- Signal used to pass Response Deadlines from main to memory process
signal res_time : TIME_TYPE := TIME_INVALID;
-- *MEMORY PROCESS*
-- Memory FSM state
@ -273,6 +277,7 @@ architecture arch of rtps_reader 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);
alias liveliness_flag : std_logic is flags(2);
-- HEARTBEAT
alias first_seq_nr : SEQUENCENUMBER_TYPE is sn_latch_1;
alias first_seq_nr_next : SEQUENCENUMBER_TYPE is sn_latch_1_next;
@ -356,6 +361,7 @@ begin
-- 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');
variable rd_guard : std_logic := '0';
variable tmp_flags : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (others => '0');
begin
-- DEFAULT Registerd
stage_next <= stage;
@ -386,7 +392,8 @@ begin
-- DEFAULT Unregistered
mem_opcode <= NOP;
dds_opcode <= ADD_CACHE_CHANGE;
deadline <= TIME_INVALID;
lease_deadline <= TIME_INVALID;
res_time <= TIME_INVALID;
meta_rd <= '0';
rd <= '0';
mem_op_start <= '0';
@ -615,7 +622,17 @@ begin
-- Insert Matched Remote Endpoint
mem_op_start <= '1';
mem_opcode <= INSERT_ENDPOINT;
deadline <= (time + LEASE_DURATION) when (LEASE_DURATION /= DURATION_INFINITE) else TIME_INVALID;
if (LEASE_DURATION /= DURATION_INFINITE) then
lease_deadline <= time + LEASE_DURATION;
-- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock)
-- Update Check Time
if ((time + LEASE_DURATION) < check_time) then
check_time_next <= time + LEASE_DURATION;
end if;
else
lease_deadline <= TIME_INVALID;
end if;
-- DONE
stage_next <= IDLE;
end if;
@ -691,7 +708,17 @@ begin
mem_op_start <= '1';
mem_opcode <= UDPATE_ENDPOINT;
mem_field_flags <= EMF_LEASE_DEADLINE_FLAG;
deadline <= (time + LEASE_DURATION) when (LEASE_DURATION /= DURATION_INFINITE) else TIME_INVALID;
if (LEASE_DURATION /= DURATION_INFINITE) then
lease_deadline <= time + LEASE_DURATION;
-- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock)
-- Update Check Time
if ((time + LEASE_DURATION) < check_time) then
check_time_next <= time + LEASE_DURATION;
end if;
else
lease_deadline <= TIME_INVALID;
end if;
end if;
cnt_next <= 1;
end if;
@ -784,6 +811,24 @@ begin
-- Endpoint in Buffer
if (mem_addr_base /= ENDPOINT_MEMORY_MAX_ADDRESS) then
-- Default
tmp_flags := (others => '0');
tmp_dw := TIME_INFINITE;
-- Liveliness Assertion
if (liveliness_flag = '1') then
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
tmp_flags := tmp_flags or EMF_LEASE_DEADLINE_FLAG;
if (LEASE_DURATION /= DURATION_INFINITE) then
lease_deadline <= time + LEASE_DURATION;
tmp_dw := time + LEASE_DURATION;
else
lease_deadline <= TIME_INVALID;
end if;
end if;
-- No scheduled Heartbeat Response
if (mem_endpoint_data.res_time = 0) then
-- If current Sequence Number obsolete (removed from source history cache)
@ -792,26 +837,28 @@ begin
next_seq_nr_next <= first_seq_nr;
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
mem_field_flags <= EMF_NEXT_SEQ_NR_FLAG or EMF_RES_TIME_FLAG;
tmp_flags := tmp_flags or EMF_NEXT_SEQ_NR_FLAG or EMF_RES_TIME_FLAG;
if (HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE) then
deadline <= time + HEARTBEAT_RESPONSE_DELAY;
res_time <= time + HEARTBEAT_RESPONSE_DELAY;
-- NOTE: Last Bit denotes if this is Response or Suppression Delay
deadline(1)(0) <= '0';
res_time(1)(0) <= '0';
tmp_dw := (time + HEARTBEAT_RESPONSE_DELAY) when ((time + HEARTBEAT_RESPONSE_DELAY) < tmp_dw);
else
deadline <= TIME_INVALID;
res_time <= TIME_INVALID;
end if;
-- If new Sequence Number is available or Writer expects ACKNACK
elsif (last_seq_nr >= mem_endpoint_data.next_seq_nr or final_flag = '0') then
-- Set Response Delay
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
mem_field_flags <= EMF_RES_TIME_FLAG;
tmp_flags := tmp_flags or EMF_RES_TIME_FLAG;
if (HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE) then
deadline <= time + HEARTBEAT_RESPONSE_DELAY;
res_time <= time + HEARTBEAT_RESPONSE_DELAY;
-- NOTE: Last Bit denotes if this is Response or Suppression Delay
deadline(1)(0) <= '0';
res_time(1)(0) <= '0';
tmp_dw := (time + HEARTBEAT_RESPONSE_DELAY) when ((time + HEARTBEAT_RESPONSE_DELAY) < tmp_dw);
else
deadline <= TIME_INVALID;
res_time <= TIME_INVALID;
end if;
end if;
-- Currently in Heartbeat Response Delay
@ -822,9 +869,17 @@ begin
next_seq_nr_next <= first_seq_nr;
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
mem_field_flags <= EMF_NEXT_SEQ_NR_FLAG;
tmp_flags <= tmp_flags or EMF_NEXT_SEQ_NR_FLAG;
end if;
end if;
mem_field_flags <= tmp_flags;
-- XXX: Possible Worst Case Path (MULTIPLE 64-bit addition and comparison in same clock)
-- Update Check Time
if (tmp_dw < check_time) then
check_time_next <= tmp_dw;
end if;
end if;
end if;
when LATCH_GAP =>
@ -1027,7 +1082,7 @@ begin
-- TODO: Use source timestamp if clocks with remote synchronized
-- Calculate Sample Lifespan Deadline
deadline <= (time + tmp_dw) when (tmp_dw /= DURATION_INFINITE) else TIME_INVALID;
lifespan_next <= (time + tmp_dw) when (tmp_dw /= DURATION_INFINITE) else TIME_INVALID;
-- DONE
stage_next <= SKIP_PARAMETER;
@ -1161,18 +1216,36 @@ begin
when FINALIZE_ADD_CACHE_CHANGE_REQUEST =>
-- NOTE: Memory is already in done state from previous state (ADD_CACHE_CHANGE)
assert (mem_op_done = '1') report "FINALIZE_ADD_CACHE_CHANGE_REQUEST precondition not met. mem_op_done /= '1'" severity FAILURE;
-- Wai for History Cache Response
-- Wait for History Cache Response
if (dds_res /= UNDEFINED) then
-- Operation was Accepted
if (dds_res = ACCEPTED) then
-- Update next sequence number and renew Lease
-- NOTE: The Lease Duration is also updated if the Cache Change is not accepted. This in effect "skews" the
-- "correctness" of the Writer Liveliness Protocol until the reader has no pending request from the Writer.
-- Update Endpoint
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
deadline <= (time + LEASE_DURATION) when (LEASE_DURATION /= DURATION_INFINITE) else TIME_INVALID;
mem_field_flags <= LEASE_DEADLINE_FLAG;
if (LEASE_DURATION /= DURATION_INFINITE) then
lease_deadline <= time + LEASE_DURATION;
-- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock)
-- Update Check Time
if ((time + LEASE_DURATION) < check_time) then
check_time_next <= time + LEASE_DURATION;
end if;
else
lease_deadline <= TIME_INVALID;
end if;
-- NOTE: In case the operation was unsucessfull (e.g. reached Resource Limits), the Sequence Number is not updated
-- and thus not "acknowledged".
-- Operation was Accepted
if (dds_res = ACCEPTED) then
-- Update also next sequence number
mem_field_flags <= NEXT_SEQ_NR_FLAG or LEASE_DEADLINE_FLAG;
end if;
-- NOTE: In case the operation was unsucessfull (e.g. reached Resource Limits), the endpoint is not updated and the
-- Sequence Number is thus not "acknowledged".
-- DONE
stage_next <= SKIP_PACKET;
end if;
@ -1208,7 +1281,7 @@ begin
-- Disable Suppression
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
deadline <= TIME_INVALID;
res_time <= TIME_INVALID;
mem_field_flags <= RES_TIME_FLAG;
-- Continue Search
cnt_next <= 0;
@ -1221,10 +1294,7 @@ begin
cnt_next <= 2;
end if;
else
-- Continue Search
cnt_next <= 0;
end if;
-- Set New Timeout (Select the closest next timeout)
-- Update Check Time
if (mem_endpoint_data.res_time /= TIME_INVALID and mem_endpoint_data.lease_deadline /= TIME_INVALID and mem_endpoint_data.res_time < mem_endpoint_data.lease_deadline) then
if (mem_endpoint_data.res_time < check_time) then
check_time_next <= mem_endpoint_data.res_time;
@ -1234,6 +1304,10 @@ begin
check_time_next <= mem_endpoint_data.lease_deadline;
end if;
end if;
-- Continue Search
cnt_next <= 0;
end if;
end if;
when 2 =>
-- Synthesis Guard
@ -1241,12 +1315,18 @@ begin
-- Set Heartbeat Suppression Time
if (HEARTBEAT_SUPPRESSION_DELAY /= DURATION_INFINITE and HEARTBEAT_SUPPRESSION_DELAY /= DURATION_ZERO) then
-- Set Heartbeat Suppression Time
deadline <= time + HEARTBEAT_SUPPRESSION_DELAY;
res_time <= time + HEARTBEAT_SUPPRESSION_DELAY;
-- NOTE: Last Bit denotes if this is Response or Suppression Delay
deadline(1)(0) <= '1';
res_time(1)(0) <= '1';
-- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock)
-- Update Check Time
if ((time + HEARTBEAT_SUPPRESSION_DELAY) < check_time) then
check_time_next <= time + HEARTBEAT_SUPPRESSION_DELAY;
end if;
else
-- Disable Suppression
deadline <= TIME_INVALID;
res_time <= TIME_INVALID;
end if;
mem_op_start <= '1';
mem_opcode <= UPDATE_PARTICIPANT;
@ -1473,7 +1553,8 @@ begin
guid => guid_next,
addr => addr_next,
portn => portn_next,
deadline => deadline,
lease_deadline => lease_deadline,
res_time => res_time,
next_seq_nr => next_seq_nr_next,
field_flag => mem_field_flags
);
@ -1491,15 +1572,15 @@ begin
mem_cnt_next <= 0;
when UPDATE_ENDPOINT =>
mem_stage_next <= UPDATE_ENDPOINT;
if (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then
if (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags.field_flag,EMF_IPV4_ADDR_FLAG)) then
mem_cnt_next <= 0;
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags.field_flag,EMF_UDP_PORT_FLAG)) then
mem_cnt_next <= 1;
elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then
elsif check_mask(mem_field_flags.field_flag,EMF_NEXT_SEQ_NR_FLAG) then
mem_cnt_next <= 2;
elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then
elsif check_mask(mem_field_flags.field_flag,EMF_LEASE_DEADLINE_FLAG) then
mem_cnt_next <= 4;
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags.field_flag,EMF_RES_TIME_FLAG)) then
mem_cnt_next <= 6;
else
-- DONE
@ -1528,19 +1609,19 @@ begin
-- Fetch Endpoint Data
mem_stage_next <= GET_ENDPOINT_DATA;
mem_endpoint_data_next <= ZERO_ENDPOINT_DATA;
if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then
if check_mask(mem_field_flags.field_flag,EMF_ENTITYID_FLAG) then
mem_cnt_next <= 0;
elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then
elsif check_mask(mem_field_flags.field_flag,EMF_GUIDPREFIX_FLAG) then
mem_cnt_next <= 1;
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags.field_flag,EMF_IPV4_ADDR_FLAG)) then
mem_cnt_next <= 4;
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags.field_flag,EMF_UDP_PORT_FLAG)) then
mem_cnt_next <= 5;
elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then
elsif check_mask(mem_field_flags.field_flag,EMF_NEXT_SEQ_NR_FLAG) then
mem_cnt_next <= 6;
elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then
elsif check_mask(mem_field_flags.field_flag,EMF_LEASE_DEADLINE_FLAG) then
mem_cnt_next <= 8;
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then
elsif (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags.field_flag,EMF_RES_TIME_FLAG)) then
mem_cnt_next <= 10;
else
-- DONE
@ -2201,7 +2282,7 @@ begin
when 8 =>
mem_valid_in <= '1';
mem_addr <= mem_addr_base + EMF_LEASE_DEADLINE_OFFSET;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.deadline(0));
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lease_deadline(0));
if (mem_ready_in = '1') then
mem_cnt_next <= mem_cnt + 1;
end if;
@ -2209,7 +2290,7 @@ begin
when 9 =>
mem_valid_in <= '1';
mem_addr <= mem_addr_base + EMF_LEASE_DEADLINE_OFFSET + 1;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.deadline(1));
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lease_deadline(1));
if (mem_ready_in = '1') then
if (RELIABILTY_QOS = RELIABLE_RELIABILITY_QOS) then
mem_cnt_next <= mem_cnt + 1;
@ -2320,7 +2401,7 @@ begin
when 4 =>
mem_valid_in <= '1';
mem_addr <= mem_addr_base + EMF_LEASE_DEADLINE_OFFSET;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.deadline(0));
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lease_deadline(0));
-- Memory Flow Control Guard
if (mem_ready_in = '1') then
mem_cnt_next <= mem_cnt + 1;
@ -2329,8 +2410,8 @@ begin
when 5 =>
mem_valid_in <= '1';
mem_addr <= mem_addr_base + EMF_LEASE_DEADLINE_OFFSET + 1;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.deadline(1));
mem_endpoint_data.lease_deadline <= mem_endpoint_latch_data.deadline;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lease_deadline(1));
mem_endpoint_data.lease_deadline <= mem_endpoint_latch_data.lease_deadline;
-- Memory Flow Control Guard
if (mem_ready_in = '1') then
if (RELIABILTY_QOS /= RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then
@ -2346,7 +2427,7 @@ begin
if (RELIABILTY_QOS = RELIABLE_RELIABILITY_QOS) then
mem_valid_in <= '1';
mem_addr <= mem_addr_base + EMF_RES_TIME_OFFSET;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.deadline(0));
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.res_time(0));
-- Memory Flow Control Guard
if (mem_ready_in = '1') then
mem_cnt_next <= mem_cnt + 1;
@ -2358,8 +2439,8 @@ begin
if (RELIABILTY_QOS = RELIABLE_RELIABILITY_QOS) then
mem_valid_in <= '1';
mem_addr <= mem_addr_base + EMF_RES_TIME_OFFSET + 1;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.deadline(1));
mem_endpoint_data.res_time <= mem_endpoint_latch_data.deadline;
mem_write_data <= std_logic_vector(mem_endpoint_latch_data.res_time(1));
mem_endpoint_data.res_time <= mem_endpoint_latch_data.res_time;
-- Memory Flow Control Guard
if (mem_ready_in = '1') then
-- DONE