diff --git a/sim/L1_AddTwoInts_service_test1.do b/sim/L1_AddTwoInts_service_test1.do new file mode 100644 index 0000000..6f14a2d --- /dev/null +++ b/sim/L1_AddTwoInts_service_test1.do @@ -0,0 +1,105 @@ +onerror {resume} +radix define ROS_RETCODE { + "10#0#" "ROS_RET_OK", + "10#1#" "ROS_RET_ERROR", + "10#2#" "ROS_RET_TIMEOUT", + "10#3#" "ROS_RET_UNSUPPORTED", + -default unsigned +} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider SYSTEM +add wave -noupdate /l1_addtwoints_service_test1/clk +add wave -noupdate /l1_addtwoints_service_test1/reset +add wave -noupdate -divider CLIENT +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/start_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/ack_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/get_data_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/done_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/valid_in_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/ready_in_r +add wave -noupdate -group CPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_c/data_in_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/last_word_in_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/si_valid_data_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/si_valid_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/si_ack_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/eoc_r +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/start_w +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/ack_w +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/done_w +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/valid_out_w +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/ready_out_w +add wave -noupdate -group CPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_c/data_out_w +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/last_word_out_w +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/start_user +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/ack_user +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/opcode_user +add wave -noupdate -group CPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_c/service_info_user +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/sequence_id +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/taken_user +add wave -noupdate -group CPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_c/a +add wave -noupdate -group CPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_c/b +add wave -noupdate -group CPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_c/sum +add wave -noupdate -group CPORTS /l1_addtwoints_service_test1/uut_c/done_user +add wave -noupdate -group CPORTS -radix ROS_RETCODE /l1_addtwoints_service_test1/uut_c/return_code_user +add wave -noupdate /l1_addtwoints_service_test1/uut_c/stage +add wave -noupdate /l1_addtwoints_service_test1/uut_c/encode_stage +add wave -noupdate /l1_addtwoints_service_test1/uut_c/decode_stage +add wave -noupdate /l1_addtwoints_service_test1/uut_c/return_stage +add wave -noupdate /l1_addtwoints_service_test1/uut_c/cnt +add wave -noupdate /l1_addtwoints_service_test1/uut_c/decode_error_latch +add wave -noupdate -divider SERVER +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/start_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/ack_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/get_data_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/done_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/valid_in_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/ready_in_r +add wave -noupdate -group SPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_s/data_in_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/last_word_in_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/si_valid_data_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/si_valid_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/si_ack_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/eoc_r +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/start_w +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/ack_w +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/done_w +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/valid_out_w +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/ready_out_w +add wave -noupdate -group SPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_s/data_out_w +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/last_word_out_w +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/start_user +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/ack_user +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/opcode_user +add wave -noupdate -group SPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_s/service_info_user +add wave -noupdate -group SPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_s/request_id_user +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/taken_user +add wave -noupdate -group SPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_s/a +add wave -noupdate -group SPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_s/b +add wave -noupdate -group SPORTS -radix hexadecimal /l1_addtwoints_service_test1/uut_s/sum +add wave -noupdate -group SPORTS /l1_addtwoints_service_test1/uut_s/done_user +add wave -noupdate -group SPORTS -radix ROS_RETCODE /l1_addtwoints_service_test1/uut_s/return_code_user +add wave -noupdate /l1_addtwoints_service_test1/uut_s/stage +add wave -noupdate /l1_addtwoints_service_test1/uut_s/encode_stage +add wave -noupdate /l1_addtwoints_service_test1/uut_s/decode_stage +add wave -noupdate /l1_addtwoints_service_test1/uut_s/return_stage +add wave -noupdate /l1_addtwoints_service_test1/uut_s/cnt +add wave -noupdate /l1_addtwoints_service_test1/uut_s/decode_error_latch +add wave -noupdate -divider MISC +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {325000 ps} 0} +quietly wave cursor active 1 +configure wave -namecolwidth 150 +configure wave -valuecolwidth 100 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +configure wave -timelineunits ns +update +WaveRestoreZoom {0 ps} {1024 ns} diff --git a/sim/modelsim.ini b/sim/modelsim.ini index 57093a8..6b493ce 100644 --- a/sim/modelsim.ini +++ b/sim/modelsim.ini @@ -23,6 +23,7 @@ Testbench_Lib3 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Test Testbench_Lib4 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib4.lib Testbench_Lib5 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib5.lib Testbench_Lib1 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_Lib1.lib +Testbench_ROS_Lib1 = W:/HDL-SIM/OSVVM-Scripts/../sim/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib1.lib [vcom] ; VHDL93 variable selects language version as the default. ; Default is VHDL-2002. diff --git a/src/ros2/Service_ref.txt b/src/ros2/Service_ref.txt new file mode 100644 index 0000000..d9d6884 --- /dev/null +++ b/src/ros2/Service_ref.txt @@ -0,0 +1,32 @@ + 31............24..............16..............8...............0 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Representation_id | Representation_options | + 00 01 (=CDR_LE) 00 00 +| request_id.writer_guid | +| | + 55 05 54 47 12 ee 90 0d +| request_id.sn | +| | + 01 00 00 00 00 00 00 00 +| AddTwoInts.a | +| | + 02 00 00 00 00 00 00 00 +| AddTwoInts.b | +| | + 03 00 00 00 00 00 00 00 ++---------------------------------------------------------------+ + + 31............24..............16..............8...............0 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Representation_id | Representation_options | + 00 01 (=CDR_LE) 00 00 +| request_id.writer_guid | +| | + 55 05 54 47 12 ee 90 0d +| request_id.sn | +| | + 01 00 00 00 00 00 00 00 +| AddTwoInts.sum | +| | + 05 00 00 00 00 00 00 00 ++---------------------------------------------------------------+ \ No newline at end of file diff --git a/src/ros2/Tests/Level_1/L1_AddTwoInts_srv_test1.vhd b/src/ros2/Tests/Level_1/L1_AddTwoInts_srv_test1.vhd new file mode 100644 index 0000000..61e929a --- /dev/null +++ b/src/ros2/Tests/Level_1/L1_AddTwoInts_srv_test1.vhd @@ -0,0 +1,428 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.ros_package.all; +use work.rtps_test_package.all; + +-- This testbench tests the General Behavour of the AddTwoInts Service. +-- More specifically following tests are done: +-- * Test Unssuported Opcode Operations +-- * Test RETCODE_NO_DATA response from DDS Reader +-- * Test RETCODE_ERROR response from DDS Reader +-- * Test RETCODE_ERROR response from DDS Writer +-- * Test Sample with No Valid response from DDS Reader +-- * Test Big Endian Encoding/Decoding of AddTwoInts Service Messages + +entity L1_AddTwoInts_srv_test1 is +end entity; + +architecture testbench of L1_AddTwoInts_srv_test1 is + + signal clk, reset : std_logic := '0'; + signal valid_rq, valid_rr, ready_rq, ready_rr, last_word_rq, last_word_rr : std_logic := '0'; + signal data_rq, data_rr : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal start_c, start_s, ack_c, ack_s, taken_c, taken_s, done_c, done_s : std_logic := '0'; + signal opcode_c, opcode_s : ROS_SERVICE_OPCODE_TYPE := NOP; + signal return_code_c, return_code_s : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) := (others => '0'); + signal a_c, a_s, b_c, b_s, sum_c, sum_s : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0) := (others => '0'); + signal service_info_c, service_info_s : SERVICE_INFO_TYPE := EMPTY_SERVICE_INFO; + signal sequence_id_c : std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0) := (others => '0'); + signal request_id_s : REQUEST_ID_TYPE := EMPTY_REQUEST_ID; + signal start_sr, start_cr, si_valid_data_cr, si_valid_data_sr : std_logic := '0'; + signal return_code_cr, return_code_cw, return_code_sr, return_code_sw : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := (others => '0'); + signal ready_sw, ready_cw, last_word_out_cw, last_word_out_sw, selector : std_logic := '0'; +begin + + uut_c : entity work.AddTwoInts_srv_client(arch) + port map ( + clk => clk, + reset => reset, + start_r => start_cr,-- + ack_r => '1',-- + opcode_r => open, + instance_state_r => open, + view_state_r => open, + sample_state_r => open, + instance_handle_r => open, + max_samples_r => open, + get_data_r => open,-- + done_r => '1',-- + return_code_r => return_code_cr,-- + valid_in_r => valid_rr,-- + ready_in_r => ready_rr,-- + data_in_r => data_rr,-- + last_word_in_r => last_word_rr,-- + si_sample_state_r => ANY_SAMPLE_STATE, + si_view_state_r => ANY_VIEW_STATE, + si_instance_state_r => ANY_INSTANCE_STATE, + si_source_timestamp_r => TIME_INVALID, + si_instance_handle_r => HANDLE_NIL, + si_publication_handle_r => HANDLE_NIL, + si_disposed_generation_count_r => (others => '0'), + si_no_writers_generation_count_r => (others => '0'), + si_sample_rank_r => (others => '0'), + si_generation_rank_r => (others => '0'), + si_absolute_generation_rank_r => (others => '0'), + si_valid_data_r => si_valid_data_cr,-- + si_valid_r => '1',-- + si_ack_r => open,-- + eoc_r => '1',-- + status_r => (others => '0'), + start_w => open,-- + ack_w => '1',-- + opcode_w => open, + instance_handle_out_w => open, + source_ts_w => open, + max_wait_w => open, + done_w => '1',-- + return_code_w => return_code_cw, + instance_handle_in_w => HANDLE_NIL, + valid_out_w => valid_rq,-- + ready_out_w => ready_cw,--ready_rq,-- + data_out_w => data_rq,-- + last_word_out_w => last_word_out_cw,--last_word_rq,-- + valid_in_w => '0', + ready_in_w => open, + data_in_w => (others => '0'), + last_word_in_w => '0', + status_w => (others => '0'), + start_user => start_c,-- + ack_user => ack_c,-- + opcode_user => opcode_c,-- + service_info_user => service_info_c,-- + sequence_id_user => sequence_id_c,-- + taken_user => taken_c,-- + data_available_user => open,-- + a => a_c,-- + b => b_c,-- + sum => sum_c,-- + done_user => done_c,-- + return_code_user => return_code_c -- + ); + + uut_s : entity work.AddTwoInts_srv_server(arch) + port map ( + clk => clk, + reset => reset, + start_r => start_sr,-- + ack_r => '1',-- + opcode_r => open, + instance_state_r => open, + view_state_r => open, + sample_state_r => open, + instance_handle_r => open, + max_samples_r => open, + get_data_r => open,-- + done_r => '1',-- + return_code_r => return_code_sr,-- + valid_in_r => valid_rq,-- + ready_in_r => ready_rq,-- + data_in_r => data_rq,-- + last_word_in_r => last_word_rq,-- + si_sample_state_r => ANY_SAMPLE_STATE, + si_view_state_r => ANY_VIEW_STATE, + si_instance_state_r => ANY_INSTANCE_STATE, + si_source_timestamp_r => TIME_INVALID, + si_instance_handle_r => HANDLE_NIL, + si_publication_handle_r => HANDLE_NIL, + si_disposed_generation_count_r => (others => '0'), + si_no_writers_generation_count_r => (others => '0'), + si_sample_rank_r => (others => '0'), + si_generation_rank_r => (others => '0'), + si_absolute_generation_rank_r => (others => '0'), + si_valid_data_r => si_valid_data_sr,-- + si_valid_r => '1',-- + si_ack_r => open,-- + eoc_r => '1',-- + status_r => (others => '0'), + start_w => open,-- + ack_w => '1',-- + opcode_w => open, + instance_handle_out_w => open, + source_ts_w => open, + max_wait_w => open, + done_w => '1',-- + return_code_w => return_code_sw,-- + instance_handle_in_w => HANDLE_NIL, + valid_out_w => valid_rr,-- + ready_out_w => ready_sw,--ready_rr,-- + data_out_w => data_rr,-- + last_word_out_w => last_word_out_sw,--last_word_rr,-- + valid_in_w => '0', + ready_in_w => open, + data_in_w => (others => '0'), + last_word_in_w => '0', + status_w => (others => '0'), + start_user => start_s,-- + ack_user => ack_s,-- + opcode_user => opcode_s,-- + service_info_user => service_info_s,-- + request_id_user => request_id_s,-- + taken_user => taken_s,-- + data_available_user => open,-- + a => a_s,-- + b => b_s,-- + sum => sum_s,-- + done_user => done_s,-- + return_code_user => return_code_s -- + ); + + process (all) + begin + if (selector = '1') then + ready_cw <= '1'; + ready_sw <= '1'; + last_word_rq <= '0'; + last_word_rr <= '0'; + else + ready_cw <= ready_rq; + ready_sw <= ready_rr; + last_word_rq <= last_word_out_cw; + last_word_rr <= last_word_out_sw; + end if; + end process; + + stimulus_prc : process + variable RV : RandomPType; + variable A, B, SUM, RET : AlertLogIDType; + + procedure wait_on_sig(signal sig : std_logic) is + begin + if (sig /= '1') then + wait on sig until sig = '1'; + end if; + end procedure; + begin + + SetAlertLogName("AddTwoInts Service - Level 1 - (Big Endian) - General"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + A := GetAlertLogID("A", ALERTLOG_BASE_ID); + B := GetAlertLogID("B", ALERTLOG_BASE_ID); + SUM := GetAlertLogID("SUM", ALERTLOG_BASE_ID); + + Log("Initial Reset", INFO); + selector <= '1'; + return_code_cr <= RETCODE_OK; + return_code_cw <= RETCODE_OK; + return_code_sr <= RETCODE_OK; + return_code_sw <= RETCODE_OK; + si_valid_data_cr <= '0'; + si_valid_data_sr <= '0'; + start_c <= '0'; + start_s <= '0'; + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + + Log("CLIENT: Test Unsupported Opcode", INFO); + start_c <= '1'; + opcode_c <= TAKE_REQUEST; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_UNSUPPORTED, "Unexpected Client Response", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test Unsupported Opcode", INFO); + start_s <= '1'; + opcode_s <= TAKE_RESPONSE; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_UNSUPPORTED, "Unexpected Server Response", FAILURE); + wait until rising_edge(clk); + + Log("CLIENT: Test No Data", INFO); + return_code_cr <= RETCODE_NO_DATA; + start_c <= '1'; + opcode_c <= TAKE_RESPONSE; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_OK, "Unexpected Client Response", FAILURE); + AlertIf(taken_c /= '0', "Client taken is unexpectedly set", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test No Data", INFO); + return_code_sr <= RETCODE_NO_DATA; + start_s <= '1'; + opcode_s <= TAKE_REQUEST; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_OK, "Unexpected Server Response", FAILURE); + AlertIf(taken_s /= '0', "Server taken is unexpectedly set", FAILURE); + wait until rising_edge(clk); + + Log("CLIENT: Test Reader Error", INFO); + return_code_cr <= RETCODE_ERROR; + start_c <= '1'; + opcode_c <= TAKE_RESPONSE; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_ERROR, "Unexpected Client Response", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test Reader Error", INFO); + return_code_sr <= RETCODE_ERROR; + start_s <= '1'; + opcode_s <= TAKE_REQUEST; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_ERROR, "Unexpected Server Response", FAILURE); + wait until rising_edge(clk); + + Log("CLIENT: Test Writer Error", INFO); + return_code_cw <= RETCODE_ERROR; + start_c <= '1'; + opcode_c <= SEND_REQUEST; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_ERROR, "Unexpected Client Response", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test Writer Error", INFO); + return_code_sw <= RETCODE_ERROR; + start_s <= '1'; + opcode_s <= SEND_RESPONSE; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_ERROR, "Unexpected Server Response", FAILURE); + wait until rising_edge(clk); + + return_code_cr <= RETCODE_OK; + return_code_cw <= RETCODE_OK; + return_code_sr <= RETCODE_OK; + return_code_sw <= RETCODE_OK; + selector <= '0'; + + Log("Setting Request", INFO); + -- Static + a_c <= RV.RandSlv(a_c'length); + b_c <= RV.RandSlv(b_c'length); + wait for 0 ns; + + Log("CLIENT: Send Request", INFO); + start_c <= '1'; + opcode_c <= SEND_REQUEST; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + + Log("SERVER: Take Request", INFO); + start_s <= '1'; + opcode_s <= TAKE_REQUEST; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + + -- TEST NO VALID DATA + wait_on_sig(start_sr); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait_on_sig(start_sr); + si_valid_data_sr <= '1'; + + Log("Wait for Request on Server", INFO); + wait_on_sig(done_s); + wait until rising_edge(clk); + + AlertIf(return_code_s /= ROS_RET_OK, "Server did Return ERROR", FAILURE); + AlertIf(taken_s /= '1', "Server did not take Request", FAILURE); + + Log("Compare Request", INFO); + AffirmIfEqual(A, a_s, a_c); + AffirmIfEqual(B, b_s, b_c); + + Log("Setting Response", INFO); + -- Static + sum_s <= RV.RandSlv(sum_s'length); + wait for 0 ns; + + Log("SERVER: Send Response", INFO); + start_s <= '1'; + opcode_s <= SEND_RESPONSE; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + + Log("CLIENT: Take Response", INFO); + start_c <= '1'; + opcode_c <= TAKE_RESPONSE; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + + -- TEST NO VALID DATA + wait_on_sig(start_cr); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait_on_sig(start_cr); + si_valid_data_cr <= '1'; + + Log("Wait for Response on Client", INFO); + wait_on_sig(done_c); + wait until rising_edge(clk); + + AlertIf(return_code_c /= ROS_RET_OK, "Client did Return ERROR", FAILURE); + AlertIf(taken_c /= '1', "Client did not take Response", FAILURE); + + Log("Compare Response", INFO); + AffirmIfEqual(SUM, sum_c, sum_s); + + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for TEST_CLOCK_PERIOD/2; + clk <= '1'; + wait for TEST_CLOCK_PERIOD/2; + end process; + + watchdog : process + begin + wait for 1 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/ros2/Tests/Level_1/L1_AddTwoInts_srv_test2.vhd b/src/ros2/Tests/Level_1/L1_AddTwoInts_srv_test2.vhd new file mode 100644 index 0000000..e4c2244 --- /dev/null +++ b/src/ros2/Tests/Level_1/L1_AddTwoInts_srv_test2.vhd @@ -0,0 +1,434 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.ros_package.all; +use work.rtps_test_package.all; + +-- This testbench tests the General Behavour of the AddTwoInts Service. +-- More specifically following tests are done: +-- * Test Unssuported Opcode Operations +-- * Test RETCODE_NO_DATA response from DDS Reader +-- * Test RETCODE_ERROR response from DDS Reader +-- * Test RETCODE_ERROR response from DDS Writer +-- * Test Sample with No Valid response from DDS Reader +-- * Test Little Endian Encoding/Decoding of AddTwoInts Service Messages + +entity L1_AddTwoInts_srv_test2 is +end entity; + +architecture testbench of L1_AddTwoInts_srv_test2 is + + signal clk, reset : std_logic := '0'; + signal valid_rq, valid_rr, ready_rq, ready_rr, last_word_rq, last_word_rr : std_logic := '0'; + signal data_rq, data_rr : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal start_c, start_s, ack_c, ack_s, taken_c, taken_s, done_c, done_s : std_logic := '0'; + signal opcode_c, opcode_s : ROS_SERVICE_OPCODE_TYPE := NOP; + signal return_code_c, return_code_s : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) := (others => '0'); + signal a_c, a_s, b_c, b_s, sum_c, sum_s : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0) := (others => '0'); + signal service_info_c, service_info_s : SERVICE_INFO_TYPE := EMPTY_SERVICE_INFO; + signal sequence_id_c : std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0) := (others => '0'); + signal request_id_s : REQUEST_ID_TYPE := EMPTY_REQUEST_ID; + signal start_sr, start_cr, si_valid_data_cr, si_valid_data_sr : std_logic := '0'; + signal return_code_cr, return_code_cw, return_code_sr, return_code_sw : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0) := (others => '0'); + signal ready_sw, ready_cw, last_word_out_cw, last_word_out_sw, selector : std_logic := '0'; +begin + + uut_c : entity work.AddTwoInts_srv_client(arch) + generic map ( + LITTLE_ENDIAN => '1' + ) + port map ( + clk => clk, + reset => reset, + start_r => start_cr,-- + ack_r => '1',-- + opcode_r => open, + instance_state_r => open, + view_state_r => open, + sample_state_r => open, + instance_handle_r => open, + max_samples_r => open, + get_data_r => open,-- + done_r => '1',-- + return_code_r => return_code_cr,-- + valid_in_r => valid_rr,-- + ready_in_r => ready_rr,-- + data_in_r => data_rr,-- + last_word_in_r => last_word_rr,-- + si_sample_state_r => ANY_SAMPLE_STATE, + si_view_state_r => ANY_VIEW_STATE, + si_instance_state_r => ANY_INSTANCE_STATE, + si_source_timestamp_r => TIME_INVALID, + si_instance_handle_r => HANDLE_NIL, + si_publication_handle_r => HANDLE_NIL, + si_disposed_generation_count_r => (others => '0'), + si_no_writers_generation_count_r => (others => '0'), + si_sample_rank_r => (others => '0'), + si_generation_rank_r => (others => '0'), + si_absolute_generation_rank_r => (others => '0'), + si_valid_data_r => si_valid_data_cr,-- + si_valid_r => '1',-- + si_ack_r => open,-- + eoc_r => '1',-- + status_r => (others => '0'), + start_w => open,-- + ack_w => '1',-- + opcode_w => open, + instance_handle_out_w => open, + source_ts_w => open, + max_wait_w => open, + done_w => '1',-- + return_code_w => return_code_cw, + instance_handle_in_w => HANDLE_NIL, + valid_out_w => valid_rq,-- + ready_out_w => ready_cw,--ready_rq,-- + data_out_w => data_rq,-- + last_word_out_w => last_word_out_cw,--last_word_rq,-- + valid_in_w => '0', + ready_in_w => open, + data_in_w => (others => '0'), + last_word_in_w => '0', + status_w => (others => '0'), + start_user => start_c,-- + ack_user => ack_c,-- + opcode_user => opcode_c,-- + service_info_user => service_info_c,-- + sequence_id_user => sequence_id_c,-- + taken_user => taken_c,-- + data_available_user => open,-- + a => a_c,-- + b => b_c,-- + sum => sum_c,-- + done_user => done_c,-- + return_code_user => return_code_c -- + ); + + uut_s : entity work.AddTwoInts_srv_server(arch) + generic map ( + LITTLE_ENDIAN => '1' + ) + port map ( + clk => clk, + reset => reset, + start_r => start_sr,-- + ack_r => '1',-- + opcode_r => open, + instance_state_r => open, + view_state_r => open, + sample_state_r => open, + instance_handle_r => open, + max_samples_r => open, + get_data_r => open,-- + done_r => '1',-- + return_code_r => return_code_sr,-- + valid_in_r => valid_rq,-- + ready_in_r => ready_rq,-- + data_in_r => data_rq,-- + last_word_in_r => last_word_rq,-- + si_sample_state_r => ANY_SAMPLE_STATE, + si_view_state_r => ANY_VIEW_STATE, + si_instance_state_r => ANY_INSTANCE_STATE, + si_source_timestamp_r => TIME_INVALID, + si_instance_handle_r => HANDLE_NIL, + si_publication_handle_r => HANDLE_NIL, + si_disposed_generation_count_r => (others => '0'), + si_no_writers_generation_count_r => (others => '0'), + si_sample_rank_r => (others => '0'), + si_generation_rank_r => (others => '0'), + si_absolute_generation_rank_r => (others => '0'), + si_valid_data_r => si_valid_data_sr,-- + si_valid_r => '1',-- + si_ack_r => open,-- + eoc_r => '1',-- + status_r => (others => '0'), + start_w => open,-- + ack_w => '1',-- + opcode_w => open, + instance_handle_out_w => open, + source_ts_w => open, + max_wait_w => open, + done_w => '1',-- + return_code_w => return_code_sw,-- + instance_handle_in_w => HANDLE_NIL, + valid_out_w => valid_rr,-- + ready_out_w => ready_sw,--ready_rr,-- + data_out_w => data_rr,-- + last_word_out_w => last_word_out_sw,--last_word_rr,-- + valid_in_w => '0', + ready_in_w => open, + data_in_w => (others => '0'), + last_word_in_w => '0', + status_w => (others => '0'), + start_user => start_s,-- + ack_user => ack_s,-- + opcode_user => opcode_s,-- + service_info_user => service_info_s,-- + request_id_user => request_id_s,-- + taken_user => taken_s,-- + data_available_user => open,-- + a => a_s,-- + b => b_s,-- + sum => sum_s,-- + done_user => done_s,-- + return_code_user => return_code_s -- + ); + + process (all) + begin + if (selector = '1') then + ready_cw <= '1'; + ready_sw <= '1'; + last_word_rq <= '0'; + last_word_rr <= '0'; + else + ready_cw <= ready_rq; + ready_sw <= ready_rr; + last_word_rq <= last_word_out_cw; + last_word_rr <= last_word_out_sw; + end if; + end process; + + stimulus_prc : process + variable RV : RandomPType; + variable A, B, SUM, RET : AlertLogIDType; + + procedure wait_on_sig(signal sig : std_logic) is + begin + if (sig /= '1') then + wait on sig until sig = '1'; + end if; + end procedure; + begin + + SetAlertLogName("AddTwoInts Service - Level 1 - (Little Endian) - General"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + A := GetAlertLogID("A", ALERTLOG_BASE_ID); + B := GetAlertLogID("B", ALERTLOG_BASE_ID); + SUM := GetAlertLogID("SUM", ALERTLOG_BASE_ID); + + Log("Initial Reset", INFO); + selector <= '1'; + return_code_cr <= RETCODE_OK; + return_code_cw <= RETCODE_OK; + return_code_sr <= RETCODE_OK; + return_code_sw <= RETCODE_OK; + si_valid_data_cr <= '0'; + si_valid_data_sr <= '0'; + start_c <= '0'; + start_s <= '0'; + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + + Log("CLIENT: Test Unsupported Opcode", INFO); + start_c <= '1'; + opcode_c <= TAKE_REQUEST; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_UNSUPPORTED, "Unexpected Client Response", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test Unsupported Opcode", INFO); + start_s <= '1'; + opcode_s <= TAKE_RESPONSE; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_UNSUPPORTED, "Unexpected Server Response", FAILURE); + wait until rising_edge(clk); + + Log("CLIENT: Test No Data", INFO); + return_code_cr <= RETCODE_NO_DATA; + start_c <= '1'; + opcode_c <= TAKE_RESPONSE; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_OK, "Unexpected Client Response", FAILURE); + AlertIf(taken_c /= '0', "Client taken is unexpectedly set", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test No Data", INFO); + return_code_sr <= RETCODE_NO_DATA; + start_s <= '1'; + opcode_s <= TAKE_REQUEST; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_OK, "Unexpected Server Response", FAILURE); + AlertIf(taken_s /= '0', "Server taken is unexpectedly set", FAILURE); + wait until rising_edge(clk); + + Log("CLIENT: Test Reader Error", INFO); + return_code_cr <= RETCODE_ERROR; + start_c <= '1'; + opcode_c <= TAKE_RESPONSE; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_ERROR, "Unexpected Client Response", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test Reader Error", INFO); + return_code_sr <= RETCODE_ERROR; + start_s <= '1'; + opcode_s <= TAKE_REQUEST; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_ERROR, "Unexpected Server Response", FAILURE); + wait until rising_edge(clk); + + Log("CLIENT: Test Writer Error", INFO); + return_code_cw <= RETCODE_ERROR; + start_c <= '1'; + opcode_c <= SEND_REQUEST; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + wait_on_sig(done_c); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_c /= ROS_RET_ERROR, "Unexpected Client Response", FAILURE); + wait until rising_edge(clk); + + Log("SERVER: Test Writer Error", INFO); + return_code_sw <= RETCODE_ERROR; + start_s <= '1'; + opcode_s <= SEND_RESPONSE; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + wait_on_sig(done_s); + wait for 1 ps; -- Make sure all signals stable + AlertIf(return_code_s /= ROS_RET_ERROR, "Unexpected Server Response", FAILURE); + wait until rising_edge(clk); + + return_code_cr <= RETCODE_OK; + return_code_cw <= RETCODE_OK; + return_code_sr <= RETCODE_OK; + return_code_sw <= RETCODE_OK; + selector <= '0'; + + Log("Setting Request", INFO); + -- Static + a_c <= RV.RandSlv(a_c'length); + b_c <= RV.RandSlv(b_c'length); + wait for 0 ns; + + Log("CLIENT: Send Request", INFO); + start_c <= '1'; + opcode_c <= SEND_REQUEST; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + + Log("SERVER: Take Request", INFO); + start_s <= '1'; + opcode_s <= TAKE_REQUEST; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + + -- TEST NO VALID DATA + wait_on_sig(start_sr); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait_on_sig(start_sr); + si_valid_data_sr <= '1'; + + Log("Wait for Request on Server", INFO); + wait_on_sig(done_s); + wait until rising_edge(clk); + + AlertIf(return_code_s /= ROS_RET_OK, "Server did Return ERROR", FAILURE); + AlertIf(taken_s /= '1', "Server did not take Request", FAILURE); + + Log("Compare Request", INFO); + AffirmIfEqual(A, a_s, a_c); + AffirmIfEqual(B, b_s, b_c); + + Log("Setting Response", INFO); + -- Static + sum_s <= RV.RandSlv(sum_s'length); + wait for 0 ns; + + Log("SERVER: Send Response", INFO); + start_s <= '1'; + opcode_s <= SEND_RESPONSE; + wait_on_sig(ack_s); + wait until rising_edge(clk); + start_s <= '0'; + + Log("CLIENT: Take Response", INFO); + start_c <= '1'; + opcode_c <= TAKE_RESPONSE; + wait_on_sig(ack_c); + wait until rising_edge(clk); + start_c <= '0'; + + -- TEST NO VALID DATA + wait_on_sig(start_cr); + wait until rising_edge(clk); + wait until rising_edge(clk); + wait_on_sig(start_cr); + si_valid_data_cr <= '1'; + + Log("Wait for Response on Client", INFO); + wait_on_sig(done_c); + wait until rising_edge(clk); + + AlertIf(return_code_c /= ROS_RET_OK, "Client did Return ERROR", FAILURE); + AlertIf(taken_c /= '1', "Client did not take Response", FAILURE); + + Log("Compare Response", INFO); + AffirmIfEqual(SUM, sum_c, sum_s); + + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for TEST_CLOCK_PERIOD/2; + clk <= '1'; + wait for TEST_CLOCK_PERIOD/2; + end process; + + watchdog : process + begin + wait for 1 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/ros2/Tests/ros_testbench.pro b/src/ros2/Tests/ros_testbench.pro new file mode 100644 index 0000000..ccde246 --- /dev/null +++ b/src/ros2/Tests/ros_testbench.pro @@ -0,0 +1,19 @@ +# Compile OSVVM Library +include ../OSVVM/osvvm.pro + +# Compile +library Testbench_ROS_Lib1 +analyze ../../math_pkg.vhd +analyze ../../rtps_package.vhd +analyze ../../TEMPLATE_user_config.vhd +analyze ../../rtps_config_package.vhd +analyze ../../rtps_test_package.vhd +analyze ../ros_package.vhd +analyze ../example_interfaces/AddTwoInts_srv_client.vhd +analyze ../example_interfaces/AddTwoInts_srv_server.vhd +analyze Level_1/L1_AddTwoInts_srv_test1.vhd +analyze Level_1/L1_AddTwoInts_srv_test2.vhd + +# Simulate +simulate L1_AddTwoInts_srv_test1 +simulate L1_AddTwoInts_srv_test2 diff --git a/src/ros2/example_interfaces/AddTwoInts.idl b/src/ros2/example_interfaces/AddTwoInts.idl new file mode 100644 index 0000000..dbe87b7 --- /dev/null +++ b/src/ros2/example_interfaces/AddTwoInts.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/srv.idl.em +// with input from example_interfaces/srv/AddTwoInts.srv +// generated code does not contain a copyright notice + + +module example_interfaces { + module srv { + struct AddTwoInts_Request { + int64 a; + + int64 b; + }; + struct AddTwoInts_Response { + int64 sum; + }; + }; +}; diff --git a/src/ros2/example_interfaces/AddTwoInts.srv b/src/ros2/example_interfaces/AddTwoInts.srv new file mode 100644 index 0000000..3a68808 --- /dev/null +++ b/src/ros2/example_interfaces/AddTwoInts.srv @@ -0,0 +1,4 @@ +int64 a +int64 b +--- +int64 sum diff --git a/src/ros2/example_interfaces/AddTwoInts_srv_client.vhd b/src/ros2/example_interfaces/AddTwoInts_srv_client.vhd new file mode 100644 index 0000000..4f55b36 --- /dev/null +++ b/src/ros2/example_interfaces/AddTwoInts_srv_client.vhd @@ -0,0 +1,741 @@ +-- 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.rtps_config_package.all; +use work.ros_package.all; + +entity AddTwoInts_srv_client is + generic ( + LITTLE_ENDIAN : std_logic := '0' + ); + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- FROM DDS READER + start_r : out std_logic; + ack_r : in std_logic; + opcode_r : out DDS_READER_OPCODE_TYPE; + instance_state_r : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + view_state_r : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + sample_state_r : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + instance_handle_r : out INSTANCE_HANDLE_TYPE; + max_samples_r : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); + get_data_r : out std_logic; + done_r : in std_logic; + return_code_r : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + valid_in_r : in std_logic; + ready_in_r : out std_logic; + data_in_r : in std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_r : in std_logic; + -- Sample Info + si_sample_state_r : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + si_view_state_r : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + si_instance_state_r : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + si_source_timestamp_r : in TIME_TYPE; + si_instance_handle_r : in INSTANCE_HANDLE_TYPE; + si_publication_handle_r : in INSTANCE_HANDLE_TYPE; + si_disposed_generation_count_r : in std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0); + si_no_writers_generation_count_r : in std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0); + si_sample_rank_r : in std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0); + si_generation_rank_r : in std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0); + si_absolute_generation_rank_r : in std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0); + si_valid_data_r : in std_logic; + si_valid_r : in std_logic; + si_ack_r : out std_logic; + eoc_r : in std_logic; + status_r : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + -- FROM DDS WRITER + start_w : out std_logic; + ack_w : in std_logic; + opcode_w : out DDS_WRITER_OPCODE_TYPE; + instance_handle_out_w : out INSTANCE_HANDLE_TYPE; + source_ts_w : out TIME_TYPE; + max_wait_w : out DURATION_TYPE; + done_w : in std_logic; + return_code_w : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + instance_handle_in_w : in INSTANCE_HANDLE_TYPE; + valid_out_w : out std_logic; + ready_out_w : in std_logic; + data_out_w : out std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_out_w : out std_logic; + valid_in_w : in std_logic; + ready_in_w : out std_logic; + data_in_w : in std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_w : in std_logic; + status_w : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + + -- TO USER + start_user : in std_logic; + ack_user : out std_logic; + opcode_user : in ROS_SERVICE_OPCODE_TYPE; + service_info_user : out SERVICE_INFO_TYPE; + sequence_id_user : out std_logic_vector(ROS_SEQUENCE_ID_WIDTH-1 downto 0); + data_available_user : out std_logic; + -- REQUEST + taken_user : out std_logic; + a : in std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + b : in std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + -- RESPONSE + sum : out std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + done_user : out std_logic; + return_code_user : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) + ); +end entity; + +architecture arch of AddTwoInts_srv_client is + + --*****TYPE DECLARATION***** + -- 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); + -- ###GENERATED END### + + -- *MAIN PROCESS* + signal stage, stage_next : STAGE_TYPE; + signal cnt, cnt_next : natural range 0 to 5; + signal endian_flag, endian_flag_next : std_logic; + signal last_word_in_latch, last_word_in_latch_next : std_logic; + signal decode_error_latch, decode_error_latch_next : std_logic; + 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 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); + signal abort_mem : std_logic; + signal ready_in_r_sig : std_logic; + signal taken_sig, taken_sig_next : std_logic; + signal service_info_sig, service_info_sig_next : SERVICE_INFO_TYPE; + signal sequence_id_sig, sequence_id_sig_next : unsigned(ROS_SEQUENCE_ID_WIDTH-1 downto 0); + signal finalize_payload, finalize_payload_next : std_logic; + signal encode_stage, encode_stage_next : ENCODE_STAGE_TYPE; + signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE; + signal return_stage, return_stage_next : DECODE_STAGE_TYPE; + signal return_code_latch, return_code_latch_next : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + signal data_available_sig, data_available_sig_next : std_logic; + -- ###GENERATED START### + signal sum_latch, sum_latch_next : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + -- ###GENERATED END### + + --*****ALIAS DECLARATION***** + alias representation_id : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) is data_in_r(WORD_WIDTH-1 downto WORD_WIDTH-PAYLOAD_REPRESENTATION_ID_WIDTH); + alias representation_options : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) is data_in_r(PAYLOAD_REPRESENTATION_OPTIONS_WIDTH-1 downto 0); + alias parameter_id : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) is data_in_latch(WORD_WIDTH-1 downto WORD_WIDTH-PARAMETER_ID_WIDTH); + alias parameter_length : std_logic_vector(PARAMETER_LENGTH_WIDTH-1 downto 0) is data_in_latch(PARAMETER_LENGTH_WIDTH-1 downto 0); + + +begin + + -- ###GENERATED START### + -- MEMORY INSTANTIATIONS + -- ###GENERATED END### + + instance_state_r <= ANY_INSTANCE_STATE; + view_state_r <= ANY_VIEW_STATE; + sample_state_r <= ANY_SAMPLE_STATE; + instance_handle_r <= HANDLE_NIL; + max_samples_r <= (others => '0'); + instance_handle_out_w <= HANDLE_NIL; + source_ts_w <= TIME_INVALID; + max_wait_w <= DURATION_ZERO; + ready_in_w <= '0'; -- DDS Writer Input is unused + taken_user <= taken_sig; + ready_in_r <= ready_in_r_sig; + service_info_user <= service_info_sig; + sequence_id_user <= std_logic_vector(sequence_id_sig); + data_available_user <= data_available_sig; + + -- ###GENERATED START### + sum <= sum_latch; + -- ###GENERATED END### + + main_prc : process (all) + variable tmp_length : unsigned(WORD_WIDTH-1 downto 0); + begin + -- DEFAULT + stage_next <= stage; + encode_stage_next <= encode_stage; + decode_stage_next <= decode_stage; + return_stage_next <= return_stage; + cnt_next <= cnt; + endian_flag_next <= endian_flag; + 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; + data_out_latch_next <= data_out_latch; + finalize_payload_next <= finalize_payload; + optional_next <= optional; + taken_sig_next <= taken_sig; + data_in_latch_next <= data_in_latch; + align_op_next <= align_op; + return_code_latch_next <= return_code_latch; + service_info_sig_next <= service_info_sig; + dw_latch_next <= dw_latch; + sequence_id_sig_next <= sequence_id_sig; + data_available_sig_next <= data_available_sig; + ready_in_r_sig <= '0'; + abort_mem <= '0'; + ack_user <= '0'; + si_ack_r <= '0'; + get_data_r <= '0'; + start_r <= '0'; + opcode_r <= NOP; + start_w <= '0'; + opcode_w <= NOP; + valid_out_w <= '0'; + last_word_out_w <= '0'; + done_user <= '0'; + return_code_user <= ROS_RET_OK; + data_out_w <= (others => '0'); + -- ###GENERATED START### + sum_latch_next <= sum_latch; + -- ###GENERATED END### + + -- Last Word Latch Setter + if (last_word_in_r = '1') then + last_word_in_latch_next <= '1'; + end if; + -- Data Available Setter + if (check_mask(status_r, DATA_AVAILABLE_STATUS)) then + data_available_sig_next <= '1'; + end if; + + + case (stage) is + when IDLE => + if (start_user = '1') then + ack_user <= '1'; + case (opcode_user) is + when SEND_REQUEST => + stage_next <= INITIATE_WRITE; + -- Increment Sequence ID + sequence_id_sig_next <= sequence_id_sig + 1; + when TAKE_RESPONSE => + stage_next <= INITIATE_READ; + when others => + return_code_latch_next <= ROS_RET_UNSUPPORTED; + stage_next <= RETURN_ROS; + end case; + -- RESET + taken_sig_next <= '0'; + abort_mem <= '1'; + else + -- ###GENERATED START### + -- MEMORY SIGNAL CONNECTIONS + -- ###GENERATED END### + end if; + when RETURN_ROS => + done_user <= '1'; + return_code_user <= return_code_latch; + + -- DONE + stage_next <= IDLE; + when INITIATE_READ => + start_r <= '1'; + opcode_r <= TAKE_NEXT_SAMPLE; + + if (ack_r = '1') then + stage_next <= WAIT_FOR_READER; + end if; + when WAIT_FOR_READER => + if (done_r = '1') then + case (return_code_r) is + when RETCODE_OK => + stage_next <= WAIT_FOR_DATA; + when RETCODE_NO_DATA => + assert (taken_sig = '0') severity FAILURE; + + -- Data Available Resetter + data_available_sig_next <= '0'; + + return_code_latch_next <= ROS_RET_OK; + stage_next <= RETURN_ROS; + when others => + return_code_latch_next <= ROS_RET_ERROR; + stage_next <= RETURN_ROS; + end case; + end if; + when WAIT_FOR_DATA => + if (si_valid_r = '1') then + si_ack_r <= '1'; + -- Meta Sample + if (si_valid_data_r = '0') then + -- Ignore and read Next Sample + stage_next <= INITIATE_READ; + else + get_data_r <= '1'; + stage_next <= GET_PAYLOAD_HEADER; + + service_info_sig_next.received_timestamp <= TIME_INVALID; + service_info_sig_next.source_timestamp <= si_source_timestamp_r; + end if; + end if; + when GET_PAYLOAD_HEADER => + -- TODO: Latch Offset from Options Field? + + ready_in_r_sig <= '1'; + -- Input Guard + if (valid_in_r = '1') then + case (representation_id) is + when CDR_BE => + endian_flag_next <= '0'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + decode_stage_next <= GET_RID_WGUID; + cnt_next <= 0; + -- Initial Fetch + when CDR_LE => + endian_flag_next <= '1'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + decode_stage_next <= GET_RID_WGUID; + cnt_next <= 0; + when others => + -- Unknown Payload Encoding + stage_next <= SKIP_PAYLOAD; + decode_error_latch_next <= '1'; + end case; + end if; + when FETCH => + ready_in_r_sig <= '1'; + -- Input Guard + if (valid_in_r = '1') then + data_in_latch_next <= data_in_r; + -- Alignment Operation in progress + if (align_op = '1') then + stage_next <= ALIGN_IN_STREAM; + -- Reset + align_op_next <= '0'; + else + stage_next <= DECODE_PAYLOAD; + end if; + end if; + when ALIGN_IN_STREAM => + -- Target Stream Alignment reached + if (check_align(align_offset, target_align)) then + -- DONE + stage_next <= DECODE_PAYLOAD; + else + align_offset_next <= align_offset + 1; + -- Need to fetch new Input Word + if (align_offset(1 downto 0) = "11") then + align_op_next <= '1'; + stage_next <= FETCH; + end if; + end if; + when DECODE_PAYLOAD => + case (decode_stage) is + -- NOTE: The Cyclone DDS implementation uses a custom request header that is pre-pended to the actual service request/response. + -- It is defined as follows: + -- struct cdds_request_header_t{ + -- uint64_t guid; + -- int64_t seq; + -- }; + -- 'seq' is set by a counter that is incremented on each "send_request". + -- 'guid' is set to the publication handle of the request writer of the service client. + -- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it) + -- Nevertheless the same 'guid' has to be returned to the client. + when GET_RID_WGUID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + service_info_sig_next.request_id.writer_guid(0) <= get_sub_vector(endian_swap(endian_flag, dw_latch),0,WORD_WIDTH,TRUE); + service_info_sig_next.request_id.writer_guid(1) <= get_sub_vector(endian_swap(endian_flag, dw_latch),1,WORD_WIDTH,TRUE); + align_offset_next <= align_offset + 8; + decode_stage_next <= GET_RID_SN; + cnt_next <= 0; + when others => + null; + end case; + end if; + when GET_RID_SN => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + 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; + cnt_next <= 0; + -- ###GENERATED END### + when others => + null; + end case; + end if; + -- ###GENERATED START### + when GET_SUM => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + sum_latch_next <= endian_swap(endian_flag, dw_latch); + align_offset_next <= align_offset + 8; + + -- DONE + stage_next <= SKIP_PAYLOAD; + when others => + null; + end case; + end if; + -- ###GENERATED END### + when GET_OPTIONAL_HEADER => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Optional Member Header + when 0 => + -- Extended Parameter Header + if (endian_swap(endian_flag,parameter_id) = PID_EXTENDED) then + cnt_next <= cnt + 1; + stage_next <= FETCH; + else + stage_next <= FETCH; + decode_stage_next <= return_stage; + cnt_next <= 0; + -- Alignment Reset + align_offset_next <= (others => '0'); + + -- Optional omitted + if(endian_swap(endian_flag,parameter_length) = (parameter_length'reverse_range => '0')) then + optional_next <= '0'; + else + optional_next <= '1'; + end if; + end if; + -- eMemberHeader + when 1 => + -- Ignore Parameter ID + cnt_next <= cnt + 1; + stage_next <= FETCH; + -- Llength + when 2 => + stage_next <= FETCH; + decode_stage_next <= return_stage; + cnt_next <= 0; + -- Alignment Reset + align_offset_next <= (others => '0'); + + -- Optional omitted + if(endian_swap(endian_flag, data_in_r) = (data_in_r'reverse_range => '0')) then + optional_next <= '0'; + else + optional_next <= '1'; + end if; + when others => + null; + end case; + end if; + when others => + null; + end case; + when SKIP_PAYLOAD => + if (last_word_in_latch = '0' and last_word_in_r = '0') then + -- Skip Read + ready_in_r_sig <= '1'; + else + -- Reset + last_word_in_latch_next <= '0'; + + -- If no Decode Error, mark output as valid + if (decode_error_latch = '0') then + taken_sig_next <= '1'; + return_code_latch_next <= ROS_RET_OK; + else + taken_sig_next <= '0'; + return_code_latch_next <= ROS_RET_ERROR; + end if; + + stage_next <= RETURN_ROS; + end if; + when INITIATE_WRITE => + start_w <= '1'; + opcode_w <= WRITE; + + if (ack_w = '1') then + stage_next <= WRITE_PAYLOAD_HEADER; + end if; + when WRITE_PAYLOAD_HEADER => + valid_out_w <= '1'; + if (LITTLE_ENDIAN = '0') then + data_out_w <= CDR_BE & x"0000"; + else + data_out_w <= CDR_LE & x"0000"; + end if; + -- Output Guard + if (ready_out_w = '1') then + stage_next <= ENCODE_PAYLOAD; + -- Reset + align_offset_next <= (others => '0'); + data_out_latch_next <= (others => '0'); + encode_stage_next <= WRITE_RID_WGUID; + cnt_next <= 0; + end if; + when PUSH => + -- Mark Last Word + if (finalize_payload = '1') then + last_word_out_w <= '1'; + end if; + + valid_out_w <= '1'; + data_out_w <= data_out_latch; + -- Output Guard + if (ready_out_w = '1') then + -- NOTE: Ensures all padding is zero. + data_out_latch_next <= (others => '0'); + -- Alignment Operation in process + if (align_op = '1') then + stage_next <= ALIGN_OUT_STREAM; + -- Reset + align_op_next <= '0'; + -- DONE + elsif (finalize_payload = '1') then + finalize_payload_next <= '0'; + stage_next <= WAIT_FOR_WRITER; + else + stage_next <= ENCODE_PAYLOAD; + end if; + end if; + when ALIGN_OUT_STREAM => + -- Target Stream Alignment reached + if (check_align(align_offset, target_align)) then + -- DONE + stage_next <= ENCODE_PAYLOAD; + else + align_offset_next <= align_offset + 1; + -- Need to push Word + if (align_offset(1 downto 0) = "11") then + align_op_next <= '1'; + stage_next <= PUSH; + end if; + end if; + when ENCODE_PAYLOAD => + case (encode_stage) is + when WRITE_RID_WGUID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_OUT_STREAM; + else + case (cnt) is + when 0 => + data_out_latch_next <= (others => '0'); + stage_next <= PUSH; + cnt_next <= cnt + 1; + when 1 => + data_out_latch_next <= (others => '0'); + stage_next <= PUSH; + align_offset_next <= align_offset + 8; + encode_stage_next <= WRITE_RID_SN; + cnt_next <= 0; + when others => + end case; + end if; + when WRITE_RID_SN => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_OUT_STREAM; + else + case (cnt) is + when 0 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, std_logic_vector(sequence_id_sig)), 0, WORD_WIDTH, TRUE); + stage_next <= PUSH; + cnt_next <= cnt + 1; + when 1 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, std_logic_vector(sequence_id_sig)), 1, WORD_WIDTH, TRUE); + stage_next <= PUSH; + align_offset_next <= align_offset + 8; + -- ###GENERATED START### + encode_stage_next <= WRITE_A; + cnt_next <= 0; + -- ###GENERATED END### + when others => + end case; + end if; + -- ###GENERATED START### + when WRITE_A => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_OUT_STREAM; + else + case (cnt) is + when 0 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, a), 0, WORD_WIDTH, TRUE); + stage_next <= PUSH; + cnt_next <= cnt + 1; + when 1 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, a), 1, WORD_WIDTH, TRUE); + stage_next <= PUSH; + align_offset_next <= align_offset + 8; + + encode_stage_next <= WRITE_B; + cnt_next <= 0; + when others => + end case; + end if; + when WRITE_B => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_OUT_STREAM; + else + case (cnt) is + when 0 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, b), 0, WORD_WIDTH, TRUE); + stage_next <= PUSH; + cnt_next <= cnt + 1; + when 1 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, b), 1, WORD_WIDTH, TRUE); + stage_next <= PUSH; + align_offset_next <= align_offset + 8; + + -- DONE + finalize_payload_next <= '1'; + when others => + end case; + end if; + -- ###GENERATED END### + when others => + null; + end case; + when WAIT_FOR_WRITER => + if (done_w = '1') then + case (return_code_w) is + when RETCODE_OK => + return_code_latch_next <= ROS_RET_OK; + stage_next <= RETURN_ROS; + when others => + return_code_latch_next <= ROS_RET_ERROR; + stage_next <= RETURN_ROS; + end case; + end if; + when others => + null; + end case; + + -- OVERREAD GUARD + -- Attempted read on empty input + if (last_word_in_latch = '1' and last_word_in_r = '0' and ready_in_r_sig = '1') then + stage_next <= SKIP_PAYLOAD; + decode_error_latch_next <= '1'; + end if; + + end process; + + sync_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + stage <= IDLE; + encode_stage <= WRITE_RID_WGUID; + decode_stage <= GET_RID_WGUID; + return_stage <= GET_RID_WGUID; + target_align <= ALIGN_1; + cnt <= 0; + endian_flag <= '0'; + last_word_in_latch <= '0'; + decode_error_latch <= '0'; + optional <= '0'; + taken_sig <= '0'; + align_op <= '0'; + finalize_payload <= '0'; + data_available_sig <= '0'; + align_offset <= (others => '0'); + data_in_latch <= (others => '0'); + data_out_latch <= (others => '0'); + dw_latch <= (others => '0'); + sequence_id_sig <= (others => '0'); + return_code_latch <= ROS_RET_OK; + service_info_sig <= EMPTY_SERVICE_INFO; + -- ###GENERATED START### + sum_latch <= (others => '0'); + -- ###GENERATED END### + else + stage <= stage_next; + encode_stage <= encode_stage_next; + decode_stage <= decode_stage_next; + return_stage <= return_stage_next; + target_align <= target_align_next; + cnt <= cnt_next; + endian_flag <= endian_flag_next; + last_word_in_latch <= last_word_in_latch_next; + decode_error_latch <= decode_error_latch_next; + optional <= optional_next; + taken_sig <= taken_sig_next; + align_op <= align_op_next; + finalize_payload <= finalize_payload_next; + data_available_sig <= data_available_sig_next; + align_offset <= align_offset_next; + data_in_latch <= data_in_latch_next; + data_out_latch <= data_out_latch_next; + dw_latch <= dw_latch_next; + sequence_id_sig <= sequence_id_sig_next; + return_code_latch <= return_code_latch_next; + service_info_sig <= service_info_sig_next; + -- ###GENERATED START### + sum_latch <= sum_latch_next; + -- ###GENERATED END### + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/ros2/example_interfaces/AddTwoInts_srv_server.vhd b/src/ros2/example_interfaces/AddTwoInts_srv_server.vhd new file mode 100644 index 0000000..7ef20ae --- /dev/null +++ b/src/ros2/example_interfaces/AddTwoInts_srv_server.vhd @@ -0,0 +1,745 @@ +-- 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.rtps_config_package.all; +use work.ros_package.all; + +entity AddTwoInts_srv_server is + generic ( + LITTLE_ENDIAN : std_logic := '0' + ); + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- FROM DDS READER + start_r : out std_logic; + ack_r : in std_logic; + opcode_r : out DDS_READER_OPCODE_TYPE; + instance_state_r : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + view_state_r : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + sample_state_r : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + instance_handle_r : out INSTANCE_HANDLE_TYPE; + max_samples_r : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); + get_data_r : out std_logic; + done_r : in std_logic; + return_code_r : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + valid_in_r : in std_logic; + ready_in_r : out std_logic; + data_in_r : in std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_r : in std_logic; + -- Sample Info + si_sample_state_r : in std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + si_view_state_r : in std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + si_instance_state_r : in std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + si_source_timestamp_r : in TIME_TYPE; + si_instance_handle_r : in INSTANCE_HANDLE_TYPE; + si_publication_handle_r : in INSTANCE_HANDLE_TYPE; + si_disposed_generation_count_r : in std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0); + si_no_writers_generation_count_r : in std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0); + si_sample_rank_r : in std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0); + si_generation_rank_r : in std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0); + si_absolute_generation_rank_r : in std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0); + si_valid_data_r : in std_logic; + si_valid_r : in std_logic; + si_ack_r : out std_logic; + eoc_r : in std_logic; + status_r : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + -- FROM DDS WRITER + start_w : out std_logic; + ack_w : in std_logic; + opcode_w : out DDS_WRITER_OPCODE_TYPE; + instance_handle_out_w : out INSTANCE_HANDLE_TYPE; + source_ts_w : out TIME_TYPE; + max_wait_w : out DURATION_TYPE; + done_w : in std_logic; + return_code_w : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + instance_handle_in_w : in INSTANCE_HANDLE_TYPE; + valid_out_w : out std_logic; + ready_out_w : in std_logic; + data_out_w : out std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_out_w : out std_logic; + valid_in_w : in std_logic; + ready_in_w : out std_logic; + data_in_w : in std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_w : in std_logic; + status_w : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + + -- TO USER + start_user : in std_logic; + ack_user : out std_logic; + opcode_user : in ROS_SERVICE_OPCODE_TYPE; + service_info_user : out SERVICE_INFO_TYPE; + request_id_user : in REQUEST_ID_TYPE; + data_available_user : out std_logic; + -- REQUEST + taken_user : out std_logic; + a : out std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + b : out std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + -- RESPONSE + sum : in std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + done_user : out std_logic; + return_code_user : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) + ); +end entity; + +architecture arch of AddTwoInts_srv_server is + + --*****TYPE DECLARATION***** + -- 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); + -- ###GENERATED END### + + -- *MAIN PROCESS* + signal stage, stage_next : STAGE_TYPE; + signal cnt, cnt_next : natural range 0 to 5; + signal endian_flag, endian_flag_next : std_logic; + signal last_word_in_latch, last_word_in_latch_next : std_logic; + signal decode_error_latch, decode_error_latch_next : std_logic; + 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 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); + signal abort_mem : std_logic; + signal ready_in_r_sig : std_logic; + signal taken_sig, taken_sig_next : std_logic; + signal service_info_sig, service_info_sig_next : SERVICE_INFO_TYPE; + signal finalize_payload, finalize_payload_next : std_logic; + signal encode_stage, encode_stage_next : ENCODE_STAGE_TYPE; + signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE; + signal return_stage, return_stage_next : DECODE_STAGE_TYPE; + signal return_code_latch, return_code_latch_next : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + signal data_available_sig, data_available_sig_next : std_logic; + -- ###GENERATED START### + signal a_latch, a_latch_next : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + signal b_latch, b_latch_next : std_logic_vector(CDR_LONG_LONG_WIDTH-1 downto 0); + -- ###GENERATED END### + + --*****ALIAS DECLARATION***** + alias representation_id : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) is data_in_r(WORD_WIDTH-1 downto WORD_WIDTH-PAYLOAD_REPRESENTATION_ID_WIDTH); + alias representation_options : std_logic_vector(PAYLOAD_REPRESENTATION_ID_WIDTH-1 downto 0) is data_in_r(PAYLOAD_REPRESENTATION_OPTIONS_WIDTH-1 downto 0); + alias parameter_id : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) is data_in_latch(WORD_WIDTH-1 downto WORD_WIDTH-PARAMETER_ID_WIDTH); + alias parameter_length : std_logic_vector(PARAMETER_LENGTH_WIDTH-1 downto 0) is data_in_latch(PARAMETER_LENGTH_WIDTH-1 downto 0); + + +begin + + -- ###GENERATED START### + -- MEMORY INSTANTIATIONS + -- ###GENERATED END### + + instance_state_r <= ANY_INSTANCE_STATE; + view_state_r <= ANY_VIEW_STATE; + sample_state_r <= ANY_SAMPLE_STATE; + instance_handle_r <= HANDLE_NIL; + max_samples_r <= (others => '0'); + instance_handle_out_w <= HANDLE_NIL; + source_ts_w <= TIME_INVALID; + max_wait_w <= DURATION_ZERO; + ready_in_w <= '0'; -- DDS Writer Input is unused + taken_user <= taken_sig; + ready_in_r <= ready_in_r_sig; + service_info_user <= service_info_sig; + data_available_user <= data_available_sig; + + -- ###GENERATED START### + a <= a_latch; + b <= b_latch; + -- ###GENERATED END### + + main_prc : process (all) + variable tmp_length : unsigned(WORD_WIDTH-1 downto 0); + begin + -- DEFAULT + stage_next <= stage; + encode_stage_next <= encode_stage; + decode_stage_next <= decode_stage; + return_stage_next <= return_stage; + cnt_next <= cnt; + endian_flag_next <= endian_flag; + 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; + data_out_latch_next <= data_out_latch; + finalize_payload_next <= finalize_payload; + optional_next <= optional; + taken_sig_next <= taken_sig; + data_in_latch_next <= data_in_latch; + align_op_next <= align_op; + return_code_latch_next <= return_code_latch; + service_info_sig_next <= service_info_sig; + dw_latch_next <= dw_latch; + data_available_sig_next <= data_available_sig; + ready_in_r_sig <= '0'; + abort_mem <= '0'; + ack_user <= '0'; + si_ack_r <= '0'; + get_data_r <= '0'; + start_r <= '0'; + opcode_r <= NOP; + start_w <= '0'; + opcode_w <= NOP; + valid_out_w <= '0'; + last_word_out_w <= '0'; + done_user <= '0'; + return_code_user <= ROS_RET_OK; + data_out_w <= (others => '0'); + -- ###GENERATED START### + a_latch_next <= a_latch; + b_latch_next <= b_latch; + -- ###GENERATED END### + + -- Last Word Latch Setter + if (last_word_in_r = '1') then + last_word_in_latch_next <= '1'; + end if; + -- Data Available Setter + if (check_mask(status_r, DATA_AVAILABLE_STATUS)) then + data_available_sig_next <= '1'; + end if; + + + case (stage) is + when IDLE => + if (start_user = '1') then + ack_user <= '1'; + case (opcode_user) is + when TAKE_REQUEST => + stage_next <= INITIATE_READ; + when SEND_RESPONSE => + stage_next <= INITIATE_WRITE; + when others => + return_code_latch_next <= ROS_RET_UNSUPPORTED; + stage_next <= RETURN_ROS; + end case; + -- RESET + taken_sig_next <= '0'; + abort_mem <= '1'; + else + -- ###GENERATED START### + -- MEMORY SIGNAL CONNECTIONS + -- ###GENERATED END### + end if; + when RETURN_ROS => + done_user <= '1'; + return_code_user <= return_code_latch; + + -- DONE + stage_next <= IDLE; + when INITIATE_READ => + start_r <= '1'; + opcode_r <= TAKE_NEXT_SAMPLE; + + if (ack_r = '1') then + stage_next <= WAIT_FOR_READER; + end if; + when WAIT_FOR_READER => + if (done_r = '1') then + case (return_code_r) is + when RETCODE_OK => + stage_next <= WAIT_FOR_DATA; + when RETCODE_NO_DATA => + assert (taken_sig = '0') severity FAILURE; + + -- Data Available Resetter + data_available_sig_next <= '0'; + + return_code_latch_next <= ROS_RET_OK; + stage_next <= RETURN_ROS; + when others => + return_code_latch_next <= ROS_RET_ERROR; + stage_next <= RETURN_ROS; + end case; + end if; + when WAIT_FOR_DATA => + if (si_valid_r = '1') then + si_ack_r <= '1'; + -- Meta Sample + if (si_valid_data_r = '0') then + -- Ignore and read Next Sample + stage_next <= INITIATE_READ; + else + get_data_r <= '1'; + stage_next <= GET_PAYLOAD_HEADER; + + service_info_sig_next.received_timestamp <= TIME_INVALID; + service_info_sig_next.source_timestamp <= si_source_timestamp_r; + end if; + end if; + when GET_PAYLOAD_HEADER => + -- TODO: Latch Offset from Options Field? + + ready_in_r_sig <= '1'; + -- Input Guard + if (valid_in_r = '1') then + case (representation_id) is + when CDR_BE => + endian_flag_next <= '0'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + decode_stage_next <= GET_RID_WGUID; + cnt_next <= 0; + -- Initial Fetch + when CDR_LE => + endian_flag_next <= '1'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + decode_stage_next <= GET_RID_WGUID; + cnt_next <= 0; + when others => + -- Unknown Payload Encoding + stage_next <= SKIP_PAYLOAD; + decode_error_latch_next <= '1'; + end case; + end if; + when FETCH => + ready_in_r_sig <= '1'; + -- Input Guard + if (valid_in_r = '1') then + data_in_latch_next <= data_in_r; + -- Alignment Operation in progress + if (align_op = '1') then + stage_next <= ALIGN_IN_STREAM; + -- Reset + align_op_next <= '0'; + else + stage_next <= DECODE_PAYLOAD; + end if; + end if; + when ALIGN_IN_STREAM => + -- Target Stream Alignment reached + if (check_align(align_offset, target_align)) then + -- DONE + stage_next <= DECODE_PAYLOAD; + else + align_offset_next <= align_offset + 1; + -- Need to fetch new Input Word + if (align_offset(1 downto 0) = "11") then + align_op_next <= '1'; + stage_next <= FETCH; + end if; + end if; + when DECODE_PAYLOAD => + case (decode_stage) is + -- NOTE: The Cyclone DDS implementation uses a custom request header that is pre-pended to the actual service request/response. + -- It is defined as follows: + -- struct cdds_request_header_t{ + -- uint64_t guid; + -- int64_t seq; + -- }; + -- 'seq' is set by a counter that is incremented on each "send_request". + -- 'guid' is set to the publication handle of the request writer of the service client. + -- Note that the publication handle is useless for the server, since it is only meanigful localy (i.e. only the client can do something with it) + -- Nevertheless the same 'guid' has to be returned to the client. + when GET_RID_WGUID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + service_info_sig_next.request_id.writer_guid(0) <= get_sub_vector(endian_swap(endian_flag, dw_latch),0,WORD_WIDTH,TRUE); + service_info_sig_next.request_id.writer_guid(1) <= get_sub_vector(endian_swap(endian_flag, dw_latch),1,WORD_WIDTH,TRUE); + align_offset_next <= align_offset + 8; + decode_stage_next <= GET_RID_SN; + cnt_next <= 0; + when others => + null; + end case; + end if; + when GET_RID_SN => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + 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; + cnt_next <= 0; + -- ###GENERATED END### + when others => + null; + end case; + end if; + -- ###GENERATED START### + when GET_A => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + a_latch_next <= endian_swap(endian_flag, dw_latch); + align_offset_next <= align_offset + 8; + decode_stage_next <= GET_B; + cnt_next <= 0; + when others => + null; + end case; + end if; + when GET_B => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Double Word 1/2 + when 0 => + dw_latch_next(CDR_LONG_LONG_WIDTH-1 downto CDR_LONG_LONG_WIDTH/2) <= data_in_latch; + stage_next <= FETCH; + cnt_next <= cnt + 1; + -- Double Word 2/2 + when 1 => + dw_latch_next((CDR_LONG_LONG_WIDTH/2)-1 downto 0) <= data_in_latch; + cnt_next <= cnt + 1; + -- Push Double Word + when 2 => + b_latch_next <= endian_swap(endian_flag, dw_latch); + align_offset_next <= align_offset + 8; + + -- DONE + stage_next <= SKIP_PAYLOAD; + when others => + null; + end case; + end if; + -- ###GENERATED END### + when GET_OPTIONAL_HEADER => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_IN_STREAM; + else + case (cnt) is + -- Optional Member Header + when 0 => + -- Extended Parameter Header + if (endian_swap(endian_flag,parameter_id) = PID_EXTENDED) then + cnt_next <= cnt + 1; + stage_next <= FETCH; + else + stage_next <= FETCH; + decode_stage_next <= return_stage; + cnt_next <= 0; + -- Alignment Reset + align_offset_next <= (others => '0'); + + -- Optional omitted + if(endian_swap(endian_flag,parameter_length) = (parameter_length'reverse_range => '0')) then + optional_next <= '0'; + else + optional_next <= '1'; + end if; + end if; + -- eMemberHeader + when 1 => + -- Ignore Parameter ID + cnt_next <= cnt + 1; + stage_next <= FETCH; + -- Llength + when 2 => + stage_next <= FETCH; + decode_stage_next <= return_stage; + cnt_next <= 0; + -- Alignment Reset + align_offset_next <= (others => '0'); + + -- Optional omitted + if(endian_swap(endian_flag, data_in_r) = (data_in_r'reverse_range => '0')) then + optional_next <= '0'; + else + optional_next <= '1'; + end if; + when others => + null; + end case; + end if; + when others => + null; + end case; + when SKIP_PAYLOAD => + if (last_word_in_latch = '0' and last_word_in_r = '0') then + -- Skip Read + ready_in_r_sig <= '1'; + else + -- Reset + last_word_in_latch_next <= '0'; + + -- If no Decode Error, mark output as valid + if (decode_error_latch = '0') then + taken_sig_next <= '1'; + return_code_latch_next <= ROS_RET_OK; + else + taken_sig_next <= '0'; + return_code_latch_next <= ROS_RET_ERROR; + end if; + + stage_next <= RETURN_ROS; + end if; + when INITIATE_WRITE => + start_w <= '1'; + opcode_w <= WRITE; + + if (ack_w = '1') then + stage_next <= WRITE_PAYLOAD_HEADER; + end if; + when WRITE_PAYLOAD_HEADER => + valid_out_w <= '1'; + if (LITTLE_ENDIAN = '0') then + data_out_w <= CDR_BE & x"0000"; + else + data_out_w <= CDR_LE & x"0000"; + end if; + -- Output Guard + if (ready_out_w = '1') then + stage_next <= ENCODE_PAYLOAD; + -- Reset + align_offset_next <= (others => '0'); + data_out_latch_next <= (others => '0'); + encode_stage_next <= WRITE_RID_WGUID; + cnt_next <= 0; + end if; + when PUSH => + -- Mark Last Word + if (finalize_payload = '1') then + last_word_out_w <= '1'; + end if; + + valid_out_w <= '1'; + data_out_w <= data_out_latch; + -- Output Guard + if (ready_out_w = '1') then + -- NOTE: Ensures all padding is zero. + data_out_latch_next <= (others => '0'); + -- Alignment Operation in process + if (align_op = '1') then + stage_next <= ALIGN_OUT_STREAM; + -- Reset + align_op_next <= '0'; + -- DONE + elsif (finalize_payload = '1') then + finalize_payload_next <= '0'; + stage_next <= WAIT_FOR_WRITER; + else + stage_next <= ENCODE_PAYLOAD; + end if; + end if; + when ALIGN_OUT_STREAM => + -- Target Stream Alignment reached + if (check_align(align_offset, target_align)) then + -- DONE + stage_next <= ENCODE_PAYLOAD; + else + align_offset_next <= align_offset + 1; + -- Need to push Word + if (align_offset(1 downto 0) = "11") then + align_op_next <= '1'; + stage_next <= PUSH; + end if; + end if; + when ENCODE_PAYLOAD => + case (encode_stage) is + when WRITE_RID_WGUID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_OUT_STREAM; + else + case (cnt) is + when 0 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, get_sub_vector(std_logic_vector(to_unsigned(request_id_user.writer_guid)), 0, 64, TRUE)), 0, WORD_WIDTH, TRUE); + stage_next <= PUSH; + cnt_next <= cnt + 1; + when 1 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, get_sub_vector(std_logic_vector(to_unsigned(request_id_user.writer_guid)), 0, 64, TRUE)), 1, WORD_WIDTH, TRUE); + stage_next <= PUSH; + align_offset_next <= align_offset + 8; + encode_stage_next <= WRITE_RID_SN; + cnt_next <= 0; + when others => + end case; + end if; + when WRITE_RID_SN => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_OUT_STREAM; + else + case (cnt) is + when 0 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, std_logic_vector(to_unsigned(request_id_user.sequence_number))), 0, WORD_WIDTH, TRUE); + stage_next <= PUSH; + cnt_next <= cnt + 1; + when 1 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, std_logic_vector(to_unsigned(request_id_user.sequence_number))), 1, WORD_WIDTH, TRUE); + stage_next <= PUSH; + align_offset_next <= align_offset + 8; + -- ###GENERATED START### + encode_stage_next <= WRITE_SUM; + cnt_next <= 0; + -- ###GENERATED END### + when others => + end case; + end if; + -- ###GENERATED START### + when WRITE_SUM => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_8)) then + target_align_next <= ALIGN_8; + stage_next <= ALIGN_OUT_STREAM; + else + case (cnt) is + when 0 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, sum), 0, WORD_WIDTH, TRUE); + stage_next <= PUSH; + cnt_next <= cnt + 1; + when 1 => + data_out_latch_next <= get_sub_vector(endian_swap(LITTLE_ENDIAN, sum), 1, WORD_WIDTH, TRUE); + stage_next <= PUSH; + align_offset_next <= align_offset + 8; + + -- DONE + finalize_payload_next <= '1'; + when others => + end case; + end if; + -- ###GENERATED END### + when others => + null; + end case; + when WAIT_FOR_WRITER => + if (done_w = '1') then + case (return_code_w) is + when RETCODE_OK => + return_code_latch_next <= ROS_RET_OK; + stage_next <= RETURN_ROS; + when others => + return_code_latch_next <= ROS_RET_ERROR; + stage_next <= RETURN_ROS; + end case; + end if; + when others => + null; + end case; + + -- OVERREAD GUARD + -- Attempted read on empty input + if (last_word_in_latch = '1' and last_word_in_r = '0' and ready_in_r_sig = '1') then + stage_next <= SKIP_PAYLOAD; + decode_error_latch_next <= '1'; + end if; + + end process; + + sync_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + stage <= IDLE; + encode_stage <= WRITE_RID_WGUID; + decode_stage <= GET_RID_WGUID; + return_stage <= GET_RID_WGUID; + target_align <= ALIGN_1; + cnt <= 0; + endian_flag <= '0'; + last_word_in_latch <= '0'; + decode_error_latch <= '0'; + optional <= '0'; + taken_sig <= '0'; + align_op <= '0'; + finalize_payload <= '0'; + data_available_sig <= '0'; + align_offset <= (others => '0'); + data_in_latch <= (others => '0'); + data_out_latch <= (others => '0'); + dw_latch <= (others => '0'); + return_code_latch <= ROS_RET_OK; + service_info_sig <= EMPTY_SERVICE_INFO; + -- ###GENERATED START### + a_latch <= (others => '0'); + b_latch <= (others => '0'); + -- ###GENERATED END### + else + stage <= stage_next; + encode_stage <= encode_stage_next; + decode_stage <= decode_stage_next; + return_stage <= return_stage_next; + target_align <= target_align_next; + cnt <= cnt_next; + endian_flag <= endian_flag_next; + last_word_in_latch <= last_word_in_latch_next; + decode_error_latch <= decode_error_latch_next; + optional <= optional_next; + taken_sig <= taken_sig_next; + align_op <= align_op_next; + finalize_payload <= finalize_payload_next; + data_available_sig <= data_available_sig_next; + align_offset <= align_offset_next; + data_in_latch <= data_in_latch_next; + data_out_latch <= data_out_latch_next; + dw_latch <= dw_latch_next; + return_code_latch <= return_code_latch_next; + service_info_sig <= service_info_sig_next; + -- ###GENERATED START### + a_latch <= a_latch_next; + b_latch <= b_latch_next; + -- ###GENERATED END### + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/ros2/example_interfaces/Bool.idl b/src/ros2/example_interfaces/Bool.idl new file mode 100644 index 0000000..911743d --- /dev/null +++ b/src/ros2/example_interfaces/Bool.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Bool.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, bool." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Bool { + boolean data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Bool.msg b/src/ros2/example_interfaces/Bool.msg new file mode 100644 index 0000000..6434834 --- /dev/null +++ b/src/ros2/example_interfaces/Bool.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, bool. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +bool data diff --git a/src/ros2/example_interfaces/Byte.idl b/src/ros2/example_interfaces/Byte.idl new file mode 100644 index 0000000..a8a719d --- /dev/null +++ b/src/ros2/example_interfaces/Byte.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Byte.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, byte." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Byte { + octet data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Byte.msg b/src/ros2/example_interfaces/Byte.msg new file mode 100644 index 0000000..3453847 --- /dev/null +++ b/src/ros2/example_interfaces/Byte.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, byte. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +byte data diff --git a/src/ros2/example_interfaces/ByteMultiArray.idl b/src/ros2/example_interfaces/ByteMultiArray.idl new file mode 100644 index 0000000..887444a --- /dev/null +++ b/src/ros2/example_interfaces/ByteMultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/ByteMultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct ByteMultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/ByteMultiArray.msg b/src/ros2/example_interfaces/ByteMultiArray.msg new file mode 100644 index 0000000..963b8f9 --- /dev/null +++ b/src/ros2/example_interfaces/ByteMultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +byte[] data # array of data diff --git a/src/ros2/example_interfaces/Char.idl b/src/ros2/example_interfaces/Char.idl new file mode 100644 index 0000000..6cdbfa0 --- /dev/null +++ b/src/ros2/example_interfaces/Char.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Char.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, char." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Char { + uint8 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Char.msg b/src/ros2/example_interfaces/Char.msg new file mode 100644 index 0000000..0725f52 --- /dev/null +++ b/src/ros2/example_interfaces/Char.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, char. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +char data diff --git a/src/ros2/example_interfaces/Empty.idl b/src/ros2/example_interfaces/Empty.idl new file mode 100644 index 0000000..87a0b0a --- /dev/null +++ b/src/ros2/example_interfaces/Empty.idl @@ -0,0 +1,15 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Empty.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type.") + struct Empty { + uint8 structure_needs_at_least_one_member; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Empty.msg b/src/ros2/example_interfaces/Empty.msg new file mode 100644 index 0000000..1cc105a --- /dev/null +++ b/src/ros2/example_interfaces/Empty.msg @@ -0,0 +1,2 @@ +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. diff --git a/src/ros2/example_interfaces/Fibonacci.action b/src/ros2/example_interfaces/Fibonacci.action new file mode 100644 index 0000000..80b94e1 --- /dev/null +++ b/src/ros2/example_interfaces/Fibonacci.action @@ -0,0 +1,8 @@ +# Goal +int32 order +--- +# Result +int32[] sequence +--- +# Feedback +int32[] sequence diff --git a/src/ros2/example_interfaces/Float32.idl b/src/ros2/example_interfaces/Float32.idl new file mode 100644 index 0000000..7077e4f --- /dev/null +++ b/src/ros2/example_interfaces/Float32.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Float32.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, float32." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Float32 { + float data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Float32.msg b/src/ros2/example_interfaces/Float32.msg new file mode 100644 index 0000000..b5dcebb --- /dev/null +++ b/src/ros2/example_interfaces/Float32.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, float32. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +float32 data diff --git a/src/ros2/example_interfaces/Float32MultiArray.idl b/src/ros2/example_interfaces/Float32MultiArray.idl new file mode 100644 index 0000000..0c2c5ca --- /dev/null +++ b/src/ros2/example_interfaces/Float32MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Float32MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct Float32MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Float32MultiArray.msg b/src/ros2/example_interfaces/Float32MultiArray.msg new file mode 100644 index 0000000..447bbfe --- /dev/null +++ b/src/ros2/example_interfaces/Float32MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +float32[] data # array of data diff --git a/src/ros2/example_interfaces/Float64.idl b/src/ros2/example_interfaces/Float64.idl new file mode 100644 index 0000000..8e1410a --- /dev/null +++ b/src/ros2/example_interfaces/Float64.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Float64.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, float64." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Float64 { + double data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Float64.msg b/src/ros2/example_interfaces/Float64.msg new file mode 100644 index 0000000..d592b7f --- /dev/null +++ b/src/ros2/example_interfaces/Float64.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, float64. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +float64 data diff --git a/src/ros2/example_interfaces/Float64MultiArray.idl b/src/ros2/example_interfaces/Float64MultiArray.idl new file mode 100644 index 0000000..ed4f941 --- /dev/null +++ b/src/ros2/example_interfaces/Float64MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Float64MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct Float64MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Float64MultiArray.msg b/src/ros2/example_interfaces/Float64MultiArray.msg new file mode 100644 index 0000000..e65292f --- /dev/null +++ b/src/ros2/example_interfaces/Float64MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +float64[] data # array of data diff --git a/src/ros2/example_interfaces/Int16.idl b/src/ros2/example_interfaces/Int16.idl new file mode 100644 index 0000000..c50dbb6 --- /dev/null +++ b/src/ros2/example_interfaces/Int16.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int16.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, int16." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Int16 { + int16 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int16.msg b/src/ros2/example_interfaces/Int16.msg new file mode 100644 index 0000000..a387e02 --- /dev/null +++ b/src/ros2/example_interfaces/Int16.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, int16. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +int16 data diff --git a/src/ros2/example_interfaces/Int16MultiArray.idl b/src/ros2/example_interfaces/Int16MultiArray.idl new file mode 100644 index 0000000..e7840c5 --- /dev/null +++ b/src/ros2/example_interfaces/Int16MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int16MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct Int16MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int16MultiArray.msg b/src/ros2/example_interfaces/Int16MultiArray.msg new file mode 100644 index 0000000..7350293 --- /dev/null +++ b/src/ros2/example_interfaces/Int16MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int16[] data # array of data diff --git a/src/ros2/example_interfaces/Int32.idl b/src/ros2/example_interfaces/Int32.idl new file mode 100644 index 0000000..0c6d51c --- /dev/null +++ b/src/ros2/example_interfaces/Int32.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int32.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, int32." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Int32 { + int32 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int32.msg b/src/ros2/example_interfaces/Int32.msg new file mode 100644 index 0000000..44bc80a --- /dev/null +++ b/src/ros2/example_interfaces/Int32.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, int32. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +int32 data diff --git a/src/ros2/example_interfaces/Int32MultiArray.idl b/src/ros2/example_interfaces/Int32MultiArray.idl new file mode 100644 index 0000000..203f91e --- /dev/null +++ b/src/ros2/example_interfaces/Int32MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int32MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct Int32MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int32MultiArray.msg b/src/ros2/example_interfaces/Int32MultiArray.msg new file mode 100644 index 0000000..6261dc3 --- /dev/null +++ b/src/ros2/example_interfaces/Int32MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int32[] data # array of data diff --git a/src/ros2/example_interfaces/Int64.idl b/src/ros2/example_interfaces/Int64.idl new file mode 100644 index 0000000..2bc2880 --- /dev/null +++ b/src/ros2/example_interfaces/Int64.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int64.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, int64." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Int64 { + int64 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int64.msg b/src/ros2/example_interfaces/Int64.msg new file mode 100644 index 0000000..1d620e1 --- /dev/null +++ b/src/ros2/example_interfaces/Int64.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, int64. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +int64 data diff --git a/src/ros2/example_interfaces/Int64MultiArray.idl b/src/ros2/example_interfaces/Int64MultiArray.idl new file mode 100644 index 0000000..2e4b605 --- /dev/null +++ b/src/ros2/example_interfaces/Int64MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int64MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct Int64MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int64MultiArray.msg b/src/ros2/example_interfaces/Int64MultiArray.msg new file mode 100644 index 0000000..3f8422c --- /dev/null +++ b/src/ros2/example_interfaces/Int64MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int64[] data # array of data diff --git a/src/ros2/example_interfaces/Int8.idl b/src/ros2/example_interfaces/Int8.idl new file mode 100644 index 0000000..9734b36 --- /dev/null +++ b/src/ros2/example_interfaces/Int8.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int8.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, in8." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct Int8 { + int8 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int8.msg b/src/ros2/example_interfaces/Int8.msg new file mode 100644 index 0000000..5fa98cc --- /dev/null +++ b/src/ros2/example_interfaces/Int8.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, in8. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +int8 data diff --git a/src/ros2/example_interfaces/Int8MultiArray.idl b/src/ros2/example_interfaces/Int8MultiArray.idl new file mode 100644 index 0000000..e26a0b1 --- /dev/null +++ b/src/ros2/example_interfaces/Int8MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/Int8MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct Int8MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Int8MultiArray.msg b/src/ros2/example_interfaces/Int8MultiArray.msg new file mode 100644 index 0000000..e88865d --- /dev/null +++ b/src/ros2/example_interfaces/Int8MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +int8[] data # array of data diff --git a/src/ros2/example_interfaces/MultiArrayDimension.idl b/src/ros2/example_interfaces/MultiArrayDimension.idl new file mode 100644 index 0000000..49d41ea --- /dev/null +++ b/src/ros2/example_interfaces/MultiArrayDimension.idl @@ -0,0 +1,26 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/MultiArrayDimension.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct MultiArrayDimension { + @verbatim (language="comment", text= + " label of given dimension") + string label; + + @verbatim (language="comment", text= + " size of given dimension (in type units)") + uint32 size; + + @verbatim (language="comment", text= + " stride of given dimension") + uint32 stride; + }; + }; +}; diff --git a/src/ros2/example_interfaces/MultiArrayDimension.msg b/src/ros2/example_interfaces/MultiArrayDimension.msg new file mode 100644 index 0000000..d34ab48 --- /dev/null +++ b/src/ros2/example_interfaces/MultiArrayDimension.msg @@ -0,0 +1,7 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +string label # label of given dimension +uint32 size # size of given dimension (in type units) +uint32 stride # stride of given dimension diff --git a/src/ros2/example_interfaces/MultiArrayLayout.idl b/src/ros2/example_interfaces/MultiArrayLayout.idl new file mode 100644 index 0000000..d1eff44 --- /dev/null +++ b/src/ros2/example_interfaces/MultiArrayLayout.idl @@ -0,0 +1,46 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/MultiArrayLayout.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayDimension.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct MultiArrayLayout { + @verbatim (language="comment", text= + " The multiarray declares a generic multi-dimensional array of a" "\n" + " particular data type. Dimensions are ordered from outer most" "\n" + " to inner most." "\n" + "" "\n" + " Accessors should ALWAYS be written in terms of dimension stride" "\n" + " and specified outer-most dimension first." "\n" + "" "\n" + " multiarray(i,j,k) = data[data_offset + dim_stride[1]*i + dim_stride[2]*j + k]" "\n" + "" "\n" + " A standard, 3-channel 640x480 image with interleaved color channels" "\n" + " would be specified as:" "\n" + "" "\n" + " dim[0].label = \"height\"" "\n" + " dim[0].size = 480" "\n" + " dim[0].stride = 3*640*480 = 921600 (note dim[0] stride is just size of image)" "\n" + " dim[1].label = \"width\"" "\n" + " dim[1].size = 640" "\n" + " dim[1].stride = 3*640 = 1920" "\n" + " dim[2].label = \"channel\"" "\n" + " dim[2].size = 3" "\n" + " dim[2].stride = 3" "\n" + "" "\n" + " multiarray(i,j,k) refers to the ith row, jth column, and kth channel." "\n" + " Array of dimension properties") + sequence dim; + + @verbatim (language="comment", text= + " padding bytes at front of data") + uint32 data_offset; + }; + }; +}; diff --git a/src/ros2/example_interfaces/MultiArrayLayout.msg b/src/ros2/example_interfaces/MultiArrayLayout.msg new file mode 100644 index 0000000..f45f31e --- /dev/null +++ b/src/ros2/example_interfaces/MultiArrayLayout.msg @@ -0,0 +1,30 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# The multiarray declares a generic multi-dimensional array of a +# particular data type. Dimensions are ordered from outer most +# to inner most. +# +# Accessors should ALWAYS be written in terms of dimension stride +# and specified outer-most dimension first. +# +# multiarray(i,j,k) = data[data_offset + dim_stride[1]*i + dim_stride[2]*j + k] +# +# A standard, 3-channel 640x480 image with interleaved color channels +# would be specified as: +# +# dim[0].label = "height" +# dim[0].size = 480 +# dim[0].stride = 3*640*480 = 921600 (note dim[0] stride is just size of image) +# dim[1].label = "width" +# dim[1].size = 640 +# dim[1].stride = 3*640 = 1920 +# dim[2].label = "channel" +# dim[2].size = 3 +# dim[2].stride = 3 +# +# multiarray(i,j,k) refers to the ith row, jth column, and kth channel. + +MultiArrayDimension[] dim # Array of dimension properties +uint32 data_offset # padding bytes at front of data diff --git a/src/ros2/example_interfaces/SetBool.idl b/src/ros2/example_interfaces/SetBool.idl new file mode 100644 index 0000000..ae8b741 --- /dev/null +++ b/src/ros2/example_interfaces/SetBool.idl @@ -0,0 +1,27 @@ +// generated from rosidl_adapter/resource/srv.idl.em +// with input from example_interfaces/srv/SetBool.srv +// generated code does not contain a copyright notice + + +module example_interfaces { + module srv { + @verbatim (language="comment", text= + " This is an example of a service to set a boolean value." "\n" + " This can be used for testing but a semantically meaningful" "\n" + " one should be created to be built upon.") + struct SetBool_Request { + @verbatim (language="comment", text= + " e.g. for hardware enabling / disabling") + boolean data; + }; + struct SetBool_Response { + @verbatim (language="comment", text= + " indicate successful run of triggered service") + boolean success; + + @verbatim (language="comment", text= + " informational, e.g. for error messages") + string message; + }; + }; +}; diff --git a/src/ros2/example_interfaces/SetBool.srv b/src/ros2/example_interfaces/SetBool.srv new file mode 100644 index 0000000..1db40de --- /dev/null +++ b/src/ros2/example_interfaces/SetBool.srv @@ -0,0 +1,8 @@ +# This is an example of a service to set a boolean value. +# This can be used for testing but a semantically meaningful +# one should be created to be built upon. + +bool data # e.g. for hardware enabling / disabling +--- +bool success # indicate successful run of triggered service +string message # informational, e.g. for error messages diff --git a/src/ros2/example_interfaces/String.idl b/src/ros2/example_interfaces/String.idl new file mode 100644 index 0000000..4f3387b --- /dev/null +++ b/src/ros2/example_interfaces/String.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/String.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, string." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct String { + string data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/String.msg b/src/ros2/example_interfaces/String.msg new file mode 100644 index 0000000..42766cb --- /dev/null +++ b/src/ros2/example_interfaces/String.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, string. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +string data diff --git a/src/ros2/example_interfaces/Trigger.idl b/src/ros2/example_interfaces/Trigger.idl new file mode 100644 index 0000000..f701b45 --- /dev/null +++ b/src/ros2/example_interfaces/Trigger.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/srv.idl.em +// with input from example_interfaces/srv/Trigger.srv +// generated code does not contain a copyright notice + + +module example_interfaces { + module srv { + @verbatim (language="comment", text= + " An example of a trigger service." "\n" + " This can be used for testing but a semantically meaningful" "\n" + " one should be created to be built upon.") + struct Trigger_Request { + uint8 structure_needs_at_least_one_member; + }; + struct Trigger_Response { + @verbatim (language="comment", text= + " indicate successful run of triggered service") + boolean success; + + @verbatim (language="comment", text= + " informational, e.g. for error messages.") + string message; + }; + }; +}; diff --git a/src/ros2/example_interfaces/Trigger.srv b/src/ros2/example_interfaces/Trigger.srv new file mode 100644 index 0000000..a55d13b --- /dev/null +++ b/src/ros2/example_interfaces/Trigger.srv @@ -0,0 +1,7 @@ +# An example of a trigger service. +# This can be used for testing but a semantically meaningful +# one should be created to be built upon. + +--- +bool success # indicate successful run of triggered service +string message # informational, e.g. for error messages. diff --git a/src/ros2/example_interfaces/UInt16.idl b/src/ros2/example_interfaces/UInt16.idl new file mode 100644 index 0000000..ffed30d --- /dev/null +++ b/src/ros2/example_interfaces/UInt16.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt16.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, uint16." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct UInt16 { + uint16 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt16.msg b/src/ros2/example_interfaces/UInt16.msg new file mode 100644 index 0000000..407d683 --- /dev/null +++ b/src/ros2/example_interfaces/UInt16.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, uint16. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +uint16 data diff --git a/src/ros2/example_interfaces/UInt16MultiArray.idl b/src/ros2/example_interfaces/UInt16MultiArray.idl new file mode 100644 index 0000000..7eedd50 --- /dev/null +++ b/src/ros2/example_interfaces/UInt16MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt16MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct UInt16MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt16MultiArray.msg b/src/ros2/example_interfaces/UInt16MultiArray.msg new file mode 100644 index 0000000..ffd8e00 --- /dev/null +++ b/src/ros2/example_interfaces/UInt16MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint16[] data # array of data diff --git a/src/ros2/example_interfaces/UInt32.idl b/src/ros2/example_interfaces/UInt32.idl new file mode 100644 index 0000000..50dc9cb --- /dev/null +++ b/src/ros2/example_interfaces/UInt32.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt32.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, uint32." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct UInt32 { + uint32 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt32.msg b/src/ros2/example_interfaces/UInt32.msg new file mode 100644 index 0000000..55b8318 --- /dev/null +++ b/src/ros2/example_interfaces/UInt32.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, uint32. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +uint32 data diff --git a/src/ros2/example_interfaces/UInt32MultiArray.idl b/src/ros2/example_interfaces/UInt32MultiArray.idl new file mode 100644 index 0000000..915701c --- /dev/null +++ b/src/ros2/example_interfaces/UInt32MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt32MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct UInt32MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt32MultiArray.msg b/src/ros2/example_interfaces/UInt32MultiArray.msg new file mode 100644 index 0000000..febf94e --- /dev/null +++ b/src/ros2/example_interfaces/UInt32MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint32[] data # array of data diff --git a/src/ros2/example_interfaces/UInt64.idl b/src/ros2/example_interfaces/UInt64.idl new file mode 100644 index 0000000..5740344 --- /dev/null +++ b/src/ros2/example_interfaces/UInt64.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt64.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, unint64." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct UInt64 { + uint64 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt64.msg b/src/ros2/example_interfaces/UInt64.msg new file mode 100644 index 0000000..1d208c0 --- /dev/null +++ b/src/ros2/example_interfaces/UInt64.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, unint64. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +uint64 data diff --git a/src/ros2/example_interfaces/UInt64MultiArray.idl b/src/ros2/example_interfaces/UInt64MultiArray.idl new file mode 100644 index 0000000..3e489a2 --- /dev/null +++ b/src/ros2/example_interfaces/UInt64MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt64MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct UInt64MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt64MultiArray.msg b/src/ros2/example_interfaces/UInt64MultiArray.msg new file mode 100644 index 0000000..3b0d22f --- /dev/null +++ b/src/ros2/example_interfaces/UInt64MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint64[] data # array of data diff --git a/src/ros2/example_interfaces/UInt8.idl b/src/ros2/example_interfaces/UInt8.idl new file mode 100644 index 0000000..7d28eb8 --- /dev/null +++ b/src/ros2/example_interfaces/UInt8.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt8.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, uint8." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct UInt8 { + uint8 data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt8.msg b/src/ros2/example_interfaces/UInt8.msg new file mode 100644 index 0000000..4d212f0 --- /dev/null +++ b/src/ros2/example_interfaces/UInt8.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, uint8. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +uint8 data diff --git a/src/ros2/example_interfaces/UInt8MultiArray.idl b/src/ros2/example_interfaces/UInt8MultiArray.idl new file mode 100644 index 0000000..5c15b89 --- /dev/null +++ b/src/ros2/example_interfaces/UInt8MultiArray.idl @@ -0,0 +1,25 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/UInt8MultiArray.msg +// generated code does not contain a copyright notice + +#include "example_interfaces/msg/MultiArrayLayout.idl" + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example of using complex datatypes." "\n" + " It is not recommended to use directly." "\n" + " To use a similar datastruct please define a custom message with appropriate semantic meaning.") + struct UInt8MultiArray { + @verbatim (language="comment", text= + " Please look at the MultiArrayLayout message definition for" "\n" + " documentation on all multiarrays." "\n" + " specification of data layout") + example_interfaces::msg::MultiArrayLayout layout; + + @verbatim (language="comment", text= + " array of data") + sequence data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/UInt8MultiArray.msg b/src/ros2/example_interfaces/UInt8MultiArray.msg new file mode 100644 index 0000000..3e22f68 --- /dev/null +++ b/src/ros2/example_interfaces/UInt8MultiArray.msg @@ -0,0 +1,9 @@ +# This is an example of using complex datatypes. +# It is not recommended to use directly. +# To use a similar datastruct please define a custom message with appropriate semantic meaning. + +# Please look at the MultiArrayLayout message definition for +# documentation on all multiarrays. + +MultiArrayLayout layout # specification of data layout +uint8[] data # array of data diff --git a/src/ros2/example_interfaces/WString.idl b/src/ros2/example_interfaces/WString.idl new file mode 100644 index 0000000..ae5c896 --- /dev/null +++ b/src/ros2/example_interfaces/WString.idl @@ -0,0 +1,17 @@ +// generated from rosidl_adapter/resource/msg.idl.em +// with input from example_interfaces/msg/WString.msg +// generated code does not contain a copyright notice + + +module example_interfaces { + module msg { + @verbatim (language="comment", text= + " This is an example message of using a primitive datatype, wstring." "\n" + " If you want to test with this that's fine, but if you are deploying" "\n" + " it into a system you should create a semantically meaningful message type." "\n" + " If you want to embed it in another message, use the primitive data type instead.") + struct WString { + wstring data; + }; + }; +}; diff --git a/src/ros2/example_interfaces/WString.msg b/src/ros2/example_interfaces/WString.msg new file mode 100644 index 0000000..779dbdf --- /dev/null +++ b/src/ros2/example_interfaces/WString.msg @@ -0,0 +1,5 @@ +# This is an example message of using a primitive datatype, wstring. +# If you want to test with this that's fine, but if you are deploying +# it into a system you should create a semantically meaningful message type. +# If you want to embed it in another message, use the primitive data type instead. +wstring data diff --git a/src/ros2/ros2.txt b/src/ros2/ros2.txt new file mode 100644 index 0000000..7f12105 --- /dev/null +++ b/src/ros2/ros2.txt @@ -0,0 +1,248 @@ +RCL +=== +rcl_get_zero_initialized_node () [NODE] +rcl_node_init (node, name, namespace, context, options) [RET] +rcl_node_fini (node) [RET] +rcl_node_is_valid (node) [BOOL] +rcl_node_is_valid_except_context (node) [BOOL] +rcl_node_get_name (node) [NAME] +rcl_node_get_namespace (node) [NAMESPACE] +rcl_node_get_fully_qualified_name (node) [FQN] +rcl_node_get_options (node) [OPTIONS] +rcl_node_get_domain_id (node, domain_id) [RET] +rcl_node_get_rmw_handle (node) [RMW NODE] +rcl_node_get_rcl_instance_id (node) [INSTANCE ID] +rcl_node_get_graph_guard_condition (node) [GUARD CONDITION] +rcl_node_get_logger_name (node) [LOGGER NAME] + +rcl_get_zero_initialized_publisher () [PUBLISHER] +rcl_publisher_init (publisher, node, type_support, topic_name, options) [RET] +rcl_publisher_fini (publisher, node) [RET] +rcl_publisher_get_default_options () [options] +rcl_borrow_loaned_message (publisher, type_support, ros_message) [RET] +rcl_return_loaned_message_from_publisher (publisher, loaned_message) [RET] +rcl_publish (publisher, ros_message, allocation) [RET] +rcl_publish_serialized_message (publisher, serialized_message, allocation) [RET] +rcl_publish_loaned_message (publisher, ros_message, allocation) [RET] +rcl_publisher_assert_liveliness (publisher) [RET] +rcl_publisher_get_topic_name (publisher) [TOPIC NAME] +rcl_publisher_get_options (publisher) [OPTIONS] +rcl_publisher_get_rmw_handle (publisher) [RMW PUBLISHER] +rcl_publisher_get_context (publisher) [CONTEXT] +rcl_publisher_is_valid (publisher) [BOOL] +rcl_publisher_is_valid_except_context (publisher) [BOOL] +rcl_publisher_get_subscription_count (publisher, subscription_count) [RET] +rcl_publisher_get_actual_qos (publisher) [RMW QOS PROFILE] +rcl_publisher_can_loan_messages (publisher) [BOOL] + +rcl_get_zero_initialized_subscription () [SUBSCRIBER] +rcl_subscription_init (subscriber, node, type_support, topic_name, options) [RET] +rcl_subscription_fini (subscriber, node) [RET] +rcl_subscription_get_default_options() [OPTIONS] +rcl_take (subscriber, ros_message, message_info, allocation) [RET] +rcl_take_sequence (subscriber, message_sequence, message_info_sequence, allocation) [RET] +rcl_take_serialized_message (subscriber, serialized_message, message_info, allocation) [RET] +rcl_take_loaned_message (subscriber, loaned_message, message_info, allocation) [RET] +rcl_return_loaned_message_from_subscription (subscriber, loaned_message) [RET] +rcl_subscription_get_topic_name (subscriber) [TOPIC NAME] +rcl_subscription_get_options (subscriber) [OPTIONS] +rcl_subscription_get_rmw_handle (subscriber) [RMW SUBSCRIBER] +rcl_subscription_is_valid (subscriber) [BOOL] +rcl_subscription_get_publisher_count (subscriber, publisher_count) [RET] +rcl_subscription_get_actual_qos (subscriber) [QOS PROFILE] +rcl_subscription_can_loan_messages (subscriber) [BOOL] + +rcl_get_zero_initialized_client () [CLIENT] +rcl_client_init (client, node, type_support, service_name, options) [RET] +rcl_client_fini (client, node) [RET] +rcl_client_get_default_options () [OPTIONS] +rcl_send_request (client, ros_request, sequence_number) [RET] +rcl_take_response_with_info (client, request_header, ros_response) +rcl_take_response (client, request_header, ros_response) +rcl_client_get_service_name (client) [SERVICE NAME] +rcl_client_get_options (client) [OPTIONS] +rcl_client_get_rmw_handle (client) [RMW HANDLE] +rcl_client_is_valid (client) [BOOL] + +rcl_get_zero_initialized_service () [SERVICE] +rcl_service_init (service, node, type_support, service_name, options) [RET] +rcl_service_fini (service, node) [RET] +rcl_service_get_default_options () [OPTIONS] +rcl_take_request_with_info (service, request_header, ros_request) [RET] +rcl_take_request (service, request_header, ros_request) [RET] +rcl_send_response (service, response_header, ros_response) [RET] +rcl_service_get_service_name (service) [SERVICE NAME] +rcl_service_get_options (service) [OPTIONS] +rcl_service_get_rmw_handle (service) [RMW SERVICE] +rcl_service_is_valid (service) [BOOL] + +rcl_get_zero_initialized_timer () [TIMER] +rcl_timer_init (timer, clock, context, period, callback, allocator) [RET] +rcl_timer_fini (timer) [RET] +rcl_timer_call (timer) [RET] +rcl_timer_clock (timer, clock) [RET] +rcl_timer_is_ready (timer, is_ready) [RET] +rcl_timer_get_time_until_next_call (timer, time_until_next_call) [RET] +rcl_timer_get_time_since_last_call (timer, time_since_last_call) [RET] +rcl_timer_get_period (timer, period) [RET] +rcl_timer_exchange_period (timer, new_period, old_period) [RET] +rcl_timer_get_callback (timer) [TIMER CALLBACK] +rcl_timer_exchange_callback (TIMER, NEW_CALLBACK) [TIMER CALLBACK] +rcl_timer_cancel (timer) [RET] +rcl_timer_is_canceled (timer, is_canceled) [RET] +rcl_timer_reset (timer) [RET] +rcl_timer_get_allocator (timer) [ALLOCATOR] +rcl_timer_get_guard_condition (timer) [GUARD CONDITION] + +RMW +=== + +rmw_get_zero_initialized_context () [CONTEXT] +rmw_init (options, context) [RET] +rmw_shutdown (context) [RET] +rmw_context_fini (context) [RET] + +rmw_get_implementation_identifier () [IMPLEMENTATION IDENTIFIER] +rmw_get_serialization_format () [SERIALIZATION FORMAT] +rmw_create_node (context, name, namespace, domain_id, localhost_only) [NODE] +rmw_destroy_node (node) [RET] +rmw_node_get_graph_guard_condition (node) [GUARD CONDITION] +rmw_init_publisher_allocation (type_support, message_bound, allocation) [RET] +rmw_fini_publisher_allocation (allocation) [RET] +rmw_get_default_publisher_options () [PUB OPTIONS] +rmw_create_publisher (node, type_support, topic_name, qos_policies, publisher_options) [PUBLISHER] +rmw_destroy_publisher (node, publisher) +rmw_borrow_loaned_message (publisher, type_support, ros_message) [RET] +rmw_return_loaned_message_from_publisher (publisher, loaned_message [RET] +rmw_publish (publisher, ros_message, allocation) [RET] +rmw_publish_loaned_message (publisher, ros_message, allocation) [RET] +rmw_publisher_count_matched_subscriptions (publisher, subscription_count) [RET] +rmw_publisher_get_actual_qos (publisher, qos) [RET] +rmw_publish_serialized_message (publisher, serialized_message, allocation) [RET] +rmw_get_serialized_message_size (type_support, message_bounds, size) [RET] +rmw_publisher_assert_liveliness (publisher) [RET] +rmw_serialize (ros_message, type_support, serialized_message) [RET] +rmw_deserialize (serialized_message, type_support, ros_message) [RET] +rmw_init_subscription_allocation (type_support, message_bounds, allocation) [RET] +rmw_fini_subscription_allocation (allocation) [RET] +rmw_create_subscription (node, type_support, topic_name, qos_policies, subscriber_options) [SUBSCRIBER] +rmw_destroy_subscription (node, subscriber) [RET] +rmw_subscription_count_matched_publishers (subscriber, publisher_count) [RET] +rmw_subscription_get_actual_qos (subscriber, qos) [RET] +rmw_take (subscriber, ros_message, taken, allocation) [RET] +rmw_take_with_info (subscriber, ros_message, taken, message_info, allocation) [RET] +rmw_take_sequence (subscriber, count, message_sequence, message_info_sequence, taken, allocation) [RET] +rmw_take_serialized_message (subscriber, serialized_message, taken, allocation) [RET] +rmw_take_serialized_message_with_info (subscriber, serialized_message, taken, message_info, allocation) [RET] +rmw_take_loaned_message (subscriber, loaned_message, taken, allocation) [RET] +rmw_take_loaned_message_with_info (subscriber, loaned_message, taken, message_info, allocation) [RET] +rmw_return_loaned_message_from_subscription (subscriber, loaned_message) [RET] +rmw_create_client (node, type_support, service_name, qos_policies) [CLIENT] +rmw_destroy_client (node, client) [RET] +rmw_send_request (client, ros_request, sequence_id) [RET] +rmw_take_response (client, service_info, ros_response, taken) [RET] +rmw_create_service (node, type_support, service_name, qos_policies) [SERVICE] +rmw_destroy_service (node, service) [RET] +rmw_take_request (service, service_info, ros_request, taken) [RET] +rmw_send_response (service, request_id, ros_response) [RET] +rmw_create_guard_condition (context) [GUARD CONDITION] +rmw_destroy_guard_condition (guard_condition) [RET] +rmw_trigger_guard_condition (guard_condition) [RET] +rmw_create_wait_set (context, max_conditions) [WAIT_SET] +rmw_destroy_wait_set (wait_set) [RET] +rmw_wait (subscriber, guard_condition, services, clients, events, wait_set, wait_timeout) [RET] +rmw_get_node_names (node, node_names, node_namespaces) [RET] +rmw_get_node_names_with_enclaves (node, node_names, node_namespaces, enclaves) [RET] +rmw_count_publishers (node, topic_name, count) [RET] +rmw_count_subscribers (node, topic_name, count) [RET] +rmw_get_gid_for_publisher (publisher, gid) [RET] +rmw_compare_gids_equal (gid1, gid2, result) [RET] +rmw_service_server_is_available (node, client, is_available) [RET] +rmw_set_log_severity (severity) [RET] + + +CONTEXT +------- +instance_id, implementation_identifier, options, impl + +OPTIONS +------- +instance_id, implementation_identifier, domain_id, security_options, localhost_only, enclave, allocator, impl + +SECURITY OPTIONS +---------------- +enforce_security, security_root_path + +GUARD CONDITION +--------------- +implementation_identifier, data, context + +SERVICE INFO +------------ +source_timestamp, received_timestamp, request_id + +REQUEST ID +---------- +writer_guid, sequence_number + + +################################## +http://design.ros2.org/articles/legacy_interface_definition.html +http://design.ros2.org/articles/idl_interface_definition.html +http://design.ros2.org/articles/topic_and_service_names.html + +http://design.ros2.org/articles/clock_and_time.html +http://design.ros2.org/articles/qos.html +http://design.ros2.org/articles/qos_configurability.html +http://design.ros2.org/articles/qos_deadline_liveliness_lifespan.html + +GENERAL +======= +http://design.ros2.org/articles/Node_to_Participant_mapping.html +REF: https://github.com/ros2/rmw_dds_common.git + +TOPIC: 'ros_discovery_info' [ParticipantInfo.msg] +QOS: TRANSIENT_LOCAL, KEEP_LAST, DEPTH 1, RELIABLE + +Each Participant publishes a message with all the information needed to match an entity to a Node. +When one entity is updated (e.g.: a Publisher is created or destroyed), a new message is sent. + +SERVICE +======= +REF: https://github.com/ros2/rmw_cyclonedds.git + +TOPIC: 'rqRequest' [cdds_request_wrapper_t] +TOPIC: 'rrResponse' [cdds_request_wrapper_t] +QOS: According to caling rmw_function + +NOTE: This is Cyclone DDS implementation specific + +ACTION +====== +http://design.ros2.org/articles/actions.html +REF: https://github.com/ros2/rclcpp.git [/rlcpp_action] + +SERVICE: '/_action/send_goal' [1st section of .action Definition] +SERVICE: '/_action/cancel_goal' [rcl_interfaces/action_msgs/CancelGoal.srv] +SERVICE: '/_action/get_result' [2nd section of .action Definition] +TOPIC: '/_action/feedback' [3rd section of .action Definition] +TOPIC: '/_action/status' + + +PARAMETER +========= +http://design.ros2.org/articles/ros_parameters.html +REF: https://github.com/ros2/rclcpp.git + +SERVICE: 'GetParameters' +SERVICE: 'HasParameters' +SERVICE: 'ListParameters' +SERVICE: 'SetParameters' +TOPIC: 'ParameterEvent' +TOPIC: 'ParameterEventDescriptor' + + +MANAGED NODE +============ +http://design.ros2.org/articles/node_lifecycle.html +REF: https://github.com/ros2/rclcpp.git [/rlcpp_lifecycle] \ No newline at end of file diff --git a/src/ros2/ros_package.vhd b/src/ros2/ros_package.vhd new file mode 100644 index 0000000..ce72d5e --- /dev/null +++ b/src/ros2/ros_package.vhd @@ -0,0 +1,463 @@ +-- 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.rtps_config_package.all; --TODO: Remove after putting DDS_*_OPCODE_TYPE inside rtps_package + +package ros_package is + + type ROS_QOS_PROFILE_TYPE is record + HISTORY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + HISTORY_DEPTH : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + RELIABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + DURABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + DEADLINE_QOS : DURATION_TYPE; + LIFESPAN_QOS : DURATION_TYPE; + LIVELINESS_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); + LEASE_DURATION : DURATION_TYPE; + AVOID_ROS_NAMESPACE_CONVENTION : boolean; + end record; + + constant ROS_QOS_PROFILE_SENSOR_DATA : ROS_QOS_PROFILE_TYPE := ( + HISTORY_QOS => KEEP_LAST_HISTORY_QOS, + HISTORY_DEPTH => std_logic_vector(to_unsigned(5, CDR_LONG_WIDTH)), + RELIABILITY_QOS => BEST_EFFORT_RELIABILITY_QOS, + DURABILITY_QOS => VOLATILE_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_PARAMETERS : ROS_QOS_PROFILE_TYPE := ( + HISTORY_QOS => KEEP_LAST_HISTORY_QOS, + HISTORY_DEPTH => std_logic_vector(to_unsigned(1000, CDR_LONG_WIDTH)), + RELIABILITY_QOS => RELIABLE_RELIABILITY_QOS, + DURABILITY_QOS => VOLATILE_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_DEFAULT : 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 => VOLATILE_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)), + RELIABILITY_QOS => RELIABLE_RELIABILITY_QOS, + DURABILITY_QOS => VOLATILE_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_PARAMETER_EVENTS : ROS_QOS_PROFILE_TYPE := ( + HISTORY_QOS => KEEP_LAST_HISTORY_QOS, + HISTORY_DEPTH => std_logic_vector(to_unsigned(1000, CDR_LONG_WIDTH)), + RELIABILITY_QOS => RELIABLE_RELIABILITY_QOS, + DURABILITY_QOS => VOLATILE_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_SYSTEM_DEFAULT : ROS_QOS_PROFILE_TYPE := ( + HISTORY_QOS => DEFAULT_HISTORY_QOS, + HISTORY_DEPTH => DEFAULT_HISTORY_DEPTH, + RELIABILITY_QOS => DEFAULT_RELIABILITY_QOS_R, + DURABILITY_QOS => DEFAULT_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 + ); + + type ROS_NODE_TYPE is record + --context_id : natural; + name : USER_STRING_TYPE; + namespace : USER_STRING_TYPE; + domain_id : natural; + NUM_PUBS : natural; + NUM_SUBS : natural; + NUM_SERVICES : natural; + NUM_ACTIONS : natural; + end record; + + type ROS_TOPIC_TYPE is record + node_id : natural; + TOPICNAME : USER_STRING_TYPE; + TYPENAME : USER_STRING_TYPE; + QOS : ROS_QOS_PROFILE_TYPE; + end record; + + type ROS_SERVICE_TYPE is record + node_id : natural; + SERVICENAME : USER_STRING_TYPE; + TYPENAME : USER_STRING_TYPE; + QOS : ROS_QOS_PROFILE_TYPE; + is_client : boolean; + end record; + + type ROS_ACTION_TYPE is record + node_id : natural; + -- TODO + end record; + + type REQUEST_ID_TYPE is record + writer_guid : GUID_TYPE; + sequence_number : SEQUENCENUMBER_TYPE; + end record; + + constant EMPTY_REQUEST_ID : REQUEST_ID_TYPE := (writer_guid => GUID_UNKNOWN, sequence_number => SEQUENCENUMBER_UNKNOWN); + + type SERVICE_INFO_TYPE is record + source_timestamp : TIME_TYPE; + received_timestamp : TIME_TYPE; + request_id : REQUEST_ID_TYPE; + end record; + + constant EMPTY_SERVICE_INFO : SERVICE_INFO_TYPE := (source_timestamp => TIME_INVALID, received_timestamp => TIME_INVALID, request_id => EMPTY_REQUEST_ID); + + type ROS_NODE_ARRAY_TYPE is array (natural range <>) of ROS_NODE_TYPE; + type ROS_TOPIC_ARRAY_TYPE is array (natural range <>) of ROS_TOPIC_TYPE; + type ROS_SERVICE_ARRAY_TYPE is array (natural range <>) of ROS_SERVICE_TYPE; + type ROS_ACTION_ARRAY_TYPE is array (natural range <>) of ROS_ACTION_TYPE; + + -- *ROS RETURN CODES* + constant ROS_RETCODE_WIDTH : natural := 32; + constant ROS_RET_OK : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(0,ROS_RETCODE_WIDTH)); + constant ROS_RET_ERROR : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(1,ROS_RETCODE_WIDTH)); + constant ROS_RET_TIMEOUT : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,ROS_RETCODE_WIDTH)); + constant ROS_RET_UNSUPPORTED : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(3,ROS_RETCODE_WIDTH)); + + type ROS_SERVICE_OPCODE_TYPE is (NOP, SEND_REQUEST, TAKE_REQUEST, SEND_RESPONSE, TAKE_RESPONSE); + + constant ROS_SEQUENCE_ID_WIDTH : natural := 64; + + type ENDPOINT_ROS_NODE_MAPPING_ARRAY_TYPE is array (natural range <>) of natural; + + constant GID_WIDTH : natural := 192; + type GID_TYPE is array (0 to (GID_WIDTH/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0); + + function to_gid(guid : GUID_TYPE) return GID_TYPE; + + 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; + function get_num_actions(nodes : ROS_NODE_ARRAY_TYPE) return natural; + function get_domain_id(nodes : ROS_NODE_ARRAY_TYPE) return natural; + function gen_fqn(ns : string; node : string; name : string) return USER_STRING_TYPE; + 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); + procedure set_from_qos_profile(profile : in ROS_QOS_PROFILE_TYPE; config : inout CONFIG_TYPE); + + type SERVICE_INTERFACE_TYPE is record + start_r : std_logic; + ack_r : std_logic; + opcode_r : DDS_READER_OPCODE_TYPE; + instance_state_r : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + view_state_r : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + sample_state_r : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + instance_handle_r : INSTANCE_HANDLE_TYPE; + max_samples_r : std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); + get_data_r : std_logic; + done_r : std_logic; + return_code_r : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + valid_in_r : std_logic; + ready_in_r : std_logic; + data_in_r : std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_r : std_logic; + si_sample_state_r : std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + si_view_state_r : std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + si_instance_state_r : std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + si_source_timestamp_r : TIME_TYPE; + si_instance_handle_r : INSTANCE_HANDLE_TYPE; + si_publication_handle_r : INSTANCE_HANDLE_TYPE; + si_disposed_generation_count_r : std_logic_vector(DISPOSED_GENERATION_COUNT_WIDTH-1 downto 0); + si_no_writers_generation_count_r : std_logic_vector(NO_WRITERS_GENERATION_COUNT_WIDTH-1 downto 0); + si_sample_rank_r : std_logic_vector(SAMPLE_RANK_WIDTH-1 downto 0); + si_generation_rank_r : std_logic_vector(GENERATION_RANK_WIDTH-1 downto 0); + si_absolute_generation_rank_r : std_logic_vector(ABSOLUTE_GENERATION_COUNT_WIDTH-1 downto 0); + si_valid_data_r : std_logic; + si_valid_r : std_logic; + si_ack_r : std_logic; + eoc_r : std_logic; + status_r : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + start_w : std_logic; + ack_w : std_logic; + opcode_w : DDS_WRITER_OPCODE_TYPE; + instance_handle_out_w : INSTANCE_HANDLE_TYPE; + source_ts_w : TIME_TYPE; + max_wait_w : DURATION_TYPE; + done_w : std_logic; + return_code_w : std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + instance_handle_in_w : INSTANCE_HANDLE_TYPE; + valid_out_w : std_logic; + ready_out_w : std_logic; + data_out_w : std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_out_w : std_logic; + valid_in_w : std_logic; + ready_in_w : std_logic; + data_in_w : std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_w : std_logic; + status_w : std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + end record; + + type SERVICE_INTERFACE_ARRAY_TYPE is array (natural range <>) of SERVICE_INTERFACE_TYPE; + +end package; + +package body ros_package is + + function to_gid(guid : GUID_TYPE) return GID_TYPE is + variable ret : GID_TYPE; + begin + ret := (others => (others => '0')); + for i in 0 to guid'length-1 loop + ret(i) := guid(i); + end loop; + + return ret; + end function; + + function get_num_pubs(nodes : ROS_NODE_ARRAY_TYPE) return natural is + variable ret : natural; + begin + ret := 0; + for i in 0 to nodes'length-1 loop + ret := ret + nodes(i).NUM_PUBS; + end loop; + return ret; + end function; + + function get_num_subs(nodes : ROS_NODE_ARRAY_TYPE) return natural is + variable ret : natural; + begin + ret := 0; + for i in 0 to nodes'length-1 loop + ret := ret + nodes(i).NUM_SUBS; + end loop; + return ret; + end function; + + function get_num_services(nodes : ROS_NODE_ARRAY_TYPE) return natural is + variable ret : natural; + begin + ret := 0; + for i in 0 to nodes'length-1 loop + ret := ret + nodes(i).NUM_SERVICES; + end loop; + return ret; + end function; + + function get_num_actions(nodes : ROS_NODE_ARRAY_TYPE) return natural is + variable ret : natural; + begin + ret := 0; + for i in 0 to nodes'length-1 loop + ret := ret + nodes(i).NUM_ACTIONS; + end loop; + return ret; + end function; + + function is_numeric_char (char : character) return boolean is + variable ret : boolean; + begin + if (character'POS(char) >= character'POS('0') and character'POS(char) <= character'POS('9')) then + return TRUE; + else + return FALSE; + end if; + end function; + + function is_valid_char (char : character) return boolean is + variable ret : boolean; + begin + -- Whitelist + -- Name may contain alphanumeric characters ([0-9|a-z|A-Z]), underscores (_), or forward slashes (/) + if is_numeric_char(char) then + return TRUE; + elsif (character'POS(char) >= character'POS('A') and character'POS(char) <= character'POS('Z')) then + return TRUE; + elsif (character'POS(char) >= character'POS('a') and character'POS(char) <= character'POS('z')) then + return TRUE; + elsif (char = '_' or char = '/') then + return TRUE; + end if; + + return FALSE; + end function; + + procedure is_valid_name (name : in string) is + variable start : natural; + variable prev : character; + begin + assert (string_len(name) > 0) report "Name must not be empty" severity FAILURE; + assert (not is_numeric_char(name(1))) report "Name must not start with a numeric character" severity FAILURE; + assert (name(string_len(name)) /= '/') report "Name must not end with a forward slash (/)" severity FAILURE; + + start := 1; + + if (name(1) = '~') then + if (string_len(name) > 1) then + assert (name(2) = '/') report "Name must separate a tilde (~) from the rest of the name with a forward slash (/), i.e. ~/foo not ~foo" severity FAILURE; + end if; + start := 2; -- Skip valid char checking for '~' + end if; + + prev := ' '; + for i in start to string_len(name) loop + assert (name(i) /= '{') report "Substitution is not supported" severity FAILURE; + assert (not (name(i) = '/' and name(i) = prev)) report "Name must not contain any number of repeated forward slashes (/)" severity FAILURE; + assert (not (name(i) = '_' and name(i) = prev)) report "Name must not contain any number of repeated underscores (_)" severity FAILURE; + assert (is_valid_char(name(i))) report "Name may contain alphanumeric characters ([0-9|a-z|A-Z]), underscores (_), or forward slashes (/)" severity FAILURE; + prev := name(i); + end loop; + end procedure; + + + function get_domain_id(nodes : ROS_NODE_ARRAY_TYPE) return natural is + variable ret : natural; + begin + ret := nodes(0).domain_id; + for i in 1 to nodes'length-1 loop + assert (nodes(i).domain_id = ret) report "No support for multiple domain IDs in same ROS context" severity FAILURE; + end loop; + return ret; + end function; + + 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 + -- Check PUB Mapping + if (nodes(i).NUM_PUBS > 0) then + tmp := 0; + for j in 0 to pubs'length loop + if (pubs(j).node_id = i) then + tmp := tmp + 1; + end if; + end loop; + assert (tmp = nodes(i).NUM_PUBS) report "Missing publication definition for Node " & integer'image(i) severity FAILURE; + end if; + + -- Check SUB Mapping + if (nodes(i).NUM_SUBS > 0) then + tmp := 0; + for j in 0 to subs'length loop + if (subs(j).node_id = i) then + tmp := tmp + 1; + end if; + end loop; + assert (tmp = nodes(i).NUM_SUBS) report "Missing subscription definition for Node " & integer'image(i) severity FAILURE; + end if; + + -- Check SERVICE Mapping + if (nodes(i).NUM_SERVICES > 0) then + tmp := 0; + for j in 0 to services'length loop + if (services(j).node_id = i) then + tmp := tmp + 1; + end if; + end loop; + assert (tmp = nodes(i).NUM_SERVICES) report "Missing service definition for Node " & integer'image(i) severity FAILURE; + end if; + + -- Check ACTION Mapping + if (nodes(i).NUM_ACTIONS > 0) then + tmp := 0; + for j in 0 to actions'length loop + if (actions(j).node_id = i) then + tmp := tmp + 1; + end if; + end loop; + assert (tmp = nodes(i).NUM_ACTIONS) report "Missing action definition for Node " & integer'image(i) severity FAILURE; + end if; + end loop; + end procedure; + + procedure set_from_qos_profile(profile : in ROS_QOS_PROFILE_TYPE; config : inout CONFIG_TYPE) is + begin + config.RELIABILITY_QOS := profile.RELIABILITY_QOS; + config.DURABILITY_QOS := profile.DURABILITY_QOS; + config.HISTORY_QOS := profile.HISTORY_QOS; + config.HISTORY_DEPTH := profile.HISTORY_DEPTH; + config.DEADLINE_QOS := profile.DEADLINE_QOS; + config.LIFESPAN_QOS := profile.LIFESPAN_QOS; + config.LIVELINESS_QOS := profile.LIVELINESS_QOS; + config.LEASE_DURATION := profile.LEASE_DURATION; + -- Since ROS does not use Keyed Topics, we can effectively limit the Resources to the History Depth + config.MAX_SAMPLES := profile.HISTORY_DEPTH; + config.MAX_INSTANCES := profile.HISTORY_DEPTH; + config.MAX_SAMPLES_PER_INSTANCE := profile.HISTORY_DEPTH; + end procedure; + + function gen_fqn(ns : string; node : string; name : string) return USER_STRING_TYPE is + variable ret : USER_STRING_TYPE; + begin + ret := EMPTY_USER_STRING; + + is_valid_name(name); + + -- Private Namespace + if (name(1) = '~') then + + -- NAMESPACE + if (string_len(ns) > 0) then + assert(ns(1) = '/') report "Namespace has to be absolute" severity FAILURE; + is_valid_name(ns); + ret := concat(ns,"/"); + else + ret := gen_user_string("/"); + end if; + -- NODENAME + assert(node(1) /= '/') report "Nodename cannot start with '/'" severity FAILURE; + is_valid_name(node); + ret := concat(ret,node); + -- NAME + if (string_len(name) > 1) then + -- Remove First Character ('~') + ret := concat(ret,substr(2,string_len(name),name)); + end if; + -- Absolute Name + elsif (name(1) = '/') then + ret := name; + -- Relative Name + else + -- NAMESPACE + if (string_len(ns) > 0) then + assert(ns(1) = '/') report "Namespace has to be absolute" severity FAILURE; + is_valid_name(ns); + ret := concat(ns,"/"); + else + ret := gen_user_string("/"); + end if; + -- NAME + ret := concat(ret,name); + end if; + + return ret; + end function; + +end package body; diff --git a/src/rtps_package.vhd b/src/rtps_package.vhd index 7829f1c..cfcfd95 100644 --- a/src/rtps_package.vhd +++ b/src/rtps_package.vhd @@ -473,9 +473,13 @@ package rtps_package is type USER_ENUMERATION_ARRAY_TYPE is array (natural range <>) of std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); type USER_LONG_ARRAY_TYPE is array (natural range <>) of std_logic_vector(CDR_LONG_WIDTH-1 downto 0); - constant DEFAULT_USER_DOMAIN_TAG : USER_STRING_TYPE := (others => NUL); + constant EMPTY_USER_STRING : USER_STRING_TYPE := (others => NUL); + constant DEFAULT_USER_DOMAIN_TAG : USER_STRING_TYPE := EMPTY_USER_STRING; function gen_user_string(input : string) return string; + function string_len (str : string) return natural; + function concat(A,B : string) return USER_STRING_TYPE; + function substr(first : natural; last : natural; str : string) return USER_STRING_TYPE; type CONFIG_TYPE is record -- If Endpoint uses Keye Topics @@ -956,4 +960,49 @@ package body rtps_package is AUTOPURGE_DISPOSED_SAMPLES_DELAY => DEFAULT_AUTOPURGE_DISPOSED_SAMPLES_DELAY ); + function string_len(str : string) return natural is + variable ret : natural; + begin + ret := 0; + for i in 1 to str'length loop + if (str(i) = NUL) then + exit; + end if; + ret := ret + 1; + end loop; + return ret; + end function; + + function concat(A,B : string) return USER_STRING_TYPE is + variable ret : USER_STRING_TYPE; + variable index : natural; + begin + assert (string_len(A) + string_len(B) <= USER_STRING_TYPE'length) report "Concatenated String exceeds USER_STRING_TYPE character limit" severity FAILURE; + + ret := EMPTY_USER_STRING; + index := 1; + for i in 1 to string_len(A) loop + ret(index) := A(i); + index := index + 1; + end loop; + for i in 1 to string_len(B) loop + ret(index) := B(i); + index := index + 1; + end loop; + return ret; + end function; + + function substr(first : natural; last : natural; str : string) return USER_STRING_TYPE is + variable ret : USER_STRING_TYPE; + begin + assert (last >= first) report "SUBSTR: Last index has to come after first index" severity FAILURE; + assert (last <= string_len(str)) report "SUBSTR: Last index exceeds string length" severity FAILURE; + + ret := EMPTY_USER_STRING; + for i in 1 to last-first+1 loop + ret(i) := str(first+i); + end loop; + return ret; + end function; + end package body;