* Package update

- New functions
	- Renames
	- New Definitions
* rtps_handler overhaul
	- Validity Check for Submessages
	- OVERREAD Guard
	- Info Timestamp parsed and sent to Endpoints
This commit is contained in:
Greek 2020-11-09 14:58:59 +01:00
parent 9acd98b32e
commit c68caec626
8 changed files with 854 additions and 403 deletions

View File

@ -1,3 +1,12 @@
RULES 8.3.4.1 (Message Receiver)
================================
* If the full Submessage header cannot be read, the rest of the Message is considered invalid.
* If submessageLength field is invalid, the rest of the Message is invalid.
* A Submessage with an unknown SubmessageId must be ignored and parsing must continue with the next Submessage.
* The receiver of a Submessage should ignore unknown flags.
* A valid submessageLength field must always be used to find the next Submessage.
* A known but invalid Submessage invalidates the rest of the Message.
RULES 8.4.2
===========
@ -85,10 +94,64 @@ ENDPOINT FIFO PACKET FORMAT
| |
+-------------------------------------------------------------+
| |
+ Timestamp +
| [only for DATA Submessage and User Destinations] |
+-------------------------------------------------------------+
| |
~ PAYLOAD (SUBMESSAGE CONTENT) ~
| |
+-------------------------------------------------------------+
HEARTBEAT PAYLOAD
-----------------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
| |
+ FirstSN +
| |
+-------------------------------------------------------------+
| |
+ LastSN +
| |
+-------------------------------------------------------------+
| Count |
+-------------------------------------------------------------+
ACKNACK PAYLOAD
---------------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
| |
+ ReaderSNState.BASE +
| |
+-------------------------------------------------------------+
| ReaderSNState.NumBits |
+-------------------------------------------------------------+
| [ReaderSNState.Bitmap] x 0-8 |
+-------------------------------------------------------------+
| Count |
+-------------------------------------------------------------+
GAP PAYLOAD
-----------
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
| |
+ GapStart +
| |
+-------------------------------------------------------------+
| |
+ GapList.BASE +
| |
+-------------------------------------------------------------+
| GapList.NumBits |
+-------------------------------------------------------------+
| [GapList.Bitmap] x 0-8 |
+-------------------------------------------------------------+
ENDPOINT_ID
===========
@ -306,3 +369,99 @@ implementations must include an InfoTimestamp Submessage with every update from
DDS_Advanced_Tutorial_2006_00-T1-2_Pardo.pdf (P.16)
INVALIDATION
============
RTPS HEADER (8.3.6.3)
-----------
* The Message has less than the required number of octets to contain a full Header
* Its protocol value does not match the value of PROTOCOL_RTPS
* The major protocol version is larger than the major protocol version supported by the implementation
ACKNACK (8.3.7.1.3)
-------
* submessageLength in the Submessage header is too small
* readerSNState is invalid
DATA (8.3.7.2.3)
----
* submessageLength in the Submessage header is too small
* writerSN.value is not strictly positive (1, 2, ...) or is SEQUENCENUMBER_UNKNOWN
* inlineQos is invalid
DATA FRAG (8.3.7.3.3)
---------
* submessageLength in the Submessage header is too small
* writerSN.value is not strictly positive (1, 2, ...) or is SEQUENCENUMBER_UNKNOWN
* fragmentStartingNum.value is not strictly positive (1, 2, ...) or exceeds the total number of fragments
* fragmentSize exceeds dataSize
* The size of serializedData exceeds (fragmentsInSubmessage * fragmentSize)
* inlineQos is invalid
GAP (8.3.7.4.3)
---
* submessageLength in the Submessage header is too small
* gapStart is zero or negative
* gapList is invalid
* (If GroupInfoFlag is set) gapStartGSN.value is zero or negative
* (If GroupInfoFlag is set) gapEndGSN.value is zero or negative
* (If GroupInfoFlag is set) gapEndGSN.value < gapStartGSN.value-1
HEARTBEAT (8.3.7.5.3)
---------
* submessageLength in the Submessage header is too small
* firstSN.value is zero or negative
* lastSN.value is negative
* lastSN.value < firstSN.value - 1
* (If GroupInfoFlag is set) currentGSN.value is zero or negative
* (If GroupInfoFlag is set) firstGSN.value is zero or negative
* (If GroupInfoFlag is set) lastGSN.value is negative
* (If GroupInfoFlag is set) lastGSN.value < firstGSN.value - 1
* (If GroupInfoFlag is set) currentGSN.value < firstGSN.value
* (If GroupInfoFlag is set) currentGSN.value < lastGSN.value
HEARTBEAT FRAG (8.3.7.6.3)
--------------
* submessageLength in the Submessage header is too small
* writerSN.value is zero or negative
* lastFragmentNum.value is zero or negative
INFO DESTINATION (8.3.7.7.3)
----------------
* submessageLength in the Submessage header is too small
INFO REPLY (8.3.7.8.3)
----------
* submessageLength in the Submessage header is too small
INFO SOURCE (8.3.7.9.3)
-----------
* submessageLength in the Submessage header is too small
INFO TIMESTAMP (8.3.7.10.3)
--------------
* submessageLength in the Submessage header is too small
NACK FRAG (8.3.7.11.3)
---------
* submessageLength in the Submessage header is too small
* writerSN.value is zero or negative
* fragmentNumberState is invalid
PAD (8.3.7.12.3)
---
ALWAYS VALID
NumberSet (9.4.2.6)
---------
* bitmapBase <= 0
* numBits < 0 or numBits > 256
* M/=(numBits+31)/32 longs in Submessage
Parameter List (8.3.5.9)
--------------
* There shall be no more than 2^16 possible values of the ParameterId_t parameterId
* A range of 2^15 values is reserved for protocol-defined parameters
* A range of 2^15 values is reserved for vendor-defined parameters
* The maximum length of any parameter is limited to 2^16 octets

View File

@ -48,12 +48,15 @@
But then, in 8.4.15.7 it says:
"So, an implementation should ensure that same logical HEARTBEATs are tagged with the same Count."
Does that mean there are cases were I have to put the same count? What is a logical HEARTBEAT?
* Should a "Keyed" Endpoint communicate with a "Non-Keyed"?
* Is the empty String a valid Topic and Type Name?
* We can determine if a Endpoint is a Reader or Writer via the Entity ID. Is it illegal to get a SEDP with incompatible source (Reader Entity ID from Publications Announcer?)
* Fast-RTPS doen not follow DDSI-RTPS Specification
- Open Github Issue
https://github.com/eProsima/Fast-RTPS/issues/1221
- Seems that Fast-RTPS is also not checking the Validity of Submessages according to Spec
* DDSI-RTPS 2.3 ISSUES
- 8.3.7.7 InfoDestination
@ -64,10 +67,13 @@
writerSN is incorrectly shown as only 32 bits in width
- 8.3.4 The RTPS Message Receiver, Table 8.16 - Initial State of the Receiver
Port of UnicastReplyLocatorList should be initialized to Source Port.
- 8.3.7.4.3 Validity
gapList.Base >= gapStart
- 8.3.7.10.3 Validity
'This Submessage is invalid when the following is true:
submessageLength in the Submessage header is too small'
But if InvalidateFlag is set, Length can be Zero. Since the length is unsigned, there cannot be an invalid length.
- 9.4.5.1.2 Flags
Clarify from where the endianness begins.
One might think it would begin after the Submessage Header, but the length is also endian dependent.
@ -101,5 +107,15 @@ DESIGN DECISIONS
Use the lowest bit of the Heartbeat/Acknack Deadline stored in the Participant Data to differentiate
between Delay and Suppression. This reduces the resolution from 0.23 ns to 0.47 ns
PROTOCOL UNCOMPLIANCE
=====================
* Partition QoS
* Built-in Endpoint is NOT the same as a normal Endpoint
-> No User access to Data
* Known but unused Submessage IDs are treated as uknown
-> No validity check
* Inline QoS validated in Endpoint
-> Cannot invalidate Rest of Message/Packet
-- Input FIFO Guard
-- Output FIFO Guard

View File

@ -58,6 +58,7 @@ package body math_pkg is
return ret_value;
end function;
-- TODO: Rename to ceil_div, since we do not actually round
function round_div(constant divident, divisor : in integer) return integer is
variable ret : integer;
begin

View File

@ -115,10 +115,10 @@ architecture arch of rtps_builtin_endpoint is
lease_deadline : TIME_TYPE;
heartbeat_res_time : TIME_TYPE;
acknack_res_time : TIME_TYPE;
spdp_seq_nr : SEQUENCE_NR_TYPE;
pub_seq_nr : SEQUENCE_NR_TYPE;
sub_seq_nr : SEQUENCE_NR_TYPE;
mes_seq_nr : SEQUENCE_NR_TYPE;
spdp_seq_nr : SEQUENCENUMBER_TYPE;
pub_seq_nr : SEQUENCENUMBER_TYPE;
sub_seq_nr : SEQUENCENUMBER_TYPE;
mes_seq_nr : SEQUENCENUMBER_TYPE;
end record;
--*****CONSTANT DECLARATION*****
@ -155,11 +155,9 @@ architecture arch of rtps_builtin_endpoint is
-- Signifies if the Reader Endpoint expects in-line QoS
constant EXPECTS_INLINE_QOS_FLAG : natural := 0;
-- Highest Sequence Number of Publisher Data
constant PUB_SEQUENCE_NR : SEQUENCE_NR_TYPE := convert_to_double_word(to_unsigned(NUM_WRITERS, 64));
constant PUB_SEQUENCENUMBER : SEQUENCENUMBER_TYPE := convert_to_double_word(to_unsigned(NUM_WRITERS, 64));
-- Highest Sequence Number of Subscriber Data
constant SUB_SEQUENCE_NR : SEQUENCE_NR_TYPE := convert_to_double_word(to_unsigned(NUM_READERS, 64));
-- Constant for Sequence Number 1
constant SEQUENCE_NR_START : SEQUENCE_NR_TYPE := convert_to_double_word(to_unsigned(1, 64));
constant SUB_SEQUENCENUMBER : SEQUENCENUMBER_TYPE := convert_to_double_word(to_unsigned(NUM_READERS, 64));
-- Heartbeat/Liveliness Assertion Period
constant HEARTBEAT_PERIOD : DURATION_TYPE := work.rtps_package.min(MIN_ENDPOINT_LEASE_DURATION, PARTICIPANT_HEARTBEAT_PERIOD) - DURATION_DELTA;
-- Constant for zero Participant Data
@ -208,7 +206,7 @@ architecture arch of rtps_builtin_endpoint is
-- Source GUID Latch
signal guid, guid_next : GUID_TYPE := (others => (others => '0'));
-- RTPS DATA Submessage Sequence Number Latch
signal seq_nr, seq_nr_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal seq_nr, seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Word aligned End of Parameter
signal parameter_end, parameter_end_next : unsigned(PARAMETER_LENGTH_WIDTH-1 downto 0) := (others => '0');
-- RTPS DATA Submessage Content Type
@ -269,13 +267,13 @@ architecture arch of rtps_builtin_endpoint is
-- General Purpose Counter (Memory FSM)
signal mem_cnt, mem_cnt_next : natural range 0 to max(22, ENDPOINT_BITMASK_SIZE-1) := 0;
-- Contains the Sequence Number stored in the Buffer of the current relevant Message Type (Participant/Publisher/Subscriber/Message Data)
signal mem_seq_nr, mem_seq_nr_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal mem_seq_nr, mem_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Signifies the next expected Sequence Number of the current relevant Message Type (Participant/Publisher/Subscriber/Message Data)
signal next_seq_nr, next_seq_nr_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal next_seq_nr, next_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Latch used to store the first Sequence Number in ACKNACK/HEARTBEAT/GAP Messages
signal first_seq_nr, first_seq_nr_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal first_seq_nr, first_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Latch used to store the last Sequence Number in HEARTBEAT/GAP Messages
signal last_seq_nr, last_seq_nr_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal last_seq_nr, last_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Signifies if we currently do a Orphan Endpoint Search (Endpoint whose parent Participant was removed)
signal is_orphan_search, is_orphan_search_next : std_logic := '0';
-- Intermediate write enable signal.
@ -306,13 +304,13 @@ architecture arch of rtps_builtin_endpoint is
signal reset_endpoint_alive : std_logic := '0';
-- NOTE: The "auto_live_seq_nr" is always higher than "man_live_seq_nr"
-- Contains the highest Sequence Number for automatic liveliness updates
signal auto_live_seq_nr, auto_live_seq_nr_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal auto_live_seq_nr, auto_live_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Contains the highest Sequence Number for manual by participant liveliness updates
signal man_live_seq_nr, man_live_seq_nr_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal man_live_seq_nr, man_live_seq_nr_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Points to the first Sequence Number after "man_live_seq_nr" (Signifies the start of the GAP between "man_live_seq_nr" and "auto_live_seq_nr")
signal live_gap_start, live_gap_start_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal live_gap_start, live_gap_start_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Points to the first Sequence Number before "auto_live_seq_nr" (Signifies the end of the GAP between "man_live_seq_nr" and "auto_live_seq_nr")
signal live_gap_end, live_gap_end_next : SEQUENCE_NR_TYPE := (others => (others => '0'));
signal live_gap_end, live_gap_end_next : SEQUENCENUMBER_TYPE := (others => (others => '0'));
-- Participant Announcement Timeout Time
signal announcement_time, announcement_time_next : TIME_TYPE := (others => (others => '0'));
-- Heartbeat/Liveliness Assertion Timeout Time
@ -413,20 +411,8 @@ begin
rd <= rd_sig;
-- This process swaps the input signal "data_in" to Big Endian Representation
endian_swap_prc: process(all)
begin
-- DEFAULT
data_in_swapped <= data_in;
-- If in Little Endian Representation
if (endian_flag = '1') then
-- Endian Swap
for i in 0 to 3 loop
data_in_swapped(i*8+8-1 downto i*8) <= data_in((3-i)*8+8-1 downto (3-i)*8);
end loop;
end if;
end process;
-- Big Endian Representation
data_in_swapped <= endian_swap(endian_flag, data_in);
-- This process is responsible for toggling the "endpoint_alive" signal
-- The signal is set high when at least one bit of the "alive" signal is high for at least one clock cycle,
@ -1301,7 +1287,7 @@ begin
-- Subscriber Acknack
if (is_subscriber = '1') then
-- If Reader has not ACKed all Publisher History Cache
if (first_seq_nr <= PUB_SEQUENCE_NR) then
if (first_seq_nr <= PUB_SEQUENCENUMBER) then
-- Set Acknack Response Time and Publisher Data as Acknack Response
mem_opcode <= UPDATE_PARTICIPANT;
deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY;
@ -1315,7 +1301,7 @@ begin
-- Publisher Acknack
else
-- If Reader has not ACKed all Subscriber History Cache
if (first_seq_nr <= SUB_SEQUENCE_NR) then
if (first_seq_nr <= SUB_SEQUENCENUMBER) then
-- Set Acknack Response Time and set Subscriber Data as Acknack Response
mem_opcode <= UPDATE_PARTICIPANT;
deadline_next <= time + PARTICIPANT_ACKNACK_RESPONSE_DELAY;
@ -1354,7 +1340,7 @@ begin
-- Publisher Data not scheduled for response
if (mem_participant_data.extra_flags(PUB_DATA_FLAG) = '0') then
-- If Reader has not ACKed all Publisher History Cache
if (first_seq_nr <= PUB_SEQUENCE_NR) then
if (first_seq_nr <= PUB_SEQUENCENUMBER) then
-- Set Publisher Data as Acknack Response
mem_opcode <= UPDATE_PARTICIPANT;
extra_flags_next <= mem_participant_data.extra_flags;
@ -1368,7 +1354,7 @@ begin
-- Subscriber Data not scheduled for response
if (mem_participant_data.extra_flags(SUB_DATA_FLAG) = '0') then
-- If Reader has not ACKed all Subscriber History Cache
if (first_seq_nr <= SUB_SEQUENCE_NR) then
if (first_seq_nr <= SUB_SEQUENCENUMBER) then
-- Set Subscriber Data as Acknack Response
mem_opcode <= UPDATE_PARTICIPANT;
extra_flags_next <= mem_participant_data.extra_flags;
@ -1550,7 +1536,7 @@ begin
-- Reset Word Counter
reset_read_cnt <= '1';
-- Latch Parameter End (In order to skip parameters)
parameter_end_next <= unsigned(big_endian_swap(endian_flag,parameter_length));
parameter_end_next <= unsigned(endian_swap(endian_flag,parameter_length));
-- DEFAULT STAGE
stage_next <= SKIP_PARAMETER;
@ -1742,7 +1728,7 @@ begin
when PID_PROPERTY_LIST =>
-- Ignore
null;
when PID_TYPE_MAX_SIZE_SERIALIZED =>
when PID_DATA_MAX_SIZE_SERIALIZED =>
-- Ignore
null;
when PID_ENTITY_NAME =>
@ -2692,16 +2678,16 @@ begin
output_sig <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER;
-- Sequence Number 1/2
when 3 =>
output_sig <= std_logic_vector(SEQUENCE_NR_START(0));
output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(0));
-- Sequence Number 2/2
when 4 =>
output_sig <= std_logic_vector(SEQUENCE_NR_START(1));
output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(1));
-- Sequence Number 1/2
when 5 =>
output_sig <= std_logic_vector(PUB_SEQUENCE_NR(0));
output_sig <= std_logic_vector(PUB_SEQUENCENUMBER(0));
-- Sequence Number 1/2
when 6 =>
output_sig <= std_logic_vector(PUB_SEQUENCE_NR(1));
output_sig <= std_logic_vector(PUB_SEQUENCENUMBER(1));
-- Count
when 7 =>
output_sig <= std_logic_vector(count);
@ -2717,16 +2703,16 @@ begin
output_sig <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER;
-- Sequence Number 1/2
when 11 =>
output_sig <= std_logic_vector(SEQUENCE_NR_START(0));
output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(0));
-- Sequence Number 2/2
when 12 =>
output_sig <= std_logic_vector(SEQUENCE_NR_START(1));
output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(1));
-- Sequence Number 1/2
when 13 =>
output_sig <= std_logic_vector(SUB_SEQUENCE_NR(0));
output_sig <= std_logic_vector(SUB_SEQUENCENUMBER(0));
-- Sequence Number 1/2
when 14 =>
output_sig <= std_logic_vector(SUB_SEQUENCE_NR(1));
output_sig <= std_logic_vector(SUB_SEQUENCENUMBER(1));
-- Count
when 15 =>
output_sig <= std_logic_vector(count);

View File

@ -16,6 +16,9 @@ package rtps_config_package is
constant ENTITYID : ENTITYID_TYPE; -- Deferred to Package Body
constant DOMAIN_ID : std_logic_vector(DOMAIN_ID_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(USER_DOMAIN_ID, DOMAIN_ID_WIDTH));
-- Constant for Sequence Number 1
constant FIRST_SEQUENCENUMBER : SEQUENCENUMBER_TYPE := convert_to_double_word(to_unsigned(1, 64));
-- Smallest Writer Endpoint Lease Duration
constant MIN_ENDPOINT_LEASE_DURATION : DURATION_TYPE; -- Deferred to package Body
@ -69,11 +72,19 @@ package rtps_config_package is
constant ENDPOINT_TOPIC : ENDPOINT_STRING_TYPE; --Deferred to package body
constant ENDPOINT_TYPE : ENDPOINT_STRING_TYPE; --Deferred to package body
constant DOMAIN_TAG : STRING_WORD_ARRAY_TYPE; -- Deferred to package body
-- TODO: Use everywhere
constant EMPTY_STRING : STRING_WORD_ARRAY_TYPE := (others => (others => '0'));
-- Swap "data" to Big Endian representation.
function big_endian_swap(is_little_endian : std_logic; data : std_logic_vector) return std_logic_vector;
function big_endian_swap(is_little_endian : std_logic; data : unsigned) return unsigned;
function endian_swap(swap : std_logic; data : std_logic_vector) return std_logic_vector;
function endian_swap(swap : std_logic; data : unsigned) return unsigned;
-- Return the Byte length of the string. (First NUL Byte is included)
function string_len (str : STRING_WORD_ARRAY_TYPE) return natural;
function boolean_to_std_logic(input : boolean) return std_logic;
function convert_string (str : string(1 to 256)) return STRING_WORD_ARRAY_TYPE;
function round_slv(slv : std_logic_vector; width : natural) return std_logic_vector;
end package;
package body rtps_config_package is
@ -132,7 +143,7 @@ package body rtps_config_package is
end loop;
end procedure;
function booelan_to_std_logic(input : boolean) return std_logic is
function boolean_to_std_logic(input : boolean) return std_logic is
variable ret : std_logic := '0';
begin
ret := '0';
@ -149,18 +160,18 @@ package body rtps_config_package is
for i in 0 to ret'length-1 loop
-- (see DDSI-RTPS 2.3 Section 9.3.1.2)
-- Entity Kind Mapping
ret(i)(7 downto 6) := USER_DEFINED_ENTITY;
ret(i)(ENTITY_KIND_H_RANGE) := USER_DEFINED_ENTITY;
if (i <= NUM_READERS-1) then
if (ENDPOINT_WITH_KEY(i)) then
ret(i)(5 downto 0) := READER_WITH_KEY;
ret(i)(ENTITY_KIND_L_RANGE) := READER_WITH_KEY;
else
ret(i)(5 downto 0) := READER_NO_KEY;
ret(i)(ENTITY_KIND_L_RANGE) := READER_NO_KEY;
end if;
else
if (ENDPOINT_WITH_KEY(i)) then
ret(i)(5 downto 0) := WRITER_WITH_KEY;
ret(i)(ENTITY_KIND_L_RANGE) := WRITER_WITH_KEY;
else
ret(i)(5 downto 0) := WRITER_NO_KEY;
ret(i)(ENTITY_KIND_L_RANGE) := WRITER_NO_KEY;
end if;
end if;
-- ID Mapping
@ -385,7 +396,7 @@ package body rtps_config_package is
len := len + 1;
ret.data(ind+len) := ENDPOINT_PRESENTATION_QOS(i);
len := len + 1;
ret.data(ind+len) := (24 => booelan_to_std_logic(ENDPOINT_COHERENT_ACCESS(i)), 16 => booelan_to_std_logic(ENDPOINT_ORDERED_ACCESS(i)), others => '0');
ret.data(ind+len) := (24 => boolean_to_std_logic(ENDPOINT_COHERENT_ACCESS(i)), 16 => boolean_to_std_logic(ENDPOINT_ORDERED_ACCESS(i)), others => '0');
end if;
-- SENTINEL
len := len + 1;
@ -534,7 +545,7 @@ package body rtps_config_package is
len := len + 1;
ret.data(ind+len) := ENDPOINT_PRESENTATION_QOS(i);
len := len + 1;
ret.data(ind+len) := (24 => booelan_to_std_logic(ENDPOINT_COHERENT_ACCESS(i)), 16 => booelan_to_std_logic(ENDPOINT_ORDERED_ACCESS(i)), others => '0');
ret.data(ind+len) := (24 => boolean_to_std_logic(ENDPOINT_COHERENT_ACCESS(i)), 16 => boolean_to_std_logic(ENDPOINT_ORDERED_ACCESS(i)), others => '0');
end if;
-- SENTINEL
len := len + 1;
@ -677,7 +688,7 @@ package body rtps_config_package is
ret.data(ind+len) := DEFAULT_IPv4_META_ADDRESS;
-- DEFAULT MULTICAST LOCATOR
len := len + 1;
ret.data(ind+len) := PID_METATRAFFIC_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16));
ret.data(ind+len) := PID_DEFAULT_MULTICAST_LOCATOR & std_logic_vector(to_unsigned(24, 16));
len := len + 1;
ret.data(ind+len) := LOCATOR_KIND_UDPv4;
len := len + 1;
@ -730,14 +741,14 @@ package body rtps_config_package is
constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE := gen_participant_data;
-- Returns the 'data' argument either as is, or with reversed Byte order, depending on the
-- 'is_little_endian' argument.
function big_endian_swap(is_little_endian : std_logic; data : std_logic_vector) return std_logic_vector is
-- 'swap' argument.
function endian_swap(swap : std_logic; data : std_logic_vector) return std_logic_vector is
variable ret : std_logic_vector(data'range);
begin
-- Assert that Data Signal is Byte aligned
assert (data'length mod 8 = 0) severity failure;
-- Little Endian
if (is_little_endian = '1') then
if (swap = '1') then
-- Reverse byte Order
for i in 0 to (data'length/8)-1 loop
ret(i*8+8-1 downto i*8) := data(((data'length/8)-1-i)*8+8-1 downto ((data'length/8)-1-i)*8);
@ -750,10 +761,20 @@ package body rtps_config_package is
end function;
-- Returns the 'data' argument either as is, or with reversed Byte order, depending on the
-- 'is_little_endian' argument.
function big_endian_swap(is_little_endian : std_logic; data : unsigned) return unsigned is
-- 'swap' argument.
function endian_swap(swap : std_logic; data : unsigned) return unsigned is
begin
return unsigned(big_endian_swap(is_little_endian, std_logic_vector(data)));
return unsigned(endian_swap(swap, std_logic_vector(data)));
end function;
function round_slv(slv : std_logic_vector; width : natural) return std_logic_vector is
variable ret : std_logic_vector(width-1 downto 0) := (others => '0');
begin
ret := slv(slv'length-1 downto slv'length-width);
if (slv(width-1 downto 0) /= (width-1 downto 0 => '0')) then
ret := std_logic_vector(unsigned(ret) + 1);
end if;
return ret;
end function;
end package body;

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,7 @@ package rtps_package is
constant LOCATOR_KIND_WIDTH : natural := CDR_LONG_WIDTH;
constant COUNT_WIDTH : natural := CDR_LONG_WIDTH;
constant SUBMESSAGE_DATA_EXTRA_FLAGS_WIDTH : natural := 16;
constant MAX_BITMAP_WIDTH : natural := 256;
-- *TYPES DEFINITION*
-- Generic Types
@ -52,19 +53,30 @@ package rtps_package is
type DOUBLE_WORD_ARRAY is array (0 to 1) of unsigned(WORD_WIDTH-1 downto 0);
-- RTPS
-- TODO: Define unconstrained WORD_ARRAY and define constrained subtypes
subtype SEQUENCE_NR_TYPE is DOUBLE_WORD_ARRAY;
subtype SEQUENCENUMBER_TYPE is DOUBLE_WORD_ARRAY;
subtype DURATION_TYPE is DOUBLE_WORD_ARRAY;
subtype TIME_TYPE is DOUBLE_WORD_ARRAY;
type GUIDPREFIX_TYPE is array (0 to (GUIDPREFIX_WIDTH/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
type GUID_TYPE is array (0 to (GUID_WIDTH/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
type BITMAP_TYPE is array (0 to (MAX_BITMAP_WIDTH/WORD_WIDTH)-1) of std_logic_vector(0 to WORD_WIDTH-1);
-- Helper Function
function gen_duration(s,ns : integer) return DURATION_TYPE;
-- *PREDEFINED VALUES*
constant DEFAULT_IPv4_META_ADDRESS : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := x"EFFF0001"; -- Default Multicast Ipv4 Address (239.255.0.1)
constant DURATION_ZERO : DURATION_TYPE := (others => (others => '0'));
constant DURATION_INFINITE : DURATION_TYPE := (x"7fffffff", x"ffffffff");
constant TIME_ZERO : TIME_TYPE := (others => (others => '0'));
constant TIME_INVALID : TIME_TYPE := (others => (others => '1'));
constant TIME_INFINITE : TIME_TYPE := (x"ffffffff", x"fffffffe");
constant SEQUENCENUMBER_UNKNOWN : SEQUENCENUMBER_TYPE := (x"ffffffff", x"00000000");
constant PROTOCOL_RTPS : std_logic_vector(PROTOCOL_WIDTH-1 downto 0) := x"52545053"; -- 'RTPS' in Ascii code
constant PROTOCOLVERSION_1_0 : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0100";
constant PROTOCOLVERSION_1_1 : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0101";
constant PROTOCOLVERSION_2_0 : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0200";
constant PROTOCOLVERSION_2_1 : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0201";
constant PROTOCOLVERSION_2_2 : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0202";
constant PROTOCOLVERSION_2_4 : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0) := x"0204";
constant VENDORID_UNKNOWN : std_logic_vector(VENDORID_WIDTH-1 downto 0) := (others => '0');
constant GUIDPREFIX_UNKNOWN : GUIDPREFIX_TYPE := (others => (others => '0'));
@ -87,6 +99,7 @@ package rtps_package is
constant SID_DATA_FRAG : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0) := x"16";
-- *SUBMESSAGE FLAG POSITIONS*
-- NOTE: The KEY and NON_STANDARD_PAYOAD Flags for the DATA_FRAG Submessage are off by one (-1) from this positions
constant SUBMESSAGE_ENDIAN_FLAG_POS : natural := 0;
constant SUBMESSAGE_FINAL_FLAG_POS : natural := 1;
constant SUBMESSAGE_INLINE_QOS_FLAG_POS : natural := 1;
@ -140,7 +153,7 @@ package rtps_package is
constant PID_BUILTIN_ENDPOINT_SET : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0058";
constant PID_BUILTIN_ENDPOINT_QOS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0077";
constant PID_PROPERTY_LIST : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0059";
constant PID_TYPE_MAX_SIZE_SERIALIZED : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0060";
constant PID_DATA_MAX_SIZE_SERIALIZED : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0060";
constant PID_ENTITY_NAME : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0062";
constant PID_ENDPOINT_GUID : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"005a";
-- INLINE-QOS ONLY
@ -186,13 +199,14 @@ package rtps_package is
constant ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER: std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000200c2");
constant ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER: std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000200c7");
-- *ENTITY KIND* (Last Byte of Entity ID)
subtype ENTITY_KIND_H_RANGE is natural range 1 downto 0;
subtype ENTITY_KIND_L_RANGE is natural range 7 downto 2;
subtype ENTITY_KIND_H_RANGE is natural range 7 downto 6;
subtype ENTITY_KIND_L_RANGE is natural range 5 downto 0;
--FOLLOWING MAP TO ENTITY_KIND_H
constant USER_DEFINED_ENTITY : std_logic_vector(ENTITY_KIND_H_RANGE) := "00";
constant BUILT_IN_ENTITY : std_logic_vector(ENTITY_KIND_H_RANGE) := "11";
constant VENDOR_SPECIFIC_ENTITY : std_logic_vector(ENTITY_KIND_H_RANGE) := "01";
--FOLLOWING MAP TO ENTITY_KIND_L
constant UNKNOWN_KIND : std_logic_vector(ENTITY_KIND_L_RANGE) := (others => '0');
constant WRITER_WITH_KEY : std_logic_vector(ENTITY_KIND_L_RANGE) := "000010";
constant WRITER_NO_KEY : std_logic_vector(ENTITY_KIND_L_RANGE) := "000011";
constant READER_NO_KEY : std_logic_vector(ENTITY_KIND_L_RANGE) := "000100";

View File

@ -39,7 +39,7 @@
set_global_assignment -name FAMILY "Cyclone V"
set_global_assignment -name DEVICE 5CGXFC7C7F23C8
set_global_assignment -name TOP_LEVEL_ENTITY rtps_builtin_endpoint
set_global_assignment -name TOP_LEVEL_ENTITY rtps_handler
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 20.1.0
set_global_assignment -name PROJECT_CREATION_TIME_DATE "13:33:09 NOVEMBER 02, 2020"
set_global_assignment -name LAST_QUARTUS_VERSION "20.1.0 Lite Edition"