* tmp (Before Buffer reorder)

This commit is contained in:
Greek 2020-10-21 12:38:51 +02:00
parent 0ec0003eb3
commit b79e631ac6
5 changed files with 1038 additions and 626 deletions

View File

@ -1,288 +1,104 @@
RULES 8.4.2 * https://github.com/osrf/ros_dds/issues/7 tries to determine the feasibility of an FPGA-only DDS implementation
=========== It was suggested using a 'OpenMS430' soft-microcontroller to run DDS middleware on-top.
- Compare resource utilization and performance with this approach
* DDS FPGA Vendors
- TwinOaks Computing Inc (CoreDX)
- OpenVPX
* Implementation makes unnecessary transitions, that are ignored in later stages.
This was a design decision to simplify complexity of each stage (and probably FMAX), but increases power consumtion.
* Is the Timestamp used by something else except ordering by source? If not, does it have to be "sane"?
2.2.3.16
This QoS relies on the sender and receiving applications having their clocks sufficiently synchronized. If this is not the case
and the Service can detect it, the DataReader is allowed to use the reception timestamp instead of the source timestamp in its
computation of the expiration time.
2.2.3.17
The mechanism to set the source timestamp is middleware dependent.
* Are the Builtin Endpoints part of the DDS Specification or the RTPS specification?
- Both
* ALL Data Fields are sent on each change:
https://community.rti.com/forum-topic/sending-only-fields-have-changed
* OFFERED_INCOMPATIBLE_QOS, REQUESTED_INCOMPATIBLE_QOS? (DDS-1.4, 2.2.4.1 Communication Status)
* Does a RTPS Reader subscribe and receive ALL Instances of a keyed Topic?
i.e. where are the instances differentiated?
S.29 - Topic Kind
* Does a RTPS reader subscribe to more than one Writer (If not using Groups)?
- Yes
* Since only positive Sequence Numbers are valid, why is the type signed?
* Replace also Locator? (In order to prevent storing the Locators in multiple Endpoints)
* Store only one locator? Select the first supported multicast? Check for active ping response? Verify with source address?
* What is the purpose of "manualLivelinessCount" in "SPDPdiscoveredParticipantData"? Since the liveliness is asserted by use of "ParticipantMessageData", what is the purpose of also sending an updated "SPDPdiscoveredParticipantData"? (Duplicates is out of the question, since it is not sent with the actual liveliness assertion)
* What does that mean?:
2.2.3.19
If reliability is BEST_EFFORT then the Service is allowed to drop samples. If the reliability is
RELIABLE, the Service will block the DataWriter or discard the sample at the DataReader in order not to lose existing
samples.
* What is now the valid Parameter List length?
According to DDSI-RTPS 9.4.2.11
The length encodes the number of octets following the length to reach the ID of the next parameter (or the ID of the sentinel). Because every parameterId starts on a 4-byte boundary, the length is always a multiple of four.
According to DDS XTypes 7.4.1.2
Unlike it is stated in [RTPS] Sub Clause 9.4.2.11 “ParameterList”, the value of the parameter length is the exact length of the serialized member. It does not account for any padding bytes that may follow the serialized member. Padding bytes may be added in order to start the next parameterID at a 4 byte offset relative to the previous parameterID.
* 32-bit Timestamps? Seriously? Ever heard of Y2k38?
* Use generic package with unconstrained arrays (VHDL-2008), and assert bounds/length inside the package.
* Count repository lines
git ls-files | grep vhd | xargs wc -l
* Count Field in Heartbeat/Acknack
The following sentence is quite self-explanatory:
"A counter that is incremented each time a new message is sent. Provides the means to detect
duplicate messages that can result from the presence of redundant communication paths."
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?
GENERAL
-------
* All communications must take place using RTPS Messages
* All implementations must implement the RTPS Message Receiver
* The timing characteristics of all implementations must be tunable
* Implementations must implement the Simple Participant and Endpoint Discovery Protocols
WRITER * Fast-RTPS doen not follow DDSI-RTPS Specification
------ - Open Github Issue
* Writers must not send data out-of-order https://github.com/eProsima/Fast-RTPS/issues/1221
* Writers must include in-line QoS values if requested by a Reader
* Writers must send periodic HEARTBEAT Messages (reliable only)
* Writers must eventually respond to a negative acknowledgment (reliable only)
* Sending Heartbeats and Gaps with Writer Group Information (Writer belonging to a Group)
READER
------ * DDSI-RTPS 2.3 ISSUES
A best-effort Reader is completely passive as it only receives data and does not send messages itself. - 8.3.7.7 InfoDestination
Therefore, the requirements below only apply to reliable Readers. 'This message is sent from an RTPS Writer to an RTPS Reader to modify the GuidPrefix used to interpret the Reader entityIds appearing in the Submessages that follow it.'
* Readers must respond eventually after receiving a HEARTBEAT with final flag not set But state is changed as follows 'Receiver.destGuidPrefix = InfoDestination.guidPrefix'.
* Readers must respond eventually after receiving a HEARTBEAT that indicates a sample is missing Isn't Reader -> Writer also valid? Does it have a specific direction?
* Once acknowledged, always acknowledged - 9.4.5.3 Data Submessage
* Readers can only send an ACKNACK Message in response to a HEARTBEAT Message 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
RELIABILITY Port of UnicastReplyLocatorList should be initialized to Source Port.
=========== - 8.3.7.10.3 Validity
* Best Effort Writer can only be matched with Best Effort Reader 'This Submessage is invalid when the following is true:
* Stateless Reader can only be Best Effort (maintains absolutely no state, does not handle duplicate and out-of-order changes) 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.
STATELESS WRITER - 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.
* Source Port of SPDP is irrelevant, since it is BEST EFFORT and we do not reply (only Destination Port is of significance)
DESIGN DECISIONS
================ ================
Note that the processing of this message uses the reply locators in the RTPS Receiver.
This is the only source of information for the StatelessWriter to determine where to send the reply to.
Proper functioning of the protocol requires that the RTPS Reader inserts an InfoReply Submessage ahead of the AckNack such that these fields are properly set.
Writer Liveness Protocol * !REJECTED!
======================== In order to save memory GUID should only be saved once.
ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER Decision was made to replace GUID with internal reference index.
ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER Discovery module is responsible for saving the GUID and map it to a refernec eindex, that can then be used by other entities.
Writer Endpoints may need access to the real GUID for message fields.
2 options exist:
- All Endpoints have access to the central memory where the real GUID is saved (needs Arbiter, handle starvation)
- Writer Endpoints fill the fields with the reference index as placeholder, and a seperate Entity will access the central memory and replace the actual values
The Second option was chosen (Less resources)
RTPS Handler should lookup received message GUID in central memory (The lookup should happen in parallel with the actual message handling):
- If not stored, and messegae not for Built-in ENdpoints, drop message
- If in memory, replace with refernece index
The central memory is accessd by 3 Entities:
- RTPS Handler (READ, GUID Lookup)
- Placeholder Handler (READ, GUID Lookup)
- Discovery Module (WRITE, GUID Save) [Need initial Lookup? RTPS Handler should have already handled it. How does DM know if actual GUID or reference index?]
Use a 2-port RAM with an arbiter for READ operations (Give Placeholder Handler priority to prevent DoS starvation)
OPTIONAL 8.4.14 * !REJECTED! (Use the unused extra flags in the stored participant data)
=============== Use the lowest bit of the Heartbeat/Acknack Deadline stored in the Participant Data to differentiate
Optional features may not be supported by all RTPS implementations. between Delay and Suppression. This reduces the resolution from 0.23 ns to 0.47 ns
* LARGE DATA (Fragmented Data)
--------------------------------------------
ENTITYID_UKNOWN also for Built-In?
Ignore Participant/Topic/Publication/Subscription (handle argument of Sampleinfo)
ENDIANNESS
==========
You have to see what datatypes PSM maps to each element.
If the datatype is bigger than a byte, byte swaping has to occur.
The elements of an array are in order (but the elements themselves may need to be swapped if bigger than a Byte)
ENDPOINT FIFO PACKET FORMAT
===========================
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------+---------------+---------------+---------------+
| OPCODE | FLAGS | SRC_UDP_PORT |
+-------------+---------------+---------------+---------------+
| SRC_IPv4_ADDR |
+-------------------------------------------------------------+
| SRC_ENTITYID |
+-------------------------------------------------------------+
| |
+ +
| SRC_GUIDPREFIX |
+ +
| |
+-------------------------------------------------------------+
| DEST_ENTITYID [only for Builtin Destinations] |
+-------------------------------------------------------------+
| |
+ Sequence Number [only for DATA Submessage] +
| |
+-------------------------------------------------------------+
| |
~ PAYLOAD (SUBMESSAGE CONTENT) ~
| |
+-------------------------------------------------------------+
ENDPOINT_ID
===========
0...MAX_ENDPOINTS
READERS...WRITERS
BUILT-IN ENDPOINTS
==================
2.2.5 Built-In Topics
The QoS of the built-in Subscriber and DataReader objects is given by the following table:
HISTORY: kind = KEEP_LAST, depth = 1
Since the Built-In Endpoints have a history depth of 1, we can safely reduce the processing complexity of ACKNACK and
HEARTBEAT messages (and even ignore GAP messages).
PARTICICPANT DATA
=================
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
01| |
+ +
02| GUIDPREFIX |
+ +
03| |
+-------------------------------------------------------------+
04| META_IPv4_ADDRESS |
+-------------------------------------------------------------+
05| DEFAULT_IPv4_ADDRESS |
+-------------------------------------------------------------+
06| META_UDP_PORT | DEFAULT_UDP_PORT |
+-------------------------------------------------------------+
07| UNUSED | EXTRA_FLAGS |Q|
+-------------------------------------------------------------+
08| LEASE_DURATION |
+ +
09| |
+-------------------------------------------------------------+
10| LEASE_DEADLINE |
+ +
11| |
+-------------------------------------------------------------+
12| |
+ SPDP_SEQ_NR +
13| |
+-------------------------------------------------------------+
14| |
+ PUBLICATION_SEQ_NR +
15| |
+-------------------------------------------------------------+
16| |
+ SUBSCRIPTION_SEQ_NR +
17| |
+-------------------------------------------------------------+
18| |
+ MESSAGE_SEQ_NR +
19| |
+-------------------------------------------------------------+
ENDPOINT DATA
=============
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
01| ENTITYID |
+-------------------------------------------------------------+
02| |
+ +
03| GUIDPREFIX |
+ +
04| |
+-------------------------------------------------------------+
05| |
~ ENDPOINT_BITMASK ~
**| |
+-------------------------------------------------------------+
ENDPOINT MATCH FRAME
====================
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
01| OPCODE |
+-------------------------------------------------------------+
02| |
+ +
03| GUIDPREFIX |
+ +
04| |
+-------------------------------------------------------------+
05| ENTITYID |
+-------------------------------------------------------------+
06| IPv4_ADDRESS |
+-------------------------------------------------------------+
07| UDP_PORT | EXTRA_FLAGS |Q|
+-------------------------------------------------------------+
ENDPOINT UNMATCH FRAME
======================
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
01| OPCODE |
+-------------------------------------------------------------+
02| |
+ +
03| GUIDPREFIX |
+ +
04| |
+-------------------------------------------------------------+
05| ENTITYID |
+-------------------------------------------------------------+
LOCAL ENDPOINT BUFFER
=====================
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------------------------------------------------------+
| |
+ +
| GUIDPREFIX |
+ +
| |
+-------------------------------------------------------------+
| ENTITYID |
+-------------------------------------------------------------+
| IPv4_ADDRESS |
+-------------------------------------------------------------+
| UDP_PORT | EXTRA_FLAGS |
+-------------------------------------------------------------+
| LIFESPAN |
+ +
| (READER_ONLY) |
+-------------------------------------------------------------+
OUTPUT DATA
===========
31............24..............16..............8...............0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
01| PACKET_LENGTH |
+-------------------------------------------------------------+
02| SRC_IPv4_ADDRESS |
+-------------------------------------------------------------+
03| DEST_IPv4_ADDRESS |
+-------------------------------------------------------------+
04| SRC_UDP_PORT | DEST_UDP_PORT |
+-------------------------------------------------------------+
05| |
~ RTPS_MESSAGE ~
| |
+-------------------------------------------------------------+
TOPIC KEYS
==========
Nominally the key is part of the serialized data of a data submessage.
Using the key hash benefits implementations by providing a faster alternative than deserializing the full key from the received data-object.
MISC
====
8.2.9 Relation to DDS Entities
How exactly a DDS Entity interacts with the HistoryCache however, is implementation specific and not
formally modeled by the RTPS protocol. Instead, the Behavior Module of the RTPS protocol only specifies how
CacheChange changes are transferred from the HistoryCache of the RTPS Writer to the HistoryCache of
each matching RTPS Reader.
8.2.9.1
When using strict reliable communication, a change can
only be removed when it has been acknowledged by all readers the change was sent to and which are still
active and alive.
8.2.9.2
Each matching Writer will attempt to transfer all relevant samples from its HistoryCache to the HistoryCache of the Reader.
8.4.3
It is also not able to drop out-of-order samples on the Reader side as this
requires keeping track of the largest sequence number received from each remote Writer.
--> Suggests there is multiple writers
8.5.4.2
For the purpose of interoperability, it is sufficient that an
implementation provides the required built-in Endpoints and reliable communication that satisfies the general
requirements listed in 8.4.2.
8.5.4.4
An implementation of the protocol need not necessarily send all information contained in the DataTypes. If any
information is not present, the implementation can assume the default values, as defined by the PSM.
8.7.2.2.6
In order to implement the DDS_BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS policy,
implementations must include an InfoTimestamp Submessage with every update from a Writer.
DDS_Advanced_Tutorial_2006_00-T1-2_Pardo.pdf (P.16)

File diff suppressed because it is too large Load Diff

View File

@ -4,38 +4,40 @@ use ieee.numeric_std.all;
use work.math_pkg.all; use work.math_pkg.all;
-- TODO: Convert ALL integers to natural, and remove all conversions (Arithmetics between natural and unsigned are directly supported)
package rtps_package is package rtps_package is
--*****USER CONFIG***** --*****USER CONFIG*****
-- Unicast IPv4 Address used by all RTPS Entities [Default 192.168.0.80] -- Unicast IPv4 Address used by all RTPS Entities [Default 192.168.0.80]
constant IPv4_UNICAST_ADDRESS : std_logic_vector(31 downto 0) := x"C0A80080"; constant IPv4_UNICAST_ADDRESS : std_logic_vector(31 downto 0) := x"C0A80080";
-- Number of RTPS Writer Endpoints -- Number of RTPS Writer Endpoints
constant NUM_WRITERS : integer := 0; constant NUM_WRITERS : natural := 0;
-- Number of RTPS Reader Endpoints -- Number of RTPS Reader Endpoints
constant NUM_READERS : integer := 1; constant NUM_READERS : natural := 1;
----------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------
-- *DO NOT MODIFY BEGIN* -- *DO NOT MODIFY BEGIN*
constant MAX_ENDPOINTS : integer := NUM_READERS+NUM_WRITERS; constant MAX_ENDPOINTS : natural := NUM_READERS+NUM_WRITERS;
-- *DO NOT MODIFY END* -- *DO NOT MODIFY END*
----------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------
-- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) -- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PB : integer := 7400; constant PORT_CONFIG_PB : natural := 7400;
-- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) -- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_DG : integer := 250; constant PORT_CONFIG_DG : natural := 250;
-- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) -- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_PG : integer := 2; constant PORT_CONFIG_PG : natural := 2;
-- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) -- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D0 : integer := 0; constant PORT_CONFIG_D0 : natural := 0;
-- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) -- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D1 : integer := 10; constant PORT_CONFIG_D1 : natural := 10;
-- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) -- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D2 : integer := 1; constant PORT_CONFIG_D2 : natural := 1;
-- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) -- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1)
constant PORT_CONFIG_D3 : integer := 11; constant PORT_CONFIG_D3 : natural := 11;
-- MAC Address of underlying network stack (Used to generate GUIDs) -- MAC Address of underlying network stack (Used to generate GUIDs)
constant MAC_ADDRESS : std_logic_vector(47 downto 0) := x"97917E0BA8CF"; constant MAC_ADDRESS : std_logic_vector(47 downto 0) := x"97917E0BA8CF";
-- Domain ID -- Domain ID
constant USER_DOMAIN_ID : integer := 1; constant USER_DOMAIN_ID : natural := 1;
-- Domain TAG -- Domain TAG
constant USER_DOMAIN_TAG : string := ""; constant USER_DOMAIN_TAG : string := "";
@ -47,10 +49,10 @@ package rtps_package is
type ENDPOINT_STRING_SLV_TYPE is array (0 to MAX_ENDPOINTS-1) of STRING_SLV_WORD_TYPE; type ENDPOINT_STRING_SLV_TYPE is array (0 to MAX_ENDPOINTS-1) of STRING_SLV_WORD_TYPE;
subtype QOS_TYPE is array (0 to MAX_ENDPOINTS-1) of std_logic_vector(31 downto 0); subtype QOS_TYPE is array (0 to MAX_ENDPOINTS-1) of std_logic_vector(31 downto 0);
subtype QOS_SLV_TYPE is array (0 to MAX_ENDPOINTS-1) of std_logic_vector(31 downto 0); subtype QOS_SLV_TYPE is array (0 to MAX_ENDPOINTS-1) of std_logic_vector(31 downto 0);
type DURATION_TYPE is array (0 to 1) of unsigned(31 downto 0); type DOUBLE_WORD_ARRAY is array (0 to 1) of unsigned(31 downto 0);
type ENDPOINT_DURATION_TYPE is array (0 to MAX_ENDPOINTS-1) of DURATION_TYPE; type ENDPOINT_DURATION_TYPE is array (0 to MAX_ENDPOINTS-1) of DOUBLE_WORD_ARRAY;
constant DURATION_INFINITE : DURATION_TYPE := (x"7fffffff", x"ffffffff"); constant DURATION_INFINITE : DOUBLE_WORD_ARRAY := (x"7fffffff", x"ffffffff");
-- DURABILITY KIND -- DURABILITY KIND
constant VOLATILE_DURABILITY_QOS : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(0,32)); constant VOLATILE_DURABILITY_QOS : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(0,32));
@ -112,30 +114,30 @@ package rtps_package is
constant ENDPOINT_MAX_INSTANCES : QOS_SLV_TYPE := (0 => std_logic_vector(to_unsigned(0,32))); --TODO: Assert constant ENDPOINT_MAX_INSTANCES : QOS_SLV_TYPE := (0 => std_logic_vector(to_unsigned(0,32))); --TODO: Assert
constant ENDPOINT_MAX_SAMP_PER_INST : QOS_SLV_TYPE := (0 => std_logic_vector(to_unsigned(0,32))); --TODO: Assert constant ENDPOINT_MAX_SAMP_PER_INST : QOS_SLV_TYPE := (0 => std_logic_vector(to_unsigned(0,32))); --TODO: Assert
constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE := (to_unsigned(100,32),to_unsigned(0,32); constant DEFAULT_PARTICIPANT_LEASE_DURATION : DOUBLE_WORD_ARRAY := (to_unsigned(100,32),to_unsigned(0,32);
constant PARTICIPANT_LEASE_DURATION : DURATION_TYPE := DEFAULT_PARTICIPANT_LEASE_DURATION; constant PARTICIPANT_LEASE_DURATION : DOUBLE_WORD_ARRAY := DEFAULT_PARTICIPANT_LEASE_DURATION;
-- NOTE: The buffer will not only store participants, but also endpoint data -- NOTE: The buffer will not only store participants, but also endpoint data
-- Used to determine the size of the built-inendpoint buffer -- Used to determine the size of the built-inendpoint buffer
constant MAX_REMOTE_PARTICIPANTS : integer := 50; constant MAX_REMOTE_PARTICIPANTS : natural := 50;
--*****DDSI-RTPS 2.3***** --*****DDSI-RTPS 2.3*****
-- Default Multicast Ipv4 Address (239.255.0.1) -- Default Multicast Ipv4 Address (239.255.0.1)
constant DEFAULT_IPv4_MULTICAST_ADDRESS : std_logic_vector(31 downto 0) := x"EFFF0001"; constant DEFAULT_IPv4_MULTICAST_ADDRESS : std_logic_vector(31 downto 0) := x"EFFF0001";
constant GUIDPREFIX_WIDTH : integer := 96; constant GUIDPREFIX_WIDTH : natural := 96;
constant PROTOCOLVERSION_WIDTH : integer := 16; constant PROTOCOLVERSION_WIDTH : natural := 16;
constant VENDORID_WIDTH : integer := 16; constant VENDORID_WIDTH : natural := 16;
constant SUBMESSAGE_ID_WIDTH : integer := 8; constant SUBMESSAGE_ID_WIDTH : natural := 8;
constant DOMAIN_ID_WIDTH : integer := 32; constant DOMAIN_ID_WIDTH : natural := 32;
constant UDP_PORT_WIDTH : integer := 16; constant UDP_PORT_WIDTH : natural := 16;
constant ENTITYID_WIDTH : integer := 32; constant ENTITYID_WIDTH : natural := 32;
constant PROTOCOL_WIDTH : integer := 32; constant PROTOCOL_WIDTH : natural := 32;
constant PARAMETER_ID_WIDTH : integer := 16; constant PARAMETER_ID_WIDTH : natural := 16;
constant PAYLOAD_REPRESENTATION_ID : integer := 16; constant PAYLOAD_REPRESENTATION_ID : natural := 16;
constant PAYLOAD_REPRESENTATION_OPTIONS : integer := 16; constant PAYLOAD_REPRESENTATION_OPTIONS : natural := 16;
constant SEQUENCE_NR_WIDTH : integer := 64; constant SEQUENCE_NR_WIDTH : natural := 64;
-- 'RTPS' in Ascii code -- 'RTPS' in Ascii code
constant PROTOCOL_RTPS : std_logic_vector(PROTOCOL_WIDTH-1 downto 0) := x"52545053"; constant PROTOCOL_RTPS : std_logic_vector(PROTOCOL_WIDTH-1 downto 0) := x"52545053";
@ -237,7 +239,7 @@ package rtps_package is
constant DOMAIN_ID : std_logic_vector(DOMAIN_ID_WIDTH-1 downto 0) := to_unsigned(USER_DOMAIN_ID, DOMAIN_ID'length); constant DOMAIN_ID : std_logic_vector(DOMAIN_ID_WIDTH-1 downto 0) := to_unsigned(USER_DOMAIN_ID, DOMAIN_ID'length);
constant DOMAIN_TAG : STRING_SLV_WORD_TYPE; -- Deferred to packgae body constant DOMAIN_TAG : STRING_SLV_WORD_TYPE; -- Deferred to package body
-- Since this implementation runs on the same network stack and the RTPS Endpoints (Readers & Writers) -- Since this implementation runs on the same network stack and the RTPS Endpoints (Readers & Writers)
-- can be differentiated based on their Entity ID, it makes no sense to have multiple IP Addresses -- can be differentiated based on their Entity ID, it makes no sense to have multiple IP Addresses
@ -297,36 +299,36 @@ 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_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"); constant ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER: std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (x"000200c7");
constant LOCATOR_KIND_WIDTH : integer := 32; constant LOCATOR_KIND_WIDTH : natural := 32;
constant LOCATOR_KIND_INVALID : std_logic_vector := std_logic_vector(to_signed(-1,LOCATOR_KIND_WIDTH)); constant LOCATOR_KIND_INVALID : std_logic_vector := std_logic_vector(to_signed(-1,LOCATOR_KIND_WIDTH));
constant LOCATOR_KIND_RESERVERD : std_logic_vector := std_logic_vector(to_signed(0,LOCATOR_KIND_WIDTH)); constant LOCATOR_KIND_RESERVERD : std_logic_vector := std_logic_vector(to_signed(0,LOCATOR_KIND_WIDTH));
constant LOCATOR_KIND_UDPv4 : std_logic_vector := std_logic_vector(to_signed(1,LOCATOR_KIND_WIDTH)); constant LOCATOR_KIND_UDPv4 : std_logic_vector := std_logic_vector(to_signed(1,LOCATOR_KIND_WIDTH));
constant LOCATOR_KIND_UDPv6 : std_logic_vector := std_logic_vector(to_signed(2,LOCATOR_KIND_WIDTH)); constant LOCATOR_KIND_UDPv6 : std_logic_vector := std_logic_vector(to_signed(2,LOCATOR_KIND_WIDTH));
-- BUILTIN ENDPOINT SET POSITIONS -- BUILTIN ENDPOINT SET POSITIONS
constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER : integer := 0; constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER : natural := 0;
constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR : integer := 1; constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR : natural := 1;
constant DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER : integer := 2; constant DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER : natural := 2;
constant DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR : integer := 3; constant DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR : natural := 3;
constant DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER : integer := 4; constant DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER : natural := 4;
constant DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR : integer := 5; constant DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR : natural := 5;
constant BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER : integer := 10; constant BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER : natural := 10;
constant BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER : integer := 11; constant BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER : natural := 11;
constant DISC_BUILTIN_ENDPOINT_TOPICS_ANNOUNCER : integer := 28; constant DISC_BUILTIN_ENDPOINT_TOPICS_ANNOUNCER : natural := 28;
constant DISC_BUILTIN_ENDPOINT_TOPICS_DETECTOR : integer := 29; constant DISC_BUILTIN_ENDPOINT_TOPICS_DETECTOR : natural := 29;
-- BUILTIN ENDPOINT QOS BITMASK -- BUILTIN ENDPOINT QOS BITMASK
constant BEST_EFFORT_PARTICIPANT_MESSAGE_DATA_READER : integer := 0; constant BEST_EFFORT_PARTICIPANT_MESSAGE_DATA_READER : natural := 0;
--*****CUSTOM***** --*****CUSTOM*****
constant PARTICIPANT_FRAME_SIZE : integer := 19; constant PARTICIPANT_FRAME_SIZE : natural := 19;
constant ENDPOINT_BITMASK_SIZE : integer := round_div(MAX_ENDPOINTS, 32); constant ENDPOINT_BITMASK_SIZE : natural := round_div(MAX_ENDPOINTS, 32);
constant ENDPOINT_FRAME_SIZE : integer := 4 + ENDPOINT_BITMASK_SIZE; constant ENDPOINT_FRAME_SIZE : natural := 4 + ENDPOINT_BITMASK_SIZE;
-- Limit Buffer to 32 bit Addresses -- Limit Buffer to 32 bit Addresses
constant BUILTIN_BUFFER_SIZE : integer := min(MAX_ENDPOINTS*PARTICIPANT_FRAME_SIZE, 2**32); constant BUILTIN_BUFFER_SIZE : natural := min(MAX_ENDPOINTS*PARTICIPANT_FRAME_SIZE, 2**32);
--**************** --****************
constant ENDPOINT_MATCH_OPCODE_WIDTH: integer := 32; constant ENDPOINT_MATCH_OPCODE_WIDTH: natural := 32;
constant OPCODE_MATCH : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000000"; constant OPCODE_MATCH : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000000";
constant OPCODE_UNMATCH : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000001"; constant OPCODE_UNMATCH : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000001";
@ -337,13 +339,29 @@ package rtps_package is
type WORD_ARRAY_TYPE is array (range <>) of std_logic_vector(31 downto 0); type WORD_ARRAY_TYPE is array (range <>) of std_logic_vector(31 downto 0);
type OUTPUT_DATA_TYPE is record type OUTPUT_DATA_TYPE is record
data : WORD_ARRAY_TYPE; data : WORD_ARRAY_TYPE;
length : integer; length : natural;
end record; end record;
constant READER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body constant READER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body
constant WRITER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body constant WRITER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body
constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body
-- OVERLOAD FUNCTIONS
function convert_from_double_word (seq: DOUBLE_WORD_ARRAY) return unsigned;
function convert_to_double_word (seq: unsigned(63 downto 0)) return DOUBLE_WORD_ARRAY;
function ">" (L,R: DOUBLE_WORD_ARRAY) return boolean;
function "<" (L,R: DOUBLE_WORD_ARRAY) return boolean;
function ">=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
function "<=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
function "=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
function "/=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
function "+" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
function "+" (L: DOUBLE_WORD_ARRAY, R: natural) return DOUBLE_WORD_ARRAY;
function "+" (L: natural, R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
function "-" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
function "-" (L: DOUBLE_WORD_ARRAY, R: natural) return DOUBLE_WORD_ARRAY;
function "-" (L: natural, R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY;
end package; end package;
package body rtps_package is package body rtps_package is
@ -424,8 +442,8 @@ package body rtps_package is
constant ENDPOINT_TYPE : ENDPOINT_STRING_SLV_TYPE := convert_endpoint_string(ENDPOINT_TYPE_STRING); constant ENDPOINT_TYPE : ENDPOINT_STRING_SLV_TYPE := convert_endpoint_string(ENDPOINT_TYPE_STRING);
constant DOMAIN_TAG : STRING_SLV_WORD_TYPE := convert_string(USER_DOMAIN_TAG); constant DOMAIN_TAG : STRING_SLV_WORD_TYPE := convert_string(USER_DOMAIN_TAG);
function string_len (str : STRING_SLV_WORD_TYPE) return integer is function string_len (str : STRING_SLV_WORD_TYPE) return natural is
ret : integer := 0; ret : natural := 0;
begin begin
ret := 0; ret := 0;
for i in 0 to str'length loop for i in 0 to str'length loop
@ -444,9 +462,9 @@ package body rtps_package is
function gen_reader_endpoint_data return OUTPUT_DATA_TYPE is function gen_reader_endpoint_data return OUTPUT_DATA_TYPE is
-- Limit DATA to MAX UDPv4 Payload Size (65,507 Bytes) -- Limit DATA to MAX UDPv4 Payload Size (65,507 Bytes)
variable ret : OUTPUT_DATA_TYPE(data(0 to 16376)) := (data => (others => (others => '0')), length => 0); variable ret : OUTPUT_DATA_TYPE(data(0 to 16376)) := (data => (others => (others => '0')), length => 0);
variable ind : integer := 0; variable ind : natural := 0;
variable len : integer := 0; variable len : natural := 0;
variable tmp : integer := 0; variable tmp : natural := 0;
begin begin
ret.data := (others => (others => '0')); ret.data := (others => (others => '0'));
ret.length := 0; ret.length := 0;
@ -596,9 +614,9 @@ package body rtps_package is
function gen_writer_endpoint_data return OUTPUT_DATA_TYPE is function gen_writer_endpoint_data return OUTPUT_DATA_TYPE is
-- Limit DATA to MAX UDPv4 Payload Size (65,507 Bytes) -- Limit DATA to MAX UDPv4 Payload Size (65,507 Bytes)
variable ret : OUTPUT_DATA_TYPE(data(0 to 16376)) := (data => (others => (others => '0')), length => 0); variable ret : OUTPUT_DATA_TYPE(data(0 to 16376)) := (data => (others => (others => '0')), length => 0);
variable ind : integer := 0; variable ind : natural := 0;
variable len : integer := 0; variable len : natural := 0;
variable tmp : integer := 0; variable tmp : natural := 0;
begin begin
ret.data := (others => (others => '0')); ret.data := (others => (others => '0'));
ret.length := 0; ret.length := 0;
@ -613,7 +631,7 @@ package body rtps_package is
ret.data(4) := GUIDPREFIX(2); ret.data(4) := GUIDPREFIX(2);
ind := 5; ind := 5;
-- RTPS Submessages -- RTPS Submessages
-- One DATA Submessage for each Endpoint -- One DATA Submessage for each Writer Endpoint
for i in NUM_READERS to MAX_ENDPOINTS-1 loop for i in NUM_READERS to MAX_ENDPOINTS-1 loop
-- RTPS Submessage Header -- RTPS Submessage Header
ret.data(ind) := SID_DATA & "00000100" & x"0000"; ret.data(ind) := SID_DATA & "00000100" & x"0000";
@ -757,9 +775,9 @@ package body rtps_package is
function gen_participant_data return OUTPUT_DATA_TYPE is function gen_participant_data return OUTPUT_DATA_TYPE is
-- Limit DATA to MAX UDPv4 Payload Size (65,507 Bytes) -- Limit DATA to MAX UDPv4 Payload Size (65,507 Bytes)
variable ret : OUTPUT_DATA_TYPE(data(0 to 16376)) := (data => (others => (others => '0')), length => 0); variable ret : OUTPUT_DATA_TYPE(data(0 to 16376)) := (data => (others => (others => '0')), length => 0);
variable ind : integer := 0; variable ind : natural := 0;
variable len : integer := 0; variable len : natural := 0;
variable tmp : integer := 0; variable tmp : natural := 0;
begin begin
ret.data := (others => (others => '0')); ret.data := (others => (others => '0'));
ret.length := 0; ret.length := 0;
@ -932,4 +950,80 @@ package body rtps_package is
constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE := gen_participant_data; constant PARTICIPANT_DATA : OUTPUT_DATA_TYPE := gen_participant_data;
function convert_from_double_word (seq: DOUBLE_WORD_ARRAY) return unsigned is
variable ret : unsigned(SEQUENCE_NR_WIDTH-1 downto 0) := (others => '0');
begin
ret(63 downto 32) := seq(0);
ret(31 downto 0) := seq(1);
return ret;
end function;
function convert_to_double_word (seq: unsigned(63 downto 0)) return DOUBLE_WORD_ARRAY is
variable ret : DOUBLE_WORD_ARRAY := (others => (others => '0'));
begin
ret(0) := seq(63 downto 32);
ret1) := seq(31 downto 0);
return ret;
end function;
function ">" (L,R: DOUBLE_WORD_ARRAY) return boolean is
begin
return convert_from_double_word(L) > convert_from_double_word(R);
end function;
function "<" (L,R: DOUBLE_WORD_ARRAY) return boolean is
begin
return convert_from_double_word(L) < convert_from_double_word(R);
end function;
function ">=" (L,R: DOUBLE_WORD_ARRAY) return boolean is
begin
return convert_from_double_word(L) >= convert_from_double_word(R);
end function;
function "<=" (L,R: DOUBLE_WORD_ARRAY) return boolean is
begin
return convert_from_double_word(L) <= convert_from_double_word(R);
end function;
function "=" (L,R: DOUBLE_WORD_ARRAY) return boolean;
begin
return convert_from_double_word(L) = convert_from_double_word(R);
end function;
function "/=" (L,R: DOUBLE_WORD_ARRAY) return boolean is
begin
return convert_from_double_word(L) /= convert_from_double_word(R);
end function;
function "+" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
begin
return convert_to_double_word(convert_from_double_word(L) + convert_from_double_word(R));
end function;
function "+" (L: DOUBLE_WORD_ARRAY, R: natural) return DOUBLE_WORD_ARRAY is
begin
return convert_to_double_word(convert_from_double_word(L) + R);
end function;
function "+" (L: natural, R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
begin
return convert_to_double_word(L + convert_from_double_word(R));
end function;
function "-" (L,R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
begin
return convert_to_double_word(convert_from_double_word(L) - convert_from_double_word(R));
end function;
function "-" (L: DOUBLE_WORD_ARRAY, R: natural) return DOUBLE_WORD_ARRAY is
begin
return convert_to_double_word(convert_from_double_word(L) - R);
end function;
function "-" (L: natural, R: DOUBLE_WORD_ARRAY) return DOUBLE_WORD_ARRAY is
begin
return convert_to_double_word(L - convert_from_double_word(R));
end function;
end package body; end package body;

View File

@ -12,11 +12,26 @@ entity test is
port ( port (
clk : in std_logic; -- Input Clock clk : in std_logic; -- Input Clock
reset : in std_logic; -- Synchronous Reset reset : in std_logic; -- Synchronous Reset
output : out std_logic cnt : in natural;
output : out unsigned(31 downto 0)
); );
end entity; end entity;
architecture arch of test is architecture arch of test is
signal output_sig : unsigned(31 downto 0) := (others => '0');
begin begin
output <= output_sig;
bitmap: process(all)
begin
output_sig <= (others => '0');
for i in 0 to cnt loop
output_sig(i) <= '1';
end loop;
end process;
end architecture; end architecture;

View File

@ -41,7 +41,7 @@ set_global_assignment -name DEVICE 5CSEBA6U23I7
set_global_assignment -name TOP_LEVEL_ENTITY test set_global_assignment -name TOP_LEVEL_ENTITY test
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.0 set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.0
set_global_assignment -name PROJECT_CREATION_TIME_DATE "12:05:11 MAY 29, 2020" set_global_assignment -name PROJECT_CREATION_TIME_DATE "12:05:11 MAY 29, 2020"
set_global_assignment -name LAST_QUARTUS_VERSION "19.1.0 Lite Edition" set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40"
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100