Various fixes in RTPS Reader/Writer and DDS Reader
Amongst other fixes the interface between RTPS-HC/DDS was changed. The Liveliness Update metatraffic operation was also made QOS dependant and put behind synthesis guards. Instance Removal trigger was modified. While before at least 1 instance slot needed to be empty at all times (similar to the sample slot), thsi was changed to only remove instances on demand. This is controlled via a signal that holds the current number of stale (removalble) instances.
This commit is contained in:
parent
80cffb8197
commit
2aedc0229d
File diff suppressed because it is too large
Load Diff
@ -51,23 +51,26 @@ package rtps_config_package is
|
||||
|
||||
type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE, GET_CACHE_CHANGE, ACK_CACHE_CHANGE, NACK_CACHE_CHANGE);
|
||||
type KEY_GENERATOR_OPCODE_TYPE is (NOP, WRITE_PAYLOAD, READ_KEY, READ_SIZE);
|
||||
type HISTORY_CACHE_RESPONSE_TYPE is (UNDEFINED, ACK, ACCEPTED, REJECTED, INVALID);
|
||||
type HISTORY_CACHE_RESPONSE_TYPE is (OK, REJECTED, INVALID, ERROR);
|
||||
|
||||
-- Sample Status Info Flags
|
||||
constant SSI_DISPOSED_FLAG : natural := STATUS_INFO_DISPOSED_FLAG;
|
||||
constant SSI_UNREGISTERED_FLAG : natural := STATUS_INFO_UNREGISTERED_FLAG;
|
||||
constant SSI_FILTERED_FLAG : natural := STATUS_INFO_FILTERED_FLAG;
|
||||
constant SSI_KEY_HASH_FLAG : natural := 28;
|
||||
constant SSI_KEY_HASH_FLAG : natural := 28; -- Reader Only
|
||||
constant SSI_ALIGNED_FLAG : natural := 29;
|
||||
constant SSI_PAYLOAD_FLAG : natural := 30;
|
||||
constant SSI_READ_FLAG : natural := 31;
|
||||
constant SSI_READ_FLAG : natural := 31; -- Reader Only
|
||||
constant SSI_ACK_FLAG : natural := 31; -- Writer Only
|
||||
|
||||
-- Instance Status Info Flags
|
||||
constant ISI_NOT_ALIVE_DISPOSED_FLAG : natural := 0;
|
||||
constant ISI_NOT_ALIVE_NO_WRITERS_FLAG : natural := 1;
|
||||
constant ISI_NOT_ALIVE_DISPOSED_FLAG : natural := 0; -- Reader Only
|
||||
constant ISI_DISPOSED_FLAG : natural := 0; -- Writer Only
|
||||
constant ISI_NOT_ALIVE_NO_WRITERS_FLAG : natural := 1; -- Reader Only
|
||||
constant ISI_UNREGISTERED_FLAG : natural := 1; -- Writer Only
|
||||
constant ISI_LIVELINESS_FLAG : natural := 2;
|
||||
constant ISI_VIEW_FLAG : natural := 3;
|
||||
constant ISI_MARK_FLAG : natural := 4;
|
||||
constant ISI_VIEW_FLAG : natural := 3; -- Reader Only
|
||||
constant ISI_MARK_FLAG : natural := 4; -- Reader Only
|
||||
|
||||
-- TODO: Prefix the Flags with something that differntiates between them
|
||||
-- Remote Endpoint Flags
|
||||
@ -123,9 +126,10 @@ package rtps_config_package is
|
||||
|
||||
constant ENDPOINT_BITMAP_WIDTH : natural := 1; -- TODO
|
||||
type ENDPOINT_BITMAP_ARRAY_TYPE is array (0 to round_div(ENDPOINT_BITMAP_WIDTH, WORD_WIDTH)-1) of std_logic_vector(0 to WORD_WIDTH-1);
|
||||
constant ZERO_ENDPOINT_BITMAP_ARRAY : ENDPOINT_BITMAP_ARRAY_TYPE := (others => (others => '0'));
|
||||
|
||||
function to_endpoint_bitmap (input : ENDPOINT_BITMAP_ARRAY_TYPE) return std_logic_vector;
|
||||
function from_endpoint_bitmap (input : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1)) return ENDPOINT_BITMAP_ARRAY_TYPE;
|
||||
function from_endpoint_bitmap_array (input : ENDPOINT_BITMAP_ARRAY_TYPE) return std_logic_vector;
|
||||
function to_endpoint_bitmap_array (input : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1)) return ENDPOINT_BITMAP_ARRAY_TYPE;
|
||||
|
||||
-- Swap "data" to Big Endian representation.
|
||||
function endian_swap(swap : std_logic; data : std_logic_vector) return std_logic_vector;
|
||||
@ -1193,7 +1197,7 @@ package body rtps_config_package is
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
function to_endpoint_bitmap (input : ENDPOINT_BITMAP_ARRAY_TYPE) return std_logic_vector is
|
||||
function from_endpoint_bitmap_array (input : ENDPOINT_BITMAP_ARRAY_TYPE) return std_logic_vector is
|
||||
variable ret : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1) := (others => '0');
|
||||
begin
|
||||
for i in 0 to input'length-1 loop
|
||||
@ -1202,7 +1206,7 @@ package body rtps_config_package is
|
||||
return ret;
|
||||
end function;
|
||||
|
||||
function from_endpoint_bitmap (input : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1)) return ENDPOINT_BITMAP_ARRAY_TYPE is
|
||||
function to_endpoint_bitmap_array (input : std_logic_vector(0 to ENDPOINT_BITMAP_WIDTH-1)) return ENDPOINT_BITMAP_ARRAY_TYPE is
|
||||
variable ret : ENDPOINT_BITMAP_ARRAY_TYPE := (others => (others => '0'));
|
||||
begin
|
||||
for i in 0 to ret'length-1 loop
|
||||
|
||||
@ -12,6 +12,7 @@ use work.rtps_config_package.all;
|
||||
entity rtps_reader is
|
||||
generic (
|
||||
RELIABILTY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_RELIABILTY_QOS;
|
||||
LIVELINESS_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := DEFAULT_LIVELINESS_QOS;
|
||||
HEARTBEAT_RESPONSE_DELAY : DURATION_TYPE := TODO;
|
||||
HEARTBEAT_SUPPRESSION_DELAY : DURATION_TYPE := TODO;
|
||||
LEASE_DURATION : DURATION_TYPE := DEFAULT_LEASE_DURATION;
|
||||
@ -38,14 +39,16 @@ entity rtps_reader is
|
||||
full_rtps : in std_logic;
|
||||
last_word_out_rtps : out std_logic;
|
||||
data_out_rtps : out std_logic_vector(WORD_WIDTH-1 downto 0);
|
||||
-- TO DDS READER
|
||||
start_dds : out std_logic;
|
||||
opcode_dds : out HISTORY_CACHE_OPCODE_TYPE;
|
||||
res_dds : in HISTORY_CACHE_RESPOSNE_TYPE;
|
||||
data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0);
|
||||
valid_out_dds : out std_logic;
|
||||
ready_out_dds : in std_logic;
|
||||
last_word_out_dds : out std_logic
|
||||
-- TO HISTORY CACHE
|
||||
start_hc : out std_logic;
|
||||
opcode_hc : out HISTORY_CACHE_OPCODE_TYPE;
|
||||
ack_hc : in std_logic;
|
||||
done_hc : in std_logic;
|
||||
ret_hc : in HISTORY_CACHE_RESPOSNE_TYPE;
|
||||
data_out_hc : out std_logic_vector(WORD_WIDTH-1 downto 0);
|
||||
valid_out_hc : out std_logic;
|
||||
ready_out_hc : in std_logic;
|
||||
last_word_out_hc : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
@ -389,18 +392,18 @@ begin
|
||||
lifespan_next <= lifespan;
|
||||
-- DEFAULT Unregistered
|
||||
mem_opcode <= NOP;
|
||||
opcode_dds <= ADD_CACHE_CHANGE;
|
||||
opcode_hc <= NOP;
|
||||
lease_deadline <= TIME_INVALID;
|
||||
res_time <= TIME_INVALID;
|
||||
rd_meta <= '0';
|
||||
rd_user <= '0';
|
||||
mem_op_start <= '0';
|
||||
start_dds <= '0';
|
||||
valid_out_dds <= '0';
|
||||
last_word_out_dds <= '0';
|
||||
start_hc <= '0';
|
||||
valid_out_hc <= '0';
|
||||
last_word_out_hc <= '0';
|
||||
rd_guard := '0';
|
||||
mem_field_flags <= (others => '0');
|
||||
data_out_dds <= (others => '0');
|
||||
data_out_hc <= (others => '0');
|
||||
|
||||
|
||||
|
||||
@ -453,8 +456,13 @@ begin
|
||||
stage_next <= LATCH_GUIDPREFIX;
|
||||
cnt_next <= 0;
|
||||
when OPCODE_LIVELINESS_UPDATE =>
|
||||
-- Synthesis Guard
|
||||
if (LIVELINESS_QOS /= MANUAL_BY_TOPIC_LIVELINESS_QOS) then
|
||||
stage_next <= LATCH_GUIDPREFIX;
|
||||
cnt_next <= 0;
|
||||
else
|
||||
stage_next <= SKIP_META_OPERATION;
|
||||
end if;
|
||||
when others =>
|
||||
stage_next <= SKIP_META_OPERATION;
|
||||
end case;
|
||||
@ -508,7 +516,7 @@ begin
|
||||
guid_next(2) <= data_in_user;
|
||||
end if;
|
||||
|
||||
if (is_meta = '1' and (meta_opcode = OPCODE_PARTICIPANT_UNMATCH or meta_opcode = OPCODE_LIVELINESS_UPDATE)) then
|
||||
if (is_meta = '1' and (meta_opcode = OPCODE_PARTICIPANT_UNMATCH or (LIVELINESS_QOS /= MANUAL_BY_TOPIC_LIVELINESS_QOS and meta_opcode = OPCODE_LIVELINESS_UPDATE))) then
|
||||
assert (last_word_in_meta = '1') report "last_word_in_meta not set" severity FAILURE;
|
||||
-- DONE Parsing
|
||||
stage_next <= INITIATE_ENDPOINT_SEARCH;
|
||||
@ -561,11 +569,14 @@ begin
|
||||
stage_next <= METATRAFFIC_OPERATION;
|
||||
cnt_next <= 0;
|
||||
when OPCODE_LIVELINESS_UPDATE =>
|
||||
-- Synthesis Guard
|
||||
if (LIVELINESS_QOS /= MANUAL_BY_TOPIC_LIVELINESS_QOS) then
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= GET_FIRST_ENDPOINT;
|
||||
mem_field_flags <= (others => '0');
|
||||
stage_next <= METATRAFFIC_OPERATION;
|
||||
cnt_next <= 0;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -657,11 +668,11 @@ begin
|
||||
stage_next <= IDLE;
|
||||
else
|
||||
-- Propagate Removal
|
||||
start_dds <= '1';
|
||||
opcode_dds <= REMOVE_WRITER;
|
||||
data_out_dds <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH));
|
||||
start_hc <= '1';
|
||||
opcode_hc <= REMOVE_WRITER;
|
||||
data_out_hc <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH));
|
||||
-- Wait for Operation Acknowledgement
|
||||
if (res_dds = ACK) then
|
||||
if (ack_hc = '1') then
|
||||
-- Remove Unmatched Remote Endpoint
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= REMOVE_ENDPOINT;
|
||||
@ -680,11 +691,11 @@ begin
|
||||
-- Participant Match
|
||||
if (guid(0) = mem_endpoint_data.guid(0) and guid(1) = mem_endpoint_data.guid(1) and guid(2) = mem_endpoint_data.guid(2)) then
|
||||
-- Propagate Removal
|
||||
start_dds <= '1';
|
||||
opcode_dds <= REMOVE_WRITER;
|
||||
data_out_dds <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH));
|
||||
start_hc <= '1';
|
||||
opcode_hc <= REMOVE_WRITER;
|
||||
data_out_hc <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH));
|
||||
-- Wait for Operation Acknowledgement
|
||||
if (res_dds = ACK) then
|
||||
if (ack_hc = '1') then
|
||||
-- Remove Unmatched Remote Endpoint
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= REMOVE_ENDPOINT;
|
||||
@ -701,6 +712,8 @@ begin
|
||||
null;
|
||||
end case;
|
||||
when OPCODE_LIVELINESS_UPDATE =>
|
||||
-- Synthesis Guard
|
||||
if (LIVELINESS_QOS /= MANUAL_BY_TOPIC_LIVELINESS_QOS) then
|
||||
case (cnt) is
|
||||
when 0 =>
|
||||
-- No matches in memory
|
||||
@ -736,6 +749,7 @@ begin
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -1136,10 +1150,10 @@ begin
|
||||
if (WITH_KEY and key_hash_rcvd = '0' and data_flag = '0' and key_flag = '0') then
|
||||
stage_next <= SKIP_PACKET;
|
||||
else
|
||||
start_dds <= '1';
|
||||
opcode_dds <= ADD_CACHE_CHANGE;
|
||||
start_hc <= '1';
|
||||
opcode_hc <= ADD_CACHE_CHANGE;
|
||||
-- Wait until History Cache acknowledges request
|
||||
if (res_dds = ACK) then
|
||||
if (ack_hc = '1') then
|
||||
stage_next <= ADD_CACHE_CHANGE;
|
||||
cnt_next <= 0;
|
||||
end if;
|
||||
@ -1148,45 +1162,45 @@ begin
|
||||
case (cnt) is
|
||||
-- Status Info
|
||||
when 0 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= status_info;
|
||||
data_out_dds(SSI_KEY_HASH_FLAG) <= key_hash_rcvd;
|
||||
data_out_dds(SSI_PAYLOAD_FLAG) <= data_flag;
|
||||
data_out_dds(SSI_ALIGNED_FLAG) <= data_flag;
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= status_info;
|
||||
data_out_hc(SSI_KEY_HASH_FLAG) <= key_hash_rcvd;
|
||||
data_out_hc(SSI_PAYLOAD_FLAG) <= data_flag;
|
||||
data_out_hc(SSI_ALIGNED_FLAG) <= data_flag;
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Timestamp 1/2
|
||||
when 1 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= ts(0);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= ts(0);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Timestamp 2/2
|
||||
when 2 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= ts(1);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= ts(1);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Lifespan Deadline 1/2
|
||||
when 3 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= lifespan(0);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= lifespan(0);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Lifespan Deadline 2/2
|
||||
when 4 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= lifespan(1);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= lifespan(1);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
-- Skip Key Hash, if not received
|
||||
if (not WITH_KEY or key_hash_rcvd = '0') then
|
||||
cnt_next <= cnt + 5;
|
||||
@ -1196,46 +1210,46 @@ begin
|
||||
end if;
|
||||
-- Key hash 1/4
|
||||
when 5 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= key_hash(0);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= key_hash(0);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Key Hash 2/4
|
||||
when 6 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= key_hash(1);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= key_hash(1);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Key Hash 3/4
|
||||
when 7 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= key_hash(2);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= key_hash(2);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Key hash 4/4
|
||||
when 8 =>
|
||||
valid_out_dds <= '1';
|
||||
data_out_dds <= key_hash(3);
|
||||
valid_out_hc <= '1';
|
||||
data_out_hc <= key_hash(3);
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Endpoint Memory Position
|
||||
when 9 =>
|
||||
-- Wait for Endpoint Search
|
||||
if (mem_op_done = '1') then
|
||||
valid_out_dds <= '1';
|
||||
valid_out_hc <= '1';
|
||||
-- TODO: Assert mem_pos range fits in CDR_LONG
|
||||
data_out_dds <= std_logic_vector(to_unsigned(mem_pos, CDR_LONG_WIDTH));
|
||||
data_out_hc <= std_logic_vector(to_unsigned(mem_pos, CDR_LONG_WIDTH));
|
||||
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
-- NOTE: We only push the Payload if there is Data, or if the Key Hash was not received and we need to push
|
||||
-- the serialized Key.
|
||||
-- Payload exists
|
||||
@ -1243,7 +1257,7 @@ begin
|
||||
stage_next <= PUSH_PAYLOAD;
|
||||
else
|
||||
-- DONE
|
||||
last_word_out_dds <= '1';
|
||||
last_word_out_hc <= '1';
|
||||
stage_next <= FINALIZE_ADD_CACHE_CHANGE_REQUEST;
|
||||
end if;
|
||||
end if;
|
||||
@ -1254,13 +1268,13 @@ begin
|
||||
when PUSH_PAYLOAD =>
|
||||
-- Input Guard
|
||||
if (empty_user = '0') then
|
||||
valid_out_dds <= '1';
|
||||
valid_out_hc <= '1';
|
||||
-- Push Payload to History Cache
|
||||
data_out_dds <= data_in_user;
|
||||
last_word_out_dds <= last_word_in_user;
|
||||
data_out_hc <= data_in_user;
|
||||
last_word_out_hc <= last_word_in_user;
|
||||
|
||||
-- Output Guard
|
||||
if (ready_out_dds = '1') then
|
||||
if (ready_out_hc = '1') then
|
||||
rd_guard := '1';
|
||||
|
||||
-- Exit Condition
|
||||
@ -1273,7 +1287,7 @@ begin
|
||||
-- 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;
|
||||
-- Wait for History Cache Response
|
||||
if (res_dds /= UNDEFINED) then
|
||||
if (done_hc = '1') then
|
||||
|
||||
-- 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.
|
||||
@ -1281,7 +1295,7 @@ begin
|
||||
-- Update Endpoint
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= UPDATE_ENDPOINT;
|
||||
mem_field_flags <= LEASE_DEADLINE_FLAG;
|
||||
mem_field_flags <= EMF_LEASE_DEADLINE_FLAG;
|
||||
if (LEASE_DURATION /= DURATION_INFINITE) then
|
||||
lease_deadline <= time + LEASE_DURATION;
|
||||
|
||||
@ -1297,9 +1311,9 @@ begin
|
||||
-- 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 (res_dds = ACCEPTED) then
|
||||
if (ret_hc = OK) then
|
||||
-- Update also next sequence number
|
||||
mem_field_flags <= NEXT_SEQ_NR_FLAG or LEASE_DEADLINE_FLAG;
|
||||
mem_field_flags <= EMF_NEXT_SEQ_NR_FLAG or EMF_LEASE_DEADLINE_FLAG;
|
||||
end if;
|
||||
|
||||
-- DONE
|
||||
|
||||
@ -297,21 +297,15 @@ architecture arch of rtps_writer is
|
||||
alias header_opcode : std_logic_vector(7 downto 0) is data_in_user(31 downto 24);
|
||||
alias header_flags : std_logic_vector(7 downto 0) is data_in_user(23 downto 16);
|
||||
alias header_udp_port : std_logic_vector(15 downto 0) is data_in_user(15 downto 0);
|
||||
-- RTPS PARAMETER LIST HEADER
|
||||
alias parameter_id : std_logic_vector(15 downto 0) is data_in_user(31 downto 16);
|
||||
alias parameter_length : std_logic_vector(15 downto 0) is data_in_user(15 downto 0);
|
||||
alias must_understand : std_logic is parameter_id(14);
|
||||
-- RTPS DATA PAYLOAD HEADER
|
||||
alias representation_id : std_logic_vector(15 downto 0) is data_in_user(31 downto 16);
|
||||
alias representation_options : std_logic_vector(15 downto 0) is data_in_user(15 downto 0);
|
||||
-- RTPS SUBMESSAGE FLAGS
|
||||
alias endian_flag : std_logic is rtps_flags(0);
|
||||
alias qos_flag : std_logic is rtps_flags(1);
|
||||
alias data_flag : std_logic is rtps_flags(2);
|
||||
alias key_flag : std_logic is rtps_flags(3);
|
||||
alias final_flag : std_logic is rtps_flags(1);
|
||||
alias payload_flag : std_logic is rtps_flags(4);
|
||||
alias liveliness_flag : std_logic is rtps_flags(2);
|
||||
-- RTPS OUT DATA SUBMESSAGE FLAGS
|
||||
alias qos_flag : std_logic is data_out_rtps(17);
|
||||
alias data_flag : std_logic is data_out_rtps(18);
|
||||
alias key_flag : std_logic is data_out_rtps(19);
|
||||
alias payload_flag : std_logic is data_out_rtps(20);
|
||||
-- ACKNACK
|
||||
alias nack_base : SEQUENCENUMBER_TYPE is sn_latch_1;
|
||||
alias nack_base_next : SEQUENCENUMBER_TYPE is sn_latch_1_next;
|
||||
@ -362,9 +356,6 @@ begin
|
||||
data_out => mem_read_data
|
||||
);
|
||||
|
||||
-- Propagate Liveliness Assertion
|
||||
alive <= assert_liveliness when (LIVELINESS_QOS /= MANUAL_BY_TOPIC_LIVELINESS_QOS) else '0';
|
||||
|
||||
-- *Main State Machine*
|
||||
-- STATE DESCRIPTION
|
||||
-- IDLE Idle State. Initiates Stale Endpoint Checks, Metatraffic Packet Processing, and User Packet Processing, in that priority order.
|
||||
@ -438,7 +429,7 @@ begin
|
||||
assert_liveliness_latch_next<= assert_liveliness_latch;
|
||||
-- DEFAULT Unregistered
|
||||
mem_opcode <= NOP;
|
||||
opcode_hc <= ADD_CACHE_CHANGE;
|
||||
opcode_hc <= NOP;
|
||||
lease_deadline <= TIME_INVALID;
|
||||
res_time <= TIME_INVALID;
|
||||
rd_meta <= '0';
|
||||
@ -449,6 +440,7 @@ begin
|
||||
get_data_hc <= '0';
|
||||
wr_rtps <= '1';
|
||||
rd_guard := '0';
|
||||
alive <= '0';
|
||||
mem_field_flags <= (others => '0');
|
||||
data_out_dds <= (others => '0');
|
||||
|
||||
@ -471,12 +463,28 @@ begin
|
||||
|
||||
-- New Cache Change in HC
|
||||
if (data_available = '1') then
|
||||
-- Propagate Liveliness
|
||||
alive <= '1';
|
||||
|
||||
new_push_next <= '1';
|
||||
|
||||
stage_next <= GET_MAX_SN;
|
||||
cnt_next <= 0;
|
||||
-- Manual Liveliness Assertion
|
||||
elsif (LIVELINESS_QOS = MANUAL_BY_TOPIC_LIVELINESS_QOS and assert_liveliness_latch = '1') then
|
||||
-- Propagate Liveliness
|
||||
alive <= '1';
|
||||
|
||||
-- Reset
|
||||
heartbeat_time_next <= time + HEARTBEAT_PERIOD;
|
||||
|
||||
-- Increment Heartbeat Count
|
||||
count_next <= count + 1;
|
||||
|
||||
stage_next <= GET_MIN_SN;
|
||||
cnt_next <= 0;
|
||||
-- Heartbeat Timeout
|
||||
elsif ((RELIABILTY_QOS = RELIABLE_RELIABILITY_QOS and time >= heartbeat_time) or (LIVELINESS_QOS = MANUAL_BY_TOPIC_LIVELINESS_QOS and assert_liveliness_latch = '1')) then
|
||||
elsif (RELIABILTY_QOS = RELIABLE_RELIABILITY_QOS and time >= heartbeat_time) then
|
||||
-- Reset
|
||||
heartbeat_time_next <= time + HEARTBEAT_PERIOD;
|
||||
|
||||
@ -722,12 +730,6 @@ begin
|
||||
-- Ignore
|
||||
stage_next <= IDLE;
|
||||
else
|
||||
-- Propagate Removal
|
||||
start_hc <= '1';
|
||||
opcode_hc <= REMOVE_WRITER;
|
||||
data_out_dds <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH));
|
||||
-- Wait for Operation Acknowledgement
|
||||
if (res_hc = ACK) then
|
||||
-- Remove Unmatched Remote Endpoint
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= REMOVE_ENDPOINT;
|
||||
@ -742,7 +744,6 @@ begin
|
||||
stage_next <= IDLE;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
when OPCODE_PARTICIPANT_UNMATCH =>
|
||||
case (cnt) is
|
||||
when 0 =>
|
||||
@ -750,6 +751,8 @@ begin
|
||||
if (mem_addr_base = ENDPOINT_MEMORY_MAX_ADDRESS) then
|
||||
-- Global ACK SN possibly changed
|
||||
if (RELIABILTY_QOS = RELIABLE_RELIABILITY_QOS and global_ack_seq_nr_base /= SEQUENCENUMBER_UNKNOWN) then
|
||||
-- NOTE: We are triggering an Global ACK SN Update on each Participant Removal. This should not happen as often, and is therefore acceptable.
|
||||
-- Otherwise we need to check the ack_seq_nr_base in the other substate and mark when equal to current Global ACK SN.
|
||||
-- Update Global ACK
|
||||
stage_next <= UPDATE_GLOBAL_ACK;
|
||||
cnt_next <= 0;
|
||||
@ -770,6 +773,7 @@ begin
|
||||
-- Continue Search
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= GET_NEXT_ENDPOINT;
|
||||
mem_field_flags <= EMF_GUIDPREFIX_FLAG;
|
||||
cnt_next <= 0;
|
||||
when others =>
|
||||
null;
|
||||
@ -1333,7 +1337,7 @@ begin
|
||||
-- Wait until Operation Response
|
||||
if (done_hc = '1') then
|
||||
-- Wait for Operation Response
|
||||
if (ret_hc = ACK) then
|
||||
if (ret_hc = OK) then
|
||||
get_data_hc <= '1';
|
||||
if (gap_in_progress = '1') then
|
||||
-- Close GAP and send DATA
|
||||
@ -1384,7 +1388,7 @@ begin
|
||||
mem_opcode <= GET_NEXT_ENDPOINT;
|
||||
mem_field_flags <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG;
|
||||
cnt_next <= cnt + 1;
|
||||
-- Initiate Hertbeat Sending
|
||||
-- Initiate Heartbeat Sending
|
||||
when 2 =>
|
||||
-- End of Endpoint
|
||||
if (mem_addr_base = ENDPOINT_MEMORY_MAX_ADDRESS) then
|
||||
@ -1418,49 +1422,17 @@ begin
|
||||
last_seq_nr_next <= last_seq_nr + 1;
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- GET SN
|
||||
when 1 =>
|
||||
start_hc <= '1';
|
||||
opcode_hc <= GET_CACHE_CHANGE;
|
||||
seq_nr_hc <= last_seq_nr;
|
||||
|
||||
-- Wait until Operation Acknowledgement
|
||||
if (ack_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- READ SN
|
||||
when 2 =>
|
||||
-- Wait until Operation Response
|
||||
if (done_hc = '1') then
|
||||
-- Cache Change Available
|
||||
if (ret_hc = ACK) then
|
||||
cnt_next <= cnt + 1;
|
||||
-- Cache Change Unavailable
|
||||
else
|
||||
report "New Cache Change unavailable" severity ERROR;
|
||||
cnt_next <= 0;
|
||||
end if;
|
||||
end if;
|
||||
-- Get First Reader
|
||||
when 3 =>
|
||||
when 1 =>
|
||||
-- Memory Operation Guard
|
||||
if (mem_op_done = '1') then
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= GET_FIRST_ENDPOINT;
|
||||
mem_field_flags <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG;
|
||||
cnt_next <= cnt + 2;
|
||||
end if;
|
||||
-- Get Next Reader
|
||||
when 4 =>
|
||||
-- Memory Operation Guard
|
||||
if (mem_op_done = '1') then
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= GET_NEXT_ENDPOINT;
|
||||
mem_field_flags <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG;
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Initiate Send
|
||||
when 5 =>
|
||||
-- GET SN
|
||||
when 2 =>
|
||||
-- Wait for Endpoint Data
|
||||
if (mem_op_done = '1') then
|
||||
-- End of Endpoints
|
||||
@ -1484,11 +1456,46 @@ begin
|
||||
cnt_next <= 0;
|
||||
end if;
|
||||
else
|
||||
start_hc <= '1';
|
||||
opcode_hc <= GET_CACHE_CHANGE;
|
||||
seq_nr_hc <= last_seq_nr;
|
||||
|
||||
-- Wait until Operation Acknowledgement
|
||||
if (ack_hc = '1') then
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
-- READ SN
|
||||
when 3 =>
|
||||
-- Wait until Operation Response
|
||||
if (done_hc = '1') then
|
||||
-- Cache Change Available
|
||||
if (ret_hc = OK) then
|
||||
-- Only request Payload if necessary (Contains DATA or Serialized Key)
|
||||
if (cc_kind = ALIVE or (WITH_KEY and cc_kind /= ALIVE)) then
|
||||
get_data_hc <= '1';
|
||||
end if;
|
||||
|
||||
stage_next <= SEND_HEADER;
|
||||
return_stage_next <= SEND_DATA_A;
|
||||
return_stage_next <= SEND_INFO_TS when (DESTINATION_ORDER_QOS = BY_SOURCE_TIMESTAMP_DESTINATION_ORDER_QOS) else SEND_DATA_A;
|
||||
cnt_next <= 0;
|
||||
-- Cache Change Unavailable
|
||||
else
|
||||
report "New Cache Change unavailable" severity WARNING;
|
||||
cnt_next <= 0;
|
||||
end if;
|
||||
end if;
|
||||
-- Get Next Reader
|
||||
when 4 =>
|
||||
-- Memory Operation Guard
|
||||
if (mem_op_done = '1') then
|
||||
mem_op_start <= '1';
|
||||
mem_opcode <= GET_NEXT_ENDPOINT;
|
||||
mem_field_flags <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG;
|
||||
-- Loop
|
||||
cnt_next <= 2;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -1548,8 +1555,12 @@ begin
|
||||
-- Wait until Operation Response
|
||||
if (done_hc = '1') then
|
||||
-- Wait for Operation Response
|
||||
if (ret_hc = ACK) then
|
||||
if (ret_hc = OK) then
|
||||
-- Only request Payload if necessary (Contains DATA or Serialized Key)
|
||||
if (cc_kind = ALIVE or (WITH_KEY and cc_kind /= ALIVE)) then
|
||||
get_data_hc <= '1';
|
||||
end if;
|
||||
|
||||
if (gap_in_progress = '1') then
|
||||
-- Close GAP and send DATA
|
||||
gap_in_progress_next <= '0';
|
||||
@ -1658,16 +1669,10 @@ begin
|
||||
-- DATA RTPS SUBMESSAGE
|
||||
-- RTPS Submessage Header
|
||||
when 0 =>
|
||||
-- Operation has no Data
|
||||
if (cc_kind /= ALIVE) then
|
||||
-- Set KEY Flag
|
||||
data_out_rtps <= SID_DATA & "00001010" & std_logic_vector(to_unsigned(0, SUBMESSAGE_LENGTH_WIDTH));
|
||||
wr_sig <= '1';
|
||||
else
|
||||
-- Set DATA Flag
|
||||
data_out_rtps <= SID_DATA & "00000110" & std_logic_vector(to_unsigned(0, SUBMESSAGE_LENGTH_WIDTH));
|
||||
wr_sig <= '1';
|
||||
end if;
|
||||
data_out_rtps <= SID_DATA & "00000000" & std_logic_vector(to_unsigned(0, SUBMESSAGE_LENGTH_WIDTH));
|
||||
data_flag <= '1' when (cc_kind = ALIVE) else '0';
|
||||
key_flag <= '1' when (WITH_KEY and cc_kind /= ALIVE) else '0';
|
||||
qos_flag <= '1' when (cc_kind /= ALIVE or WITH_KEY or mem_endpoint_data.flags(EXPECTS_INLINE_QOS_FLAG) = '1') else '0';
|
||||
cnt_next <= cnt + 1;
|
||||
-- extraFlags, octetsToInlineQoS
|
||||
when 1 =>
|
||||
@ -1693,13 +1698,82 @@ begin
|
||||
when 5 =>
|
||||
data_out_rtps <= std_logic_vector(next_seq_nr(1));
|
||||
wr_sig <= '1';
|
||||
|
||||
-- Need to send Key Hash
|
||||
if (WITH_KEY) then
|
||||
cnt_next <= cnt + 1;
|
||||
-- Need to send Status Info
|
||||
elsif (cc_kind /= ALIVE) then
|
||||
cnt_next <= cnt + 5;
|
||||
-- Reader expect in-line QoS
|
||||
elsif(mem_endpoint_data.flags(EXPECTS_INLINE_QOS_FLAG) = '1') then
|
||||
stage_next <= SEND_INLINE_QOS;
|
||||
cnt3_next <= 0;
|
||||
-- Payload Available (DATA or Serialized Key)
|
||||
elsif (cc_kind = ALIVE or (WITH_KEY and cc_kind /= ALIVE)) then
|
||||
stage_next <= SEND_DATA_B;
|
||||
cnt_next <= 0;
|
||||
else
|
||||
-- Continue
|
||||
if (stale_check = '1') then
|
||||
stage_next <= HANDLE_REQUESTS;
|
||||
cnt_next <= 0;
|
||||
req_bitmap_pos_next <= req_bitmap_pos + 1;
|
||||
next_seq_nr_next <= next_seq_nr + 1;
|
||||
elsif (new_push = '1') then
|
||||
stage_next <= HANDLE_NEW;
|
||||
cnt_next <= 4;
|
||||
elsif (historical_push = '1') then
|
||||
stage_next <= HANDLE_HISTORICAL;
|
||||
cnt_next <= 0;
|
||||
else
|
||||
assert FALSE severity FAILURE;
|
||||
end if;
|
||||
end if;
|
||||
-- Key Hash 1/4
|
||||
when 6 =>
|
||||
-- Synthesis Guard
|
||||
if (WITH_KEY) then
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(0));
|
||||
wr_sig <= '1';
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Key Hash 2/4
|
||||
when 7 =>
|
||||
-- Synthesis Guard
|
||||
if (WITH_KEY) then
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(1));
|
||||
wr_sig <= '1';
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Key Hash 3/4
|
||||
when 8 =>
|
||||
-- Synthesis Guard
|
||||
if (WITH_KEY) then
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(2));
|
||||
wr_sig <= '1';
|
||||
cnt_next <= cnt + 1;
|
||||
end if;
|
||||
-- Key Hash 4/4
|
||||
when 9 =>
|
||||
-- Synthesis Guard
|
||||
if (WITH_KEY) then
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(3));
|
||||
wr_sig <= '1';
|
||||
|
||||
-- Need to send Status Info
|
||||
if (cc_kind /= ALIVE) then
|
||||
cnt_next <= cnt + 1;
|
||||
-- Reader expects in-line QoS
|
||||
elsif (mem_endpoint_data.flags(EXPECTS_INLINE_QOS_FLAG) = '1') then
|
||||
stage_next <= SEND_INLINE_QOS;
|
||||
cnt3_next <= 0;
|
||||
else
|
||||
cnt_next <= cnt + 2;
|
||||
end if;
|
||||
end if;
|
||||
-- Status Info
|
||||
when 6 =>
|
||||
when 10 =>
|
||||
data_out_rtps <= (others => '0');
|
||||
wr_sig <= '1';
|
||||
case (cc_kind) is
|
||||
@ -1712,26 +1786,8 @@ begin
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
cnt_next <= cnt + 1;
|
||||
-- Key Hash 1/4
|
||||
when 7 =>
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(0));
|
||||
wr_sig <= '1';
|
||||
cnt_next <= cnt + 1;
|
||||
-- Key Hash 2/4
|
||||
when 8 =>
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(1));
|
||||
wr_sig <= '1';
|
||||
cnt_next <= cnt + 1;
|
||||
-- Key Hash 3/4
|
||||
when 9 =>
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(2));
|
||||
wr_sig <= '1';
|
||||
cnt_next <= cnt + 1;
|
||||
-- Key Hash 4/4
|
||||
when 10 =>
|
||||
data_out_rtps <= std_logic_vector(cc_instance_handle(3));
|
||||
wr_sig <= '1';
|
||||
|
||||
-- Reader expects in-line QoS
|
||||
if (mem_endpoint_data.flags(EXPECTS_INLINE_QOS_FLAG) = '1') then
|
||||
stage_next <= SEND_INLINE_QOS;
|
||||
cnt3_next <= 0;
|
||||
@ -1742,7 +1798,27 @@ begin
|
||||
when 11 =>
|
||||
data_out_rtps <= PID_SENTINEL & std_logic_vector(to_unsigned(0, 16));
|
||||
wr_sig <= '1';
|
||||
|
||||
-- Payload Available (DATA or Serialized Key)
|
||||
if (cc_kind = ALIVE or (WITH_KEY and cc_kind /= ALIVE)) then
|
||||
stage_next <= SEND_DATA_B;
|
||||
else
|
||||
-- Continue
|
||||
if (stale_check = '1') then
|
||||
stage_next <= HANDLE_REQUESTS;
|
||||
cnt_next <= 0;
|
||||
req_bitmap_pos_next <= req_bitmap_pos + 1;
|
||||
next_seq_nr_next <= next_seq_nr + 1;
|
||||
elsif (new_push = '1') then
|
||||
stage_next <= HANDLE_NEW;
|
||||
cnt_next <= 4;
|
||||
elsif (historical_push = '1') then
|
||||
stage_next <= HANDLE_HISTORICAL;
|
||||
cnt_next <= 0;
|
||||
else
|
||||
assert FALSE severity FAILURE;
|
||||
end if;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
@ -1756,7 +1832,26 @@ begin
|
||||
|
||||
-- Exit Condition
|
||||
if (cnt3 = INLINE_QOS.length-1) then
|
||||
-- Payload Available (DATA or Serialized Key)
|
||||
if (cc_kind = ALIVE or (WITH_KEY and cc_kind /= ALIVE)) then
|
||||
stage_next <= SEND_DATA_B;
|
||||
else
|
||||
-- Continue
|
||||
if (stale_check = '1') then
|
||||
stage_next <= HANDLE_REQUESTS;
|
||||
cnt_next <= 0;
|
||||
req_bitmap_pos_next <= req_bitmap_pos + 1;
|
||||
next_seq_nr_next <= next_seq_nr + 1;
|
||||
elsif (new_push = '1') then
|
||||
stage_next <= HANDLE_NEW;
|
||||
cnt_next <= 4;
|
||||
elsif (historical_push = '1') then
|
||||
stage_next <= HANDLE_HISTORICAL;
|
||||
cnt_next <= 0;
|
||||
else
|
||||
assert FALSE severity FAILURE;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
when SEND_DATA_B =>
|
||||
@ -1958,6 +2053,7 @@ begin
|
||||
-- FIND_EMPTY_SLOT Find first empty_user slot in memory.
|
||||
-- RESET_MAX_POINTER Reset the max_endpoint_addr pointer to last occupied slot in memory.
|
||||
-- GET_NEXT_ENDPOINT See Memory OPCODE Description
|
||||
-- RESET_MEMORY Reset Endpoint Memory to Empty State
|
||||
mem_ctrl_prc : process(all)
|
||||
begin
|
||||
-- DEFAULT Registered
|
||||
|
||||
Loading…
Reference in New Issue
Block a user