From 9c95e58e321967b4c3e9165a1ca0c33bfdb6ae6e Mon Sep 17 00:00:00 2001 From: Greek Date: Sun, 15 Nov 2020 20:34:39 +0100 Subject: [PATCH] * Added OSVVM Library as Submodule * Merged stimulus generation procedures to one single procedure * Integrated OSVVM into testbench * Generated OSVVM Project Script File * Various Bug Fixes to compile testbench --- .gitignore | 2 +- .gitmodules | 3 + sim/rtps_handler.do | 44 + src/OSVVM | 1 + src/TODO.txt | 4 +- src/Tests/Level 0/rtps_handler-test1.vhd | 834 ---------- src/Tests/Level_0/rtps_handler_test1.vhd | 1265 ++++++++++++++ src/Tests/testbench.pro | 14 + src/rtps_config_package.vhd | 7 +- src/rtps_handler.vhd | 6 +- src/rtps_package.vhd | 44 +- src/rtps_test_package.vhd | 1918 ++++++++-------------- 12 files changed, 2050 insertions(+), 2092 deletions(-) create mode 100644 .gitmodules create mode 100644 sim/rtps_handler.do create mode 160000 src/OSVVM delete mode 100644 src/Tests/Level 0/rtps_handler-test1.vhd create mode 100644 src/Tests/Level_0/rtps_handler_test1.vhd create mode 100644 src/Tests/testbench.pro diff --git a/.gitignore b/.gitignore index cb1f2c6..7dd60c9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ #Ignore List /syn/** -/modelsim/** +/sim/** /download/** diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6b9f2b8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/OSVVM"] + path = src/OSVVM + url = https://github.com/OSVVM/OSVVM.git diff --git a/sim/rtps_handler.do b/sim/rtps_handler.do new file mode 100644 index 0000000..e3c108e --- /dev/null +++ b/sim/rtps_handler.do @@ -0,0 +1,44 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider SYSTEM +add wave -noupdate /rtps_handler_test1/uut/clk +add wave -noupdate /rtps_handler_test1/uut/reset +add wave -noupdate -divider INPUT +add wave -noupdate /rtps_handler_test1/uut/empty +add wave -noupdate /rtps_handler_test1/uut/rd +add wave -noupdate -radix hexadecimal /rtps_handler_test1/uut/data_in +add wave -noupdate -divider OUTPUT +add wave -noupdate -radix hexadecimal /rtps_handler_test1/uut/data_out +add wave -noupdate /rtps_handler_test1/uut/builtin_full +add wave -noupdate /rtps_handler_test1/uut/builtin_wr +add wave -noupdate /rtps_handler_test1/uut/user_full +add wave -noupdate /rtps_handler_test1/uut/user_wr +add wave -noupdate /rtps_handler_test1/uut/last_word_out +add wave -noupdate -divider MISC +add wave -noupdate /rtps_handler_test1/stimulus.length +add wave -noupdate /rtps_handler_test1/cnt_stim +add wave -noupdate /rtps_handler_test1/packet_sent +add wave -noupdate /rtps_handler_test1/reference.length +add wave -noupdate /rtps_handler_test1/cnt_ref +add wave -noupdate /rtps_handler_test1/packet_checked +add wave -noupdate -divider RTPS_HANDLER +add wave -noupdate /rtps_handler_test1/uut/stage +add wave -noupdate /rtps_handler_test1/uut/stage_next +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {0 ps} 0} +quietly wave cursor active 1 +configure wave -namecolwidth 150 +configure wave -valuecolwidth 63 +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 ps +update +WaveRestoreZoom {0 ps} {1206528 ps} diff --git a/src/OSVVM b/src/OSVVM new file mode 160000 index 0000000..6b81053 --- /dev/null +++ b/src/OSVVM @@ -0,0 +1 @@ +Subproject commit 6b810535967433ae4bec4094ea58fc09c1e49227 diff --git a/src/TODO.txt b/src/TODO.txt index 8dd1971..861d4cf 100644 --- a/src/TODO.txt +++ b/src/TODO.txt @@ -51,6 +51,7 @@ * Should a "Keyed" Endpoint communicate with a "Non-Keyed"? * Is the empty String a valid Topic and Type Name? * We can determine if a Endpoint is a Reader or Writer via the Entity ID. Is it illegal to get a SEDP with incompatible source (Reader Entity ID from Publications Announcer?) +* Can we make an array of records of uncontrained strings? That we we could make an array of variable sized strings... * Fast-RTPS doen not follow DDSI-RTPS Specification @@ -118,4 +119,5 @@ PROTOCOL UNCOMPLIANCE -> Cannot invalidate Rest of Message/Packet -- Input FIFO Guard --- Output FIFO Guard \ No newline at end of file +-- Output FIFO Guard +-- Deferred to package Body \ No newline at end of file diff --git a/src/Tests/Level 0/rtps_handler-test1.vhd b/src/Tests/Level 0/rtps_handler-test1.vhd deleted file mode 100644 index c4c62d3..0000000 --- a/src/Tests/Level 0/rtps_handler-test1.vhd +++ /dev/null @@ -1,834 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - - -entity rtps_handler-test1 is -end entity; - -architecture testbench of rtps_handler-test1 is - - -- *COMPONENT DECLARATION* - component rtps_handler is - port ( - clk : in std_logic; -- Input Clock - reset : in std_logic; -- Synchronous Reset - empty : in std_logic; -- Input FIFO empty flag - rd : out std_logic; -- Input FIFO read signal - data_in : in std_logic_vector(WORD_WIDTH-1 downto 0); -- Input FIFO data signal - data_out : out std_logic_vector(WORD_WIDTH-1 downto 0); -- Output data signal - builtin_full : in std_logic; -- Output FIFO (Built-In Endpoint) full signal - builtin_wr : out std_logic; -- Output FIFO (Built-In Endpoint) write signal - user_full : in std_logic_vector(0 to NUM_ENDPOINTS-1); -- Output FIFO (User Endpoints) full signal - user_wr : out std_logic_vector(0 to NUM_ENDPOINTS-1); -- Output FIFO (User Endpoints) write signal - last_word_out : out std_logic -- Output FIFO Last Word signal - ); - end component; - - -- *FUNCTION DECLARATION* - - -- *SIGNAL DECLARATION* - signal clk, reset, in_empty, rd_sig, builtin_full, builtin_wr, user_full, user_wr, last_word_out, packet_done : std_logic := '0'; - signal data_in, data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); - signal stimulus, reference : TEST_PACKET_TYPE := ( - data => (others => (others => '0')), - length => 0 - ); - -begin - - -- Unit Under Test - uut : rtps_handler - port map ( - clk => clk, - reset => reset, - empty => in_empty, - rd => rd_sig, - data_in => data_in, - data_out => data_out, - builtin_full => builtin_full, - builtin_wr => builtin_wr - user_full => user_full, - user_wr => user_wr - last_word_out => last_word_out - ); - - stimulus_prc : process - variable ep : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; - constant rand_data : TEST_PACKET_TYPE := (length => 2, data => (0 => rand_slv(WORD_WIDTH), 1 => rand_slv(WORD_WIDTH))); - variable rtps_header : RTPS_HEADER_TYPE := DEFAULT_RTPS_HEADER; - variable acknack : RTPS_ACKNACK_SUBMESSAGE_TYPE := DEFAULT_RTPS_ACKNACK_SUBMESSAGE; - variable data : RTPS_DATA_SUBMESSAGE_TYPE := DEFAULT_RTPS_DATA_SUBMESSAGE; - variable gap : RTPS_GAP_SUBMESSAGE_TYPE := DEFAULT_RTPS_GAP_SUBMESSAGE; - variable heartbeat : RTPS_HEARTBEAT_SUBMESSAGE_TYPE := DEFAULT_RTPS_HEARTBEAT_SUBMESSAGE; - variable info_ts : RTPS_INFO_TIMESTAMP_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_TIMESTAMP_SUBMESSAGE; - variable pad : RTPS_PAD_SUBMESSAGE_TYPE := DEFAULT_RTPS_PAD_SUBMESSAGE; - variable info_dest : RTPS_INFO_DESTINATION_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_DESTINATION_SUBMESSAGE; - variable info_src : RTPS_INFO_SOURCE_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_SOURCE_SUBMESSAGE; - variable info_reply : RTPS_INFO_REPLY_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_REPLY_SUBMESSAGE; - variable info_reply4 : RTPS_INFO_REPLY_IP4_SUBMESSAGE_TYPE := DEFAULT_RTPS_INFO_REPLY_IP4_SUBMESSAGE; - variable udp_header_meta, udp_header_user : UDP_HEADER_TYPE := DEFAULT_UDP_HEADER; - begin - ep.entityId := rand_slv(ep.entityId'length); - acknack.readerId := ep.entityId; - data.writerId := ep.entityId; - gap.writerId := ep.entityId; - heartbeat.writerId := ep.entityId; - - data.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - data.data := rand_data; - - rtps_header.guidPrefix := ep.participant.guidPrefix; - udp_header_meta.dest := DEST_LOC.meta.locator(0); - udp_header_user.dest := DEST_LOC.user.locator(0); - udp_header_meta.src := ep.participant.defaultUnicastLocatorList.locator(0); - udp_header_user.src := ep.participant.defaultUnicastLocatorList.locator(0); - info_dest.guidPrefix := GUIDPREFIX; - info_ts.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) := '0'; - info_ts.timestamp := (unsigned(rand_slv(WORD_WIDTH)),unsigned(rand_slv(WORD_WIDTH))); - pad.submessageLength := int(28,16); - info_reply.unicastLocatorList.numLocators := int(2,32); - info_reply.unicastLocatorList.locator(0) := ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH), - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH) - ); - info_reply.unicastLocatorList.locator(1) := ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => (others => '0'), -- Invalid Port - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH) - ); - info_reply.multicastLocatorList.numLocators := int(2,32); - info_reply.multicastLocatorList.locator(0) := ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH), - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH) - ); - info_reply.multicastLocatorList.locator(1) := ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH), - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => (others => '0') -- Invalid Addr - ); - info_reply4.unicastLocator := ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH), - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH) - ); - info_reply4.multicastLocator := ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH), - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => rand_slv(IPv4_ADDRESS_WIDTH) - ); - - report "Initiating Test" severity note; - reset <= '1'; - wait until rising_edge(clk); - - - -- *RTPS HEADER* - report "Sending invalid RTPS Header [Packet Size to small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - stimulus.length := length-1; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid RTPS Header [Protocol Missmatch]" severity note; - gen_udp_header(udp_header_meta, stimulus); - rtps_header.protocol := rand_slv(PROTOCOL_WIDTH); - gen_rtps_header(rtps_header, stimulus); - rtps_header.protocol := DEFAULT_RTPS_HEADER.protocol; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid RTPS Header [Protocol Major Version Missmatch]" severity note; - gen_udp_header(udp_header_meta, stimulus); - rtps_header.version := PROTOCOLVERSION_1_0; - gen_rtps_header(rtps_header, stimulus); - rtps_header.version := DEFAULT_RTPS_HEADER.version; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *DATA SUBMESSAGE* - report "Sending valid DATA [Empty Submessage]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - data.flags(SUBMESSAGE_DATA_FLAG_POS) := '0'; - data.data.length := 0; - gen_data(data, stimulus); - data.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; - data.data := rand_data; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending valid DATA [Meta Traffic, Both Endianness]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - data.littleEndian := '1'; - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - data.littleEndian := '0'; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending valid DATA [User Traffic]" severity note; - gen_udp_header(udp_header_user, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_data(data, stimulus); - gen_data_out(data, udp_header_user.src, FALSE, TIME_INVALID, rtps_header.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending valid DATA [Extra Header Bytes]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - data.octetsToInlineQos := int(23,16); - gen_data(data, stimulus); - data.octetsToInlineQos := DEFAULT_RTPS_DATA_SUBMESSAGE.octetsToInlineQos; - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid DATA [DATA and KEY Flag set]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - data.flags(SUBMESSAGE_KEY_FLAG_POS) := '1'; - gen_data(data, stimulus); - data.flags(SUBMESSAGE_KEY_FLAG_POS) := '0'; - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid DATA [Packet Size too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_data(data, stimulus); - stimulus.length := length-1; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid DATA [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - data.submessageLength := int(16,16); - gen_data(data, stimulus); - data.submessageLength := DEFAULT_RTPS_DATA_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid DATA [Invalid writerSN]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - data.sequenceNumber := (others => (others => '0')); - gen_data(data, stimulus); - data.sequenceNumber := DEFAULT_RTPS_DATA_SUBMESSAGE.sequenceNumber; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *ACKNACK SUBMESSAGE* - report "Sending valid ACKNACK [Meta Traffic, Both Endianness]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_acknack(acknack, stimulus); - gen_acknack_out(acknack, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference); - acknack.littleEndian := '1'; - gen_acknack(acknack, stimulus); - gen_acknack_out(acknack, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference); - acknack.littleEndian := '0'; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending valid ACKNACK [User Traffic]" severity note; - gen_udp_header(udp_header_user, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_acknack(acknack, stimulus); - gen_acknack_out(acknack, udp_header_user.src, FALSE, rtps_header.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid ACKNACK [Packet Size too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_acknack(acknack, stimulus); - stimulus.length := length-1; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid ACKNACK [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - acknack.submessageLength := int(20,16); - gen_acknack(acknack, stimulus); - acknack.submessageLength := DEFAULT_RTPS_ACKNACK_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid ACKNACK [ReaderSNState invalid (Base invalid)]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - acknack.readerSNState.base := (others => (others => '0')); - gen_acknack(acknack, stimulus); - acknack.readerSNState := DEFAULT_RTPS_ACKNACK_SUBMESSAGE.readerSNState; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid ACKNACK [ReaderSNState invalid (NumBits invalid)]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - acknack.readerSNState.numBits := int(257, 32); - gen_acknack(acknack, stimulus); - acknack.readerSNState := DEFAULT_RTPS_ACKNACK_SUBMESSAGE.readerSNState; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - -- *GAP SUBMESSAGE* - report "Sending valid GAP [Meta Traffic, Both Endianness]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_gap(gap, stimulus); - gen_gap_out(gap, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference); - gap.littleEndian := '1'; - gen_gap(gap, stimulus); - gen_gap_out(gap, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference); - gap.littleEndian := '0'; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending valid GAP [User Traffic]" severity note; - gen_udp_header(udp_header_user, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_gap(gap, stimulus); - gen_gap_out(gap, udp_header_user.src, FALSE, rtps_header.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid GAP [Packet Size too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_gap(gap, stimulus); - stimulus.length := length-1; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid GAP [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gap.submessageLength := int(24,16); - gen_gap(gap, stimulus); - gap.submessageLength := DEFAULT_RTPS_GAP_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid GAP [GapStart invalid]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gap.gapStart := (others => (others => '0')); - gen_gap(gap, stimulus); - gap.gapStart := DEFAULT_RTPS_GAP_SUBMESSAGE.gapStart; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid GAP [GapList invalid (Base invalid)]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gap.gapList.base := (others => (others => '0')); - gen_gap(gap, stimulus); - gap.gapList := DEFAULT_RTPS_GAP_SUBMESSAGE.gapList; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid GAP [GapList invalid (NumBits invalid)]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gap.gapList.numBits := int(257,32); - gen_gap(gap, stimulus); - gap.gapList := DEFAULT_RTPS_GAP_SUBMESSAGE.gapList; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *HEARTBEAT SUBMESSAGE* - report "Sending valid HEARTBEAT [Meta Traffic, Both Endianness]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_heartbeat(heartbeat, stimulus); - gen_heartbeat_out(heartbeat, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference); - heartbeat.littleEndian := '1'; - gen_heartbeat(heartbeat, stimulus); - gen_heartbeat_out(heartbeat, udp_header_meta.src, TRUE, rtps_header.guidPrefix, reference); - heartbeat.littleEndian := '0'; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending valid HEARTBEAT [User Traffic]" severity note; - gen_udp_header(udp_header_user, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_heartbeat(heartbeat, stimulus); - gen_heartbeat_out(heartbeat, udp_header_user.src, FALSE, rtps_header.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid HEARTBEAT [Packet Size too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - gen_heartbeat(heartbeat, stimulus); - stimulus.length := length-1; - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid HEARTBEAT [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - heartbeat.submessageLength := int(24,16); - gen_heartbeat(heartbeat, stimulus); - heartbeat.submessageLength := (others => '1'); - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid HEARTBEAT [FirstSN invalid]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - heartbeat.firstSN := (others => (others => '0')); - gen_heartbeat(heartbeat, stimulus); - heartbeat.firstSN := DEFAULT_RTPS_HEARTBEAT_SUBMESSAGE.firstSN; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid HEARTBEAT [LastSN invalid]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - heartbeat.lastSN := (others => (others => '1')); - gen_heartbeat(heartbeat, stimulus); - heartbeat.lastSN := DEFAULT_RTPS_HEARTBEAT_SUBMESSAGE.lastSN; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *INFO_SOURCE SUBMESSAGE* - report "Testing INFO_SOURCE interpretation" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - -- Send INFO_SOURCE (Change Source GUID Prefix) - info_src.guidPrefix(0) := rand_slv(WORD_WIDTH); - gen_info_src(info_src, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_SOURCE (Change GUID Prefix, Little Endian) - info_src.littleEndian := '1'; - info_src.guidPrefix := ep.participant.guidPrefix; - gen_info_src(info_src, stimulus); - info_src.littleEndian := '0'; - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, ep.participant.guidPrefix, reference); - -- Send INFO_SOURCE [Protocol Major Version Missmatch] - info_src.version := PROTOCOLVERSION_1_0; - gen_info_src(info_src, stimulus); - info_src.version := PROTOCOLVERSION_2_4; - -- Send valid DATA - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid INFO_SOURCE [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - info_src.submessageLength := int(16,16); - gen_info_src(info_src, stimulus); - info_src.submessageLength := DEFAULT_RTPS_INFO_SOURCE_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *INFO_DESTINATION SUBMESSAGE* - report "Testing INFO_DESTINATION interpretation" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - -- Send INFO_DESTINATION [Correct GUID Prefix] - gen_info_dest(info_dest, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_DESTINATION [Correct GUID Prefix, Little Endian] - info_dest.littleEndian := '1'; - gen_info_dest(info_dest, stimulus); - info_dest.littleEndian := '0'; - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_DESTINATION [Incorrect GUID Prefix] - info_dest.guidPrefix := rtps_header.guidPrefix; - gen_info_src(info_dest, stimulus); - info_dest.guidPrefix := GUIDPREFIX; - -- Send valid DATA - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid INFO_DESTINATION [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - info_dest.submessageLength := int(8,16); - gen_info_dest(info_dest, stimulus); - info_dest.submessageLength := DEFAULT_RTPS_INFO_DESTINATION_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *INFO_REPLY SUBMESSAGE* - report "Testing INFO_REPLY interpretation" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - -- Send INFO_REPLY [Empty Locator Lists] - info_reply.unicastLocatorList.numLocators := int(0,32); - gen_info_reply(info_reply, stimulus); - info_reply.unicastLocatorList.numLocators := int(2,32); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_REPLY [1 valid Unicast, 1 invalid Unicast] - gen_info_reply(info_reply, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, info_reply.unicastLocatorList.locator(0), TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_REPLY [0 Unicast, 1 invalid Multicast, 1 valid Multicast, Little Endian] - info_reply.unicastLocatorList.numLocators := int(0,32); - info_reply.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '1'; - gen_info_reply(info_reply, stimulus); - info_reply.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '0'; - info_reply.unicastLocatorList.numLocators := int(2,32); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, info_reply.multicastLocatorList.locator(0), TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid INFO_REPLY [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - info_reply.submessageLength := int(48,16); - gen_info_reply(info_reply, stimulus); - info_reply.submessageLength := DEFAULT_RTPS_INFO_REPLY_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *INFO_REPLY_IP4 SUBMESSAGE* - report "Testing INFO_REPLY_IP4 interpretation" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); - -- Send INFO_REPLY_IP4 [Valid Unicast] - gen_info_reply(info_reply, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, info_reply4.unicastLocator, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_REPLY_IP4 [Invalid Unicast, Valid Multicast, Little Endian] - info_reply4.littleEndian := '1'; - info_reply4.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '1'; - info_reply4.unicastLocator.addr := (others => '0'); - gen_info_reply(info_reply, stimulus); - info_reply4.littleEndian := '0'; - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, info_reply4.multicastLocator, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_REPLY_IP4 [Invalid Unicast, Invalid Multicast] - gen_data_out(data, info_reply4.multicastLocator, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); -- Generate Reference while locator still valid - info_reply4.multicastLocator.port_ := (others => '0'); - gen_info_reply(info_reply, stimulus); - info_reply4.unicastLocator.addr := rand_slv(IPv4_ADDRESS_WIDTH); - info_reply4.multicastLocator.port_ := rand_slv(UDP_PORT_WIDTH); - info_reply4.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '0'; - -- Send valid DATA - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid INFO_REPLY_IP4 [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - info_reply4.submessageLength := int(4,16); - gen_info_reply_ip4(info_reply4, stimulus); - info_reply4.submessageLength := DEFAULT_RTPS_INFO_REPLY_IP4_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - -- *INFO TS* - report "Testing INFO_TIMESTAMP interpretation" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send INFO_TIMESTAMP [Change Timestamp] - gen_info_ts(info_ts, stimulus); - -- Send valid Data - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, info_ts.timestamp, info_dest.guidPrefix, reference); - -- Send INFO_TIMESTAMP [Change Timestamp, Little Endian] - info_ts.timestamp(0) := unsigned(rand_slv(WORD_WIDTH)); - info_ts.littleEndian := '1'; - gen_info_ts(info_ts, stimulus); - info_ts.littleEndian := '0'; - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, info_ts.timestamp, info_dest.guidPrefix, reference); - -- Send INFO_TIMESTAMP [Invalidate Timestamp] - info_ts.timestamp(0) := unsigned(rand_slv(WORD_WIDTH)); - info_ts.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) := '1'; - gen_info_ts(info_ts, stimulus); - info_ts.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) := '0'; - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - report "Sending invalid INFO_TMESTAMP [Submessage Length too small]" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - info_ts.submessageLength := int(4,16); - gen_info_ts(info_ts, stimulus); - info_ts.submessageLength := DEFAULT_RTPS_INFO_REPLY_IP4_SUBMESSAGE.submessageLength; - gen_data(data, stimulus); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *PAD* - report "Testing PAD interpretation" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send PAD - gen_pad(pad, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - - -- *UNKNOWN* - report "Testing unknown Submessage handling" severity note; - gen_udp_header(udp_header_meta, stimulus); - gen_rtps_header(rtps_header, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send valid DATA_FRAG Submessage (DATA_FRAG ignored) - gen_data_frag(DEFAULT_RTPS_DATA_FRAG_SUBMESSAGE, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send valid HEARTBEAT_FRAG Submessage (HEARTBEAT_FRAG ignored) - gen_heartbeat_frag(DEFAULT_RTPS_HEARTBEAT_FRAG_SUBMESSAGE, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send valid NACK_FRAG Submesage (NACK_FRAG ignored) - gen_nack_frag(DEFAULT_RTPS_NACK_FRAG_SUBMESSAGE, stimulus); - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - -- Send UNKNOWN Submessage (ignored) - pad.submessageID := (others => '1'); - gen_pad(pad, stimulus); - pad.submessageID := DEFAULT_RTPS_PAD_SUBMESSAGE.submessageID; - -- Send valid DATA - gen_data(data, stimulus); - gen_data_out(data, udp_header_meta.src, TRUE, TIME_INVALID, info_dest.guidPrefix, reference); - fix_udp_packet(stimulus); - wait until (packet_done = '1'); - stimulus.length := 0; - reference.length := 0; - - end process; - - clock_prc : process - begin - clk <= '0'; - wait for 25 ns; - clk <= '1'; - wait for 25 ns; - end process; - - fifo_ctl_prc : process - begin - in_empty <= '0'; - builtin_full <= '0'; - user_full <= '0'; - wait until rising_edge(clk); - in_empty <= '1'; - builtin_full <= '0'; - user_full <= '0'; - wait until rising_edge(clk); - in_empty <= '0'; - builtin_full <= '1'; - user_full <= '0'; - wait until rising_edge(clk); - in_empty <= '0'; - builtin_full <= '0'; - user_full <= '1'; - wait until rising_edge(clk); - end process; - - assert (not (in_empty = '1' and rd_sig = '1')) report "Input FIFO read signal high while empty signal high" severity failure; - assert (not (builtin_full = '1' and builtin_wr = '1')) report "Builtin FIFO write signal high while full signal high" severity failure; - assert (not (user_full = '1' and user_wr = '1')) report "Builtin FIFO write signal high while full signal high" severity failure; - - input_prc : process(all) - signal cnt : natural := 0; - begin - if rising_edge(clk) then - if (reset = '1') then - data_in <= (others => '0'); - cnt <= 0; - packet_done <= '0'; - else - if (cnt = stimulus.length) then - cnt <= 0; - packet_done <= '1'; - elsif (rd_sig = '1') then - data_in <= stimulus.data(cnt); - cnt <= cnt + 1; - packet_done <= '0'; - end if; - end if; - end if; - end process; - - output_prc : process(all) - signal cnt : natural := 0; - begin - if rising_edge(clk) then - if (reset = '1') then - cnt <= 0; - else - assert (cnt <= reference.length) report "Received too many words in output" severity failure; - if ((builtin_wr = '1' or user_wr = '1') and rd_sig = '0') then - assert (data_out = reference.data(cnt)) report "Received unexpected output. Received: " & str(data_out) & ", Expected: " & str(reference.data(cnt)) severity failure; - cnt <= cnt + 1; - end if; - end if; - end if; - end process; - -end architecture; \ No newline at end of file diff --git a/src/Tests/Level_0/rtps_handler_test1.vhd b/src/Tests/Level_0/rtps_handler_test1.vhd new file mode 100644 index 0000000..c54afc5 --- /dev/null +++ b/src/Tests/Level_0/rtps_handler_test1.vhd @@ -0,0 +1,1265 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; +use work.rtps_test_package.all; + +entity rtps_handler_test1 is +end entity; + +architecture testbench of rtps_handler_test1 is + + -- *COMPONENT DECLARATION* + component rtps_handler is + port ( + clk : in std_logic; -- Input Clock + reset : in std_logic; -- Synchronous Reset + empty : in std_logic; -- Input FIFO empty flag + rd : out std_logic; -- Input FIFO read signal + data_in : in std_logic_vector(WORD_WIDTH-1 downto 0); -- Input FIFO data signal + data_out : out std_logic_vector(WORD_WIDTH-1 downto 0); -- Output data signal + builtin_full : in std_logic; -- Output FIFO (Built-In Endpoint) full signal + builtin_wr : out std_logic; -- Output FIFO (Built-In Endpoint) write signal + user_full : in std_logic_vector(0 to NUM_ENDPOINTS-1); -- Output FIFO (User Endpoints) full signal + user_wr : out std_logic_vector(0 to NUM_ENDPOINTS-1); -- Output FIFO (User Endpoints) write signal + last_word_out : out std_logic -- Output FIFO Last Word signal + ); + end component; + + -- *CONSTANT DECALRATION* + constant RAND_DATA : TEST_PACKET_TYPE := (length => 2, data => (0 => rand_slv(WORD_WIDTH), 1 => rand_slv(WORD_WIDTH), others => (others => '0'))); + constant UDP_META : UDP_HEADER_TYPE := (src => gen_rand_loc, dest => DEST_LOC.meta.locator(0)); + constant UDP_USER : UDP_HEADER_TYPE := (src => gen_rand_loc, dest => DEST_LOC.user.locator(0)); + + + -- *SIGNAL DECLARATION* + signal clk, reset, in_empty, rd_sig, builtin_full, builtin_wr, last_word_out : std_logic := '0'; + signal user_full, user_wr : std_logic_vector(NUM_ENDPOINTS-1 downto 0) := (others => '0'); + signal data_in, data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + shared variable stimulus, reference : TEST_PACKET_TYPE := ( + data => (others => (others => '0')), + length => 0 + ); + signal packet_sent, packet_checked : std_logic := '0'; + signal cnt_stim, cnt_ref : natural := 0; + + -- *FUNCTION DECLARATION* + procedure wait_on_complete is + begin + wait until rising_edge(packet_sent); + if (packet_checked /= '1') then + wait until (packet_checked = '1'); + end if; + end procedure; + +begin + + -- Unit Under Test + uut : rtps_handler + port map ( + clk => clk, + reset => reset, + empty => in_empty, + rd => rd_sig, + data_in => data_in, + data_out => data_out, + builtin_full => builtin_full, + builtin_wr => builtin_wr, + user_full => user_full, + user_wr => user_wr, + last_word_out => last_word_out + ); + + stimulus_prc : process + variable rtps_header : RTPS_HEADER_TYPE := DEFAULT_RTPS_HEADER; + variable rtps_sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable rtps_data : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable tmp_loc : LOCATOR_TYPE := EMPTY_LOCATOR; + variable ts : TIME_TYPE := TIME_INVALID; + variable check_cnt : natural := 0; + begin + + SetAlertLogName("L0-rtps_handler-input_handling"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + + -- Default Valid Data Submessage (Used to test Packet drop) + -- NOTE: Each time a stimulus is generated, the Sequence Number is (manually) incremented + rtps_data := DEFAULT_RTPS_SUBMESSAGE; + rtps_data.submessageID := SID_DATA; + rtps_data.writerId := DEFAULT_ENTITYID; + rtps_data.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_data.data := RAND_DATA; + + + + report "Initiating Test" severity note; + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + + -- *RTPS HEADER* + report "Sending invalid RTPS Header [Packet Size to small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header [RTPS Header Length > PacketSize] + rtps_header := DEFAULT_RTPS_HEADER; + gen_rtps_header(rtps_header, stimulus); + stimulus.length := stimulus.length-1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid RTPS Header [Protocol Missmatch]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header [Incompatible Protocol] + rtps_header := DEFAULT_RTPS_HEADER; + rtps_header.protocol := rand_slv(PROTOCOL_WIDTH); + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid RTPS Header [Protocol Major Version Missmatch]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header [Incompatible Version] + rtps_header := DEFAULT_RTPS_HEADER; + rtps_header.version := PROTOCOLVERSION_1_0; + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + -- Valid RTPS Header from here on + rtps_header := DEFAULT_RTPS_HEADER; + + -- *DATA SUBMESSAGE* + report "Sending valid DATA [Empty Submessage]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [Empty DATA] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending valid DATA [Meta Traffic, Both Endianness]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [META Traffic, Big Endian] (Expected) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_sub.data := RAND_DATA; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Valid DATA [META Traffic, Little Endian] (Expected) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending valid DATA [User Traffic]" severity note; + -- UDP Header + gen_udp_header(UDP_USER, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [USER Traffic, Big Endian] (Expected) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_sub.data := RAND_DATA; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_USER.src, FALSE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending valid DATA [Extra Header Bytes]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [+7 Unknown Header Bytes] (Expected) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_sub.data := RAND_DATA; + rtps_sub.octetsToInlineQos := int(23,16); + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid DATA [DATA and KEY Flag set]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [Invalid Flags] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_sub.flags(SUBMESSAGE_KEY_FLAG_POS) := '1'; + rtps_sub.data := RAND_DATA; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid DATA [Packet Size too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [SubLength > PackeSize] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_sub.data := RAND_DATA; + gen_rtps_submessage(rtps_sub, stimulus); + stimulus.length := stimulus.length-1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid DATA [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_sub.data := RAND_DATA; + rtps_sub.submessageLength := int(16,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid DATA [Invalid writerSN]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid DATA [Invalid writerSN] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + rtps_sub.data := RAND_DATA; + rtps_sub.writerSN := (others => (others => '0')); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + + -- *ACKNACK SUBMESSAGE* + report "Sending valid ACKNACK [Meta Traffic, Both Endianness]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid ACKNACK [META Traffic, Big Endian] (Expected) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_ACKNACK; + rtps_sub.readerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Valid ACKNACK [META Traffic, Little Endian] (Expected) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending valid ACKNACK [User Traffic]" severity note; + -- UDP Header + gen_udp_header(UDP_USER, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid ACKNACK [USER Traffic, Big Endian] (Expected) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_ACKNACK; + rtps_sub.readerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_USER.src, FALSE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid ACKNACK [Packet Size too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid ACKNACK [SubLength > PacketSize] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_ACKNACK; + rtps_sub.readerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + stimulus.length := stimulus.length-1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid ACKNACK [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid ACKNACK [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_ACKNACK; + rtps_sub.readerId := DEFAULT_ENTITYID; + rtps_sub.submessageLength := int(20,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid ACKNACK [ReaderSNState invalid (Base invalid)]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid ACKNACK [readerSNState invalid (Base Invalid)] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_ACKNACK; + rtps_sub.readerId := DEFAULT_ENTITYID; + rtps_sub.readerSNState.base := (others => (others => '0')); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid DATA (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid ACKNACK [ReaderSNState invalid (NumBits invalid)]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid ACKNACK [readerSNState invalid (NumBits Invalid)] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_ACKNACK; + rtps_sub.readerId := DEFAULT_ENTITYID; + rtps_sub.readerSNState.numBits := int(257, 32); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid DATA (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + -- *GAP SUBMESSAGE* + report "Sending valid GAP [Meta Traffic, Both Endianness]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid GAP [META Traffic, Big Endian] + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_GAP; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Valid GAP [META Traffic, Little Endian] + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending valid GAP [User Traffic]" severity note; + -- UDP Header + gen_udp_header(UDP_USER, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid GAP [User Traffic, Big Endian] + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_GAP; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_USER.src, FALSE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid GAP [Packet Size too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid GAP [SubLength > PacketSize] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_GAP; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + stimulus.length := stimulus.length-1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid GAP [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid GAP [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_GAP; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.submessageLength := int(24,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid GAP [GapStart invalid]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid GAP [GapStart invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_GAP; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.gapStart := (others => (others => '0')); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid GAP [GapList invalid (Base invalid)]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid GAP [GapList invalid (Base invalid)] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_GAP; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.gapList.base := (others => (others => '0')); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid GAP [GapList invalid (NumBits invalid)]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid GAP [GapList invalid (NumBits invalid)] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_GAP; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.gapList.numBits := int(257,32); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + + -- *HEARTBEAT SUBMESSAGE* + report "Sending valid HEARTBEAT [Meta Traffic, Both Endianness]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid HEARTBEAT [META Traffic, Big Endian] (Expected) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Valid HEARTBEAT [META Traffic, Little Endian] (Expected) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending valid HEARTBEAT [User Traffic]" severity note; + -- UDP Header + gen_udp_header(UDP_USER, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid HEARTBEAT [USER Traffic, Big Endian] (Expected) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + gen_rtps_handler_out(rtps_sub, UDP_USER.src, FALSE, TIME_INVALID, rtps_header.guidPrefix, reference); + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid HEARTBEAT [Packet Size too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid HEARTBEAT [SubLength > PackeSize] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + stimulus.length := stimulus.length-1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid HEARTBEAT [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid HEARTBEAT [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.submessageLength := int(24,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid HEARTBEAT [FirstSN invalid]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid HEARTBEAT [FirstSN invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.firstSN := (others => (others => '0')); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid HEARTBEAT [LastSN invalid]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid HEARTBEAT [LastSN invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.lastSN := (others => (others => '1')); -- Negative + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid HEARTBEAT [LastSN < FirstSN - 1]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid HEARTBEAT [LastSN invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT; + rtps_sub.writerId := DEFAULT_ENTITYID; + rtps_sub.firstSN := ((others => '0'), unsigned(int(5,WORD_WIDTH))); -- 5 + rtps_sub.lastSN := ((others => '0'), unsigned(int(1,WORD_WIDTH))); -- 1 + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + -- *INFO_SOURCE SUBMESSAGE* + report "Testing INFO_SOURCE interpretation" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_header.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_SOURCE [Big Endian] (Change Source GUID Prefix) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_SRC; + rtps_sub.guidPrefix(0) := rand_slv(WORD_WIDTH); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_SOURCE [Little Endian] (Change Source GUID Prefix) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + rtps_sub.guidPrefix(0) := rand_slv(WORD_WIDTH); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_SOURCE [Protocol Major Version Missmatch] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_SRC; + rtps_sub.version := PROTOCOLVERSION_1_0; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid INFO_SOURCE [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid INFO_SOURCE [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_SRC; + rtps_sub.submessageLength := int(16,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + + -- *INFO_DESTINATION SUBMESSAGE* + report "Testing INFO_DESTINATION interpretation" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_DESTINATION [Expected GUID Prefix, Big Endian] (No Change) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_DST; + rtps_sub.guidPrefix := GUIDPREFIX; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_DESTINATION [Expected GUID Prefix, Little Endian] (No Change) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_DESTINATION [Unexpected GUID Prefix] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_DST; + rtps_sub.guidPrefix := DEFAULT_GUIDPREFIX; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid INFO_DESTINATION [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid INFO_DESTINATION [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_DST; + rtps_sub.submessageLength := int(8,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + + -- *INFO_REPLY SUBMESSAGE* + report "Testing INFO_REPLY interpretation" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_REPLY [Empty] (No Change) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_REPLY; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_REPLY [2 valid Unicast, Big Endian] (Second Unicast applied) + rtps_sub.unicastLocatorList.numLocators := int(2,32); + rtps_sub.unicastLocatorList.locator(0) := gen_rand_loc; + rtps_sub.unicastLocatorList.locator(1) := gen_rand_loc; + gen_rtps_submessage(rtps_sub, stimulus); + tmp_loc := rtps_sub.unicastLocatorList.locator(1); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, tmp_loc, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_REPLY [1 valid Unicast, 1 invalid Unicast, 2 valid Multicast, Little Endian] (Second Multicast applied) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + rtps_sub.unicastLocatorList.locator(1).portn := (others => '0'); -- Invalid Port + rtps_sub.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '1'; + rtps_sub.multicastLocatorList.numLocators := int(2,32); + rtps_sub.multicastLocatorList.locator(0) := gen_rand_loc; + rtps_sub.multicastLocatorList.locator(1) := gen_rand_loc; + gen_rtps_submessage(rtps_sub, stimulus); + tmp_loc := rtps_sub.multicastLocatorList.locator(1); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, tmp_loc, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_REPLY [2 invalid Unicast, 2 invalid Multicast] (No change) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '0'; + rtps_sub.unicastLocatorList.locator(0).addr := (others => '0'); -- Invalid Address + rtps_sub.multicastLocatorList.locator(0).addr := (others => '0'); -- Invalid Address + rtps_sub.multicastLocatorList.locator(1).portn := (others => '0'); -- Invalid Port + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, tmp_loc, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid INFO_REPLY [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid INFO_REPLY [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_REPLY; + rtps_sub.unicastLocatorList.numLocators := int(2,32); + rtps_sub.unicastLocatorList.locator(0) := gen_rand_loc; + rtps_sub.unicastLocatorList.locator(1) := gen_rand_loc; + rtps_sub.submessageLength := int(48,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + + -- *INFO_REPLY_IP4 SUBMESSAGE* + report "Testing INFO_REPLY_IP4 interpretation" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_REPLY_IP4 [Valid Unicast, Big Endian] (Unicast applied) + report "A" severity NOTE; + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_REPLY_IP4; + rtps_sub.unicastLocator := gen_rand_loc; + report "B" severity NOTE; + gen_rtps_submessage(rtps_sub, stimulus); + report "C" severity NOTE; + tmp_loc := rtps_sub.unicastLocator; + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, tmp_loc, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_REPLY_IP4 [Invalid Unicast, Valid Multicast, Little Endian] (Multicast applied) + report "E" severity NOTE; + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + rtps_sub.flags(SUBMESSAGE_MULTICAST_FLAG_POS) := '1'; + rtps_sub.unicastLocator.addr := (others => '0'); -- Invalid Address + rtps_sub.multicastLocator := gen_rand_loc; + gen_rtps_submessage(rtps_sub, stimulus); + tmp_loc := rtps_sub.multicastLocator; + report "F" severity NOTE; + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, tmp_loc, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_REPLY_IP4 [Invalid Unicast, Invalid Multicast] (No change) + report "G" severity NOTE; + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '0'; + rtps_sub.multicastLocator.portn := (others => '0'); -- Invalid Port + gen_rtps_submessage(rtps_sub, stimulus); + report "H" severity NOTE; + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, tmp_loc, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + report "I" severity NOTE; + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid INFO_REPLY_IP4 [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid INFO_REPLY_IP4 [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_REPLY_IP4; + rtps_sub.submessageLength := int(4,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + -- *INFO TS* + report "Testing INFO_TIMESTAMP interpretation" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_TIMESTAMP [Big Endian] (Change Timestamp) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_TS; + rtps_sub.timestamp := (unsigned(rand_slv(WORD_WIDTH)), unsigned(rand_slv(WORD_WIDTH))); + gen_rtps_submessage(rtps_sub, stimulus); + ts := rtps_sub.timestamp; + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, ts, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_TIMESTAMP [Little Endian] (Change Timestamp) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '1'; + rtps_sub.timestamp := (unsigned(rand_slv(WORD_WIDTH)), unsigned(rand_slv(WORD_WIDTH))); + gen_rtps_submessage(rtps_sub, stimulus); + ts := rtps_sub.timestamp; + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, ts, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid INFO_TIMESTAMP [Invalidate Time] (Invalidate Timestamp) + rtps_sub.flags(SUBMESSAGE_ENDIAN_FLAG_POS) := '0'; + rtps_sub.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) := '1'; + gen_rtps_submessage(rtps_sub, stimulus); + ts := TIME_INVALID; + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, ts, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + report "Sending invalid INFO_TMESTAMP [Submessage Length too small]" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Invalid INFO_TIMESTAMP [SubLength invalid] (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_INFO_TS; + rtps_sub.submessageLength := int(4,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Dropped) + gen_rtps_submessage(rtps_data, stimulus); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + + -- *PAD* + report "Testing PAD interpretation" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid PAD (No Change) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_PAD; + rtps_sub.submessageLength := int(28,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + + -- *UNKNOWN* + report "Testing unknown Submessage handling" severity note; + -- UDP Header + gen_udp_header(UDP_META, stimulus); + -- RTPS Header + gen_rtps_header(rtps_header, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid DATA_FRAG (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA_FRAG; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid HEARTBEAT_FRAG (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_HEARTBEAT_FRAG; + rtps_sub.writerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Valid NACK_FRAG (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_NACK_FRAG; + rtps_sub.readerId := DEFAULT_ENTITYID; + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- UKNOWN (Dropped) + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := (others => '1'); + rtps_sub.submessageLength := int(28,16); + gen_rtps_submessage(rtps_sub, stimulus); + -- Valid Data (Expected) + gen_rtps_submessage(rtps_data, stimulus); + gen_rtps_handler_out(rtps_data, UDP_META.src, TRUE, TIME_INVALID, rtps_sub.guidPrefix, reference); + rtps_data.writerSN := rtps_data.writerSN + 1; + -- Finalize Packet + fix_udp_packet(stimulus); + wait_on_complete; + check_cnt := check_cnt + reference.length; + stimulus.length := 0; + reference.length := 0; + + AlertIf(GetAffirmCount < check_cnt, "Incomplete test run"); + ReportAlerts; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for 25 ns; + clk <= '1'; + wait for 25 ns; + end process; + + fifo_ctl_prc : process + begin + in_empty <= '0'; + builtin_full <= '0'; + user_full <= (others => '0'); + wait until rising_edge(clk); + in_empty <= '1'; + builtin_full <= '0'; + user_full <= (others => '0'); + wait until rising_edge(clk); + in_empty <= '0'; + builtin_full <= '1'; + user_full <= (others => '0'); + wait until rising_edge(clk); + in_empty <= '0'; + builtin_full <= '0'; + user_full <= (others => '1'); + wait until rising_edge(clk); + end process; + + alert_prc : process(all) + begin + if rising_edge(clk) then + alertif(in_empty = '1' and rd_sig = '1', "Input FIFO read signal high while empty signal high", ERROR); + alertif(builtin_full = '1' and builtin_wr = '1', "Builtin FIFO write signal high while full signal high", ERROR); + alertif(user_full /= (0 to NUM_ENDPOINTS-1 => '0') and (user_wr /= (0 to NUM_ENDPOINTS-1 => '0')), "User FIFO write signal high while full signal high", ERROR); + end if; + --wait until rising_edge(clk); + --wait for 10 ns; + --alertif(not (in_empty = '1' and rd_sig = '1'), "Input FIFO read signal high while empty signal high", ERROR); + --alertif(not (builtin_full = '1' and builtin_wr = '1'), "Builtin FIFO write signal high while full signal high", ERROR); + --alertif(not (user_full /= (0 to NUM_ENDPOINTS-1 => '0') and (user_wr /= (0 to NUM_ENDPOINTS-1 => '0'))), "User FIFO write signal high while full signal high", ERROR); + end process; + + input_prc : process(all) + begin + data_in <= stimulus.data(cnt_stim); + + if rising_edge(clk) then + if (reset = '1') then + cnt_stim <= 0; + packet_sent <= '0'; + else + if (cnt_stim = stimulus.length) then + -- Packet Send, wait for output_prc and stimulus_prc + packet_sent <= '1'; + cnt_stim <= 0; + elsif (rd_sig = '1') then + cnt_stim <= cnt_stim + 1; + packet_sent <= '0'; + end if; + end if; + end if; + end process; + + + + output_prc : process(all) + begin + if rising_edge(clk) then + if (reset = '1') then + cnt_ref <= 0; + packet_checked <= '0'; + else + if (cnt_ref = reference.length) then + -- Packet Check Done + cnt_ref <= 0; + packet_checked <= '1'; + elsif (builtin_wr = '1' or user_wr /= (0 to NUM_ENDPOINTS-1 => '0')) then + AffirmIfEqual(data_out, reference.data(cnt_ref)); + cnt_ref <= cnt_ref + 1; + packet_checked <= '0'; + end if; + end if; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/testbench.pro b/src/Tests/testbench.pro new file mode 100644 index 0000000..6456286 --- /dev/null +++ b/src/Tests/testbench.pro @@ -0,0 +1,14 @@ +# Compile OSVVM Library +include ../OSVVM/osvvm.pro + +# Compile +library Level0-rtps_handler +analyze ../math_pkg.vhd +analyze ../rtps_package.vhd +analyze ../user_config.vhd +analyze ../rtps_config_package.vhd +analyze ../rtps_test_package.vhd +analyze ../rtps_handler.vhd +analyze Level_0/rtps_handler_test1.vhd + +simulate rtps_handler_test1 \ No newline at end of file diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index 7bb9ea9..57a51ed 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -257,11 +257,11 @@ package body rtps_config_package is begin ret := 0; for i in 0 to str'length-1 loop - for j in 0 to (str(i)'length/8)-1 loop + for j in 0 to (WORD_WIDTH/BYTE_WIDTH)-1 loop -- Count Bytes ret := ret + 1; -- Exit on first NULL byte (NULL Byte included in count) - if (str(i)(str(i)'length-j*8-1 downto str(i)'length-j*8-8) = (7 downto 0 => '0')) then + if (str(i)(WORD_WIDTH-(j*BYTE_WIDTH)-1 downto WORD_WIDTH-(j*BYTE_WIDTH)-BYTE_WIDTH) = (BYTE_WIDTH-1 downto 0 => '0')) then exit; end if; end loop; @@ -613,8 +613,7 @@ package body rtps_config_package is len := len + 1; ret.data(ind+len):= DOMAIN_ID; -- DOMAIN TAG - -- TODO: Check if Guard works - if (USER_DOMAIN_TAG /= "") then + if (DOMAIN_TAG /= EMPTY_STRING) then tmp := string_len(DOMAIN_TAG); len := len + 1; ret.data(ind+len) := PID_DOMAIN_TAG & std_logic_vector(to_unsigned((round_div(tmp,4)+1)*4, 16)); diff --git a/src/rtps_handler.vhd b/src/rtps_handler.vhd index 7260158..ada0cb0 100644 --- a/src/rtps_handler.vhd +++ b/src/rtps_handler.vhd @@ -182,7 +182,7 @@ begin data_in_aligned <= input(39 downto 8); when "10" => data_in_aligned <= input(47 downto 16); - when "11" => + when others => --"11" data_in_aligned <= input(55 downto 24); end case; end process; @@ -1008,7 +1008,7 @@ begin when PUSH_PAYLOAD_HEADER => -- NOTE: This is a synchronised push on potentially multiple output FIFOs. If one FIFO gets full, the process stalls for all FIFOs. -- Output FIFO Guard - if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'reverse_range => '0'))) then + if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'range => '0'))) then cnt_next <= cnt + 1; case (cnt) is @@ -1076,7 +1076,7 @@ begin when PUSH_PAYLOAD => -- NOTE: This is a synchronised push on potentially multiple output FIFOs. If one FIFO gets full, the process stalls for all FIFOs. -- Output FIFO Guard - if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'reverse_range => '0'))) then + if (builtin_endpoint = '1' and builtin_full = '0') or (builtin_endpoint = '0' and ((user_endpoint and user_full) = (user_endpoint'range => '0'))) then cnt_next <= cnt + 1; case (opcode) is diff --git a/src/rtps_package.vhd b/src/rtps_package.vhd index 76f2358..ae5d43f 100644 --- a/src/rtps_package.vhd +++ b/src/rtps_package.vhd @@ -2,6 +2,7 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use ieee.math_real.CEIL; +use ieee.math_real.TRUNC; package rtps_package is @@ -49,7 +50,6 @@ package rtps_package is -- *TYPES DEFINITION* -- Generic Types - type STRING_WORD_ARRAY_TYPE is array (0 to ((256*BYTE_WIDTH)/WORD_WIDTH)-1) of std_logic_vector(WORD_WIDTH-1 downto 0); -- Strings are constrained to 256 Characters type DOUBLE_WORD_ARRAY is array (0 to 1) of unsigned(WORD_WIDTH-1 downto 0); -- RTPS -- TODO: Define unconstrained WORD_ARRAY and define constrained subtypes @@ -260,7 +260,7 @@ package rtps_package is constant RELIABLE_RELIABILITY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := std_logic_vector(to_unsigned(2,CDR_ENUMERATION_WIDTH)); constant DEFAULT_RELIABILTY_QOS : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0) := RELIABLE_RELIABILITY_QOS; -- MAX BLOCKING TIME (RELIABILITY) - constant DEFAULT_MAX_BLOCKING_TIME : DURATION_TYPE := gen_duration(0,100 * (10**6)); -- 100 ms + constant DEFAULT_MAX_BLOCKING_TIME : DURATION_TYPE; --Deferred to Package Body (100 ms) -- TRANSPORT_PRIORITY constant DEFAULT_TRANSPORT_PRIORITY_QOS : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); -- LIFESPAN @@ -295,7 +295,7 @@ package rtps_package is constant DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED constant DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE: std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := std_logic_vector(to_signed(-1,CDR_LONG_WIDTH)); -- LENGTH_UNLIMITED - constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE := gen_duration(100, 0); -- 100 s + constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE; -- Deferred to package Body (100 s) -- *BUILTIN ENDPOINT SET POSITIONS* constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER : natural := 0; @@ -358,6 +358,32 @@ end package; package body rtps_package is + function gen_duration(s,ns : integer) return DURATION_TYPE is + variable ret : DURATION_TYPE := (others => (others => '0')); + -- "unit" is the value of "ret(1)" equal to 1 nanosecond + -- (1 / 2^-32) * 10^-9 + constant unit : real := 4.294967296; + constant sec : natural := 10**9; + constant half_sec : natural := sec/2; + begin + assert (ns < 10**9) report "ns argument has to be less than a second" severity failure; + ret(0) := to_unsigned(s, 32); + + -- If Fraction Bit is >= 500 ms it cannot be represented as a natural (because naturals/integers are signed). + -- So we handle that manualy + if (ns >= half_sec) then + ret(1)(31) := '1'; + ret(1) := to_unsigned(natural(CEIL(real(ns/2)*unit)),32); + else + ret(1) := to_unsigned(natural(CEIL(real(ns)*unit)),32); + end if; + + return ret; + end function; + + constant DEFAULT_MAX_BLOCKING_TIME : DURATION_TYPE := gen_duration(0,100 * (10**6)); -- 100 ms + constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE := gen_duration(100, 0); -- 100 s + function convert_from_double_word (input: DOUBLE_WORD_ARRAY) return unsigned is variable ret : unsigned(63 downto 0) := (others => '0'); begin @@ -516,16 +542,4 @@ package body rtps_package is return ret; end function; - function gen_duration(s,ns : integer) return DURATION_TYPE is - variable ret : DURATION_TYPE := (others => (others => '0')); - -- "unit" is the value of "ret(1)" equal to 1 nanosecond - -- (1 / 2^-32) * 10^-9 - constant unit : real := 4.294967296; - begin - assert (ns < 10**9) report "ns argument has to be less than a second" severity failure; - ret(0) := to_unsigned(s, 32); - ret(1) := to_unsigned(natural(CEIL(real(ns)*unit)),32); - return ret; - end function; - end package body; diff --git a/src/rtps_test_package.vhd b/src/rtps_test_package.vhd index f19fb27..9555904 100644 --- a/src/rtps_test_package.vhd +++ b/src/rtps_test_package.vhd @@ -4,21 +4,15 @@ use ieee.numeric_std.all; use ieee.math_real.UNIFORM; use ieee.math_real.ROUND; +use work.math_pkg.all; +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; + package rtps_test_package is - -- converts std_logic into a character - function chr(sl: std_logic) return character; - -- converts std_logic_vector into a string (binary base) - function str(slv: std_logic_vector) return string; - -- converts std_logic into a string - function str(sl: std_logic) return string; - impure function rand_int(min_val, max_val : integer) return integer; - impure function rand_slv(len : integer) return std_logic_vector; - function gen_rand_addr return LOCATOR_TYPE; - function int(n : integer, width : natural) return std_logic_vector; - - constant DEFAULT_GUIDPREFIX := (0 => rand_slv(WORD_WIDTH), 1 => rand_slv(WORD_WIDTH), 2 => rand_slv(WORD_WIDTH)); - constant DEFAULT_ENTITYID := rand_slv(ENTITYID_WIDTH); + constant DEFAULT_GUIDPREFIX : GUIDPREFIX_TYPE; -- Deferred to Package Body + constant DEFAULT_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0); -- Deferred to Package Body type TEST_PACKET_TYPE is record -- Limit Packet Size to 2^16 (IPv4 size limit) @@ -26,17 +20,16 @@ package rtps_test_package is length : natural; end record; + constant LOCATOR_PORT_WIDTH : natural := CDR_LONG_WIDTH; + constant LOCATOR_ADDR_WIDTH : natural := 4*CDR_LONG_WIDTH; + type LOCATOR_TYPE is record kind : std_logic_vector(LOCATOR_KIND_WIDTH-1 downto 0); - port_ : std_logic_vector(31 downto 0); - addr : std_logic_vector(127 downto 0); + portn : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + addr : std_logic_vector(LOCATOR_ADDR_WIDTH-1 downto 0); end record; - constant EMPTY_LOCATOR : LOCATOR_TYPE := ( - kind => LOCATOR_KIND_INVALID, - port_ => (others => '0'), - addr => (others => '0') - ); + constant EMPTY_LOCATOR : LOCATOR_TYPE; -- Deferred to Package Body -- Limit Number of Locators to maximum number that fits in a maximum length RTPS Submessage type LOCATOR_TYPE_ARRAY is array (0 to ((2**16)/4)/6) of LOCATOR_TYPE; @@ -46,10 +39,7 @@ package rtps_test_package is locator : LOCATOR_TYPE_ARRAY; end record; - constant EMPTY_LOCATOR_LIST : LOCATOR_LIST_TYPE := ( - numLocators => (others => '0'), - locator => (others => EMPTY_LOCATOR) - ); + constant EMPTY_LOCATOR_LIST : LOCATOR_LIST_TYPE; -- Deferred to Package Body type SEQUENCENUMBER_SET_TYPE is record base : SEQUENCENUMBER_TYPE; @@ -57,11 +47,7 @@ package rtps_test_package is bitmap : std_logic_vector(0 to 255); end record; - constant DEFAULT_SEQUENCENUMBER_SET : SEQUENCENUMBER_SET_TYPE := ( - base => FIRST_SEQUENCENUMBER, - numBits => (others => '0'), - bitmap => (others => '0') - ); + constant DEFAULT_SEQUENCENUMBER_SET : SEQUENCENUMBER_SET_TYPE; -- Deferred to package Body type FRAGMENTNUMBER_SET_TYPE is record base : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); @@ -69,11 +55,7 @@ package rtps_test_package is bitmap : std_logic_vector(0 to 255); end record; - constant DEFAULT_FRAGMENTNUMBER_SET : FRAGMENTNUMBER_SET_TYPE := ( - base => int(1,CDR_LONG_WIDTH), - numBits => (others => '0'), - bitmap => (others => '0') - ); + constant DEFAULT_FRAGMENTNUMBER_SET : FRAGMENTNUMBER_SET_TYPE; -- Deferred to Package Body -- Valid Destination Locators type DEST_LOCATOR_LIST_TYPE is record @@ -81,59 +63,15 @@ package rtps_test_package is user : LOCATOR_LIST_TYPE; end record; - constant DEST_LOC : DEST_LOCATOR_LIST_TYPE := ( - meta => ( - numLocators => int(4,CDR_LONG_WIDTH), - locator => ( - 0 => ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => META_IPv4_MULTICAST_PORT, - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => DEFAULT_META_ADDR - ), - 1 => ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => META_IPv4_UNICAST_PORT, - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => DEFAULT_META_ADDR - ), - 2 => ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => META_IPv4_MULTICAST_PORT, - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => DEFAULT_ADDR - ), - 3 => ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => META_IPv4_UNICAST_PORT, - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => DEFAULT_ADDR - ) - ), - user => ( - numLocators => int(2,CDR_LONG_WIDTH), - locator => ( - 0 => ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => USER_IPv4_MULTICAST_PORT, - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => DEFAULT_ADDR - ), - 1 => ( - kind => LOCATOR_KIND_UDPv4, - port_(UDP_PORT_WIDTH-1 downto 0) => USER_IPv4_UNICAST_PORT, - addr(IPv4_ADDRESS_WIDTH-1 downto 0) => DEFAULT_ADDR - ) - ) - ); + constant DEST_LOC : DEST_LOCATOR_LIST_TYPE; -- Deferred to Package Body -- *UDP HEADER* type UDP_HEADER_TYPE is record src : LOCATOR_TYPE; dest : LOCATOR_TYPE; - is_meta : boolean; - end type; + end record; - constant DEFAULT_UDP_HEADER : UDP_HEADER_TYPE := ( - src => EMPTY_LOCATOR, - dest => EMPTY_LOCATOR, - is_meta => FALSE - ); + constant DEFAULT_UDP_HEADER : UDP_HEADER_TYPE; -- Deferred to Package Body procedure gen_udp_header(ref : in UDP_HEADER_TYPE; output : inout TEST_PACKET_TYPE); procedure fix_udp_packet(output : inout TEST_PACKET_TYPE); @@ -146,316 +84,48 @@ package rtps_test_package is guidPrefix : GUIDPREFIX_TYPE; end record; - constant DEFAULT_RTPS_HEADER : RTPS_HEADER_TYPE := ( - protocol => PROTOCOL_RTPS, - version => PROTOCOLVERSION_2_4, - vendorId => VENDORID_UNKNOWN, - guidPrefix => DEFAULT_GUIDPREFIX - ); + constant DEFAULT_RTPS_HEADER : RTPS_HEADER_TYPE; -- Deferred to Package Body procedure gen_rtps_header( ref : in RTPS_HEADER_TYPE; output : inout TEST_PACKET_TYPE); -- *GENERIC RTPS SUBMESSAGE HEADER* - type RTPS_SUBMESSAGE_HEADER_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength: std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - end record; - - procedure gen_rtps_subheader( ref : in RTPS_SUBMESSAGE_HEADER_TYPE; output : inout TEST_PACKET_TYPE); - - -- *ACKNACK* - type RTPS_ACKNACK_SUBMESSAGE_TYPE is record + type RTPS_SUBMESSAGE_TYPE is record submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - readerSNState : SEQUENCENUMBER_SET_TYPE; - count : std_logic_vector(COUNT_WIDTH-1 downto 0); - end record; - - constant DEFAULT_RTPS_ACKNACK_SUBMESSAGE : RTPS_ACKNACK_SUBMESSAGE_TYPE := ( - submessageID => SID_ACKNACK, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', SUBMESSAGE_FINAL_FLAG_POS => '1', others => '0'), - submessageLength => (others => '1'), - readerId => DEFAULT_ENTITYID, - writerId => ENTITYID_UNKNOWN, - readerSNState => DEFAULT_SEQUENCENUMBER_SET, - count => int(1,COUNT_WIDTH) - ); - - procedure gen_acknack( ref : in RTPS_ACKNACK_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - procedure gen_acknack_out(ref : in RTPS_ACKNACK_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE); - - -- *NACK FRAG* - type RTPS_NACK_FRAG_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerSN : SEQUENCENUMBER_TYPE; - fragmentNumberState : FRAGMENTNUMBER_SET_TYPE; - count : std_logic_vector(COUNT_WIDTH-1 downto 0); - end record; - - constant DEFAULT_RTPS_NACK_FRAG_SUBMESSAGE : RTPS_NACK_FRAG_SUBMESSAGE_TYPE := ( - submessageID => SID_NACK_FRAG, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1'), - readerId => DEFAULT_ENTITYID, - writerId => ENTITYID_UNKNOWN, - writerSN => FIRST_SEQUENCENUMBER, - fragmentNumberState => DEFAULT_FRAGMENTNUMBER_SET, - count => int(1,COUNT_WIDTH) - ); - - procedure gen_nack_frag( ref : in RTPS_NACK_FRAG_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *DATA* - type RTPS_DATA_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - extraFlags : std_logic_vector(SUBMESSAGE_DATA_EXTRA_FLAGS_WIDTH-1 downto 0); - octetsToInlineQos : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - sequenceNumber : SEQUENCENUMBER_TYPE; - data : TEST_PACKET_TYPE; - end record; - - constant DEFAULT_RTPS_DATA_SUBMESSAGE : RTPS_DATA_SUBMESSAGE_TYPE := ( - submessageID => SID_DATA, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', SUBMESSAGE_INLINE_QOS_FLAG_POS => '0', SUBMESSAGE_DATA_FLAG_POS => '0', SUBMESSAGE_KEY_FLAG_POS => '0', SUBMESSAGE_NON_STANDARD_PAYLOAD_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1'), - extraFlags => (others => '0'), - octetsToInlineQos => int(16, SUBMESSAGE_LENGTH_WIDTH), - readerId => ENTITYID_UNKNOWN, - writerId => DEFAULT_ENTITYID, - sequenceNumber => FIRST_SEQUENCENUMBER, - data => (length => 0, data => (others => (others => '0'))) - ); - - procedure gen_data( ref : in RTPS_DATA_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - procedure gen_data_out(ref : in RTPS_DATA_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; ts : in TIME_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE); - - -- *DATA FRAG* - type RTPS_DATA_FRAG_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); extraFlags : std_logic_vector(SUBMESSAGE_DATA_EXTRA_FLAGS_WIDTH-1 downto 0); octetsToInlineQos : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - sequenceNumber : SEQUENCENUMBER_TYPE; - fragmentNumber : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + readerSNState : SEQUENCENUMBER_SET_TYPE; + count : std_logic_vector(COUNT_WIDTH-1 downto 0); + writerSN : SEQUENCENUMBER_TYPE; + fragmentNumberState : FRAGMENTNUMBER_SET_TYPE; + data : TEST_PACKET_TYPE; + fragmentStartingNumber : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); fragmentsInSubmessage : std_logic_vector(CDR_SHORT_WIDTH-1 downto 0); fragmentSize : std_logic_vector(CDR_SHORT_WIDTH-1 downto 0); sampleSize : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); - data : TEST_PACKET_TYPE; - end record; - - constant DEFAULT_RTPS_DATA_FRAG_SUBMESSAGE : RTPS_DATA_FRAG_SUBMESSAGE_TYPE := ( - submessageID => SID_DATA_FRAG, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', SUBMESSAGE_INLINE_QOS_FLAG_POS => '0', (SUBMESSAGE_KEY_FLAG_POS-1) => '0', (SUBMESSAGE_NON_STANDARD_PAYLOAD_FLAG_POS-1) => '0', others => '0'), - submessageLength => (others => '1'), - extraFlags => (others => '0'), - octetsToInlineQos => int(28, SUBMESSAGE_LENGTH_WIDTH), - readerId => ENTITYID_UNKNOWN, - writerId => DEFAULT_ENTITYID, - sequenceNumber => FIRST_SEQUENCENUMBER, - fragmentNumber => int(1,CDR_SHORT_WIDTH), - fragmentsInSubmessage => int(1,CDR_SHORT_WIDTH), - fragmentSize => (others => '0'), - sampleSize => (others => '0'), - data => (length => 0, data => (others => (others => '0'))) - ); - - procedure gen_data_frag( ref : in RTPS_DATA_FRAG_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *GAP* - type RTPS_GAP_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - gapStart : SEQUENCENUMBER_TYPE; - gapList : SEQUENCENUMBER_SET_TYPE; - end record; - - constant DEFAULT_RTPS_GAP_SUBMESSAGE : RTPS_GAP_SUBMESSAGE_TYPE := ( - submessageID => SID_GAP, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1'), - readerId => ENTITYID_UNKNOWN, - writerId => ENTITYID_UNKNOWN, - gapStart => FIRST_SEQUENCENUMBER, - gapList => DEFAULT_SEQUENCENUMBER_SET - ); - - procedure gen_gap( ref : in RTPS_GAP_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - procedure gen_gap_out(ref : in RTPS_GAP_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE); - - -- *HEARTBEAT* - type RTPS_HEARTBEAT_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - firstSN : SEQUENCENUMBER_TYPE; - lastSN : SEQUENCENUMBER_TYPE; - count : std_logic_vector(COUNT_WIDTH-1 downto 0); - end record; - - constant DEFAULT_RTPS_HEARTBEAT_SUBMESSAGE : RTPS_HEARTBEAT_SUBMESSAGE_TYPE := ( - submessageID => SID_HEARTBEAT, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', SUBMESSAGE_FINAL_FLAG_POS => '1', SUBMESSAGE_LIVELINESS_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1'), - readerId => ENTITYID_UNKNOWN, - writerId => DEFAULT_ENTITYID, - firstSN => FIRST_SEQUENCENUMBER, - lastSN => (others => (others => '0')), - count => int(1, COUNT_WIDTH), - ); - - procedure gen_heartbeat( ref : in RTPS_HEARTBEAT_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - procedure gen_heartbeat_out(ref : in RTPS_HEARTBEAT_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE); - - -- *HEARTBEAT FRAG* - type RTPS_HEARTBEAT_FRAG_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - readerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerId : std_logic_vector(ENTITYID_WIDTH-1 downto 0); - writerSN : SEQUENCENUMBER_TYPE; - lastFragmentNum : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); - count : std_logic_vector(COUNT_WIDTH-1 downto 0); - end record; - - constant DEFAULT_RTPS_HEARTBEAT_FRAG_SUBMESSAGE : RTPS_HEARTBEAT__FRAG_SUBMESSAGE_TYPE := ( - submessageID => SID_HEARTBEAT_FRAG, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1'), - readerId => ENTITYID_UNKNOWN, - writerId => DEFAULT_ENTITYID, - writerSN => FIRST_SEQUENCENUMBER, - lastFragmentNum => int(1,CDR_LONG_WIDTH), - count => int(1, COUNT_WIDTH) - ); - - procedure gen_heartbeat_frag( ref : in RTPS_HEARTBEAT_FRAG_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *INFO DESTINATION* - type RTPS_INFO_DESTINATION_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - guidPrefix : GUIDPREFIX_TYPE; - end record; - - constant DEFAULT_RTPS_INFO_DESTINATION_SUBMESSAGE : RTPS_INFO_DESTINATION_SUBMESSAGE_TYPE := ( - submessageID => SID_INFO_DST, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1'), - guidPrefix => DEFAULT_GUIDPREFIX - ); - - procedure gen_info_dest( ref : in RTPS_INFO_DESTINATION_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *INFO REPLY* - type RTPS_INFO_REPLY_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - unicastLocatorList : LOCATOR_LIST_TYPE; - multicastLocatorList: LOCATOR_LIST_TYPE; - end record; - - constant DEFAULT_RTPS_INFO_REPLY_SUBMESSAGE : RTPS_INFO_REPLY_SUBMESSAGE_TYPE := ( - submessageID => SID_INFO_REPLY, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', SUBMESSAGE_MULTICAST_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1') - unicastLocatorList => EMPTY_LOCATOR_LIST, - multicastLocatorList=> EMPTY_LOCATOR_LIST - ); - - procedure gen_info_reply( ref : in RTPS_INFO_REPLY_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *INFO SOURCE* - type RTPS_INFO_SOURCE_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength: std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - unused : std_logic_vector(31 downto 0); - version : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0); - vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0); - guidPrefix : GUIDPREFIX_TYPE; - end record; - - constant DEFAULT_RTPS_INFO_SOURCE_SUBMESSAGE : RTPS_INFO_SOURCE_SUBMESSAGE_TYPE := ( - submessageID => SID_INFO_SRC, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', others => '0'), - submessageLength=> (others => '1'), - unused => (others => '0'), - version => PROTOCOLVERSION_2_4, - vendorId => VENDORID_UNKNOWN, - guidPrefix => DEFAULT_GUIDPREFIX - ); - - procedure gen_info_src( ref : in RTPS_INFO_SOURCE_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *INFO TIMESTAMP* - type RTPS_INFO_TIMESTAMP_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength: std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); - timestamp : TIME_TYPE; - end record; - - constant DEFAULT_RTPS_INFO_TIMESTAMP_SUBMESSAGE : RTPS_INFO_TIMESTAMP_SUBMESSAGE_TYPE := ( - submessageID => SID_INFO_TS - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', SUBMESSAGE_INVALIDATE_FLAG_POS => '1', others => '0'), - submessageLength=> (others => '1'), - timestamp => (others => (others => '0')); - ); - - procedure gen_info_ts( ref : in RTPS_INFO_TIMESTAMP_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *PAD* - subtype RTPS_PAD_SUBMESSAGE_TYPE is RTPS_SUBMESSAGE_HEADER_TYPE; - - constant DEFAULT_RTPS_PAD_SUBMESSAGE : RTPS_PAD_SUBMESSAGE_TYPE := ( - submessageID => SID_PAD, - flags => (others => '0'), - submessageLength=> (others => '0') - ); - - procedure gen_pad( ref : in RTPS_PAD_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); - - -- *INFO REPLY IPv4* - type RTPS_INFO_REPLY_IP4_SUBMESSAGE_TYPE is record - submessageID : std_logic_vector(SUBMESSAGE_ID_WIDTH-1 downto 0); - flags : std_logic_vector(SUBMESSAGE_FLAGS_WIDTH-1 downto 0); - submessageLength : std_logic_vector(SUBMESSAGE_LENGTH_WIDTH-1 downto 0); + gapStart : SEQUENCENUMBER_TYPE; + gapList : SEQUENCENUMBER_SET_TYPE; + firstSN : SEQUENCENUMBER_TYPE; + lastSN : SEQUENCENUMBER_TYPE; + lastFragmentNum : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + guidPrefix : GUIDPREFIX_TYPE; + unicastLocatorList : LOCATOR_LIST_TYPE; + multicastLocatorList : LOCATOR_LIST_TYPE; unicastLocator : LOCATOR_TYPE; multicastLocator : LOCATOR_TYPE; + unused : std_logic_vector(31 downto 0); + version : std_logic_vector(PROTOCOLVERSION_WIDTH-1 downto 0); + vendorId : std_logic_vector(VENDORID_WIDTH-1 downto 0); + timestamp : TIME_TYPE; end record; - constant DEFAULT_RTPS_INFO_REPLY_IP4_SUBMESSAGE : RTPS_INFO_REPLY_IP4_SUBMESSAGE_TYPE := ( - submessageID => SID_INFO_REPLY_IP4, - flags => (SUBMESSAGE_ENDIAN_FLAG_POS => '0', SUBMESSAGE_MULTICAST_FLAG_POS => '0', others => '0'), - submessageLength => (others => '1'), - unicastLocator => EMPTY_LOCATOR, - multicastLocator => EMPTY_LOCATOR - ); + constant DEFAULT_RTPS_SUBMESSAGE : RTPS_SUBMESSAGE_TYPE; -- Deferred to Package Body - procedure gen_info_reply_ip4( ref : in RTPS_INFO_REPLY_IP4_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); + procedure gen_rtps_submessage( ref : in RTPS_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE); + procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; ts : in TIME_TYPE; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE); type PARTICIPANT_DATA_TYPE is record littleEndian : std_logic; @@ -476,24 +146,7 @@ package rtps_test_package is availableBuiltinEndpoints : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); end record; - constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := ( - littleEndian => '0', - domainId => (others => '0'), - domainTag => (others => (others => '0')), - protocolVersion => PROTOCOLVERSION_2_4, - vendorId => VENDORID_UNKNOWN, - guidPrefix => GUIDPREFIX_UNKNOWN, - expectsInlineQoS => (others => '0'), - metatrafficUnicastLocatorList => EMPTY_LOCATOR_LIST, - metatrafficMulticastLocatorList => EMPTY_LOCATOR_LIST, - defaultUnicastLocatorList => (numLocators => int(1,CDR_LONG_WIDTH), - locator(0) => gen_rand_addr), - defaultMulticastLocatorList => EMPTY_LOCATOR_LIST, - leaseDuration => DEFAULT_PARTICIPANT_LEASE_DURATION, - manualLivelinessCount => (others => '0'), - builtinEndpointQoS => (others => '0'), - availableBuiltinEndpoints => (DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER => '1', DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER => '1', others => '0'); - ); + constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE; -- Deferred to Pckage Body procedure gen_participant_announcement( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE); @@ -504,7 +157,7 @@ package rtps_test_package is topic_name : STRING_WORD_ARRAY_TYPE; type_name : STRING_WORD_ARRAY_TYPE; durability : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); - durability_service_cleanup_delay : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + durability_service_cleanup_delay : DURATION_TYPE; durability_service_history : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); durability_service_history_depth : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); durability_service_max_samples : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); @@ -516,13 +169,13 @@ package rtps_test_package is deadline : DURATION_TYPE; latency_budget : DURATION_TYPE; ownership : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); - ownership_strength : std_logic_vector() + ownership_strength : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); liveliness : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); leaseDuration : DURATION_TYPE; time_based_filter : DURATION_TYPE; reliability : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); - max_blocking_time : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); - transport_priority : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + max_blocking_time : DURATION_TYPE; + transportnpriority : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); lifespan : DURATION_TYPE; destination_order : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); -- Represent Data as Strings (Ease of Use) @@ -535,6 +188,192 @@ package rtps_test_package is max_size_serialized : std_logic_vector(CDR_LONG_WIDTH-1 downto 0); end record; + constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE; -- Deferred to Package Body + + procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); + + impure function rand_int(min_val, max_val : integer) return integer; + impure function rand_slv(len : integer) return std_logic_vector; + impure function gen_rand_loc return LOCATOR_TYPE; + function int(n : integer; width : natural) return std_logic_vector; + +end package; + +package body rtps_test_package is + + -- *UTILITY FUNCTIONS* + impure function rand_int(min_val, max_val : integer) return integer is + variable r : real; + variable SEED : natural := 999; + begin + UNIFORM(SEED, SEED, r); + return integer(ROUND(r * real(max_val - min_val + 1) + real(min_val) - 0.5)); + end function; + + impure function rand_slv(len : integer) return std_logic_vector is + variable r : real; + variable slv : std_logic_vector(len - 1 downto 0); + variable SEED : natural := 999; + begin + for i in slv'range loop + uniform(SEED, SEED, r); + slv(i) := '1' when r > 0.5 else '0'; + end loop; + return slv; + end function; + + impure function gen_rand_loc return LOCATOR_TYPE is + variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; + begin + ret.kind := LOCATOR_KIND_UDPv4; + ret.portn(UDP_PORT_WIDTH-1 downto 0) := rand_slv(UDP_PORT_WIDTH); + ret.addr(IPv4_ADDRESS_WIDTH-1 downto 0) := rand_slv(IPv4_ADDRESS_WIDTH); + return ret; + end function; + + function int(n : integer; width : natural) return std_logic_vector is + begin + return std_logic_vector(to_signed(n, width)); + end function; + + -- *DEFERRED DEFINITIONS* + + constant DEFAULT_GUIDPREFIX : GUIDPREFIX_TYPE := (0 => rand_slv(WORD_WIDTH), 1 => rand_slv(WORD_WIDTH), 2 => rand_slv(WORD_WIDTH)); + + constant DEFAULT_ENTITYID : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := rand_slv(ENTITYID_WIDTH); + + constant EMPTY_LOCATOR : LOCATOR_TYPE := ( + kind => LOCATOR_KIND_INVALID, + portn => (others => '0'), + addr => (others => '0') + ); + + constant EMPTY_LOCATOR_LIST : LOCATOR_LIST_TYPE := ( + numLocators => (others => '0'), + locator => (others => EMPTY_LOCATOR) + ); + + constant DEFAULT_SEQUENCENUMBER_SET : SEQUENCENUMBER_SET_TYPE := ( + base => FIRST_SEQUENCENUMBER, + numBits => (others => '0'), + bitmap => (others => '0') + ); + + constant DEFAULT_FRAGMENTNUMBER_SET : FRAGMENTNUMBER_SET_TYPE := ( + base => int(1,CDR_LONG_WIDTH), + numBits => (others => '0'), + bitmap => (others => '0') + ); + + constant DEST_LOC : DEST_LOCATOR_LIST_TYPE := ( + meta => ( + numLocators => int(4,CDR_LONG_WIDTH), + locator => ( + 0 => ( + kind => LOCATOR_KIND_UDPv4, + portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_MULTICAST_PORT, + addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_META_ADDRESS + ), + 1 => ( + kind => LOCATOR_KIND_UDPv4, + portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_UNICAST_PORT, + addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_META_ADDRESS + ), + 2 => ( + kind => LOCATOR_KIND_UDPv4, + portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_MULTICAST_PORT, + addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS + ), + 3 => ( + kind => LOCATOR_KIND_UDPv4, + portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & META_IPv4_UNICAST_PORT, + addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS + ), + others => EMPTY_LOCATOR + ) + ), + user => ( + numLocators => int(2,CDR_LONG_WIDTH), + locator => ( + 0 => ( + kind => LOCATOR_KIND_UDPv4, + portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & USER_IPv4_MULTICAST_PORT, + addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS + ), + 1 => ( + kind => LOCATOR_KIND_UDPv4, + portn => (LOCATOR_PORT_WIDTH-1 downto UDP_PORT_WIDTH => '0') & USER_IPv4_UNICAST_PORT, + addr => (LOCATOR_ADDR_WIDTH-1 downto IPv4_ADDRESS_WIDTH => '0') & DEFAULT_IPv4_ADDRESS + ), + others => EMPTY_LOCATOR + ) + ) + ); + + constant DEFAULT_UDP_HEADER : UDP_HEADER_TYPE := ( + src => EMPTY_LOCATOR, + dest => EMPTY_LOCATOR + ); + + constant DEFAULT_RTPS_HEADER : RTPS_HEADER_TYPE := ( + protocol => PROTOCOL_RTPS, + version => PROTOCOLVERSION_2_4, + vendorId => VENDORID_UNKNOWN, + guidPrefix => DEFAULT_GUIDPREFIX + ); + + constant DEFAULT_RTPS_SUBMESSAGE : RTPS_SUBMESSAGE_TYPE := ( + submessageID => (others => '0'), + flags => (others => '0'), + submessageLength => (others => '1'), + readerId => ENTITYID_UNKNOWN, + writerId => ENTITYID_UNKNOWN, + readerSNState => DEFAULT_SEQUENCENUMBER_SET, + count => int(1,COUNT_WIDTH), + extraFlags => (others => '0'), + octetsToInlineQos => int(16, SUBMESSAGE_LENGTH_WIDTH), + writerSN => FIRST_SEQUENCENUMBER, + fragmentNumberState => DEFAULT_FRAGMENTNUMBER_SET, + data => (length => 0, data => (others => (others => '0'))), + fragmentStartingNumber => int(1,CDR_LONG_WIDTH), + fragmentsInSubmessage => int(1,CDR_SHORT_WIDTH), + fragmentSize => (others => '0'), + sampleSize => (others => '0'), + gapStart => FIRST_SEQUENCENUMBER, + gapList => DEFAULT_SEQUENCENUMBER_SET, + firstSN => FIRST_SEQUENCENUMBER, + lastSN => (others => (others => '0')), + lastFragmentNum => int(1,CDR_LONG_WIDTH), + guidPrefix => DEFAULT_GUIDPREFIX, + unicastLocatorList => EMPTY_LOCATOR_LIST, + multicastLocatorList => EMPTY_LOCATOR_LIST, + unicastLocator => EMPTY_LOCATOR, + multicastLocator => EMPTY_LOCATOR, + unused => (others => '0'), + version => PROTOCOLVERSION_2_4, + vendorId => VENDORID_UNKNOWN, + timestamp => TIME_ZERO + ); + + constant DEFAULT_PARTICIPANT_DATA : PARTICIPANT_DATA_TYPE := ( + littleEndian => '0', + domainId => (others => '0'), + domainTag => (others => (others => '0')), + protocolVersion => PROTOCOLVERSION_2_4, + vendorId => VENDORID_UNKNOWN, + guidPrefix => GUIDPREFIX_UNKNOWN, + entityId => ENTITYID_PARTICIPANT, + expectsInlineQoS => (others => '0'), + metatrafficUnicastLocatorList => EMPTY_LOCATOR_LIST, + metatrafficMulticastLocatorList => EMPTY_LOCATOR_LIST, + defaultUnicastLocatorList => EMPTY_LOCATOR_LIST, -- NOTE: Has to be initialized + defaultMulticastLocatorList => EMPTY_LOCATOR_LIST, + leaseDuration => DEFAULT_PARTICIPANT_LEASE_DURATION, + manualLivelinessCount => (others => '0'), + builtinEndpointQoS => (others => '0'), + availableBuiltinEndpoints => (DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER => '1', DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_WRITER => '1', BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER => '1', others => '0') + ); + constant DEFAULT_ENDPOINT_DATA : ENDPOINT_DATA_TYPE := ( littleEndian => '0', participant => DEFAULT_PARTICIPANT_DATA, @@ -560,7 +399,7 @@ package rtps_test_package is time_based_filter => DEFAULT_TIME_BASED_FILTER_QOS, reliability => DEFAULT_RELIABILTY_QOS, max_blocking_time => DEFAULT_MAX_BLOCKING_TIME, - transport_priority => DEFAULT_TRANSPORT_PRIORITY_QOS, + transportnpriority => DEFAULT_TRANSPORT_PRIORITY_QOS, lifespan => DEFAULT_LIFESPAN_QOS, destination_order => DEFAULT_DESTINATION_ORDER_QOS, user_data => EMPTY_STRING, @@ -572,879 +411,559 @@ package rtps_test_package is max_size_serialized => (others => '0') ); - procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); - -end package; - -package body rtps_test_package is + -- *PACKAGE INTERNAL HELPER FUNCTIONS* procedure store_byte(in_off : in natural range 0 to 3; input : in std_logic_vector(WORD_WIDTH-1 downto 0); out_off : in natural range 0 to 3; output : inout TEST_PACKET_TYPE) is begin - output.data(length)((BYTE_WIDTH*out_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*out_off)) := input(BYTE_WIDTH*in_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*in_off) + output.data(output.length)((BYTE_WIDTH*out_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*out_off)) := input((BYTE_WIDTH*in_off)+BYTE_WIDTH-1 downto (BYTE_WIDTH*in_off)); end procedure; procedure gen_udp_header(ref : in UDP_HEADER_TYPE; output : inout TEST_PACKET_TYPE) is begin -- Source Port & Destination Port - output.data(length) := ref.src.port_(UDP_PORT_WIDTH-1 downto 0) & ref.dest.port_(UDP_PORT_WIDTH-1 downto 0); - output.length := output.length + 1; + output.data(output.length) := ref.src.portn(UDP_PORT_WIDTH-1 downto 0) & ref.dest.portn(UDP_PORT_WIDTH-1 downto 0); + output.length := output.length + 1; -- Length & Checksum - output.data(length) := (others => '0'); - output.length := output.length + 1; + output.data(output.length) := (others => '0'); + output.length := output.length + 1; end procedure; procedure fix_udp_packet(output : inout TEST_PACKET_TYPE) is begin assert (output.length < 2**UDP_PORT_WIDTH) report "Exceeded maximum UDP Packet Size" severity error; - output.data(31 downto 16) := int(output.length*4, UDP_HEADER_LENGTH_WIDTH); + output.data(1)(31 downto 16) := int(output.length*4, UDP_HEADER_LENGTH_WIDTH); -- TODO: Calculate Checksum end procedure; procedure gen_rtps_header( ref : in RTPS_HEADER_TYPE; output : inout TEST_PACKET_TYPE) is begin -- Protocol - output.data(length) := ref.protocol; + output.data(output.length) := ref.protocol; output.length := output.length + 1; -- Protocol Version & Vendor ID - output.data(length) := ref.version & ref.vendorId; + output.data(output.length) := ref.version & ref.vendorId; output.length := output.length + 1; -- GUID Prefix - output.data(length) := ref.guidPrefix(0); + output.data(output.length) := ref.guidPrefix(0); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(1); + output.data(output.length) := ref.guidPrefix(1); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(2); + output.data(output.length) := ref.guidPrefix(2); output.length := output.length + 1; end procedure; - procedure gen_rtps_subheader( ref : in RTPS_SUBMESSAGE_HEADER_TYPE; output : inout TEST_PACKET_TYPE) is + procedure write_sequence_ns(input : in SEQUENCENUMBER_SET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); + -- Sequence Number State (Base) + output.data(output.length) := endian_swap(littleEndian, std_logic_vector(input.base(0))); output.length := output.length + 1; - end procedure; - - procedure gen_acknack( ref : in RTPS_ACKNACK_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); + output.data(output.length) := endian_swap(littleEndian, std_logic_vector(input.base(1))); output.length := output.length + 1; - -- Reader ID - output.data(length) := ref.readerId; + -- Sequence Number State (NumBits) + assert (unsigned(input.numBits) > 256) report "SequenceNS.numbits is higher than 256." severity warning; + output.data(output.length) := endian_swap(littleEndian, input.numBits); output.length := output.length + 1; - -- Writer ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Reader State (Base) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.readerSNState.base(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.readerSNState.base(1))); - output.length := output.length + 1; - -- Reader State (NumBits) - assert (unsigned(ref.readerSNState.numBits) > 256) report "ACKNACK: readerSNState.numbits is higher than 256." severity warning; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.readerSNState.numBits); - output.length := output.length + 1; - -- Reader State (Bitmap) - for i in 0 to round_div(to_integer(unsigned(ref.readerSNState.numBits)),32)-1 loop + -- Sequence Number State (Bitmap) + for i in 0 to round_div(to_integer(unsigned(input.numBits)),WORD_WIDTH)-1 loop if (i < MAX_BITMAP_WIDTH/WORD_WIDTH) then - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.readerSNState.bitmap(i*32 to i*32+31)); + output.data(output.length) := endian_swap(littleEndian, input.bitmap(i*32 to i*32+31)); output.length := output.length + 1; end if; end loop; - -- Count - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.count); - output.length := output.length + 1; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; end procedure; - procedure gen_acknack_out(ref : in RTPS_ACKNACK_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE) is + procedure write_fragment_ns(input : in FRAGMENTNUMBER_SET_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is begin - -- Opcode & Flags & Source Port - output.data(length) := ref.submessageID & ref.flags & loc.port_(UDP_PORT_WIDTH-1 downto 0); + -- Sequence Number State (Base) + output.data(output.length) := endian_swap(littleEndian, input.base); output.length := output.length + 1; - -- Source Address - output.data(length) := ref.loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); + -- Sequence Number State (NumBits) + assert (unsigned(input.numBits) > 256) report "SequenceNS.numbits is higher than 256." severity warning; + output.data(output.length) := endian_swap(littleEndian, input.numBits); output.length := output.length + 1; - -- Source Entity ID - output.data(length) := ref.readerId; - output.length := output.length + 1; - -- Source GUID Prefix - output.data(length) := src_guid(0); - output.length := output.length + 1; - output.data(length) := src_guid(1); - output.length := output.length + 1; - output.data(length) := src_guid(2); - output.length := output.length + 1; - -- Destination Enity ID - if (is_meta) then - output.data(length) := ref.writerId; - output.length := output.length + 1; - end if; - -- ACKNACK PAYLOAD - -- Reader State (Base) - output.data(length) := ref.readerSNState.base(0); - output.length := output.length + 1; - output.data(length) := ref.readerSNState.base(1); - output.length := output.length + 1; - -- Reader State (NumBits) - output.data(length) := ref.readerSNState.numBits; - output.length := output.length + 1; - -- Reader State (Bitmap) - for i in 0 to round_div(to_integer(unsigned(ref.readerSNState.numBits)),32)-1 loop - output.data(length) := ref.readerSNState.bitmap(i*32 to i*32+31); - output.length := output.length + 1; - end loop; - -- Count - output.data(length) := ref.count; - output.length := output.length + 1; - end procedure; - - procedure gen_nack_frag( ref : in RTPS_NACK_FRAG_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Reader ID - output.data(length) := ref.readerId; - output.length := output.length + 1; - -- Writer ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Writer Sequence Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(1))); - output.length := output.length + 1; - -- FragmentNumber State (Base) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentNumberState.base); - output.length := output.length + 1; - -- Reader State (NumBits) - assert (unsigned(ref.fragmentNumberState.numBits) > 256) report "ACKNACK: fragmentNumberState.numbits is higher than 256." severity warning; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentNumberState.numBits); - output.length := output.length + 1; - -- Reader State (Bitmap) - for i in 0 to round_div(to_integer(unsigned(ref.fragmentNumberState.numBits)),32)-1 loop + -- Sequence Number State (Bitmap) + for i in 0 to round_div(to_integer(unsigned(input.numBits)),WORD_WIDTH)-1 loop if (i < MAX_BITMAP_WIDTH/WORD_WIDTH) then - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentNumberState.bitmap(i*32 to i*32+31)); + output.data(output.length) := endian_swap(littleEndian, input.bitmap(i*32 to i*32+31)); output.length := output.length + 1; end if; end loop; - -- Count - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.count); - output.length := output.length + 1; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; end procedure; - procedure gen_data( ref : in RTPS_DATA_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is + procedure write_locator_list(input : in LOCATOR_LIST_TYPE; littleEndian : in std_logic; output : inout TEST_PACKET_TYPE) is + begin + -- NumLocators + output.data(output.length) := endian_swap(littleEndian, input.numLocators); + output.length := output.length + 1; + for i in 0 to to_integer(unsigned(input.numLocators))-1 loop + -- Kind + output.data(output.length) := endian_swap(littleEndian, input.locator(i).kind); + output.length := output.length + 1; + -- Port + output.data(output.length) := endian_swap(littleEndian, input.locator(i).portn); + output.length := output.length + 1; + -- Address + output.data(output.length) := input.locator(i).addr(127 downto 96); + output.length := output.length + 1; + output.data(output.length) := input.locator(i).addr(95 downto 64); + output.length := output.length + 1; + output.data(output.length) := input.locator(i).addr(63 downto 32); + output.length := output.length + 1; + output.data(output.length) := input.locator(i).addr(31 downto 0); + output.length := output.length + 1; + end loop; + end procedure; + + procedure gen_rtps_submessage( ref : in RTPS_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is variable start : natural := 0; variable tmp : natural := 0; - variable tmp2 : natural := 0; begin + -- *GENERAL* start := output.length; -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); + output.data(output.length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); output.length := output.length + 1; - -- Extra Flags & octetsToInlineQos - output.data(length) := ref.extraFlags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.octetsToInlineQos); - output.length := output.length + 1; - -- Reader ID - output.data(length) := ref.readerId; - output.length := output.length + 1; - -- Writer ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Sequence Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.sequenceNumber(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.sequenceNumber(1))); - output.length := output.length + 1; - -- EXTRA HEADER - tmp := to_integer(unsigned(ref.octetsToInlineQos)) - 16; - if (tmp > 0) then - for i in 0 to tmp-1 loop - store_byte(i mod 4, output, i mod 4, rand_slv(WORD_WIDTH)); - if (i mod 4 = 3) then - output.length := output.length + 1; - output.data(length) := (others => '0'); - end if; - end loop; - end if; - -- DATA - if (ref.data.length > 0) then - assert ((ref.flags(SUBMESSAGE_DATA_FLAG_POS) or ref.flags(SUBMESSAGE_INLINE_QOS_FLAG_POS) or ref.flags(SUBMESSAGE_KEY_FLAG_POS)) = '1') report "DATA: Writing serialized payload with no flags." severity warning; - for i in 0 to (ref.data.length*4)-1 loop - store_byte((i+tmp) mod 4, output, i mod 4, ref.data.data(i/4)); - if ((i+tmp) mod 4 = 3) then - output.length := output.length + 1; - output.data(length) := (others => '0'); - end if; - end loop; - end if; - -- Fix Alignement - if ((tmp + ref.data.length*4) mod 4 /= 0) then + + -- *DATA/DATA_FRAG* + if (ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then + -- Extra Flags & octetsToInlineQos + output.data(output.length) := ref.extraFlags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.octetsToInlineQos); output.length := output.length + 1; end if; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; - end procedure; - - procedure gen_data_out(ref : in RTPS_DATA_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; ts : in TIME_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE) is - begin - -- Opcode & Flags & Source Port - output.data(length) := ref.submessageID & ref.flags & loc.port_(UDP_PORT_WIDTH-1 downto 0); - output.length := output.length + 1; - -- Source Address - output.data(length) := ref.loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); - output.length := output.length + 1; - -- Source Entity ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Source GUID Prefix - output.data(length) := src_guid(0); - output.length := output.length + 1; - output.data(length) := src_guid(1); - output.length := output.length + 1; - output.data(length) := src_guid(2); - output.length := output.length + 1; - -- Destination Enity ID - if (is_meta) then - output.data(length) := ref.readerId; + + -- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG/GAP/DATA/DATA_FRAG* + if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_HEARTBEAT_FRAG or ref.submessageID = SID_GAP or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then + -- Reader ID + output.data(output.length) := ref.readerId; + output.length := output.length + 1; + -- Writer ID + output.data(output.length) := ref.writerId; output.length := output.length + 1; end if; - -- Sequence Number - output.data(length) := std_logic_vector(ref.sequenceNumber(0)); - output.length := output.length + 1; - output.data(length) := std_logic_vector(ref.sequenceNumber(1)); - output.length := output.length + 1; - -- Timestamp - if (not is_meta) then - output.data(length) := std_logic_vector(ts(0)); + + -- *NACK_FRAG/DATA/DATA_FRAG/HEARTBEAT_FRAG* + if (ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG or ref.submessageID = SID_HEARTBEAT_FRAG) then + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(0))); output.length := output.length + 1; - output.data(length) := std_logic_vector(ts(1)); + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(1))); output.length := output.length + 1; end if; - -- DATA PAYLOAD - if (ref.data.length > 0) then - for i in 0 to ref.data.length-1 loop - output.data(length) := ref.data.data(i); - output.length := output.length + 1; - end loop; - end if; - end procedure; - - procedure gen_data_frag( ref : in RTPS_DATA_FRAG_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - variable tmp : natural := 0; - varibale off : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Extra Flags & octetsToInlineQos - output.data(length) := ref.extraFlags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.octetsToInlineQos); - output.length := output.length + 1; - -- Reader ID - output.data(length) := ref.readerId; - output.length := output.length + 1; - -- Writer ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Sequence Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.sequenceNumber(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.sequenceNumber(1))); - output.length := output.length + 1; - -- Fragment Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentNumber); - output.length := output.length + 1; - -- FragmentsinSubmessage & FragmentSize - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentsInSubmessage) & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentSize); - output.length := output.length + 1; - -- EXTRA HEADER - tmp := to_integer(unsigned(ref.octetsToInlineQos)) - 16; - if (tmp > 0) then - for i in 0 to tmp-1 loop - store_byte(i mod 4, output, i mod 4, rand_slv(WORD_WIDTH)); - if (i mod 4 = 3) then - output.length := output.length + 1; - output.data(length) := (others => '0'); - end if; - end loop; - end if; - -- DATA - if (ref.data.length > 0) then - assert ((ref.flags(SUBMESSAGE_INLINE_QOS_FLAG_POS) or ref.flags(SUBMESSAGE_KEY_FLAG_POS-1)) = '1') report "DATA_FRAG: Writing serialized payload with no flags." severity warning; - for i in 0 to (ref.data.length*4)-1 loop - store_byte((i+tmp) mod 4, output, i mod 4, ref.data.data(i/4)); - if ((i+tmp) mod 4 = 3) then - output.length := output.length + 1; - output.data(length) := (others => '0'); - end if; - end loop; - end if; - -- Fix Alignement - if ((tmp + ref.data.length*4) mod 4 /= 0) then + + -- *ACKNACK* + if (ref.submessageID = SID_ACKNACK) then + -- Reader State + write_sequence_ns(ref.readerSNState, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); + -- *NACK_FRAG* + elsif (ref.submessageID = SID_NACK_FRAG) then + -- Fragment Number State + write_fragment_ns(ref.fragmentNumberState, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); + -- *HEARTBEAT* + elsif (ref.submessageID = SID_HEARTBEAT) then + -- First Sequence Number + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(0))); + output.length := output.length + 1; + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(1))); + output.length := output.length + 1; + -- Last Sequence Number + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(0))); + output.length := output.length + 1; + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(1))); + output.length := output.length + 1; + -- *HEARTBEAT_FRAG* + elsif (ref.submessageID = SID_HEARTBEAT_FRAG) then + -- Last Fargment Number + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.lastFragmentNum); output.length := output.length + 1; end if; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; - end procedure; - - procedure gen_gap( ref : in RTPS_GAP_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Reader ID - output.data(length) := ref.readerId; - output.length := output.length + 1; - -- Writer ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Gap Start - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(1))); - output.length := output.length + 1; - -- Gap List (Base) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapList.base(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapList.base(1))); - output.length := output.length + 1; - -- Gap List (NumBits) - assert (unsigned(ref.gapList.numBits) > 256) report "GAP: gapList.numbits is higher than 256." severity warning; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.gapList.numBits); - output.length := output.length + 1; - -- Gap List (Bitmap) - for i in 0 to round_div(to_integer(unsigned(ref.gapList.numBits)),32)-1 loop - if (i < MAX_BITMAP_WIDTH/WORD_WIDTH) then - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.gapList.bitmap(i*32 to i*32+31)); + + -- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG* + if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT_FRAG) then + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.count); + output.length := output.length + 1; + end if; + + -- *GAP* + if (ref.submessageID = SID_GAP) then + -- Gap Start + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(0))); + output.length := output.length + 1; + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.gapStart(1))); + output.length := output.length + 1; + -- Gap List + write_sequence_ns(ref.gapList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); + end if; + + -- *DATA_FRAG* + if (ref.submessageID = SID_DATA_FRAG) then + -- Fragment Number + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentStartingNumber); + output.length := output.length + 1; + -- FragmentsinSubmessage & FragmentSize + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentsInSubmessage) & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.fragmentSize); + output.length := output.length + 1; + -- Sample Size + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.sampleSize); + output.length := output.length + 1; + end if; + + -- *DATA/DATA_FRAG* + if (ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG) then + -- EXTRA HEADER + tmp := to_integer(unsigned(ref.octetsToInlineQos)) - 16; + if (tmp > 0) then + for i in 0 to tmp-1 loop + store_byte(i mod 4, rand_slv(WORD_WIDTH), i mod 4, output); + if (i mod 4 = 3) then + output.length := output.length + 1; + output.data(output.length) := (others => '0'); + end if; + end loop; + end if; + -- DATA + if (ref.data.length > 0) then + for i in 0 to (ref.data.length*4)-1 loop + store_byte((i+tmp) mod 4, ref.data.data(i/4), i mod 4, output); + if ((i+tmp) mod 4 = 3) then + output.length := output.length + 1; + output.data(output.length) := (others => '0'); + end if; + end loop; + end if; + -- Fix Alignement + if ((tmp + ref.data.length*4) mod 4 /= 0) then output.length := output.length + 1; end if; - end loop; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); end if; - end procedure; - - procedure gen_gap_out(ref : in RTPS_GAP_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE) is - begin - -- Opcode & Flags & Source Port - output.data(length) := ref.submessageID & ref.flags & loc.port_(UDP_PORT_WIDTH-1 downto 0); - output.length := output.length + 1; - -- Source Address - output.data(length) := ref.loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); - output.length := output.length + 1; - -- Source Entity ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Source GUID Prefix - output.data(length) := src_guid(0); - output.length := output.length + 1; - output.data(length) := src_guid(1); - output.length := output.length + 1; - output.data(length) := src_guid(2); - output.length := output.length + 1; - -- Destination Enity ID - if (is_meta) then - output.data(length) := ref.readerId; + + -- *INFO_SRC* + if (ref.submessageID = SID_INFO_SRC) then + -- UNUSED + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unused); output.length := output.length + 1; - end if; - -- GAP PAYLOAD - -- Gap Start - output.data(length) := ref.gapStart(0); - output.length := output.length + 1; - output.data(length) := ref.gapStart(1); - output.length := output.length + 1; - -- Gap List (Base) - output.data(length) := ref.gapList.base(0); - output.length := output.length + 1; - output.data(length) := ref.gapList.base(1); - output.length := output.length + 1; - -- Gap List (NumBits) - output.data(length) := ref.gapList.numBits; - output.length := output.length + 1; - -- Gap List (Bitmap) - for i in 0 to round_div(to_integer(unsigned(ref.gapList.numBits)),32)-1 loop - output.data(length) := ref.gapList.bitmap(i*32 to i*32+31); + -- Protocol Version & Vendor ID + output.data(output.length) := ref.version & ref.vendorId; output.length := output.length + 1; - end loop; - end procedure; - - procedure gen_heartbeat( ref : in RTPS_HEARTBEAT_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Reader ID - output.data(length) := ref.readerId; - output.length := output.length + 1; - -- Writer ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- First Sequence Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.firstSN(1))); - output.length := output.length + 1; - -- Last Sequence Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.lastSN(1))); - output.length := output.length + 1; - -- Count - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.count); - output.length := output.length + 1; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; - end procedure; - - procedure gen_heartbeat_out(ref : in RTPS_HEARTBEAT_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE) is - begin - -- Opcode & Flags & Source Port - output.data(length) := ref.submessageID & ref.flags & loc.port_(UDP_PORT_WIDTH-1 downto 0); - output.length := output.length + 1; - -- Source Address - output.data(length) := ref.loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); - output.length := output.length + 1; - -- Source Entity ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Source GUID Prefix - output.data(length) := src_guid(0); - output.length := output.length + 1; - output.data(length) := src_guid(1); - output.length := output.length + 1; - output.data(length) := src_guid(2); - output.length := output.length + 1; - -- Destination Enity ID - if (is_meta) then - output.data(length) := ref.readerId; - output.length := output.length + 1; - end if; - -- HEARTBEAT PAYLOAD-- First Sequence Number - output.data(length) := ref.firstSN(0); - output.length := output.length + 1; - output.data(length) := ref.firstSN(1); - output.length := output.length + 1; - -- Last Sequence Number - output.data(length) := ref.lastSN(0); - output.length := output.length + 1; - output.data(length) := ref.lastSN(1); - output.length := output.length + 1; - -- Count - output.data(length) := ref.count; - output.length := output.length + 1; - end procedure; - - procedure gen_heartbeat_frag( ref : in RTPS_HEARTBEAT_FRAG_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Reader ID - output.data(length) := ref.readerId; - output.length := output.length + 1; - -- Writer ID - output.data(length) := ref.writerId; - output.length := output.length + 1; - -- Sequence Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.writerSN(1))); - output.length := output.length + 1; - -- Last Fargment Number - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.lastFragmentNum); - output.length := output.length + 1; - -- Count - output.data(length) := ref.count; - output.length := output.length + 1; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; - end procedure; - - procedure gen_info_dest( ref : in RTPS_INFO_DESTINATION_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- GUID Prefix - output.data(length) := ref.guidPrefix(0); - output.length := output.length + 1; - output.data(length) := ref.guidPrefix(1); - output.length := output.length + 1; - output.data(length) := ref.guidPrefix(2); - output.length := output.length + 1; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; - end procedure; - - procedure gen_info_reply( ref : in RTPS_INFO_REPLY_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Unicast Locator (NumLocators) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocatorList.numLocators); - output.length := output.length + 1; - for i in 0 to to_integer(unsigned(ref.unicastLocatorList.numLocators))-1 loop - -- Unicast Locator (Kind) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocatorList.locator(i).kind); + -- *INFO_REPLY* + elsif (ref.submessageID = SID_INFO_REPLY) then + write_locator_list(ref.unicastLocatorList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); + if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then + write_locator_list(ref.multicastLocatorList, ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), output); + end if; + -- *INFO_REPLY_IP4* + elsif (ref.submessageID = SID_INFO_REPLY_IP4) then + -- Unicast Locator (Address) + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.addr(IPv4_ADDRESS_WIDTH-1 downto 0)); output.length := output.length + 1; -- Unicast Locator (Port) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocatorList.locator(i).port_); + output.data(output.length)(UDP_PORT_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.portn(UDP_PORT_WIDTH-1 downto 0)); output.length := output.length + 1; - -- Unicast Locator (Address) - output.data(length) := ref.unicastLocatorList.locator(i).addr(127 downto 96); - output.length := output.length + 1; - output.data(length) := ref.unicastLocatorList.locator(i).addr(95 downto 64); - output.length := output.length + 1; - output.data(length) := ref.unicastLocatorList.locator(i).addr(63 downto 32); - output.length := output.length + 1; - output.data(length) := ref.unicastLocatorList.locator(i).addr(31 downto 0); - output.length := output.length + 1; - end loop; - if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then - -- Unicast Locator (NumLocators) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocatorList.numLocators); - output.length := output.length + 1; - for i in 0 to to_integer(unsigned(ref.multicastLocatorList.numLocators))-1 loop - -- Unicast Locator (Kind) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocatorList.locator(i).kind); + if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then + -- Multicast Locator (Address) + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.addr(IPv4_ADDRESS_WIDTH-1 downto 0)); output.length := output.length + 1; - -- Unicast Locator (Port) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocatorList.locator(i).port_); + -- Multicast Locator (Port) + output.data(output.length)(UDP_PORT_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.portn(UDP_PORT_WIDTH-1 downto 0)); output.length := output.length + 1; - -- Unicast Locator (Address) - output.data(length) := ref.multicastLocatorList.locator(i).addr(127 downto 96); + end if; + -- *INFO_TS* + elsif (ref.submessageID = SID_INFO_TS) then + -- Timestamp + if (ref.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) = '0') then + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(0))); output.length := output.length + 1; - output.data(length) := ref.multicastLocatorList.locator(i).addr(95 downto 64); + output.data(output.length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(1))); output.length := output.length + 1; - output.data(length) := ref.multicastLocatorList.locator(i).addr(63 downto 32); - output.length := output.length + 1; - output.data(length) := ref.multicastLocatorList.locator(i).addr(31 downto 0); + end if; + end if; + + -- *INFO_DEST/INFO_SRC* + if (ref.submessageID = SID_INFO_DST or ref.submessageID = SID_INFO_SRC) then + -- GUID Prefix + output.data(output.length) := ref.guidPrefix(0); + output.length := output.length + 1; + output.data(output.length) := ref.guidPrefix(1); + output.length := output.length + 1; + output.data(output.length) := ref.guidPrefix(2); + output.length := output.length + 1; + end if; + + -- *ACKNACK/NACK_FRAG/HEARTBEAT/HEARTBEAT_FRAG/GAP/DATA/DATA_FRAG* + if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG or ref.submessageID = SID_HEARTBEAT or ref.submessageID = SID_HEARTBEAT_FRAG or ref.submessageID = SID_GAP or ref.submessageID = SID_DATA or ref.submessageID = SID_DATA_FRAG or ref.submessageID = SID_INFO_TS or ref.submessageID = SID_INFO_SRC or ref.submessageID = SID_INFO_DST or ref.submessageID = SID_INFO_REPLY or ref.submessageID =SID_INFO_REPLY_IP4) then + -- Fix Submessage Length + if (ref.submessageLength = (ref.submessageLength'range => '1')) then + output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); + -- Fix Packet Length + else + output.length := start + to_integer(unsigned(ref.submessageLength)); + end if; + -- *PAD/UKNOWN* + else + -- Padding + for i in 0 to to_integer(unsigned(ref.submessageLength))-1 loop + output.data(output.length) := (others => '0'); output.length := output.length + 1; end loop; end if; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; end procedure; - procedure gen_info_src( ref : in RTPS_INFO_SOURCE_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; + procedure gen_rtps_handler_out(ref : in RTPS_SUBMESSAGE_TYPE; loc : in LOCATOR_TYPE; is_meta : in boolean; ts : in TIME_TYPE; src_guid : in GUIDPREFIX_TYPE; output : inout TEST_PACKET_TYPE) is begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); + -- Opcode & Flags & Source Port + output.data(output.length) := ref.submessageID & ref.flags & loc.portn(UDP_PORT_WIDTH-1 downto 0); output.length := output.length + 1; - -- UNUSED - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unused); + -- Source Address + output.data(output.length) := loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); output.length := output.length + 1; - -- Protocol Version & Vendor ID - output.data(length) := ref.version & ref.vendorId; - output.length := output.length + 1; - -- GUID Prefix - output.data(length) := ref.guidPrefix(0); - output.length := output.length + 1; - output.data(length) := ref.guidPrefix(1); - output.length := output.length + 1; - output.data(length) := ref.guidPrefix(2); - output.length := output.length + 1; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length + -- Source Entity ID + if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG) then + output.data(output.length) := ref.readerId; + output.length := output.length + 1; else - output.length := start + to_integer(ref.submessageLength); + output.data(output.length) := ref.writerId; + output.length := output.length + 1; + end if; + -- Source GUID Prefix + output.data(output.length) := src_guid(0); + output.length := output.length + 1; + output.data(output.length) := src_guid(1); + output.length := output.length + 1; + output.data(output.length) := src_guid(2); + output.length := output.length + 1; + -- Destination Enity ID + if (is_meta) then + if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_NACK_FRAG) then + output.data(output.length) := ref.writerId; + output.length := output.length + 1; + else + output.data(output.length) := ref.readerId; + output.length := output.length + 1; + end if; + end if; + + -- *DATA* + if (ref.submessageID = SID_DATA) then + -- Sequence Number + output.data(output.length) := std_logic_vector(ref.writerSN(0)); + output.length := output.length + 1; + output.data(output.length) := std_logic_vector(ref.writerSN(1)); + output.length := output.length + 1; + -- Timestamp + if (not is_meta) then + output.data(output.length) := std_logic_vector(ref.timestamp(0)); + output.length := output.length + 1; + output.data(output.length) := std_logic_vector(ref.timestamp(1)); + output.length := output.length + 1; + end if; + -- DATA PAYLOAD + if (ref.data.length > 0) then + for i in 0 to ref.data.length-1 loop + output.data(output.length) := ref.data.data(i); + output.length := output.length + 1; + end loop; + end if; + end if; + + -- *ACKNACK* + if (ref.submessageID = SID_ACKNACK) then + -- Reader State + write_sequence_ns(ref.readerSNState, '0', output); + -- *HEARTBEAT* + elsif (ref.submessageID = SID_HEARTBEAT) then + -- First Sequence Number + output.data(output.length) := std_logic_vector(ref.firstSN(0)); + output.length := output.length + 1; + output.data(output.length) := std_logic_vector(ref.firstSN(1)); + output.length := output.length + 1; + -- Last Sequence Number + output.data(output.length) := std_logic_vector(ref.lastSN(0)); + output.length := output.length + 1; + output.data(output.length) := std_logic_vector(ref.lastSN(1)); + output.length := output.length + 1; + end if; + + -- *ACKNACK/HEARTBEAT* + if (ref.submessageID = SID_ACKNACK or ref.submessageID = SID_HEARTBEAT) then + output.data(output.length) := ref.count; + output.length := output.length + 1; + end if; + + -- *GAP* + if (ref.submessageID = SID_GAP) then + -- Gap Start + output.data(output.length) := std_logic_vector(ref.gapStart(0)); + output.length := output.length + 1; + output.data(output.length) := std_logic_vector(ref.gapStart(1)); + output.length := output.length + 1; + -- Gap List + write_sequence_ns(ref.gapList, '0', output); end if; end procedure; - - procedure gen_info_ts( ref : in RTPS_INFO_TIMESTAMP_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Timestamp - if (ref.flags(SUBMESSAGE_INVALIDATE_FLAG_POS) = '0') then - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(0))); - output.length := output.length + 1; - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), std_logic_vector(ref.timestamp(1))); - output.length := output.length + 1; - end if; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; - end procedure; - - procedure gen_pad( ref : in RTPS_PAD_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - begin - -- Submessage Header - gen_rtps_subheader(ref, output); - -- Padding - for i in 0 to to_integer(unsigned(ref.submessageLength))-1 loop - output.data(length) := (others => '0') - output.length := output.length + 1; - end loop; - end procedure; - - procedure gen_info_reply_ip4( ref : in RTPS_INFO_REPLY_IP4_SUBMESSAGE_TYPE; output : inout TEST_PACKET_TYPE) is - variable start : natural := 0; - begin - start := output.length; - -- Submessage ID & Submessage Flags & Submessage Length - output.data(length) := ref.submessageID & ref.flags & endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.submessageLength); - output.length := output.length + 1; - -- Unicast Locator (Address) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.addr(IPv4_ADDRESS_WIDTH-1 downto 0)); - output.length := output.length + 1; - -- Unicast Locator (Port) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.unicastLocator.port_(UDP_PORT_WIDTH-1 downto 0)); - output.length := output.length + 1; - if (ref.flags(SUBMESSAGE_MULTICAST_FLAG_POS) = '1') then - -- Multicast Locator (Address) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.addr(IPv4_ADDRESS_WIDTH-1 downto 0)); - output.length := output.length + 1; - -- Multicast Locator (Port) - output.data(length) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), ref.multicastLocator.port_(UDP_PORT_WIDTH-1 downto 0)); - output.length := output.length + 1; - end if; - -- Fix Submessage Length - if (ref.submessageLength = (ref.submessageLength'range => '1')) then - output.data(start)(SUBMESSAGE_LENGTH_WIDTH-1 downto 0) := endian_swap(ref.flags(SUBMESSAGE_ENDIAN_FLAG_POS), int(output.length-start-1,SUBMESSAGE_LENGTH_WIDTH)); - -- Fix Packet Length - else - output.length := start + to_integer(ref.submessageLength); - end if; - end procedure; - + procedure gen_participant_announcement( ref : in PARTICIPANT_DATA_TYPE; output : inout TEST_PACKET_TYPE) is variable tmp : natural := 0; begin -- Representation Identifier & Representation Options - output.data(length) := (PL_CDR_BE when ref.littleEndian = '0' else PL_CDR_LE) & x"0000"; + if (ref.littleEndian = '0') then + output.data(output.length) := PL_CDR_BE & x"0000"; + else + output.data(output.length) := PL_CDR_LE & x"0000"; + end if; output.length := output.length + 1; -- GUID - output.data(length) := PID_PARTICIPANT_GUID & endian_swap(ref.littleEndian, int(16, PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_PARTICIPANT_GUID & endian_swap(ref.littleEndian, int(16, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(0); + output.data(output.length) := ref.guidPrefix(0); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(1); + output.data(output.length) := ref.guidPrefix(1); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(2); + output.data(output.length) := ref.guidPrefix(2); output.length := output.length + 1; - output.data(length) := ref.entityId; + output.data(output.length) := ref.entityId; output.length := output.length + 1; -- DOMAIN ID - output.data(length) := PID_DOMAIN_ID & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_DOMAIN_ID & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.domainId); + output.data(output.length) := endian_swap(ref.littleEndian, ref.domainId); output.length := output.length + 1; -- DOMAIN TAG if (ref.domainTag /= EMPTY_STRING) then tmp := string_len(ref.domainTag); - output.data(length) := PID_DOMAIN_TAG & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4, PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_DOMAIN_TAG & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH);); + output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop - output.data(length) := ref.domainTag(i); + output.data(output.length) := ref.domainTag(i); output.length := output.length + 1; end loop; end if; -- PROTOCOL VERSION - output.data(length) := PID_PROTOCOL_VERSION & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_PROTOCOL_VERSION & endian_swap(ref.littleEndian, int(4, PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := (others => '0'); - output.data(length)(31 downto 16) := ref.protocolVersion; + output.data(output.length) := (others => '0'); + output.data(output.length)(31 downto 16) := ref.protocolVersion; output.length := output.length + 1; -- VENDORID - output.data(length) := PID_VENDORID & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_VENDORID & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := (others => '0'); - output.data(length)(31 downto 16) := ref.vendorId; + output.data(output.length) := (others => '0'); + output.data(output.length)(31 downto 16) := ref.vendorId; output.length := output.length + 1; -- EXPECTS IN-LINE QOS if (ref.expectsInlineQoS(0) /= '0') then - output.data(length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := (others => '0'); - output.data(length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap + output.data(output.length) := (others => '0'); + output.data(output.length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap output.length := output.length + 1; end if; -- METATRAFFIC UNICAST LOCATOR - if (ref.metatrafficUnicastLocatorList.numLocators /= ref.metatrafficUnicastLocatorList.numLocators'range => '0') then + if (ref.metatrafficUnicastLocatorList.numLocators /= (ref.metatrafficUnicastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.metatrafficUnicastLocatorList.numLocators)); - output.data(length) := PID_METATRAFFIC_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_METATRAFFIC_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.numLocators); + output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop - output.data(length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).kind); + output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).kind); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).port_); + output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).portn); output.length := output.length + 1; - output.data(length) := ref.metatrafficUnicastLocatorList.locator(i).addr(127 downto 96); + output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; - output.data(length) := ref.metatrafficUnicastLocatorList.locator(i).addr(95 downto 64); + output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; - output.data(length) := ref.metatrafficUnicastLocatorList.locator(i).addr(63 downto 32); + output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; - output.data(length) := ref.metatrafficUnicastLocatorList.locator(i).addr(31 downto 0); + output.data(output.length) := ref.metatrafficUnicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- METATRAFFIC MULTICAST LOCATOR - if (ref.metatrafficMulticastLocatorList.numLocators /= ref.metatrafficMulticastLocatorList.numLocators'range => '0') then + if (ref.metatrafficMulticastLocatorList.numLocators /= (ref.metatrafficMulticastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.metatrafficMulticastLocatorList.numLocators)); - output.data(length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.numLocators); + output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop - output.data(length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).kind); + output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).kind); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).port_); + output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).portn); output.length := output.length + 1; - output.data(length) := ref.metatrafficMulticastLocatorList.locator(i).addr(127 downto 96); + output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; - output.data(length) := ref.metatrafficMulticastLocatorList.locator(i).addr(95 downto 64); + output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; - output.data(length) := ref.metatrafficMulticastLocatorList.locator(i).addr(63 downto 32); + output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; - output.data(length) := ref.metatrafficMulticastLocatorList.locator(i).addr(31 downto 0); + output.data(output.length) := ref.metatrafficMulticastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- DEFAULT UNICAST LOCATOR assert (unsigned(ref.defaultUnicastLocatorList.numLocators) > 0) report "PARTICIPANT_DATA: Participant needs to have at least one Default Unicast Locator." severity error; - if (ref.defaultUnicastLocatorList.numLocators /= ref.defaultUnicastLocatorList.numLocators'range => '0') then + if (ref.defaultUnicastLocatorList.numLocators /= (ref.defaultUnicastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.defaultUnicastLocatorList.numLocators)); - output.data(length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.numLocators); + output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop - output.data(length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).kind); + output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).kind); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).port_); + output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).portn); output.length := output.length + 1; - output.data(length) := ref.defaultUnicastLocatorList.locator(i).addr(127 downto 96); + output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; - output.data(length) := ref.defaultUnicastLocatorList.locator(i).addr(95 downto 64); + output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; - output.data(length) := ref.defaultUnicastLocatorList.locator(i).addr(63 downto 32); + output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; - output.data(length) := ref.defaultUnicastLocatorList.locator(i).addr(31 downto 0); + output.data(output.length) := ref.defaultUnicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- DEFAULT MULTICAST LOCATOR - if (ref.defaultMulticastLocatorList.numLocators /= ref.defaultMulticastLocatorList.numLocators'range => '0') then + if (ref.defaultMulticastLocatorList.numLocators /= (ref.defaultMulticastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.defaultMulticastLocatorList.numLocators)); - output.data(length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(((tmp*6)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.numLocators); + output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.numLocators); output.length := output.length + 1; for i in 0 to tmp-1 loop - output.data(length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).kind); + output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).kind); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).port_); + output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).portn); output.length := output.length + 1; - output.data(length) := ref.defaultMulticastLocatorList.locator(i).addr(127 downto 96); + output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; - output.data(length) := ref.defaultMulticastLocatorList.locator(i).addr(95 downto 64); + output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; - output.data(length) := ref.defaultMulticastLocatorList.locator(i).addr(63 downto 32); + output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; - output.data(length) := ref.defaultMulticastLocatorList.locator(i).addr(31 downto 0); + output.data(output.length) := ref.defaultMulticastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- LEASE DURATION if (ref.leaseDuration /= DEFAULT_PARTICIPANT_LEASE_DURATION) then - output.data(length) := PID_PARTICIPANT_LEASE_DURATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_PARTICIPANT_LEASE_DURATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1))); output.length := output.length + 1; end if; -- AVAILABLE ENDPOINTS - output.data(length) := PID_BUILTIN_ENDPOINT_SET & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_BUILTIN_ENDPOINT_SET & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.availableBuiltinEndpoints); + output.data(output.length) := endian_swap(ref.littleEndian, ref.availableBuiltinEndpoints); output.length := output.length + 1; -- MANUAL LIVELINESS COUNT - output.data(length) := PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.manualLivelinessCount); + output.data(output.length) := endian_swap(ref.littleEndian, ref.manualLivelinessCount); output.length := output.length + 1; end procedure; @@ -1452,49 +971,49 @@ package body rtps_test_package is variable tmp : natural := 0; begin -- GUID - output.data(length) := PID_ENDPOINT_GUID & endian_swap(ref.littleEndian, int(16,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_ENDPOINT_GUID & endian_swap(ref.littleEndian, int(16,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(0); + output.data(output.length) := ref.participant.guidPrefix(0); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(1); + output.data(output.length) := ref.participant.guidPrefix(1); output.length := output.length + 1; - output.data(length) := ref.guidPrefix(2); + output.data(output.length) := ref.participant.guidPrefix(2); output.length := output.length + 1; - output.data(length) := ref.entityId; + output.data(output.length) := ref.entityId; output.length := output.length + 1; -- EXPECTS IN-LINE QOS if (ref.expectsInlineQoS(0) /= '0') then - output.data(length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := (others => '0'); - output.data(length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap + output.data(output.length) := (others => '0'); + output.data(output.length)(31 downto 24) := ref.expectsInlineQoS; -- 1 Byte, No endian swap output.length := output.length + 1; end if; -- TOPIC NAME tmp := string_len(ref.topic_name); - output.data(length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH)); + output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop - output.data(length) := ref.topic_name(i); + output.data(output.length) := ref.topic_name(i); output.length := output.length + 1; end loop; -- TYPE NAME tmp := string_len(ref.type_name); - output.data(length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_TOPIC_NAME & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, int(tmp,CDR_LONG_WIDTH)); + output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,CDR_LONG_WIDTH)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop - output.data(length) := ref.type_name(i); + output.data(output.length) := ref.type_name(i); output.length := output.length + 1; end loop; -- DURABILITY if (ref.durability /= DEFAULT_DURABILITY_QOS) then - output.data(length) := PID_DURABILITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_DURABILITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.durability); + output.data(output.length) := endian_swap(ref.littleEndian, ref.durability); output.length := output.length + 1; end if; -- DURABILITY SERVICE @@ -1502,135 +1021,135 @@ package body rtps_test_package is ref.durability_service_history_depth /= DEFAULT_DURABILITY_SERVICE_HISTORY_DEPTH or ref.durability_service_max_samples /= DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES or ref.durability_service_max_instances /= DEFAULT_DURABILITY_SERVICE_MAX_INSTANCES or ref.durability_service_max_samples_per_instances /= DEFAULT_DURABILITY_SERVICE_MAX_SAMPLES_PER_INSTANCE) then - output.data(length) := PID_DURABILITY_SERVICE & endian_swap(ref.littleEndian, int(28,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_DURABILITY_SERVICE & endian_swap(ref.littleEndian, int(28,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.durability_service_cleanup_delay(1))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.durability_service_history); + output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_history); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.durability_service_history_depth); + output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_history_depth); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples); + output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.durability_service_max_instances); + output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_instances); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples_per_instances); + output.data(output.length) := endian_swap(ref.littleEndian, ref.durability_service_max_samples_per_instances); output.length := output.length + 1; end if; -- PRESENTATION if (ref.presentation /= DEFAULT_PRESENTATION_QOS or ref.coherent_access(0) /= boolean_to_std_logic(DEFAULT_COHERENT_ACCESS) or ref.ordered_access(0) /= boolean_to_std_logic(DEFAULT_ORDERED_ACCESS)) then - output.data(length) := PID_PRESENTATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_PRESENTATION & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.presentation); + output.data(output.length) := endian_swap(ref.littleEndian, ref.presentation); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.coherent_access) & endian_swap(ref.littleEndian, ref.ordered_access); + output.data(output.length) := endian_swap(ref.littleEndian, ref.coherent_access) & endian_swap(ref.littleEndian, ref.ordered_access); output.length := output.length + 1; end if; -- DEADLINE if (ref.deadline /= DEFAULT_DEADLINE_QOS) then - output.data(length) := PID_DEADLINE & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_DEADLINE & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1))); output.length := output.length + 1; end if; -- LATENCY BUDGET if (ref.latency_budget /= DEFAULT_LATENCY_BUDGET_QOS) then - output.data(length) := PID_LATENCY_BUDGET & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_LATENCY_BUDGET & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.deadline(1))); output.length := output.length + 1; end if; -- OWNERSHIP if (ref.ownership /= DEFAULT_OWNERSHIP_QOS) then - output.data(length) := PID_OWNERSHIP & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_OWNERSHIP & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.ownership); + output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership); output.length := output.length + 1; end if; -- OWNERSHIP STRENGTH if (ref.ownership /= DEFAULT_OWNERSHIP_STRENGTH_QOS) then - output.data(length) := PID_OWNERSHIP_STRENGTH & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_OWNERSHIP_STRENGTH & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.ownership_strength); + output.data(output.length) := endian_swap(ref.littleEndian, ref.ownership_strength); output.length := output.length + 1; end if; -- LIVELINESS if (ref.liveliness /= DEFAULT_LIVELINESS_QOS or ref.leaseDuration /= DEFAULT_LEASE_DURATION) then - output.data(length) := PID_LIVELINESS & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_LIVELINESS & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.liveliness); + output.data(output.length) := endian_swap(ref.littleEndian, ref.liveliness); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.leaseDuration(1))); output.length := output.length + 1; end if; -- TIME BASED FILTER if (ref.time_based_filter /= DEFAULT_TIME_BASED_FILTER_QOS) then - output.data(length) := PID_TIME_BASED_FILTER & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_TIME_BASED_FILTER & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.time_based_filter(1))); output.length := output.length + 1; end if; -- RELIABILITY if (ref.reliability /= DEFAULT_RELIABILTY_QOS or ref.max_blocking_time /= DEFAULT_MAX_BLOCKING_TIME) then - output.data(length) := PID_RELIABILITY & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_RELIABILITY & endian_swap(ref.littleEndian, int(12,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.reliability); + output.data(output.length) := endian_swap(ref.littleEndian, ref.reliability); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.max_blocking_time(1))); output.length := output.length + 1; end if; -- TRANSPORT PRIORITY - if (ref.transport_priority /= DEFAULT_TRANSPORT_PRIORITY_QOS) then - output.data(length) := PID_TRANSPORT_PRIORITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + if (ref.transportnpriority /= DEFAULT_TRANSPORT_PRIORITY_QOS) then + output.data(output.length) := PID_TRANSPORT_PRIORITY & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.transport_priority); + output.data(output.length) := endian_swap(ref.littleEndian, ref.transportnpriority); output.length := output.length + 1; end if; -- LIFESPAN if (ref.lifespan /= DEFAULT_LIFESPAN_QOS) then - output.data(length) := PID_LIFESPAN & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_LIFESPAN & endian_swap(ref.littleEndian, int(8,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(0))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(0))); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(1))); + output.data(output.length) := endian_swap(ref.littleEndian, std_logic_vector(ref.lifespan(1))); output.length := output.length + 1; end if; -- DESTINATION ORDER if (ref.destination_order /= DEFAULT_DESTINATION_ORDER_QOS) then - output.data(length) := PID_DESTINATION_ORDER & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_DESTINATION_ORDER & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.destination_order); + output.data(output.length) := endian_swap(ref.littleEndian, ref.destination_order); output.length := output.length + 1; end if; -- UNICAST LOCATORS if (unsigned(ref.unicastLocatorList.numLocators) > 0) then tmp := to_integer(unsigned(ref.unicastLocatorList.numLocators)); for i in 0 to tmp-1 loop - output.data(length) := PID_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).kind); + output.data(output.length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).kind); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).port_); + output.data(output.length) := endian_swap(ref.littleEndian, ref.unicastLocatorList.locator(i).portn); output.length := output.length + 1; - output.data(length) := ref.unicastLocatorList.locator(i).addr(127 downto 96); + output.data(output.length) := ref.unicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; - output.data(length) := ref.unicastLocatorList.locator(i).addr(95 downto 64); + output.data(output.length) := ref.unicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; - output.data(length) := ref.unicastLocatorList.locator(i).addr(63 downto 32); + output.data(output.length) := ref.unicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; - output.data(length) := ref.unicastLocatorList.locator(i).addr(31 downto 0); + output.data(output.length) := ref.unicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; @@ -1638,134 +1157,65 @@ package body rtps_test_package is if (unsigned(ref.multicastLocatorList.numLocators) > 0) then tmp := to_integer(unsigned(ref.multicastLocatorList.numLocators)); for i in 0 to tmp-1 loop - output.data(length) := PID_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).kind); + output.data(output.length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).kind); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).port_); + output.data(output.length) := endian_swap(ref.littleEndian, ref.multicastLocatorList.locator(i).portn); output.length := output.length + 1; - output.data(length) := ref.multicastLocatorList.locator(i).addr(127 downto 96); + output.data(output.length) := ref.multicastLocatorList.locator(i).addr(127 downto 96); output.length := output.length + 1; - output.data(length) := ref.multicastLocatorList.locator(i).addr(95 downto 64); + output.data(output.length) := ref.multicastLocatorList.locator(i).addr(95 downto 64); output.length := output.length + 1; - output.data(length) := ref.multicastLocatorList.locator(i).addr(63 downto 32); + output.data(output.length) := ref.multicastLocatorList.locator(i).addr(63 downto 32); output.length := output.length + 1; - output.data(length) := ref.multicastLocatorList.locator(i).addr(31 downto 0); + output.data(output.length) := ref.multicastLocatorList.locator(i).addr(31 downto 0); output.length := output.length + 1; end loop; end if; -- USER DATA tmp := string_len(ref.user_data); if (tmp > 1) then - output.data(length) := PID_USER_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_USER_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, int(tmp, 32)); + output.data(output.length) := endian_swap(ref.littleEndian, int(tmp, 32)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop - output.data(length) := ref.user_data(i); + output.data(output.length) := ref.user_data(i); output.length := output.length + 1; end loop; end if; -- TOPIC DATA tmp := string_len(ref.topic_data); if (tmp > 1) then - output.data(length) := PID_TOPIC_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_TOPIC_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, int(tmp,32)); + output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,32)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop - output.data(length) := ref.topic_data(i); + output.data(output.length) := ref.topic_data(i); output.length := output.length + 1; end loop; end if; -- GROUP DATA tmp := string_len(ref.group_data); if (tmp > 1) then - output.data(length) := PID_GROUP_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_GROUP_DATA & endian_swap(ref.littleEndian, int((round_div(tmp,4)+1)*4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, int(tmp,32)); + output.data(output.length) := endian_swap(ref.littleEndian, int(tmp,32)); output.length := output.length + 1; for i in 0 to round_div(tmp,4)-1 loop - output.data(length) := ref.group_data(i); + output.data(output.length) := ref.group_data(i); output.length := output.length + 1; end loop; end if; -- MAX SIZE SERIALIZED if (unsigned(ref.max_size_serialized) /= 0) then - output.data(length) := PID_DATA_MAX_SIZE_SERIALIZED & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); + output.data(output.length) := PID_DATA_MAX_SIZE_SERIALIZED & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; - output.data(length) := endian_swap(ref.littleEndian, ref.max_size_serialized); + output.data(output.length) := endian_swap(ref.littleEndian, ref.max_size_serialized); output.length := output.length + 1; end if; end procedure; - -- converts std_logic into a character - function chr(sl: std_logic) return character is - variable c: character; - begin - case sl is - when 'U' => c:= 'U'; - when 'X' => c:= 'X'; - when '0' => c:= '0'; - when '1' => c:= '1'; - when 'Z' => c:= 'Z'; - when 'W' => c:= 'W'; - when 'L' => c:= 'L'; - when 'H' => c:= 'H'; - when '-' => c:= '-'; - end case; - return c; - end function; - - -- converts std_logic_vector into a string (binary base) - -- (this also takes care of the fact that the range of - -- a string is natural while a std_logic_vector may - -- have an integer range) - function str(slv: std_logic_vector) return string is - variable ret : string (1 to slv'length); - begin - for i in slv'range loop - ret(i+1) := chr(slv(i)); - end loop; - return ret; - end function; - - function str(sl: std_logic) return string is - variable ret : string (1 to 1); - begin - ret(1) := chr(sl); - return ret; - end function; - - impure function rand_int(min_val, max_val : integer) return integer is - variable r : real; - begin - UNIFORM(999, 999, r); - return integer(ROUND(r * real(max_val - min_val + 1) + real(min_val) - 0.5)); - end function; - - impure function rand_slv(len : integer) return std_logic_vector is - variable r : real; - variable slv : std_logic_vector(len - 1 downto 0); - begin - for i in slv'range loop - uniform(999, 999, r); - slv(i) := '1' when r > 0.5 else '0'; - end loop; - return slv; - end function; - - function gen_rand_addr return LOCATOR_TYPE is - variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; - begin - ret.kind => LOCATOR_KIND_UDPv4; - ret.port_(UDP_PORT_WIDTH-1 downto 0) => rand_slv(UDP_PORT_WIDTH); - ret.addr(IPv4_ADDRESS_WIDTH-1 downto 0)=> rand_slv(IPv4_ADDRESS_WIDTH); - end function; - - function int(n : integer, width : natural) return std_logic_vector is - begin - return std_logic_vector(to_signed(n, width)); - end function; - end package body; \ No newline at end of file