From bcdf8f0ed9912c470dca5680ec8b901283963479 Mon Sep 17 00:00:00 2001 From: Greek64 Date: Wed, 7 Oct 2020 13:12:04 +0200 Subject: [PATCH] * Switch to single Domain ID --- src/rtps_builtin_endpoint.vhd | 2 - src/rtps_handler.vhd | 1 + src/rtps_package.vhd | 160 ++++++---------------------------- 3 files changed, 29 insertions(+), 134 deletions(-) diff --git a/src/rtps_builtin_endpoint.vhd b/src/rtps_builtin_endpoint.vhd index eec1f1c..8293e3c 100644 --- a/src/rtps_builtin_endpoint.vhd +++ b/src/rtps_builtin_endpoint.vhd @@ -5,8 +5,6 @@ use ieee.numeric_std.all; use work.math_pkg.all; use work.rtps_package.all; --- XXX: The AUTO_PURGE could return through the FIND_ORPHAN_ENDPOINT branch, which returns to IDLE through the SKIP_PACKET stage. Could it be, that a entire packet is droped due to this, or is the "read_counter" and "packet_length" set to prevent that? - entity rtps_builtin_endpoint is generic ( DOMAIN_ID : integer := 0; diff --git a/src/rtps_handler.vhd b/src/rtps_handler.vhd index a61e50d..b66e7e8 100644 --- a/src/rtps_handler.vhd +++ b/src/rtps_handler.vhd @@ -9,6 +9,7 @@ use work.rtps_package.all; -- TODO: Merge CHECK_SUB_END and SKIP_SUB stages -- TODO: Remove payload length and implement "last_word" bit -- TODO: Change all Endpoint Bit Vectors to "to" Ranges +-- TODO: Move to single DOMAIN ID logic -- Checksum has to be checked before entity rtps_handler is diff --git a/src/rtps_package.vhd b/src/rtps_package.vhd index d63e12b..0b5d4b5 100644 --- a/src/rtps_package.vhd +++ b/src/rtps_package.vhd @@ -32,21 +32,13 @@ package rtps_package is constant PORT_CONFIG_D2 : integer := 1; -- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) constant PORT_CONFIG_D3 : integer := 11; - -- Number of Domains - constant NUM_DOMAIN : integer := 1; -- MAC Address of underlying network stack (Used to generate GUIDs) constant MAC_ADDRESS : std_logic_vector(47 downto 0) := x"97917E0BA8CF"; - ----------------------------------------------------------------------------------------------------- - -- *DO NOT MODIFY BEGIN* - type USER_DOMAIN_ID_TYPE is array (0 to NUM_DOMAIN-1) of integer; - -- *DO NOT MODIFY END* - ----------------------------------------------------------------------------------------------------- - -- Array of Domain IDs - constant USER_DOMAIN_ID : USER_DOMAIN_ID_TYPE := (0 => 1); + -- Domain ID + constant USER_DOMAIN_ID : integer := 1; ----------------------------------------------------------------------------------------------------- -- *DO NOT MODIFY BEGIN* - type ENDPOINT_DOMAIN_MAP_TYPE is array (0 to MAX_ENDPOINTS-1) of integer; type ENDPOINT_WITH_KEY_TYPE is array (0 to MAX_ENDPOINTS-1) of boolean; type ENDPOINT_TOPIC_STRING_TYPE is array (0 to MAX_ENDPOINTS-1) of string(1 to 256); type ENDPOINT_TOPIC_TYPE is array (0 to MAX_ENDPOINTS-1) of std_logic_vector(0 to (256*8)-1); @@ -89,9 +81,6 @@ package rtps_package is ----------------------------------------------------------------------------------------------------- --***RTPS ENDPOINTS*** - -- Array mapping the RTPS Endpoints to their respective Domain IDs - -- The index of this array denotes the Endpoint, and the element value the index of the Domain in the 'USER_DOMAIN_ID'. - constant ENDPOINT_DOMAIN_MAP : ENDPOINT_DOMAIN_MAP_TYPE := (0 => 0); -- Array denoting if Endpoints use Keyed Topics constant ENDPOINT_WITH_KEY : ENDPOINT_WITH_KEY_TYPE := (0 => FALSE); -- Array mapping Topic Strings to Endpoints @@ -239,11 +228,7 @@ package rtps_package is - type DOMAIN_ID_TYPE is array (0 to NUM_DOMAIN-1) of std_logic_vector(DOMAIN_ID_WIDTH-1 downto 0); - constant DOMAIN_ID : DOMAIN_ID_TYPE; -- Deferred to Package Body - - type DOMAIN_ENDPOINT_MAP_TYPE is array (0 to NUM_DOMAIN-1) of std_logic_vector(MAX_ENDPOINTS-1 downto 0); - constant DOMAIN_ENDPOINT_MAP : DOMAIN_ENDPOINT_MAP_TYPE; -- Deferred to Package Body + constant DOMAIN_ID : std_logic_vector(DOMAIN_ID_WIDTH-1 downto 0) := to_unsigned(USER_DOMAIN_ID, DOMAIN_ID'length); -- 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 @@ -251,18 +236,30 @@ package rtps_package is -- We generate just a single participant for every Domain, and later match the Endpoints to their respective -- Domain (and thus also to their respective RTPS Participant). - type IPv4_PORT_TYPE is array (0 to NUM_DOMAIN-1) of std_logic_vector(UDP_PORT_WIDTH-1 downto 0); - constant META_IPv4_MULTICAST_PORT: IPv4_PORT_TYPE; -- Deferred to Package Body - constant META_IPv4_UNICAST_PORT : IPv4_PORT_TYPE; -- Deferred to Package Body - constant USER_IPv4_MULTICAST_PORT: IPv4_PORT_TYPE; -- Deferred to Package Body - constant USER_IPv4_UNICAST_PORT : IPv4_PORT_TYPE; -- Deferred to Package Body + -- (see DDSI-RTPS 2.3 Section 9.6.1) + -- PB + DG * domain_id + d0 + constant META_IPv4_MULTICAST_PORT: std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D0 + PORT_CONFIG_DG*USER_DOMAIN_ID, UDP_PORT_WIDTH)); + -- (see DDSI-RTPS 2.3 Section 9.6.1) + -- PB + DG * domainId + d1 + PG * participant_id + -- participant_id=0 + constant META_IPv4_UNICAST_PORT : std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D1 + PORT_CONFIG_DG*USER_DOMAIN_ID, UDP_PORT_WIDTH)); + -- (see DDSI-RTPS 2.3 Section 9.6.1) + -- PB + DG * domainId + d2 + constant USER_IPv4_MULTICAST_PORT: std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D2 + PORT_CONFIG_DG*USER_DOMAIN_ID, UDP_PORT_WIDTH)); + -- (see DDSI-RTPS 2.3 Section 9.6.1) + -- PB + DG * domainId + d3 + PG * participant_id + -- participant_id=0 + constant USER_IPv4_UNICAST_PORT : std_logic_vector(UDP_PORT_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D3 + PORT_CONFIG_DG*USER_DOMAIN_ID, UDP_PORT_WIDTH)); - type GUIDPREFIX_TYPE is array (0 to NUM_DOMAIN-1) of std_logic_vector(GUIDPREFIX_WIDTH-1 downto 0); + -- First two bytes have to be Vendor ID (see DDSI-RTPS 2.3 Section 9.3.1.5) + -- Next we insert the MAC address for uniqueness + -- Next we insert the Domain ID type GUIDPREFIX_ARRAY_TYPE is array (0 to GUIDPREFIX_WIDTH/32-1) of std_logic_vector(31 downto 0); type GUID_ARRAY_TYPE is array (0 to (GUIDPREFIX_WIDTH+ENTITYID_WIDTH)/32-1) of std_logic_vector(31 downto 0); - constant GUIDPREFIX : GUIDPREFIX_TYPE; -- Deferred to Package Body - constant GUIDPREFIX_UNKNOWN : std_logic_vector(0 to GUIDPREFIX_WIDTH-1) := (others => '0'); - constant GUIDPREFIX_UNKNOWN_ARRAY : GUIDPREFIX_ARRAY_TYPE := (others => (others => '0')); + + constant GUIDPREFIX : std_logic_vector(GUIDPREFIX_WIDTH-1 downto 0) := (GUIDPREFIX_WIDTH-1 downto GUIDPREFIX_WIDTH-VENDORID_WIDTH => VENDORID, GUIDPREFIX_WIDTH-VENDORID_WIDTH-1 downto GUIDPREFIX_WIDTH-VENDORID_WIDTH-48 => MAC_ADDRESS, DOMAIN_ID_WIDTH-1 downto 0 => DOMAIN_ID); + constant GUIDPREFIX_UNKNOWN : std_logic_vector(GUIDPREFIX_WIDTH-1 downto 0) := (others => '0'); + constant GUIDPREFIX_UNKNOWN_ARRAY : GUIDPREFIX_ARRAY_TYPE := (others => (others => '0')); subtype ENTITY_KIND_H is std_logic_vector(1 downto 0); subtype ENTITY_KIND_L is std_logic_vector(5 downto 0); @@ -330,116 +327,15 @@ package rtps_package is constant OPCODE_UNMATCH : std_logic_vector(ENDPOINT_MATCH_OPCODE_WIDTH-1 downto 0) := x"55000001"; type USER_ENDPOINT_OUTPUT is array (0 to MAX_ENDPOINTS-1) of std_logic_vector(31 downto 0); - type BUILTIN_ENDPOINT_TYPE is array (0 to NUM_DOMAIN-1) of std_logic_vector(31 downto 0); type ENDPOINT_BITMASK_ARRAY_TYPE is array (0 to ENDPOINT_BITMASK_SIZE-1) of std_logic_vector(31 downto 0); + -- TODO + type BUILTIN_ENDPOINT_DATA_TYPE is array (range <>) of std_logic_vector(31 downto 0); + constant BUILTIN_ENDPOINT_DATA : BUILTIN_ENDPOINT_DATA_TYPE; --Deferred to package body + end package; package body rtps_package is - - function gen_domain_ids (user_id : USER_DOMAIN_ID_TYPE) return DOMAIN_ID_TYPE is - variable ret : DOMAIN_ID_TYPE; - begin - ret := (others => (others => '0')); - for i in 0 to user_id'length-1 loop - -- Check if User provided Domain ID fits - -- NOTE: Cannot assert due to vhdl integer overflow. - --assert (user_id(i) < (2**DOMAIN_ID_WIDTH-1 - PORT_CONFIG_PB) / PORT_CONFIG_DG) report "Domain ID range exceeded" severity failure; - ret(i) := std_logic_vector(to_unsigned(user_id(i), ret(i)'length)); - end loop; - return ret; - end function; - - constant DOMAIN_ID : DOMAIN_ID_TYPE := gen_domain_ids(USER_DOMAIN_ID); - - function gen_domain_endpoint_map (end_id : ENDPOINT_DOMAIN_MAP_TYPE) return DOMAIN_ENDPOINT_MAP_TYPE is - variable ret : DOMAIN_ENDPOINT_MAP_TYPE; - begin - ret := (others => (others => '0')); - for i in 0 to NUM_DOMAIN-1 loop - for j in 0 to MAX_ENDPOINTS-1 loop - if (i = end_id(j)) then - ret(i)(j) := '1'; - end if; - end loop; - end loop; - return ret; - end function; - - constant DOMAIN_ENDPOINT_MAP : DOMAIN_ENDPOINT_MAP_TYPE := gen_domain_endpoint_map(ENDPOINT_DOMAIN_MAP); - - function gen_meta_multicast_ports (domain_id : DOMAIN_ID_TYPE) return IPv4_PORT_TYPE is - variable ret : IPv4_PORT_TYPE; - begin - ret := (others => (others => '0')); - for i in 0 to domain_id'length-1 loop - -- (see DDSI-RTPS 2.3 Section 9.6.1) - -- PB + DG * domain_id + d0 - ret(i) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D0 + PORT_CONFIG_DG*to_integer(unsigned(domain_id(i))), ret(i)'length)); - end loop; - return ret; - end function; - - function gen_meta_unicast_ports (domain_id : DOMAIN_ID_TYPE) return IPv4_PORT_TYPE is - variable ret : IPv4_PORT_TYPE; - begin - ret := (others => (others => '0')); - for i in 0 to domain_id'length-1 loop - -- (see DDSI-RTPS 2.3 Section 9.6.1) - -- PB + DG * domainId + d1 + PG * participant_id - -- participant_id=0 - ret(i) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D1 + PORT_CONFIG_DG*to_integer(unsigned(domain_id(i))), ret(i)'length)); - end loop; - return ret; - end function; - - function gen_user_multicast_ports (domain_id : DOMAIN_ID_TYPE) return IPv4_PORT_TYPE is - variable ret : IPv4_PORT_TYPE; - begin - ret := (others => (others => '0')); - for i in 0 to domain_id'length-1 loop - -- (see DDSI-RTPS 2.3 Section 9.6.1) - -- PB + DG * domainId + d2 - ret(i) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D2 + PORT_CONFIG_DG*to_integer(unsigned(domain_id(i))), ret(i)'length)); - end loop; - return ret; - end function; - - function gen_user_unicast_ports (domain_id : DOMAIN_ID_TYPE) return IPv4_PORT_TYPE is - variable ret : IPv4_PORT_TYPE; - begin - ret := (others => (others => '0')); - for i in 0 to domain_id'length-1 loop - -- (see DDSI-RTPS 2.3 Section 9.6.1) - -- PB + DG * domainId + d3 + PG * participant_id - -- participant_id=0 - ret(i) := std_logic_vector(to_unsigned(PORT_CONFIG_PB + PORT_CONFIG_D3 + PORT_CONFIG_DG*to_integer(unsigned(domain_id(i))), ret(i)'length)); - end loop; - return ret; - end function; - - constant META_IPv4_MULTICAST_PORT: IPv4_PORT_TYPE := gen_meta_multicast_ports(DOMAIN_ID); - constant META_IPv4_UNICAST_PORT : IPv4_PORT_TYPE := gen_meta_unicast_ports(DOMAIN_ID); - constant USER_IPv4_MULTICAST_PORT: IPv4_PORT_TYPE := gen_user_multicast_ports(DOMAIN_ID); - constant USER_IPv4_UNICAST_PORT : IPv4_PORT_TYPE := gen_user_unicast_ports(DOMAIN_ID); - - function gen_guid_prefix (domain_id : DOMAIN_ID_TYPE) return GUIDPREFIX_TYPE is - variable ret : GUIDPREFIX_TYPE; - begin - ret := (others => (others => '0')); - for i in 0 to ret'length-1 loop - -- First to bytes have to be Vendor ID (see DDSI-RTPS 2.3 Section 9.3.1.5) - ret(i)(ret(i)'length-1 downto ret(i)'length-VENDORID_WIDTH) := VENDORID; - -- Next we insert the MAC address for uniqueness - ret(i)(ret(i)'length-VENDORID_WIDTH-1 downto ret(i)'length-VENDORID_WIDTH-48) := MAC_ADDRESS; - -- Next we insert the Domain ID - -- NOTE: If the widths of signals change in the future, this will overwrite part of the MAC Address. - ret(i)(DOMAIN_ID_WIDTH-1 downto 0) := domain_id(i); - end loop; - return ret; - end function; - - constant GUIDPREFIX : GUIDPREFIX_TYPE := gen_guid_prefix(DOMAIN_ID); function gen_entyid return ENTITYID_TYPE is variable ret : ENTITYID_TYPE;