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
|
31............24..............16..............8...............0
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
00| STATUS_INFO |
|
00| STATUS_INFO | {A/B}
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
01| |
|
01| |
|
||||||
+ +
|
+ +
|
||||||
02| |
|
02| |
|
||||||
+ KEY_HASH +
|
+ KEY_HASH + {A}
|
||||||
03| |
|
03| |
|
||||||
+ +
|
+ +
|
||||||
04| |
|
04| |
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
05| ENTITYID |
|
05| |
|
||||||
+-------------------------------------------------------------+
|
+ TIMESTAMP + {A}
|
||||||
06| |
|
06| |
|
||||||
+ +
|
+-------------------------------------------------------------+
|
||||||
07| GUIDPREFIX |
|
07| |
|
||||||
+ +
|
+ LIFESPAN_DEADLINE + {A}
|
||||||
08| |
|
08| |
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
09| |
|
09| PAYLOAD_ADDRESS | {A}
|
||||||
+ SEQUENCE_NUMBER +
|
|
||||||
10| |
|
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
11| |
|
10| DISPOSED_GENERATION_COUNT | {A} [only GENERATION_COUNTERS]
|
||||||
+ TIMESTAMP +
|
|
||||||
12| |
|
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
13| |
|
11| NO_WRITERS_GENERATION_COUNT | {A} [only GENERATION_COUNTERS]
|
||||||
+ LIFESPAN_DEADLINE +
|
|
||||||
14| |
|
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
15| PAYLOAD_ADDRESS |
|
12| PREV_ADDRESS | {A}
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
16| PREV_ADDRESS |
|
13| NEXT_ADDRESS | {A/B}
|
||||||
+-------------------------------------------------------------+
|
|
||||||
17| NEXT_ADDRESS |
|
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
@ -383,12 +375,12 @@ STATUS INFO
|
|||||||
31............24..............16..............8...............0
|
31............24..............16..............8...............0
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
+-+-+-+-------------------------------------------------+-+-+-+
|
+-+-+-+-------------------------------------------------+-+-+-+
|
||||||
|R|K|P| UNUSED |F|U|D|
|
|R|P|K| UNUSED |F|U|D|
|
||||||
+-+-+-+-------------------------------------------------+-+-+-+
|
+-+-+-+-------------------------------------------------+-+-+-+
|
||||||
|
|
||||||
R...Sample has been Read
|
R...Sample has been Read
|
||||||
K...Key Hash available
|
|
||||||
P...Sample has associated Payload
|
P...Sample has associated Payload
|
||||||
|
K...Key Hash available
|
||||||
|
|
||||||
F...FilteredFlag
|
F...FilteredFlag
|
||||||
U...UnregisteredFlag
|
U...UnregisteredFlag
|
||||||
@ -398,9 +390,9 @@ PAYLOAD MEMORY
|
|||||||
==============
|
==============
|
||||||
31............24..............16..............8...............0
|
31............24..............16..............8...............0
|
||||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
+-----------------------------------------------------------+-+
|
+-------------------------------------------------------------+
|
||||||
00| NEXT_ADDRESS |O|
|
00| NEXT_ADDRESS |
|
||||||
+-----------------------------------------------------------+-+
|
+-------------------------------------------------------------+
|
||||||
01| |
|
01| |
|
||||||
~ PAYLOAD ~
|
~ PAYLOAD ~
|
||||||
**| |
|
**| |
|
||||||
@ -421,31 +413,67 @@ HISTORY CACHE INPUT
|
|||||||
+ +
|
+ +
|
||||||
04| |
|
04| |
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
05| ENTITYID |
|
05| |
|
||||||
+-------------------------------------------------------------+
|
+ TIMESTAMP +
|
||||||
06| |
|
06| |
|
||||||
+ +
|
+-------------------------------------------------------------+
|
||||||
07| GUIDPREFIX |
|
07| |
|
||||||
+ +
|
+ LIFESPAN_DEADLINE +
|
||||||
08| |
|
08| |
|
||||||
+-------------------------------------------------------------+
|
+-------------------------------------------------------------+
|
||||||
09| |
|
09| ENDPOINT_POSITION |
|
||||||
+ SEQUENCE_NUMBER +
|
+-------------------------------------------------------------+
|
||||||
10| |
|
10| |
|
||||||
+-------------------------------------------------------------+
|
|
||||||
11| |
|
|
||||||
+ TIMESTAMP +
|
|
||||||
12| |
|
|
||||||
+-------------------------------------------------------------+
|
|
||||||
13| |
|
|
||||||
+ LIFESPAN_DEADLINE +
|
|
||||||
14| |
|
|
||||||
+-------------------------------------------------------------+
|
|
||||||
15| |
|
|
||||||
~ PAYLOAD ~
|
~ 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
|
OUTPUT DATA
|
||||||
===========
|
===========
|
||||||
|
|||||||
@ -95,6 +95,8 @@
|
|||||||
'This Submessage is invalid when the following is true:
|
'This Submessage is invalid when the following is true:
|
||||||
submessageLength in the Submessage header is too small'
|
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.
|
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
|
- 9.4.5.1.2 Flags
|
||||||
Clarify from where the endianness begins.
|
Clarify from where the endianness begins.
|
||||||
One might think it would begin after the Submessage Header, but the length is also endian dependent.
|
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 HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE);
|
||||||
type KEY_GENERATOR_OPCODE_TYPE is (NOP, WRITE_PAYLOAD, READ_KEY, READ_SIZE);
|
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 DISPOSED_FLAG : natural := 0;
|
||||||
constant UNREGISTERED_FLAG : natural := 1;
|
constant UNREGISTERED_FLAG : natural := 1;
|
||||||
constant FILTERED_FLAG : natural := 2;
|
constant FILTERED_FLAG : natural := 2;
|
||||||
constant PAYLOAD_FLAG : natural := 29;
|
constant KEY_HASH_FLAG : natural := 29;
|
||||||
constant KEY_HASH_FLAG : natural := 30;
|
constant PAYLOAD_FLAG : natural := 30;
|
||||||
constant READ_FLAG : natural := 31;
|
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
|
-- 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');
|
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);
|
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.
|
-- 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 : std_logic_vector) return std_logic_vector;
|
||||||
function endian_swap(swap : std_logic; data : unsigned) return unsigned;
|
function endian_swap(swap : std_logic; data : unsigned) return unsigned;
|
||||||
@ -1053,4 +1066,22 @@ package body rtps_config_package is
|
|||||||
return ret;
|
return ret;
|
||||||
end function;
|
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;
|
end package body;
|
||||||
|
|||||||
@ -10,7 +10,9 @@ use work.rtps_config_package.all;
|
|||||||
-- TODO: Check for special values of time/duration?
|
-- TODO: Check for special values of time/duration?
|
||||||
-- TODO: Remove last_word flag from metattraffic operations
|
-- TODO: Remove last_word flag from metattraffic operations
|
||||||
-- TODO: Replace all ('range => 0) checks with defined constants, where possible
|
-- 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
|
entity rtps_endpoint is
|
||||||
generic (
|
generic (
|
||||||
@ -38,11 +40,13 @@ entity rtps_endpoint is
|
|||||||
|
|
||||||
hc_start : out std_logic;
|
hc_start : out std_logic;
|
||||||
hc_opcode : out HISTORY_CACHE_OPCODE_TYPE;
|
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_data_out : in std_logic_vector(WORD_WIDTH-1 downto 0);
|
||||||
hc_valid_out : in std_logic;
|
hc_valid_out : in std_logic;
|
||||||
hc_ready_out : out std_logic;
|
hc_ready_out : out std_logic;
|
||||||
hc_last_word_out: in std_logic;
|
hc_last_word_out: in std_logic;
|
||||||
|
|
||||||
hc_data_in : out std_logic_vector(WORD_WIDTH-1 downto 0);
|
hc_data_in : out std_logic_vector(WORD_WIDTH-1 downto 0);
|
||||||
hc_valid_in : out std_logic;
|
hc_valid_in : out std_logic;
|
||||||
hc_ready_in : in std_logic;
|
hc_ready_in : in std_logic;
|
||||||
@ -54,27 +58,26 @@ architecture arch of rtps_endpoint is
|
|||||||
|
|
||||||
--*****CONSTANT DECLARATION*****
|
--*****CONSTANT DECLARATION*****
|
||||||
-- Endpoint Memory Size in 4-Byte Words
|
-- Endpoint Memory Size in 4-Byte Words
|
||||||
constant ENDPOINT_MEMORY_SIZE : natural := TODO;
|
constant ENDPOINT_MEMORY_SIZE : natural := TODO;
|
||||||
-- Endpoint Memory Address Width
|
-- 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
|
-- 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
|
-- 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
|
-- 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*
|
-- *UPDATE PARTICIPANT FLAG POSITIONS*
|
||||||
constant UPDATE_ENDPOINT_FLAG_WIDTH : natural := 4;
|
constant UPDATE_ENDPOINT_FLAG_WIDTH : natural := 4;
|
||||||
-- Signifies that the main Endpoint Data are updated
|
-- 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
|
-- 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
|
-- 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
|
-- 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 RES_TIME_FLAG : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1) := (3 => 1, others => '0');
|
||||||
constant BITMAP_BLOCK_SIZE : natural := 16;
|
|
||||||
|
|
||||||
--*****TYPE DECLARATION*****
|
--*****TYPE DECLARATION*****
|
||||||
-- FSM states. Explained below in detail
|
-- FSM states. Explained below in detail
|
||||||
@ -106,8 +109,7 @@ architecture arch of rtps_endpoint is
|
|||||||
expects_inline_qos : std_logic;
|
expects_inline_qos : std_logic;
|
||||||
deadline : TIME_TYPE;
|
deadline : TIME_TYPE;
|
||||||
next_seq_nr : SEQUENCENUMBER_TYPE;
|
next_seq_nr : SEQUENCENUMBER_TYPE;
|
||||||
update_flags : std_logic_vector(UPDATE_ENDPOINT_FLAG_WIDTH-1 downto 0);
|
update_flags : std_logic_vector(0 to UPDATE_ENDPOINT_FLAG_WIDTH-1);
|
||||||
mem_opcode : MEM_OPCODE_TYPE;
|
|
||||||
end record;
|
end record;
|
||||||
constant ZERO_MEM_CTRL_DATA : MEM_CTRL_DATA_TYPE := (
|
constant ZERO_MEM_CTRL_DATA : MEM_CTRL_DATA_TYPE := (
|
||||||
guid => (others => (others => '0')),
|
guid => (others => (others => '0')),
|
||||||
@ -117,7 +119,6 @@ architecture arch of rtps_endpoint is
|
|||||||
deadline => TIME_INVALID,
|
deadline => TIME_INVALID,
|
||||||
next_seq_nr => SEQUENCENUMBER_UNKNOWN,
|
next_seq_nr => SEQUENCENUMBER_UNKNOWN,
|
||||||
update_flags => (others => '0'),
|
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 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 expects_inline_qos, expects_inline_qos_next : std_logic := '0';
|
||||||
signal is_meta, is_meta_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 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 flags, flags_next : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0) := (others => '0');
|
||||||
signal seq_nr, seq_nr_next : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN;
|
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_stage, mem_stage_next : MEM_STAGE_TYPE := IDLE;
|
||||||
signal mem_wr, mem_rd : std_logic := '0';
|
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_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, mem_addr_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0) := (others => '0');
|
||||||
signal mem_addr_base, mem_addr_base_next : unsigned(ENDPOINT_MEMORY_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 addr_res, addr_res_next : unsigned(ENDPOINT_MEMORY_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_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_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_cnt, mem_cnt_next : natural range TODO := 0;
|
||||||
signal mem_endpoint_data, mem_endpoint_data_next : ENDPOINT_DATA_TYPE := ZERO_ENDPOINT_DATA;
|
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 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_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_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 stale_check, stale_check_next : std_logic := '0';
|
||||||
signal count, count_next : unsigned(COUNT_WIDTH-1 downto 0) := (others => '0');
|
signal count, count_next : unsigned(COUNT_WIDTH-1 downto 0) := (others => '0');
|
||||||
@ -227,7 +230,7 @@ begin
|
|||||||
--*****COMPONENT INSTANTIATION*****
|
--*****COMPONENT INSTANTIATION*****
|
||||||
ram_inst : single_port_ram
|
ram_inst : single_port_ram
|
||||||
generic map (
|
generic map (
|
||||||
ADDR_WIDTH => ENDPOINT_MEMORY_WIDTH,
|
ADDR_WIDTH => ENDPOINT_MEMORY_ADDR_WIDTH,
|
||||||
DATA_WIDTH => WORD_WIDTH,
|
DATA_WIDTH => WORD_WIDTH,
|
||||||
MEMORY_DEPTH => ENDPOINT_MEMORY_SIZE
|
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
|
if (is_meta = '1' and (meta_opcode = OPCODE_PARTICIPANT_UNMATCH or meta_opcode = OPCODE_LIVELINESS_UPDATE)) then
|
||||||
-- DONE Parsing
|
-- DONE Parsing
|
||||||
stage_next <= METATRAFFIC_OPERATION;
|
stage_next <= INITIATE_ENDPOINT_SEARCH;
|
||||||
else
|
else
|
||||||
stage_next <= LATCH_ENTITYID;
|
stage_next <= LATCH_ENTITYID;
|
||||||
end if;
|
end if;
|
||||||
@ -398,19 +401,57 @@ begin
|
|||||||
if (is_meta = '1') then
|
if (is_meta = '1') then
|
||||||
meta_rd <= '1';
|
meta_rd <= '1';
|
||||||
guid_next(3) <= meta_data_in;
|
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
|
-- Memory Operation Guard
|
||||||
else
|
else
|
||||||
rd_guard := '1';
|
rd_guard := '1';
|
||||||
guid_next(3) <= data_in;
|
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
|
||||||
|
|
||||||
stage_next <= INITIATE_ENDPOINT_SEARCH;
|
if (is_meta = '1') then
|
||||||
|
|
||||||
|
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;
|
||||||
end if;
|
end if;
|
||||||
when LATCH_ENDPOINT_DATA =>
|
when LATCH_ENDPOINT_DATA =>
|
||||||
@ -441,28 +482,76 @@ begin
|
|||||||
|
|
||||||
case (meta_opcode) is
|
case (meta_opcode) is
|
||||||
when OPCODE_ENDPOINT_MATCH =>
|
when OPCODE_ENDPOINT_MATCH =>
|
||||||
-- Insert Matched Remote Endpoint
|
-- Endpoint already in Memory
|
||||||
-- NOTE: The Lease Duration is NOT updated in case of an update. That is the responsibility of the Liveliness Update
|
if (mem_addr_base /= MAX_ADDRESS) then
|
||||||
update_endpoint_flags <= ENDPOINT_DATA_FLAG; -- In case the Endpoint is already in the memory, we update the data
|
-- Update the Endpoint Data
|
||||||
mem_opcode <= INSERT_ENDPOINT;
|
-- NOTE: The Lease Duration is NOT updated in case of an update. That is the responsibility of the Liveliness Update
|
||||||
mem_op_start <= '1';
|
update_endpoint_flags <= ENDPOINT_DATA_FLAG;
|
||||||
stage_next <= IDLE;
|
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 =>
|
when OPCODE_ENDPOINT_UNMATCH =>
|
||||||
-- Remove Unmatched Remote Endpoint
|
-- Endpoint not in Memory
|
||||||
mem_opcode <= REMOVE_ENDPOINT;
|
if (mem_addr_base = MAX_ADDRESS) then
|
||||||
mem_op_start <= '1';
|
-- Ignore
|
||||||
stage_next <= IDLE;
|
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 =>
|
when OPCODE_PARTICIPANT_UNMATCH =>
|
||||||
-- Remove All Endpoint of Remote Participant
|
-- No matches in memory
|
||||||
mem_opcode <= REMOVE_PARTICIPANT;
|
if (mem_addr_base = MAX_ADDRESS) then
|
||||||
mem_op_start <= '1';
|
-- DONE
|
||||||
stage_next <= IDLE;
|
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 =>
|
when OPCODE_LIVELINESS_UPDATE =>
|
||||||
-- Renew Lease of Remote Endpoint
|
-- No matches in memory
|
||||||
update_endpoint_flags <= LEASE_DEADLINE_FLAG;
|
if (mem_addr_base = MAX_ADDRESS) then
|
||||||
mem_opcode <= UDPATE_ENDPOINT;
|
-- DONE
|
||||||
mem_op_start <= '1';
|
stage_next <= IDLE;
|
||||||
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 =>
|
when others =>
|
||||||
assert FALSE report "Uknown metatraffic endpoint frame opcode." severity FAILURE;
|
assert FALSE report "Uknown metatraffic endpoint frame opcode." severity FAILURE;
|
||||||
null;
|
null;
|
||||||
@ -470,6 +559,13 @@ begin
|
|||||||
-- DONE
|
-- DONE
|
||||||
stage_next <= SKIP_PACKET;
|
stage_next <= SKIP_PACKET;
|
||||||
end if;
|
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 =>
|
when LATCH_SRC_ADDR =>
|
||||||
-- Input FIFO Guard
|
-- Input FIFO Guard
|
||||||
if (empty = '0') then
|
if (empty = '0') then
|
||||||
@ -481,26 +577,6 @@ begin
|
|||||||
stage_next <= LATCH_GUIDPREFIX;
|
stage_next <= LATCH_GUIDPREFIX;
|
||||||
cnt_next <= 0;
|
cnt_next <= 0;
|
||||||
end if;
|
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 =>
|
when LATCH_EXTRA_DATA =>
|
||||||
-- Input FIFO Guard
|
-- Input FIFO Guard
|
||||||
if (empty = '0') then
|
if (empty = '0') then
|
||||||
@ -515,7 +591,7 @@ begin
|
|||||||
when 1 =>
|
when 1 =>
|
||||||
seq_nr_next(1) <= unsigned(data_in);
|
seq_nr_next(1) <= unsigned(data_in);
|
||||||
-- Store Next Sequence Number
|
-- 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;
|
next_seq_nr_next <= tmp_dw + 1;
|
||||||
-- Timestamp 1/2
|
-- Timestamp 1/2
|
||||||
when 2 =>
|
when 2 =>
|
||||||
@ -565,7 +641,7 @@ begin
|
|||||||
stage_next <= SKIP_PACKET;
|
stage_next <= SKIP_PACKET;
|
||||||
|
|
||||||
-- Endpoint in Buffer
|
-- Endpoint in Buffer
|
||||||
if (addr_res /= MAX_ADDRESS) then
|
if (mem_addr_base /= MAX_ADDRESS) then
|
||||||
-- No scheduled Heartbeat Response
|
-- No scheduled Heartbeat Response
|
||||||
if (mem_endpoint_data.res_time = 0) then
|
if (mem_endpoint_data.res_time = 0) then
|
||||||
-- If current Sequence Number obsolete (removed from source history cache)
|
-- If current Sequence Number obsolete (removed from source history cache)
|
||||||
@ -651,7 +727,7 @@ begin
|
|||||||
stage_next <= SKIP_PACKET;
|
stage_next <= SKIP_PACKET;
|
||||||
|
|
||||||
-- Known Remote Endpoint
|
-- Known Remote Endpoint
|
||||||
if (addr_res /= MAX_ADDRESS) then
|
if (mem_addr_base /= MAX_ADDRESS) then
|
||||||
-- GAP is relevant
|
-- GAP is relevant
|
||||||
if (gap_start <= mem_endpoint_data.next_seq_nr and mem_endpoint_data.next_seq_nr <= gap_list_end) then
|
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
|
-- Next Expected is in GAP List
|
||||||
@ -794,10 +870,15 @@ begin
|
|||||||
case (cnt) is
|
case (cnt) is
|
||||||
-- Lifespan 1/2
|
-- Lifespan 1/2
|
||||||
when 0 =>
|
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
|
-- Lifespan 2/2
|
||||||
when 1 =>
|
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
|
-- DONE
|
||||||
stage_next <= SKIP_PARAMETER;
|
stage_next <= SKIP_PARAMETER;
|
||||||
@ -845,7 +926,7 @@ begin
|
|||||||
hc_start <= '1';
|
hc_start <= '1';
|
||||||
hc_opcode <= ADD_CACHE_CHANGE;
|
hc_opcode <= ADD_CACHE_CHANGE;
|
||||||
-- Wait until History Cache acknowledges request
|
-- Wait until History Cache acknowledges request
|
||||||
if (hc_ack = '1') then
|
if (hc_res = ACK) then
|
||||||
stage_next <= ADD_CACHE_CHANGE;
|
stage_next <= ADD_CACHE_CHANGE;
|
||||||
cnt_next <= 0;
|
cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
@ -872,51 +953,38 @@ begin
|
|||||||
-- Key hash 4/4
|
-- Key hash 4/4
|
||||||
when 4 =>
|
when 4 =>
|
||||||
hc_data_in <= key_hash(3);
|
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
|
-- Timestamp 1/2
|
||||||
when 11 =>
|
when 5 =>
|
||||||
hc_data_in <= ts(0);
|
hc_data_in <= ts(0);
|
||||||
-- Timestamp 2/2
|
-- Timestamp 2/2
|
||||||
when 12 =>
|
when 6 =>
|
||||||
hc_data_in <= ts(1);
|
hc_data_in <= ts(1);
|
||||||
-- Lifespan Deadline 1/2
|
-- Lifespan Deadline 1/2
|
||||||
when 13 =>
|
when 7 =>
|
||||||
hc_data_in <= deadline(0);
|
hc_data_in <= deadline(0);
|
||||||
-- Lifespan Deadline 2/2
|
-- Lifespan Deadline 2/2
|
||||||
when 14 =>
|
when 8 =>
|
||||||
hc_data_in <= deadline(1);
|
hc_data_in <= deadline(1);
|
||||||
|
-- Endpoint Memory Position
|
||||||
|
when 9 =>
|
||||||
|
-- Wait for Endpoint Search
|
||||||
|
if (mem_op_done = '1') then
|
||||||
|
|
||||||
-- Payload exists
|
-- TODO: Assert mem_pos range fits in CDR_LONG
|
||||||
if (data_flag = '1' or key_flag = '1') then
|
hc_data_in <= std_logic_vector(to_unsigned(mem_pos, CDR_LONG_WIDTH));
|
||||||
stage_next <= PUSH_PAYLOAD;
|
|
||||||
else
|
|
||||||
-- DONE
|
|
||||||
hc_last_word_in <= '1';
|
|
||||||
|
|
||||||
-- Operation Sucessfull
|
-- Payload exists
|
||||||
if (hc_ack = '1') then
|
if (data_flag = '1' or key_flag = '1') then
|
||||||
stage_next <= FINALIZE_HISTORY_CACHE_REQUEST;
|
stage_next <= PUSH_PAYLOAD;
|
||||||
else
|
else
|
||||||
-- Operation Failed, Skip
|
-- DONE
|
||||||
stage_next <= SKIP_PACKET;
|
hc_last_word_in <= '1';
|
||||||
|
stage_next <= FINALIZE_HISTORY_CACHE_REQUEST;
|
||||||
end if;
|
end if;
|
||||||
|
else
|
||||||
|
-- Keep State
|
||||||
|
hc_valid_in <= '0';
|
||||||
|
cnt_next <= cnt;
|
||||||
end if;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
@ -933,34 +1001,33 @@ begin
|
|||||||
|
|
||||||
-- Exit Condition
|
-- Exit Condition
|
||||||
if (last_word_in = '1') then
|
if (last_word_in = '1') then
|
||||||
hc_last_word_in <= '1';
|
hc_last_word_in <= '1';
|
||||||
-- XXX: Possible worst case path (The hc_ack is set from last_word signal -> round trip delay between entities)
|
stage_next <= FINALIZE_HISTORY_CACHE_REQUEST;
|
||||||
-- 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;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when FINALIZE_HISTORY_CACHE_REQUEST =>
|
when FINALIZE_HISTORY_CACHE_REQUEST =>
|
||||||
-- Memory Operation Guard
|
-- NOTE: Memory is already in done state from previous state (ADD_CACHE_CHANGE)
|
||||||
if (mem_op_done = '1') then
|
assert (mem_op_done = '1') report "FINALIZE_HISTORY_CACHE_REQUEST precondition not met. mem_op_done /= '1'" severity FAILURE;
|
||||||
-- Update next sequence number and renew Lease
|
-- Wai for History Cache Response
|
||||||
mem_op_start <= '1';
|
if (hc_res /= UNDEFINED) then
|
||||||
mem_opcode <= UPDATE_ENDPOINT;
|
-- Operation was Accepted
|
||||||
deadline_next <= time + ENDPOINT_LEASE_DURATION(ID);
|
if (hc_res = ACCEPTED) then
|
||||||
update_endpoint_flags <= NEXT_SEQ_NR_FLAG or LEASE_DEADLINE_FLAG;
|
-- 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
|
-- DONE
|
||||||
stage_next <= SKIP_PACKET;
|
stage_next <= SKIP_PACKET;
|
||||||
end if;
|
end if;
|
||||||
when ENDPOINT_STALE_CHECK =>
|
when ENDPOINT_STALE_CHECK =>
|
||||||
-- Wait for Stale Search to finish
|
-- Wait for Stale Search to finish
|
||||||
if (mem_op_done = '1') then
|
if (mem_op_done = '1') then
|
||||||
-- Found Stale Entry
|
-- Found Stale Entry
|
||||||
if (addr_res /= MAX_ADDRESS) then
|
if (mem_addr_base /= MAX_ADDRESS) then
|
||||||
-- Endpoint Lease Expired
|
-- Endpoint Lease Expired
|
||||||
-- NOTE: The mem_endpoint_data is zero initialized on lease expiration, so we check if the address is set
|
-- 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
|
if (mem_endpoint_data.addr = IPv4_ADDRESS_INVALID) then
|
||||||
@ -1169,7 +1236,6 @@ begin
|
|||||||
mem_stage_next <= mem_stage;
|
mem_stage_next <= mem_stage;
|
||||||
mem_addr_base_next <= mem_addr_base;
|
mem_addr_base_next <= mem_addr_base;
|
||||||
mem_addr_next <= mem_addr;
|
mem_addr_next <= mem_addr;
|
||||||
addr_res_next <= addr_res;
|
|
||||||
mem_cnt_next <= mem_cnt;
|
mem_cnt_next <= mem_cnt;
|
||||||
last_addr_next <= last_addr;
|
last_addr_next <= last_addr;
|
||||||
mem_endpoint_data_next <= mem_endpoint_data;
|
mem_endpoint_data_next <= mem_endpoint_data;
|
||||||
@ -1178,6 +1244,7 @@ begin
|
|||||||
reset_max_pointer_next <= reset_max_pointer;
|
reset_max_pointer_next <= reset_max_pointer;
|
||||||
mem_long_latch_next <= mem_long_latch;
|
mem_long_latch_next <= mem_long_latch;
|
||||||
mem_ctrl_data_next <= mem_ctrl_data;
|
mem_ctrl_data_next <= mem_ctrl_data;
|
||||||
|
mem_pos_next <= mem_pos;
|
||||||
-- DEFAULT Unregistered
|
-- DEFAULT Unregistered
|
||||||
mem_write_data <= (others => '0');
|
mem_write_data <= (others => '0');
|
||||||
mem_op_done <= '0';
|
mem_op_done <= '0';
|
||||||
@ -1189,6 +1256,7 @@ begin
|
|||||||
when IDLE =>
|
when IDLE =>
|
||||||
mem_op_done <= '1';
|
mem_op_done <= '1';
|
||||||
reset_max_pointer_next <= '0';
|
reset_max_pointer_next <= '0';
|
||||||
|
is_psearch_next <= '0';
|
||||||
|
|
||||||
if (mem_op_start = '1') then
|
if (mem_op_start = '1') then
|
||||||
-- Latch Signals needed for Mermory Operation (Use _next signals, because some signals are set in same clk)
|
-- 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,
|
expects_inline_qos => expects_inline_qos_next,
|
||||||
deadline => deadline_next,
|
deadline => deadline_next,
|
||||||
next_seq_nr => next_seq_nr_next,
|
next_seq_nr => next_seq_nr_next,
|
||||||
update_flags => update_endpoint_flags_next,
|
update_flags => update_endpoint_flags_next
|
||||||
mem_opcode => mem_opcode_next
|
|
||||||
);
|
);
|
||||||
|
|
||||||
case(mem_opcode) is
|
case(mem_opcode) is
|
||||||
when SEARCH_ENDPOINT =>
|
when SEARCH_ENDPOINT =>
|
||||||
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
|
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
|
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
|
mem_pos_next <= 0;
|
||||||
mem_stage_next <= SEARCH_ENDPOINT;
|
mem_stage_next <= SEARCH_ENDPOINT;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
when INSERT_ENDPOINT =>
|
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_base_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
mem_addr_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;
|
mem_cnt_next <= 0;
|
||||||
when UPDATE_ENDPOINT =>
|
when UPDATE_ENDPOINT =>
|
||||||
if ((update_endpoint_flags and ENDPOINT_DATA_FLAG) = ENDPOINT_DATA_FLAG) then
|
if ((update_endpoint_flags and ENDPOINT_DATA_FLAG) = ENDPOINT_DATA_FLAG) then
|
||||||
mem_stage_next <= UPDATE_ENDPOINT;
|
mem_stage_next <= UPDATE_ENDPOINT;
|
||||||
mem_addr_next <= addr_res + 4;
|
mem_addr_next <= mem_addr_base + 4;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
elsif ((update_endpoint_flags and LEASE_DEADLINE_FLAG) = LEASE_DEADLINE_FLAG) then
|
elsif ((update_endpoint_flags and LEASE_DEADLINE_FLAG) = LEASE_DEADLINE_FLAG) then
|
||||||
mem_stage_next <= UPDATE_ENDPPOINT;
|
mem_stage_next <= UPDATE_ENDPPOINT;
|
||||||
mem_addr_next <= addr_res + 6;
|
mem_addr_next <= mem_addr_base + 6;
|
||||||
mem_cnt_next <= 2;
|
mem_cnt_next <= 2;
|
||||||
elsif ((update_endpoint_flags and RES_TIME_FLAG) = RES_TIME_FLAG) then
|
elsif ((update_endpoint_flags and RES_TIME_FLAG) = RES_TIME_FLAG) then
|
||||||
mem_stage_next <= UPDATE_ENDPOINT;
|
mem_stage_next <= UPDATE_ENDPOINT;
|
||||||
mem_addr_next <= addr_res + 8;
|
mem_addr_next <= mem_addr_base + 8;
|
||||||
mem_cnt_next <= 4;
|
mem_cnt_next <= 4;
|
||||||
elsif ((update_endpoint_flags and NEXT_SEQ_NR_FLAG) = NEXT_SEQ_NR_FLAG) then
|
elsif ((update_endpoint_flags and NEXT_SEQ_NR_FLAG) = NEXT_SEQ_NR_FLAG) then
|
||||||
mem_stage_next <= UPDATE_ENDPOINT;
|
mem_stage_next <= UPDATE_ENDPOINT;
|
||||||
mem_addr_next <= addr_res + 10;
|
mem_addr_next <= mem_addr_base + 10;
|
||||||
mem_cnt_next <= 6;
|
mem_cnt_next <= 6;
|
||||||
end if;
|
end if;
|
||||||
when REMOVE_ENDPOINT =>
|
when REMOVE_ENDPOINT =>
|
||||||
mem_addr_next <= addr_res;
|
mem_addr_next <= mem_addr_base;
|
||||||
mem_stage_next <= REMOVE_ENDPOINT;
|
mem_stage_next <= REMOVE_ENDPOINT;
|
||||||
mem_cnt_next <= 0;
|
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 =>
|
when FIND_STALE_ENDPOINT =>
|
||||||
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
|
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
|
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
|
mem_pos_next <= 0;
|
||||||
mem_stage_next <= FIND_STALE_ENDPOINT;
|
mem_stage_next <= FIND_STALE_ENDPOINT;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
when FIND_FIRST_ENDPOINT =>
|
when GET_FIRST_ENDPOINT =>
|
||||||
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
|
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
mem_addr_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;
|
mem_cnt_next <= 0;
|
||||||
when FIND_NEXT_ENDPOINT =>
|
when GET_NEXT_ENDPOINT =>
|
||||||
-- Memory Bound Guard
|
-- Memory Bound Guard
|
||||||
if (addr_res /= max_endpoint_addr) then
|
if (mem_addr_base /= max_endpoint_addr) then
|
||||||
-- Reached End of Memory, No match
|
-- 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_base_next <= tmp;
|
||||||
mem_addr_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;
|
mem_cnt_next <= 0;
|
||||||
else
|
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;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
@ -1282,84 +1369,77 @@ begin
|
|||||||
null;
|
null;
|
||||||
-- Entity ID
|
-- Entity ID
|
||||||
when 1 =>
|
when 1 =>
|
||||||
-- No Match (Ignore Entity ID match on Participant Search, but skip empty Slot)
|
-- No Match (Ignore Entity ID match on Participant Endpoint 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
|
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
|
-- Reached End of Memory, No Match
|
||||||
if (mem_addr_base = max_endpoint_addr) then
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
case (mem_ctrl_data.mem_opcode) is
|
mem_addr_base_next <= MAX_ADDRESS; --No match
|
||||||
when INSERT_ENDPOINT =>
|
-- DONE
|
||||||
-- Insert new Endpoint
|
mem_stage_next <= IDLE;
|
||||||
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;
|
|
||||||
else
|
else
|
||||||
-- Continue Search
|
-- Continue Search
|
||||||
mem_addr_next <= tmp;
|
mem_addr_next <= tmp;
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= tmp;
|
||||||
|
mem_pos_next <= mem_pos + 1;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
-- GUID Prefix 1/3
|
-- GUID Prefix 1/3
|
||||||
when 2 =>
|
when 2 =>
|
||||||
-- No Match
|
-- No Match
|
||||||
if (mem_read_data /= guid(0)) then
|
if (mem_read_data /= mem_ctrl_data.guid(0)) then
|
||||||
-- Continue Search
|
-- Reached End of Memory, No Match
|
||||||
mem_addr_next <= tmp;
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= MAX_ADDRESS; --No match
|
||||||
mem_cnt_next <= 0;
|
-- 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;
|
end if;
|
||||||
-- GUID Prefix 2/3
|
-- GUID Prefix 2/3
|
||||||
when 3 =>
|
when 3 =>
|
||||||
-- No Match
|
-- No Match
|
||||||
if (mem_read_data /= guid(1)) then
|
if (mem_read_data /= mem_ctrl_data.guid(1)) then
|
||||||
-- Continue Search
|
-- Reached End of Memory, No Match
|
||||||
mem_addr_next <= tmp;
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= MAX_ADDRESS; --No match
|
||||||
mem_cnt_next <= 0;
|
-- 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;
|
end if;
|
||||||
-- GUID Prefix 3/3
|
-- GUID Prefix 3/3
|
||||||
when 4 =>
|
when 4 =>
|
||||||
-- No Match
|
-- No Match
|
||||||
if (mem_read_data /= guid(2)) then
|
if (mem_read_data /= mem_ctrl_data.guid(2)) then
|
||||||
-- Continue Search
|
-- Reached End of Memory, No Match
|
||||||
mem_addr_next <= tmp;
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= MAX_ADDRESS; --No match
|
||||||
mem_cnt_next <= 0;
|
-- 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
|
-- Match
|
||||||
else
|
else
|
||||||
case (mem_ctrl_data.mem_opcode) is
|
mem_addr_base_next <= mem_addr_base;
|
||||||
when REMOVE_PARTICIPANT =>
|
-- Fetch Endpoint Data
|
||||||
addr_res_next <= mem_addr_base;
|
mem_stage_next <= GET_ENDPOINT_DATA;
|
||||||
-- Remove Endpoint from remote Participant
|
mem_cnt_next <= 1; -- No preload needed
|
||||||
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;
|
|
||||||
end if;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
@ -1528,21 +1608,14 @@ begin
|
|||||||
mem_wr <= '1';
|
mem_wr <= '1';
|
||||||
mem_write_data <= ENTITYID_UNKNOWN;
|
mem_write_data <= ENTITYID_UNKNOWN;
|
||||||
|
|
||||||
if (mem_ctrl_data.mem_opcode = REMOVE_PARTICIPANT) then
|
-- Reset MAX Endpoint Pointer
|
||||||
-- Continue Participant Match Search
|
mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
mem_addr_base_next <= addr_res;
|
mem_addr_next <= FIRST_ENDPOINT_ADDRESS;
|
||||||
mem_addr_next <= addr_res;
|
mem_pos_next <= 0;
|
||||||
mem_stage_next <= SEARCH_ENDPOINT;
|
reset_max_pointer_next <= '1';
|
||||||
mem_cnt_next <= 0;
|
last_addr_next <= (others => '0');
|
||||||
else
|
mem_stage_next <= FIND_ENDPOINT_SLOT;
|
||||||
-- Reset MAX Endpoint Pointer
|
mem_cnt_next <= 0;
|
||||||
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;
|
|
||||||
when FIND_ENDPOINT_SLOT =>
|
when FIND_ENDPOINT_SLOT =>
|
||||||
mem_rd <= '1';
|
mem_rd <= '1';
|
||||||
mem_addr_next <= mem_addr + 1;
|
mem_addr_next <= mem_addr + 1;
|
||||||
@ -1570,16 +1643,18 @@ begin
|
|||||||
report "Memory Full, Ignoring Endpoint Data" severity NOTE;
|
report "Memory Full, Ignoring Endpoint Data" severity NOTE;
|
||||||
-- Ignore Insertion
|
-- Ignore Insertion
|
||||||
mem_stage_next <= IDLE;
|
mem_stage_next <= IDLE;
|
||||||
addr_res_next <= MAX_ADDRESS;
|
mem_addr_base_next <= MAX_ADDRESS;
|
||||||
else
|
else
|
||||||
-- Extend Endpoint Memory Area
|
-- Extend Endpoint Memory Area
|
||||||
-- NOTE: "max_endpoint_addr" points to the first address of last Endpoint Frame
|
-- NOTE: "max_endpoint_addr" points to the first address of last Endpoint Frame
|
||||||
max_endpoint_addr_next <= tmp;
|
max_endpoint_addr_next <= tmp;
|
||||||
-- Populate Endpoint Slot
|
-- Populate Endpoint Slot
|
||||||
mem_stage_next <= INSERT_ENDPOINT;
|
mem_stage_next <= INSERT_ENDPOINT;
|
||||||
mem_addr_next <= tmp;
|
mem_addr_base_next <= tmp;
|
||||||
addr_res_next <= tmp;
|
mem_addr_next <= tmp;
|
||||||
mem_cnt_next <= 0;
|
mem_pos_next <= mem_pos + 1;
|
||||||
|
mem_addr_base_next <= tmp;
|
||||||
|
mem_cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
-- Latch last occupied Endpoint Slot
|
-- Latch last occupied Endpoint Slot
|
||||||
@ -1587,10 +1662,12 @@ begin
|
|||||||
-- Continue Search
|
-- Continue Search
|
||||||
mem_addr_next <= tmp;
|
mem_addr_next <= tmp;
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= tmp;
|
||||||
|
mem_pos_next <= mem_pos + 1;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
-- Slot Empty
|
-- Slot Empty
|
||||||
else
|
else
|
||||||
|
-- We are in the middle of resetting the MAX Endpoint Pointer
|
||||||
if (reset_max_pointer = '1') then
|
if (reset_max_pointer = '1') then
|
||||||
-- Make sure to iterate through complete Endpoint Area
|
-- Make sure to iterate through complete Endpoint Area
|
||||||
if (mem_addr_base = max_endpoint_addr) then
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
@ -1602,20 +1679,20 @@ begin
|
|||||||
-- Continue Search
|
-- Continue Search
|
||||||
mem_addr_next <= tmp;
|
mem_addr_next <= tmp;
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= tmp;
|
||||||
|
mem_pos_next <= mem_pos + 1;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
else
|
else
|
||||||
-- Populate Endpoint Slot
|
-- Populate Endpoint Slot
|
||||||
mem_stage_next <= INSERT_ENDPOINT;
|
mem_stage_next <= INSERT_ENDPOINT;
|
||||||
mem_addr_next <= mem_addr_base;
|
mem_addr_next <= mem_addr_base;
|
||||||
addr_res_next <= mem_addr_base;
|
mem_cnt_next <= 0;
|
||||||
mem_cnt_next <= 0;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when others =>
|
when others =>
|
||||||
null;
|
null;
|
||||||
end case;
|
end case;
|
||||||
when FIND_NEXT_ENDPOINT =>
|
when GET_NEXT_ENDPOINT =>
|
||||||
mem_rd <= '1';
|
mem_rd <= '1';
|
||||||
mem_cnt_next <= mem_cnt + 1;
|
mem_cnt_next <= mem_cnt + 1;
|
||||||
mem_addr_next <= mem_addr + 1;
|
mem_addr_next <= mem_addr + 1;
|
||||||
@ -1634,21 +1711,21 @@ begin
|
|||||||
-- Slot Occupied
|
-- Slot Occupied
|
||||||
if (mem_read_data /= ENTITYID_UNKNOWN) then
|
if (mem_read_data /= ENTITYID_UNKNOWN) then
|
||||||
-- Get Endpoint Data
|
-- Get Endpoint Data
|
||||||
mem_addr_next <= tmp2;
|
mem_addr_next <= tmp2;
|
||||||
addr_res_next <= mem_addr_base;
|
mem_stage_next <= GET_ENDPOINT_DATA;
|
||||||
mem_stage_next <= GET_ENDPOINT_DATA;
|
mem_cnt_next <= 0;
|
||||||
mem_cnt_next <= 0;
|
|
||||||
-- Slot Empty
|
-- Slot Empty
|
||||||
else
|
else
|
||||||
-- Reached End of Memory, No Match
|
-- Reached End of Memory, No Match
|
||||||
if (mem_addr_base = max_endpoint_addr) then
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
addr_res_next <= MAX_ADDRESS; --No match
|
mem_addr_base_next <= MAX_ADDRESS; --No match
|
||||||
-- DONE
|
-- DONE
|
||||||
mem_stage_next <= IDLE;
|
mem_stage_next <= IDLE;
|
||||||
else
|
else
|
||||||
-- Continue Search
|
-- Continue Search
|
||||||
mem_addr_next <= tmp;
|
mem_addr_next <= tmp;
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= tmp;
|
||||||
|
mem_pos_next <= mem_pos + 1;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
@ -1682,13 +1759,14 @@ begin
|
|||||||
else
|
else
|
||||||
-- Reached End of Memory, No Match
|
-- Reached End of Memory, No Match
|
||||||
if (mem_addr_base = max_endpoint_addr) then
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
addr_res_next <= MAX_ADDRESS; --No match
|
mem_addr_base_next <= MAX_ADDRESS; --No match
|
||||||
-- DONE
|
-- DONE
|
||||||
mem_stage_next <= IDLE;
|
mem_stage_next <= IDLE;
|
||||||
else
|
else
|
||||||
-- Continue Search
|
-- Continue Search
|
||||||
mem_addr_next <= tmp;
|
mem_addr_next <= tmp;
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= tmp;
|
||||||
|
mem_pos_next <= mem_pos + 1;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
@ -1704,7 +1782,6 @@ begin
|
|||||||
-- Lease Deadline passed
|
-- Lease Deadline passed
|
||||||
if (tmp_dw < time) then
|
if (tmp_dw < time) then
|
||||||
-- Mark Endpoint as stale
|
-- Mark Endpoint as stale
|
||||||
addr_res_next <= mem_addr_base;
|
|
||||||
mem_endpoint_data_next <= ZERO_ENDPOINT_DATA;
|
mem_endpoint_data_next <= ZERO_ENDPOINT_DATA;
|
||||||
-- DONE
|
-- DONE
|
||||||
mem_stage_next <= IDLE;
|
mem_stage_next <= IDLE;
|
||||||
@ -1718,21 +1795,21 @@ begin
|
|||||||
-- Response/Suppression Time passed
|
-- Response/Suppression Time passed
|
||||||
if (tmp_dw /= 0 and tmp_dw < time) then
|
if (tmp_dw /= 0 and tmp_dw < time) then
|
||||||
-- Mark Endpoint and get Endpoint Data
|
-- Mark Endpoint and get Endpoint Data
|
||||||
addr_res_next <= mem_addr_base;
|
mem_addr_next <= tmp2;
|
||||||
mem_addr_next <= tmp2;
|
mem_stage_next <= GET_ENDPOINT_DATA;
|
||||||
mem_stage_next <= GET_ENDPOINT_DATA;
|
mem_cnt_next <= 0;
|
||||||
mem_cnt_next <= 0;
|
|
||||||
-- Endpoint not Stale
|
-- Endpoint not Stale
|
||||||
else
|
else
|
||||||
-- Reached End of Memory, No Match
|
-- Reached End of Memory, No Match
|
||||||
if (mem_addr_base = max_endpoint_addr) then
|
if (mem_addr_base = max_endpoint_addr) then
|
||||||
addr_res_next <= MAX_ADDRESS; --No match
|
mem_addr_base_next <= MAX_ADDRESS; --No match
|
||||||
-- DONE
|
-- DONE
|
||||||
mem_stage_next <= IDLE;
|
mem_stage_next <= IDLE;
|
||||||
else
|
else
|
||||||
-- Continue Search
|
-- Continue Search
|
||||||
mem_addr_next <= tmp;
|
mem_addr_next <= tmp;
|
||||||
mem_addr_base_next <= tmp;
|
mem_addr_base_next <= tmp;
|
||||||
|
mem_pos_next <= mem_pos + 1;
|
||||||
mem_cnt_next <= 0;
|
mem_cnt_next <= 0;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
@ -85,6 +85,7 @@ package rtps_package is
|
|||||||
constant GUIDPREFIX_UNKNOWN : GUIDPREFIX_TYPE := (others => (others => '0'));
|
constant GUIDPREFIX_UNKNOWN : GUIDPREFIX_TYPE := (others => (others => '0'));
|
||||||
constant UDP_PORT_INVALID : std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := (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 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*
|
-- *SUBMESSAGE IDs*
|
||||||
constant SID_PAD : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"01";
|
constant SID_PAD : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"01";
|
||||||
@ -279,9 +280,9 @@ package rtps_package is
|
|||||||
-- DEPTH (HISTORY)
|
-- DEPTH (HISTORY)
|
||||||
constant DEFAULT_HISTORY_DEPTH : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_LONG_WIDTH));
|
constant DEFAULT_HISTORY_DEPTH : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,CDR_LONG_WIDTH));
|
||||||
-- RESOURCE_LIMITS
|
-- 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_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) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- 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) := 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) := LENGTH_UNLIMITED;
|
||||||
-- WRITER_DATA_LIFECYCLE
|
-- WRITER_DATA_LIFECYCLE
|
||||||
constant DEFAULT_AUTODISPOSE_UNREGISTERED_INSTANCES : boolean := TRUE;
|
constant DEFAULT_AUTODISPOSE_UNREGISTERED_INSTANCES : boolean := TRUE;
|
||||||
-- READER_DATA_LIFECYCLE
|
-- 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_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 : 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_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_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) := 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) := 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_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)
|
constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE; -- Deferred to package Body (100 s)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user