Implement ROS glue logic & ROS discovery data
All the necessary "glue" logic to convert ROS Data to a form that the DDS/RTPS back-end can use is implemented in packages. The ROS Node discovery information is statically generated in packages (similar to the RTPS Participant Data), and a special dds writer is implemented (ros_static_discovery_writer) that has this static data as its only payload sample. Some definitions are moved out of rtps_config_package to prevent circular package dependency.
This commit is contained in:
parent
2d3c5cf896
commit
b5741dc9ae
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
21
src/ros2/ROS_IDL.txt
Normal file
21
src/ros2/ROS_IDL.txt
Normal file
@ -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 <NAME> 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 <SERVICENAME>_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 <SERVICENAME>_package calculates both a maximum request and response message size, named
|
||||
MAX_<SERVICENAME>_RQ_SIZE and MAX_<SERVICENAME>_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.
|
||||
78
src/ros2/TEMPLATE_ros_config.vhd
Normal file
78
src/ros2/TEMPLATE_ros_config.vhd
Normal file
@ -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;
|
||||
195
src/ros2/dds_user_config.vhd
Normal file
195
src/ros2/dds_user_config.vhd
Normal file
@ -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;
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
1
src/ros2/rmw_dds_common/Gid.msg
Normal file
1
src/ros2/rmw_dds_common/Gid.msg
Normal file
@ -0,0 +1 @@
|
||||
char[24] data
|
||||
4
src/ros2/rmw_dds_common/NodeEntitiesInfo.msg
Normal file
4
src/ros2/rmw_dds_common/NodeEntitiesInfo.msg
Normal file
@ -0,0 +1,4 @@
|
||||
string<=256 node_namespace
|
||||
string<=256 node_name
|
||||
Gid[] reader_gid_seq
|
||||
Gid[] writer_gid_seq
|
||||
2
src/ros2/rmw_dds_common/ParticipantEntitiesInfo.msg
Normal file
2
src/ros2/rmw_dds_common/ParticipantEntitiesInfo.msg
Normal file
@ -0,0 +1,2 @@
|
||||
Gid gid
|
||||
NodeEntitiesInfo[] node_entities_info_seq
|
||||
141
src/ros2/ros_config_package.vhd
Normal file
141
src/ros2/ros_config_package.vhd
Normal file
@ -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;
|
||||
@ -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;
|
||||
|
||||
159
src/ros2/ros_static_discovery_writer.vhd
Normal file
159
src/ros2/ros_static_discovery_writer.vhd
Normal file
@ -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;
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user