From e7591b0e033b0f55e4d5550a37f8b13d2ac12325 Mon Sep 17 00:00:00 2001 From: Greek Date: Mon, 23 Nov 2020 12:20:05 +0100 Subject: [PATCH] * Add new DEFAULT values in packages * Add test RAM (Used for testbenches) * Add Data Structures and functions to check memory contents * Add rtps_builtin_endpoint_test1 - Compiles and Passes * Various bug fixes in rtps_builtin_endpoint to Pass testbench --- sim/rtps_builtin_endpoint_test1.do | 68 ++ src/REF.txt | 46 +- .../Level_0/rtps_builtin_endpoint_test1.vhd | 593 ++++++++++++++++++ src/Tests/ScoreBoard_test_memory.vhd | 17 + src/Tests/test_config.vhd | 2 +- src/Tests/test_ram.vhd | 51 ++ src/Tests/testbench.pro | 9 +- src/rtps_builtin_endpoint.vhd | 517 ++++++++------- src/rtps_config_package.vhd | 31 +- src/rtps_package.vhd | 57 +- src/rtps_test_package.vhd | 56 +- 11 files changed, 1138 insertions(+), 309 deletions(-) create mode 100644 sim/rtps_builtin_endpoint_test1.do create mode 100644 src/Tests/Level_0/rtps_builtin_endpoint_test1.vhd create mode 100644 src/Tests/ScoreBoard_test_memory.vhd create mode 100644 src/Tests/test_ram.vhd diff --git a/sim/rtps_builtin_endpoint_test1.do b/sim/rtps_builtin_endpoint_test1.do new file mode 100644 index 0000000..2cdeda8 --- /dev/null +++ b/sim/rtps_builtin_endpoint_test1.do @@ -0,0 +1,68 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider SYSTEM +add wave -noupdate /rtps_builtin_endpoint_test1/uut/clk +add wave -noupdate /rtps_builtin_endpoint_test1/uut/reset +add wave -noupdate -divider INPUT +add wave -noupdate /rtps_builtin_endpoint_test1/uut/empty +add wave -noupdate /rtps_builtin_endpoint_test1/uut/rd +add wave -noupdate -radix hexadecimal /rtps_builtin_endpoint_test1/uut/data_in +add wave -noupdate /rtps_builtin_endpoint_test1/uut/last_word_in +add wave -noupdate /rtps_builtin_endpoint_test1/uut/last_word_in_latch +add wave -noupdate -divider TESTBENCH +add wave -noupdate /rtps_builtin_endpoint_test1/start +add wave -noupdate /rtps_builtin_endpoint_test1/stim_stage +add wave -noupdate /rtps_builtin_endpoint_test1/stimulus.length +add wave -noupdate /rtps_builtin_endpoint_test1/cnt_stim +add wave -noupdate /rtps_builtin_endpoint_test1/packet_sent +add wave -noupdate /rtps_builtin_endpoint_test1/SB.ItemNumberVar +add wave -noupdate -divider {MAIN FSM} +add wave -noupdate /rtps_builtin_endpoint_test1/uut/stage +add wave -noupdate /rtps_builtin_endpoint_test1/uut/stage_next +add wave -noupdate /rtps_builtin_endpoint_test1/uut/cnt +add wave -noupdate /rtps_builtin_endpoint_test1/uut/endpoint_mask +add wave -noupdate /rtps_builtin_endpoint_test1/uut/participant_match +add wave -noupdate -divider {MEM FSM} +add wave -noupdate /rtps_builtin_endpoint_test1/uut/mem_opcode +add wave -noupdate /rtps_builtin_endpoint_test1/uut/mem_op_start +add wave -noupdate /rtps_builtin_endpoint_test1/uut/mem_op_done +add wave -noupdate /rtps_builtin_endpoint_test1/uut/mem_stage +add wave -noupdate /rtps_builtin_endpoint_test1/uut/mem_stage_next +add wave -noupdate /rtps_builtin_endpoint_test1/uut/mem_cnt +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/mem_addr_base +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/addr_res +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/last_addr +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/max_participant_addr +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/max_endpoint_addr +add wave -noupdate -divider GUARD +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/read_cnt +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/parameter_end +add wave -noupdate /rtps_builtin_endpoint_test1/uut/parse_prc/rd_guard +add wave -noupdate -divider MEMORY +add wave -noupdate -group MEMORY -radix unsigned /rtps_builtin_endpoint_test1/uut/ram_inst/addr +add wave -noupdate -group MEMORY /rtps_builtin_endpoint_test1/uut/ram_inst/wen +add wave -noupdate -group MEMORY /rtps_builtin_endpoint_test1/uut/ram_inst/ren +add wave -noupdate -group MEMORY -radix hexadecimal /rtps_builtin_endpoint_test1/uut/ram_inst/wr_data +add wave -noupdate -group MEMORY -radix hexadecimal /rtps_builtin_endpoint_test1/uut/ram_inst/rd_data +add wave -noupdate -divider MISC +add wave -noupdate /rtps_builtin_endpoint_test1/uut/update_participant_flags +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/mem_seq_nr +add wave -noupdate -radix unsigned /rtps_builtin_endpoint_test1/uut/seq_nr +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {15299092 ps} 0} +quietly wave cursor active 1 +configure wave -namecolwidth 149 +configure wave -valuecolwidth 144 +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 {14808192 ps} {15956534 ps} diff --git a/src/REF.txt b/src/REF.txt index 6b11d98..8fc6276 100644 --- a/src/REF.txt +++ b/src/REF.txt @@ -175,51 +175,51 @@ PARTICICPANT DATA 31............24..............16..............8...............0 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------------------------------------------------------+ -01| | +00| | + + -02| GUIDPREFIX | +01| GUIDPREFIX | + + -03| | +02| | +-------------------------------------------------------------+ -04| META_IPv4_ADDRESS | +03| META_IPv4_ADDRESS | +-------------------------------------------------------------+ -05| DEFAULT_IPv4_ADDRESS | +04| DEFAULT_IPv4_ADDRESS | +-------------------------------------------------------------+ -06| META_UDP_PORT | DEFAULT_UDP_PORT | +05| META_UDP_PORT | DEFAULT_UDP_PORT | +-------------------------------------------------------------+ -07| | +06| | + SPDP_SEQ_NR + +07| | + +-------------------------------------------------------------+ 08| | - +-------------------------------------------------------------+ -09| | + LEASE_DURATION + +09| | + +-------------------------------------------------------------+ 10| | - +-------------------------------------------------------------+ -11| | + LEASE_DEADLINE + -12| | +11| | +-------------------------------------------------------------+ -13| UNUSED |P|S|M|Q| +12| UNUSED |P|S|M|Q| +-------------------------------------------------------------+ -14| | +13| | + ACKNACK_RES_TIME + +14| | + +-------------------------------------------------------------+ 15| | - +-------------------------------------------------------------+ -16| | + HEARTBEAT_RES_TIME + +16| | + +-------------------------------------------------------------+ 17| | - +-------------------------------------------------------------+ -18| | + PUBLICATION_SEQ_NR + +18| | + +-------------------------------------------------------------+ 19| | - +-------------------------------------------------------------+ -20| | + SUBSCRIPTION_SEQ_NR + -21| | +20| | +-------------------------------------------------------------+ -22| | +21| | + MESSAGE_SEQ_NR + -23| | +22| | +-------------------------------------------------------------+ ENDPOINT DATA diff --git a/src/Tests/Level_0/rtps_builtin_endpoint_test1.vhd b/src/Tests/Level_0/rtps_builtin_endpoint_test1.vhd new file mode 100644 index 0000000..3e583e0 --- /dev/null +++ b/src/Tests/Level_0/rtps_builtin_endpoint_test1.vhd @@ -0,0 +1,593 @@ +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_builtin_endpoint_test1 is +end entity; + +architecture testbench of rtps_builtin_endpoint_test1 is + + -- *COMPONENT DECLARATION* + component rtps_builtin_endpoint is + port ( + clk : in std_logic; + reset : in std_logic; + empty : in std_logic; + rd : out std_logic; + data_in : in std_logic_vector(WORD_WIDTH-1 downto 0); + data_out : out std_logic_vector(WORD_WIDTH-1 downto 0); + last_word_in : in std_logic; + time : in TIME_TYPE; + endpoint_full : in std_logic_vector(0 to NUM_ENDPOINTS-1); + endpoint_wr : out std_logic_vector(0 to NUM_ENDPOINTS-1); + rtps_wr : out std_logic; + rtps_full : in std_logic; + last_word_out : out std_logic; + alive : in std_logic_vector(0 to NUM_ENDPOINTS-1) + ); + end component; + + -- *TYPE DECLARATION* + type TEST_STAGE_TYPE is (IDLE, BUSY); + + -- *SIGNAL DECLARATION* + signal clk, in_empty, rd_sig, last_word_in, last_word_out: std_logic := '0'; + signal reset : std_logic := '1'; --TODO: Do that in all testbenches + signal data_in, data_out : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal stim_stage : TEST_STAGE_TYPE := IDLE; + shared variable stimulus : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; + signal packet_sent : std_logic := '0'; + signal cnt_stim : natural := 0; + signal start : std_logic := '0'; + shared variable SB : work.ScoreBoardPkg_MemoryTest.ScoreBoardPType; + -- *FUNCTION DECLARATION* + procedure wait_on_complete is + begin + wait until rising_edge(packet_sent); + end procedure; + +begin + + -- Unit Under Test + uut : rtps_builtin_endpoint + port map ( + clk => clk, + reset => reset, + empty => in_empty or packet_sent, + rd => rd_sig, + data_in => data_in, + data_out => data_out, + last_word_in => last_word_in, + time => TIME_ZERO, + endpoint_full => (others => '0'), + endpoint_wr => open, + rtps_wr => open, + rtps_full => '0', + last_word_out => last_word_out, + alive => (others => '0') + ); + + stimulus_prc : process + variable rtps_sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable check_cnt : natural := 0; + variable RV : RandomPType; + variable participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; + variable p0, p1, p2 : GUIDPREFIX_TYPE; + + -- Wrapper to use procedure as function + impure function gen_rand_loc_2 return LOCATOR_TYPE is + variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; + begin + gen_rand_loc(RV, ret); + return ret; + end function; + + impure function gen_rand_guid_prefix return GUIDPREFIX_TYPE is + variable ret : GUIDPREFIX_TYPE; + begin + ret := (0 => RV.RandSlv(WORD_WIDTH), 1 => RV.RandSlv(WORD_WIDTH), 2 => RV.RandSlv(WORD_WIDTH)); + return ret; + end function; + + procedure start_test is + begin + start <= '1'; + wait until rising_edge(clk); + start <= '0'; + wait until rising_edge(clk); + end procedure; + begin + + SetAlertLogName("L0-rtps_builtin_endpoint-participant_matching"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + + -- NOTE: A single incremented Sequence Number is used for all the Participants. This should not be a problem for + -- the best effort participant data, as long as it is monotonically increasing. + rtps_sub := DEFAULT_RTPS_SUBMESSAGE; + rtps_sub.submessageID := SID_DATA; + rtps_sub.writerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_ANNOUNCER; + rtps_sub.readerId := ENTITYID_SPDP_BUILTIN_PARTICIPANT_DETECTOR; + rtps_sub.flags(SUBMESSAGE_DATA_FLAG_POS) := '1'; + + p0 := gen_rand_guid_prefix; + p1 := gen_rand_guid_prefix; + p2 := gen_rand_guid_prefix; + + + Log("Initiating Test", INFO); + start <= '0'; + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + + Log("Match Participant 0 [Compatible]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p0; + participant.nr := 0; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,0,0] + + Log("Match Participant 1 [Compatible, Little Endian]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p1; + participant.nr := 1; + participant.littleEndian := '1'; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,0] + + Log("Ignore Participant 2 [Incompatible Domain ID]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p2; + participant.nr := 2; + participant.domainId := int(2, DOMAIN_ID_WIDTH); + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,0] + + Log("Unmatch Participant 0 [Incompatible Domain ID]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p0; + participant.nr := 0; + participant.domainId := int(2, DOMAIN_ID_WIDTH); + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [0,p1,0] + + Log("Ignore Participant 2 [Incompatible Domain TAG]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p2; + participant.nr := 2; + participant.domainTag := DEFAULT_DOMAIN_TAG; + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [0,p1,0] + + Log("Unmatch Participant 1 [Incompatible Domain TAG]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p1; + participant.nr := 1; + participant.domainTag := DEFAULT_DOMAIN_TAG; + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [0,0,0] + + Log("Match Participant 0 [+Unicast Metatraffic Locator]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p0; + participant.nr := 0; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.metatrafficUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,0,0] + + Log("Match Participant 1 [ALL Values Set non default]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p1; + participant.nr := 1; + participant.vendorId := RV.RandSlv(VENDORID_WIDTH); + participant.expectsInlineQoS(0) := '1'; + participant.leaseDuration := gen_duration(5,500); + participant.manualLivelinessCount := int(6, CDR_LONG_WIDTH); + participant.builtinEndpointQoS(0) := '1'; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.defaultMulticastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.metatrafficUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.metatrafficMulticastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.match := MATCH; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,0] + + Log("Ignore Participant 2 [Incompatible Protocol Version]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p2; + participant.nr := 2; + participant.protocolVersion := PROTOCOLVERSION_1_0; + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,0] + + Log("Unmatch Participant 0 [Incompatible Protocol Version]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p0; + participant.nr := 0; + participant.protocolVersion := PROTOCOLVERSION_1_0; + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [0,p1,0] + + Log("Match Participant 0 [Compatible, Only Subscribers]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p0; + participant.nr := 0; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER):= '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,0] + + Log("Match Participant 2 [Compatible, Only Publishers]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p2; + participant.nr := 2; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,p2] + + Log("Update Participant 1 [Valid/Invalid Default/Metatraffic Locators]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p1; + participant.nr := 1; + participant.match := MATCH; + participant.defaultUnicastLocatorList := (numLocators => int(4,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, 1 => gen_rand_loc_2, 2 => gen_rand_loc_2, 3 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.defaultUnicastLocatorList.locator(1).kind := LOCATOR_KIND_UDPv6; + participant.defaultUnicastLocatorList.locator(2).addr := (others => '0'); + participant.defaultUnicastLocatorList.locator(3).portn := (others => '0'); + participant.defaultMulticastLocatorList := (numLocators => int(4,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, 1 => gen_rand_loc_2, 2 => gen_rand_loc_2, 3 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.defaultMulticastLocatorList.locator(1).kind := LOCATOR_KIND_UDPv6; + participant.defaultMulticastLocatorList.locator(2).portn := (others => '0'); + participant.defaultMulticastLocatorList.locator(3).addr := (others => '0'); + participant.metatrafficUnicastLocatorList := (numLocators => int(4,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, 1 => gen_rand_loc_2, 2 => gen_rand_loc_2, 3 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.metatrafficUnicastLocatorList.locator(1).kind := LOCATOR_KIND_UDPv6; + participant.metatrafficUnicastLocatorList.locator(2).addr := (others => '0'); + participant.metatrafficUnicastLocatorList.locator(3).portn := (others => '0'); + participant.metatrafficMulticastLocatorList := (numLocators => int(4,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, 1 => gen_rand_loc_2, 2 => gen_rand_loc_2, 3 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.metatrafficMulticastLocatorList.locator(1).kind := LOCATOR_KIND_UDPv6; + participant.metatrafficMulticastLocatorList.locator(2).portn := (others => '0'); + participant.metatrafficMulticastLocatorList.locator(3).addr := (others => '0'); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,p2] + + Log("Unmatch Participant 2 [No Endpoints]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p2; + participant.nr := 2; + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [p0,p1,0] + + Log("Unmatch Participant 0 [Incompatible Built-in Endpoints]", INFO); + participant := DEFAULT_PARTICIPANT_DATA; + participant.guidPrefix := p0; + participant.nr := 0; + participant.match := UNMATCH; + participant.defaultUnicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) := '1'; + participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; + gen_participant_data(participant, rtps_sub.data); + gen_sentinel(rtps_sub.data); + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, participant.guidPrefix, stimulus); + SB.Push(gen_participant_mem_frame(participant)); + start_test; + wait_on_complete; + check_cnt := check_cnt + TEST_PARTICIPANT_MEMORY_FRAME_TYPE'length; + stimulus := EMPTY_TEST_PACKET; + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE [0,p1,0] + + -- LAST PACKET + -- Mark Packet as non-standard Payload, in order to trigger the packet to be skipped (as early as possible) + rtps_sub.data := EMPTY_TEST_PACKET; + rtps_sub.flags(SUBMESSAGE_NON_STANDARD_PAYLOAD_FLAG_POS):= '1'; + gen_rtps_handler_out(rtps_sub, gen_rand_loc_2, TRUE, TIME_INVALID, p0, stimulus); + start_test; + wait_on_complete; + + AlertIf(GetAffirmCount < check_cnt, "Incomplete test run"); + ReportAlerts; + wait; --TODO: Remove + std.env.stop; + 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'; + wait; --TODO: Remove + wait until rising_edge(clk); + in_empty <= '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); + end if; + end process; + + input_prc : process(all) + begin + data_in <= stimulus.data(cnt_stim); + last_word_in <= stimulus.last(cnt_stim); + case (stim_stage) is + when IDLE => + packet_sent <= '1'; + when BUSY => + packet_sent <= '0'; + end case; + + if rising_edge(clk) then + if (reset = '1') then + cnt_stim <= 0; + stim_stage <= IDLE; + else + case (stim_stage) is + when IDLE => + if (start = '1') then + stim_stage <= BUSY; + cnt_stim <= 0; + end if; + when BUSY => + if (cnt_stim = stimulus.length) then + stim_stage <= IDLE; + elsif (rd_sig = '1') then + cnt_stim <= cnt_stim + 1; + end if; + end case; + end if; + end if; + end process; + + + output_prc : process + alias mem is <>; + alias mem_op_done is <>; + variable reference : TEST_PARTICIPANT_MEMORY_FRAME_TYPE; + begin + -- SAFEGUARD: (Prevent Fall-through Behavior) + if (reset /= '0') then + wait until reset = '0'; + end if; + -- NOTE: The first read after the packet is sent signifies that the State Machine has begun processing the next packet. + -- The memory operation that could still be in progress is the last one concerning the last sent packet. + wait until packet_sent = '1'; + if (rd_sig /= '1') then + wait until rd_sig = '1'; + end if; + if (mem_op_done /= '1') then + wait until mem_op_done = '1'; + end if; + if (not SB.empty) then + SB.Pop(reference); + for i in 0 to reference'length-1 loop + AffirmIf(?? (mem(reference(i).addr) ?= reference(i).data), "Address: " & integer'image(reference(i).addr) & " Received: " & to_hstring(mem(reference(i).addr)) & " Expected: " & to_hstring(reference(i).data)); + end loop; + end if; + end process; + + watchdog : process + begin + wait for 5 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/ScoreBoard_test_memory.vhd b/src/Tests/ScoreBoard_test_memory.vhd new file mode 100644 index 0000000..87b33ee --- /dev/null +++ b/src/Tests/ScoreBoard_test_memory.vhd @@ -0,0 +1,17 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_test_package.all; + +package ScoreBoardPkg_MemoryTest is new osvvm.ScoreboardGenericPkg + generic map ( + ExpectedType => TEST_MEMORY_TYPE, + ActualType => TEST_MEMORY_TYPE, + Match => test_memory_match, + expected_to_string => to_string, + actual_to_string => to_string + ); \ No newline at end of file diff --git a/src/Tests/test_config.vhd b/src/Tests/test_config.vhd index 7c3dd33..a9b9422 100644 --- a/src/Tests/test_config.vhd +++ b/src/Tests/test_config.vhd @@ -37,7 +37,7 @@ package user_config is -- Domain ID constant USER_DOMAIN_ID : natural := 1; -- Domain TAG - constant USER_DOMAIN_TAG : string(1 to 256) := (others => NUL); --"" + constant USER_DOMAIN_TAG : USER_STRING_TYPE := "TEST_DOMAIN" & (12 to 256 => NUL); --***RTPS ENDPOINTS*** -- Array denoting if Endpoints use Keyed Topics diff --git a/src/Tests/test_ram.vhd b/src/Tests/test_ram.vhd new file mode 100644 index 0000000..b87103d --- /dev/null +++ b/src/Tests/test_ram.vhd @@ -0,0 +1,51 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.rtps_test_package.all; + +entity single_port_ram is + generic ( + ADDR_WIDTH : natural := 8; + DATA_WIDTH : natural := 12; + MEMORY_DEPTH : natural := 256 + ); + port ( + clk : in std_logic; + addr : in std_logic_vector(ADDR_WIDTH-1 downto 0); + wen : in std_logic; + ren : in std_logic; + wr_data : in std_logic_vector(DATA_WIDTH-1 downto 0); + rd_data : out std_logic_vector(DATA_WIDTH-1 downto 0) + ); +end entity; + +architecture arch of single_port_ram is + + + signal mem : TEST_RAM_TYPE := (others => (others => '0')); + +begin + + assert (TEST_RAM_TYPE'length = MEMORY_DEPTH) report "TEST_RAM_TYPE does not respect Memory Depth" severity FAILURE; + + ram_prc : process(all) + begin + if rising_edge(clk) then + rd_data <= (others => '0'); + + if (wen = '1') then + mem(to_integer(unsigned(addr))) <= wr_data; + end if; + + if (ren = '1') then + if (wen = '1') then + rd_data <= wr_data; + else + rd_data <= mem(to_integer(unsigned(addr))); + end if; + end if; + end if; + end process; + +end architecture; diff --git a/src/Tests/testbench.pro b/src/Tests/testbench.pro index 94e09f9..6b408c4 100644 --- a/src/Tests/testbench.pro +++ b/src/Tests/testbench.pro @@ -9,8 +9,13 @@ analyze test_config.vhd analyze ../rtps_config_package.vhd analyze ../rtps_test_package.vhd analyze ../rtps_handler.vhd +analyze ../rtps_builtin_endpoint.vhd +analyze test_ram.vhd +analyze ScoreBoard_test_memory.vhd analyze Level_0/rtps_handler_test1.vhd analyze Level_0/rtps_handler_test2.vhd +analyze Level_0/rtps_builtin_endpoint_test1.vhd -simulate rtps_handler_test1 -simulate rtps_handler_test2 \ No newline at end of file +#simulate rtps_handler_test1 +#simulate rtps_handler_test2 +simulate rtps_builtin_endpoint_test1 \ No newline at end of file diff --git a/src/rtps_builtin_endpoint.vhd b/src/rtps_builtin_endpoint.vhd index 1765c6d..0c2dcb8 100644 --- a/src/rtps_builtin_endpoint.vhd +++ b/src/rtps_builtin_endpoint.vhd @@ -7,6 +7,7 @@ use work.rtps_package.all; use work.user_config.all; use work.rtps_config_package.all; +-- TODO: Initialise RAM to zeroes -- TODO: Skip Packet while we are waiting for memory operation to complete -- TODO: add_res is still valid after removal. So we could continue searching the next orphan endpoint from that address on @@ -16,13 +17,12 @@ entity rtps_builtin_endpoint is 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_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); last_word_in : in std_logic; time : in TIME_TYPE; - endpoint_output : out std_logic_vector(WORD_WIDTH-1 downto 0); endpoint_full : in std_logic_vector(0 to NUM_ENDPOINTS-1); endpoint_wr : out std_logic_vector(0 to NUM_ENDPOINTS-1); - rtps_output : out std_logic_vector(WORD_WIDTH-1 downto 0); rtps_wr : out std_logic; rtps_full : in std_logic; last_word_out : out std_logic; @@ -127,11 +127,11 @@ architecture arch of rtps_builtin_endpoint is -- Memory Address Width constant BUILTIN_BUFFER_ADDR_WIDTH : natural := log2c(BUILTIN_BUFFER_SIZE); -- Highest Memory Address - constant MAX_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := to_unsigned(BUILTIN_BUFFER_SIZE, BUILTIN_BUFFER_ADDR_WIDTH); + constant MAX_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := to_unsigned(BUILTIN_BUFFER_SIZE-1, BUILTIN_BUFFER_ADDR_WIDTH); -- Address pointing to the beginning of the first Participant Data Frame constant FIRST_PARTICIPANT_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := (others => '0'); -- Address pointing to the beginning of the first Endpoint Data Frame - constant FIRST_ENDPOINT_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := to_unsigned(BUILTIN_BUFFER_SIZE - ENDPOINT_FRAME_SIZE, BUILTIN_BUFFER_ADDR_WIDTH); + constant FIRST_ENDPOINT_ADDRESS : unsigned(BUILTIN_BUFFER_ADDR_WIDTH-1 downto 0) := to_unsigned(BUILTIN_BUFFER_SIZE - ENDPOINT_FRAME_SIZE-1, BUILTIN_BUFFER_ADDR_WIDTH); -- *UPDATE PARTICIPANT FLAG POSITIONS* -- Signifies that the main Participant Data are updated constant PARTICIPANT_DATA_FLAG : natural := 0; @@ -234,7 +234,7 @@ architecture arch of rtps_builtin_endpoint is -- Signifies that the read Locator is a Metatraffic Locator signal is_meta_addr, is_meta_addr_next : std_logic := '0'; -- General Purpose counter - signal cnt, cnt_next : natural range 0 to 23 := 0; + signal cnt, cnt_next : natural range 0 to max(23, STRING_WORD_ARRAY_TYPE'length) := 0; -- NOTE: In order to avoid synthesizing indexing for the full range of the OUTPUT_DATA_TYPE, we explicitly use counters constrained to the actual size -- Counter used to index the Participant Data signal participant_data_cnt, participant_data_cnt_next : natural range 0 to PARTICIPANT_DATA.length-1 := 0; @@ -278,8 +278,6 @@ architecture arch of rtps_builtin_endpoint is signal is_orphan_search, is_orphan_search_next : std_logic := '0'; -- Intermediate write enable signal. signal wr_sig : std_logic := '0'; - -- Intermediate Output Signal - signal output_sig : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); -- Signifies if we currently are resetting the MAX Participant/Endpoint Pointer signal reset_max_pointer, reset_max_pointer_next : std_logic := '0'; -- Signifies if we currently are doing a Participant Stale Entry Check (Used to start Stale Checks between packet handling) @@ -320,7 +318,7 @@ architecture arch of rtps_builtin_endpoint is -- Signifies the content of the string read from input signal string_content, string_content_next : STRING_CONTENT_TYPE := TOPIC_NAME_TYPE; -- Signifies that the expects_inline_qos Flag was explicitly set via a Parameter ID - signal expects_inline_qos_set, expects_inline_qos_set_next : std_logic := '0'; + signal expects_inline_qos_rcv, expects_inline_qos_rcv_next : std_logic := '0'; -- Endpoint Locator IPv4 Address Latch signal def_addr, def_addr_next : std_logic_vector(IPv4_ADDRESS_WIDTH-1 downto 0) := (others => '0'); -- Metatraffic Locator IPv4 Address Latch @@ -333,6 +331,11 @@ architecture arch of rtps_builtin_endpoint is signal lease_duration, lease_duration_next : DURATION_TYPE := (others => (others => '0')); -- Extra Flags Latch signal extra_flags, extra_flags_next : std_logic_vector(EXTRA_FLAGS_WIDTH-1 downto 0) := (others => '0'); + -- General Purpose Long latch + signal long_latch, long_latch_next : std_logic_vector(CDR_LONG_WIDTH-1 downto 0) := (others => '0'); + -- Signifies if the Participant Domain Tag was checked/matched + -- NOTE: Because the Domain Tag has a default value, we have to note if we received a PID_DOMAIN_TAG (since the default value is implied on its absence) + signal domain_tag_rcv, domain_tag_rcv_next : std_logic := '0'; @@ -396,7 +399,7 @@ begin ram_inst : single_port_ram generic map ( ADDR_WIDTH => BUILTIN_BUFFER_ADDR_WIDTH, - DATA_WIDTH => 32, + DATA_WIDTH => WORD_WIDTH, MEMORY_DEPTH => BUILTIN_BUFFER_SIZE ) port map ( @@ -477,11 +480,6 @@ begin -- This process connects the Intermediate Output Signals to the actual output FIFOs output_prc : process(all) begin - -- Data Signal - endpoint_output <= output_sig; - rtps_output <= output_sig; - - --Write Enable Signal endpoint_wr <= (others => '0'); rtps_wr <= '0'; case (stage) is @@ -563,7 +561,8 @@ begin -- SKIP_PARAMETER Skip rest of Parameter -- SKIP_PACKET Skip rest of Packet parse_prc: process(all) - variable tmp_endpoint_mask : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); + variable tmp_endpoint_mask : std_logic_vector(0 to NUM_ENDPOINTS-1) := (others => '0'); + variable rd_guard : std_logic := '0'; begin --DEFAULT Registered stage_next <= stage; @@ -591,7 +590,7 @@ begin meta_port_next <= meta_port; is_meta_addr_next <= is_meta_addr; cnt_next <= cnt; - expects_inline_qos_set_next <= expects_inline_qos_set; + expects_inline_qos_rcv_next <= expects_inline_qos_rcv; is_orphan_search_next <= is_orphan_search; extra_flags_next <= extra_flags; stale_check_next <= stale_check; @@ -613,15 +612,18 @@ begin seq_nr_next <= seq_nr; last_word_in_latch_next <= last_word_in_latch; count_next <= count; + long_latch_next <= long_latch; + domain_tag_rcv_next <= domain_tag_rcv; -- DEFAULT Unregistered rd_sig <= '0'; + rd_guard := '0'; reset_read_cnt <= '0'; wr_sig <= '0'; mem_opcode <= NOP; mem_op_start <= '0'; last_word_out <= '0'; reset_endpoint_alive <= '0'; - output_sig <= (others => '0'); + data_out <= (others => '0'); -- Last Word Latch Setter if (last_word_in = '1') then @@ -689,9 +691,11 @@ begin meta_addr_next <= DEFAULT_IPv4_META_ADDRESS; def_port_next <= (others => '0'); meta_port_next <= META_IPv4_MULTICAST_PORT; - lease_duration_next <= (others => (others => '0')); - expects_inline_qos_set_next <= '0'; + lease_duration_next <= DEFAULT_PARTICIPANT_LEASE_DURATION; + expects_inline_qos_rcv_next <= '0'; extra_flags_next <= (others => '0'); + extra_flags_next(EXPECTS_INLINE_QOS_FLAG) <= DEFAULT_EXPECTS_INLINE_QOS; + domain_tag_rcv_next <= '0'; -- NOTE: We work with a "mark by default, and unmark on first missmatch" System participant_match_next <= '1'; endpoint_mask_next <= (others => '1'); @@ -699,7 +703,7 @@ begin when PACKET_HEADER => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Latch Opcode opcode_next <= header_opcode; -- Latch Flags @@ -716,7 +720,7 @@ begin when PACKET_SRC_ADDR => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Latch Source IP Address src_addr_next <= data_in; @@ -725,7 +729,7 @@ begin when PACKET_SRC_ENTITYID => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Latch Source Entity ID src_entityid_next <= data_in; @@ -735,7 +739,9 @@ begin when PACKET_SRC_GUIDPREFIX => -- Input FIFO Guard and Memory Operation Guard if (empty = '0' and mem_op_done = '1') then - rd_sig <= '1'; + rd_guard := '1'; + cnt_next <= cnt + 1; + -- Latch Src GUIDPrefix case (cnt) is when 0 => @@ -749,7 +755,7 @@ begin mem_opcode <= SEARCH_PARTICIPANT; mem_op_start <= '1'; - stage_next <= PACKET_DEST_ENTITYID; + stage_next <= PACKET_DEST_ENTITYID; when others => null; end case; @@ -757,7 +763,7 @@ begin when PACKET_DEST_ENTITYID => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- DEFAULT STAGE stage_next <= SKIP_PACKET; @@ -1003,7 +1009,7 @@ begin when LATCH_SEQ_NR => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; -- Latch Sequence Number @@ -1025,7 +1031,7 @@ begin elsif (data_flag = '1') then -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- DEFAULT STAGE stage_next <= SKIP_PACKET; @@ -1068,7 +1074,7 @@ begin when PROCESS_MESSAGE => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; case (cnt) is @@ -1136,16 +1142,16 @@ begin case (cnt) is -- Liveliness Assertion Opcode when 0 => - output_sig <= OPCODE_LIVELINESS_UPDATE; + data_out <= OPCODE_LIVELINESS_UPDATE; -- GUID Prefix 1/3 when 1 => - output_sig <= guid(0); + data_out <= guid(0); -- GUID Prefix 2/3 when 2 => - output_sig <= guid(1); + data_out <= guid(1); -- GUID Prefix 3/3 when 3 => - output_sig <= guid(2); + data_out <= guid(2); -- DONE stage_next <= SKIP_PACKET; @@ -1156,7 +1162,7 @@ begin when PROCESS_GAP => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; -- Latch Sequence Numbers @@ -1182,6 +1188,7 @@ begin if (addr_res /= MAX_ADDRESS) then -- XXX: This logic relies on the sender marking continuous GAPs with the GAP Start Sequence Number and GAP End Sequence Number Set Base (i.e. the first bit in the bitmask should be 0/not in GAP) -- It also relies on the sender starting the GAP from the next expected/requested sequence number (Not Begining the GAP from an already ACKed sequence number) + -- TODO: Couldn't we do something like (first_seq_nr <= seq_nr and last_seq_nr >= next_seq_nr) to also handle the case were the GAP is not begining from the next expected? -- GAP only relevant if GAP start is the next expected sequence number if (first_seq_nr = next_seq_nr) then -- Store GAP end as last sequence number @@ -1197,7 +1204,7 @@ begin when PROCESS_HEARTBEAT => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; -- Latch Sequence Numbers @@ -1259,7 +1266,7 @@ begin end if; when PROCESS_ACKNACK => if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; -- Latch Sequence Number @@ -1532,7 +1539,7 @@ begin when PROCESS_PL => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Reset Word Counter reset_read_cnt <= '1'; -- Latch Parameter End (In order to skip parameters) @@ -1562,9 +1569,11 @@ begin -- Ignore in-line QoS -- Only relevant for Participant Discovery Protocol if(qos_flag = '0' and message_type = PDP) then - stage_next <= LATCH_STRING_LENGTH; + stage_next <= LATCH_STRING_LENGTH; -- Mark String contents (Needed for string comparison) - string_content_next <= DOMAIN_TAG_TYPE; + string_content_next <= DOMAIN_TAG_TYPE; + -- Mark reception of DOMAIN_TAG + domain_tag_rcv_next <= '1'; end if; when PID_PROTOCOL_VERSION => -- Ignore in-line QoS @@ -1578,7 +1587,7 @@ begin if(qos_flag = '0' and message_type = PDP) then stage_next <= LATCH_LOCATOR; cnt_next <= 0; - is_meta_addr_next <= '0'; + is_meta_addr_next <= '0'; end if; when PID_DEFAULT_MULTICAST_LOCATOR => -- Ignore in-line QoS @@ -1586,7 +1595,7 @@ begin if(qos_flag = '0' and message_type = PDP) then stage_next <= LATCH_LOCATOR; cnt_next <= 0; - is_meta_addr_next <= '0'; + is_meta_addr_next <= '0'; end if; when PID_METATRAFFIC_UNICAST_LOCATOR => -- Ignore in-line QoS @@ -1594,7 +1603,7 @@ begin if(qos_flag = '0' and message_type = PDP) then stage_next <= LATCH_LOCATOR; cnt_next <= 0; - is_meta_addr_next <= '1'; + is_meta_addr_next <= '1'; end if; when PID_METATRAFFIC_MULTICAST_LOCATOR => -- Ignore in-line QoS @@ -1602,7 +1611,7 @@ begin if(qos_flag = '0' and message_type = PDP) then stage_next <= LATCH_LOCATOR; cnt_next <= 0; - is_meta_addr_next <= '1'; + is_meta_addr_next <= '1'; end if; when PID_PARTICIPANT_LEASE_DURATION => -- Ignore in-line QoS @@ -1705,7 +1714,7 @@ begin stage_next <= LATCH_LOCATOR; cnt_next <= 0; -- Mark Latch 1 for storing - is_meta_addr_next <= '0'; + is_meta_addr_next <= '0'; end if; when PID_ENDPOINT_GUID => -- Ignore in-line QoS @@ -1811,6 +1820,10 @@ begin -- Ignore null; when PID_SENTINEL => + -- SANITY CHECK: Default DOMAIN TAG Match + if (domain_tag_rcv = '0' and DOMAIN_TAG /= DEFAULT_DOMAIN_TAG) then + participant_match_next <= '0'; + end if; -- If Processing in-line QoS until now, start processing data if(qos_flag = '1') then -- Override QoS Flag @@ -1836,16 +1849,18 @@ begin when LATCH_STRING_LENGTH => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; string_length_next <= unsigned(data_in_swapped); stage_next <= COMPARE_STRING; - compare_length_next <= (others => '0'); + compare_length_next <= to_unsigned(1,compare_length'length); + cnt_next <= 0; end if; when COMPARE_STRING => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; compare_length_next <= compare_length + 1; + cnt_next <= cnt + 1; -- NOTE: This assumes that the Parameter is padded with zeroes (Since we also compare the padding) -- XTypes 7.4.1.1 requires padding bytes for "PLAIN_CDR" to be zero, but does not specify the value for "PL_CDR" @@ -1882,7 +1897,7 @@ begin when MATCH_GUID => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; -- Check if GUID Prefix valid (Should be the same as the GUID Prefix of the Packet) and update the Entity ID @@ -1912,7 +1927,7 @@ begin when MATCH_DOMAIN_ID => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Match Domain ID if (data_in_swapped /= DOMAIN_ID) then @@ -1924,7 +1939,7 @@ begin when MATCH_PROTOCOL_VERSION => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Match major Protocol Version if(data_in(31 downto 24) /= PROTOCOLVERSION_2_4(15 downto 8)) then @@ -1936,7 +1951,7 @@ begin when LATCH_LOCATOR => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; case (cnt) is @@ -1952,11 +1967,12 @@ begin -- Latch Source Port -- SANITY CHECK: Check if UDP Port valid if (data_in_swapped(UDP_PORT_INVALID'range) /= UDP_PORT_INVALID) then - if (is_meta_addr = '0') then - def_port_next <= data_in_swapped(def_port'length-1 downto 0); - else - meta_port_next <= data_in_swapped(meta_port'length-1 downto 0); - end if; + -- NOTE: We have to make sure that the address is also valid + -- Temporal Latch + long_latch_next <= data_in_swapped; + else + -- Ignore + stage_next <= SKIP_PARAMETER; end if; -- Locator Address 1/4 when 2 => @@ -1973,9 +1989,11 @@ begin -- SANITY CHECK: Check if IPv4 Address valid if (data_in_swapped /= IPv4_ADDRESS_INVALID) then if (is_meta_addr = '0') then - def_addr_next <= data_in_swapped; + def_addr_next <= data_in; + def_port_next <= long_latch(def_port'length-1 downto 0); else - meta_addr_next <= data_in_swapped; + meta_addr_next <= data_in; + meta_port_next <= long_latch(meta_port'length-1 downto 0); end if; end if; -- DONE @@ -1987,11 +2005,11 @@ begin when LATCH_EXPECTS_INLINE_QOS => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Latch 'expectsInlineQoS' extra_flags_next(EXPECTS_INLINE_QOS_FLAG) <= data_in(24); - expects_inline_qos_set_next <= '1'; + expects_inline_qos_rcv_next <= '1'; -- DONE stage_next <= SKIP_PARAMETER; @@ -1999,7 +2017,7 @@ begin when LATCH_LEASE_DURATION => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; -- Latch Lease Duration @@ -2017,7 +2035,7 @@ begin when CHECK_REMOTE_BUILTIN_ENDPOINTS => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- SANITY CHECK (Builtin Participant and Participant Message Endpoints have to be always available) if ( data_in_swapped(DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER) = '0' or @@ -2026,27 +2044,20 @@ begin data_in_swapped(BUILTIN_ENDPOINT_PARTICIPANT_MESSAGE_DATA_READER) = '0') then participant_match_next <= '0'; end if; - -- Check for necessary Builtin Endpoints for Readers - if (NUM_READERS > 0) then - if ( data_in_swapped(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) = '0' or - data_in_swapped(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) = '0') then - participant_match_next <= '0'; - end if; - end if; - -- Check for necessary Builtin Endpoints for Writers - if (NUM_WRITERS > 0) then - if ( data_in_swapped(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER) = '0' or - data_in_swapped(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) = '0') then - participant_match_next <= '0'; - end if; + -- Check for necessary Builtin Endpoints for Readers and Writers + if ( (NUM_READERS > 0 and (data_in_swapped(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) = '0' or data_in_swapped(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_DETECTOR) = '0')) and + (NUM_WRITERS > 0 and (data_in_swapped(DISC_BUILTIN_ENDPOINT_SUBSCRIPTIONS_ANNOUNCER) = '0' or data_in_swapped(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) = '0')) + ) then + participant_match_next <= '0'; end if; + -- DONE stage_next <= SKIP_PARAMETER; end if; when RXO_DURABILITY => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Check QoS Compatibility (Unmark match on incompatibility) -- COMPATIBLE (DDS v1.4): offered >= requested, with VOLATILE < TRANSIENT_LOCAL < TRANSIENT < PERSISTENT @@ -2069,7 +2080,7 @@ begin when RXO_DEADLINE => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; case (cnt) is @@ -2114,7 +2125,7 @@ begin when RXO_LIVELINESS => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Check QoS Compatibility (Unmark match on incompatibility) -- COMPATIBLE (DDS v1.4): offered >= requested, with AUTOMATIC < MANUAL_BY_PARTICIPANT < MANUAL_BY_TOPIC @@ -2138,7 +2149,7 @@ begin when RXO_LEASE_DURATION => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; case (cnt) is @@ -2183,7 +2194,7 @@ begin when RXO_RELIABILITY => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Check QoS Compatibility (Unmark match on incompatibility) -- COMPATIBLE (DDS v1.4): offered >= requested, with BEST_EFFORT < RELIABLE @@ -2208,7 +2219,7 @@ begin when RXO_DESTINATION_ORDER => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- Check QoS Compatibility (Unmark match on incompatibility) -- COMPATIBLE (DDS v1.4): offered >= requested, with BY_RECEPTION_TIMESTAMP < BY_SOURCE_TIMESTAMP @@ -2231,7 +2242,7 @@ begin when RXO_OWNERSHIP => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- NOTE: Currently we only support Shared Ownership -- Check QoS Compatibility (Unmark match on incompatibility) @@ -2245,7 +2256,7 @@ begin when RXO_PRESENTATION => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; cnt_next <= cnt + 1; case (cnt) is @@ -2288,7 +2299,7 @@ begin when RXO_PARTITION => -- Input FIFO Guard if (empty = '0') then - rd_sig <= '1'; + rd_guard := '1'; -- NOTE: Endpoints are only matched against the default empty partition. -- Match Partition Names @@ -2432,44 +2443,46 @@ begin case (cnt) is -- Match Opcode when 0 => - output_sig <= OPCODE_MATCH; + data_out <= OPCODE_MATCH; -- GUID Prefix 1/3 when 1 => - output_sig <= guid(0); + data_out <= guid(0); -- GUID Prefix 2/3 when 2 => - output_sig <= guid(1); + data_out <= guid(1); -- GUID Prefix 3/3 when 3 => - output_sig <= guid(2); + data_out <= guid(2); -- Entity ID when 4 => - output_sig <= guid(3); + data_out <= guid(3); -- IPv4 Address when 5 => -- If Endpoint did not set Address, use Participant Default if (def_addr /= (def_addr'reverse_range => '0')) then - output_sig <= def_addr; + data_out <= def_addr; else - output_sig <= mem_participant_data.def_addr; + data_out <= mem_participant_data.def_addr; end if; -- UDPv4 Port and ExpectsInlineQoSFlag when 6 => -- Default - output_sig <= (others => '0'); + data_out <= (others => '0'); -- If Endpoint did not set Port, use Participant Default if (def_port /= (def_port'reverse_range => '0')) then - output_sig(31 downto 16) <= def_port; + data_out(31 downto 16) <= def_port; else - output_sig(31 downto 16) <= mem_participant_data.def_port; + data_out(31 downto 16) <= mem_participant_data.def_port; end if; -- If Endpoint did not set Flags, use Participant Default - if (expects_inline_qos_set = '1') then - output_sig(0) <= extra_flags(EXPECTS_INLINE_QOS_FLAG); + if (expects_inline_qos_rcv = '1') then + data_out(0) <= extra_flags(EXPECTS_INLINE_QOS_FLAG); else - output_sig(0) <= mem_participant_data.extra_flags(EXPECTS_INLINE_QOS_FLAG); + -- TODO: Which one is it? + --data_out(0) <= mem_participant_data.extra_flags(EXPECTS_INLINE_QOS_FLAG); + data_out(0) <= DEFAULT_EXPECTS_INLINE_QOS; end if; -- If there are Endpoints to unmatch, inform them @@ -2493,19 +2506,19 @@ begin case (cnt) is -- Match Opcode when 0 => - output_sig <= OPCODE_UNMATCH; + data_out <= OPCODE_UNMATCH; -- GUID Prefix 1/3 when 1 => - output_sig <= guid(0); + data_out <= guid(0); -- GUID Prefix 2/3 when 2 => - output_sig <= guid(1); + data_out <= guid(1); -- GUID Prefix 3/3 when 3 => - output_sig <= guid(2); + data_out <= guid(2); -- Entity ID when 4 => - output_sig <= guid(3); + data_out <= guid(3); -- If we are in the middle of an Orphan Purge Process, return to the search stage if (is_orphan_search = '1') then @@ -2527,34 +2540,34 @@ begin -- OUTPUT HEADER -- Src IPv4 Address when 0 => - output_sig <= DEFAULT_IPv4_META_ADDRESS; + data_out <= DEFAULT_IPv4_META_ADDRESS; -- Dest IPv4 Address when 1 => -- Set Default Multicast Announce Address if Participant Announcement if (return_stage = SEND_PARTICIPANT_ANNOUNCEMENT) then - output_sig <= DEFAULT_IPv4_META_ADDRESS; + data_out <= DEFAULT_IPv4_META_ADDRESS; else - output_sig <= mem_participant_data.meta_addr; + data_out <= mem_participant_data.meta_addr; end if; -- Src and Dest UDPv4 Ports when 2 => -- Set Default Multicast Announce Port if Participant Announcement if (return_stage = SEND_PARTICIPANT_ANNOUNCEMENT) then - output_sig <= META_IPv4_UNICAST_PORT & META_IPv4_MULTICAST_PORT; + data_out <= META_IPv4_UNICAST_PORT & META_IPv4_MULTICAST_PORT; else - output_sig <= META_IPv4_UNICAST_PORT & mem_participant_data.meta_port; + data_out <= META_IPv4_UNICAST_PORT & mem_participant_data.meta_port; end if; -- RTPS MESSAGE HEADER when 3 => - output_sig <= PROTOCOL_RTPS; + data_out <= PROTOCOL_RTPS; when 4 => - output_sig <= PROTOCOLVERSION_2_4 & VENDORID; + data_out <= PROTOCOLVERSION_2_4 & VENDORID; when 5 => - output_sig <= GUIDPREFIX(0); + data_out <= GUIDPREFIX(0); when 6 => - output_sig <= GUIDPREFIX(1); + data_out <= GUIDPREFIX(1); when 7 => - output_sig <= GUIDPREFIX(2); + data_out <= GUIDPREFIX(2); -- Continue with respective RTPS Submessage stage_next <= return_stage; cnt_next <= 0; @@ -2571,7 +2584,7 @@ begin participant_data_cnt_next <= participant_data_cnt + 1; -- Send Participant Data - output_sig <= PARTICIPANT_DATA.data(participant_data_cnt); + data_out <= PARTICIPANT_DATA.data(participant_data_cnt); -- Exit Condition if (participant_data_cnt = (PARTICIPANT_DATA.length-1)) then @@ -2589,69 +2602,69 @@ begin -- ACKNACK RTPS SUBMESSAGE (Publication) -- RTPS Submessage Header when 0 => - output_sig <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); + data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); -- Reader Entity ID when 1 => - output_sig <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; + data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; -- Writer Entity ID when 2 => - output_sig <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER; + data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER; -- Sequence Number Set (Bitmap Base 1/2) when 3 => - output_sig <= std_logic_vector(mem_participant_data.pub_seq_nr(0)); + data_out <= std_logic_vector(mem_participant_data.pub_seq_nr(0)); -- Sequence Number Set (Bitmap Base 2/2) when 4 => - output_sig <= std_logic_vector(mem_participant_data.pub_seq_nr(1)); + data_out <= std_logic_vector(mem_participant_data.pub_seq_nr(1)); -- Sequence Number Set (NumBits) when 5 => - output_sig <= (others => '0'); + data_out <= (others => '0'); -- Count when 6 => - output_sig <= std_logic_vector(count); + data_out <= std_logic_vector(count); -- ACKNACK RTPS SUBMESSAGE (Subscription) -- RTPS Submessage Header when 7 => - output_sig <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); + data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); -- Reader Entity ID when 8 => - output_sig <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; -- Writer Entity ID when 9 => - output_sig <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; -- Sequence Number Set (Bitmap Base 1/2) when 10 => - output_sig <= std_logic_vector(mem_participant_data.sub_seq_nr(0)); + data_out <= std_logic_vector(mem_participant_data.sub_seq_nr(0)); -- Sequence Number Set (Bitmap Base 2/2) when 11 => - output_sig <= std_logic_vector(mem_participant_data.sub_seq_nr(1)); + data_out <= std_logic_vector(mem_participant_data.sub_seq_nr(1)); -- Sequence Number Set (NumBits) when 12 => - output_sig <= (others => '0'); + data_out <= (others => '0'); -- Count when 13 => - output_sig <= std_logic_vector(count); + data_out <= std_logic_vector(count); -- ACKNACK RTPS SUBMESSAGE (Message) -- RTPS Submessage Header when 14 => - output_sig <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); + data_out <= SID_ACKNACK & "00000010" & std_logic_vector(to_unsigned(24, 16)); -- Reader Entity ID when 15 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; -- Writer Entity ID when 16 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; -- Sequence Number Set (Bitmap Base 1/2) when 17 => - output_sig <= std_logic_vector(mem_participant_data.mes_seq_nr(0)); + data_out <= std_logic_vector(mem_participant_data.mes_seq_nr(0)); -- Sequence Number Set (Bitmap Base 2/2) when 18 => - output_sig <= std_logic_vector(mem_participant_data.mes_seq_nr(1)); + data_out <= std_logic_vector(mem_participant_data.mes_seq_nr(1)); -- Sequence Number Set (NumBits) when 19 => - output_sig <= (others => '0'); + data_out <= (others => '0'); -- Count when 20 => - output_sig <= std_logic_vector(count); + data_out <= std_logic_vector(count); last_word_out <= '1'; -- DONE @@ -2669,78 +2682,78 @@ begin -- HEARTBEAT RTPS SUBMESSAGE (Publication) -- RTPS Submessage Header when 0 => - output_sig <= SID_HEARTBEAT & "00000010" & std_logic_vector(to_unsigned(28, 16)); + data_out <= SID_HEARTBEAT & "00000010" & std_logic_vector(to_unsigned(28, 16)); -- Reader Entity ID when 1 => - output_sig <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; + data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR; -- Writer Entity ID when 2 => - output_sig <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER; + data_out <= ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER; -- Sequence Number 1/2 when 3 => - output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); + data_out <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); -- Sequence Number 2/2 when 4 => - output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); + data_out <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); -- Sequence Number 1/2 when 5 => - output_sig <= std_logic_vector(PUB_SEQUENCENUMBER(0)); + data_out <= std_logic_vector(PUB_SEQUENCENUMBER(0)); -- Sequence Number 1/2 when 6 => - output_sig <= std_logic_vector(PUB_SEQUENCENUMBER(1)); + data_out <= std_logic_vector(PUB_SEQUENCENUMBER(1)); -- Count when 7 => - output_sig <= std_logic_vector(count); + data_out <= std_logic_vector(count); -- HEARTBEAT RTPS SUBMESSAGE (Subscription) -- RTPS Submessage Header when 8 => - output_sig <= SID_HEARTBEAT & "00000010" & std_logic_vector(to_unsigned(28, 16)); + data_out <= SID_HEARTBEAT & "00000010" & std_logic_vector(to_unsigned(28, 16)); -- Reader Entity ID when 9 => - output_sig <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; -- Writer Entity ID when 10 => - output_sig <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; -- Sequence Number 1/2 when 11 => - output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); + data_out <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); -- Sequence Number 2/2 when 12 => - output_sig <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); + data_out <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); -- Sequence Number 1/2 when 13 => - output_sig <= std_logic_vector(SUB_SEQUENCENUMBER(0)); + data_out <= std_logic_vector(SUB_SEQUENCENUMBER(0)); -- Sequence Number 1/2 when 14 => - output_sig <= std_logic_vector(SUB_SEQUENCENUMBER(1)); + data_out <= std_logic_vector(SUB_SEQUENCENUMBER(1)); -- Count when 15 => - output_sig <= std_logic_vector(count); + data_out <= std_logic_vector(count); -- HEARTBEAT RTPS SUBMESSAGE (Message) -- RTPS Submessage Header when 16 => - output_sig <= SID_HEARTBEAT & "00000010" & std_logic_vector(to_unsigned(28, 16)); + data_out <= SID_HEARTBEAT & "00000010" & std_logic_vector(to_unsigned(28, 16)); -- Reader Entity ID when 17 => - output_sig <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR; -- Writer Entity ID when 18 => - output_sig <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; + data_out <= ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER; -- Sequence Number 1/2 when 19 => - output_sig <= std_logic_vector(man_live_seq_nr(0)); + data_out <= std_logic_vector(man_live_seq_nr(0)); -- Sequence Number 2/2 when 20 => - output_sig <= std_logic_vector(man_live_seq_nr(1)); + data_out <= std_logic_vector(man_live_seq_nr(1)); -- Sequence Number 1/2 when 21 => - output_sig <= std_logic_vector(auto_live_seq_nr(0)); + data_out <= std_logic_vector(auto_live_seq_nr(0)); -- Sequence Number 1/2 when 22 => - output_sig <= std_logic_vector(auto_live_seq_nr(1)); + data_out <= std_logic_vector(auto_live_seq_nr(1)); -- Count when 23 => - output_sig <= std_logic_vector(count); + data_out <= std_logic_vector(count); -- If manual and automatic sequence numbers are not consecutive, we have only asserted the automatic liveliness if (live_gap_start /= auto_live_seq_nr) then stage_next <= SEND_MES_AUTO_LIVE; @@ -2764,7 +2777,7 @@ begin publisher_data_cnt_next <= publisher_data_cnt + 1; -- Send Publisher Data - output_sig <= WRITER_ENDPOINT_DATA.data(publisher_data_cnt); + data_out <= WRITER_ENDPOINT_DATA.data(publisher_data_cnt); -- Exit Condition if (publisher_data_cnt = (WRITER_ENDPOINT_DATA.length-1)) then @@ -2790,7 +2803,7 @@ begin subscriber_data_cnt_next <= subscriber_data_cnt + 1; -- Send Subscriber Data - output_sig <= READER_ENDPOINT_DATA.data(subscriber_data_cnt); + data_out <= READER_ENDPOINT_DATA.data(subscriber_data_cnt); -- Exit Condition if (subscriber_data_cnt = (READER_ENDPOINT_DATA.length-1)) then @@ -2816,41 +2829,41 @@ begin -- DATA RTPS SUBMESSAGE (Participant Message) -- RTPS Submessage Header when 0 => - output_sig <= SID_DATA & "00000100" & std_logic_vector(to_unsigned(44, 16)); + data_out <= SID_DATA & "00000100" & std_logic_vector(to_unsigned(44, 16)); -- ExtraFlags, octetsToInlineQoS when 1 => - output_sig <= x"0000" & std_logic_vector(to_unsigned(16, 16)); + data_out <= x"0000" & std_logic_vector(to_unsigned(16, 16)); -- Reader Entity ID when 2 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; -- Writer Entity ID when 3 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; -- Sequence Number 1/2 when 4 => - output_sig <= std_logic_vector(man_live_seq_nr(0)); + data_out <= std_logic_vector(man_live_seq_nr(0)); -- Sequence Number 2/2 when 5 => - output_sig <= std_logic_vector(man_live_seq_nr(1)); + data_out <= std_logic_vector(man_live_seq_nr(1)); -- Serialized Payload Header when 6 => - output_sig <= CDR_BE & x"0000"; + data_out <= CDR_BE & x"0000"; -- Serialized Payload BEGIN -- GUID Prefix 1/3 when 7 => - output_sig <= GUIDPREFIX(0); + data_out <= GUIDPREFIX(0); -- GUID Prefix 2/3 when 8 => - output_sig <= GUIDPREFIX(1); + data_out <= GUIDPREFIX(1); -- GUID Prefix 3/3 when 9 => - output_sig <= GUIDPREFIX(2); + data_out <= GUIDPREFIX(2); -- Participant Message Kind when 10 => - output_sig <= PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE; + data_out <= PARTICIPANT_MESSAGE_DATA_KIND_MANUAL_LIVELINESS_UPDATE; -- Data Length when 11 => - output_sig <= (others => '0'); + data_out <= (others => '0'); -- If manual and automatic sequence numbers are not consecutive, we need to send a GAP Message if (live_gap_start /= auto_live_seq_nr) then stage_next <= SEND_MES_GAP; @@ -2873,28 +2886,28 @@ begin -- DATA RTPS SUBMESSAGE (Participant Message) -- RTPS Submessage Header when 0 => - output_sig <= SID_GAP & "00000000" & std_logic_vector(to_unsigned(28, 16)); + data_out <= SID_GAP & "00000000" & std_logic_vector(to_unsigned(28, 16)); -- Reader Entity ID when 1 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; -- Writer Entity ID when 2 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; -- GAP Start Sequence Number 1/2 when 3 => - output_sig <= std_logic_vector(live_gap_start(0)); + data_out <= std_logic_vector(live_gap_start(0)); -- GAP Start Sequence Number 2/2 when 4 => - output_sig <= std_logic_vector(live_gap_start(1)); + data_out <= std_logic_vector(live_gap_start(1)); -- GAP End Sequence Number Set (Bitmap Base 1/2) when 5 => - output_sig <= std_logic_vector(live_gap_end(0)); + data_out <= std_logic_vector(live_gap_end(0)); -- GAP End Sequence Number Set (Bitmap Base 2/2) when 6 => - output_sig <= std_logic_vector(live_gap_end(1)); + data_out <= std_logic_vector(live_gap_end(1)); -- GAP End Sequence Number Set (NumBits) when 7 => - output_sig <= (others => '0'); + data_out <= (others => '0'); stage_next <= SEND_MES_AUTO_LIVE; cnt_next <= 0; when others => @@ -2911,41 +2924,41 @@ begin -- DATA RTPS SUBMESSAGE (Participant Message) -- RTPS Submessage Header when 0 => - output_sig <= SID_DATA & "00000100" & std_logic_vector(to_unsigned(44, 16)); + data_out <= SID_DATA & "00000100" & std_logic_vector(to_unsigned(44, 16)); -- ExtraFlags, octetsToInlineQoS when 1 => - output_sig <= x"0000" & std_logic_vector(to_unsigned(16, 16)); + data_out <= x"0000" & std_logic_vector(to_unsigned(16, 16)); -- Reader Entity ID when 2 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_READER; -- Writer Entity ID when 3 => - output_sig <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; + data_out <= ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER; -- Sequence Number 1/2 when 4 => - output_sig <= std_logic_vector(auto_live_seq_nr(0)); + data_out <= std_logic_vector(auto_live_seq_nr(0)); -- Sequence Number 2/2 when 5 => - output_sig <= std_logic_vector(auto_live_seq_nr(1)); + data_out <= std_logic_vector(auto_live_seq_nr(1)); -- Serialized Payload Header when 6 => - output_sig <= CDR_BE & x"0000"; + data_out <= CDR_BE & x"0000"; -- Serialized Payload BEGIN -- GUID Prefix 1/3 when 7 => - output_sig <= GUIDPREFIX(0); + data_out <= GUIDPREFIX(0); -- GUID Prefix 2/3 when 8 => - output_sig <= GUIDPREFIX(1); + data_out <= GUIDPREFIX(1); -- GUID Prefix 3/3 when 9 => - output_sig <= GUIDPREFIX(2); + data_out <= GUIDPREFIX(2); -- Participant Message Kind when 10 => - output_sig <= PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE; + data_out <= PARTICIPANT_MESSAGE_DATA_KIND_AUTOMATIC_LIVELINESS_UPDATE; -- Data Length when 11 => - output_sig <= (others => '0'); + data_out <= (others => '0'); last_word_out <= '1'; -- If we are in the middle of a liveliness assertion, find the next Participant destination if (is_live_assert = '1') then @@ -2961,39 +2974,82 @@ begin end case; end if; when SKIP_PARAMETER => + if (last_word_in_latch = '1' and last_word_in = '0') then + -- Reset Last Word In Latch + last_word_in_latch_next <= '0'; + -- Continue parsing next Packet + stage_next <= IDLE; + -- Reset Lengths + parameter_end_next <= (others => '1'); -- End of Parameter - if ((read_cnt & "00" ) >= parameter_end) then + elsif ((read_cnt & "00" ) >= parameter_end) then -- Parse Next Parameter -- NOTE: data_in is already showing the next parameter - stage_next <= PROCESS_PL; + stage_next <= PROCESS_PL; + -- Reset Parameter End + parameter_end_next <= (others => '1'); -- Input FIFO Guard elsif (empty = '0') then -- Skip-Read - rd_sig <= '1'; + rd_guard := '1'; end if; when SKIP_PACKET => -- NOTE: At the end of a Stale Entry Removal this stage is entered, without having started reading a Packet from input. + -- Reset Parameter End + parameter_end_next <= (others => '1'); + -- Stale Check Exit if (stale_check = '1') then -- DONE stage_next <= IDLE; -- End of Packet - elsif (last_word_in_latch = '1') then + elsif (last_word_in_latch = '1' and last_word_in = '0') then + -- Reset Last Word In Latch + last_word_in_latch_next <= '0'; -- DONE - stage_next <= IDLE; + stage_next <= IDLE; -- Input FIFO Guard elsif (empty = '0') then -- Skip-Read - rd_sig <= '1'; - -- End of Packet - if (last_word_in = '1') then - -- DONE - stage_next <= IDLE; - end if; + rd_guard := '1'; end if; when others => null; end case; + + -- OVERREAD GUARD + -- Read outside of packet Length + -- NOTE: If the Packet Length is smaller than expected there will be a read from input FIFO while + -- the Packet Length has been reached and will be caught by this clause. + -- The SKIP_PACKET clause prevents a read signal from occuring in this situation, and thus prevents from entering this state. + if ((last_word_in_latch = '1' and last_word_in = '0') and rd_guard = '1') then + -- Force rd_sig low + rd_sig <= '0'; + -- Notify Endpoints of EOP + last_word_out <= '1'; + -- Continue parsing next Packet + stage_next <= IDLE; + -- Reset Last Word In Latch + last_word_in_latch_next <= '0'; + -- Reset Lengths + parameter_end_next <= (others => '1'); + -- Read outside of Parameter Length + -- NOTE: If the Parameter Length is smaller than expected for a particular parameter, there will be a read from input FIFO while + -- the Parameter Length has been reached and will be caught by this clause. + -- The SKIP_PARAMETER clause prevents a read signal from occuring in this situation, and thus prevents from entering this state. + elsif ((read_cnt & "00") >= parameter_end and rd_guard = '1') then + -- Force rd_sig low + rd_sig <= '0'; + -- Notify Endpoints of EOP + last_word_out <= '1'; + -- Invalid Parameter Length, Skip Packet + stage_next <= SKIP_PACKET; + -- Reset Submessage End + parameter_end_next <= (others => '1'); + -- DEFAULT + else + rd_sig <= rd_guard; + end if; end process; @@ -3069,23 +3125,29 @@ begin mem_stage_next <= FIND_ENDPOINT_SLOT; mem_cnt_next <= 0; when UPDATE_PARTICIPANT => - mem_stage_next <= UPDATE_PARTICIPANT; - if (update_participant_flags(PARTICIPANT_DATA_FLAG) = '1') then + -- NOTE: We use the "_next" flag here, because it is not yet latched. + if (update_participant_flags_next(PARTICIPANT_DATA_FLAG) = '1') then + mem_stage_next <= UPDATE_PARTICIPANT; mem_addr_next <= addr_res + 3; mem_cnt_next <= 0; - elsif (update_participant_flags(LEASE_DEADLINE_FLAG) = '1') then + elsif (update_participant_flags_next(LEASE_DEADLINE_FLAG) = '1') then + mem_stage_next <= UPDATE_PARTICIPANT; mem_addr_next <= addr_res + 10; mem_cnt_next <= 7; - elsif (update_participant_flags(EXTRA_FLAGS_FLAG) = '1') then + elsif (update_participant_flags_next(EXTRA_FLAGS_FLAG) = '1') then + mem_stage_next <= UPDATE_PARTICIPANT; mem_addr_next <= addr_res + 12; mem_cnt_next <= 9; - elsif (update_participant_flags(ACKNACK_RES_TIME_FLAG) = '1') then + elsif (update_participant_flags_next(ACKNACK_RES_TIME_FLAG) = '1') then + mem_stage_next <= UPDATE_PARTICIPANT; mem_addr_next <= addr_res + 13; mem_cnt_next <= 10; - elsif (update_participant_flags(HEARTBEAT_RES_TIME_FLAG) = '1') then + elsif (update_participant_flags_next(HEARTBEAT_RES_TIME_FLAG) = '1') then + mem_stage_next <= UPDATE_PARTICIPANT; mem_addr_next <= addr_res + 15; mem_cnt_next <= 12; - elsif (update_participant_flags(EDP_SEQ_NR_FLAG) = '1') then + elsif (update_participant_flags_next(EDP_SEQ_NR_FLAG) = '1') then + mem_stage_next <= UPDATE_PARTICIPANT; mem_addr_next <= addr_res + 17; mem_cnt_next <= 14; end if; @@ -3166,6 +3228,7 @@ begin -- Match else -- Fetch Participant Data + addr_res_next <= mem_addr_base; mem_stage_next <= GET_PARTICIPANT_DATA; -- No preload needed mem_cnt_next <= 1; @@ -3229,6 +3292,7 @@ begin mem_cnt_next <= 0; -- Match Found else + addr_res_next <= mem_addr_base; mem_stage_next <= GET_ENDPOINT_MASK; mem_cnt_next <= 0; end if; @@ -3688,6 +3752,7 @@ begin max_participant_addr_next <= tmp; -- Populate Participant Slot mem_stage_next <= INSERT_PARTICIPANT; + mem_addr_next <= mem_addr_base; mem_cnt_next <= 0; end if; end if; @@ -3731,9 +3796,14 @@ begin if (last_addr = 0) then last_addr_next <= mem_addr_base; end if; + -- Continue Search + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; else -- Populate Participant Slot mem_stage_next <= INSERT_PARTICIPANT; + mem_addr_next <= mem_addr_base; mem_cnt_next <= 0; end if; end if; @@ -3755,7 +3825,7 @@ begin -- We are in the middle of resetting the MAX Participant Pointer if (reset_max_pointer = '1') then -- Reset MAX Endpoint Pointer to last occupied slot - if (last_addr /= BUILTIN_BUFFER_SIZE) then + if (last_addr /= MAX_ADDRESS) then max_endpoint_addr_next <= last_addr; end if; -- DONE @@ -3770,6 +3840,7 @@ begin max_endpoint_addr_next <= mem_addr_base; -- Populate Endpoint Slot mem_stage_next <= INSERT_ENDPOINT; + mem_addr_next <= mem_addr_base; mem_cnt_next <= 0; end if; end if; @@ -3786,9 +3857,15 @@ begin -- Slot Empty else -- If we are in the middle of resetting the MAX Participant Pointer, go through all the Endpoint memory area to reset the pointer - if (reset_max_pointer = '0') then + if (reset_max_pointer = '1') then + -- Continue Search + mem_addr_next <= tmp; + mem_addr_base_next <= tmp; + mem_cnt_next <= 0; + else -- Populate Endpoint mem_stage_next <= INSERT_ENDPOINT; + mem_addr_next <= mem_addr_base; mem_cnt_next <= 0; end if; end if; @@ -3997,7 +4074,7 @@ begin if rising_edge(clk) then -- Reset Read counter if (reset = '1' or reset_read_cnt = '1') then - read_cnt <= to_unsigned(1, read_cnt'length); + read_cnt <= (others => '0'); -- Increment read counter each time rd is high elsif (rd_sig = '1') then read_cnt <= read_cnt + 1; @@ -4014,13 +4091,13 @@ begin message_type <= NONE; string_content <= DOMAIN_TAG_TYPE; mem_stage <= IDLE; + parameter_end <= (others => '1'); opcode <= (others => '0'); flags <= (others => '0'); src_port <= (others => '0'); src_addr <= (others => '0'); src_entityid <= (others => '0'); dest_entityid <= (others => '0'); - parameter_end <= (others => '0'); string_length <= (others => '0'); compare_length <= (others => '0'); endpoint_mask <= (others => '0'); @@ -4037,8 +4114,9 @@ begin mem_addr <= (others => '0'); addr_res <= (others => '0'); last_addr <= (others => '0'); - max_participant_addr <= (others => '0'); - max_endpoint_addr <= (others => '0'); + long_latch <= (others => '0'); + max_participant_addr <= FIRST_PARTICIPANT_ADDRESS; + max_endpoint_addr <= FIRST_ENDPOINT_ADDRESS; guid <= (others => (others => '0')); mem_guidprefix <= (others => (others => '0')); endpoint_mask_array <= (others => (others => '0')); @@ -4065,13 +4143,14 @@ begin participant_match <= '0'; is_subscriber <= '0'; is_meta_addr <= '0'; - expects_inline_qos_set <= '0'; + expects_inline_qos_rcv <= '0'; is_orphan_search <= '0'; stale_check <= '0'; is_live_assert <= '0'; is_heartbeat_res <= '0'; reset_max_pointer <= '0'; last_word_in_latch <= '0'; + domain_tag_rcv <= '0'; else stage <= stage_next; return_stage <= return_stage_next; @@ -4101,6 +4180,7 @@ begin mem_addr <= mem_addr_next; addr_res <= addr_res_next; last_addr <= last_addr_next; + long_latch <= long_latch_next; max_participant_addr <= max_participant_addr_next; max_endpoint_addr <= max_endpoint_addr_next; guid <= guid_next; @@ -4129,13 +4209,14 @@ begin participant_match <= participant_match_next; is_subscriber <= is_subscriber_next; is_meta_addr <= is_meta_addr_next; - expects_inline_qos_set <= expects_inline_qos_set_next; + expects_inline_qos_rcv <= expects_inline_qos_rcv_next; is_orphan_search <= is_orphan_search_next; stale_check <= stale_check_next; is_live_assert <= is_live_assert_next; is_heartbeat_res <= is_heartbeat_res_next; reset_max_pointer <= reset_max_pointer_next; last_word_in_latch <= last_word_in_latch_next; + domain_tag_rcv <= domain_tag_rcv_next; end if; end if; end process; diff --git a/src/rtps_config_package.vhd b/src/rtps_config_package.vhd index b746c7e..8719f1a 100644 --- a/src/rtps_config_package.vhd +++ b/src/rtps_config_package.vhd @@ -69,12 +69,14 @@ package rtps_config_package is type STRING_WORD_ARRAY_TYPE is array (0 to (256/(WORD_WIDTH/8))-1) of std_logic_vector(WORD_WIDTH-1 downto 0); type ENDPOINT_STRING_TYPE is array (0 to NUM_ENDPOINTS-1) of STRING_WORD_ARRAY_TYPE; - constant ENDPOINT_TOPIC : ENDPOINT_STRING_TYPE; --Deferred to package body - constant ENDPOINT_TYPE : ENDPOINT_STRING_TYPE; --Deferred to package body - constant DOMAIN_TAG : STRING_WORD_ARRAY_TYPE; -- Deferred to package body + constant ENDPOINT_TOPIC : ENDPOINT_STRING_TYPE; --Deferred to package body + constant ENDPOINT_TYPE : ENDPOINT_STRING_TYPE; --Deferred to package body + constant DOMAIN_TAG : STRING_WORD_ARRAY_TYPE; -- Deferred to package body + constant DEFAULT_DOMAIN_TAG : STRING_WORD_ARRAY_TYPE; -- Deferred to package body -- TODO: Use everywhere constant EMPTY_STRING : STRING_WORD_ARRAY_TYPE := (others => (others => '0')); + -- Swap "data" to Big Endian representation. function endian_swap(swap : std_logic; data : std_logic_vector) return std_logic_vector; function endian_swap(swap : std_logic; data : unsigned) return unsigned; @@ -82,7 +84,7 @@ package rtps_config_package is function string_len (str : STRING_WORD_ARRAY_TYPE) return natural; function boolean_to_std_logic(input : boolean) return std_logic; - function convert_string (str : string(1 to 256)) return STRING_WORD_ARRAY_TYPE; + function convert_string (str : USER_STRING_TYPE) return STRING_WORD_ARRAY_TYPE; function round_slv(slv : std_logic_vector; width : natural) return std_logic_vector; end package; @@ -228,7 +230,7 @@ package body rtps_config_package is constant MIN_ENDPOINT_LEASE_DURATION : DURATION_TYPE := find_min_lease_duration; - function convert_string (str : string(1 to 256)) return STRING_WORD_ARRAY_TYPE is + function convert_string (str : USER_STRING_TYPE) return STRING_WORD_ARRAY_TYPE is variable ret : STRING_WORD_ARRAY_TYPE := (others => (others => '0')); begin ret := (others => (others => '0')); @@ -248,23 +250,30 @@ package body rtps_config_package is return ret; end function; - constant ENDPOINT_TOPIC : ENDPOINT_STRING_TYPE := convert_endpoint_string(ENDPOINT_TOPIC_STRING); - constant ENDPOINT_TYPE : ENDPOINT_STRING_TYPE := convert_endpoint_string(ENDPOINT_TYPE_STRING); - constant DOMAIN_TAG : STRING_WORD_ARRAY_TYPE := convert_string(USER_DOMAIN_TAG); + constant ENDPOINT_TOPIC : ENDPOINT_STRING_TYPE := convert_endpoint_string(ENDPOINT_TOPIC_STRING); + constant ENDPOINT_TYPE : ENDPOINT_STRING_TYPE := convert_endpoint_string(ENDPOINT_TYPE_STRING); + constant DOMAIN_TAG : STRING_WORD_ARRAY_TYPE := convert_string(USER_DOMAIN_TAG); + constant DEFAULT_DOMAIN_TAG : STRING_WORD_ARRAY_TYPE := convert_string(DEFAULT_USER_DOMAIN_TAG); function string_len (str : STRING_WORD_ARRAY_TYPE) return natural is - variable ret : natural := 0; + variable ret : natural := 0; + variable done : boolean := FALSE; begin - ret := 0; + ret := 0; + done := FALSE; for i in 0 to str'length-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)(WORD_WIDTH-(j*BYTE_WIDTH)-1 downto WORD_WIDTH-(j*BYTE_WIDTH)-BYTE_WIDTH) = (BYTE_WIDTH-1 downto 0 => '0')) then + done := TRUE; exit; end if; end loop; + if (done) then + exit; + end if; end loop; return ret; end function; @@ -613,7 +622,7 @@ package body rtps_config_package is len := len + 1; ret.data(ind+len):= DOMAIN_ID; -- DOMAIN TAG - if (DOMAIN_TAG /= EMPTY_STRING) then + if (DOMAIN_TAG /= DEFAULT_DOMAIN_TAG) 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_package.vhd b/src/rtps_package.vhd index ae5d43f..8bedaeb 100644 --- a/src/rtps_package.vhd +++ b/src/rtps_package.vhd @@ -113,49 +113,49 @@ package rtps_package is -- *PARAMETER IDs* constant PID_PAD : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0000"; constant PID_SENTINEL : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0001"; - constant PID_TOPIC_NAME : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0005"; - constant PID_TYPE_NAME : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0007"; - constant PID_USER_DATA : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002c"; - constant PID_GROUP_DATA : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002d"; - constant PID_TOPIC_DATA : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002e"; - constant PID_DURABILITY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001d"; - constant PID_DURABILITY_SERVICE : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001e"; - constant PID_DEADLINE : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0023"; - constant PID_LATENCY_BUDGET : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0027"; - constant PID_LIVELINESS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001b"; - constant PID_RELIABILITY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001a"; - constant PID_LIFESPAN : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002b"; - constant PID_DESTINATION_ORDER : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0025"; - constant PID_HISTORY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0040"; - constant PID_RESOURCE_LIMITS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0041"; - constant PID_OWNERSHIP : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001f"; - constant PID_OWNERSHIP_STRENGTH : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0006"; - constant PID_PRESENTATION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0021"; - constant PID_PARTITION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0029"; + constant PID_PARTICIPANT_LEASE_DURATION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0002"; constant PID_TIME_BASED_FILTER : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0004"; - constant PID_TRANSPORT_PRIORITY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0049"; + constant PID_TOPIC_NAME : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0005"; + constant PID_OWNERSHIP_STRENGTH : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0006"; + constant PID_TYPE_NAME : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0007"; constant PID_DOMAIN_ID : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"000f"; constant PID_DOMAIN_TAG : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"4014"; constant PID_PROTOCOL_VERSION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0015"; constant PID_VENDORID : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0016"; + constant PID_RELIABILITY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001a"; + constant PID_LIVELINESS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001b"; + constant PID_DURABILITY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001d"; + constant PID_DURABILITY_SERVICE : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001e"; + constant PID_OWNERSHIP : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"001f"; + constant PID_PRESENTATION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0021"; + constant PID_DEADLINE : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0023"; + constant PID_DESTINATION_ORDER : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0025"; + constant PID_LATENCY_BUDGET : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0027"; + constant PID_PARTITION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0029"; + constant PID_LIFESPAN : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002b"; + constant PID_USER_DATA : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002c"; + constant PID_GROUP_DATA : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002d"; + constant PID_TOPIC_DATA : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002e"; constant PID_UNICAST_LOCATOR : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"002f"; constant PID_MULTICAST_LOCATOR : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0030"; constant PID_DEFAULT_UNICAST_LOCATOR : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0031"; - constant PID_DEFAULT_MULTICAST_LOCATOR : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0048"; constant PID_METATRAFFIC_UNICAST_LOCATOR : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0032"; constant PID_METATRAFFIC_MULTICAST_LOCATOR : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0033"; - constant PID_EXPECTS_INLINE_QOS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0043"; constant PID_PARTICIPANT_MANUAL_LIVELINESS_COUNT : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0034"; - constant PID_PARTICIPANT_LEASE_DURATION : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0002"; constant PID_CONTENT_FILTER_PROPERTY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0035"; + constant PID_HISTORY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0040"; + constant PID_RESOURCE_LIMITS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0041"; + constant PID_EXPECTS_INLINE_QOS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0043"; + constant PID_DEFAULT_MULTICAST_LOCATOR : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0048"; + constant PID_TRANSPORT_PRIORITY : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0049"; constant PID_PARTICIPANT_GUID : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0050"; constant PID_GROUP_GUID : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0052"; constant PID_BUILTIN_ENDPOINT_SET : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0058"; - constant PID_BUILTIN_ENDPOINT_QOS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0077"; constant PID_PROPERTY_LIST : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0059"; + constant PID_ENDPOINT_GUID : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"005a"; constant PID_DATA_MAX_SIZE_SERIALIZED : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0060"; constant PID_ENTITY_NAME : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0062"; - constant PID_ENDPOINT_GUID : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"005a"; + constant PID_BUILTIN_ENDPOINT_QOS : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0077"; -- INLINE-QOS ONLY constant PID_CONTENT_FILTER_INFO : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0055"; constant PID_COHERENT_SET : std_logic_vector(PARAMETER_ID_WIDTH-1 downto 0) := x"0056"; @@ -297,6 +297,8 @@ package rtps_package is constant DEFAULT_PARTICIPANT_LEASE_DURATION : DURATION_TYPE; -- Deferred to package Body (100 s) + constant DEFAULT_EXPECTS_INLINE_QOS : std_logic := '0'; + -- *BUILTIN ENDPOINT SET POSITIONS* constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_ANNOUNCER : natural := 0; constant DISC_BUILTIN_ENDPOINT_PARTICIPANT_DETECTOR : natural := 1; @@ -320,11 +322,14 @@ package rtps_package is --*CUSTOM TYPES* type USER_BOOLEAN_ARRAY_TYPE is array (natural range <>) of boolean; - type USER_STRING_ARRAY_TYPE is array (natural range <>) of string(1 to 256); + subtype USER_STRING_TYPE is string(1 to 256); + type USER_STRING_ARRAY_TYPE is array (natural range <>) of USER_STRING_TYPE; type USER_DURATION_ARRAY_TYPE is array (natural range <>) of DURATION_TYPE; type USER_ENUMERATION_ARRAY_TYPE is array (natural range <>) of std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0); type USER_LONG_ARRAY_TYPE is array (natural range <>) of std_logic_vector(CDR_LONG_WIDTH-1 downto 0); + constant DEFAULT_USER_DOMAIN_TAG : USER_STRING_TYPE := (others => NUL); + -- *OVERLOAD FUNCTIONS* function convert_from_double_word (input: DOUBLE_WORD_ARRAY) return unsigned; function convert_to_double_word (input: unsigned(63 downto 0)) return DOUBLE_WORD_ARRAY; diff --git a/src/rtps_test_package.vhd b/src/rtps_test_package.vhd index 8efef99..54fda0f 100644 --- a/src/rtps_test_package.vhd +++ b/src/rtps_test_package.vhd @@ -217,6 +217,8 @@ package rtps_test_package is procedure gen_endpoint_data( ref : in ENDPOINT_DATA_TYPE; output : inout TEST_PACKET_TYPE); + procedure gen_sentinel(output : inout TEST_PACKET_TYPE); + procedure gen_rand_loc(RV : inout RandomPType; ret : out LOCATOR_TYPE); function int(n : integer; width : natural) return std_logic_vector; @@ -877,8 +879,9 @@ package body rtps_test_package is output.data(output.length) := endian_swap(ref.littleEndian, ref.domainId); output.length := output.length + 1; -- DOMAIN TAG - if (ref.domainTag /= EMPTY_STRING) then + if (ref.domainTag /= DEFAULT_DOMAIN_TAG) then tmp := string_len(ref.domainTag); + report "Strlen domain_tag = " & to_string(tmp); 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(output.length) := endian_swap(ref.littleEndian, int(tmp, CDR_LONG_WIDTH)); @@ -901,7 +904,7 @@ package body rtps_test_package is output.data(output.length)(31 downto 16) := ref.vendorId; output.length := output.length + 1; -- EXPECTS IN-LINE QOS - if (ref.expectsInlineQoS(0) /= '0') then + if (ref.expectsInlineQoS(0) /= DEFAULT_EXPECTS_INLINE_QOS) then output.data(output.length) := PID_EXPECTS_INLINE_QOS & endian_swap(ref.littleEndian, int(4,PARAMETER_LENGTH_WIDTH)); output.length := output.length + 1; output.data(output.length) := (others => '0'); @@ -911,11 +914,9 @@ package body rtps_test_package is -- METATRAFFIC MULTICAST LOCATOR if (ref.metatrafficMulticastLocatorList.numLocators /= (ref.metatrafficMulticastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.metatrafficMulticastLocatorList.numLocators)); - 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(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.numLocators); - output.length := output.length + 1; for i in 0 to tmp-1 loop + output.data(output.length) := PID_METATRAFFIC_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); + output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficMulticastLocatorList.locator(i).portn); @@ -933,11 +934,9 @@ package body rtps_test_package is -- METATRAFFIC UNICAST LOCATOR if (ref.metatrafficUnicastLocatorList.numLocators /= (ref.metatrafficUnicastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.metatrafficUnicastLocatorList.numLocators)); - 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(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.numLocators); - output.length := output.length + 1; for i in 0 to tmp-1 loop + output.data(output.length) := PID_METATRAFFIC_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); + output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.metatrafficUnicastLocatorList.locator(i).portn); @@ -955,11 +954,9 @@ package body rtps_test_package is -- DEFAULT MULTICAST LOCATOR if (ref.defaultMulticastLocatorList.numLocators /= (ref.defaultMulticastLocatorList.numLocators'range => '0')) then tmp := to_integer(unsigned(ref.defaultMulticastLocatorList.numLocators)); - 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(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.numLocators); - output.length := output.length + 1; for i in 0 to tmp-1 loop + output.data(output.length) := PID_DEFAULT_MULTICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); + output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultMulticastLocatorList.locator(i).portn); @@ -978,11 +975,9 @@ package body rtps_test_package is 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 tmp := to_integer(unsigned(ref.defaultUnicastLocatorList.numLocators)); - 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(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.numLocators); - output.length := output.length + 1; for i in 0 to tmp-1 loop + output.data(output.length) := PID_DEFAULT_UNICAST_LOCATOR & endian_swap(ref.littleEndian, int(24,PARAMETER_LENGTH_WIDTH)); + output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).kind); output.length := output.length + 1; output.data(output.length) := endian_swap(ref.littleEndian, ref.defaultUnicastLocatorList.locator(i).portn); @@ -1097,28 +1092,27 @@ package body rtps_test_package is else ret(i).data := (others => '-'); end if; - -- SPDP Sequence Number 1/2 - when 6 => - -- Ignored - ret(i).data := (others => '-'); - -- SPDP Sequence Number 2/2 - when 8 => - -- Ignored - ret(i).data := (others => '-'); -- Lease Duration 1/2 - when 9 => + when 8 => if (ref.match = MATCH) then ret(i).data := std_logic_vector(ref.leaseDuration(0)); else ret(i).data := (others => '-'); end if; -- Lease Duration 2/2 - when 10 => + when 9 => if (ref.match = MATCH) then ret(i).data := std_logic_vector(ref.leaseDuration(1)); else ret(i).data := (others => '-'); end if; + -- EXTRA FLAGS + when 12 => + if (ref.match = MATCH) then + ret(i).data := (0 => ref.expectsInlineQoS(0), others => '-'); + else + ret(i).data := (others => '-'); + end if; -- Other Fields Ignored when others => ret(i).data := (others => '-'); @@ -1378,6 +1372,12 @@ package body rtps_test_package is end if; end procedure; + procedure gen_sentinel(output : inout TEST_PACKET_TYPE) is + begin + output.data(output.length) := PID_SENTINEL & (PARAMETER_LENGTH_WIDTH-1 downto 0 => '0'); + output.length := output.length + 1; + end procedure; + function test_memory_match (A,B : TEST_MEMORY_TYPE) return boolean is begin if (A'length /= B'length) then