diff --git a/src/Tests/Level_2/L2_Type1_test1.vhd b/src/Tests/Level_2/L2_Type1_test1.vhd index 5ea842b..5cc2508 100644 --- a/src/Tests/Level_2/L2_Type1_test1.vhd +++ b/src/Tests/Level_2/L2_Type1_test1.vhd @@ -71,14 +71,14 @@ architecture testbench of L2_Type1_test1 is -- because I cannot use a qualified expression to define an enumeration literal (and direct type casting cannot be done because -- the types are not closely related). So I have to do define explicit type conversions between the types... - function to_Lib2(input : DDS_WRITER_OPCODE_TYPE) return Testbench_Lib2.rtps_config_package.DDS_WRITER_OPCODE_TYPE is + function to_Lib2(input : DDS_WRITER_OPCODE_TYPE) return Testbench_Lib2.rtps_package.DDS_WRITER_OPCODE_TYPE is begin - return Testbench_Lib2.rtps_config_package.DDS_WRITER_OPCODE_TYPE'VAL(DDS_WRITER_OPCODE_TYPE'POS(input)); + return Testbench_Lib2.rtps_package.DDS_WRITER_OPCODE_TYPE'VAL(DDS_WRITER_OPCODE_TYPE'POS(input)); end function; - function to_Lib3(input : DDS_READER_OPCODE_TYPE) return Testbench_Lib3.rtps_config_package.DDS_READER_OPCODE_TYPE is + function to_Lib3(input : DDS_READER_OPCODE_TYPE) return Testbench_Lib3.rtps_package.DDS_READER_OPCODE_TYPE is begin - return Testbench_Lib3.rtps_config_package.DDS_READER_OPCODE_TYPE'VAL(DDS_READER_OPCODE_TYPE'POS(input)); + return Testbench_Lib3.rtps_package.DDS_READER_OPCODE_TYPE'VAL(DDS_READER_OPCODE_TYPE'POS(input)); end function; begin diff --git a/src/Tests/Level_2/L2_Type1_test2.vhd b/src/Tests/Level_2/L2_Type1_test2.vhd index 2f68a09..8a5a89f 100644 --- a/src/Tests/Level_2/L2_Type1_test2.vhd +++ b/src/Tests/Level_2/L2_Type1_test2.vhd @@ -71,14 +71,14 @@ architecture testbench of L2_Type1_test2 is -- because I cannot use a qualified expression to define an enumeration literal (and direct type casting cannot be done because -- the types are not closely related). So I have to do define explicit type conversions between the types... - function to_Lib5(input : DDS_READER_OPCODE_TYPE) return Testbench_Lib5.rtps_config_package.DDS_READER_OPCODE_TYPE is + function to_Lib5(input : DDS_READER_OPCODE_TYPE) return Testbench_Lib5.rtps_package.DDS_READER_OPCODE_TYPE is begin - return Testbench_Lib5.rtps_config_package.DDS_READER_OPCODE_TYPE'VAL(DDS_READER_OPCODE_TYPE'POS(input)); + return Testbench_Lib5.rtps_package.DDS_READER_OPCODE_TYPE'VAL(DDS_READER_OPCODE_TYPE'POS(input)); end function; - function to_Lib5(input : DDS_WRITER_OPCODE_TYPE) return Testbench_Lib5.rtps_config_package.DDS_WRITER_OPCODE_TYPE is + function to_Lib5(input : DDS_WRITER_OPCODE_TYPE) return Testbench_Lib5.rtps_package.DDS_WRITER_OPCODE_TYPE is begin - return Testbench_Lib5.rtps_config_package.DDS_WRITER_OPCODE_TYPE'VAL(DDS_WRITER_OPCODE_TYPE'POS(input)); + return Testbench_Lib5.rtps_package.DDS_WRITER_OPCODE_TYPE'VAL(DDS_WRITER_OPCODE_TYPE'POS(input)); end function; begin diff --git a/src/ros2/ROS_IDL.txt b/src/ros2/ROS_IDL.txt new file mode 100644 index 0000000..e14d229 --- /dev/null +++ b/src/ros2/ROS_IDL.txt @@ -0,0 +1,21 @@ +SERVICE +####### + +GENERAL +======= + +The Service VHDL generation closely follows the general RTPS IDL interface generation. +For each Service (i.e. .srv File) two files are generated, a server and a client file. +Each file contains both encoding and decoding functionality (similar to the key_holder files). +The code generation follows the normal code generation for encoding and decoding with following changes: + +* Encoding and Decoding stages get a "RQ_"or "RR_" prepended to the to differentiate between + Request and Response message members, respectively. + e.g. GET_A -> GET_RQ_A, WRITE_SUM -> WRITE_RR_SUM +* Similar to the previous point, the _package differentiates the MAX_* sizes of the Request + and Response message members. + e.g. MAX_A_SIZE -> MAX_RQ_A_SIZE, MAX_SUM_SIZE -> MAX_RR_SUM_SIZE +* The _package calculates both a maximum request and response message size, named + MAX__RQ_SIZE and MAX__RR_SIZE, respectively. + The maximum includes the service overhead bytes that are contained in the DDS Payloads. The constant + SERVICE_OVERHEAD_BYTES from ros_package gives this overhead bytes. \ No newline at end of file diff --git a/src/ros2/TEMPLATE_ros_config.vhd b/src/ros2/TEMPLATE_ros_config.vhd new file mode 100644 index 0000000..733d3c7 --- /dev/null +++ b/src/ros2/TEMPLATE_ros_config.vhd @@ -0,0 +1,78 @@ +-- altera vhdl_input_version vhdl_2008 +-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- TODO: Move gen_user_string out of rtps_package? +use work.rtps_package.all; -- gen_user_string + +package ros_config is + + -- IPv4 Address of ROS System [Default 192.168.0.128] + constant ROS_ADDRESS : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := x"C0A80080"; + -- Random Key used to generate GUIDs + constant ROS_RAND_KEY : std_logic_vector(47 downto 0) := x"97917E0BA8CF"; + + constant NUM_NODES : natural := 1; + + constant ROS_NODES : ROS_NODE_ARRAY_TYPE(0 to NUM_NODES-1) := ( + 0 => ( + name => gen_user_string("TestNode"), + namespace => gen_user_string(""), + domain_id => 1, + NUM_PUBS => 1, + NUM_SUBS => 1, + NUM_SERVICES => 1, + NUM_ACTIONS => 0 + ) + ); + + constant NUM_PUBS : natural := get_num_pubs(ROS_NODES); + constant NUM_SUBS : natural := get_num_subs(ROS_NODES); + constant NUM_SERVICES : natural := get_num_services(ROS_NODES); + constant NUM_ACTIONS : natural := get_num_actions(ROS_NODES); + + constant ROS_PUBLICATIONS : ROS_TOPIC_ARRAY_TYPE(0 to NUM_PUBS-1) := ( + 0 => ( + node_id => 0, + TOPICNAME => gen_user_string("Topic1"), + TYPENAME => gen_user_string("Type1"), + QOS => ROS_QOS_PROFILE_DEFAULT, + MAX_SIZE => 10 + ) + ); + + constant ROS_SUBSCRIPTIONS : ROS_TOPIC_ARRAY_TYPE(0 to NUM_SUBS-1) := ( + 0 => ( + node_id => 0, + TOPICNAME => gen_user_string("Topic2"), + TYPENAME => gen_user_string("Type2"), + QOS => ROS_QOS_PROFILE_DEFAULT, + MAX_SIZE => 10 + ) + ); + + constant ROS_SERVICES : ROS_SERVICE_ARRAY_TYPE(0 to NUM_SERVICES-1) := ( + 0 => ( + node_id => 0, + SERVICENAME => gen_user_string("Service1"), + TYPENAME => gen_user_string("Type3"), + QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + MAX_RQ_SIZE => 10, + MAX_RR_SIZE => 10, + is_client => FALSE + ) + ); + + -- TODO + constant ROS_ACTIONS : ROS_ACTION_ARRAY_TYPE(0 to NUM_ACTIONS-1) := ( + others => ( + node_id => 0 + ) + ); + + -- Defines sensible RTPS timings for simulation + constant SIMULATION_TIMING : boolean := FALSE; +end package; \ No newline at end of file diff --git a/src/ros2/dds_user_config.vhd b/src/ros2/dds_user_config.vhd new file mode 100644 index 0000000..e0d4510 --- /dev/null +++ b/src/ros2/dds_user_config.vhd @@ -0,0 +1,195 @@ +-- altera vhdl_input_version vhdl_2008 +-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.rtps_package.all; +use work.ros_package.all; +use work.ros_config.all; + +package user_config is + + --*****USER CONFIG***** + + -- Period of system clock + constant CLOCK_PERIOD : time := 50 ns; + -- Maximum number of supported remote Participants (Affects generated Memory Size) + constant MAX_REMOTE_PARTICIPANTS : natural := 50; + -- Maximum number of supported remote Endpoints (Affects generated Memory Size) + constant MAX_REMOTE_ENDPOINTS : natural := 50; + -- If Multicast Locators should be used instead of Unicast Locators + constant PREFER_MULTICAST_LOCATORS : boolean := FALSE; + + -- Unicast IPv4 Address used by all RTPS Entities [Default 192.168.0.128] + constant DEFAULT_IPv4_ADDRESS : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := ROS_ADDRESS; + -- Number of RTPS Writer Endpoints + constant NUM_WRITERS : natural := NUM_PUBS + NUM_SERVICES + 1; + -- Number of RTPS Reader Endpoints + constant NUM_READERS : natural := NUM_SUBS + NUM_SERVICES; + -- Number of RTPS Endpoints (Do not modify) + constant NUM_ENDPOINTS : natural := NUM_READERS+NUM_WRITERS; + -- PB Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) + constant PORT_CONFIG_PB : natural := 7400; + -- DG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) + constant PORT_CONFIG_DG : natural := 250; + -- PG Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) + constant PORT_CONFIG_PG : natural := 2; + -- D0 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) + constant PORT_CONFIG_D0 : natural := 0; + -- D1 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) + constant PORT_CONFIG_D1 : natural := 10; + -- D2 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) + constant PORT_CONFIG_D2 : natural := 1; + -- D3 Value of Default Port Generation (see DDSI-RTPS 2.3 Section 9.6.1) + constant PORT_CONFIG_D3 : natural := 11; + -- MAC Address of underlying network stack (Used to generate GUIDs) + constant MAC_ADDRESS : std_logic_vector(47 downto 0) := ROS_RAND_KEY; + -- Domain ID + constant USER_DOMAIN_ID : natural := get_domain_id(ROS_NODES); + -- Domain TAG + constant USER_DOMAIN_TAG : USER_STRING_TYPE := gen_user_string(""); + + -- *TIMING CHARACTERISTICS* + -- Timing Characteristics for Participant + constant PARTICIPANT_ANNOUNCEMENT_PERIOD : DURATION_TYPE; + constant PARTICIPANT_LEASE_DURATION : DURATION_TYPE; + -- Denotes how much faster then the deadline/period we schedule in order to account for transport delay. + constant DURATION_DELTA : DURATION_TYPE; + -- Timing Characteristics for built-in Endpoints (Discovery Module) + constant PARTICIPANT_HEARTBEAT_PERIOD : DURATION_TYPE; + constant PARTICIPANT_HEARTBEAT_RESPONSE_DELAY : DURATION_TYPE; + constant PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY : DURATION_TYPE; + constant PARTICIPANT_ACKNACK_RESPONSE_DELAY : DURATION_TYPE; + constant PARTICIPANT_ACKNACK_SUPPRESSION_DELAY : DURATION_TYPE; + + -- *ENDPOINT CONFIG* + constant ENDPOINT_CONFIG : CONFIG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1); -- Deferred to Package Body + + -- Set to TRUE for Simulation Testing (Extra Code generated) + constant SIMULATION_FLAG : boolean := SIMULATION_TIMING; +end package; + +package body user_config is + + function duration_mux(a : DURATION_TYPE; b : DURATION_TYPE; sel : boolean) return DURATION_TYPE is + begin + if (sel) then + return a; + else + return b; + end if; + end function; + + constant PARTICIPANT_ANNOUNCEMENT_PERIOD : DURATION_TYPE := duration_mux(gen_duration(50 us), gen_duration(30 sec), SIMULATION_TIMING); + constant PARTICIPANT_LEASE_DURATION : DURATION_TYPE := duration_mux(DEFAULT_PARTICIPANT_LEASE_DURATION, DEFAULT_PARTICIPANT_LEASE_DURATION, SIMULATION_TIMING); + constant DURATION_DELTA : DURATION_TYPE := duration_mux(gen_duration(50 ns), gen_duration(100 ms), SIMULATION_TIMING); + constant PARTICIPANT_HEARTBEAT_PERIOD : DURATION_TYPE := duration_mux(gen_duration(40 us), gen_duration(1 sec), SIMULATION_TIMING); + constant PARTICIPANT_HEARTBEAT_RESPONSE_DELAY : DURATION_TYPE := duration_mux(gen_duration(500 ns), gen_duration(500 ms), SIMULATION_TIMING); + constant PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY : DURATION_TYPE := duration_mux(gen_duration(100 ns), gen_duration(0 ms), SIMULATION_TIMING); + constant PARTICIPANT_ACKNACK_RESPONSE_DELAY : DURATION_TYPE := duration_mux(gen_duration(500 ns), gen_duration(200 ms), SIMULATION_TIMING); + constant PARTICIPANT_ACKNACK_SUPPRESSION_DELAY : DURATION_TYPE := duration_mux(gen_duration(100 ns), gen_duration(0 ms), SIMULATION_TIMING); + + procedure set_sim_timing (ref : inout CONFIG_TYPE; sel : in boolean) is + begin + if (sel) then + ref.HEARTBEAT_PERIOD := gen_duration(10 us); + ref.HEARTBEAT_RESPONSE_DELAY := gen_duration(500 ns); + ref.HEARTBEAT_SUPPRESSION_DELAY := gen_duration(100 ns); + ref.ACKNACK_RESPONSE_DELAY := gen_duration(500 ns); + ref.ACKNACK_SUPPRESSION_DELAY := gen_duration(100 ns); + end if; + end procedure; + + -- NOTE: This function sets also the + function gen_config return CONFIG_ARRAY_TYPE is + variable ret : CONFIG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1); + variable index : natural; + variable tmp : USER_STRING_TYPE; + begin + + check_node_mapping(ROS_NODES, ROS_PUBLICATIONS, ROS_SUBSCRIPTIONS, ROS_SERVICES, ROS_ACTIONS); + index := 0; + + -- SUBSCRIPTIONS + for i in 0 to ROS_SUBSCRIPTIONS'length-1 loop + ret(index) := DEFAULT_READER_CONFIG; + set_from_qos_profile(ROS_SUBSCRIPTIONS(i).QOS, ret(index)); + set_sim_timing(ret(index),SIMULATION_TIMING); + ret(index).TYPENAME := ROS_SUBSCRIPTIONS(i).TYPENAME; + ret(index).MAX_PAYLOAD_SIZE := ROS_SUBSCRIPTIONS(i).MAX_SIZE; + tmp := gen_fqn(ROS_NODES(ROS_SUBSCRIPTIONS(i).node_id).namespace, ROS_NODES(ROS_SUBSCRIPTIONS(i).node_id).name, ROS_SUBSCRIPTIONS(i).TOPICNAME); + if (not ROS_SUBSCRIPTIONS(i).QOS.AVOID_ROS_NAMESPACE_CONVENTION) then + ret(index).TOPICNAME := concat("rt",tmp); + else + ret(index).TOPICNAME := tmp; + end if; + index := index + 1; + end loop; + -- SERVICE SUBS + for i in 0 to ROS_SERVICES'length-1 loop + ret(index) := DEFAULT_READER_CONFIG; + set_from_qos_profile(ROS_SERVICES(i).QOS, ret(index)); + set_sim_timing(ret(index),SIMULATION_TIMING); + ret(index).TYPENAME := ROS_SERVICES(i).TYPENAME; + tmp := gen_fqn(ROS_NODES(ROS_SERVICES(i).node_id).namespace, ROS_NODES(ROS_SERVICES(i).node_id).name, ROS_SERVICES(i).SERVICENAME); + if (ROS_SERVICES(i).is_client) then + ret(index).TOPICNAME := concat("rr",concat(tmp,"Response")); + ret(index).MAX_PAYLOAD_SIZE := ROS_SERVICES(i).MAX_RR_SIZE; + else + ret(index).TOPICNAME := concat("rq",concat(tmp,"Request")); + ret(index).MAX_PAYLOAD_SIZE := ROS_SERVICES(i).MAX_RQ_SIZE; + end if; + index := index + 1; + end loop; + -- PUBLICATIONS + for i in 0 to ROS_PUBLICATIONS'length-1 loop + ret(index) := DEFAULT_WRITER_CONFIG; + set_from_qos_profile(ROS_PUBLICATIONS(i).QOS, ret(index)); + set_sim_timing(ret(index),SIMULATION_TIMING); + ret(index).TYPENAME := ROS_PUBLICATIONS(i).TYPENAME; + ret(index).MAX_PAYLOAD_SIZE := ROS_PUBLICATIONS(i).MAX_SIZE; + tmp := gen_fqn(ROS_NODES(ROS_PUBLICATIONS(i).node_id).namespace, ROS_NODES(ROS_PUBLICATIONS(i).node_id).name, ROS_PUBLICATIONS(i).TOPICNAME); + if (not ROS_PUBLICATIONS(i).QOS.AVOID_ROS_NAMESPACE_CONVENTION) then + ret(index).TOPICNAME := concat("rt",tmp); + else + ret(index).TOPICNAME := tmp; + end if; + index := index + 1; + end loop; + -- SERVICE PUBS + for i in 0 to ROS_SERVICES'length-1 loop + ret(index) := DEFAULT_WRITER_CONFIG; + set_from_qos_profile(ROS_SERVICES(i).QOS, ret(index)); + set_sim_timing(ret(index),SIMULATION_TIMING); + ret(index).TYPENAME := ROS_SERVICES(i).TYPENAME; + tmp := gen_fqn(ROS_NODES(ROS_SERVICES(i).node_id).namespace, ROS_NODES(ROS_SERVICES(i).node_id).name, ROS_SERVICES(i).SERVICENAME); + if (ROS_SERVICES(i).is_client) then + ret(index).TOPICNAME := concat("rq",concat(tmp,"Request")); + ret(index).MAX_PAYLOAD_SIZE := ROS_SERVICES(i).MAX_RQ_SIZE; + else + ret(index).TOPICNAME := concat("rr",concat(tmp,"Response")); + ret(index).MAX_PAYLOAD_SIZE := ROS_SERVICES(i).MAX_RR_SIZE; + end if; + index := index + 1; + end loop; + -- ROS DISCOVERY PUB + ret(index) := DEFAULT_WRITER_CONFIG; + set_sim_timing(ret(index),SIMULATION_TIMING); + ret(index).RELIABILITY_QOS := RELIABLE_RELIABILITY_QOS; + ret(index).DURABILITY_QOS := TRANSIENT_LOCAL_DURABILITY_QOS; + ret(index).HISTORY_QOS := KEEP_LAST_HISTORY_QOS; + ret(index).HISTORY_DEPTH := std_logic_vector(to_unsigned(1, CDR_LONG_WIDTH)); + ret(index).MAX_SAMPLES := std_logic_vector(to_unsigned(1, CDR_LONG_WIDTH)); + ret(index).MAX_INSTANCES := std_logic_vector(to_unsigned(1, CDR_LONG_WIDTH)); + ret(index).MAX_SAMPLES_PER_INSTANCE := std_logic_vector(to_unsigned(1, CDR_LONG_WIDTH)); + ret(index).TOPICNAME := gen_user_string("ros_discovery_info"); + ret(index).TYPENAME := gen_user_string("rmw_dds_common::msg::dds_::ParticipantEntitiesInfo_"); + + return ret; + end function; + + constant ENDPOINT_CONFIG : CONFIG_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := gen_config; + +end package body; \ No newline at end of file diff --git a/src/ros2/example_interfaces/AddTwoInts_srv_client.vhd b/src/ros2/example_interfaces/AddTwoInts_srv_client.vhd index 4f55b36..a85fbf0 100644 --- a/src/ros2/example_interfaces/AddTwoInts_srv_client.vhd +++ b/src/ros2/example_interfaces/AddTwoInts_srv_client.vhd @@ -94,8 +94,8 @@ architecture arch of AddTwoInts_srv_client is -- FSM states. Explained below in detail type STAGE_TYPE is (IDLE,RETURN_ROS,INITIATE_READ,WAIT_FOR_READER,WAIT_FOR_WRITER,WAIT_FOR_DATA,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD,INITIATE_WRITE,WRITE_PAYLOAD_HEADER,PUSH,ALIGN_OUT_STREAM,ENCODE_PAYLOAD); -- ###GENERATED START### - type ENCODE_STAGE_TYPE is (WRITE_RID_WGUID,WRITE_RID_SN,WRITE_A,WRITE_B); - type DECODE_STAGE_TYPE is (GET_RID_WGUID,GET_RID_SN,GET_OPTIONAL_HEADER,GET_SUM); + type ENCODE_STAGE_TYPE is (WRITE_RID_WGUID,WRITE_RID_SN,WRITE_RQ_A,WRITE_RQ_B); + type DECODE_STAGE_TYPE is (GET_RID_WGUID,GET_RID_SN,GET_OPTIONAL_HEADER,GET_RR_SUM); -- ###GENERATED END### -- *MAIN PROCESS* @@ -397,7 +397,7 @@ begin service_info_sig_next.request_id.sequence_number <= to_double_word(unsigned(endian_swap(endian_flag, dw_latch))); align_offset_next <= align_offset + 8; -- ###GENERATED START### - decode_stage_next <= GET_SUM; + decode_stage_next <= GET_RR_SUM; cnt_next <= 0; -- ###GENERATED END### when others => @@ -405,7 +405,7 @@ begin end case; end if; -- ###GENERATED START### - when GET_SUM => + when GET_RR_SUM => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then target_align_next <= ALIGN_8; @@ -604,14 +604,14 @@ begin stage_next <= PUSH; align_offset_next <= align_offset + 8; -- ###GENERATED START### - encode_stage_next <= WRITE_A; + encode_stage_next <= WRITE_RQ_A; cnt_next <= 0; -- ###GENERATED END### when others => end case; end if; -- ###GENERATED START### - when WRITE_A => + when WRITE_RQ_A => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then target_align_next <= ALIGN_8; @@ -627,12 +627,12 @@ begin stage_next <= PUSH; align_offset_next <= align_offset + 8; - encode_stage_next <= WRITE_B; + encode_stage_next <= WRITE_RQ_B; cnt_next <= 0; when others => end case; end if; - when WRITE_B => + when WRITE_RQ_B => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then target_align_next <= ALIGN_8; diff --git a/src/ros2/example_interfaces/AddTwoInts_srv_server.vhd b/src/ros2/example_interfaces/AddTwoInts_srv_server.vhd index 7ef20ae..8606f35 100644 --- a/src/ros2/example_interfaces/AddTwoInts_srv_server.vhd +++ b/src/ros2/example_interfaces/AddTwoInts_srv_server.vhd @@ -94,8 +94,8 @@ architecture arch of AddTwoInts_srv_server is -- FSM states. Explained below in detail type STAGE_TYPE is (IDLE,RETURN_ROS,INITIATE_READ,WAIT_FOR_READER,WAIT_FOR_WRITER,WAIT_FOR_DATA,GET_PAYLOAD_HEADER,FETCH,ALIGN_IN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD,INITIATE_WRITE,WRITE_PAYLOAD_HEADER,PUSH,ALIGN_OUT_STREAM,ENCODE_PAYLOAD); -- ###GENERATED START### - type ENCODE_STAGE_TYPE is (WRITE_RID_WGUID,WRITE_RID_SN,WRITE_SUM); - type DECODE_STAGE_TYPE is (GET_RID_WGUID,GET_RID_SN,GET_OPTIONAL_HEADER,GET_A,GET_B); + type ENCODE_STAGE_TYPE is (WRITE_RID_WGUID,WRITE_RID_SN,WRITE_RR_SUM); + type DECODE_STAGE_TYPE is (GET_RID_WGUID,GET_RID_SN,GET_OPTIONAL_HEADER,GET_RQ_A,GET_RQ_B); -- ###GENERATED END### -- *MAIN PROCESS* @@ -107,7 +107,7 @@ architecture arch of AddTwoInts_srv_server is signal dw_latch, dw_latch_next : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); signal align_offset, align_offset_next : unsigned(MAX_ALIGN_OFFSET_WIDTH-1 downto 0); signal align_op, align_op_next : std_logic; - signal target_align, target_align_next : ALIGN_TYPE; + signal tarGET_RQ_Align, tarGET_RQ_Align_next : ALIGN_TYPE; signal data_in_latch, data_in_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0); signal optional, optional_next : std_logic; signal data_out_latch, data_out_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0); @@ -171,7 +171,7 @@ begin last_word_in_latch_next <= last_word_in_latch; decode_error_latch_next <= decode_error_latch; align_offset_next <= align_offset; - target_align_next <= target_align; + tarGET_RQ_Align_next <= tarGET_RQ_Align; data_out_latch_next <= data_out_latch; finalize_payload_next <= finalize_payload; optional_next <= optional; @@ -322,7 +322,7 @@ begin end if; when ALIGN_IN_STREAM => -- Target Stream Alignment reached - if (check_align(align_offset, target_align)) then + if (check_align(align_offset, tarGET_RQ_Align)) then -- DONE stage_next <= DECODE_PAYLOAD; else @@ -348,7 +348,7 @@ begin when GET_RID_WGUID => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then - target_align_next <= ALIGN_8; + tarGET_RQ_Align_next <= ALIGN_8; stage_next <= ALIGN_IN_STREAM; else case (cnt) is @@ -376,7 +376,7 @@ begin when GET_RID_SN => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then - target_align_next <= ALIGN_8; + tarGET_RQ_Align_next <= ALIGN_8; stage_next <= ALIGN_IN_STREAM; else case (cnt) is @@ -395,7 +395,7 @@ begin service_info_sig_next.request_id.sequence_number <= to_double_word(unsigned(endian_swap(endian_flag, dw_latch))); align_offset_next <= align_offset + 8; -- ###GENERATED START### - decode_stage_next <= GET_A; + decode_stage_next <= GET_RQ_A; cnt_next <= 0; -- ###GENERATED END### when others => @@ -403,10 +403,10 @@ begin end case; end if; -- ###GENERATED START### - when GET_A => + when GET_RQ_A => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then - target_align_next <= ALIGN_8; + tarGET_RQ_Align_next <= ALIGN_8; stage_next <= ALIGN_IN_STREAM; else case (cnt) is @@ -424,16 +424,16 @@ begin when 2 => a_latch_next <= endian_swap(endian_flag, dw_latch); align_offset_next <= align_offset + 8; - decode_stage_next <= GET_B; + decode_stage_next <= GET_RQ_B; cnt_next <= 0; when others => null; end case; end if; - when GET_B => + when GET_RQ_B => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then - target_align_next <= ALIGN_8; + tarGET_RQ_Align_next <= ALIGN_8; stage_next <= ALIGN_IN_STREAM; else case (cnt) is @@ -461,7 +461,7 @@ begin when GET_OPTIONAL_HEADER => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_4)) then - target_align_next <= ALIGN_4; + tarGET_RQ_Align_next <= ALIGN_4; stage_next <= ALIGN_IN_STREAM; else case (cnt) is @@ -580,7 +580,7 @@ begin end if; when ALIGN_OUT_STREAM => -- Target Stream Alignment reached - if (check_align(align_offset, target_align)) then + if (check_align(align_offset, tarGET_RQ_Align)) then -- DONE stage_next <= ENCODE_PAYLOAD; else @@ -596,7 +596,7 @@ begin when WRITE_RID_WGUID => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then - target_align_next <= ALIGN_8; + tarGET_RQ_Align_next <= ALIGN_8; stage_next <= ALIGN_OUT_STREAM; else case (cnt) is @@ -616,7 +616,7 @@ begin when WRITE_RID_SN => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then - target_align_next <= ALIGN_8; + tarGET_RQ_Align_next <= ALIGN_8; stage_next <= ALIGN_OUT_STREAM; else case (cnt) is @@ -629,17 +629,17 @@ begin stage_next <= PUSH; align_offset_next <= align_offset + 8; -- ###GENERATED START### - encode_stage_next <= WRITE_SUM; + encode_stage_next <= WRITE_RR_SUM; cnt_next <= 0; -- ###GENERATED END### when others => end case; end if; -- ###GENERATED START### - when WRITE_SUM => + when WRITE_RR_SUM => -- ALIGN GUARD if (not check_align(align_offset, ALIGN_8)) then - target_align_next <= ALIGN_8; + tarGET_RQ_Align_next <= ALIGN_8; stage_next <= ALIGN_OUT_STREAM; else case (cnt) is @@ -693,7 +693,7 @@ begin encode_stage <= WRITE_RID_WGUID; decode_stage <= GET_RID_WGUID; return_stage <= GET_RID_WGUID; - target_align <= ALIGN_1; + tarGET_RQ_Align <= ALIGN_1; cnt <= 0; endian_flag <= '0'; last_word_in_latch <= '0'; @@ -718,7 +718,7 @@ begin encode_stage <= encode_stage_next; decode_stage <= decode_stage_next; return_stage <= return_stage_next; - target_align <= target_align_next; + tarGET_RQ_Align <= tarGET_RQ_Align_next; cnt <= cnt_next; endian_flag <= endian_flag_next; last_word_in_latch <= last_word_in_latch_next; diff --git a/src/ros2/rmw_dds_common/Gid.msg b/src/ros2/rmw_dds_common/Gid.msg new file mode 100644 index 0000000..97d1a4c --- /dev/null +++ b/src/ros2/rmw_dds_common/Gid.msg @@ -0,0 +1 @@ +char[24] data diff --git a/src/ros2/rmw_dds_common/NodeEntitiesInfo.msg b/src/ros2/rmw_dds_common/NodeEntitiesInfo.msg new file mode 100644 index 0000000..00c410f --- /dev/null +++ b/src/ros2/rmw_dds_common/NodeEntitiesInfo.msg @@ -0,0 +1,4 @@ +string<=256 node_namespace +string<=256 node_name +Gid[] reader_gid_seq +Gid[] writer_gid_seq diff --git a/src/ros2/rmw_dds_common/ParticipantEntitiesInfo.msg b/src/ros2/rmw_dds_common/ParticipantEntitiesInfo.msg new file mode 100644 index 0000000..968b253 --- /dev/null +++ b/src/ros2/rmw_dds_common/ParticipantEntitiesInfo.msg @@ -0,0 +1,2 @@ +Gid gid +NodeEntitiesInfo[] node_entities_info_seq diff --git a/src/ros2/ros_config_package.vhd b/src/ros2/ros_config_package.vhd new file mode 100644 index 0000000..3821272 --- /dev/null +++ b/src/ros2/ros_config_package.vhd @@ -0,0 +1,141 @@ +-- altera vhdl_input_version vhdl_2008 +-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.math_pkg.all; +use work.rtps_package.all; +use work.ros_package.all; +use work.ros_config.all; +use work.user_config.all; +use work.rtps_config_package.all; + +package ros_config_package is + constant ENDPOINT_ROS_NODE_MAPPING : ENDPOINT_ROS_NODE_MAPPING_ARRAY_TYPE(0 to NUM_ENDPOINTS-1); -- Deferred to Package Body + constant ROS_DISCOVERY_DATA : OUTPUT_DATA_TYPE; --Deferred to package body +end package; + +package body ros_config_package is + + -- NOTE: This function has to mirror the behaviour of the 'gen_config' function of the user_config package + function gen_endpoint_node_mapping return ENDPOINT_ROS_NODE_MAPPING_ARRAY_TYPE is + variable ret : ENDPOINT_ROS_NODE_MAPPING_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := (others => 0); + variable index : natural; + begin + ret := (others => NUM_NODES); + index := 0; + + -- SUBSCRIPTIONS + for i in 0 to ROS_SUBSCRIPTIONS'length-1 loop + ret(index) := ROS_SUBSCRIPTIONS(i).node_id; + index := index + 1; + end loop; + -- SERVICE SUBS + for i in 0 to ROS_SERVICES'length-1 loop + ret(index) := ROS_SERVICES(i).node_id; + index := index + 1; + end loop; + -- PUBLICATIONS + for i in 0 to ROS_PUBLICATIONS'length-1 loop + ret(index) := ROS_PUBLICATIONS(i).node_id; + index := index + 1; + end loop; + -- SERVICE PUBS + for i in 0 to ROS_SERVICES'length-1 loop + ret(index) := ROS_SERVICES(i).node_id; + index := index + 1; + end loop; + + return ret; + end function; + + constant ENDPOINT_ROS_NODE_MAPPING : ENDPOINT_ROS_NODE_MAPPING_ARRAY_TYPE(0 to NUM_ENDPOINTS-1) := gen_endpoint_node_mapping; + + function gen_ros_discovery_data return OUTPUT_DATA_TYPE is + variable ret : OUTPUT_DATA_TYPE; + variable gid : GID_TYPE; + variable tmp : natural; + begin + ret.data := (others => (others => '0')); + ret.length := 0; + + -- Sanity Check + if (NUM_NODES = 0) then + return ret; + end if; + + -- Serialized Payload Header + ret.data(ret.length) := PL_CDR_BE & x"0000"; + ret.length := ret.length + 1; + -- ParticipantEntitiesInfo.gid + gid := to_gid(to_guid(GUIDPREFIX,ENTITYID_PARTICIPANT)); + for i in 0 to GID'length-1 loop + ret.data(ret.length) := gid(i); + ret.length := ret.length + 1; + end loop; + -- ParticipantEntitiesInfo.node_entities_info_seq [LENGTH] + ret.data(ret.length) := std_logic_vector(to_unsigned(NUM_NODES,WORD_WIDTH)); + ret.length := ret.length + 1; + for i in 0 to NUM_NODES-1 loop + -- ParticipantEntitiesInfo.node_entities_info_seq[i].node_namespace + ret.data(ret.length) := std_logic_vector(to_unsigned(string_len(ROS_NODES(i).namespace),WORD_WIDTH)); + ret.length := ret.length + 1; + for j in 0 to round_div(string_len(ROS_NODES(i).namespace),WORD_WIDTH/BYTE_WIDTH)-1 loop + ret.data(ret.length) := convert_string(ROS_NODES(i).namespace)(j); + ret.length := ret.length + 1; + end loop; + -- ParticipantEntitiesInfo.node_entities_info_seq[i].node_name + ret.data(ret.length) := std_logic_vector(to_unsigned(string_len(ROS_NODES(i).name),WORD_WIDTH)); + ret.length := ret.length + 1; + for j in 0 to round_div(string_len(ROS_NODES(i).name),WORD_WIDTH/BYTE_WIDTH)-1 loop + ret.data(ret.length) := convert_string(ROS_NODES(i).name)(j); + ret.length := ret.length + 1; + end loop; + -- ParticipantEntitiesInfo.node_entities_info_seq[i].reader_gid_seq [LENGTH] + tmp := 0; + for j in 0 to NUM_READERS-1 loop + if (i = ENDPOINT_ROS_NODE_MAPPING(j)) then + tmp := tmp + 1; + end if; + end loop; + ret.data(ret.length) := std_logic_vector(to_unsigned(tmp,WORD_WIDTH)); + ret.length := ret.length + 1; + -- ParticipantEntitiesInfo.node_entities_info_seq[i].reader_gid_seq[j] + for j in 0 to NUM_READERS-1 loop + if (i = ENDPOINT_ROS_NODE_MAPPING(j)) then + gid := to_gid(to_guid(GUIDPREFIX,ENTITYID(j))); + for k in 0 to GID'length-1 loop + ret.data(ret.length) := gid(k); + ret.length := ret.length + 1; + end loop; + end if; + end loop; + -- ParticipantEntitiesInfo.node_entities_info_seq[i].writer_gid_seq [LENGTH] + tmp := 0; + for j in NUM_READERS to NUM_ENDPOINTS-1 loop + if (i = ENDPOINT_ROS_NODE_MAPPING(j)) then + tmp := tmp + 1; + end if; + end loop; + ret.data(ret.length) := std_logic_vector(to_unsigned(tmp,WORD_WIDTH)); + ret.length := ret.length + 1; + -- ParticipantEntitiesInfo.node_entities_info_seq[i].writer_gid_seq[j] + for j in NUM_READERS to NUM_ENDPOINTS-1 loop + if (i = ENDPOINT_ROS_NODE_MAPPING(j)) then + gid := to_gid(to_guid(GUIDPREFIX,ENTITYID(j))); + for k in 0 to GID'length-1 loop + ret.data(ret.length) := gid(k); + ret.length := ret.length + 1; + end loop; + end if; + end loop; + end loop; + + return ret; + end function; + + constant ROS_DISCOVERY_DATA : OUTPUT_DATA_TYPE := gen_ros_discovery_data; + +end package body; diff --git a/src/ros2/ros_package.vhd b/src/ros2/ros_package.vhd index ce72d5e..b39aa5b 100644 --- a/src/ros2/ros_package.vhd +++ b/src/ros2/ros_package.vhd @@ -6,7 +6,6 @@ use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.rtps_package.all; -use work.rtps_config_package.all; --TODO: Remove after putting DDS_*_OPCODE_TYPE inside rtps_package package ros_package is @@ -58,6 +57,18 @@ package ros_package is AVOID_ROS_NAMESPACE_CONVENTION => FALSE ); + constant ROS_QOS_PROFILE_TRANSIENT : ROS_QOS_PROFILE_TYPE := ( + HISTORY_QOS => KEEP_LAST_HISTORY_QOS, + HISTORY_DEPTH => std_logic_vector(to_unsigned(10, CDR_LONG_WIDTH)), + RELIABILITY_QOS => RELIABLE_RELIABILITY_QOS, + DURABILITY_QOS => TRANSIENT_LOCAL_DURABILITY_QOS, + DEADLINE_QOS => DEFAULT_DEADLINE_QOS, + LIFESPAN_QOS => DEFAULT_LIFESPAN_QOS, + LIVELINESS_QOS => DEFAULT_LIVELINESS_QOS, + LEASE_DURATION => DEFAULT_LEASE_DURATION, + AVOID_ROS_NAMESPACE_CONVENTION => FALSE + ); + constant ROS_QOS_PROFILE_SERVICES_DEFAULT : ROS_QOS_PROFILE_TYPE := ( HISTORY_QOS => KEEP_LAST_HISTORY_QOS, HISTORY_DEPTH => std_logic_vector(to_unsigned(10, CDR_LONG_WIDTH)), @@ -94,6 +105,8 @@ package ros_package is AVOID_ROS_NAMESPACE_CONVENTION => FALSE ); + + type ROS_NODE_TYPE is record --context_id : natural; name : USER_STRING_TYPE; @@ -110,6 +123,7 @@ package ros_package is TOPICNAME : USER_STRING_TYPE; TYPENAME : USER_STRING_TYPE; QOS : ROS_QOS_PROFILE_TYPE; + MAX_SIZE : natural; end record; type ROS_SERVICE_TYPE is record @@ -117,6 +131,8 @@ package ros_package is SERVICENAME : USER_STRING_TYPE; TYPENAME : USER_STRING_TYPE; QOS : ROS_QOS_PROFILE_TYPE; + MAX_RQ_SIZE : natural; + MAX_RR_SIZE : natural; is_client : boolean; end record; @@ -163,6 +179,8 @@ package ros_package is function to_gid(guid : GUID_TYPE) return GID_TYPE; + constant SERVICE_OVERHEAD_BYTES : natural := 16; + function get_num_pubs(nodes : ROS_NODE_ARRAY_TYPE) return natural; function get_num_subs(nodes : ROS_NODE_ARRAY_TYPE) return natural; function get_num_services(nodes : ROS_NODE_ARRAY_TYPE) return natural; @@ -350,11 +368,11 @@ package body ros_package is procedure check_node_mapping (nodes : in ROS_NODE_ARRAY_TYPE; pubs : in ROS_TOPIC_ARRAY_TYPE; subs : in ROS_TOPIC_ARRAY_TYPE; services : in ROS_SERVICE_ARRAY_TYPE; actions : in ROS_ACTION_ARRAY_TYPE) is variable tmp : natural; begin - for i in 0 to nodes'length loop + for i in 0 to nodes'length-1 loop -- Check PUB Mapping if (nodes(i).NUM_PUBS > 0) then tmp := 0; - for j in 0 to pubs'length loop + for j in 0 to pubs'length-1 loop if (pubs(j).node_id = i) then tmp := tmp + 1; end if; @@ -365,7 +383,7 @@ package body ros_package is -- Check SUB Mapping if (nodes(i).NUM_SUBS > 0) then tmp := 0; - for j in 0 to subs'length loop + for j in 0 to subs'length-1 loop if (subs(j).node_id = i) then tmp := tmp + 1; end if; @@ -376,7 +394,7 @@ package body ros_package is -- Check SERVICE Mapping if (nodes(i).NUM_SERVICES > 0) then tmp := 0; - for j in 0 to services'length loop + for j in 0 to services'length-1 loop if (services(j).node_id = i) then tmp := tmp + 1; end if; @@ -387,7 +405,7 @@ package body ros_package is -- Check ACTION Mapping if (nodes(i).NUM_ACTIONS > 0) then tmp := 0; - for j in 0 to actions'length loop + for j in 0 to actions'length-1 loop if (actions(j).node_id = i) then tmp := tmp + 1; end if; diff --git a/src/ros2/ros_static_discovery_writer.vhd b/src/ros2/ros_static_discovery_writer.vhd new file mode 100644 index 0000000..648a75a --- /dev/null +++ b/src/ros2/ros_static_discovery_writer.vhd @@ -0,0 +1,159 @@ +-- altera vhdl_input_version vhdl_2008 +-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.math_pkg.all; +use work.rtps_package.all; +use work.ros_config_package.all; + +entity ros_static_discovery_writer is + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- TO/FROM RTPS ENDPOINT + start : in std_logic; + opcode : in HISTORY_CACHE_OPCODE_TYPE; + ack : out std_logic; + done : out std_logic; + ret : out HISTORY_CACHE_RESPONSE_TYPE; + seq_nr : in SEQUENCENUMBER_TYPE; + get_data : in std_logic; + data_out : out std_logic_vector(WORD_WIDTH-1 downto 0); + valid_out : out std_logic; + ready_out : in std_logic; + last_word_out : out std_logic; + liveliness_assertion : out std_logic; + data_available : out std_logic; + -- Cache Change + cc_instance_handle : out INSTANCE_HANDLE_TYPE; + cc_kind : out CACHE_CHANGE_KIND_TYPE; + cc_source_timestamp : out TIME_TYPE; + cc_seq_nr : out SEQUENCENUMBER_TYPE + ); +end entity; + +architecture arch of ros_static_discovery_writer is + + constant SN : SEQUENCENUMBER_TYPE := FIRST_SEQUENCENUMBER; + + --*****TYPE DECLARATION***** + type STAGE_TYPE is (IDLE,CACHE_CHANGE,DATA,RET_SN,RET_RTPS); + + --*****SIGNAL DECLARATION***** + signal stage, stage_next : STAGE_TYPE; + signal ret_code, ret_code_next : HISTORY_CACHE_RESPONSE_TYPE; + signal data_available_sig, data_available_sig_next : std_logic; + signal cnt, cnt_next : integer range 0 to ROS_DISCOVERY_DATA.length; + +begin + + liveliness_assertion <= '0'; + data_available <= data_available_sig; + + main_prc : process(all) + begin + -- DEFAULT + stage_next <= stage; + cnt_next <= cnt; + ret_code_next <= ret_code; + data_available_sig_next <= data_available_sig; + -- DEFAULT Unregistered + ack <= '0'; + done <= '0'; + ret <= OK; + data_out <= (others => '0'); + valid_out <= '0'; + last_word_out <= '0'; + cc_instance_handle <= HANDLE_NIL; + cc_kind <= ALIVE; + cc_source_timestamp <= TIME_INVALID; + cc_seq_nr <= SEQUENCENUMBER_UNKNOWN; + + + case (stage) is + when IDLE => + if (start = '1') then + ack <= '1'; + case (opcode) is + when GET_MIN_SN => + stage_next <= RET_SN; + when GET_MAX_SN => + -- Reset Data Available + data_available_sig_next <= '0'; + + stage_next <= RET_SN; + when GET_CACHE_CHANGE => + cnt_next <= 0; + stage_next <= CACHE_CHANGE; + when ACK_CACHE_CHANGE => + ret_code_next <= OK; + stage_next <= RET_RTPS; + when NACK_CACHE_CHANGE => + ret_code_next <= OK; + stage_next <= RET_RTPS; + when REMOVE_CACHE_CHANGE => + ret_code_next <= OK; + stage_next <= RET_RTPS; + when others => + end case; + end if; + when CACHE_CHANGE => + done <= '1'; + ret <= OK; + cc_seq_nr <= SN; + + if (get_data = '1') then + stage_next <= DATA; + else + stage_next <= IDLE; + end if; + when DATA => + valid_out <= '1'; + data_out <= ROS_DISCOVERY_DATA.data(cnt); + if (cnt = ROS_DISCOVERY_DATA.length-1) then + last_word_out <= '1'; + end if; + + if (ready_out = '1') then + if (cnt = ROS_DISCOVERY_DATA.length-1) then + stage_next <= IDLE; + else + cnt_next <= cnt + 1; + end if; + end if; + when RET_SN => + done <= '1'; + ret <= OK; + cc_seq_nr <= SN; + + stage_next <= IDLE; + when RET_RTPS => + done <= '1'; + ret <= ret_code; + + stage_next <= IDLE; + end case; + end process; + + sync_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + stage <= IDLE; + cnt <= 0; + ret_code <= ERROR; + data_available_sig <= '1'; + else + stage <= stage_next; + cnt <= cnt_next; + ret_code <= ret_code_next; + data_available_sig <= data_available_sig_next; + end if; + end if; + end process; + +end architecture; diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index 9b4db23..a12ef16 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -44,13 +44,8 @@ package rtps_config_package is constant EMO_ENDPOINT_MATCH : std_logic_vector(EMO_WIDTH-1 downto 0) := x"55000000"; constant EMO_ENDPOINT_UNMATCH : std_logic_vector(EMO_WIDTH-1 downto 0) := x"55000001"; constant EMO_PARTICIPANT_UNMATCH : std_logic_vector(EMO_WIDTH-1 downto 0) := x"55000002"; - constant EMO_LIVELINESS_UPDATE : std_logic_vector(EMO_WIDTH-1 downto 0) := x"55000003"; + constant EMO_LIVELINESS_UPDATE : std_logic_vector(EMO_WIDTH-1 downto 0) := x"55000003"; - type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE, GET_CACHE_CHANGE, ACK_CACHE_CHANGE, NACK_CACHE_CHANGE, REMOVE_CACHE_CHANGE, REMOVE_WRITER, GET_MIN_SN, GET_MAX_SN); - type KEY_HOLDER_OPCODE_TYPE is (NOP, PUSH_DATA, PUSH_SERIALIZED_KEY, READ_KEY_HASH, READ_SERIALIZED_KEY); - type HISTORY_CACHE_RESPONSE_TYPE is (OK, REJECTED, INVALID, ERROR); - type DDS_WRITER_OPCODE_TYPE is (NOP, REGISTER_INSTANCE, WRITE, DISPOSE, UNREGISTER_INSTANCE, LOOKUP_INSTANCE, WAIT_FOR_ACKNOWLEDGEMENTS, GET_OFFERED_DEADLINE_MISSED_STATUS, ASSERT_LIVELINESS, GET_LIVELINESS_LOST_STATUS); - type DDS_READER_OPCODE_TYPE is (NOP, READ, TAKE, READ_NEXT_SAMPLE, TAKE_NEXT_SAMPLE, READ_INSTANCE, TAKE_INSTANCE, READ_NEXT_INSTANCE, TAKE_NEXT_INSTANCE, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS); -- Sample Status Info Flags constant SSI_DISPOSED_FLAG : natural := STATUS_INFO_DISPOSED_FLAG; @@ -91,7 +86,7 @@ package rtps_config_package is -- Marks the readers with AUTOMATIC Liveliness Qos constant AUTOMATIC_LIVELINESS_READERS : std_logic_vector(0 to NUM_ENDPOINTS-1); --Deferred to package body -- Marks the readers with MANUAL BY PARTICIPANT Liveliness Qos - constant MANUAL_BY_PARTICIPANT_LIVELINESS_READERS : std_logic_vector(0 to NUM_ENDPOINTS-1); --Deferred to package body + constant MANUAL_BY_PARTICIPANT_LIVELINESS_READERS : std_logic_vector(0 to NUM_ENDPOINTS-1); --Deferred to package body type WORD_ARRAY_TYPE is array (natural range <>) of std_logic_vector(WORD_WIDTH-1 downto 0); type OUTPUT_DATA_TYPE is record @@ -99,6 +94,7 @@ package rtps_config_package is data : WORD_ARRAY_TYPE(0 to 16371); length : natural; end record; + constant READER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body constant WRITER_ENDPOINT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body constant LOCAL_PARTICIPANT_DATA : OUTPUT_DATA_TYPE; --Deferred to package body diff --git a/src/rtps_package.vhd b/src/rtps_package.vhd index 6b51ff4..c011c8c 100644 --- a/src/rtps_package.vhd +++ b/src/rtps_package.vhd @@ -476,6 +476,12 @@ package rtps_package is constant EMPTY_USER_STRING : USER_STRING_TYPE := (others => NUL); constant DEFAULT_USER_DOMAIN_TAG : USER_STRING_TYPE := EMPTY_USER_STRING; + type HISTORY_CACHE_OPCODE_TYPE is (NOP, ADD_CACHE_CHANGE, GET_CACHE_CHANGE, ACK_CACHE_CHANGE, NACK_CACHE_CHANGE, REMOVE_CACHE_CHANGE, REMOVE_WRITER, GET_MIN_SN, GET_MAX_SN); + type KEY_HOLDER_OPCODE_TYPE is (NOP, PUSH_DATA, PUSH_SERIALIZED_KEY, READ_KEY_HASH, READ_SERIALIZED_KEY); + type HISTORY_CACHE_RESPONSE_TYPE is (OK, REJECTED, INVALID, ERROR); + type DDS_WRITER_OPCODE_TYPE is (NOP, REGISTER_INSTANCE, WRITE, DISPOSE, UNREGISTER_INSTANCE, LOOKUP_INSTANCE, WAIT_FOR_ACKNOWLEDGEMENTS, GET_OFFERED_DEADLINE_MISSED_STATUS, ASSERT_LIVELINESS, GET_LIVELINESS_LOST_STATUS); + type DDS_READER_OPCODE_TYPE is (NOP, READ, TAKE, READ_NEXT_SAMPLE, TAKE_NEXT_SAMPLE, READ_INSTANCE, TAKE_INSTANCE, READ_NEXT_INSTANCE, TAKE_NEXT_INSTANCE, GET_SAMPLE_REJECTED_STATUS, GET_REQUESTED_DEADLINE_MISSED_STATUS); + function gen_user_string(input : string) return string; function string_len (str : string) return natural; function concat(A,B : string) return USER_STRING_TYPE;