diff --git a/sim/L2_ROS_loopback_test1.do b/sim/L2_ROS_loopback_test1.do new file mode 100644 index 0000000..d1c73d4 --- /dev/null +++ b/sim/L2_ROS_loopback_test1.do @@ -0,0 +1,124 @@ +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", + "10#10#" "ROS_RET_BAD_ALLOC", + "10#11#" "ROS_RET_INVALID_ARGUMENT", + "10#12#" "ROS_RET_INCORRECT_RMW_IMPLEMENTATION", + "10#100#" "ROS_RET_ALREADY_INIT", + "10#101#" "ROS_RET_NOT_INIT", + "10#102#" "ROS_RET_MISMATCHED_RMW", + "10#103#" "ROS_RET_TOPIC_NAME_INVALID", + "10#104#" "ROS_RET_SERVICE_NAME_INVALID", + "10#105#" "ROS_RET_UNKNOWN_SUBSTITUTION", + "10#106#" "ROS_RET_ALREADY_SHUTDOWN", + "10#200#" "ROS_RET_NODE_INVALID", + "10#201#" "ROS_RET_NODE_INVALID_NAME", + "10#202#" "ROS_RET_NODE_INVALID_NAMESPACE", + "10#203#" "ROS_RET_NODE_NAME_NON_EXISTENT", + "10#400#" "ROS_RET_SUBSCRIPTION_INVALID", + "10#401#" "ROS_RET_SUBSCRIPTION_TAKE_FAILED", + "10#500#" "ROS_RET_CLIENT_INVALID", + "10#501#" "ROS_RET_CLIENT_TAKE_FAILED", + "10#600#" "ROS_RET_SERVICE_INVALID", + "10#601#" "ROS_RET_SERVICE_TAKE_FAILED", + "10#800#" "ROS_RET_TIMER_INVALID", + "10#801#" "ROS_RET_TIMER_CANCELED", + "10#900#" "ROS_RET_WAIT_SET_INVALID", + "10#901#" "ROS_RET_WAIT_SET_EMPTY", + "10#902#" "ROS_RET_WAIT_SET_FULL", + "10#1001#" "ROS_RET_INVALID_REMAP_RULE", + "10#1002#" "ROS_RET_WRONG_LEXEME", + "10#1003#" "ROS_RET_INVALID_ROS_ARGS", + "10#1010#" "ROS_RET_INVALID_PARAM_RULE", + "10#1020#" "ROS_RET_INVALID_LOG_LEVEL_RULE", + "10#2001#" "ROS_RET_EVENT_TAKE_FAILED", + "10#2000#" "ROS_RET_ACTION_NAME_INVALID", + "10#2100#" "ROS_RET_ACTION_GOAL_ACCEPTED", + "10#2101#" "ROS_RET_ACTION_GOAL_REJECTED", + "10#2102#" "ROS_RET_ACTION_CLIENT_INVALID", + "10#2103#" "ROS_RET_ACTION_CLIENT_TAKE_FAILED", + "10#2200#" "ROS_RET_ACTION_SERVER_INVALID", + "10#2201#" "ROS_RET_ACTION_SERVER_TAKE_FAILED", + "10#2300#" "ROS_RET_ACTION_GOAL_HANDLE_INVALID", + "10#2301#" "ROS_RET_ACTION_GOAL_EVENT_INVALID", + "10#3000#" "ROS_RET_LIFECYCLE_STATE_REGISTERED", + "10#3001#" "ROS_RET_LIFECYCLE_STATE_NOT_REGISTERED", + -default unsigned +} +radix define GOAL_STATUS { + "10#0#" "STATUS_UNKNOWN", + "10#1#" "STATUS_ACCEPTED", + "10#2#" "STATUS_EXECUTING", + "10#3#" "STATUS_CANCELING", + "10#4#" "STATUS_SUCCEEDED", + "10#5#" "STATUS_CANCELED", + "10#6#" "STATUS_ABORTED", + -default unsigned +} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider SYSTEM +add wave -noupdate /l2_ros_loopback_test1/clk +add wave -noupdate /l2_ros_loopback_test1/reset +add wave -noupdate -divider {Lib7 ROS Publish} +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/start_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/opcode_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/ack_user +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/id +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/a +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/done_user +add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/return_code_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_pub_inst/stage +add wave -noupdate -divider {Lib6 ROS Subscriber} +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/start_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/opcode_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/ack_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/done_user +add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/return_code_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/data_available_user +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/id +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/a +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/message_info_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/taken_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_sub_inst/stage +add wave -noupdate -divider {Lib6 ROS Publisher} +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/start_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/opcode_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/ack_user +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/id +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/a +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/done_user +add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/return_code_user +add wave -noupdate /l2_ros_loopback_test1/Lib6_inst/Type1_ros_pub_inst/stage +add wave -noupdate -divider {Lib7 ROS Subscribe} +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/start_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/opcode_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/ack_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/done_user +add wave -noupdate -radix ROS_RETCODE /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/return_code_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/data_available_user +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/id +add wave -noupdate -radix unsigned /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/a +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/message_info_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/taken_user +add wave -noupdate /l2_ros_loopback_test1/Lib7_inst/Type1_ros_sub_inst/stage +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {2981796 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} {2042496 ps} diff --git a/sim/modelsim.ini b/sim/modelsim.ini index cd6d7bd..e0e255f 100644 --- a/sim/modelsim.ini +++ b/sim/modelsim.ini @@ -28,6 +28,8 @@ Testbench_ROS_Lib2 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib2 Testbench_ROS_Lib3 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib3.lib Testbench_ROS_Lib4 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib4.lib Testbench_ROS_Lib5 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib5.lib +Testbench_ROS_Lib6 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib6.lib +Testbench_ROS_Lib7 = /tmp/sim_temp/VHDL_LIBS/ModelSim-2020.02/Testbench_ROS_Lib7.lib [vcom] ; VHDL93 variable selects language version as the default. ; Default is VHDL-2002. diff --git a/src/ros2/Tests/Level_2/L2_ROS_Loopback_test1.vhd b/src/ros2/Tests/Level_2/L2_ROS_Loopback_test1.vhd new file mode 100644 index 0000000..aa089b8 --- /dev/null +++ b/src/ros2/Tests/Level_2/L2_ROS_Loopback_test1.vhd @@ -0,0 +1,300 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +library Testbench_ROS_Lib6; +library Testbench_ROS_Lib7; + +use work.rtps_package.all; +use work.ros_package.all; +use work.rtps_test_package.all; + +-- This testbench tests a loopback application in ROS and can be used to measure the Round Trip Time (RTT) of messages between a client and server. +-- The client writes messages to the server, and the server "mirrors" this messages back to the client. +-- The server also instantiates moving_averages for the current utilization of the input & output FIFOs, and sends them periodically to the client. +-- The client and server implementations are put in different Libraries(Testbench_ROS_Lib6 for server and Testbench_ROS_Lib7 for client). +-- This testbench directly interfaces Testbench_ROS_Lib7 and implements the client logic. +-- Because ROS does not use keyed Topics, 2 Topics are defined for the intercommunication: +-- * rt/Loopback_1 client->server +-- * rt/Loopback_2 server->client +-- A custom type containing an id and an integer (a) is used for the communication. The id differentiates what 'a' is containing: +-- * ID=1: 'a' contains the ID of the sent message by the client. The ID (in 'a') is a incrementing counter of sent messages. +-- * ID=2: 'a' contains the ID of the sent message by the server. The ID (in 'a') is the same ID contained in the message received from the client (Message with ID=1) +-- * ID=3: 'a' contains the average number of free slots in the input FIFO of the server implementation, and can be used to calculate the average FIFO utilization. +-- * ID=4: 'a' contains the average number of free slots in the output FIFO of the server implementation, and can be used to calculate the average FIFO utilization. +-- The client/testbench sends 5 messages to the server and checks the expected contents of the messages sent by the server. + +entity L2_ROS_Loopback_test1 is +end entity; + +architecture testbench of L2_ROS_Loopback_test1 is + + signal clk, reset : std_logic := '0'; + signal time : TIME_TYPE := TIME_ZERO; + signal empty_l6, empty_l7, read_l6, read_l7, full_l6, full_l7, write_l6, write_l7 : std_logic := '0'; + signal data_in_l6, data_in_l7, data_out_l6, data_out_l7 : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal input_util, output_util : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal start_r, ack_r, done_r, data_available_r, taken_r, start_w, ack_w, done_w : std_logic := '0'; + signal opcode_r, opcode_w : ROS_TOPIC_OPCODE_TYPE := NOP; + signal id_r, a_r, id_w, a_w : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + signal message_info_r : Testbench_ROS_Lib7.ros_package.MESSAGE_INFO_TYPE := Testbench_ROS_Lib7.ros_package.EMPTY_MESSAGE_INFO; + signal return_code_r, return_code_w : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + shared variable SB : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; + signal write_done : std_logic := '0'; + + -- HACK: For some reason (possibly Modelsim/Questasim Bug) I cannot declare the opcode signals from their respective Library sources, + -- because I cannot use a qualified expression to define an enumeration literal (and direct type casting cannot be done because + -- the types are not closely related). So I have to do define explicit type conversions between the types... + + function to_Lib7(input : ROS_TOPIC_OPCODE_TYPE) return Testbench_ROS_Lib7.ros_package.ROS_TOPIC_OPCODE_TYPE is + begin + return Testbench_ROS_Lib7.ros_package.ROS_TOPIC_OPCODE_TYPE'VAL(ROS_TOPIC_OPCODE_TYPE'POS(input)); + end function; + + -- Waits until signal toggles high for at least 1 ps + procedure wait_on_sig(signal sig : std_logic) is + begin + loop + if (sig /= '1') then + wait on sig until sig = '1'; + end if; + -- Prevent triggering on glitches + wait for 1 ps; + if (sig = '1') then + exit; + end if; + end loop; + end procedure; + + procedure wait_clock(num : in natural := 1) is + begin + assert (num > 0) report "Num has to be > 0" severity FAILURE; + for i in 0 to num-1 loop + wait until rising_edge(clk); + end loop; + end procedure; + +begin + + Lib6_inst : entity Testbench_ROS_Lib6.L2_Testbench_ROS_Lib6(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => Testbench_ROS_Lib6.rtps_package.TIME_TYPE(time), + -- UTILIZATION + input_util => input_util, + output_util => output_util, + -- INPUT + empty => empty_l6, + read => read_l6, + data_in => data_in_l6, + -- OUTPUT + full => full_l6, + write => write_l6, + data_out => data_out_l6 + ); + + fifo_l6_l7_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 65536/(WORD_WIDTH/BYTE_WIDTH), + DATA_WIDTH => WORD_WIDTH + ) + port map + ( + clk => clk, + reset => reset, + empty => empty_l7, + read => read_l7, + data_out => data_in_l7, + full => full_l6, + write => write_l6, + data_in => data_out_l6, + free => open + ); + + fifo_l7_l6_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 65536/(WORD_WIDTH/BYTE_WIDTH), + DATA_WIDTH => WORD_WIDTH + ) + port map + ( + clk => clk, + reset => reset, + empty => empty_l6, + read => read_l6, + data_out => data_in_l6, + full => full_l7, + write => write_l7, + data_in => data_out_l7, + free => open + ); + + Lib7_inst : entity Testbench_ROS_Lib7.L2_Testbench_ROS_Lib7(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => Testbench_ROS_Lib7.rtps_package.TIME_TYPE(time), + -- INPUT + empty => empty_l7, + read => read_l7, + data_in => data_in_l7, + -- OUTPUT + full => full_l7, + write => write_l7, + data_out => data_out_l7, + -- READER + start_r => start_r, + opcode_r => to_Lib7(opcode_r), + ack_r => ack_r, + done_r => done_r, + return_code_r => return_code_r, + data_available_r => data_available_r, + id_r => id_r, + a_r => a_r, + message_info_r => message_info_r, + taken_r => taken_r, + -- WRITER + start_w => start_w, + opcode_w => to_Lib7(opcode_w), + ack_w => ack_w, + id_w => id_w, + a_w => a_w, + done_w => done_w, + return_code_w => return_code_w + ); + + stimulus_prc : process + variable RV : RandomPType; + begin + + SetAlertLogName("L2_ROS_Loopback_test1 - Loopback"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + + Log("Initial Reset", INFO); + reset <= '1'; + wait_clock(2); + reset <= '0'; + + wait_on_sig(write_done); + while not SB.empty loop + wait_clock; + end loop; + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + write_prc : process + begin + start_w <= '0'; + opcode_w <= NOP; + id_w <= int(1,CDR_LONG_WIDTH); + a_w <= (others => '0'); + write_done <= '0'; + + wait until falling_edge(reset); + + Log("Begin Publishing Samples", INFO); + + for i in 1 to 5 loop + Log("Publish Sample " & integer'image(i), INFO); + start_w <= '1'; + opcode_w <= PUBLISH; + a_w <= int(i,CDR_LONG_WIDTH); + wait_on_sig(ack_w); + wait_clock; + start_w <= '0'; + SB.push(a_w); + wait_on_sig(done_w); + AlertIf(return_code_w /= RETCODE_OK, "Publish Operation Failed", FAILURE); + wait_clock; + end loop; + + Log("DONE Publishing Samples", INFO); + write_done <= '1'; + wait; + end process; + + read_prc : process + begin + start_r <= '0'; + opcode_r <= NOP; + + wait_on_sig(data_available_r); + Log("DATA Available on Subscriber", INFO); + + start_r <= '1'; + opcode_r <= TAKE; + wait_on_sig(ack_r); + wait_clock; + start_r <= '0'; + wait_on_sig(done_r); + AlertIf(return_code_r /= RETCODE_OK, "Take Operation Failed", FAILURE); + Log("Received Sample with ID:" & integer'image(to_integer(unsigned(id_r))), INFO); + if (taken_r = '1') then + case (to_integer(unsigned(id_r))) is + when 2 => + SB.Check(a_r); + when 3 => + AlertIf(unsigned(a_r) /= 50, "Content of received sample with ID:3 is incorrect.",ERROR); + when 4 => + AlertIf(unsigned(a_r) /= 25, "Content of received sample with ID:4 is incorrect.",ERROR); + when others => + Alert("Sample received has Unknown id", ERROR); + end case; + end if; + wait_clock; + end process; + + util_prc : process + begin + input_util <= int(0,WORD_WIDTH); + output_util <= int(0,WORD_WIDTH); + wait_clock; + input_util <= int(100,WORD_WIDTH); + output_util <= int(50,WORD_WIDTH); + wait_clock; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for TEST_CLOCK_PERIOD/2; + clk <= '1'; + wait for TEST_CLOCK_PERIOD/2; + end process; + + time_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + time <= TIME_ZERO; + else + time <= time + gen_duration(TEST_CLOCK_PERIOD); + end if; + end if; + 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_2/L2_Testbench_ROS_Lib6.vhd b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib6.vhd new file mode 100644 index 0000000..b8b4998 --- /dev/null +++ b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib6.vhd @@ -0,0 +1,668 @@ +-- 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.ros_package.all; +use work.ros_config.all; +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; + +entity L2_Testbench_ROS_Lib6 is + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + time : in TIME_TYPE; + -- UTILIZATION + input_util : in std_logic_vector(WORD_WIDTH-1 downto 0); + output_util : in std_logic_vector(WORD_WIDTH-1 downto 0); + -- INPUT + empty : in std_logic; + read : out std_logic; + data_in : in std_logic_vector(WORD_WIDTH-1 downto 0); + -- OUTPUT + full : in std_logic; + write : out std_logic; + data_out : out std_logic_vector(WORD_WIDTH-1 downto 0) + ); +end entity; + +architecture arch of L2_Testbench_ROS_Lib6 is + + signal full_fire_rh, write_rh_fire : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal last_word_rh_firb, last_word_rh_fire : std_logic; + signal data_rh_fire, data_rh_firb : std_logic_vector(WORD_WIDTH-1 downto 0); + signal full_firb_rh, write_rh_firb : std_logic; + signal read_rb_firb, empty_firb_rb, last_word_firb_rb : std_logic; + signal data_firb_rb : std_logic_vector(WORD_WIDTH-1 downto 0); + signal read_re_fire, last_word_fire_re : std_logic_vector(0 to 1); + signal empty_fire_re : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal data_fire_re : WORD_ARRAY_TYPE(0 to 1); + signal alive_re_rb, full_frbre_re, write_rb_frbre : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal last_word_rb_frbre , last_word_rb_firo : std_logic; + signal data_rb_frbre , data_rb_firo : std_logic_vector(WORD_WIDTH-1 downto 0); + signal full_firo_rb, write_rb_firo : std_logic; + signal read_re_frbre, last_word_frbre_re : std_logic_vector(0 to 1); + signal empty_frbre_re : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal data_frbre_re : WORD_ARRAY_TYPE(0 to 1); + signal full_firo_re, write_re_firo, last_word_re_firo : std_logic_vector(0 to 1); + signal data_re_firo : WORD_ARRAY_TYPE(0 to 1); + signal start_rr_dr, ack_dr_rr, done_dr_rr, valid_rr_dr, ready_dr_rr, last_word_rr_dr : std_logic_vector(0 to NUM_READERS-1); + signal opcode_rr_dr : HISTORY_CACHE_OPCODE_ARRAY_TYPE(0 to NUM_READERS-1); + signal ret_dr_rr : HISTORY_CACHE_RESPONSE_ARRAY_TYPE(0 to NUM_READERS-1); + signal data_rr_dr : WORD_ARRAY_TYPE(0 to NUM_READERS-1); + signal liveliness_assertion_dw_rw, data_available_dw_rw, start_rw_dw, ack_dw_rw, done_rw_dw, get_data_rw_dw, valid_dw_rw, ready_rw_dw, last_word_dw_rw : std_logic_vector(0 to NUM_WRITERS-1); + signal opcode_rw_dw : HISTORY_CACHE_OPCODE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal seq_nr_rw_dw, cc_seq_nr_dw_rw : SEQUENCENUMBER_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal ret_dw_rw : HISTORY_CACHE_RESPONSE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal data_dw_rw : WORD_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal cc_instance_handle_dw_rw : INSTANCE_HANDLE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal cc_kind_dw_rw : CACHE_CHANGE_KIND_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal cc_source_timestamp_dw_rw : TIME_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal sample_info_dr_ri : SAMPLE_INFO_ARRAY_TYPE(0 to NUM_READERS-1); + signal start_ri_dr, ack_dr_ri, get_data_ri_dr, done_dr_ri, ready_ri_dr, valid_dr_ri, sample_info_valid_dr_ri, sample_info_ack_ri_dr, eoc_dr_ri, last_word_dr_ri : std_logic_vector(0 to NUM_READERS-1); + signal opcode_ri_dr : DDS_READER_OPCODE_ARRAY_TYPE(0 to NUM_READERS-1); + signal instance_state_ri_dr : INSTANCE_STATE_ARRAY_TYPE(0 to NUM_READERS-1); + signal view_state_ri_dr : VIEW_STATE_ARRAY_TYPE(0 to NUM_READERS-1); + signal sample_state_ri_dr : SAMPLE_STATE_ARRAY_TYPE(0 to NUM_READERS-1); + signal instance_handle_ri_dr : INSTANCE_HANDLE_ARRAY_TYPE(0 to NUM_READERS-1); + signal max_samples_ri_dr : MAX_SAMPLES_ARRAY_TYPE(0 to NUM_READERS-1); + signal return_code_dr_ri : RETURN_CODE_ARRAY_TYPE(0 to NUM_READERS-1); + signal data_dr_ri : WORD_ARRAY_TYPE(0 to NUM_READERS-1); + signal status_dr_ri : STATUS_KIND_ARRAY_TYPE(0 to NUM_READERS-1); + signal start_wi_dw, ack_dw_wi, done_dw_wi, valid_wi_dw, valid_dw_wi, ready_wi_dw, ready_dw_wi, last_word_wi_dw, last_word_dw_wi : std_logic_vector(0 to NUM_WRITERS-1); + signal opcode_wi_dw : DDS_WRITER_OPCODE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal instance_handle_wi_dw, instance_handle_dw_wi : INSTANCE_HANDLE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal source_ts_wi_dw : TIME_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal max_wait_wi_dw : DURATION_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal return_code_dw_wi : RETURN_CODE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal data_dw_wi, data_wi_dw : WORD_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal status_dw_wi : STATUS_KIND_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal empty_firo_ro, read_ro_firo, last_word_firo_ro : std_logic_vector(0 to 2); + signal data_firo_ro : WORD_ARRAY_TYPE(0 to 2); + -- ###GENERATED START### + signal start_user_wi, start_user_ri, ack_wi_user, ack_ri_user, done_wi_user, done_ri_user, taken_ri_user, data_available_ri_user : std_logic; + signal opcode_user_wi, opcode_user_ri : ROS_TOPIC_OPCODE_TYPE; + signal id_user_wi, a_user_wi, id_ri_user, a_ri_user : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + signal return_code_wi_user, return_code_ri_user : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + signal message_info_ri_user : MESSAGE_INFO_TYPE; + -- ###GENERATED END### + +begin + + + rtps_handler_inst : entity work.rtps_handler(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- INPUT + empty => empty, + rd => read, + data_in => data_in, + -- TO DISCOVERY MODULE + full_dm => full_firb_rh, + wr_dm => write_rh_firb, + data_out_dm => data_rh_firb, + last_word_out_dm => last_word_rh_firb, + -- TO USER ENDPOINTS + full_rtps => full_fire_rh, + wr_rtps => write_rh_fire, + data_out_rtps => data_rh_fire, + last_word_out_rtps => last_word_rh_fire + ); + + + fifo_in_rb_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1 + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_firb_rh, + write => write_rh_firb, + data_in(WORD_WIDTH-1 downto 0) => data_rh_firb, + data_in(WORD_WIDTH) => last_word_rh_firb, + -- OUTPUT + empty => empty_firb_rb, + read => read_rb_firb, + data_out(WORD_WIDTH-1 downto 0) => data_firb_rb, + data_out(WORD_WIDTH) => last_word_firb_rb, + -- MISC + free => open + ); + + fifo_in_re_r_if : if (NUM_READERS > 0) generate + fifo_in_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_READERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_fire_rh(0 to NUM_READERS-1), + write => write_rh_fire(0 to NUM_READERS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rh_fire, -- Multicast + data_in(WORD_WIDTH) => last_word_rh_fire, -- Multicast + -- OUTPUT + empty => empty_fire_re(0 to NUM_READERS-1), + read => read_re_fire(0), + data_out(WORD_WIDTH-1 downto 0) => data_fire_re(0), + data_out(WORD_WIDTH) => last_word_fire_re(0) + ); + end generate; + fifo_in_re_w_if : if (NUM_WRITERS > 0) generate + fifo_in_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_WRITERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_fire_rh(NUM_READERS to NUM_ENDPOINTS-1), + write => write_rh_fire(NUM_READERS to NUM_ENDPOINTS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rh_fire, -- Multicast + data_in(WORD_WIDTH) => last_word_rh_fire, -- Multicast + -- OUTPUT + empty => empty_fire_re(NUM_READERS to NUM_ENDPOINTS-1), + read => read_re_fire(1), + data_out(WORD_WIDTH-1 downto 0) => data_fire_re(1), + data_out(WORD_WIDTH) => last_word_fire_re(1) + ); + end generate; + + rtps_discovery_module_inst : entity work.rtps_discovery_module(arch) + generic map ( + MAX_REMOTE_PARTICIPANTS => MAX_REMOTE_PARTICIPANTS, + PREFER_MULTICAST => PREFER_MULTICAST_LOCATORS + ) + port map ( + clk => clk, + reset => reset, + time => time, + -- FROM RTPS HANDLER + empty => empty_firb_rb, + rd => read_rb_firb, + data_in => data_firb_rb, + last_word_in => last_word_firb_rb, + -- FROM USER ENDPOINTS + alive => alive_re_rb, + -- TO USER ENDPOINTS + full_rtps => full_frbre_re, + wr_rtps => write_rb_frbre, + data_out_rtps => data_rb_frbre, + last_word_out_rtps => last_word_rb_frbre, + -- TO RTPS OUT + full_ro => full_firo_rb, + wr_ro => write_rb_firo, + data_out_ro => data_rb_firo, + last_word_out_ro => last_word_rb_firo + ); + + fifo_rb_re_r_if : if (NUM_READERS > 0) generate + fifo_rb_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_READERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_frbre_re(0 to NUM_READERS-1), + write => write_rb_frbre(0 to NUM_READERS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rb_frbre, + data_in(WORD_WIDTH) => last_word_rb_frbre, + -- OUTPUT + empty => empty_frbre_re(0 to NUM_READERS-1), + read => read_re_frbre(0), + data_out(WORD_WIDTH-1 downto 0) => data_frbre_re(0), + data_out(WORD_WIDTH) => last_word_frbre_re(0) + ); + end generate; + fifo_rb_re_w_if : if (NUM_WRITERS > 0) generate + fifo_rb_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_WRITERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_frbre_re(NUM_READERS to NUM_ENDPOINTS-1), + write => write_rb_frbre(NUM_READERS to NUM_ENDPOINTS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rb_frbre, + data_in(WORD_WIDTH) => last_word_rb_frbre, + -- OUTPUT + empty => empty_frbre_re(NUM_READERS to NUM_ENDPOINTS-1), + read => read_re_frbre(1), + data_out(WORD_WIDTH-1 downto 0) => data_frbre_re(1), + data_out(WORD_WIDTH) => last_word_frbre_re(1) + ); + end generate; + + + rtps_endpoint_r_if : if (NUM_READERS > 0) generate + rtps_reader_inst : entity work.rtps_reader(arch) + generic map ( + NUM_READERS => NUM_READERS, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(0 to NUM_READERS-1)), + ENTITYID => ENTITYID(0 to NUM_READERS-1), + MAX_REMOTE_ENDPOINTS => MAX_REMOTE_ENDPOINTS + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- FROM RTPS_HANDLER (USER TRAFFIC) + empty_user => empty_fire_re(0 to NUM_READERS-1), + rd_user => read_re_fire(0), + data_in_user => data_fire_re(0), + last_word_in_user => last_word_fire_re(0), + -- FROM DISCOVERY MODULE (META TRAFFIC) + empty_meta => empty_frbre_re(0 to NUM_READERS-1), + rd_meta => read_re_frbre(0), + data_in_meta => data_frbre_re(0), + last_word_in_meta => last_word_frbre_re(0), + -- RTPS OUTPUT + full_ro => full_firo_re(0), + wr_ro => write_re_firo(0), + data_out_ro => data_re_firo(0), + last_word_out_ro => last_word_re_firo(0), + -- TO HISTORY CACHE + start_hc => start_rr_dr(0 to NUM_READERS-1), + opcode_hc => opcode_rr_dr(0 to NUM_READERS-1), + ack_hc => ack_dr_rr(0 to NUM_READERS-1), + done_hc => done_dr_rr(0 to NUM_READERS-1), + ret_hc => ret_dr_rr(0 to NUM_READERS-1), + valid_out_hc => valid_rr_dr(0 to NUM_READERS-1), + ready_out_hc => ready_dr_rr(0 to NUM_READERS-1), + data_out_hc => data_rr_dr(0 to NUM_READERS-1), + last_word_out_hc => last_word_rr_dr(0 to NUM_READERS-1) + ); + + -- Set Alive Signals of Readers to Zero + alive_re_rb(0 to NUM_READERS-1) <= (others => '0'); + end generate; + + rtps_endpoint_w_if : if (NUM_WRITERS > 0) generate + rtps_writer_inst : entity work.rtps_writer(arch) + generic map ( + NUM_WRITERS => NUM_WRITERS, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(NUM_READERS to NUM_ENDPOINTS-1)), + ENTITYID => ENTITYID(NUM_READERS to NUM_ENDPOINTS-1), + INLINE_QOS => INLINE_QOS_DATA(0 to NUM_WRITERS-1), + MAX_REMOTE_ENDPOINTS => MAX_REMOTE_ENDPOINTS + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- FROM RTPS_HANDLER (USER TRAFFIC) + empty_user => empty_fire_re(NUM_READERS to NUM_ENDPOINTS-1), + rd_user => read_re_fire(1), + data_in_user => data_fire_re(1), + last_word_in_user => last_word_fire_re(1), + -- FROM DISCOVERY MODULE (META TRAFFIC) + empty_meta => empty_frbre_re(NUM_READERS to NUM_ENDPOINTS-1), + rd_meta => read_re_frbre(1), + data_in_meta => data_frbre_re(1), + last_word_in_meta => last_word_frbre_re(1), + -- TO DISCOVERY MODULE (META TRAFFIC) + alive_sig => alive_re_rb(NUM_READERS to NUM_ENDPOINTS-1), + -- RTPS OUTPUT + full_ro => full_firo_re(1), + wr_ro => write_re_firo(1), + data_out_ro => data_re_firo(1), + last_word_out_ro => last_word_re_firo(1), + -- FROM HC + liveliness_assertion => liveliness_assertion_dw_rw(0 to NUM_WRITERS-1), + data_available => data_available_dw_rw(0 to NUM_WRITERS-1), + start_hc => start_rw_dw(0 to NUM_WRITERS-1), + opcode_hc => opcode_rw_dw(0 to NUM_WRITERS-1), + ack_hc => ack_dw_rw(0 to NUM_WRITERS-1), + seq_nr_hc => seq_nr_rw_dw(0 to NUM_WRITERS-1), + done_hc => done_rw_dw(0 to NUM_WRITERS-1), + ret_hc => ret_dw_rw(0 to NUM_WRITERS-1), + get_data_hc => get_data_rw_dw(0 to NUM_WRITERS-1), + valid_in_hc => valid_dw_rw(0 to NUM_WRITERS-1), + ready_in_hc => ready_rw_dw(0 to NUM_WRITERS-1), + data_in_hc => data_dw_rw(0 to NUM_WRITERS-1), + last_word_in_hc => last_word_dw_rw(0 to NUM_WRITERS-1), + cc_instance_handle => cc_instance_handle_dw_rw(0 to NUM_WRITERS-1), + cc_kind => cc_kind_dw_rw(0 to NUM_WRITERS-1), + cc_source_timestamp => cc_source_timestamp_dw_rw(0 to NUM_WRITERS-1), + cc_seq_nr => cc_seq_nr_dw_rw(0 to NUM_WRITERS-1) + ); + end generate; + + dds_endpoint_w_if : if (NUM_WRITERS > 1) generate + dds_writer_inst : entity work.dds_writer(arch) + generic map ( + NUM_WRITERS => NUM_WRITERS-1, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(NUM_READERS to NUM_ENDPOINTS-2)) + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- TO/FROM RTPS ENDPOINT + start_rtps => start_rw_dw(0 to NUM_WRITERS-2), + opcode_rtps => opcode_rw_dw(0 to NUM_WRITERS-2), + ack_rtps => ack_dw_rw(0 to NUM_WRITERS-2), + done_rtps => done_rw_dw(0 to NUM_WRITERS-2), + ret_rtps => ret_dw_rw(0 to NUM_WRITERS-2), + seq_nr_rtps => seq_nr_rw_dw(0 to NUM_WRITERS-2), + get_data_rtps => get_data_rw_dw(0 to NUM_WRITERS-2), + valid_out_rtps => valid_dw_rw(0 to NUM_WRITERS-2), + ready_out_rtps => ready_rw_dw(0 to NUM_WRITERS-2), + data_out_rtps => data_dw_rw(0 to NUM_WRITERS-2), + last_word_out_rtps => last_word_dw_rw(0 to NUM_WRITERS-2), + liveliness_assertion => liveliness_assertion_dw_rw(0 to NUM_WRITERS-2), + data_available => data_available_dw_rw(0 to NUM_WRITERS-2), + -- Cache Change + cc_instance_handle => cc_instance_handle_dw_rw(0 to NUM_WRITERS-2), + cc_kind => cc_kind_dw_rw(0 to NUM_WRITERS-2), + cc_source_timestamp => cc_source_timestamp_dw_rw(0 to NUM_WRITERS-2), + cc_seq_nr => cc_seq_nr_dw_rw(0 to NUM_WRITERS-2), + -- TO/FROM USER ENTITY + start_dds => start_wi_dw(0 to NUM_WRITERS-2), + ack_dds => ack_dw_wi(0 to NUM_WRITERS-2), + opcode_dds => opcode_wi_dw(0 to NUM_WRITERS-2), + instance_handle_in_dds => instance_handle_wi_dw(0 to NUM_WRITERS-2), + source_ts_dds => source_ts_wi_dw(0 to NUM_WRITERS-2), + max_wait_dds => max_wait_wi_dw(0 to NUM_WRITERS-2), + done_dds => done_dw_wi(0 to NUM_WRITERS-2), + return_code_dds => return_code_dw_wi(0 to NUM_WRITERS-2), + instance_handle_out_dds => instance_handle_dw_wi(0 to NUM_WRITERS-2), + valid_in_dds => valid_wi_dw(0 to NUM_WRITERS-2), + ready_in_dds => ready_dw_wi(0 to NUM_WRITERS-2), + data_in_dds => data_wi_dw(0 to NUM_WRITERS-2), + last_word_in_dds => last_word_wi_dw(0 to NUM_WRITERS-2), + valid_out_dds => valid_dw_wi(0 to NUM_WRITERS-2), + ready_out_dds => ready_wi_dw(0 to NUM_WRITERS-2), + data_out_dds => data_dw_wi(0 to NUM_WRITERS-2), + last_word_out_dds => last_word_dw_wi(0 to NUM_WRITERS-2), + -- Communication Status + status => status_dw_wi(0 to NUM_WRITERS-2) + ); + end generate; + dds_endpoint_r_if : if (NUM_READERS > 0) generate + dds_reader_inst : entity work.dds_reader(arch) + generic map ( + NUM_READERS => NUM_READERS, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(0 to NUM_READERS-1)), + MAX_REMOTE_ENDPOINTS => MAX_REMOTE_ENDPOINTS + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- FROM RTPS ENDPOINT + start_rtps => start_rr_dr(0 to NUM_READERS-1), + opcode_rtps => opcode_rr_dr(0 to NUM_READERS-1), + ack_rtps => ack_dr_rr(0 to NUM_READERS-1), + done_rtps => done_dr_rr(0 to NUM_READERS-1), + ret_rtps => ret_dr_rr(0 to NUM_READERS-1), + valid_in_rtps => valid_rr_dr(0 to NUM_READERS-1), + ready_in_rtps => ready_dr_rr(0 to NUM_READERS-1), + data_in_rtps => data_rr_dr(0 to NUM_READERS-1), + last_word_in_rtps => last_word_rr_dr(0 to NUM_READERS-1), + -- TO USER ENTITY + start_dds => start_ri_dr(0 to NUM_READERS-1), + ack_dds => ack_dr_ri(0 to NUM_READERS-1), + opcode_dds => opcode_ri_dr(0 to NUM_READERS-1), + instance_state_dds => instance_state_ri_dr(0 to NUM_READERS-1), + view_state_dds => view_state_ri_dr(0 to NUM_READERS-1), + sample_state_dds => sample_state_ri_dr(0 to NUM_READERS-1), + instance_handle_dds => instance_handle_ri_dr(0 to NUM_READERS-1), + max_samples_dds => max_samples_ri_dr(0 to NUM_READERS-1), + get_data_dds => get_data_ri_dr(0 to NUM_READERS-1), + done_dds => done_dr_ri(0 to NUM_READERS-1), + return_code_dds => return_code_dr_ri(0 to NUM_READERS-1), + valid_out_dds => valid_dr_ri(0 to NUM_READERS-1), + ready_out_dds => ready_ri_dr(0 to NUM_READERS-1), + data_out_dds => data_dr_ri(0 to NUM_READERS-1), + last_word_out_dds => last_word_dr_ri(0 to NUM_READERS-1), + sample_info => sample_info_dr_ri(0 to NUM_READERS-1), + sample_info_valid => sample_info_valid_dr_ri(0 to NUM_READERS-1), + sample_info_ack => sample_info_ack_ri_dr(0 to NUM_READERS-1), + eoc => eoc_dr_ri(0 to NUM_READERS-1), + -- Communication Status + status => status_dr_ri(0 to NUM_READERS-1) + ); + end generate; + + + ros_discovery_writer_inst : entity work.ros_static_discovery_writer(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- TO/FROM RTPS ENDPOINT + start => start_rw_dw(NUM_WRITERS-1), + opcode => opcode_rw_dw(NUM_WRITERS-1), + ack => ack_dw_rw(NUM_WRITERS-1), + done => done_rw_dw(NUM_WRITERS-1), + ret => ret_dw_rw(NUM_WRITERS-1), + seq_nr => seq_nr_rw_dw(NUM_WRITERS-1), + get_data => get_data_rw_dw(NUM_WRITERS-1), + valid_out => valid_dw_rw(NUM_WRITERS-1), + ready_out => ready_rw_dw(NUM_WRITERS-1), + data_out => data_dw_rw(NUM_WRITERS-1), + last_word_out => last_word_dw_rw(NUM_WRITERS-1), + liveliness_assertion => liveliness_assertion_dw_rw(NUM_WRITERS-1), + data_available => data_available_dw_rw(NUM_WRITERS-1), + -- Cache Change + cc_instance_handle => cc_instance_handle_dw_rw(NUM_WRITERS-1), + cc_kind => cc_kind_dw_rw(NUM_WRITERS-1), + cc_source_timestamp => cc_source_timestamp_dw_rw(NUM_WRITERS-1), + cc_seq_nr => cc_seq_nr_dw_rw(NUM_WRITERS-1) + ); + + + fifo_in_ro_gen : for i in 0 to 2 generate + fifo_in_ro_if : if (i = 2) generate + fifo_in_ro_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1 + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_firo_rb, + write => write_rb_firo, + data_in(WORD_WIDTH-1 downto 0) => data_rb_firo, + data_in(WORD_WIDTH) => last_word_rb_firo, + -- OUTPUT + empty => empty_firo_ro(i), + read => read_ro_firo(i), + data_out(WORD_WIDTH) => last_word_firo_ro(i), + data_out(WORD_WIDTH-1 downto 0) => data_firo_ro(i), + -- MISC + free => open + ); + else generate + fifo_in_ro_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1 + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_firo_re(i), + write => write_re_firo(i), + data_in(WORD_WIDTH-1 downto 0) => data_re_firo(i), + data_in(WORD_WIDTH) => last_word_re_firo(i), + -- OUTPUT + empty => empty_firo_ro(i), + read => read_ro_firo(i), + data_out(WORD_WIDTH) => last_word_firo_ro(i), + data_out(WORD_WIDTH-1 downto 0) => data_firo_ro(i), + -- MISC + free => open + ); + end generate; + end generate; + + + rtps_out_inst : entity work.rtps_out(arch) + generic map ( + RTPS_OUT_WIDTH => 3 + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- INPUT + empty => empty_firo_ro, + rd => read_ro_firo, + data_in => data_firo_ro, + last_word_in => last_word_firo_ro, + -- OUTPUT + full => full, + wr => write, + data_out => data_out + ); + + + -- ######GENERATED START###### + + Type1_ros_sub_inst : entity work.Type1_ros_sub(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- FROM DDS READER + start_dds => start_ri_dr(0), + ack_dds => ack_dr_ri(0), + opcode_dds => opcode_ri_dr(0), + instance_state_dds => instance_state_ri_dr(0), + view_state_dds => view_state_ri_dr(0), + sample_state_dds => sample_state_ri_dr(0), + instance_handle_dds => instance_handle_ri_dr(0), + max_samples_dds => max_samples_ri_dr(0), + get_data_dds => get_data_ri_dr(0), + done_dds => done_dr_ri(0), + return_code_dds => return_code_dr_ri(0), + valid_in_dds => valid_dr_ri(0), + ready_in_dds => ready_ri_dr(0), + data_in_dds => data_dr_ri(0), + last_word_in_dds => last_word_dr_ri(0), + sample_info_dds => sample_info_dr_ri(0), + sample_info_valid_dds => sample_info_valid_dr_ri(0), + sample_info_ack_dds => sample_info_ack_ri_dr(0), + eoc_dds => eoc_dr_ri(0), + -- Communication Status + status_dds => status_dr_ri(0), + -- TO USER ENTITY + start_user => start_user_ri, + ack_user => ack_ri_user, + opcode_user => opcode_user_ri, + done_user => done_ri_user, + return_code_user => return_code_ri_user, + data_available_user => data_available_ri_user, + -- ###GENERATED START### + id => id_ri_user, + a => a_ri_user, + -- ###GENERATED END### + message_info_user => message_info_ri_user, + taken_user => taken_ri_user + ); + + Type1_ros_pub_inst : entity work.Type1_ros_pub(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- FROM DDS WRITER + start_dds => start_wi_dw(0), + ack_dds => ack_dw_wi(0), + opcode_dds => opcode_wi_dw(0), + instance_handle_in_dds => instance_handle_wi_dw(0), + source_ts_dds => source_ts_wi_dw(0), + max_wait_dds => max_wait_wi_dw(0), + done_dds => done_dw_wi(0), + return_code_dds => return_code_dw_wi(0), + instance_handle_out_dds => instance_handle_dw_wi(0), + valid_out_dds => valid_wi_dw(0), + ready_out_dds => ready_dw_wi(0), + data_out_dds => data_wi_dw(0), + last_word_out_dds => last_word_wi_dw(0), + valid_in_dds => valid_dw_wi(0), + ready_in_dds => ready_wi_dw(0), + data_in_dds => data_dw_wi(0), + last_word_in_dds => last_word_dw_wi(0), + -- Communication Status + status_dds => status_dw_wi(0), + -- TO USER ENTITY + start_user => start_user_wi, + ack_user => ack_wi_user, + opcode_user => opcode_user_wi, + -- ###GENERATED START### + id => id_user_wi, + a => a_user_wi, + -- ###GENERATED END### + done_user => done_wi_user, + return_code_user => return_code_wi_user + ); + + test_loopback_util_inst : entity work.test_loopback_util(arch) + port map( + clk => clk, + reset => reset, + input_util => input_util, + output_util => output_util, + start_r => start_user_ri, + opcode_r => opcode_user_ri, + ack_r => ack_ri_user, + done_r => done_ri_user, + return_code_r => return_code_ri_user, + data_available_r => data_available_ri_user, + id_r => id_ri_user, + a_r => a_ri_user, + message_info_r => message_info_ri_user, + taken_r => taken_ri_user, + start_w => start_user_wi, + opcode_w => opcode_user_wi, + ack_w => ack_wi_user, + id_w => id_user_wi, + a_w => a_user_wi, + done_w => done_wi_user, + return_code_w => return_code_wi_user + ); + + -- ######GENERATED END###### + +end architecture; diff --git a/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib6_config.vhd b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib6_config.vhd new file mode 100644 index 0000000..eea376b --- /dev/null +++ b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib6_config.vhd @@ -0,0 +1,98 @@ +-- altera vhdl_input_version vhdl_2008 +-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.rtps_package.all; +use work.ros_package.all; +use work.Type1_package.all; + +package ros_config is + + -- Period of ros system clock + constant ROS_CLOCK_PERIOD : time := 50 ns; + -- IPv4 Address of ROS System [Default 192.168.0.133] + constant ROS_ADDRESS : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := x"C0A80084"; + -- Random Key used to generate GUIDs + constant ROS_RAND_KEY : std_logic_vector(47 downto 0) := x"5BC9374EE750"; + + constant NUM_NODES : natural := 1; + + constant ROS_NODES : ROS_NODE_ARRAY_TYPE(0 to NUM_NODES-1) := ( + 0 => ( + name => gen_user_string("test_loopback_server"), + namespace => gen_user_string(""), + domain_id => 0, + NUM_PUBS => 1, + NUM_SUBS => 1, + NUM_SERVICES => 0, + NUM_ACTIONS => 0 + ) + ); + + constant NUM_PUBS : natural := get_num_pubs(ROS_NODES); + constant NUM_SUBS : natural := get_num_subs(ROS_NODES); + constant NUM_SERVICES : natural := get_num_services(ROS_NODES); + constant NUM_ACTIONS : natural := get_num_actions(ROS_NODES); + + constant ROS_PUBLICATIONS : ROS_TOPIC_ARRAY_TYPE(0 to NUM_PUBS-1) := ( + 0 => ( + node_id => 0, + TOPICNAME => gen_user_string("Loopback_2"), + TYPENAME => gen_user_string("tutorial_interfaces::msg::dds_::Type1_"), + QOS => ROS_QOS_PROFILE_TRANSIENT, + MAX_SIZE => MAX_TYPE1_SIZE + ) + ); + + constant ROS_SUBSCRIPTIONS : ROS_TOPIC_ARRAY_TYPE(0 to NUM_SUBS-1) := ( + 0 => ( + node_id => 0, + TOPICNAME => gen_user_string("Loopback_1"), + TYPENAME => gen_user_string("tutorial_interfaces::msg::dds_::Type1_"), + QOS => ROS_QOS_PROFILE_TRANSIENT, + MAX_SIZE => MAX_TYPE1_SIZE + ) + ); + + constant ROS_SERVICES : ROS_SERVICE_ARRAY_TYPE(0 to NUM_SERVICES-1) := ( + others => ( + node_id => 0, + SERVICENAME => gen_user_string(""), + RQ_TYPENAME => gen_user_string(""), + RR_TYPENAME => gen_user_string(""), + QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + MAX_RQ_SIZE => 0, + MAX_RR_SIZE => 0, + is_client => FALSE + ) + ); + + constant ROS_ACTIONS : ROS_ACTION_ARRAY_TYPE(0 to NUM_ACTIONS-1) := ( + others => ( + node_id => 0, + ACTIONNAME => gen_user_string(""), + GOAL_RQ_TYPENAME => gen_user_string(""), + GOAL_RR_TYPENAME => gen_user_string(""), + RESULT_RQ_TYPENAME => gen_user_string(""), + RESULT_RR_TYPENAME => gen_user_string(""), + FEEDBACK_TYPENAME => gen_user_string(""), + GOAL_QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + RESULT_QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + FEEDBACK_QOS => ROS_QOS_PROFILE_DEFAULT, + CANCEL_QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + MAX_GOAL_RQ_SIZE => 0, + MAX_GOAL_RR_SIZE => 0, + MAX_RESULT_RQ_SIZE => 0, + MAX_RESULT_RR_SIZE => 0, + MAX_FEEDBACK_SIZE => 0, + is_client => FALSE, + enable_feedback => TRUE + ) + ); + + -- Defines sensible RTPS timings for simulation + constant SIMULATION_TIMING : boolean := TRUE; +end package; \ No newline at end of file diff --git a/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib7.vhd b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib7.vhd new file mode 100644 index 0000000..a93bb52 --- /dev/null +++ b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib7.vhd @@ -0,0 +1,654 @@ +-- 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.ros_package.all; +use work.ros_config.all; +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; + +entity L2_Testbench_ROS_Lib7 is + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + time : in TIME_TYPE; + -- INPUT + empty : in std_logic; + read : out std_logic; + data_in : in std_logic_vector(WORD_WIDTH-1 downto 0); + -- OUTPUT + full : in std_logic; + write : out std_logic; + data_out : out std_logic_vector(WORD_WIDTH-1 downto 0); + -- READER + start_r : in std_logic; + opcode_r : in ROS_TOPIC_OPCODE_TYPE; + ack_r : out std_logic; + done_r : out std_logic; + return_code_r : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + data_available_r : out std_logic; + id_r : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a_r : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + message_info_r : out MESSAGE_INFO_TYPE; + taken_r : out std_logic; + -- WRITER + start_w : in std_logic; + opcode_w : in ROS_TOPIC_OPCODE_TYPE; + ack_w : out std_logic; + id_w : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a_w : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + done_w : out std_logic; + return_code_w : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) + ); +end entity; + +architecture arch of L2_Testbench_ROS_Lib7 is + + signal full_fire_rh, write_rh_fire : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal last_word_rh_firb, last_word_rh_fire : std_logic; + signal data_rh_fire, data_rh_firb : std_logic_vector(WORD_WIDTH-1 downto 0); + signal full_firb_rh, write_rh_firb : std_logic; + signal read_rb_firb, empty_firb_rb, last_word_firb_rb : std_logic; + signal data_firb_rb : std_logic_vector(WORD_WIDTH-1 downto 0); + signal read_re_fire, last_word_fire_re : std_logic_vector(0 to 1); + signal empty_fire_re : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal data_fire_re : WORD_ARRAY_TYPE(0 to 1); + signal alive_re_rb, full_frbre_re, write_rb_frbre : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal last_word_rb_frbre , last_word_rb_firo : std_logic; + signal data_rb_frbre , data_rb_firo : std_logic_vector(WORD_WIDTH-1 downto 0); + signal full_firo_rb, write_rb_firo : std_logic; + signal read_re_frbre, last_word_frbre_re : std_logic_vector(0 to 1); + signal empty_frbre_re : std_logic_vector(0 to NUM_ENDPOINTS-1); + signal data_frbre_re : WORD_ARRAY_TYPE(0 to 1); + signal full_firo_re, write_re_firo, last_word_re_firo : std_logic_vector(0 to 1); + signal data_re_firo : WORD_ARRAY_TYPE(0 to 1); + signal start_rr_dr, ack_dr_rr, done_dr_rr, valid_rr_dr, ready_dr_rr, last_word_rr_dr : std_logic_vector(0 to NUM_READERS-1); + signal opcode_rr_dr : HISTORY_CACHE_OPCODE_ARRAY_TYPE(0 to NUM_READERS-1); + signal ret_dr_rr : HISTORY_CACHE_RESPONSE_ARRAY_TYPE(0 to NUM_READERS-1); + signal data_rr_dr : WORD_ARRAY_TYPE(0 to NUM_READERS-1); + signal liveliness_assertion_dw_rw, data_available_dw_rw, start_rw_dw, ack_dw_rw, done_rw_dw, get_data_rw_dw, valid_dw_rw, ready_rw_dw, last_word_dw_rw : std_logic_vector(0 to NUM_WRITERS-1); + signal opcode_rw_dw : HISTORY_CACHE_OPCODE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal seq_nr_rw_dw, cc_seq_nr_dw_rw : SEQUENCENUMBER_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal ret_dw_rw : HISTORY_CACHE_RESPONSE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal data_dw_rw : WORD_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal cc_instance_handle_dw_rw : INSTANCE_HANDLE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal cc_kind_dw_rw : CACHE_CHANGE_KIND_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal cc_source_timestamp_dw_rw : TIME_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal sample_info_dr_ri : SAMPLE_INFO_ARRAY_TYPE(0 to NUM_READERS-1); + signal start_ri_dr, ack_dr_ri, get_data_ri_dr, done_dr_ri, ready_ri_dr, valid_dr_ri, sample_info_valid_dr_ri, sample_info_ack_ri_dr, eoc_dr_ri, last_word_dr_ri : std_logic_vector(0 to NUM_READERS-1); + signal opcode_ri_dr : DDS_READER_OPCODE_ARRAY_TYPE(0 to NUM_READERS-1); + signal instance_state_ri_dr : INSTANCE_STATE_ARRAY_TYPE(0 to NUM_READERS-1); + signal view_state_ri_dr : VIEW_STATE_ARRAY_TYPE(0 to NUM_READERS-1); + signal sample_state_ri_dr : SAMPLE_STATE_ARRAY_TYPE(0 to NUM_READERS-1); + signal instance_handle_ri_dr : INSTANCE_HANDLE_ARRAY_TYPE(0 to NUM_READERS-1); + signal max_samples_ri_dr : MAX_SAMPLES_ARRAY_TYPE(0 to NUM_READERS-1); + signal return_code_dr_ri : RETURN_CODE_ARRAY_TYPE(0 to NUM_READERS-1); + signal data_dr_ri : WORD_ARRAY_TYPE(0 to NUM_READERS-1); + signal status_dr_ri : STATUS_KIND_ARRAY_TYPE(0 to NUM_READERS-1); + signal start_wi_dw, ack_dw_wi, done_dw_wi, valid_wi_dw, valid_dw_wi, ready_wi_dw, ready_dw_wi, last_word_wi_dw, last_word_dw_wi : std_logic_vector(0 to NUM_WRITERS-1); + signal opcode_wi_dw : DDS_WRITER_OPCODE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal instance_handle_wi_dw, instance_handle_dw_wi : INSTANCE_HANDLE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal source_ts_wi_dw : TIME_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal max_wait_wi_dw : DURATION_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal return_code_dw_wi : RETURN_CODE_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal data_dw_wi, data_wi_dw : WORD_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal status_dw_wi : STATUS_KIND_ARRAY_TYPE(0 to NUM_WRITERS-1); + signal empty_firo_ro, read_ro_firo, last_word_firo_ro : std_logic_vector(0 to 2); + signal data_firo_ro : WORD_ARRAY_TYPE(0 to 2); + -- ###GENERATED START### + -- ###GENERATED END### + +begin + + + rtps_handler_inst : entity work.rtps_handler(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- INPUT + empty => empty, + rd => read, + data_in => data_in, + -- TO DISCOVERY MODULE + full_dm => full_firb_rh, + wr_dm => write_rh_firb, + data_out_dm => data_rh_firb, + last_word_out_dm => last_word_rh_firb, + -- TO USER ENDPOINTS + full_rtps => full_fire_rh, + wr_rtps => write_rh_fire, + data_out_rtps => data_rh_fire, + last_word_out_rtps => last_word_rh_fire + ); + + + fifo_in_rb_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1 + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_firb_rh, + write => write_rh_firb, + data_in(WORD_WIDTH-1 downto 0) => data_rh_firb, + data_in(WORD_WIDTH) => last_word_rh_firb, + -- OUTPUT + empty => empty_firb_rb, + read => read_rb_firb, + data_out(WORD_WIDTH-1 downto 0) => data_firb_rb, + data_out(WORD_WIDTH) => last_word_firb_rb, + -- MISC + free => open + ); + + fifo_in_re_r_if : if (NUM_READERS > 0) generate + fifo_in_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_READERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_fire_rh(0 to NUM_READERS-1), + write => write_rh_fire(0 to NUM_READERS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rh_fire, -- Multicast + data_in(WORD_WIDTH) => last_word_rh_fire, -- Multicast + -- OUTPUT + empty => empty_fire_re(0 to NUM_READERS-1), + read => read_re_fire(0), + data_out(WORD_WIDTH-1 downto 0) => data_fire_re(0), + data_out(WORD_WIDTH) => last_word_fire_re(0) + ); + end generate; + fifo_in_re_w_if : if (NUM_WRITERS > 0) generate + fifo_in_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_WRITERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_fire_rh(NUM_READERS to NUM_ENDPOINTS-1), + write => write_rh_fire(NUM_READERS to NUM_ENDPOINTS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rh_fire, -- Multicast + data_in(WORD_WIDTH) => last_word_rh_fire, -- Multicast + -- OUTPUT + empty => empty_fire_re(NUM_READERS to NUM_ENDPOINTS-1), + read => read_re_fire(1), + data_out(WORD_WIDTH-1 downto 0) => data_fire_re(1), + data_out(WORD_WIDTH) => last_word_fire_re(1) + ); + end generate; + + rtps_discovery_module_inst : entity work.rtps_discovery_module(arch) + generic map ( + MAX_REMOTE_PARTICIPANTS => MAX_REMOTE_PARTICIPANTS, + PREFER_MULTICAST => PREFER_MULTICAST_LOCATORS + ) + port map ( + clk => clk, + reset => reset, + time => time, + -- FROM RTPS HANDLER + empty => empty_firb_rb, + rd => read_rb_firb, + data_in => data_firb_rb, + last_word_in => last_word_firb_rb, + -- FROM USER ENDPOINTS + alive => alive_re_rb, + -- TO USER ENDPOINTS + full_rtps => full_frbre_re, + wr_rtps => write_rb_frbre, + data_out_rtps => data_rb_frbre, + last_word_out_rtps => last_word_rb_frbre, + -- TO RTPS OUT + full_ro => full_firo_rb, + wr_ro => write_rb_firo, + data_out_ro => data_rb_firo, + last_word_out_ro => last_word_rb_firo + ); + + fifo_rb_re_r_if : if (NUM_READERS > 0) generate + fifo_rb_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_READERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_frbre_re(0 to NUM_READERS-1), + write => write_rb_frbre(0 to NUM_READERS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rb_frbre, + data_in(WORD_WIDTH) => last_word_rb_frbre, + -- OUTPUT + empty => empty_frbre_re(0 to NUM_READERS-1), + read => read_re_frbre(0), + data_out(WORD_WIDTH-1 downto 0) => data_frbre_re(0), + data_out(WORD_WIDTH) => last_word_frbre_re(0) + ); + end generate; + fifo_rb_re_w_if : if (NUM_WRITERS > 0) generate + fifo_rb_re_inst : entity work.vector_FIFO + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1, + FIFO_WIDTH => NUM_WRITERS + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_frbre_re(NUM_READERS to NUM_ENDPOINTS-1), + write => write_rb_frbre(NUM_READERS to NUM_ENDPOINTS-1), + data_in(WORD_WIDTH-1 downto 0) => data_rb_frbre, + data_in(WORD_WIDTH) => last_word_rb_frbre, + -- OUTPUT + empty => empty_frbre_re(NUM_READERS to NUM_ENDPOINTS-1), + read => read_re_frbre(1), + data_out(WORD_WIDTH-1 downto 0) => data_frbre_re(1), + data_out(WORD_WIDTH) => last_word_frbre_re(1) + ); + end generate; + + + rtps_endpoint_r_if : if (NUM_READERS > 0) generate + rtps_reader_inst : entity work.rtps_reader(arch) + generic map ( + NUM_READERS => NUM_READERS, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(0 to NUM_READERS-1)), + ENTITYID => ENTITYID(0 to NUM_READERS-1), + MAX_REMOTE_ENDPOINTS => MAX_REMOTE_ENDPOINTS + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- FROM RTPS_HANDLER (USER TRAFFIC) + empty_user => empty_fire_re(0 to NUM_READERS-1), + rd_user => read_re_fire(0), + data_in_user => data_fire_re(0), + last_word_in_user => last_word_fire_re(0), + -- FROM DISCOVERY MODULE (META TRAFFIC) + empty_meta => empty_frbre_re(0 to NUM_READERS-1), + rd_meta => read_re_frbre(0), + data_in_meta => data_frbre_re(0), + last_word_in_meta => last_word_frbre_re(0), + -- RTPS OUTPUT + full_ro => full_firo_re(0), + wr_ro => write_re_firo(0), + data_out_ro => data_re_firo(0), + last_word_out_ro => last_word_re_firo(0), + -- TO HISTORY CACHE + start_hc => start_rr_dr(0 to NUM_READERS-1), + opcode_hc => opcode_rr_dr(0 to NUM_READERS-1), + ack_hc => ack_dr_rr(0 to NUM_READERS-1), + done_hc => done_dr_rr(0 to NUM_READERS-1), + ret_hc => ret_dr_rr(0 to NUM_READERS-1), + valid_out_hc => valid_rr_dr(0 to NUM_READERS-1), + ready_out_hc => ready_dr_rr(0 to NUM_READERS-1), + data_out_hc => data_rr_dr(0 to NUM_READERS-1), + last_word_out_hc => last_word_rr_dr(0 to NUM_READERS-1) + ); + + -- Set Alive Signals of Readers to Zero + alive_re_rb(0 to NUM_READERS-1) <= (others => '0'); + end generate; + + rtps_endpoint_w_if : if (NUM_WRITERS > 0) generate + rtps_writer_inst : entity work.rtps_writer(arch) + generic map ( + NUM_WRITERS => NUM_WRITERS, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(NUM_READERS to NUM_ENDPOINTS-1)), + ENTITYID => ENTITYID(NUM_READERS to NUM_ENDPOINTS-1), + INLINE_QOS => INLINE_QOS_DATA(0 to NUM_WRITERS-1), + MAX_REMOTE_ENDPOINTS => MAX_REMOTE_ENDPOINTS + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- FROM RTPS_HANDLER (USER TRAFFIC) + empty_user => empty_fire_re(NUM_READERS to NUM_ENDPOINTS-1), + rd_user => read_re_fire(1), + data_in_user => data_fire_re(1), + last_word_in_user => last_word_fire_re(1), + -- FROM DISCOVERY MODULE (META TRAFFIC) + empty_meta => empty_frbre_re(NUM_READERS to NUM_ENDPOINTS-1), + rd_meta => read_re_frbre(1), + data_in_meta => data_frbre_re(1), + last_word_in_meta => last_word_frbre_re(1), + -- TO DISCOVERY MODULE (META TRAFFIC) + alive_sig => alive_re_rb(NUM_READERS to NUM_ENDPOINTS-1), + -- RTPS OUTPUT + full_ro => full_firo_re(1), + wr_ro => write_re_firo(1), + data_out_ro => data_re_firo(1), + last_word_out_ro => last_word_re_firo(1), + -- FROM HC + liveliness_assertion => liveliness_assertion_dw_rw(0 to NUM_WRITERS-1), + data_available => data_available_dw_rw(0 to NUM_WRITERS-1), + start_hc => start_rw_dw(0 to NUM_WRITERS-1), + opcode_hc => opcode_rw_dw(0 to NUM_WRITERS-1), + ack_hc => ack_dw_rw(0 to NUM_WRITERS-1), + seq_nr_hc => seq_nr_rw_dw(0 to NUM_WRITERS-1), + done_hc => done_rw_dw(0 to NUM_WRITERS-1), + ret_hc => ret_dw_rw(0 to NUM_WRITERS-1), + get_data_hc => get_data_rw_dw(0 to NUM_WRITERS-1), + valid_in_hc => valid_dw_rw(0 to NUM_WRITERS-1), + ready_in_hc => ready_rw_dw(0 to NUM_WRITERS-1), + data_in_hc => data_dw_rw(0 to NUM_WRITERS-1), + last_word_in_hc => last_word_dw_rw(0 to NUM_WRITERS-1), + cc_instance_handle => cc_instance_handle_dw_rw(0 to NUM_WRITERS-1), + cc_kind => cc_kind_dw_rw(0 to NUM_WRITERS-1), + cc_source_timestamp => cc_source_timestamp_dw_rw(0 to NUM_WRITERS-1), + cc_seq_nr => cc_seq_nr_dw_rw(0 to NUM_WRITERS-1) + ); + end generate; + + dds_endpoint_w_if : if (NUM_WRITERS > 1) generate + dds_writer_inst : entity work.dds_writer(arch) + generic map ( + NUM_WRITERS => NUM_WRITERS-1, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(NUM_READERS to NUM_ENDPOINTS-2)) + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- TO/FROM RTPS ENDPOINT + start_rtps => start_rw_dw(0 to NUM_WRITERS-2), + opcode_rtps => opcode_rw_dw(0 to NUM_WRITERS-2), + ack_rtps => ack_dw_rw(0 to NUM_WRITERS-2), + done_rtps => done_rw_dw(0 to NUM_WRITERS-2), + ret_rtps => ret_dw_rw(0 to NUM_WRITERS-2), + seq_nr_rtps => seq_nr_rw_dw(0 to NUM_WRITERS-2), + get_data_rtps => get_data_rw_dw(0 to NUM_WRITERS-2), + valid_out_rtps => valid_dw_rw(0 to NUM_WRITERS-2), + ready_out_rtps => ready_rw_dw(0 to NUM_WRITERS-2), + data_out_rtps => data_dw_rw(0 to NUM_WRITERS-2), + last_word_out_rtps => last_word_dw_rw(0 to NUM_WRITERS-2), + liveliness_assertion => liveliness_assertion_dw_rw(0 to NUM_WRITERS-2), + data_available => data_available_dw_rw(0 to NUM_WRITERS-2), + -- Cache Change + cc_instance_handle => cc_instance_handle_dw_rw(0 to NUM_WRITERS-2), + cc_kind => cc_kind_dw_rw(0 to NUM_WRITERS-2), + cc_source_timestamp => cc_source_timestamp_dw_rw(0 to NUM_WRITERS-2), + cc_seq_nr => cc_seq_nr_dw_rw(0 to NUM_WRITERS-2), + -- TO/FROM USER ENTITY + start_dds => start_wi_dw(0 to NUM_WRITERS-2), + ack_dds => ack_dw_wi(0 to NUM_WRITERS-2), + opcode_dds => opcode_wi_dw(0 to NUM_WRITERS-2), + instance_handle_in_dds => instance_handle_wi_dw(0 to NUM_WRITERS-2), + source_ts_dds => source_ts_wi_dw(0 to NUM_WRITERS-2), + max_wait_dds => max_wait_wi_dw(0 to NUM_WRITERS-2), + done_dds => done_dw_wi(0 to NUM_WRITERS-2), + return_code_dds => return_code_dw_wi(0 to NUM_WRITERS-2), + instance_handle_out_dds => instance_handle_dw_wi(0 to NUM_WRITERS-2), + valid_in_dds => valid_wi_dw(0 to NUM_WRITERS-2), + ready_in_dds => ready_dw_wi(0 to NUM_WRITERS-2), + data_in_dds => data_wi_dw(0 to NUM_WRITERS-2), + last_word_in_dds => last_word_wi_dw(0 to NUM_WRITERS-2), + valid_out_dds => valid_dw_wi(0 to NUM_WRITERS-2), + ready_out_dds => ready_wi_dw(0 to NUM_WRITERS-2), + data_out_dds => data_dw_wi(0 to NUM_WRITERS-2), + last_word_out_dds => last_word_dw_wi(0 to NUM_WRITERS-2), + -- Communication Status + status => status_dw_wi(0 to NUM_WRITERS-2) + ); + end generate; + dds_endpoint_r_if : if (NUM_READERS > 0) generate + dds_reader_inst : entity work.dds_reader(arch) + generic map ( + NUM_READERS => NUM_READERS, + CONFIG_ARRAY => to_QUARTUS_CONFIG_ARRAY_TYPE(ENDPOINT_CONFIG(0 to NUM_READERS-1)), + MAX_REMOTE_ENDPOINTS => MAX_REMOTE_ENDPOINTS + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + time => time, + -- FROM RTPS ENDPOINT + start_rtps => start_rr_dr(0 to NUM_READERS-1), + opcode_rtps => opcode_rr_dr(0 to NUM_READERS-1), + ack_rtps => ack_dr_rr(0 to NUM_READERS-1), + done_rtps => done_dr_rr(0 to NUM_READERS-1), + ret_rtps => ret_dr_rr(0 to NUM_READERS-1), + valid_in_rtps => valid_rr_dr(0 to NUM_READERS-1), + ready_in_rtps => ready_dr_rr(0 to NUM_READERS-1), + data_in_rtps => data_rr_dr(0 to NUM_READERS-1), + last_word_in_rtps => last_word_rr_dr(0 to NUM_READERS-1), + -- TO USER ENTITY + start_dds => start_ri_dr(0 to NUM_READERS-1), + ack_dds => ack_dr_ri(0 to NUM_READERS-1), + opcode_dds => opcode_ri_dr(0 to NUM_READERS-1), + instance_state_dds => instance_state_ri_dr(0 to NUM_READERS-1), + view_state_dds => view_state_ri_dr(0 to NUM_READERS-1), + sample_state_dds => sample_state_ri_dr(0 to NUM_READERS-1), + instance_handle_dds => instance_handle_ri_dr(0 to NUM_READERS-1), + max_samples_dds => max_samples_ri_dr(0 to NUM_READERS-1), + get_data_dds => get_data_ri_dr(0 to NUM_READERS-1), + done_dds => done_dr_ri(0 to NUM_READERS-1), + return_code_dds => return_code_dr_ri(0 to NUM_READERS-1), + valid_out_dds => valid_dr_ri(0 to NUM_READERS-1), + ready_out_dds => ready_ri_dr(0 to NUM_READERS-1), + data_out_dds => data_dr_ri(0 to NUM_READERS-1), + last_word_out_dds => last_word_dr_ri(0 to NUM_READERS-1), + sample_info => sample_info_dr_ri(0 to NUM_READERS-1), + sample_info_valid => sample_info_valid_dr_ri(0 to NUM_READERS-1), + sample_info_ack => sample_info_ack_ri_dr(0 to NUM_READERS-1), + eoc => eoc_dr_ri(0 to NUM_READERS-1), + -- Communication Status + status => status_dr_ri(0 to NUM_READERS-1) + ); + end generate; + + + ros_discovery_writer_inst : entity work.ros_static_discovery_writer(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- TO/FROM RTPS ENDPOINT + start => start_rw_dw(NUM_WRITERS-1), + opcode => opcode_rw_dw(NUM_WRITERS-1), + ack => ack_dw_rw(NUM_WRITERS-1), + done => done_rw_dw(NUM_WRITERS-1), + ret => ret_dw_rw(NUM_WRITERS-1), + seq_nr => seq_nr_rw_dw(NUM_WRITERS-1), + get_data => get_data_rw_dw(NUM_WRITERS-1), + valid_out => valid_dw_rw(NUM_WRITERS-1), + ready_out => ready_rw_dw(NUM_WRITERS-1), + data_out => data_dw_rw(NUM_WRITERS-1), + last_word_out => last_word_dw_rw(NUM_WRITERS-1), + liveliness_assertion => liveliness_assertion_dw_rw(NUM_WRITERS-1), + data_available => data_available_dw_rw(NUM_WRITERS-1), + -- Cache Change + cc_instance_handle => cc_instance_handle_dw_rw(NUM_WRITERS-1), + cc_kind => cc_kind_dw_rw(NUM_WRITERS-1), + cc_source_timestamp => cc_source_timestamp_dw_rw(NUM_WRITERS-1), + cc_seq_nr => cc_seq_nr_dw_rw(NUM_WRITERS-1) + ); + + + fifo_in_ro_gen : for i in 0 to 2 generate + fifo_in_ro_if : if (i = 2) generate + fifo_in_ro_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1 + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_firo_rb, + write => write_rb_firo, + data_in(WORD_WIDTH-1 downto 0) => data_rb_firo, + data_in(WORD_WIDTH) => last_word_rb_firo, + -- OUTPUT + empty => empty_firo_ro(i), + read => read_ro_firo(i), + data_out(WORD_WIDTH) => last_word_firo_ro(i), + data_out(WORD_WIDTH-1 downto 0) => data_firo_ro(i), + -- MISC + free => open + ); + else generate + fifo_in_ro_inst : configuration work.FWFT_FIFO_cfg + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1 + ) + port map ( + -- SYSTEM + reset => reset, + clk => clk, + -- INPUT + full => full_firo_re(i), + write => write_re_firo(i), + data_in(WORD_WIDTH-1 downto 0) => data_re_firo(i), + data_in(WORD_WIDTH) => last_word_re_firo(i), + -- OUTPUT + empty => empty_firo_ro(i), + read => read_ro_firo(i), + data_out(WORD_WIDTH) => last_word_firo_ro(i), + data_out(WORD_WIDTH-1 downto 0) => data_firo_ro(i), + -- MISC + free => open + ); + end generate; + end generate; + + + rtps_out_inst : entity work.rtps_out(arch) + generic map ( + RTPS_OUT_WIDTH => 3 + ) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- INPUT + empty => empty_firo_ro, + rd => read_ro_firo, + data_in => data_firo_ro, + last_word_in => last_word_firo_ro, + -- OUTPUT + full => full, + wr => write, + data_out => data_out + ); + + + -- ######GENERATED START###### + + Type1_ros_sub_inst : entity work.Type1_ros_sub(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- FROM DDS READER + start_dds => start_ri_dr(0), + ack_dds => ack_dr_ri(0), + opcode_dds => opcode_ri_dr(0), + instance_state_dds => instance_state_ri_dr(0), + view_state_dds => view_state_ri_dr(0), + sample_state_dds => sample_state_ri_dr(0), + instance_handle_dds => instance_handle_ri_dr(0), + max_samples_dds => max_samples_ri_dr(0), + get_data_dds => get_data_ri_dr(0), + done_dds => done_dr_ri(0), + return_code_dds => return_code_dr_ri(0), + valid_in_dds => valid_dr_ri(0), + ready_in_dds => ready_ri_dr(0), + data_in_dds => data_dr_ri(0), + last_word_in_dds => last_word_dr_ri(0), + sample_info_dds => sample_info_dr_ri(0), + sample_info_valid_dds => sample_info_valid_dr_ri(0), + sample_info_ack_dds => sample_info_ack_ri_dr(0), + eoc_dds => eoc_dr_ri(0), + -- Communication Status + status_dds => status_dr_ri(0), + -- TO USER ENTITY + start_user => start_r, + ack_user => ack_r, + opcode_user => opcode_r, + done_user => done_r, + return_code_user => return_code_r, + data_available_user => data_available_r, + -- ###GENERATED START### + id => id_r, + a => a_r, + -- ###GENERATED END### + message_info_user => message_info_r, + taken_user => taken_r + ); + + Type1_ros_pub_inst : entity work.Type1_ros_pub(arch) + port map ( + -- SYSTEM + clk => clk, + reset => reset, + -- FROM DDS WRITER + start_dds => start_wi_dw(0), + ack_dds => ack_dw_wi(0), + opcode_dds => opcode_wi_dw(0), + instance_handle_in_dds => instance_handle_wi_dw(0), + source_ts_dds => source_ts_wi_dw(0), + max_wait_dds => max_wait_wi_dw(0), + done_dds => done_dw_wi(0), + return_code_dds => return_code_dw_wi(0), + instance_handle_out_dds => instance_handle_dw_wi(0), + valid_out_dds => valid_wi_dw(0), + ready_out_dds => ready_dw_wi(0), + data_out_dds => data_wi_dw(0), + last_word_out_dds => last_word_wi_dw(0), + valid_in_dds => valid_dw_wi(0), + ready_in_dds => ready_wi_dw(0), + data_in_dds => data_dw_wi(0), + last_word_in_dds => last_word_dw_wi(0), + -- Communication Status + status_dds => status_dw_wi(0), + -- TO USER ENTITY + start_user => start_w, + ack_user => ack_w, + opcode_user => opcode_w, + -- ###GENERATED START### + id => id_w, + a => a_w, + -- ###GENERATED END### + done_user => done_w, + return_code_user => return_code_w + ); + + -- ######GENERATED END###### + +end architecture; diff --git a/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib7_config.vhd b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib7_config.vhd new file mode 100644 index 0000000..d47e7f3 --- /dev/null +++ b/src/ros2/Tests/Level_2/L2_Testbench_ROS_Lib7_config.vhd @@ -0,0 +1,98 @@ +-- altera vhdl_input_version vhdl_2008 +-- XXX: QSYS Fix (https://www.intel.com/content/www/us/en/support/programmable/articles/000079458.html) + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.rtps_package.all; +use work.ros_package.all; +use work.Type1_package.all; + +package ros_config is + + -- Period of ros system clock + constant ROS_CLOCK_PERIOD : time := 50 ns; + -- IPv4 Address of ROS System [Default 192.168.0.134] + constant ROS_ADDRESS : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := x"C0A80085"; + -- Random Key used to generate GUIDs + constant ROS_RAND_KEY : std_logic_vector(47 downto 0) := x"8BD9DA5FB97D"; + + constant NUM_NODES : natural := 1; + + constant ROS_NODES : ROS_NODE_ARRAY_TYPE(0 to NUM_NODES-1) := ( + 0 => ( + name => gen_user_string("test_loopback_client"), + namespace => gen_user_string(""), + domain_id => 0, + NUM_PUBS => 1, + NUM_SUBS => 1, + NUM_SERVICES => 0, + NUM_ACTIONS => 0 + ) + ); + + constant NUM_PUBS : natural := get_num_pubs(ROS_NODES); + constant NUM_SUBS : natural := get_num_subs(ROS_NODES); + constant NUM_SERVICES : natural := get_num_services(ROS_NODES); + constant NUM_ACTIONS : natural := get_num_actions(ROS_NODES); + + constant ROS_PUBLICATIONS : ROS_TOPIC_ARRAY_TYPE(0 to NUM_PUBS-1) := ( + 0 => ( + node_id => 0, + TOPICNAME => gen_user_string("Loopback_1"), + TYPENAME => gen_user_string("tutorial_interfaces::msg::dds_::Type1_"), + QOS => ROS_QOS_PROFILE_TRANSIENT, + MAX_SIZE => MAX_TYPE1_SIZE + ) + ); + + constant ROS_SUBSCRIPTIONS : ROS_TOPIC_ARRAY_TYPE(0 to NUM_SUBS-1) := ( + 0 => ( + node_id => 0, + TOPICNAME => gen_user_string("Loopback_2"), + TYPENAME => gen_user_string("tutorial_interfaces::msg::dds_::Type1_"), + QOS => ROS_QOS_PROFILE_TRANSIENT, + MAX_SIZE => MAX_TYPE1_SIZE + ) + ); + + constant ROS_SERVICES : ROS_SERVICE_ARRAY_TYPE(0 to NUM_SERVICES-1) := ( + others => ( + node_id => 0, + SERVICENAME => gen_user_string(""), + RQ_TYPENAME => gen_user_string(""), + RR_TYPENAME => gen_user_string(""), + QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + MAX_RQ_SIZE => 0, + MAX_RR_SIZE => 0, + is_client => FALSE + ) + ); + + constant ROS_ACTIONS : ROS_ACTION_ARRAY_TYPE(0 to NUM_ACTIONS-1) := ( + others => ( + node_id => 0, + ACTIONNAME => gen_user_string(""), + GOAL_RQ_TYPENAME => gen_user_string(""), + GOAL_RR_TYPENAME => gen_user_string(""), + RESULT_RQ_TYPENAME => gen_user_string(""), + RESULT_RR_TYPENAME => gen_user_string(""), + FEEDBACK_TYPENAME => gen_user_string(""), + GOAL_QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + RESULT_QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + FEEDBACK_QOS => ROS_QOS_PROFILE_DEFAULT, + CANCEL_QOS => ROS_QOS_PROFILE_SERVICES_DEFAULT, + MAX_GOAL_RQ_SIZE => 0, + MAX_GOAL_RR_SIZE => 0, + MAX_RESULT_RQ_SIZE => 0, + MAX_RESULT_RR_SIZE => 0, + MAX_FEEDBACK_SIZE => 0, + is_client => FALSE, + enable_feedback => TRUE + ) + ); + + -- Defines sensible RTPS timings for simulation + constant SIMULATION_TIMING : boolean := TRUE; +end package; \ No newline at end of file diff --git a/src/ros2/Tests/Type1.idl b/src/ros2/Tests/Type1.idl new file mode 100644 index 0000000..61020e3 --- /dev/null +++ b/src/ros2/Tests/Type1.idl @@ -0,0 +1,5 @@ +@extensibility(FINAL) +struct Type1 { + long id; + long a; +}; \ No newline at end of file diff --git a/src/ros2/Tests/Type1_package.vhd b/src/ros2/Tests/Type1_package.vhd new file mode 100644 index 0000000..eb30cc0 --- /dev/null +++ b/src/ros2/Tests/Type1_package.vhd @@ -0,0 +1,14 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.math_pkg.all; +use work.rtps_package.all; + +package Type1_package is + + constant MAX_ID_SIZE : natural := 4; + constant MAX_A_SIZE : natural := 4; -- 8 + constant MAX_TYPE1_SIZE : natural := 8 + RTPS_PAYLOAD_HEADER_SIZE; + +end package; \ No newline at end of file diff --git a/src/ros2/Tests/Type1_ros_pub.vhd b/src/ros2/Tests/Type1_ros_pub.vhd new file mode 100644 index 0000000..6f1b8ed --- /dev/null +++ b/src/ros2/Tests/Type1_ros_pub.vhd @@ -0,0 +1,269 @@ +-- 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; +use work.Type1_package.all; + +entity Type1_ros_pub is + generic ( + LITTLE_ENDIAN : std_logic := '0' + ); + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- FROM DDS WRITER + start_dds : out std_logic; + ack_dds : in std_logic; + opcode_dds : out DDS_WRITER_OPCODE_TYPE; + instance_handle_in_dds : out INSTANCE_HANDLE_TYPE; + source_ts_dds : out TIME_TYPE; + max_wait_dds : out DURATION_TYPE; + done_dds : in std_logic; + return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + instance_handle_out_dds : in INSTANCE_HANDLE_TYPE; + valid_out_dds : out std_logic; + ready_out_dds : in std_logic; + data_out_dds : out std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_out_dds : out std_logic; + valid_in_dds : in std_logic; + ready_in_dds : out std_logic; + data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_dds : in std_logic; + -- Communication Status + status_dds : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + + -- TO USER ENTITY + start_user : in std_logic; + opcode_user : in ROS_TOPIC_OPCODE_TYPE; + ack_user : out std_logic; + + -- ###GENERATED START### + id : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + -- ###GENERATED END### + + done_user : out std_logic; + return_code_user : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) + ); +end entity; + +architecture arch of Type1_ros_pub is + + --*****TYPE DECLARATION***** + -- FSM states. Explained below in detail + type STAGE_TYPE is (IDLE,INITIATE_WRITE,WRITE_PAYLOAD_HEADER,PUSH,ALIGN_STREAM,ENCODE_PAYLOAD,WAIT_FOR_WRITER,RETURN_ROS); + -- ###GENERATED START### + type ENCODE_STAGE_TYPE is (WRITE_ID, WRITE_A); + -- ###GENERATED END### + + -- *MAIN PROCESS* + signal stage, stage_next : STAGE_TYPE; + signal cnt, cnt_next : natural range 0 to 5; + 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_out_latch, data_out_latch_next : std_logic_vector(WORD_WIDTH-1 downto 0); + signal abort_mem : std_logic; + signal finalize_payload, finalize_payload_next : std_logic; + signal return_code_latch, return_code_latch_next : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + signal encode_stage, encode_stage_next : ENCODE_STAGE_TYPE; + + +begin + + -- PASSTHROUGH + instance_handle_in_dds <= HANDLE_NIL; + source_ts_dds <= TIME_INVALID; + max_wait_dds <= DURATION_ZERO; + ready_in_dds <= '0'; -- DDS Writer Input is unused + -- ###GENERATED START### + -- PORT SIGNAL CONNECTIONS + -- ###GENERATED END### + + main_prc : process (all) + begin + -- DEFAULT + stage_next <= stage; + encode_stage_next <= encode_stage; + cnt_next <= cnt; + align_offset_next <= align_offset; + align_op_next <= align_op; + target_align_next <= target_align; + data_out_latch_next <= data_out_latch; + finalize_payload_next <= finalize_payload; + return_code_latch_next <= return_code_latch; + abort_mem <= '0'; + start_dds <= '0'; + opcode_dds <= NOP; + valid_out_dds <= '0'; + last_word_out_dds <= '0'; + ack_user <= '0'; + done_user <= '0'; + return_code_user <= ROS_RET_OK; + data_out_dds <= (others => '0'); + + case (stage) is + when IDLE => + if (start_user = '1') then + ack_user <= '1'; + case (opcode_user) is + when PUBLISH => + stage_next <= INITIATE_WRITE; + when others => + return_code_latch_next <= ROS_RET_UNSUPPORTED; + stage_next <= RETURN_ROS; + end case; + -- RESET + abort_mem <= '1'; + else + null; + end if; + when RETURN_ROS => + done_user <= '1'; + return_code_user <= return_code_latch; + + -- DONE + stage_next <= IDLE; + when INITIATE_WRITE => + start_dds <= '1'; + opcode_dds <= WRITE; + + if (ack_dds = '1') then + stage_next <= WRITE_PAYLOAD_HEADER; + end if; + + when WRITE_PAYLOAD_HEADER => + valid_out_dds <= '1'; + if (LITTLE_ENDIAN = '0') then + data_out_dds <= CDR_BE & x"0000"; + else + data_out_dds <= CDR_LE & x"0000"; + end if; + -- Output Guard + if (ready_out_dds = '1') then + stage_next <= ENCODE_PAYLOAD; + -- Reset + align_offset_next <= (others => '0'); + data_out_latch_next <= (others => '0'); + -- ###GENERATED START### + encode_stage_next <= WRITE_ID; + -- ###GENERATED END### + end if; + when PUSH => + -- Mark Last Word + if (finalize_payload = '1') then + last_word_out_dds <= '1'; + end if; + + valid_out_dds <= '1'; + data_out_dds <= data_out_latch; + -- Output Guard + if (ready_out_dds = '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_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_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 + -- ###GENERATED START### + when WRITE_ID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + data_out_latch_next <= endian_swap(LITTLE_ENDIAN,id); + align_offset_next <= align_offset + 4; + stage_next <= PUSH; + -- Next Member + encode_stage_next <= WRITE_A; + end if; + when WRITE_A => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + data_out_latch_next <= endian_swap(LITTLE_ENDIAN,a); + align_offset_next <= align_offset + 4; + -- DONE + stage_next <= PUSH; + finalize_payload_next <= '1'; + end if; + -- ###GENERATED END### + when others => + null; + end case; + when WAIT_FOR_WRITER => + if (done_dds = '1') then + case (return_code_dds) 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; + end case; + end process; + + sync_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + stage <= IDLE; + encode_stage <= WRITE_ID; + target_align <= ALIGN_1; + return_code_latch <= ROS_RET_OK; + cnt <= 0; + finalize_payload <= '0'; + align_op <= '0'; + align_offset <= (others => '0'); + data_out_latch <= (others => '0'); + else + stage <= stage_next; + encode_stage <= encode_stage_next; + target_align <= target_align_next; + return_code_latch <= return_code_latch_next; + cnt <= cnt_next; + finalize_payload <= finalize_payload_next; + align_op <= align_op_next; + align_offset <= align_offset_next; + data_out_latch <= data_out_latch_next; + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/ros2/Tests/Type1_ros_sub.vhd b/src/ros2/Tests/Type1_ros_sub.vhd new file mode 100644 index 0000000..5cd7dbf --- /dev/null +++ b/src/ros2/Tests/Type1_ros_sub.vhd @@ -0,0 +1,440 @@ +-- 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; +use work.Type1_package.all; + +entity Type1_ros_sub is + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- FROM DDS READER + start_dds : out std_logic; + ack_dds : in std_logic; + opcode_dds : out DDS_READER_OPCODE_TYPE; + instance_state_dds : out std_logic_vector(INSTANCE_STATE_KIND_WIDTH-1 downto 0); + view_state_dds : out std_logic_vector(VIEW_STATE_KIND_WIDTH-1 downto 0); + sample_state_dds : out std_logic_vector(SAMPLE_STATE_KIND_WIDTH-1 downto 0); + instance_handle_dds : out INSTANCE_HANDLE_TYPE; + max_samples_dds : out std_logic_vector(MAX_SAMPLES_WIDTH-1 downto 0); + get_data_dds : out std_logic; + done_dds : in std_logic; + return_code_dds : in std_logic_vector(RETURN_CODE_WIDTH-1 downto 0); + valid_in_dds : in std_logic; + ready_in_dds : out std_logic; + data_in_dds : in std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in_dds : in std_logic; + sample_info_dds : in SAMPLE_INFO_TYPE; + sample_info_valid_dds : in std_logic; + sample_info_ack_dds : out std_logic; + eoc_dds : in std_logic; + -- Communication Status + status_dds : in std_logic_vector(STATUS_KIND_WIDTH-1 downto 0); + + -- TO USER ENTITY + start_user : in std_logic; + opcode_user : in ROS_TOPIC_OPCODE_TYPE; + ack_user : out std_logic; + + done_user : out std_logic; + return_code_user : out std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + + data_available_user : out std_logic; + + -- ###GENERATED START### + id : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + -- ###GENERATED END### + message_info_user : out MESSAGE_INFO_TYPE; + taken_user : out std_logic + ); +end entity; + +architecture arch of Type1_ros_sub is + + --*****TYPE DECLARATION***** + -- FSM states. Explained below in detail + type STAGE_TYPE is (IDLE,INITIATE_READ,WAIT_FOR_READER,WAIT_FOR_DATA,GET_PAYLOAD_HEADER,FETCH,ALIGN_STREAM,SKIP_PAYLOAD,DECODE_PAYLOAD,RETURN_ROS); + -- ###GENERATED START### + type DECODE_STAGE_TYPE is (GET_ID, GET_A, GET_OPTIONAL_HEADER); + -- ###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 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 abort_mem : std_logic; + signal ready_in_dds_sig : std_logic; + signal taken_sig, taken_sig_next : std_logic; + signal data_available_sig, data_available_sig_next : std_logic; + signal message_info_sig, message_info_sig_next : MESSAGE_INFO_TYPE; + signal return_code_latch, return_code_latch_next : std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + signal decode_stage, decode_stage_next : DECODE_STAGE_TYPE; + signal return_stage, return_stage_next : DECODE_STAGE_TYPE; + -- ###GENERATED START### + signal id_latch, id_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + signal a_latch, a_latch_next : std_logic_vector(CDR_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_dds(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_dds(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 + + -- PASSTHROUGH + taken_user <= taken_sig; + ready_in_dds <= ready_in_dds_sig; + message_info_user <= message_info_sig; + data_available_user <= data_available_sig; + instance_state_dds <= ANY_INSTANCE_STATE; + view_state_dds <= ANY_VIEW_STATE; + sample_state_dds <= ANY_SAMPLE_STATE; + instance_handle_dds <= HANDLE_NIL; + max_samples_dds <= (others => '0'); + -- ###GENERATED START### + id <= id_latch; + a <= a_latch; + -- ###GENERATED END### + + + main_prc : process (all) + variable tmp_length : unsigned(WORD_WIDTH-1 downto 0); + begin + -- DEFAULT + stage_next <= 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; + optional_next <= optional; + taken_sig_next <= taken_sig; + data_in_latch_next <= data_in_latch; + align_op_next <= align_op; + data_available_sig_next <= data_available_sig; + return_code_latch_next <= return_code_latch; + message_info_sig_next <= message_info_sig; + abort_mem <= '0'; + ready_in_dds_sig <= '0'; + sample_info_ack_dds <= '0'; + get_data_dds <= '0'; + start_dds <= '0'; + opcode_dds <= NOP; + ack_user <= '0'; + done_user <= '0'; + return_code_user <= ROS_RET_OK; + -- ###GENERATED START### + id_latch_next <= id_latch; + a_latch_next <= a_latch; + -- ###GENERATED END### + + -- Last Word Latch Setter + if (last_word_in_dds = '1' and valid_in_dds = '1') then + last_word_in_latch_next <= '1'; + end if; + -- Data Available Setter + if (check_mask(status_dds, 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 => + 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 + null; + end if; + when RETURN_ROS => + done_user <= '1'; + return_code_user <= return_code_latch; + + -- DONE + stage_next <= IDLE; + when INITIATE_READ => + start_dds <= '1'; + opcode_dds <= TAKE_NEXT_SAMPLE; + + if (ack_dds = '1') then + stage_next <= WAIT_FOR_READER; + end if; + when WAIT_FOR_READER => + if (done_dds = '1') then + case (return_code_dds) 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 (sample_info_valid_dds = '1') then + sample_info_ack_dds <= '1'; + -- Meta Sample + if (sample_info_dds.valid_data = '0') then + -- Ignore and read Next Sample + stage_next <= INITIATE_READ; + else + get_data_dds <= '1'; + stage_next <= GET_PAYLOAD_HEADER; + + message_info_sig_next.publisher_gid <= to_gid(GUID_UNKNOWN); + message_info_sig_next.received_timestamp <= TIME_INVALID; + message_info_sig_next.source_timestamp <= sample_info_dds.source_timestamp; + end if; + end if; + when GET_PAYLOAD_HEADER => + -- TODO: Latch Offset from Options Field? + + ready_in_dds_sig <= '1'; + -- Input Guard + if (valid_in_dds = '1') then + case (representation_id) is + when CDR_BE => + endian_flag_next <= '0'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + -- ###GENERATED START### + decode_stage_next <= GET_ID; + -- ###GENERATED END### + -- Initial Fetch + when CDR_LE => + endian_flag_next <= '1'; + stage_next <= FETCH; + -- Alignment Reset + align_offset_next <= (others => '0'); + -- ###GENERATED START### + decode_stage_next <= GET_ID; + -- ###GENERATED END### + when others => + -- Unknown Payload Encoding + stage_next <= SKIP_PAYLOAD; + decode_error_latch_next <= '1'; + end case; + end if; + when FETCH => + ready_in_dds_sig <= '1'; + -- Input Guard + if (valid_in_dds = '1') then + data_in_latch_next <= data_in_dds; + -- Alignment Operation in progress + if (align_op = '1') then + stage_next <= ALIGN_STREAM; + -- Reset + align_op_next <= '0'; + else + stage_next <= DECODE_PAYLOAD; + end if; + end if; + when ALIGN_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 + -- ###GENERATED START### + when GET_ID => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + id_latch_next <= endian_swap(endian_flag, data_in_latch); + align_offset_next <= align_offset + 4; + stage_next <= FETCH; + -- Next Member + decode_stage_next <= GET_A; + end if; + when GET_A => + -- ALIGN GUARD + if (not check_align(align_offset, ALIGN_4)) then + target_align_next <= ALIGN_4; + stage_next <= ALIGN_STREAM; + else + a_latch_next <= endian_swap(endian_flag, data_in_latch); + align_offset_next <= align_offset + 4; + stage_next <= FETCH; + -- Next Member + stage_next <= SKIP_PAYLOAD; + 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_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_dds) = (data_in_dds'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') then + -- Skip Read + ready_in_dds_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; + end case; + + -- OVERREAD GUARD + -- Attempted read on empty input + if (last_word_in_latch = '1' and last_word_in_dds = '0' and ready_in_dds_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; + decode_stage <= GET_ID; + return_stage <= GET_ID; + target_align <= ALIGN_1; + return_code_latch <= ROS_RET_OK; + message_info_sig <= EMPTY_MESSAGE_INFO; + cnt <= 0; + endian_flag <= '0'; + last_word_in_latch <= '0'; + decode_error_latch <= '0'; + optional <= '0'; + taken_sig <= '0'; + align_op <= '0'; + data_available_sig <= '0'; + align_offset <= (others => '0'); + data_in_latch <= (others => '0'); + -- ###GENERATED START### + id_latch <= (others => '0'); + a_latch <= (others => '0'); + -- ###GENERATED END### + else + stage <= stage_next; + decode_stage <= decode_stage_next; + return_stage <= return_stage_next; + target_align <= target_align_next; + return_code_latch <= return_code_latch_next; + message_info_sig <= message_info_sig_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; + data_available_sig <= data_available_sig_next; + align_offset <= align_offset_next; + data_in_latch <= data_in_latch_next; + -- ###GENERATED START### + id_latch <= id_latch_next; + a_latch <= a_latch_next; + -- ###GENERATED END### + end if; + end if; + 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 index a98a969..9d8bf20 100644 --- a/src/ros2/Tests/ros_testbench.pro +++ b/src/ros2/Tests/ros_testbench.pro @@ -201,6 +201,101 @@ analyze ../example_interfaces/Fibonacci_ros_action_client.vhd analyze ../example_interfaces/Fibonacci_ros_action_server.vhd analyze Level_2/L2_Testbench_ROS_Lib5.vhd +library Testbench_ROS_Lib6 +analyze ../../math_pkg.vhd +analyze ../../rtps_package.vhd +analyze ../ros_package.vhd +analyze ../rcl_interfaces/action_msgs/GoalInfo_package.vhd +analyze ../rcl_interfaces/action_msgs/GoalStatus_package.vhd +analyze ../rcl_interfaces/action_msgs/GoalStatusArray_package.vhd +analyze ../rcl_interfaces/action_msgs/CancelGoal_package.vhd +analyze Type1_package.vhd +analyze Level_2/L2_Testbench_ROS_Lib6_config.vhd +analyze ../dds_user_config.vhd +analyze ../../rtps_config_package.vhd +analyze ../../rtps_test_package.vhd +analyze ../ros_config_package.vhd +analyze ../../single_port_ram.vhd +analyze ../../single_port_ram_Altera.vhd +analyze ../../single_port_ram_cfg.vhd +analyze ../../dual_port_ram.vhd +analyze ../../dual_port_ram_Altera.vhd +analyze ../../dual_port_ram_cfg.vhd +analyze ../../FWFT_FIFO.vhd +analyze ../../FWFT_FIFO_Altera.vhd +analyze ../../FWFT_FIFO_cfg.vhd +analyze ../../vector_FIFO.vhd +analyze ../../mem_ctrl.vhd +analyze ../../dp_mem_ctrl.vhd +analyze ../../moving_average.vhd +analyze ../../moving_average_wrapper.vhd +analyze ../../rtps_handler.vhd +analyze ../../rtps_discovery_module.vhd +analyze ../../rtps_out.vhd +analyze ../../rtps_reader.vhd +analyze ../../rtps_writer.vhd +analyze ../../dds_writer.vhd +analyze ../../dds_reader.vhd +analyze ../../key_holder.vhd +analyze ../../key_hash_generator.vhd +analyze ../../Tests/test_key_holder.vhd +analyze ../../Tests/test_key_hash_generator.vhd +analyze ../../mult.vhd +analyze ../../mult_Altera.vhd +analyze ../../mult_cfg.vhd +analyze ../ros_time_converter.vhd +analyze ../ros_static_discovery_writer.vhd +analyze Type1_ros_pub.vhd +analyze Type1_ros_sub.vhd +analyze test_loopback_util.vhd +analyze Level_2/L2_Testbench_ROS_Lib6.vhd + +library Testbench_ROS_Lib7 +analyze ../../math_pkg.vhd +analyze ../../rtps_package.vhd +analyze ../ros_package.vhd +analyze ../rcl_interfaces/action_msgs/GoalInfo_package.vhd +analyze ../rcl_interfaces/action_msgs/GoalStatus_package.vhd +analyze ../rcl_interfaces/action_msgs/GoalStatusArray_package.vhd +analyze ../rcl_interfaces/action_msgs/CancelGoal_package.vhd +analyze Type1_package.vhd +analyze Level_2/L2_Testbench_ROS_Lib7_config.vhd +analyze ../dds_user_config.vhd +analyze ../../rtps_config_package.vhd +analyze ../../rtps_test_package.vhd +analyze ../ros_config_package.vhd +analyze ../../single_port_ram.vhd +analyze ../../single_port_ram_Altera.vhd +analyze ../../single_port_ram_cfg.vhd +analyze ../../dual_port_ram.vhd +analyze ../../dual_port_ram_Altera.vhd +analyze ../../dual_port_ram_cfg.vhd +analyze ../../FWFT_FIFO.vhd +analyze ../../FWFT_FIFO_Altera.vhd +analyze ../../FWFT_FIFO_cfg.vhd +analyze ../../vector_FIFO.vhd +analyze ../../mem_ctrl.vhd +analyze ../../dp_mem_ctrl.vhd +analyze ../../rtps_handler.vhd +analyze ../../rtps_discovery_module.vhd +analyze ../../rtps_out.vhd +analyze ../../rtps_reader.vhd +analyze ../../rtps_writer.vhd +analyze ../../dds_writer.vhd +analyze ../../dds_reader.vhd +analyze ../../key_holder.vhd +analyze ../../key_hash_generator.vhd +analyze ../../Tests/test_key_holder.vhd +analyze ../../Tests/test_key_hash_generator.vhd +analyze ../../mult.vhd +analyze ../../mult_Altera.vhd +analyze ../../mult_cfg.vhd +analyze ../ros_time_converter.vhd +analyze ../ros_static_discovery_writer.vhd +analyze Type1_ros_pub.vhd +analyze Type1_ros_sub.vhd +analyze Level_2/L2_Testbench_ROS_Lib7.vhd + library Testbench_ROS_Lib1 analyze ../../math_pkg.vhd analyze ../../rtps_package.vhd @@ -252,6 +347,7 @@ analyze Level_0/L0_ros_action_server_test2.vhd analyze Level_1/L1_Fibonacci_ros_action_test1.vhd analyze Level_1/L1_Fibonacci_ros_action_test2.vhd analyze Level_2/L2_Fibonacci_ros_action_test1.vhd +analyze Level_2/L2_ROS_Loopback_test1.vhd simulate L1_AddTwoInts_ros_srv_test1 @@ -271,4 +367,5 @@ simulate L0_ros_action_server_test1 simulate L0_ros_action_server_test2 simulate L1_Fibonacci_ros_action_test1 simulate L1_Fibonacci_ros_action_test2 -simulate L2_Fibonacci_ros_action_test1 \ No newline at end of file +simulate L2_Fibonacci_ros_action_test1 +simulate L2_ROS_Loopback_test1 \ No newline at end of file diff --git a/src/ros2/Tests/test_loopback_util.vhd b/src/ros2/Tests/test_loopback_util.vhd new file mode 100644 index 0000000..c13b22a --- /dev/null +++ b/src/ros2/Tests/test_loopback_util.vhd @@ -0,0 +1,268 @@ +-- 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.user_config.all; +use work.ros_package.all; + +entity test_loopback_util is + port ( + -- SYSTEM + clk : in std_logic; + reset : in std_logic; + -- UTILIZATION + input_util : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + output_util : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + -- READER + start_r : out std_logic; + opcode_r : out ROS_TOPIC_OPCODE_TYPE; + ack_r : in std_logic; + done_r : in std_logic; + return_code_r : in std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0); + data_available_r : in std_logic; + id_r : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a_r : in std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + message_info_r : in MESSAGE_INFO_TYPE; + taken_r : in std_logic; + -- WRITER + start_w : out std_logic; + opcode_w : out ROS_TOPIC_OPCODE_TYPE; + ack_w : in std_logic; + id_w : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + a_w : out std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + done_w : in std_logic; + return_code_w : in std_logic_vector(ROS_RETCODE_WIDTH-1 downto 0) + ); +end entity; + +architecture arch of test_loopback_util is + + --*****TYPE DECLARATION***** + type STAGE_TYPE is (IDLE, READ, WRITE); + + function gen_window_size return natural is + variable ret : natural := 0; + begin + if (SIMULATION_FLAG) then + ret := 64; + else + ret := 8192; + end if; + return ret; + end function; + constant WINDOW_SIZE : natural := gen_window_size; + + --*****SIGNAL DECLARATION***** + signal stage, stage_next : STAGE_TYPE; + signal cnt, cnt_next : natural range 0 to 1; + signal id_latch, id_latch_next, a_latch, a_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + signal input_average, input_average_latch : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + signal output_average, output_average_latch : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + signal input_trigger, input_trigger_latch, input_trigger_latch_next, input_overflow, input_overflow_latch : std_logic; + signal output_trigger, output_trigger_latch, output_trigger_latch_next, output_overflow, output_overflow_latch : std_logic; + +begin + + input_util_average_inst : entity work.moving_average_wrapper(arch) + generic map( + INNER_WINDOW_SIZE => WINDOW_SIZE, + OUTER_WINDOW_SIZE => WINDOW_SIZE, + DATA_WIDTH => CDR_LONG_WIDTH, + ENABLE_ROUNDING => TRUE + ) + port map( + clk => clk, + reset => reset, + data_in => input_util, + average => input_average, + trigger => input_trigger, + overflow => input_overflow + ); + + output_util_average_inst : entity work.moving_average_wrapper(arch) + generic map( + INNER_WINDOW_SIZE => WINDOW_SIZE, + OUTER_WINDOW_SIZE => WINDOW_SIZE, + DATA_WIDTH => CDR_LONG_WIDTH, + ENABLE_ROUNDING => TRUE + ) + port map( + clk => clk, + reset => reset, + data_in => output_util, + average => output_average, + trigger => output_trigger, + overflow => output_overflow + ); + + latch_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + input_average_latch <= (others => '0'); + output_average_latch <= (others => '0'); + input_trigger_latch <= '0'; + output_trigger_latch <= '0'; + input_overflow_latch <= '0'; + output_overflow_latch <= '0'; + else + if (input_trigger = '1') then + input_trigger_latch <= input_trigger; + input_average_latch <= input_average; + end if; + if (output_trigger = '1') then + output_trigger_latch <= output_trigger; + output_average_latch <= output_average; + end if; + if (input_overflow = '1') then + input_overflow_latch <= input_overflow; + end if; + if (output_overflow = '1') then + output_overflow_latch <= output_overflow; + end if; + end if; + end if; + end process; + + main_prc : process(all) + begin + -- DEFAULT + stage_next <= stage; + cnt_next <= cnt; + id_latch_next <= id_latch; + a_latch_next <= a_latch; + input_trigger_latch_next <= input_trigger_latch; + output_trigger_latch_next <= output_trigger_latch; + -- DEFAULT Unregistered + start_r <= '0'; + opcode_r <= NOP; + start_w <= '0'; + opcode_w <= NOP; + id_w <= (others => '0'); + a_w <= (others => '0'); + + -- Latch Setter + if (input_trigger = '1') then + input_trigger_latch_next <= '1'; + end if; + if (output_trigger = '1') then + output_trigger_latch_next <= '1'; + end if; + + case (stage) is + when IDLE => + -- Input FIFO Utilization Report + if (input_trigger_latch = '1') then + id_latch_next <= std_logic_vector(to_unsigned(3,CDR_LONG_WIDTH)); + a_latch_next <= input_average_latch; + stage_next <= WRITE; + cnt_next <= 0; + -- Reset + input_trigger_latch_next <= '0'; + -- Output FIFO Utilization Report + elsif (output_trigger_latch = '1') then + id_latch_next <= std_logic_vector(to_unsigned(4,CDR_LONG_WIDTH)); + a_latch_next <= output_average_latch; + stage_next <= WRITE; + cnt_next <= 0; + -- Reset + output_trigger_latch_next <= '0'; + -- Reader has Available Data + elsif (data_available_r = '1') then + stage_next <= READ; + cnt_next <= 0; + end if; + when READ => + case (cnt) is + when 0 => + start_r <= '1'; + opcode_r <= TAKE; + if (ack_r = '1') then + cnt_next <= cnt + 1; + end if; + when 1 => + if (done_r = '1') then + case (return_code_r) is + when ROS_RET_OK => + if (taken_r = '1') then + if (unsigned(id_r) = 1) then + id_latch_next <= std_logic_vector(to_unsigned(2,CDR_LONG_WIDTH)); + a_latch_next <= a_r; + stage_next <= WRITE; + cnt_next <= 0; + -- Unknown Instance + else + -- Take Next Sample + cnt_next <= 0; + end if; + elsif (data_available_r = '1') then + -- Take Next Sample + cnt_next <= 0; + else + -- DONE + stage_next <= IDLE; + end if; + when others => + -- ERROR + assert FALSE report "Unexpected DDS Reader Return Code" severity FAILURE; + stage_next <= IDLE; + end case; + end if; + when others => + null; + end case; + when WRITE => + id_w <= id_latch; + a_w <= a_latch; + case (cnt) is + when 0 => + start_w <= '1'; + opcode_w <= PUBLISH; + if (ack_w = '1') then + cnt_next <= cnt + 1; + end if; + when 1 => + if (done_w = '1') then + case (return_code_w) is + when ROS_RET_OK => + -- DONE + stage_next <= IDLE; + when others => + -- ERROR + assert FALSE report "Unexpected DDS Writer Return Code" severity FAILURE; + stage_next <= IDLE; + end case; + end if; + when others => + null; + end case; + end case; + end process; + + sync_prc : process(clk) + begin + if rising_edge(clk) then + if (reset = '1') then + stage <= IDLE; + cnt <= 0; + id_latch <= (others => '0'); + a_latch <= (others => '0'); + input_trigger_latch <= '0'; + output_trigger_latch <= '0'; + else + stage <= stage_next; + cnt <= cnt_next; + id_latch <= id_latch_next; + a_latch <= a_latch_next; + input_trigger_latch <= input_trigger_latch_next; + output_trigger_latch <= output_trigger_latch_next; + end if; + end if; + end process; + +end architecture;