Redo Blind Implementation of READER side (RTPS Endpoint & History Cache)

Redefined Sample Memory Format. The design decision was made to handle
most (if not all) of the DDS QOS inside the History Cache, which allows
storing needed information in a more efiicient way.
A (dual port) Instance Memory was added into the HC, to support the QOS
operations.
This commit only implements the A side processes for the READER case.
RESOURCE_LIMITS_QOS, TIME_BASED_FILTER_QOS, and HISTORY_QOS are handled.
The inter-entity communication was changed to allow the HC to mark
parsed changes as rejected, and allow future re-transmission (in the
case of Reliable communication).
This commit is contained in:
Greek 2021-01-16 18:22:36 +01:00
parent d2f466d588
commit 7e84a15d54
6 changed files with 1591 additions and 508 deletions

View File

@ -340,41 +340,33 @@ READER
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
00| STATUS_INFO |
00| STATUS_INFO | {A/B}
+-------------------------------------------------------------+
01| |
+ +
02| |
+ KEY_HASH +
+ KEY_HASH + {A}
03| |
+ +
04| |
+-------------------------------------------------------------+
05| ENTITYID |
+-------------------------------------------------------------+
05| |
+ TIMESTAMP + {A}
06| |
+ +
07| GUIDPREFIX |
+ +
+-------------------------------------------------------------+
07| |
+ LIFESPAN_DEADLINE + {A}
08| |
+-------------------------------------------------------------+
09| |
+ SEQUENCE_NUMBER +
10| |
09| PAYLOAD_ADDRESS | {A}
+-------------------------------------------------------------+
11| |
+ TIMESTAMP +
12| |
10| DISPOSED_GENERATION_COUNT | {A} [only GENERATION_COUNTERS]
+-------------------------------------------------------------+
13| |
+ LIFESPAN_DEADLINE +
14| |
11| NO_WRITERS_GENERATION_COUNT | {A} [only GENERATION_COUNTERS]
+-------------------------------------------------------------+
15| PAYLOAD_ADDRESS |
12| PREV_ADDRESS | {A}
+-------------------------------------------------------------+
16| PREV_ADDRESS |
+-------------------------------------------------------------+
17| NEXT_ADDRESS |
13| NEXT_ADDRESS | {A/B}
+-------------------------------------------------------------+
@ -383,12 +375,12 @@ STATUS INFO
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-------------------------------------------------+-+-+-+
|R|K|P| UNUSED |F|U|D|
|R|P|K| UNUSED |F|U|D|
+-+-+-+-------------------------------------------------+-+-+-+
R...Sample has been Read
K...Key Hash available
P...Sample has associated Payload
K...Key Hash available
F...FilteredFlag
U...UnregisteredFlag
@ -398,9 +390,9 @@ PAYLOAD MEMORY
==============
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-----------------------------------------------------------+-+
00| NEXT_ADDRESS |O|
+-----------------------------------------------------------+-+
+-------------------------------------------------------------+
00| NEXT_ADDRESS |
+-------------------------------------------------------------+
01| |
~ PAYLOAD ~
**| |
@ -421,31 +413,67 @@ HISTORY CACHE INPUT
+ +
04| |
+-------------------------------------------------------------+
05| ENTITYID |
+-------------------------------------------------------------+
05| |
+ TIMESTAMP +
06| |
+ +
07| GUIDPREFIX |
+ +
+-------------------------------------------------------------+
07| |
+ LIFESPAN_DEADLINE +
08| |
+-------------------------------------------------------------+
09| |
+ SEQUENCE_NUMBER +
09| ENDPOINT_POSITION |
+-------------------------------------------------------------+
10| |
+-------------------------------------------------------------+
11| |
+ TIMESTAMP +
12| |
+-------------------------------------------------------------+
13| |
+ LIFESPAN_DEADLINE +
14| |
+-------------------------------------------------------------+
15| |
~ PAYLOAD ~
**| |
+-------------------------------------------------------------+
INSTANCE MEMORY
===============
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
00| NEXT_ADDRESS | {A/B}
+-------------------------------------------------------------+
01| |
+ +
02| |
+ KEY_HASH + {A}
03| |
+ +
04| |
+-------------------------------------------------------------+
05| STATUS_INFO | {A/B}
+-------------------------------------------------------------+
06| SAMPLE_COUNT | {A/B} [only MAX_SAMPLES_PER_INSTANCE/HISTORY]
+-------------------------------------------------------------+
07| DISPOSED_GENERATION_COUNT | {A} [only GENERATION_COUNTERS]
+-------------------------------------------------------------+
08| NO_WRITERS_GENERATION_COUNT | {A} [only GENERATION_COUNTERS]
+-------------------------------------------------------------+
09| |
+ IGNORE_DEADLINE + {A} [only TIME_BASED_FILTER]
10| |
+-------------------------------------------------------------+
11| |
~ WRITER_BITMAP ~ {A}
**| |
+-------------------------------------------------------------+
STATUS INFO
-----------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-----------------------------------------------------+-+-+-+-+
| UNUSED |V|L|W|D|
+-----------------------------------------------------+-+-+-+-+
D...NOT_ALIVE_DISPOSED
W...NOT_ALIVE_NO_WRITERS
L...LIVELINESS FLAG
V...VIEW STATE
OUTPUT DATA
===========

View File

@ -95,6 +95,8 @@
'This Submessage is invalid when the following is true:
submessageLength in the Submessage header is too small'
But if InvalidateFlag is set, Length can be Zero. Since the length is unsigned, there cannot be an invalid length.
- 8.7.3.2 Indicating to a Reader that a Sample has been filtered
Text refs 8.3.7.2.2 for DataFlag, but shoudl also ref 8.7.4 for FilteredFlag
- 9.4.5.1.2 Flags
Clarify from where the endianness begins.
One might think it would begin after the Submessage Header, but the length is also endian dependent.

File diff suppressed because it is too large Load Diff

View File

@ -51,15 +51,22 @@ package rtps_config_package is
type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE);
type KEY_GENERATOR_OPCODE_TYPE is (NOP, WRITE_PAYLOAD, READ_KEY, READ_SIZE);
type HISTORY_CACHE_RESPOSNE_TYPE is (UNDEFINED, ACK, ACCEPTED, REJECTED);
type INSTANCE_STATE_TYPE is (ALIVE, NOT_ALIVE_DISPOSED, NOT_ALIVE_NO_WRITERS);
-- Status Info Flags
-- Sample Status Info Flags
constant DISPOSED_FLAG : natural := 0;
constant UNREGISTERED_FLAG : natural := 1;
constant FILTERED_FLAG : natural := 2;
constant PAYLOAD_FLAG : natural := 29;
constant KEY_HASH_FLAG : natural := 30;
constant KEY_HASH_FLAG : natural := 29;
constant PAYLOAD_FLAG : natural := 30;
constant READ_FLAG : natural := 31;
constant NOT_ALIVE_DISPOSED_FLAG : natural := 0;
constant NOT_ALIVE_NO_WRITERS_FLAG : natural := 1;
constant LIVELINESS_FLAG : natural := 2;
constant VIEW_FLAG : natural := 3;
-- Marks the Reader Endpoint in the Endpoint Array
constant ENDPOINT_READERS : std_logic_vector(0 to NUM_ENDPOINTS-1) := (0 to NUM_READERS-1 => '1', others => '0');
@ -106,6 +113,12 @@ package rtps_config_package is
type RTPS_OUT_DATA_TYPE is array (0 to NUM_ENDPOINTS) of std_logic_vector(WORD_WIDTH-1 downto 0);
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);
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;
-- Swap "data" to Big Endian representation.
function endian_swap(swap : std_logic; data : std_logic_vector) return std_logic_vector;
function endian_swap(swap : std_logic; data : unsigned) return unsigned;
@ -1053,4 +1066,22 @@ package body rtps_config_package is
return ret;
end function;
function to_endpoint_bitmap (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
ret(i*WORD_WIDTH to ((i+1)*WORD_WIDTH)-1) := input(i);
end loop;
return ret;
end function;
function from_endpoint_bitmap (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
ret(i) := input(i*WORD_WIDTH to ((i+1)*WORD_WIDTH)-1);
end loop;
return ret;
end function;
end package body;

View File

@ -10,7 +10,9 @@ use work.rtps_config_package.all;
-- TODO: Check for special values of time/duration?
-- TODO: Remove last_word flag from metattraffic operations
-- TODO: Replace all ('range => 0) checks with defined constants, where possible
-- TODO: Remove highest_seq_nr in stand alone git commit
-- TODO: Adding LIFESPAN Duration in the stored Endpoint Metatraffic Data would allow us to not expect in-line QoS (Which could be a significant overhead)
-- TODO: Is mem_addr_base needed? Isn't it a direct mirror of addr_mem_base? mem_addr_base is only used in the same clock cycle as mem_op_done is pulled high.
entity rtps_endpoint is
generic (
@ -38,11 +40,13 @@ entity rtps_endpoint is
hc_start : out std_logic;
hc_opcode : out HISTORY_CACHE_OPCODE_TYPE;
hc_ack : in std_logic;
hc_res : in HISTORY_CACHE_RESPOSNE_TYPE;
hc_data_out : in std_logic_vector(WORD_WIDTH-1 downto 0);
hc_valid_out : in std_logic;
hc_ready_out : out std_logic;
hc_last_word_out: in std_logic;
hc_data_in : out std_logic_vector(WORD_WIDTH-1 downto 0);
hc_valid_in : out std_logic;
hc_ready_in : in std_logic;
@ -54,27 +58,26 @@ architecture arch of rtps_endpoint is
--*****CONSTANT DECLARATION*****
-- Endpoint Memory Size in 4-Byte Words
constant ENDPOINT_MEMORY_SIZE : natural := TODO;
constant ENDPOINT_MEMORY_SIZE : natural := TODO;
-- Endpoint Memory Address Width
constant ENDPOINT_MEMORY_WIDTH : natural := log2c(ENDPOINT_MEMORY_SIZE);
constant ENDPOINT_MEMORY_ADDR_WIDTH : natural := log2c(ENDPOINT_MEMORY_SIZE);
-- Highest Memory Address
constant MAX_ADDRESS : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := to_unsigned(ENDPOINT_MEMORY_SIZE-1, ENDPOINT_MEMORY_WIDTH);
constant MAX_ADDRESS : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := to_unsigned(ENDPOINT_MEMORY_SIZE-1, ENDPOINT_MEMORY_ADDR_WIDTH);
-- Highest Endpoint Frame Address
constant MAX_ENDPOINT_ADDRESS : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := MAX_ADDRESS - ENDPOINT_FRAME_SIZE + 1;
constant MAX_ENDPOINT_ADDRESS : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := MAX_ADDRESS - ENDPOINT_FRAME_SIZE + 1;
-- Address pointing to the beginning of the first Endpoint Data Frame
constant FIRST_ENDPOINT_ADDRESS : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := (others => '0');
constant FIRST_ENDPOINT_ADDRESS : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
-- *UPDATE PARTICIPANT FLAG POSITIONS*
constant UPDATE_ENDPOINT_FLAG_WIDTH : natural := 4;
-- Signifies that the main Endpoint Data are updated
constant ENDPOINT_DATA_FLAG : std_logic_vector(UPDATE_ENDPOINT_FLAG_WIDTH-1 downto 0) := (0 => 1, others => '0');
constant ENDPOINT_DATA_FLAG : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1) := (0 => 1, others => '0');
-- Signifies that the Lease Deadline of the Endpoint Data is updated
constant LEASE_DEADLINE_FLAG : std_logic_vector(UPDATE_ENDPOINT_FLAG_WIDTH-1 downto 0) := (1 => 1, others => '0');
constant LEASE_DEADLINE_FLAG : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1) := (1 => 1, others => '0');
-- Signifies that the last Sequence Number of the Endpoint Data is updated
constant NEXT_SEQ_NR_FLAG : std_logic_vector(UPDATE_ENDPOINT_FLAG_WIDTH-1 downto 0) := (2 => 1, others => '0');
constant NEXT_SEQ_NR_FLAG : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1) := (2 => 1, others => '0');
-- Signifies that the HEARTBEAT/ACKNACK Timeout Time of the Endpoint Data is updated
constant RES_TIME_FLAG : std_logic_vector(UPDATE_ENDPOINT_FLAG_WIDTH-1 downto 0) := (3 => 1, others => '0');
constant BITMAP_BLOCK_SIZE : natural := 16;
constant RES_TIME_FLAG : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1) := (3 => 1, others => '0');
--*****TYPE DECLARATION*****
-- FSM states. Explained below in detail
@ -106,8 +109,7 @@ architecture arch of rtps_endpoint is
expects_inline_qos : std_logic;
deadline : TIME_TYPE;
next_seq_nr : SEQUENCENUMBER_TYPE;
update_flags : std_logic_vector(UPDATE_ENDPOINT_FLAG_WIDTH-1 downto 0);
mem_opcode : MEM_OPCODE_TYPE;
update_flags : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1);
end record;
constant ZERO_MEM_CTRL_DATA : MEM_CTRL_DATA_TYPE := (
guid => (others => (others => '0')),
@ -117,7 +119,6 @@ architecture arch of rtps_endpoint is
deadline => TIME_INVALID,
next_seq_nr => SEQUENCENUMBER_UNKNOWN,
update_flags => (others => '0'),
mem_opcode => IDLE
);
@ -134,7 +135,7 @@ architecture arch of rtps_endpoint is
signal portn, portn_next : std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := (others => '0');
signal expects_inline_qos, expects_inline_qos_next : std_logic := '0';
signal is_meta, is_meta_next : std_logic := '0';
signal update_endpoint_flags : std_logic_vector(UPDATE_ENDPOINT_FLAG_WIDTH-1 downto 0) := (others => '0');
signal update_endpoint_flags : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1) := (others => '0');
signal opcode, opcode_next : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := (others => '0');
signal flags, flags_next : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0) := (others => '0');
signal seq_nr, seq_nr_next : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
@ -165,16 +166,18 @@ architecture arch of rtps_endpoint is
signal mem_stage, mem_stage_next : MEM_STAGE_TYPE := IDLE;
signal mem_wr, mem_rd : std_logic := '0';
signal mem_wr_data, mem_rd_data : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0');
signal mem_addr, mem_addr_next : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := (others => '0');
signal mem_addr_base, mem_addr_base_next : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := (others => '0');
signal addr_res, addr_res_next : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := (others => '0');
signal last_addr, last_addr_next : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := (others => '0');
signal max_endpoint_addr, max_endpoint_addr_next : unsigned(ENDPOINT_MEMORY_WIDTH-1 downto 0) := (others => '0');
signal mem_addr, mem_addr_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
signal mem_addr_base, mem_addr_base_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
signal mem_addr_base, mem_addr_base_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
signal last_addr, last_addr_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
signal max_endpoint_addr, max_endpoint_addr_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
signal mem_cnt, mem_cnt_next : natural range TODO := 0;
signal mem_endpoint_data, mem_endpoint_data_next : ENDPOINT_DATA_TYPE := ZERO_ENDPOINT_DATA;
signal reset_max_pointer, reset_max_pointer_next : std_logic := '0';
signal mem_long_latch, mem_long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0');
signal mem_ctrl_data, mem_ctrl_data_next : MEM_CTRL_DATA_TYPE := ZERO_MEM_CTRL_DATA;
signal mem_pos, mem_pos_next : natural range TODO := 0;
signal is_psearch, is_psearch_next : std_logic := '0';
signal stale_check, stale_check_next : std_logic := '0';
signal count, count_next : unsigned(COUNT_WIDTH-1 downto 0) := (others => '0');
@ -227,7 +230,7 @@ begin
--*****COMPONENT INSTANTIATION*****
ram_inst : single_port_ram
generic map (
ADDR_WIDTH => ENDPOINT_MEMORY_WIDTH,
ADDR_WIDTH => ENDPOINT_MEMORY_ADDR_WIDTH,
DATA_WIDTH => WORD_WIDTH,
MEMORY_DEPTH => ENDPOINT_MEMORY_SIZE
)
@ -386,7 +389,7 @@ begin
if (is_meta = '1' and (meta_opcode = OPCODE_PARTICIPANT_UNMATCH or meta_opcode = OPCODE_LIVELINESS_UPDATE)) then
-- DONE Parsing
stage_next <= METATRAFFIC_OPERATION;
stage_next <= INITIATE_ENDPOINT_SEARCH;
else
stage_next <= LATCH_ENTITYID;
end if;
@ -398,19 +401,57 @@ begin
if (is_meta = '1') then
meta_rd <= '1';
guid_next(3) <= meta_data_in;
if (mem_opcode = OPCODE_ENDPOINT_MATCH) then
stage_next <= LATCH_ENDPOINT_DATA;
cnt_next <= 0;
else
stage_next <= METATRAFFIC_OPERATION;
end if;
-- Memory Operation Guard
else
rd_guard := '1';
guid_next(3) <= data_in;
end if;
stage_next <= INITIATE_ENDPOINT_SEARCH;
end if;
when INITIATE_ENDPOINT_SEARCH =>
-- Memory Operation Guard
if (mem_op_done = '1') then
if (is_meta = '1') then
stage_next <= INITIATE_ENDPOINT_SEARCH;
case (meta_opcode) is
when OPCODE_ENDPOINT_MATCH =>
mem_op_start <= '1';
mem_opcode <= SEARCH_ENDPOINT;
stage_next <= LATCH_ENDPOINT_DATA;
when OPCODE_ENDPOINT_UNMATCH =>
mem_op_start <= '1';
mem_opcode <= SEARCH_ENDPOINT;
stage_next <= METATRAFFIC_OPERATION;
when OPCODE_PARTICIPANT_UNMATCH =>
mem_op_start <= '1';
mem_opcode <= FIND_FIRST_PARTICIPANT_ENDPOINT;
stage_next <= METATRAFFIC_OPERATION;
when OPCODE_LIVELINESS_UPDATE =>
mem_op_start <= '1';
mem_opcode <= FIND_FIRST_PARTICIPANT_ENDPOINT;
stage_next <= METATRAFFIC_OPERATION;
when others =>
assert FALSE report "Uknown metatraffic endpoint frame opcode." severity FAILURE;
null;
end case;
else
mem_op_start <= '1';
mem_opcode <= SEARCH_ENDPOINT;
case (opcode) is
when SID_DATA =>
stage_next <= LATCH_EXTRA_DATA;
cnt_next <= 0;
when SID_HEARTBEAT =>
stage_next <= LATCH_HEARTBEAT;
cnt_next <= 0;
when SID_GAP =>
stage_next <= LATCH_GAP;
cnt_next <= 0;
when others =>
stage_next <= SKIP_PACKET;
end case;
end if;
end if;
when LATCH_ENDPOINT_DATA =>
@ -441,28 +482,76 @@ begin
case (meta_opcode) is
when OPCODE_ENDPOINT_MATCH =>
-- Insert Matched Remote Endpoint
-- NOTE: The Lease Duration is NOT updated in case of an update. That is the responsibility of the Liveliness Update
update_endpoint_flags <= ENDPOINT_DATA_FLAG; -- In case the Endpoint is already in the memory, we update the data
mem_opcode <= INSERT_ENDPOINT;
mem_op_start <= '1';
stage_next <= IDLE;
-- Endpoint already in Memory
if (mem_addr_base /= MAX_ADDRESS) then
-- Update the Endpoint Data
-- NOTE: The Lease Duration is NOT updated in case of an update. That is the responsibility of the Liveliness Update
update_endpoint_flags <= ENDPOINT_DATA_FLAG;
mem_opcode <= UDPATE_ENDPOINT;
mem_op_start <= '1';
stage_next <= IDLE;
else
-- Insert Matched Remote Endpoint
mem_opcode <= INSERT_ENDPOINT;
mem_op_start <= '1';
stage_next <= IDLE;
end if;
when OPCODE_ENDPOINT_UNMATCH =>
-- Remove Unmatched Remote Endpoint
mem_opcode <= REMOVE_ENDPOINT;
mem_op_start <= '1';
stage_next <= IDLE;
-- Endpoint not in Memory
if (mem_addr_base = MAX_ADDRESS) then
-- Ignore
stage_next <= IDLE;
else
-- Output Guard
if (hc_ready_in = '1') then
-- Propagate Removal
hc_start <= '1';
hc_opcode <= REMOVE_WRITER;
hc_valid_in <= '1';
hc_data_in <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH));
-- Wait until HC Acknowledgement
if (hc_res = ACK) then
-- Remove Unmatched Remote Endpoint
mem_opcode <= REMOVE_ENDPOINT;
mem_op_start <= '1';
stage_next <= IDLE;
end if;
end if;
end if;
when OPCODE_PARTICIPANT_UNMATCH =>
-- Remove All Endpoint of Remote Participant
mem_opcode <= REMOVE_PARTICIPANT;
mem_op_start <= '1';
stage_next <= IDLE;
-- No matches in memory
if (mem_addr_base = MAX_ADDRESS) then
-- DONE
stage_next <= IDLE;
else
-- Output Guard
if (hc_ready_in = '1') then
-- Propagate Removal
hc_start <= '1';
hc_opcode <= REMOVE_WRITER;
hc_valid_in <= '1';
hc_data_in <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH));
-- Wait until HC Acknowledgement
if (hc_res = ACK) then
-- Remove Unmatched Remote Endpoint
mem_opcode <= REMOVE_ENDPOINT;
mem_op_start <= '1';
stage_next <= INITIATE_NEXT_ENDPOINT_SEARCH;
end if;
end if;
end if;
when OPCODE_LIVELINESS_UPDATE =>
-- Renew Lease of Remote Endpoint
update_endpoint_flags <= LEASE_DEADLINE_FLAG;
mem_opcode <= UDPATE_ENDPOINT;
mem_op_start <= '1';
stage_next <= IDLE;
-- No matches in memory
if (mem_addr_base = MAX_ADDRESS) then
-- DONE
stage_next <= IDLE;
else
-- Renew Lease of Remote Endpoint
update_endpoint_flags <= LEASE_DEADLINE_FLAG;
mem_opcode <= UDPATE_ENDPOINT;
mem_op_start <= '1';
stage_next <= INITIATE_NEXT_ENDPOINT_SEARCH;
end if;
when others =>
assert FALSE report "Uknown metatraffic endpoint frame opcode." severity FAILURE;
null;
@ -470,6 +559,13 @@ begin
-- DONE
stage_next <= SKIP_PACKET;
end if;
when INITIATE_NEXT_ENDPOINT_SEARCH =>
-- Memory Operation Guard
if (mem_op_done = '1') then
mem_opcode <= FIND_NEXT_PARTICIPANT_ENDPOINT;
mem_op_start <= '1';
stage_next <= METATRAFFIC_OPERATION;
end if;
when LATCH_SRC_ADDR =>
-- Input FIFO Guard
if (empty = '0') then
@ -481,26 +577,6 @@ begin
stage_next <= LATCH_GUIDPREFIX;
cnt_next <= 0;
end if;
when INITIATE_ENDPOINT_SEARCH =>
-- Memory Operation Guard
if (mem_op_done = '1') then
mem_op_start <= '1';
mem_opcode <= SEARCH_ENDPOINT;
case (opcode) is
when SID_DATA =>
stage_next <= LATCH_EXTRA_DATA;
cnt_next <= 0;
when SID_HEARTBEAT =>
stage_next <= LATCH_HEARTBEAT;
cnt_next <= 0;
when SID_GAP =>
stage_next <= LATCH_GAP;
cnt_next <= 0;
when others =>
stage_next <= SKIP_PACKET;
end case;
end if;
when LATCH_EXTRA_DATA =>
-- Input FIFO Guard
if (empty = '0') then
@ -515,7 +591,7 @@ begin
when 1 =>
seq_nr_next(1) <= unsigned(data_in);
-- Store Next Sequence Number
tmp_dw := (0 => seq_nr(0), 1 => unsigned(data_in_swapped));
tmp_dw := (0 => seq_nr(0), 1 => unsigned(data_in));
next_seq_nr_next <= tmp_dw + 1;
-- Timestamp 1/2
when 2 =>
@ -565,7 +641,7 @@ begin
stage_next <= SKIP_PACKET;
-- Endpoint in Buffer
if (addr_res /= MAX_ADDRESS) then
if (mem_addr_base /= MAX_ADDRESS) then
-- No scheduled Heartbeat Response
if (mem_endpoint_data.res_time = 0) then
-- If current Sequence Number obsolete (removed from source history cache)
@ -651,7 +727,7 @@ begin
stage_next <= SKIP_PACKET;
-- Known Remote Endpoint
if (addr_res /= MAX_ADDRESS) then
if (mem_addr_base /= MAX_ADDRESS) then
-- GAP is relevant
if (gap_start <= mem_endpoint_data.next_seq_nr and mem_endpoint_data.next_seq_nr <= gap_list_end) then
-- Next Expected is in GAP List
@ -794,10 +870,15 @@ begin
case (cnt) is
-- Lifespan 1/2
when 0 =>
deadline_next(0) <= unsigned(data_in_swapped);
-- NOTE: We are misusing the sn_latch_1 as temporal CDR_LONG storage
sn_latch_1_next(0) <= unsigned(data_in_swapped);
-- Lifespan 2/2
when 1 =>
deadline_next(1) <= unsigned(data_in_swapped);
tmp_dw := (0 => sn_latch_1(0), 1 => unsigned(data_in_swapped));
-- TODO: Use source timestamp if clocks with remote synchronized
-- Calculate Sample Lifespan Deadline
deadline_next <= time + tmp_dw;
-- DONE
stage_next <= SKIP_PARAMETER;
@ -845,7 +926,7 @@ begin
hc_start <= '1';
hc_opcode <= ADD_CACHE_CHANGE;
-- Wait until History Cache acknowledges request
if (hc_ack = '1') then
if (hc_res = ACK) then
stage_next <= ADD_CACHE_CHANGE;
cnt_next <= 0;
end if;
@ -872,51 +953,38 @@ begin
-- Key hash 4/4
when 4 =>
hc_data_in <= key_hash(3);
-- Entity ID
when 5 =>
hc_data_in <= guid(3);
-- GUID Prefix 1/3
when 6 =>
hc_data_in <= guid(0);
-- GUID Prefix 2/3
when 7 =>
hc_data_in <= guid(1);
-- GUID Prefix 3/3
when 8 =>
hc_data_in <= guid(2);
-- Sequence Number 1/2
when 9 =>
hc_data_in <= seq_nr(0);
-- Sequence Number 2/2
when 10 =>
hc_data_in <= seq_nr(1);
-- Timestamp 1/2
when 11 =>
when 5 =>
hc_data_in <= ts(0);
-- Timestamp 2/2
when 12 =>
when 6 =>
hc_data_in <= ts(1);
-- Lifespan Deadline 1/2
when 13 =>
when 7 =>
hc_data_in <= deadline(0);
-- Lifespan Deadline 2/2
when 14 =>
when 8 =>
hc_data_in <= deadline(1);
-- Payload exists
if (data_flag = '1' or key_flag = '1') then
stage_next <= PUSH_PAYLOAD;
else
-- DONE
hc_last_word_in <= '1';
-- Endpoint Memory Position
when 9 =>
-- Wait for Endpoint Search
if (mem_op_done = '1') then
-- Operation Sucessfull
if (hc_ack = '1') then
stage_next <= FINALIZE_HISTORY_CACHE_REQUEST;
-- TODO: Assert mem_pos range fits in CDR_LONG
hc_data_in <= std_logic_vector(to_unsigned(mem_pos, CDR_LONG_WIDTH));
-- Payload exists
if (data_flag = '1' or key_flag = '1') then
stage_next <= PUSH_PAYLOAD;
else
-- Operation Failed, Skip
stage_next <= SKIP_PACKET;
-- DONE
hc_last_word_in <= '1';
stage_next <= FINALIZE_HISTORY_CACHE_REQUEST;
end if;
else
-- Keep State
hc_valid_in <= '0';
cnt_next <= cnt;
end if;
when others =>
null;
@ -933,34 +1001,33 @@ begin
-- Exit Condition
if (last_word_in = '1') then
hc_last_word_in <= '1';
-- XXX: Possible worst case path (The hc_ack is set from last_word signal -> round trip delay between entities)
-- Change Add Sucessfull
if (hc_ack = '1') then
-- Update Endpoint Data
stage_next <= FINALIZE_HISTORY_CACHE_REQUEST;
else
-- Operation Failed, Skip
stage_next <= SKIP_PACKET;
end if;
hc_last_word_in <= '1';
stage_next <= FINALIZE_HISTORY_CACHE_REQUEST;
end if;
end if;
when FINALIZE_HISTORY_CACHE_REQUEST =>
-- Memory Operation Guard
if (mem_op_done = '1') then
-- Update next sequence number and renew Lease
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
deadline_next <= time + ENDPOINT_LEASE_DURATION(ID);
update_endpoint_flags <= NEXT_SEQ_NR_FLAG or LEASE_DEADLINE_FLAG;
-- NOTE: Memory is already in done state from previous state (ADD_CACHE_CHANGE)
assert (mem_op_done = '1') report "FINALIZE_HISTORY_CACHE_REQUEST precondition not met. mem_op_done /= '1'" severity FAILURE;
-- Wai for History Cache Response
if (hc_res /= UNDEFINED) then
-- Operation was Accepted
if (hc_res = ACCEPTED) then
-- Update next sequence number and renew Lease
mem_op_start <= '1';
mem_opcode <= UPDATE_ENDPOINT;
deadline_next <= time + ENDPOINT_LEASE_DURATION(ID);
update_endpoint_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;
stage_next <= SKIP_PACKET;
end if;
when ENDPOINT_STALE_CHECK =>
-- Wait for Stale Search to finish
if (mem_op_done = '1') then
-- Found Stale Entry
if (addr_res /= MAX_ADDRESS) then
if (mem_addr_base /= MAX_ADDRESS) then
-- Endpoint Lease Expired
-- NOTE: The mem_endpoint_data is zero initialized on lease expiration, so we check if the address is set
if (mem_endpoint_data.addr = IPv4_ADDRESS_INVALID) then
@ -1169,7 +1236,6 @@ begin
mem_stage_next <= mem_stage;
mem_addr_base_next <= mem_addr_base;
mem_addr_next <= mem_addr;
addr_res_next <= addr_res;
mem_cnt_next <= mem_cnt;
last_addr_next <= last_addr;
mem_endpoint_data_next <= mem_endpoint_data;
@ -1178,6 +1244,7 @@ begin
reset_max_pointer_next <= reset_max_pointer;
mem_long_latch_next <= mem_long_latch;
mem_ctrl_data_next <= mem_ctrl_data;
mem_pos_next <= mem_pos;
-- DEFAULT Unregistered
mem_write_data <= (others => '0');
mem_op_done <= '0';
@ -1189,6 +1256,7 @@ begin
when IDLE =>
mem_op_done <= '1';
reset_max_pointer_next <= '0';
is_psearch_next <= '0';
if (mem_op_start = '1') then
-- Latch Signals needed for Mermory Operation (Use _next signals, because some signals are set in same clk)
@ -1199,70 +1267,89 @@ begin
expects_inline_qos => expects_inline_qos_next,
deadline => deadline_next,
next_seq_nr => next_seq_nr_next,
update_flags => update_endpoint_flags_next,
mem_opcode => mem_opcode_next
update_flags => update_endpoint_flags_next
);
case(mem_opcode) is
when SEARCH_ENDPOINT =>
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_pos_next <= 0;
mem_stage_next <= SEARCH_ENDPOINT;
mem_cnt_next <= 0;
when INSERT_ENDPOINT =>
-- NOTE: First check if Endpoint is already inserted. If yes, just update the data.
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_stage_next <= SEARCH_ENDPOINT;
mem_pos_next <= 0;
mem_stage_next <= FIND_ENDPOINT_SLOT;
mem_cnt_next <= 0;
when UPDATE_ENDPOINT =>
if ((update_endpoint_flags and ENDPOINT_DATA_FLAG) = ENDPOINT_DATA_FLAG) then
mem_stage_next <= UPDATE_ENDPOINT;
mem_addr_next <= addr_res + 4;
mem_addr_next <= mem_addr_base + 4;
mem_cnt_next <= 0;
elsif ((update_endpoint_flags and LEASE_DEADLINE_FLAG) = LEASE_DEADLINE_FLAG) then
mem_stage_next <= UPDATE_ENDPPOINT;
mem_addr_next <= addr_res + 6;
mem_addr_next <= mem_addr_base + 6;
mem_cnt_next <= 2;
elsif ((update_endpoint_flags and RES_TIME_FLAG) = RES_TIME_FLAG) then
mem_stage_next <= UPDATE_ENDPOINT;
mem_addr_next <= addr_res + 8;
mem_addr_next <= mem_addr_base + 8;
mem_cnt_next <= 4;
elsif ((update_endpoint_flags and NEXT_SEQ_NR_FLAG) = NEXT_SEQ_NR_FLAG) then
mem_stage_next <= UPDATE_ENDPOINT;
mem_addr_next <= addr_res + 10;
mem_addr_next <= mem_addr_base + 10;
mem_cnt_next <= 6;
end if;
when REMOVE_ENDPOINT =>
mem_addr_next <= addr_res;
mem_addr_next <= mem_addr_base;
mem_stage_next <= REMOVE_ENDPOINT;
mem_cnt_next <= 0;
when REMOVE_PARTICIPANT =>
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_stage_next <= SEARCH_ENDPOINT;
mem_cnt_next <= 0;
when FIND_STALE_ENDPOINT =>
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_pos_next <= 0;
mem_stage_next <= FIND_STALE_ENDPOINT;
mem_cnt_next <= 0;
when FIND_FIRST_ENDPOINT =>
when GET_FIRST_ENDPOINT =>
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_stage_next <= FIND_NEXT_ENDPOINT;
mem_pos_next <= 0;
mem_stage_next <= GET_NEXT_ENDPOINT;
mem_cnt_next <= 0;
when FIND_NEXT_ENDPOINT =>
when GET_NEXT_ENDPOINT =>
-- Memory Bound Guard
if (addr_res /= max_endpoint_addr) then
if (mem_addr_base /= max_endpoint_addr) then
-- Reached End of Memory, No match
tmp := addr_res + ENDPOINT_FRAME_SIZE;
tmp := mem_addr_base + ENDPOINT_FRAME_SIZE;
mem_addr_base_next <= tmp;
mem_addr_next <= tmp;
mem_stage_next <= FIND_NEXT_ENDPOINT;
mem_pos_next <= mem_pos + 1;
mem_stage_next <= GET_NEXT_ENDPOINT;
mem_cnt_next <= 0;
else
addr_res_next <= MAX_ADDRESS;
mem_addr_base_next <= MAX_ADDRESS;
end if;
when FIND_FIRST_PARTICIPANT_ENDPOINT =>
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_pos_next <= 0;
mem_stage_next <= SEARCH_ENDPOINT;
mem_cnt_next <= 0;
is_psearch_next <= '1';
when FIND_NEXT_PARTICIPANT_ENDPOINT =>
-- Memory Bound Guard
if (mem_addr_base /= max_endpoint_addr) then
-- Reached End of Memory, No match
tmp := mem_addr_base + ENDPOINT_FRAME_SIZE;
mem_addr_base_next <= tmp;
mem_addr_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_stage_next <= SEARCH_ENDPOINT;
mem_cnt_next <= 0;
is_psearch_next <= '1';
else
mem_addr_base_next <= MAX_ADDRESS;
end if;
when others =>
null;
@ -1282,84 +1369,77 @@ begin
null;
-- Entity ID
when 1 =>
-- No Match (Ignore Entity ID match on Participant Search, but skip empty Slot)
if ((mem_read_data /= guid(3) and mem_ctrl_data.mem_opcode /= REMOVE_PARTICIPANT) or (mem_read_data = ENTITYID_UNKNOWN)) then
-- No Match (Ignore Entity ID match on Participant Endpoint Search, but skip empty Slot)
if ((mem_read_data /= mem_ctrl_data.guid(3) and is_psearch = '0') or (mem_read_data = ENTITYID_UNKNOWN)) then
-- Reached End of Memory, No Match
if (mem_addr_base = max_endpoint_addr) then
case (mem_ctrl_data.mem_opcode) is
when INSERT_ENDPOINT =>
-- Insert new Endpoint
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_stage_next <= FIND_ENDPOINT_SLOT;
mem_cnt_next <= 0;
when REMOVE_PARTICIPANT =>
-- Reset MAX Endpoint Pointer
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
reset_max_pointer_next <= '1';
last_addr_next <= (others => '0');
mem_stage_next <= FIND_ENDPOINT_SLOT;
mem_cnt_next <= 0;
when others =>
addr_res_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
end case;
mem_addr_base_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
else
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
end if;
-- GUID Prefix 1/3
when 2 =>
-- No Match
if (mem_read_data /= guid(0)) then
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_cnt_next <= 0;
if (mem_read_data /= mem_ctrl_data.guid(0)) then
-- Reached End of Memory, No Match
if (mem_addr_base = max_endpoint_addr) then
mem_addr_base_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
else
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
end if;
-- GUID Prefix 2/3
when 3 =>
-- No Match
if (mem_read_data /= guid(1)) then
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_cnt_next <= 0;
if (mem_read_data /= mem_ctrl_data.guid(1)) then
-- Reached End of Memory, No Match
if (mem_addr_base = max_endpoint_addr) then
mem_addr_base_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
else
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
end if;
-- GUID Prefix 3/3
when 4 =>
-- No Match
if (mem_read_data /= guid(2)) then
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_cnt_next <= 0;
if (mem_read_data /= mem_ctrl_data.guid(2)) then
-- Reached End of Memory, No Match
if (mem_addr_base = max_endpoint_addr) then
mem_addr_base_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
else
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
-- Match
else
case (mem_ctrl_data.mem_opcode) is
when REMOVE_PARTICIPANT =>
addr_res_next <= mem_addr_base;
-- Remove Endpoint from remote Participant
mem_stage_next <= REMOVE_ENDPOINT;
mem_addr_next <= mem_addr_base;
mem_cnt_next <= 0;
when INSERT_ENDPOINT =>
addr_res_next <= mem_addr_base;
-- Update Endpoint Data
mem_stage_next <= UPDATE_ENDPOINT;
mem_addr_next <= mem_addr_base + 4;
mem_cnt_next <= 0;
when others =>
addr_res_next <= mem_addr_base;
-- Fetch Endpoint Data
mem_stage_next <= GET_ENDPOINT_DATA;
mem_cnt_next <= 1; -- No preload needed
end case;
mem_addr_base_next <= mem_addr_base;
-- Fetch Endpoint Data
mem_stage_next <= GET_ENDPOINT_DATA;
mem_cnt_next <= 1; -- No preload needed
end if;
when others =>
null;
@ -1528,21 +1608,14 @@ begin
mem_wr <= '1';
mem_write_data <= ENTITYID_UNKNOWN;
if (mem_ctrl_data.mem_opcode = REMOVE_PARTICIPANT) then
-- Continue Participant Match Search
mem_addr_base_next <= addr_res;
mem_addr_next <= addr_res;
mem_stage_next <= SEARCH_ENDPOINT;
mem_cnt_next <= 0;
else
-- Reset MAX Endpoint Pointer
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
reset_max_pointer_next <= '1';
last_addr_next <= (others => '0');
mem_stage_next <= FIND_ENDPOINT_SLOT;
mem_cnt_next <= 0;
end if;
-- Reset MAX Endpoint Pointer
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
mem_pos_next <= 0;
reset_max_pointer_next <= '1';
last_addr_next <= (others => '0');
mem_stage_next <= FIND_ENDPOINT_SLOT;
mem_cnt_next <= 0;
when FIND_ENDPOINT_SLOT =>
mem_rd <= '1';
mem_addr_next <= mem_addr + 1;
@ -1570,16 +1643,18 @@ begin
report "Memory Full, Ignoring Endpoint Data" severity NOTE;
-- Ignore Insertion
mem_stage_next <= IDLE;
addr_res_next <= MAX_ADDRESS;
mem_addr_base_next <= MAX_ADDRESS;
else
-- Extend Endpoint Memory Area
-- NOTE: "max_endpoint_addr" points to the first address of last Endpoint Frame
max_endpoint_addr_next <= tmp;
-- Populate Endpoint Slot
mem_stage_next <= INSERT_ENDPOINT;
mem_addr_next <= tmp;
addr_res_next <= tmp;
mem_cnt_next <= 0;
mem_stage_next <= INSERT_ENDPOINT;
mem_addr_base_next <= tmp;
mem_addr_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_addr_base_next <= tmp;
mem_cnt_next <= 0;
end if;
else
-- Latch last occupied Endpoint Slot
@ -1587,10 +1662,12 @@ begin
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
-- Slot Empty
else
-- We are in the middle of resetting the MAX Endpoint Pointer
if (reset_max_pointer = '1') then
-- Make sure to iterate through complete Endpoint Area
if (mem_addr_base = max_endpoint_addr) then
@ -1602,20 +1679,20 @@ begin
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
else
-- Populate Endpoint Slot
mem_stage_next <= INSERT_ENDPOINT;
mem_addr_next <= mem_addr_base;
addr_res_next <= mem_addr_base;
mem_cnt_next <= 0;
mem_stage_next <= INSERT_ENDPOINT;
mem_addr_next <= mem_addr_base;
mem_cnt_next <= 0;
end if;
end if;
when others =>
null;
end case;
when FIND_NEXT_ENDPOINT =>
when GET_NEXT_ENDPOINT =>
mem_rd <= '1';
mem_cnt_next <= mem_cnt + 1;
mem_addr_next <= mem_addr + 1;
@ -1634,21 +1711,21 @@ begin
-- Slot Occupied
if (mem_read_data /= ENTITYID_UNKNOWN) then
-- Get Endpoint Data
mem_addr_next <= tmp2;
addr_res_next <= mem_addr_base;
mem_stage_next <= GET_ENDPOINT_DATA;
mem_cnt_next <= 0;
mem_addr_next <= tmp2;
mem_stage_next <= GET_ENDPOINT_DATA;
mem_cnt_next <= 0;
-- Slot Empty
else
-- Reached End of Memory, No Match
if (mem_addr_base = max_endpoint_addr) then
addr_res_next <= MAX_ADDRESS; --No match
mem_addr_base_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
else
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
end if;
@ -1682,13 +1759,14 @@ begin
else
-- Reached End of Memory, No Match
if (mem_addr_base = max_endpoint_addr) then
addr_res_next <= MAX_ADDRESS; --No match
mem_addr_base_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
else
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
end if;
@ -1704,7 +1782,6 @@ begin
-- Lease Deadline passed
if (tmp_dw < time) then
-- Mark Endpoint as stale
addr_res_next <= mem_addr_base;
mem_endpoint_data_next <= ZERO_ENDPOINT_DATA;
-- DONE
mem_stage_next <= IDLE;
@ -1718,21 +1795,21 @@ begin
-- Response/Suppression Time passed
if (tmp_dw /= 0 and tmp_dw < time) then
-- Mark Endpoint and get Endpoint Data
addr_res_next <= mem_addr_base;
mem_addr_next <= tmp2;
mem_stage_next <= GET_ENDPOINT_DATA;
mem_cnt_next <= 0;
mem_addr_next <= tmp2;
mem_stage_next <= GET_ENDPOINT_DATA;
mem_cnt_next <= 0;
-- Endpoint not Stale
else
-- Reached End of Memory, No Match
if (mem_addr_base = max_endpoint_addr) then
addr_res_next <= MAX_ADDRESS; --No match
mem_addr_base_next <= MAX_ADDRESS; --No match
-- DONE
mem_stage_next <= IDLE;
mem_stage_next <= IDLE;
else
-- Continue Search
mem_addr_next <= tmp;
mem_addr_base_next <= tmp;
mem_pos_next <= mem_pos + 1;
mem_cnt_next <= 0;
end if;
end if;

View File

@ -85,6 +85,7 @@ package rtps_package is
constant GUIDPREFIX_UNKNOWN : GUIDPREFIX_TYPE := (others => (others => '0'));
constant UDP_PORT_INVALID : std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := (others => '0');
constant IPv4_ADDRESS_INVALID : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := (others => '0');
constant LENGTH_UNLIMITED : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH));
-- *SUBMESSAGE IDs*
constant SID_PAD : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"01";
@ -279,9 +280,9 @@ package rtps_package is
-- DEPTH (HISTORY)
constant DEFAULT_HISTORY_DEPTH : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_LONG_WIDTH));
-- RESOURCE_LIMITS
constant DEFAULT_MAX_SAMPLES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
constant DEFAULT_MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
constant DEFAULT_MAX_SAMPLES_PER_INSTANCE : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
constant DEFAULT_MAX_SAMPLES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
constant DEFAULT_MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
constant DEFAULT_MAX_SAMPLES_PER_INSTANCE : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
-- WRITER_DATA_LIFECYCLE
constant DEFAULT_AUTODISPOSE_UNREGISTERED_INSTANCES : boolean := TRUE;
-- READER_DATA_LIFECYCLE
@ -294,9 +295,9 @@ package rtps_package is
constant DEFAULT_DURABILITY_SERVICE_CLEANUP_DELAY : DURATION_TYPE := DURATION_ZERO;
constant DEFAULT_DURABILITY_SERVICE_HISTORY : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := KEEP_LAST_HISTORY_QOS;
constant DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_LONG_WIDTH));
constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
constant DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE: std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED
constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
constant DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE: std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := LENGTH_UNLIMITED;
constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE; -- Deferred to package Body (100 s)