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:
parent
d2f466d588
commit
7e84a15d54
112
src/REF.txt
112
src/REF.txt
@ -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
|
||||
===========
|
||||
|
||||
@ -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
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user