Fix unaligned payload handling in DDS Reader

Since the payload can only be padded until the next 4-byte aligned
address, we needed a way to read out only the actual payload in case the
payload was not aligned in the last payload slot (did not go until the
end of the payload slot). This is now handled by an additional bit flag
in the Sample Status Info which denotes if the payload is aligned. In
the case the payload is unaligned, the last address of the last payload
slot contains the offset of the actual payload end.
This commit also adds MEMORY RESET states for the Sample, payload, and
instance Memory.
This commit is contained in:
Greek 2021-02-08 12:31:36 +01:00
parent e8670aaf59
commit 80cffb8197
5 changed files with 303 additions and 140 deletions

View File

@ -348,9 +348,9 @@ WRITER
03| |
+-------------------------------------------------------------+
04| IPv4_ADDRESS |
+-----------------------------+-------------------------+-+-+-+
05| UDP_PORT | UNUSED |B|H|Q|
+-----------------------------+-------------------------+-+-+-+
+-----------------------------+-------------------------------+
05| UDP_PORT | READER_FLAGS |
+-----------------------------+-------------------------------+
06| |
+ LEASE_DEADLINE + [Reliable Only]
07| |
@ -370,6 +370,16 @@ WRITER
14| REQ_BITMAP | [Reliable Only]
+-------------------------------------------------------------+
READER_FLAGS
------------
16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------+-+-+-+
| UNUSED |B|H|Q|
+-------------------------+-+-+-+
Q...Reader expects in-line QoS
H...Reader expects Historical Data
B...Reader has RELIABILITY BEST_EFFORT
HISTORY CACHE
=============
@ -434,12 +444,13 @@ STATUS INFO
-----------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-------------------------------------------------+-+-+-+
|R|P|K| UNUSED |F|U|D|
+-+-+-+-------------------------------------------------+-+-+-+
+-+-+-+-+-----------------------------------------------+-+-+-+
|R|P|A|K| UNUSED |F|U|D|
+-+-+-+-+-----------------------------------------------+-+-+-+
R...Sample has been Read
P...Sample has associated Payload
A...Associated Payload is aligned (Payload does extend until end of last Palyload Slot)
K...Key Hash available
F...FilteredFlag
@ -458,8 +469,10 @@ PAYLOAD MEMORY
**| |
+-------------------------------------------------------------+
HISTORY CACHE INPUT
===================
DDS ENTITY INPUT
================
READER
------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+

View File

@ -72,6 +72,8 @@
* The Lease Duration is also updated if the Cache Change is not accepted by the DDS/HC. This in effect "skews" the "correctness" of the Writer Liveliness Protocol until the reader has no pending request from the Writer.
* If an Instance is DISPOSED, but later has no active writers, the Instance STAYS in the NOT_ALIVE_DISPOSED state.
* Is a Writer that is Disposing a Instance also Unregistering that instance? (Currently only Unregistering removes the remote Writer)
- No
* Since Lifespan is a duration, there is an inherent difference in the expiration time between writer and reader. This in addition to the fact that the reader may use the Reception time for the expiration time calculation could lead to an actual expiration duration almost double in length (If sent right before expiring locally in the writer).
* Fast-RTPS doen not follow DDSI-RTPS Specification
- Open Github Issue
@ -191,10 +193,16 @@ DESIGN DECISIONS
sizes are adjusted according to that), or may be variable, in which case the payload is stored in
a linked list of predefined sized memory frames. The first word of a payload contains the address
of the next linked memory frame. If this is the last frame (or if the payload is static and there
are no linked frames), the address is MAX_ADDRESS. The last bit of this address is the "occupied"
bit. This bit signifies if the memory frame is used or free, and is used for the insert operation
to find a new empty slot. This in effect means that all frame sizes have to be a multiple of 2
(all frame addresses have to be aligned to 2).
are no linked frames), the address is MAX_ADDRESS.
* !REJECTED! The last bit of this address is the "occupied" bit. This bit signifies if the memory
frame is used or free, and is used for the insert operation to find a new empty slot. This in
effect means that all frame sizes have to be a multiple of 2 (all frame addresses have to be
aligned to 2).
* If the last payload slot of a variable sized payload is not aligned with the actual end of the
Payload slot, we mark this via a bit in the sample info memory, and store the last address of the
actual payload in the last address of the payload slot.
* !REJECTED! The History Cache (HC) is the interface between RTPS and DDS. The History Cache contains
the Sample Info and Payload memories. The HC has two input "sides", one is connected to the DDS
@ -224,6 +232,7 @@ DESIGN DECISIONS
sense to implement dual port RAMs for the History Cache.
PROTOCOL UNCOMPLIANCE
=====================
* Partition QoS

View File

@ -78,7 +78,7 @@ architecture arch of dds_reader is
-- Highest Sample Info Memory Address
constant SAMPLE_MEMORY_MAX_ADDRESS : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := to_unsigned(SAMPLE_MEMORY_SIZE-1, SAMPLE_MEMORY_ADDR_WIDTH);
-- Highest Sample Info Frame Address
constant MAX_SAMPLE_ADDRESS : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := SAMPLE_MEMORY_MAX_ADDRESS - SAMPLE_INFO_FRAME_SIZE + 1;
constant MAX_SAMPLE_ADDRESS : unsigned(SAMPLE_MEMORY_ADDR_WIDTH-1 downto 0) := SAMPLE_MEMORY_MAX_ADDRESS - SAMPLE_FRAME_SIZE + 1;
-- *PAYLOAD MEMORY*
-- Payload Memory Size in 4-Byte Words
@ -143,7 +143,7 @@ architecture arch of dds_reader is
--*****TYPE DECLARATION*****
-- FSM states. Explained below in detail
type STAGE_TYPE is (IDLE, UNKNOWN_OPERATION, ADD_SAMPLE_INFO, ADD_PAYLOAD_ADDRESS, ADD_PAYLOAD, NEXT_PAYLOAD_SLOT, ZERO_PAYLOAD, GET_KEY_HASH, INITIATE_INSTANCE_SEARCH,
type STAGE_TYPE is (IDLE, UNKNOWN_OPERATION, ADD_SAMPLE_INFO, ADD_PAYLOAD_ADDRESS, ADD_PAYLOAD, NEXT_PAYLOAD_SLOT, ALIGN_PAYLOAD, GET_KEY_HASH, INITIATE_INSTANCE_SEARCH,
FILTER_STAGE, UPDATE_INSTANCE, FINALIZE_PAYLOAD, PRE_SAMPLE_FINALIZE, FIND_POS, FIX_POINTERS, FINALIZE_SAMPLE, GET_OLDEST_SAMPLE_INSTANCE, FIND_OLDEST_INST_SAMPLE,
REMOVE_SAMPLE, POST_SAMPLE_REMOVE, SKIP_ADD_REJECT, SKIP_ADD_DROP, REMOVE_WRITER, REMOVE_STALE_INSTANCE, GET_NEXT_SAMPLE, PRE_CALCULATE, FINALIZE_SAMPLE_INFO,
GET_PAYLOAD, FIND_NEXT_INSTANCE, CHECK_INSTANCE, CHECK_LIFESPAN, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS, CHECK_DEADLINE);
@ -411,13 +411,13 @@ architecture arch of dds_reader is
alias cur_payload : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_1;
alias cur_payload_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_1_next;
alias next_payload : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_2;
alias next_payload_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_2_next;
alias next_payload_next : unsigned(PAYLOAD_MEMORY_ADDR_WIDTH-1 downto 0) is payload_addr_latch_2_next;
alias cur_inst : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_1;
alias cur_inst_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_1_next;
alias next_inst : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_2;
alias next_inst_next : unsigned(INSTANCE_MEMORY_ADDR_WIDTH-1 downto 0) is inst_addr_latch_2_next;
alias has_data : std_logic is sample_status_info(PAYLOAD_FLAG);
alias has_key_hash : std_logic is sample_status_info(KEY_HASH_FLAG);
alias has_data : std_logic is sample_status_info(SSI_PAYLOAD_FLAG);
alias has_key_hash : std_logic is sample_status_info(SSI_KEY_HASH_FLAG);
-- *FUNCTION DECLARATION*
function to_unsigned(input : KEY_HASH_TYPE) return unsigned is
@ -532,7 +532,7 @@ begin
-- ADD_PAYLOAD_ADDRESS Store payload pointer.
-- ADD_PAYLOAD Push payload to memory and key hash generator (as needed)
-- NEXT_PAYLOAD_SLOT Get pointer to next empty payload slot
-- ZERO_PAYLOAD Fill rest of payload slot with zeroes
-- ALIGN_PAYLOAD Store the offset of the actual payload in the last address of the last payload slot.
-- GET_KEY_HASH Fetch the calculated key hash from the Key Hash Generator
-- INITIATE_INSTANCE_SEARCH Initiate Instance Search Memory Operation. This state is used to start the Search operation as soon as the required data is available
-- FILTER_STAGE This state decides if the RTPS Cache Change is accepted, dropped, or rejected. It also decides what sample (if any) has to be removed.
@ -678,9 +678,9 @@ begin
stage_next <= CHECK_DEADLINE;
cnt_next <= 0;
else
if (inst_data.status_info(LIVELINESS_FLAG) = '1') then
if (inst_data.status_info(ISI_LIVELINESS_FLAG) = '1') then
-- Reset Liveliness Flag
inst_data_next.status_info(LIVELINESS_FLAG) <= '0';
inst_data_next.status_info(ISI_LIVELINESS_FLAG) <= '0';
else
-- Update Requested Deadline Missed Status
status_sig_next(REQUESTED_DEADLINE_MISSED_STATUS) <= '1';
@ -729,8 +729,8 @@ begin
inst_data_next.writer_bitmap <= from_endpoint_bitmap(tmp_bitmap);
-- NOT_ALIVE_NO_WRITERS Transition
if (tmp_bitmap = (tmp_bitmap'range => '0') and inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0') then
inst_data_next.status_info(NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
if (tmp_bitmap = (tmp_bitmap'range => '0') and inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
inst_data_next.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
end if;
end if;
when others =>
@ -892,14 +892,16 @@ begin
case (cnt) is
-- Status Info
when 0 =>
-- NOTE: The PAYLOAD_FLAG, ALIGNED_FLAG, and KEY_HASH_FLAG are set by the RTPS Reader
-- NOTE: The ALIGNED_FLAG is set by default. if actual Payload is not aligned, need to reset.
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET;
sample_write_data <= data_in_rtps;
-- Initialize local status bits
sample_write_data(READ_FLAG) <= '0';
sample_write_data(SSI_READ_FLAG) <= '0';
-- Latch Status Info
sample_status_info_next <= data_in_rtps;
sample_status_info_next(READ_FLAG) <= '0';
sample_status_info_next <= data_in_rtps;
sample_status_info_next(SSI_READ_FLAG) <= '0';
-- Memory Flow Control Guard
if (sample_ready_in = '1') then
ready_in_rtps <= '1';
@ -1050,20 +1052,18 @@ begin
payload_write_data <= data_in_rtps;
-- Memory Control Flow Guard
if (payload_ready_in = '1') then
cnt2_next <= cnt2 + 1;
-- Key Hash needs to be calculated
if (WITH_KEY and has_key_hash = '0') then
cnt_next <= 1;
cnt_next <= cnt + 1;
else
ready_in_rtps <= '1';
-- End of Payload
if (last_word_in_rtps = '1') then
-- End of Payload Slot
if (cnt2 = PAYLOAD_FRAME_SIZE-1) then
stage_next <= FILTER_STAGE;
stage_next <= FILTER_STAGE;
else
stage_next <= ZERO_PAYLOAD;
stage_next <= ALIGN_PAYLOAD;
end if;
else
-- End of Payload Slot
@ -1072,7 +1072,7 @@ begin
cnt_next <= 0;
else
-- Next Word
cnt_next <= 0;
cnt2_next <= cnt2 + 1;
end if;
end if;
end if;
@ -1099,7 +1099,7 @@ begin
stage_next <= GET_KEY_HASH;
cnt_next <= 0;
else
stage_next <= ZERO_PAYLOAD;
stage_next <= ALIGN_PAYLOAD;
end if;
else
-- End of Payload Slot
@ -1109,6 +1109,7 @@ begin
else
-- Next Word
cnt_next <= 0;
cnt2_next <= cnt2 + 1;
end if;
end if;
else
@ -1119,7 +1120,7 @@ begin
cnt_next <= 0;
else
-- Next Word
cnt_next <= 1;
cnt_next <= 1; -- Same Sub-state
end if;
end if;
end if;
@ -1164,24 +1165,37 @@ begin
when others =>
null;
end case;
when ZERO_PAYLOAD =>
-- Zero Payload
payload_valid_in <= '1';
payload_addr <= cur_payload + cnt2;
payload_write_data <= (others => '0');
-- Memory Control Flow Guard
if (payload_ready_in = '1') then
-- Exit Condition
if (cnt2 = PAYLOAD_FRAME_SIZE-1) then
if (WITH_KEY and has_key_hash = '0') then
stage_next <= GET_KEY_HASH;
cnt_next <= 0;
else
stage_next <= FILTER_STAGE;
when ALIGN_PAYLOAD =>
case (cnt) is
-- Mark Payload as unaligned
when 0 =>
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET;
sample_write_data <= sample_status_info;
sample_write_data(SSI_ALIGNED_FLAG) <= '0';
-- Memory Control Flow Guard
if (sample_ready_in = '1') then
cnt_next <= cnt + 1;
end if;
end if;
end if;
-- Store Payload End Offset
when 1 =>
payload_valid_in <= '1';
payload_addr <= cur_payload + PAYLOAD_FRAME_SIZE-1;
payload_write_data <= to_unsigned(cnt2, WORD_WIDTH);
-- Memory Control Flow Guard
if (payload_ready_in = '1') then
if (WITH_KEY and has_key_hash = '0') then
stage_next <= GET_KEY_HASH;
cnt_next <= 0;
else
stage_next <= FILTER_STAGE;
end if;
end if;
when others =>
null;
end case;
when GET_KEY_HASH =>
-- Synthesis Guard
if (WITH_KEY) then
@ -1316,7 +1330,7 @@ begin
res_rtps <= ACCEPTED;
-- Only Insert Sample/Instance if Instance is ALIVE
if (sample_status_info(DISPOSED_FLAG) /= '1' and sample_status_info(UNREGISTERED_FLAG) /= '1' and sample_status_info(FILTERED_FLAG) /= '1') then
if (sample_status_info(SSI_DISPOSED_FLAG) /= '1' and sample_status_info(SSI_UNREGISTERED_FLAG) /= '1' and sample_status_info(SSI_FILTERED_FLAG) /= '1') then
-- Insert New Instance
inst_op_start <= '1';
inst_opcode <= INSERT_INSTANCE;
@ -1340,7 +1354,7 @@ begin
res_rtps <= ACCEPTED;
-- Only Insert Sample/Instance if Instance is ALIVE
if (sample_status_info(DISPOSED_FLAG) /= '1' and sample_status_info(UNREGISTERED_FLAG) /= '1' and sample_status_info(FILTERED_FLAG) /= '1') then
if (sample_status_info(SSI_DISPOSED_FLAG) /= '1' and sample_status_info(SSI_UNREGISTERED_FLAG) /= '1' and sample_status_info(SSI_FILTERED_FLAG) /= '1') then
-- Insert New Instance
inst_op_start <= '1';
inst_opcode <= INSERT_INSTANCE;
@ -1367,23 +1381,23 @@ begin
tmp_update := (others => '0');
-- Instance DISPOSED
if (sample_status_info(DISPOSED_FLAG) = '1') then
if (sample_status_info(SSI_DISPOSED_FLAG) = '1') then
-- ALIVE -> NOT_ALIVE_DISPOSED Transition
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) /= '1' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) /= '1') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) /= '1' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) /= '1') then
-- STATUS INFO
-- Synthesis Guard
if (WITH_KEY) then
tmp_update <= tmp_update or IMF_STATUS_FLAG;
status_info_update <= inst_data.status_info;
status_info_update(NOT_ALIVE_DISPOSED_FLAG) <= '1';
status_info_update(LIVELINESS_FLAG) <= '1';
status_info_update(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '1';
status_info_update(ISI_LIVELINESS_FLAG) <= '1';
else
inst_data_next.status_info(NOT_ALIVE_DISPOSED_FLAG) <= '1';
inst_data_next.status_info(LIVELINESS_FLAG) <= '1';
inst_data_next.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '1';
inst_data_next.status_info(ISI_LIVELINESS_FLAG) <= '1';
end if;
end if;
-- Instance UNREGISTERED
elsif (sample_status_info(UNREGISTERED_FLAG) = '1') then
elsif (sample_status_info(SSI_UNREGISTERED_FLAG) = '1') then
-- WRITER BITMAP
-- Convert Writer Bitmap to SLV
tmp_bitmap := to_endpoint_bitmap(inst_data.writer_bitmap);
@ -1400,17 +1414,17 @@ begin
end if;
-- ALIVE -> NOT_ALIVE_NO_WRITERS Transition
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) /= '1' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) /= '1' and tmp_bitmap = (tmp_bitmap => '0')) then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) /= '1' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) /= '1' and tmp_bitmap = (tmp_bitmap => '0')) then
-- STATUS INFO
-- Synthesis Guard
if (WITH_KEY) then
tmp_update <= tmp_update or IMF_STATUS_FLAG;
status_info_update <= inst_data.status_info;
status_info_update(NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
status_info_update(LIVELINESS_FLAG) <= '1';
status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
status_info_update(ISI_LIVELINESS_FLAG) <= '1';
else
inst_data_next.status_info(NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
inst_data_next.status_info(LIVELINESS_FLAG) <= '1';
inst_data_next.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
inst_data_next.status_info(ISI_LIVELINESS_FLAG) <= '1';
end if;
end if;
-- Instance ALIVE/FILTERED
@ -1420,19 +1434,19 @@ begin
if (WITH_KEY) then
tmp_update <= tmp_update or IMF_STATUS_FLAG;
status_info_update <= inst_data.status_info;
status_info_update(NOT_ALIVE_DISPOSED_FLAG) <= '0';
status_info_update(NOT_ALIVE_NO_WRITERS_FLAG) <= '0';
status_info_update(LIVELINESS_FLAG) <= '1';
status_info_update(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '0';
status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '0';
status_info_update(ISI_LIVELINESS_FLAG) <= '1';
else
inst_data_next.status_info(NOT_ALIVE_DISPOSED_FLAG) <= '0';
inst_data_next.status_info(NOT_ALIVE_NO_WRITERS_FLAG) <= '0';
inst_data_next.status_info(LIVELINESS_FLAG) <= '1';
inst_data_next.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) <= '0';
inst_data_next.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '0';
inst_data_next.status_info(ISI_LIVELINESS_FLAG) <= '1';
end if;
-- GENERATION COUNTERS
-- NOT_ALIVE_DISPOSED -> ALIVE Transition
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1') then
-- Synthesis Guard
if (WITH_KEY) then
tmp_update := tmp_update or IMF_DISPOSED_CNT_FLAG;
@ -1441,7 +1455,7 @@ begin
inst_data_next.disposed_gen_cnt <= inst_data.disposed_gen_cnt + 1;
end if;
-- NOT_ALIVE_NO_WRITERS -> ALIVE Transition
elsif (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
elsif (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
-- Synthesis Guard
if (WITH_KEY) then
tmp_update := tmp_update or IMF_NO_WRITERS_CNT_FLAG;
@ -2218,9 +2232,9 @@ begin
writer_bitmap <= from_endpoint_bitmap(tmp_bitmap);
-- NOT_ALIVE_NO_WRITERS Transition
if (tmp_bitmap = (tmp_bitmap'range => '0') and inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0') then
if (tmp_bitmap = (tmp_bitmap'range => '0') and inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
status_info_update <= inst_data.status_info;
status_info_update(NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
status_info_update(ISI_NOT_ALIVE_NO_WRITERS_FLAG) <= '1';
inst_op_start <= '1';
inst_opcode <= UPDATE_INSTANCE;
inst_mem_fields <= IMF_STATUS_FLAG or IMF_WRITER_BITMAP_FLAG;
@ -2347,13 +2361,13 @@ begin
-- Check Sample State
case (sample_state) is
when READ_SAMPLE_STATE =>
if (sample_read_data(READ_FLAG) /= '1') then
if (sample_read_data(SSI_READ_FLAG) /= '1') then
-- Sample not in collection, Skip Sample
cnt_next <= 17;
sample_abort_read <= '1';
end if;
when NOT_READ_SAMPLE_STATE =>
if (sample_read_data(READ_FLAG) /= '0') then
if (sample_read_data(SSI_READ_FLAG) /= '0') then
-- Sample not in collection, Skip Sample
cnt_next <= 17;
sample_abort_read <= '1';
@ -2367,7 +2381,7 @@ begin
sample_abort_read <= '1';
end case;
if (sample_read_data(READ_FLAG) = '1') then
if (sample_read_data(SSI_READ_FLAG) = '1') then
si_sample_state_sig_next <= READ_SAMPLE_STATE;
else
si_sample_state_sig_next <= NOT_READ_SAMPLE_STATE;
@ -2447,19 +2461,19 @@ begin
-- Check Instance State
case (instance_state) is
when ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when ANY_INSTANCE_STATE =>
@ -2471,11 +2485,11 @@ begin
-- Check View State
case (view_state) is
when NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '0') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '1') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when ANY_VIEW_STATE =>
@ -2485,7 +2499,7 @@ begin
end case;
-- Check Instance Mark
if (inst_data.status_info(MARK_FLAG) = '1') then
if (inst_data.status_info(ISI_MARK_FLAG) = '1') then
-- Skip Marked Instance
tmp_bool := FALSE;
end if;
@ -2613,12 +2627,12 @@ begin
-- Exit Condition (Sample Selected)
if (first_sample = cur_sample) then
-- Sample not marked as Read
if (sample_status_info(READ_FLAG) /= '1') then
if (sample_status_info(SSI_READ_FLAG) /= '1') then
-- Mark Sample as Read
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET;
sample_write_data <= sample_status_info;
sample_write_data(READ_FLAG) <= '1';
sample_write_data(SSI_READ_FLAG) <= '1';
-- Memory Control Flow Guard
if (sample_ready_in = '1') then
stage_next <= FINALIZE_SAMPLE_INFO;
@ -2655,12 +2669,12 @@ begin
-- Exit Condition (Sample Selected)
if (first_sample = cur_sample) then
-- Sample not marked as Read
if (sample_status_info(READ_FLAG) /= '1') then
if (sample_status_info(SSI_READ_FLAG) /= '1') then
-- Mark Sample as Read
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_STATUS_INFO_OFFSET;
sample_write_data <= sample_status_info;
sample_write_data(READ_FLAG) <= '1';
sample_write_data(SSI_READ_FLAG) <= '1';
-- Memory Control Flow Guard
if (sample_ready_in = '1') then
-- Pre-Calculation already done for selected Instance (Or not necessary)
@ -2764,13 +2778,13 @@ begin
-- Check Sample State
case (sample_state) is
when READ_SAMPLE_STATE =>
if (sample_read_data(READ_FLAG) /= '1') then
if (sample_read_data(SSI_READ_FLAG) /= '1') then
-- Skip Sample
cnt_next <= 12;
sample_abort_read <= '1';
end if;
when NOT_READ_SAMPLE_STATE =>
if (sample_read_data(READ_FLAG) /= '0') then
if (sample_read_data(SSI_READ_FLAG) /= '0') then
-- Skip Sample
cnt_next <= 12;
sample_abort_read <= '1';
@ -2856,19 +2870,19 @@ begin
-- Check Instance State
case (instance_state) is
when ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when ANY_INSTANCE_STATE =>
@ -2880,11 +2894,11 @@ begin
-- Check View State
case (view_state) is
when NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '0') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '1') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when ANY_VIEW_STATE =>
@ -2894,7 +2908,7 @@ begin
end case;
-- Check Instance Mark
if (inst_data.status_info(MARK_FLAG) = '1') then
if (inst_data.status_info(ISI_MARK_FLAG) = '1') then
-- Skip Marked Instance
tmp_bool := FALSE;
end if;
@ -2934,16 +2948,16 @@ begin
-- Instance Data valid
if (not WITH_KEY or inst_addr_base = cur_inst) then
-- Sample Info View State
if (inst_data.status_info(VIEW_FLAG) = '1') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
si_view_state_sig_next <= NEW_VIEW_STATE;
else
si_view_state_sig_next <= NOT_NEW_VIEW_STATE;
end if;
-- Sample Info Instance State
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1') then
si_instance_state_sig_next <= NOT_ALIVE_DISPOSED_INSTANCE_STATE;
elsif (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
elsif (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
si_instance_state_sig_next <= NOT_ALIVE_NO_WRITERS_INSTANCE_STATE;
else
si_instance_state_sig_next <= ALIVE_INSTANCE_STATE;
@ -3023,20 +3037,20 @@ begin
unmark_instances_next <= '1';
else
-- Mark Instance
status_info_update(MARK_FLAG) <= '1';
status_info_update(ISI_MARK_FLAG) <= '1';
end if;
end if;
-- Instance is NOT_VIEWED and sample is from last generation of Instance
if (inst_data.status_info(VIEW_FLAG) = '0' and si_absolute_generation_count_sig = 0) then
if (inst_data.status_info(ISI_VIEW_FLAG) = '0' and si_absolute_generation_count_sig = 0) then
-- Mark Instance as VIEWED
status_info_update(VIEW_FLAG) <= '1';
status_info_update(ISI_VIEW_FLAG) <= '1';
end if;
else
-- Instance is NOT_VIEWED and sample is from last generation of Instance
if (inst_data.status_info(VIEW_FLAG) = '0' and si_absolute_generation_count_sig = 0) then
if (inst_data.status_info(ISI_VIEW_FLAG) = '0' and si_absolute_generation_count_sig = 0) then
-- Mark Instance as VIEWED
inst_data_next.status_info(VIEW_FLAG) <= '1';
inst_data_next.status_info(ISI_VIEW_FLAG) <= '1';
end if;
end if;
end if;
@ -3092,7 +3106,7 @@ begin
null;
end case;
when GET_PAYLOAD =>
-- Precondition: cur_payload set
-- Precondition: cur_payload set, sample_status_info set
-- DEFAULT
tmp_bool := FALSE;
@ -3115,11 +3129,37 @@ begin
-- Memory Flow Control Guard
if (payload_valid_out = '1') then
next_payload_next <= payload_read_data;
cnt_next <= cnt + 1;
cnt2 <= 1;
-- Last Payload Slot is unaligned
if (payload_read_data = PAYLOAD_MEMORY_MAX_ADDRESS and sample_status_info(SSI_ALIGNED_FLAG) = '0') then
cnt_next <= cnt + 1
else
cnt_next <= cnt + 3;
long_latch_next <= PAYLOAD_FRAME_SIZE-1;
end if;
end if;
-- GET Payload Offset
when 2 =>
payload_valid_in <= '1';
payload_addr <= cur_payload + PAYLOAD_FRAME_SIZE-1;
payload_read <= '1';
-- Memory Flow Control Guard
if (payload_ready_in = '1') then
cnt_next <= cnt + 1;
end if;
-- READ Payload Offset
when 3 =>
payload_ready_out <= '1';
-- Memory Flow Control Guard
if (payload_valid_out = '1') then
long_latch_next <= payload_read_data;
cnt_next <= cnt + 1;
end if;
-- GET PAYLOAD
when 3 =>
when 4 =>
payload_valid_in <= '1';
payload_addr <= cur_payload + cnt2;
payload_read <= '1';
@ -3129,7 +3169,7 @@ begin
cnt3_next <= cnt3 + 1;
tmp_bool := TRUE;
-- End of Payload Slot
if (cnt2 = PAYLOAD_FRAME_SIZE-1) then
if (cnt2 = unsigned(long_latch)) then
-- End of Payload
if (next_payload = PAYLOAD_MEMORY_MAX_ADDRESS) then
-- DONE (Wait for Output to finidh reading)
@ -3211,19 +3251,19 @@ begin
-- Check Instance State
case (instance_state) is
when ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when ANY_INSTANCE_STATE =>
@ -3235,11 +3275,11 @@ begin
-- Check View State
case (view_state) is
when NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '0') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '1') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when ANY_VIEW_STATE =>
@ -3290,19 +3330,19 @@ begin
-- Check Instance State
case (instance_state) is
when ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '1' or inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_DISPOSED_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_NO_WRITERS_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_ALIVE_INSTANCE_STATE =>
if (inst_data.status_info(NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
if (inst_data.status_info(ISI_NOT_ALIVE_DISPOSED_FLAG) = '0' and inst_data.status_info(ISI_NOT_ALIVE_NO_WRITERS_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when ANY_INSTANCE_STATE =>
@ -3314,11 +3354,11 @@ begin
-- Check View State
case (view_state) is
when NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '0') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '0') then
tmp_bool := FALSE;
end if;
when NOT_NEW_VIEW_STATE =>
if (inst_data.status_info(VIEW_FLAG) = '1') then
if (inst_data.status_info(ISI_VIEW_FLAG) = '1') then
tmp_bool := FALSE;
end if;
when ANY_VIEW_STATE =>
@ -3547,13 +3587,13 @@ begin
stage_next <= IDLE;
else
-- Instance received Sample
if (inst_data.status_info(LIVELINESS_FLAG) = '1') then
if (inst_data.status_info(ISI_LIVELINESS_FLAG) = '1') then
-- Reset Liveliness Flag
inst_op_start <= '1';
inst_opcode <= UPDATE_INSTANCE;
inst_mem_fields <= IMF_STATUS_FLAG;
status_info_update <= inst_data.status_info;
status_info_update(LIVELINESS_FLAG) <= '0';
status_info_update(ISI_LIVELINESS_FLAG) <= '0';
cnt_next <= 1;
else
-- Update Requested Deadline Missed Status
@ -3569,6 +3609,77 @@ begin
end case;
end if;
end if;
when RESET_SAMPLE_MEMORY =>
case (cnt) is
-- Initialize
when 0 =>
prev_sample_next <= SAMPLE_MEMORY_MAX_ADDRESS;
cur_sample_next <= (others => '0');
cnt_next <= cnt + 1;
-- Set Previous Pointer
when 1 =>
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_PREV_ADDR_OFFSET;
sample_write_data <= prev_sample;
-- Memory Flow Control Guard
if (sample_ready_in = '1') then
cnt_next <= cnt + 1;
end if;
-- Set Next Pointer
when 2 =>
sample_valid_in <= '1';
sample_addr <= cur_sample + SMF_NEXT_ADDR_OFFSET;
if (cur_sample = MAX_SAMPLE_ADDRESS) then
sample_write_data <= SAMPLE_MEMORY_MAX_ADDRESS;
else
sample_write_data <= cur_sample + SAMPLE_FRAME_SIZE;
end if;
-- Memory Flow Control Guard
if (sample_ready_in = '1') then
if (cur_sample = MAX_SAMPLE_ADDRESS) then
-- DONE
stage_next <= RESET_PAYLOAD_MEMORY;
cnt_next <= 0;
else
-- Continue
cur_sample_next <= cur_sample + SAMPLE_FRAME_SIZE;
prev_sample_next <= cur_sample;
cnt_next <= 1;
end if;
end if;
when others =>
null;
end case;
when RESET_PAYLOAD_MEMORY =>
case (inst_cnt) is
-- Initialize
when 0 =>
cur_payload_next <= (others => '0');
cnt_next <= cnt + 1;
-- Set Next Pointer
when 1 =>
payload_valid_in <= '1';
payload_addr <= cur_payload + PMF_NEXT_ADDR_OFFSET;
if (cur_payload = MAX_PAYLOAD_ADDRESS) then
payload_write_data <= PAYLOAD_MEMORY_MAX_ADDRESS;
else
payload_write_data <= cur_payload + PAYLOAD_FRAME_SIZE;
end if;
-- Memory Flow Control Guard
if (payload_ready_in = '1') then
if (cur_payload = MAX_PAYLOAD_ADDRESS) then
-- DONE
stage_next <= IDLE;
else
cur_payload_next <= cur_payload + PAYLOAD_FRAME_SIZE;
end if;
end if;
when others =>
null;
end case;
when others =>
null;
end case;
@ -5059,10 +5170,10 @@ begin
-- Memory Flow Control Guard
if (inst_valid_out = '1') then
-- MARK Flag Set
if (inst_read_data(MARK_FLAG) = '1') then
if (inst_read_data(ISI_MARK_FLAG) = '1') then
-- Latch Status Info (With MARK removed)
inst_long_latch_next <= inst_read_data;
inst_long_latch_next(MARK_FLAG) <= '0';
inst_long_latch_next(ISI_MARK_FLAG) <= '0';
inst_cnt_next <= inst_cnt + 1;
else
-- End of Instances
@ -5097,6 +5208,34 @@ begin
when others =>
null;
end case;
when RESET_MEMORY =>
case (inst_cnt) is
-- Initialize
when 0 =>
inst_addr_base_next <= FIRST_INSTANCE_ADDRESS;
inst_cnt_next <= inst_cnt + 1;
-- Set Next Pointer
when 1 =>
inst_valid_in <= '1';
inst_addr <= inst_addr_base + IMF_NEXT_ADDR_OFFSET;
if (inst_addr_base = MAX_INSTANCE_ADDRESS) then
inst_write_data <= INSTANCE_MEMORY_MAX_ADDRESS;
else
inst_write_data <= inst_addr_base + INSTANCE_FRAME_SIZE;
end if;
-- Memory Flow Control Guard
if (inst_ready_in = '1') then
if (inst_addr_base = MAX_INSTANCE_ADDRESS) then
-- DONE
inst_stage_next <= IDLE;
else
inst_addr_base_next <= inst_addr_base + INSTANCE_FRAME_SIZE;
end if;
end if;
when others =>
null;
end case;
when others =>
null;
end case;

View File

@ -53,22 +53,23 @@ package rtps_config_package is
type KEY_GENERATOR_OPCODE_TYPE is (NOP, WRITE_PAYLOAD, READ_KEY, READ_SIZE);
type HISTORY_CACHE_RESPONSE_TYPE is (UNDEFINED, ACK, ACCEPTED, REJECTED, INVALID);
-- TODO: Prefix the Flags with something that differntiates between them
-- Sample Status Info Flags
constant DISPOSED_FLAG : natural := STATUS_INFO_DISPOSED_FLAG;
constant UNREGISTERED_FLAG : natural := STATUS_INFO_UNREGISTERED_FLAG;
constant FILTERED_FLAG : natural := STATUS_INFO_FILTERED_FLAG;
constant KEY_HASH_FLAG : natural := 29;
constant PAYLOAD_FLAG : natural := 30;
constant READ_FLAG : natural := 31;
constant SSI_DISPOSED_FLAG : natural := STATUS_INFO_DISPOSED_FLAG;
constant SSI_UNREGISTERED_FLAG : natural := STATUS_INFO_UNREGISTERED_FLAG;
constant SSI_FILTERED_FLAG : natural := STATUS_INFO_FILTERED_FLAG;
constant SSI_KEY_HASH_FLAG : natural := 28;
constant SSI_ALIGNED_FLAG : natural := 29;
constant SSI_PAYLOAD_FLAG : natural := 30;
constant SSI_READ_FLAG : natural := 31;
-- Instance Status Info Flags
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;
constant MARK_FLAG : natural := 4;
constant ISI_NOT_ALIVE_DISPOSED_FLAG : natural := 0;
constant ISI_NOT_ALIVE_NO_WRITERS_FLAG : natural := 1;
constant ISI_LIVELINESS_FLAG : natural := 2;
constant ISI_VIEW_FLAG : natural := 3;
constant ISI_MARK_FLAG : natural := 4;
-- TODO: Prefix the Flags with something that differntiates between them
-- Remote Endpoint Flags
constant EXPECTS_INLINE_QOS_FLAG : natural := 0;
constant SEND_HISTORICAL_DATA_FLAG : natural := 1;

View File

@ -1149,9 +1149,10 @@ begin
-- Status Info
when 0 =>
valid_out_dds <= '1';
data_out_dds <= status_info;
data_out_dds(KEY_HASH_FLAG) <= key_hash_rcvd;
data_out_dds(PAYLOAD_FLAG) <= data_flag;
data_out_dds <= status_info;
data_out_dds(SSI_KEY_HASH_FLAG) <= key_hash_rcvd;
data_out_dds(SSI_PAYLOAD_FLAG) <= data_flag;
data_out_dds(SSI_ALIGNED_FLAG) <= data_flag;
-- Output Guard
if (ready_out_dds = '1') then
cnt_next <= cnt + 1;