diff --git a/sim/L0_rtps_builtin_endpoint_test1.do b/sim/L0_rtps_builtin_endpoint_test1.do deleted file mode 100644 index c87213e..0000000 --- a/sim/L0_rtps_builtin_endpoint_test1.do +++ /dev/null @@ -1,71 +0,0 @@ -onerror {resume} -quietly WaveActivateNextPane {} 0 -add wave -noupdate -divider SYSTEM -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/clk -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/reset -add wave -noupdate -divider INPUT -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/empty -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/rd -add wave -noupdate -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/data_in -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/last_word_in -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/last_word_in_latch -add wave -noupdate -divider OUTPUT -add wave -noupdate -group ENDPOINTS /l0_rtps_builtin_endpoint_test1/uut/full_ue -add wave -noupdate -group ENDPOINTS /l0_rtps_builtin_endpoint_test1/uut/wr_ue -add wave -noupdate -group ENDPOINTS -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/data_out_ue -add wave -noupdate -group ENDPOINTS /l0_rtps_builtin_endpoint_test1/uut/last_word_out_ue -add wave -noupdate -group {RTPS OUT} /l0_rtps_builtin_endpoint_test1/uut/full_ro -add wave -noupdate -group {RTPS OUT} /l0_rtps_builtin_endpoint_test1/uut/wr_ro -add wave -noupdate -group {RTPS OUT} -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/data_out_ro -add wave -noupdate -group {RTPS OUT} /l0_rtps_builtin_endpoint_test1/uut/last_word_out_ro -add wave -noupdate -divider TESTBENCH -add wave -noupdate /l0_rtps_builtin_endpoint_test1/start -add wave -noupdate /l0_rtps_builtin_endpoint_test1/stim_stage -add wave -noupdate /l0_rtps_builtin_endpoint_test1/stimulus.length -add wave -noupdate /l0_rtps_builtin_endpoint_test1/cnt_stim -add wave -noupdate /l0_rtps_builtin_endpoint_test1/packet_sent -add wave -noupdate /l0_rtps_builtin_endpoint_test1/SB.ItemNumberVar -add wave -noupdate -divider {MAIN FSM} -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/stage -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/stage_next -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/cnt -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/endpoint_mask -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/participant_match -add wave -noupdate -divider {MEM FSM} -add wave -noupdate -group MEM_FSM /l0_rtps_builtin_endpoint_test1/uut/mem_opcode -add wave -noupdate -group MEM_FSM /l0_rtps_builtin_endpoint_test1/uut/mem_op_start -add wave -noupdate -group MEM_FSM /l0_rtps_builtin_endpoint_test1/uut/mem_op_done -add wave -noupdate -group MEM_FSM /l0_rtps_builtin_endpoint_test1/uut/mem_stage -add wave -noupdate -group MEM_FSM /l0_rtps_builtin_endpoint_test1/uut/mem_stage_next -add wave -noupdate -group MEM_FSM /l0_rtps_builtin_endpoint_test1/uut/mem_cnt -add wave -noupdate -group MEM_FSM -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/mem_addr_base -add wave -noupdate -divider GUARD -add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/read_cnt -add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/parameter_end -add wave -noupdate /l0_rtps_builtin_endpoint_test1/uut/parse_prc/rd_guard -add wave -noupdate -divider MEMORY -add wave -noupdate -group MEMORY -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ram_inst/addr -add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ram_inst/wen -add wave -noupdate -group MEMORY /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ram_inst/ren -add wave -noupdate -group MEMORY -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ram_inst/wr_data -add wave -noupdate -group MEMORY -radix hexadecimal /l0_rtps_builtin_endpoint_test1/uut/mem_ctrl_inst/ram_inst/rd_data -add wave -noupdate -divider MISC -add wave -noupdate -radix unsigned /l0_rtps_builtin_endpoint_test1/uut/seq_nr -TreeUpdate [SetDefaultTree] -WaveRestoreCursors {Begin {63775000 ps} 1} {Error {66975000 ps} 1} {Cursor {33675000 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 ns -update -WaveRestoreZoom {63200829 ps} {64349171 ps} diff --git a/sim/L0_rtps_discovery_module_test1_uc.do b/sim/L0_rtps_discovery_module_test1_uc.do new file mode 100644 index 0000000..6dc26ba --- /dev/null +++ b/sim/L0_rtps_discovery_module_test1_uc.do @@ -0,0 +1,65 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider SYSTEM +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/clk +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/reset +add wave -noupdate -divider INPUT +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/empty +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/rd +add wave -noupdate -radix hexadecimal /l0_rtps_discovery_module_test1_uc/uut/data_in +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/last_word_in +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/last_word_in_latch +add wave -noupdate -divider OUTPUT +add wave -noupdate -group {RTPS OUT} /l0_rtps_discovery_module_test1_uc/uut/full_ro +add wave -noupdate -group {RTPS OUT} /l0_rtps_discovery_module_test1_uc/uut/wr_ro +add wave -noupdate -group {RTPS OUT} -radix hexadecimal /l0_rtps_discovery_module_test1_uc/uut/data_out_ro +add wave -noupdate -group {RTPS OUT} /l0_rtps_discovery_module_test1_uc/uut/last_word_out_ro +add wave -noupdate -divider {MAIN FSM} +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/stage +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/cnt +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/endpoint_mask +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/participant_match +add wave -noupdate -divider {MEM FSM} +add wave -noupdate -expand -group MEM_FSM /l0_rtps_discovery_module_test1_uc/uut/mem_op_start +add wave -noupdate -expand -group MEM_FSM /l0_rtps_discovery_module_test1_uc/uut/mem_opcode +add wave -noupdate -expand -group MEM_FSM /l0_rtps_discovery_module_test1_uc/uut/mem_op_done +add wave -noupdate -expand -group MEM_FSM /l0_rtps_discovery_module_test1_uc/uut/mem_stage +add wave -noupdate -expand -group MEM_FSM /l0_rtps_discovery_module_test1_uc/uut/mem_cnt +add wave -noupdate -expand -group MEM_FSM -radix unsigned /l0_rtps_discovery_module_test1_uc/uut/mem_empty_head +add wave -noupdate -expand -group MEM_FSM -radix unsigned /l0_rtps_discovery_module_test1_uc/uut/mem_occupied_head +add wave -noupdate -expand -group MEM_FSM -radix unsigned /l0_rtps_discovery_module_test1_uc/uut/mem_addr_base +add wave -noupdate -expand -group MEMORY -radix unsigned /l0_rtps_discovery_module_test1_uc/uut/mem_ctrl_inst/ram_inst/addr +add wave -noupdate -expand -group MEMORY /l0_rtps_discovery_module_test1_uc/uut/mem_ctrl_inst/ram_inst/wen +add wave -noupdate -expand -group MEMORY /l0_rtps_discovery_module_test1_uc/uut/mem_ctrl_inst/ram_inst/ren +add wave -noupdate -expand -group MEMORY -radix hexadecimal /l0_rtps_discovery_module_test1_uc/uut/mem_ctrl_inst/ram_inst/wr_data +add wave -noupdate -expand -group MEMORY -radix hexadecimal /l0_rtps_discovery_module_test1_uc/uut/mem_ctrl_inst/ram_inst/rd_data +add wave -noupdate -divider MISC +add wave -noupdate -radix unsigned /l0_rtps_discovery_module_test1_uc/uut/seq_nr +add wave -noupdate -divider TESTBENCH +add wave -noupdate -group TESTBENCH /l0_rtps_discovery_module_test1_uc/start +add wave -noupdate -group TESTBENCH /l0_rtps_discovery_module_test1_uc/stim_stage +add wave -noupdate -group TESTBENCH /l0_rtps_discovery_module_test1_uc/stimulus.length +add wave -noupdate -group TESTBENCH /l0_rtps_discovery_module_test1_uc/cnt_stim +add wave -noupdate -group TESTBENCH /l0_rtps_discovery_module_test1_uc/packet_sent +add wave -noupdate -divider GUARD +add wave -noupdate -radix unsigned /l0_rtps_discovery_module_test1_uc/uut/read_cnt +add wave -noupdate -radix unsigned /l0_rtps_discovery_module_test1_uc/uut/parameter_end +add wave -noupdate /l0_rtps_discovery_module_test1_uc/uut/parse_prc/rd_guard +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {Begin {63775000 ps} 1} {Error {66975000 ps} 1} {Cursor {4039782 ps} 0} +quietly wave cursor active 3 +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 ns +update +WaveRestoreZoom {3817836 ps} {4966178 ps} diff --git a/src/REF.txt b/src/REF.txt index a993fc6..aaa8c5e 100644 --- a/src/REF.txt +++ b/src/REF.txt @@ -195,53 +195,55 @@ PARTICICPANT DATA | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +---------------------------------------------------------------+ -00| NEXT_ADDRESS | - +---------------------------------------------------------------+ -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| +12| UNUSED |P|S|M| +---------------------------------------------------------+-+-+-+ -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| | + +---------------------------------------------------------------+ +23| NEXT_ADDRESS | + +---------------------------------------------------------------+ +24| PREV_ADDRESS | +---------------------------------------------------------------+ M...Send Message Data (Liveliness Update) diff --git a/src/Tests/Level_0/L0_rtps_discovery_module_test1_mc.vhd b/src/Tests/Level_0/L0_rtps_discovery_module_test1_mc.vhd index 644d042..2cf00f5 100644 --- a/src/Tests/Level_0/L0_rtps_discovery_module_test1_mc.vhd +++ b/src/Tests/Level_0/L0_rtps_discovery_module_test1_mc.vhd @@ -108,6 +108,8 @@ begin variable m0, m1, m2 : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; variable p0, p1, p2, p3 : GUIDPREFIX_TYPE; + alias empty_head is <>; + -- Wrapper to use procedure as function impure function gen_rand_loc_2 return LOCATOR_TYPE is variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; @@ -171,7 +173,7 @@ begin wait until rising_edge(clk); wait until rising_edge(clk); reset <= '0'; - -- MEMORY STATE: -/0,1,2 + -- MEMORY STATE -/0,25,50 Log("Match Participant 0 [Compatible]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -192,10 +194,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p0)/1,2 + -- MEMORY STATE: 0(P0)/25,50 Log("Match Participant 1 [Compatible, Little Endian]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -210,8 +213,6 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; m1 := participant; - report "DOMAIN_ID: " & to_hstring(DOMAIN_ID); - report "PARTICIPANT DOMAIN_ID: " & to_hstring(participant.domainId); gen_participant_data(participant, rtps_sub.data); gen_sentinel('1', rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); @@ -219,10 +220,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1),0(p0)/2 + -- MEMORY STATE: 25(P1),0(P0)/50 Log("Ignore Participant 2 [Incompatible Domain ID]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -242,10 +244,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1),0(p0)/2 + -- MEMORY STATE: 25(P1),0(P0)/50 Log("Unmatch Participant 0 [Incompatible Domain ID]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -267,10 +270,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1)/0,2 + -- MEMORY STATE: 25(P1)/0,50 Log("Ignore Participant 2 [Incompatible Domain TAG]", INFO); @@ -291,10 +295,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1)/0,2 + -- MEMORY STATE: 25(P1)/0,50 Log("Unmatch Participant 1 [Incompatible Domain TAG]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -315,10 +320,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: -/1,0,2 + -- MEMORY STATE: -/25,0,50 Log("Match Participant 0 [+Unicast Metatraffic Locator]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -340,10 +346,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p0)/0,2 + -- MEMORY STATE: 25(P0)/0,50 Log("Match Participant 1 [ALL Values Set non default]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -372,10 +379,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1),1(p0)/2 + -- MEMORY STATE: 0(P1),25(P0)/50 Log("Ignore Participant 2 [Incompatible Protocol Version]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -395,10 +403,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1),1(p0)/2 + -- MEMORY STATE: 0(P1),25(P0)/50 Log("Unmatch Participant 0 [Incompatible Protocol Version]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -420,10 +429,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1)/1,2 + -- MEMORY STATE: 0(P1)/25,50 Log("Match Participant 0 [Compatible, Only Subscribers]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -442,10 +452,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p0),0(p1)/2 + -- MEMORY STATE: 25(P0),0(P1)/50 Log("Match Participant 2 [Compatible, Only Publishers]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -464,10 +475,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 74, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 2(p2),1(p0),0(p1)/- + -- MEMORY STATE: 50(P2),25(P0),0(P1)/- Log("Update Participant 1 [Valid/Invalid Default/Metatraffic Locators]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -501,10 +513,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 74, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 2(p2),1(p0),0(p1)/- + -- MEMORY STATE: 50(P2),25(P0),0(P1)/- Log("Ignore Participant 3 [Memory Full]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -527,9 +540,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 74, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE: 50(P2),25(P0),0(P1)/- Log("Unmatch Participant 2 [No Endpoints]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -546,10 +561,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p0),0(p1)/2 + -- MEMORY STATE: 25(P0),0(P1)/50 Log("Unmatch Participant 0 [Incompatible Built-in Endpoints]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -568,10 +584,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1)/1,2 + -- MEMORY STATE: 0(P1)/25,50 Log("Unmatch Participant 1 [Unregister/Dispose]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -588,11 +605,12 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.inlineQos := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; rtps_sub.flags := (SUBMESSAGE_DATA_FLAG_POS => '1', others => '0'); - -- MEMORY STATE: -/0,1,2 + -- MEMORY STATE: -/0,25,50 stim_done <= '1'; wait_on_complete; diff --git a/src/Tests/Level_0/L0_rtps_discovery_module_test1_uc.vhd b/src/Tests/Level_0/L0_rtps_discovery_module_test1_uc.vhd index 5f3b35e..a96f852 100644 --- a/src/Tests/Level_0/L0_rtps_discovery_module_test1_uc.vhd +++ b/src/Tests/Level_0/L0_rtps_discovery_module_test1_uc.vhd @@ -107,6 +107,8 @@ begin variable m0, m1, m2 : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; variable p0, p1, p2, p3 : GUIDPREFIX_TYPE; + alias empty_head is <>; + -- Wrapper to use procedure as function impure function gen_rand_loc_2 return LOCATOR_TYPE is variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; @@ -170,7 +172,7 @@ begin wait until rising_edge(clk); wait until rising_edge(clk); reset <= '0'; - -- MEMORY STATE: -/0,1,2 + -- MEMORY STATE: -/0,25,50 Log("Match Participant 0 [Compatible]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -190,10 +192,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p0)/1,2 + -- MEMORY STATE: 0(P0)/25,50 Log("Match Participant 1 [Compatible, Little Endian]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -207,8 +210,6 @@ begin participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_DETECTOR) := '1'; participant.availableBuiltinEndpoints(DISC_BUILTIN_ENDPOINT_PUBLICATIONS_ANNOUNCER) := '1'; m1 := participant; - report "DOMAIN_ID: " & to_hstring(DOMAIN_ID); - report "PARTICIPANT DOMAIN_ID: " & to_hstring(participant.domainId); gen_participant_data(participant, rtps_sub.data); gen_sentinel('1', rtps_sub.data); gen_rtps_handler_out(rtps_sub, participant, stimulus); @@ -216,10 +217,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1),0(p0)/2 + -- MEMORY STATE: 25(P1),0(P0)/50 Log("Ignore Participant 2 [Incompatible Domain ID]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -238,10 +240,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1),0(p0)/2 + -- MEMORY STATE: 25(P1),0(P0)/50 Log("Unmatch Participant 0 [Incompatible Domain ID]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -262,10 +265,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1)/0,2 + -- MEMORY STATE: 25(P1)/0,50 Log("Ignore Participant 2 [Incompatible Domain TAG]", INFO); @@ -285,10 +289,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p1)/0,2 + -- MEMORY STATE: 25(P1)/0,50 Log("Unmatch Participant 1 [Incompatible Domain TAG]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -308,10 +313,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: -/1,0,2 + -- MEMORY STATE: -/25,0,50 Log("Match Participant 0 [+Unicast Metatraffic Locator]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -332,10 +338,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p0)/0,2 + -- MEMORY STATE: 25(P0)/0,50 Log("Match Participant 1 [ALL Values Set non default]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -363,10 +370,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1),1(p0)/2 + -- MEMORY STATE: 0(P1),25(P0)/50 Log("Ignore Participant 2 [Incompatible Protocol Version]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -385,10 +393,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1),1(p0)/2 + -- MEMORY STATE: 0(P1),25(P0)/50 Log("Unmatch Participant 0 [Incompatible Protocol Version]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -409,10 +418,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1)/1,2 + -- MEMORY STATE: 0(P1)/25,50 Log("Match Participant 0 [Compatible, Only Subscribers]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -430,10 +440,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p0),0(p1)/2 + -- MEMORY STATE: 25(P0),0(P1)/50 Log("Match Participant 2 [Compatible, Only Publishers]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -451,10 +462,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 74, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 2(p2),1(p0),0(p1)/- + -- MEMORY STATE: 50(P2),25(P0),0(P1)/- Log("Update Participant 1 [Valid/Invalid Default/Metatraffic Locators]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -487,10 +499,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 74, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 2(p2),1(p0),0(p1)/- + -- MEMORY STATE: 50(P2),25(P0),0(P1)/- Log("Ignore Participant 3 [Memory Full]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -512,9 +525,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 74, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; + -- MEMORY STATE: 50(P2),25(P0),0(P1)/- Log("Unmatch Participant 2 [No Endpoints]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -530,10 +545,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 1(p0),0(p1)/2 + -- MEMORY STATE: 25(P0),0(P1)/50 Log("Unmatch Participant 0 [Incompatible Built-in Endpoints]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -551,10 +567,11 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 25, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.data := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; - -- MEMORY STATE: 0(p1)/1,2 + -- MEMORY STATE: 0(P1)/25,50 Log("Unmatch Participant 1 [Unregister/Dispose]", INFO); participant := DEFAULT_PARTICIPANT_DATA; @@ -570,11 +587,12 @@ begin start_test; wait_on_sent; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); stimulus := EMPTY_TEST_PACKET; rtps_sub.inlineQos := EMPTY_TEST_PACKET; rtps_sub.writerSN := rtps_sub.writerSN + 1; rtps_sub.flags := (SUBMESSAGE_DATA_FLAG_POS => '1', others => '0'); - -- MEMORY STATE: -/0,1,2 + -- MEMORY STATE: -/0,25,50 stim_done <= '1'; wait_on_complete; diff --git a/src/rtps_discovery_module.vhd b/src/rtps_discovery_module.vhd index d59ef12..8319eef 100644 --- a/src/rtps_discovery_module.vhd +++ b/src/rtps_discovery_module.vhd @@ -54,7 +54,7 @@ architecture arch of rtps_discovery_module is -- *PARTICIPANT MEMORY* -- 4-Byte Word Size of a Participant Entry in Memory - constant PARTICIPANT_FRAME_SIZE : natural := 24; + constant PARTICIPANT_FRAME_SIZE : natural := 25; -- Memory Size in 4-Byte Words constant PARTICIPANT_MEMORY_SIZE : natural := MAX_REMOTE_PARTICIPANTS * PARTICIPANT_FRAME_SIZE; -- Memory Address Width @@ -68,37 +68,37 @@ architecture arch of rtps_discovery_module is -- *PARTICIPANT MEMORY FRAME FIELD FLAGS* -- Flags mapping to the respective Participant Memory Frame Fields - constant PMF_FLAG_WIDTH : natural := 14; - constant PMF_NEXT_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (0 => '1', others => '0'); - constant PMF_GUIDPREFIX_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (1 => '1', others => '0'); - constant PMF_META_IPV4_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (2 => '1', others => '0'); - constant PMF_DEFAULT_IPV4_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (3 => '1', others => '0'); - constant PMF_UDP_PORT_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (4 => '1', others => '0'); - constant PMF_SPDP_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (5 => '1', others => '0'); - constant PMF_LEASE_DURATION_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (6 => '1', others => '0'); - constant PMF_LEASE_DEADLINE_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (7 => '1', others => '0'); - constant PMF_EXTRA_FLAGS_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (8 => '1', others => '0'); - constant PMF_ACKNACK_RES_TIME_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (9 => '1', others => '0'); - constant PMF_HEARTBEAT_RES_TIME_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (10 => '1', others => '0'); - constant PMF_PUB_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (11 => '1', others => '0'); - constant PMF_SUB_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (12 => '1', others => '0'); - constant PMF_MES_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (13 => '1', others => '0'); + constant PMF_FLAG_WIDTH : natural := 13; + constant PMF_GUIDPREFIX_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (0 => '1', others => '0'); + constant PMF_META_IPV4_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (1 => '1', others => '0'); + constant PMF_DEFAULT_IPV4_ADDR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (2 => '1', others => '0'); + constant PMF_UDP_PORT_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (3 => '1', others => '0'); + constant PMF_SPDP_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (4 => '1', others => '0'); + constant PMF_LEASE_DURATION_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (5 => '1', others => '0'); + constant PMF_LEASE_DEADLINE_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (6 => '1', others => '0'); + constant PMF_EXTRA_FLAGS_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (7 => '1', others => '0'); + constant PMF_ACKNACK_RES_TIME_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (8 => '1', others => '0'); + constant PMF_HEARTBEAT_RES_TIME_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (9 => '1', others => '0'); + constant PMF_PUB_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (10 => '1', others => '0'); + constant PMF_SUB_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (11 => '1', others => '0'); + constant PMF_MES_SEQ_NR_FLAG : std_logic_vector(0 to PMF_FLAG_WIDTH-1) := (12 => '1', others => '0'); -- *PARTICIPANT MEMORY FRAME FIELD OFFSETS* - constant PMF_NEXT_ADDR_OFFSET : natural := 0; - constant PMF_GUIDPREFIX_OFFSET : natural := 1; - constant PMF_META_IPV4_ADDR_OFFSET : natural := 4; - constant PMF_DEFAULT_IPV4_ADDR_OFFSET : natural := 5; - constant PMF_UDP_PORT_OFFSET : natural := 6; - constant PMF_SPDP_SEQ_NR_OFFSET : natural := 7; - constant PMF_LEASE_DURATION_OFFSET : natural := 9; - constant PMF_LEASE_DEADLINE_OFFSET : natural := 11; - constant PMF_EXTRA_FLAGS_OFFSET : natural := 13; - constant PMF_ACKNACK_RES_TIME_OFFSET : natural := 14; - constant PMF_HEARTBEAT_RES_TIME_OFFSET : natural := 16; - constant PMF_PUB_SEQ_NR_OFFSET : natural := 18; - constant PMF_SUB_SEQ_NR_OFFSET : natural := 20; - constant PMF_MES_SEQ_NR_OFFSET : natural := 22; + constant PMF_GUIDPREFIX_OFFSET : natural := 0; + constant PMF_META_IPV4_ADDR_OFFSET : natural := 3; + constant PMF_DEFAULT_IPV4_ADDR_OFFSET : natural := 4; + constant PMF_UDP_PORT_OFFSET : natural := 5; + constant PMF_SPDP_SEQ_NR_OFFSET : natural := 6; + constant PMF_LEASE_DURATION_OFFSET : natural := 8; + constant PMF_LEASE_DEADLINE_OFFSET : natural := 10; + constant PMF_EXTRA_FLAGS_OFFSET : natural := 12; + constant PMF_ACKNACK_RES_TIME_OFFSET : natural := 13; + constant PMF_HEARTBEAT_RES_TIME_OFFSET : natural := 15; + constant PMF_PUB_SEQ_NR_OFFSET : natural := 17; + constant PMF_SUB_SEQ_NR_OFFSET : natural := 19; + constant PMF_MES_SEQ_NR_OFFSET : natural := 21; + constant PMF_NEXT_ADDR_OFFSET : natural := 23; + constant PMF_PREV_ADDR_OFFSET : natural := 24; -- *EXTRA FLAGS* -- Width of extra_flags signal @@ -153,13 +153,12 @@ architecture arch of rtps_discovery_module is -- INSERT_PARTICIPANT Write Participant Data to next avialable empty slot. -- UPDATE_PARTICIPANT Update the Participant Data of the Participant Entry pointed by "mem_addr_base" according to the "mem_field_flags" flags. -- REMOVE_PARTICIPANT Remove the Participant Entry pointed by "mem_addr_base". - -- GET_FIRST_PATICIPANT Get Participant Data of first participant according to "mem_field_flags". - -- "mem_addr_base" is set to the Address of the Participant, or PARTICIPANT_MEMORY_MAX_ADDRESS if no Participant in Memory + -- "mem_addr_base" is set to the next Endpoint (or ENDPOINT_MEMORY_MAX_ADDRESS if no next Endpoint exists) -- GET_NEXT_PARTICIPANT Get Participant Data of next participant (from the one pointed by "mem_addr_base") according to "mem_field_flags". -- "mem_addr_base" is set to the Address of the Participant, or PARTICIPANT_MEMORY_MAX_ADDRESS if no Participant in Memory -- GET_PATICIPANT Get Participant Data of participant pointed by "mem_addr_update" according to "mem_field_flags". -- Already fetched Data of the same Participant is not modified - type MEM_OPCODE_TYPE is (NOP, SEARCH_PARTICIPANT, INSERT_PARTICIPANT, UPDATE_PARTICIPANT, GET_FIRST_PARTICIPANT, GET_NEXT_PARTICIPANT, REMOVE_PARTICIPANT, GET_PARTICIPANT); + type MEM_OPCODE_TYPE is (NOP, SEARCH_PARTICIPANT, INSERT_PARTICIPANT, UPDATE_PARTICIPANT, GET_NEXT_PARTICIPANT, REMOVE_PARTICIPANT, GET_PARTICIPANT); -- RTPS Data Submessage Content: -- * PDP Simple Participant Discovery Protocol Data -- * EDP Simple Endpoint Discovery Protocol Data @@ -278,7 +277,9 @@ architecture arch of rtps_discovery_module is -- Signifies that the read Locator is a Multicast Locator signal is_multicast_addr, is_multicast_addr_next : std_logic; -- General Purpose counter - signal cnt, cnt_next : natural range 0 to max(23, STRING_WORD_ARRAY_TYPE'length); + signal cnt, cnt_next : natural range 0 to 23; + -- Counter used to index STRING_WORD_ARRAY_TYPEs + signal string_cnt, string_cnt_next : natural range 0 to STRING_WORD_ARRAY_TYPE'length-1; -- 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 LOCAL_PARTICIPANT_DATA.length-1; @@ -378,6 +379,8 @@ architecture arch of rtps_discovery_module is signal data_out_sig : std_logic_vector(WORD_WIDTH-1 downto 0); -- Internal Signal for last_word_out signal last_word_out_sig : std_logic; + -- Test signal used in testbenches for removal check + signal empty_head_sig : natural; -- *MEMORY PROCESS* -- Memory FSM State @@ -392,10 +395,8 @@ architecture arch of rtps_discovery_module is signal mem_opcode : MEM_OPCODE_TYPE; -- Base Memory Address of current Participant Frame signal mem_addr_base, mem_addr_base_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0); - -- Pointer to previous Participant Memory Frame Address - signal mem_prev_addr_base, mem_prev_addr_base_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0); - -- Pointer to next Participant Memory Frame Address - signal mem_next_addr_base, mem_next_addr_base_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0); + -- General Memory Address Latch + signal mem_addr_latch, mem_addr_latch_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0); -- Head of Empty Participant List signal mem_empty_head, mem_empty_head_next : unsigned(PARTICIPANT_MEMORY_ADDR_WIDTH-1 downto 0); -- Head of Occupied Participant List @@ -471,16 +472,27 @@ architecture arch of rtps_discovery_module is return ret; end function; + -- HACK: Due to delta cycle race condition some assertions trigger false positives, + -- so we check the signals on the falling edge + function stable(clk : std_logic; a : boolean) return boolean is + begin + if (clk = '0') then + return a; + else + return TRUE; + end if; + end function; + procedure assert_sn is begin if (message_type = EDP and is_subscriber = '0') then - assert check_mask(current_pmf, PMF_PUB_SEQ_NR_FLAG) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_PUB_SEQ_NR_FLAG)) severity FAILURE; elsif (message_type = EDP and is_subscriber = '1') then - assert check_mask(current_pmf, PMF_SUB_SEQ_NR_FLAG) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_SUB_SEQ_NR_FLAG)) severity FAILURE; elsif (message_type = MESSAGE) then - assert check_mask(current_pmf, PMF_MES_SEQ_NR_FLAG) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_MES_SEQ_NR_FLAG)) severity FAILURE; elsif (message_type = PDP) then - assert check_mask(current_pmf, PMF_SPDP_SEQ_NR_FLAG) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_SPDP_SEQ_NR_FLAG)) severity FAILURE; else assert FALSE report "assert_sn: Unknown Message Type" severity FAILURE; end if; @@ -678,6 +690,7 @@ begin heartbeat_time_next <= heartbeat_time; is_live_assert_next <= is_live_assert; string_content_next <= string_content; + string_cnt_next <= string_cnt; participant_data_cnt_next <= participant_data_cnt; publisher_data_cnt_next <= publisher_data_cnt; subscriber_data_cnt_next <= subscriber_data_cnt; @@ -770,7 +783,8 @@ begin heartbeat_time_next <= time + HEARTBEAT_PERIOD; -- Send Heartbeat and Liveliness Assertions to all stored Participants mem_op_start <= '1'; - mem_opcode <= GET_FIRST_PARTICIPANT; + mem_opcode <= GET_PARTICIPANT; + mem_addr_update <= mem_occupied_head; mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; stage_next <= FIND_PARTICIPANT_DEST; -- Increment the counter for the new Heartbeat Messages @@ -783,12 +797,13 @@ begin -- Memory Operation Guard if (mem_op_done = '1') then mem_op_start <= '1'; - mem_opcode <= GET_FIRST_PARTICIPANT; + mem_opcode <= GET_PARTICIPANT; + mem_addr_update <= mem_occupied_head; mem_field_flags <= PMF_LEASE_DEADLINE_FLAG or PMF_ACKNACK_RES_TIME_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; stale_check_next <= '1'; stage_next <= PARTICIPANT_STALE_CHECK; - cnt_next <= 1; -- EXIT CONDITION + cnt_next <= 2; -- EXIT CONDITION -- Reset Timeout check_time_next <= TIME_INFINITE; @@ -875,6 +890,8 @@ begin stage_next <= PACKET_DEST_ENTITYID; end if; when PACKET_DEST_ENTITYID => + assert (mem_op_done = '1') severity FAILURE; + -- Input FIFO Guard if (empty = '0') then rd_guard := '1'; @@ -1070,6 +1087,8 @@ begin end case; end if; when CHECK_SRC_ENTITYID => + assert (mem_op_done = '1') severity FAILURE; + -- DEFAULT stage_next <= SKIP_PACKET; is_subscriber_next <= '0'; @@ -1347,16 +1366,17 @@ begin -- Wait for Participant Data if (mem_op_done = '1') then - assert check_mask(current_pmf, PMF_MES_SEQ_NR_FLAG) severity FAILURE; - -- Participant in Buffer if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then + assert stable(clk, check_mask(current_pmf, PMF_MES_SEQ_NR_FLAG)) severity FAILURE; + -- NOTE: Since the BuiltinParticipantMessageWriter has a History Depth of 1 (see DDSI-RTPS 2.3 8.4.13.3), we accept all newer SNs, since -- if the Writer has sent a newer SN he doesn't have the previous one anymore. -- Next Valid Sequence Number if (seq_nr >= mem_seq_nr) then mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_MES_SEQ_NR_FLAG; -- Process Message Data @@ -1508,13 +1528,13 @@ begin -- Wait for Sequence Number to be fetched from buffer if (mem_op_done = '1') then - assert_sn; - -- DEFAULT stage_next <= SKIP_PACKET; -- Sender known if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then + assert_sn; + -- GAP is relevant if (gap_start <= mem_seq_nr and mem_seq_nr <= gap_list_end) then -- Next Expected is in GAP List @@ -1534,6 +1554,8 @@ begin when FIND_NEXT_VALID_IN_BITMAP => -- Memory Operation Guard if (mem_op_done = '1') then + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + tmp_bitmap := to_slv_bitmap(bitmap_latch); -- First valid sequence number found @@ -1541,6 +1563,7 @@ begin -- Update next sequence number mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; if (message_type = EDP and is_subscriber = '0') then mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; elsif (message_type = EDP and is_subscriber = '1') then @@ -1586,11 +1609,11 @@ begin -- Wait for Participant Search to finish if (mem_op_done = '1') then - assert check_mask(current_pmf, PMF_HEARTBEAT_RES_TIME_FLAG) severity FAILURE; - assert_sn; - -- Participant in Buffer if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then + assert stable(clk, check_mask(current_pmf, PMF_HEARTBEAT_RES_TIME_FLAG)) severity FAILURE; + assert_sn; + -- No scheduled Heartbeat Response if (participant_data.heartbeat_res_time = TIME_INVALID) then -- If current Sequence Number obsolete (removed from source history cache) @@ -1598,6 +1621,7 @@ begin -- Store new expected Sequence Number and set Response Dealy mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; next_seq_nr_next <= first_seq_nr; if (message_type = EDP and is_subscriber = '0') then mem_field_flags <= PMF_PUB_SEQ_NR_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; @@ -1625,6 +1649,7 @@ begin -- Set Response Delay mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG; if (PARTICIPANT_HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE) then tmp_dw := time + PARTICIPANT_HEARTBEAT_RESPONSE_DELAY; @@ -1647,6 +1672,7 @@ begin -- Store new expected Sequence Number mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; next_seq_nr_next <= first_seq_nr; if (message_type = EDP and is_subscriber = '0') then mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; @@ -1687,10 +1713,10 @@ begin -- Wait for Participant Search to finish if (mem_op_done = '1') then - assert check_mask(current_pmf, PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG) severity FAILURE; - -- Participant in Buffer if (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) then + assert stable(clk, check_mask(current_pmf, PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; + -- No scheduled Acknack Response if (participant_data.acknack_res_time = TIME_INVALID) then case (message_type) is @@ -1702,6 +1728,7 @@ begin -- Set Acknack Response Time and Publisher Data as Acknack Response mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_EXTRA_FLAGS_FLAG or PMF_ACKNACK_RES_TIME_FLAG; if (PARTICIPANT_ACKNACK_RESPONSE_DELAY /= DURATION_INFINITE) then tmp_dw := time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; @@ -1725,6 +1752,7 @@ begin -- Set Acknack Response Time and set Subscriber Data as Acknack Response mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_EXTRA_FLAGS_FLAG or PMF_ACKNACK_RES_TIME_FLAG; if (PARTICIPANT_ACKNACK_RESPONSE_DELAY /= DURATION_INFINITE) then tmp_dw := time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; @@ -1750,6 +1778,7 @@ begin -- Set Acknack Response Time and set Message Data as Acknack Response mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_EXTRA_FLAGS_FLAG or PMF_ACKNACK_RES_TIME_FLAG; if (PARTICIPANT_ACKNACK_RESPONSE_DELAY /= DURATION_INFINITE) then tmp_dw := time + PARTICIPANT_ACKNACK_RESPONSE_DELAY; @@ -1782,6 +1811,7 @@ begin -- Set Publisher Data as Acknack Response mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_EXTRA_FLAGS_FLAG; extra_flags <= participant_data.extra_flags or EF_PUB_DATA_FLAG; end if; @@ -1795,6 +1825,7 @@ begin -- Set Subscriber Data as Acknack Response mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_EXTRA_FLAGS_FLAG; extra_flags <= participant_data.extra_flags or EF_SUB_DATA_FLAG; end if; @@ -1811,6 +1842,7 @@ begin -- Set Message Data as Acknack Response mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_EXTRA_FLAGS_FLAG; extra_flags <= participant_data.extra_flags or EF_MES_DATA_FLAG; end if; @@ -1849,10 +1881,18 @@ begin when 0 => mem_op_start <= '1'; mem_opcode <= GET_NEXT_PARTICIPANT; + mem_addr_update <= mem_addr_base; + mem_field_flags <= PMF_LEASE_DEADLINE_FLAG or PMF_ACKNACK_RES_TIME_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; + cnt_next <= cnt + 2; + -- GET PARTICIPANT + when 1 => + mem_op_start <= '1'; + mem_opcode <= GET_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_LEASE_DEADLINE_FLAG or PMF_ACKNACK_RES_TIME_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; cnt_next <= cnt + 1; -- EXIT CONDITION - when 1 => + when 2 => -- No More Participants if (mem_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then -- Reset @@ -1864,17 +1904,17 @@ begin cnt_next <= cnt + 1; end if; -- LEASE DEADLINE - when 2 => - assert check_mask(current_pmf, PMF_LEASE_DEADLINE_FLAG) severity FAILURE; - assert (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + when 3 => + assert stable(clk, check_mask(current_pmf, PMF_LEASE_DEADLINE_FLAG)) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; -- Lease Expiration if (participant_data.lease_deadline /= TIME_INVALID and participant_data.lease_deadline <= time) then mem_op_start <= '1'; mem_opcode <= GET_PARTICIPANT; - mem_field_flags <= PMF_GUIDPREFIX_FLAG; mem_addr_update <= mem_addr_base; - cnt_next <= 5; -- HELPER STAGE + mem_field_flags <= PMF_GUIDPREFIX_FLAG; + cnt_next <= 6; -- HELPER STAGE else -- Check Next Field cnt_next <= cnt + 1; @@ -1885,9 +1925,9 @@ begin end if; end if; -- HEARTBEAT RESPONSE TIME - when 3 => - assert check_mask(current_pmf, PMF_HEARTBEAT_RES_TIME_FLAG) severity FAILURE; - assert (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + when 4 => + assert stable(clk, check_mask(current_pmf, PMF_HEARTBEAT_RES_TIME_FLAG)) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; -- HEARTBEAT Response Time Passed if (participant_data.heartbeat_res_time /= TIME_INVALID and participant_data.heartbeat_res_time <= time) then @@ -1895,14 +1935,15 @@ begin if (participant_data.heartbeat_res_time(1)(0) = '1') then mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG; res_time <= TIME_INVALID; -- Response Delay else mem_op_start <= '1'; mem_opcode <= GET_PARTICIPANT; - mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_PUB_SEQ_NR_FLAG or PMF_SUB_SEQ_NR_FLAG or PMF_MES_SEQ_NR_FLAG; mem_addr_update <= mem_addr_base; + mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_PUB_SEQ_NR_FLAG or PMF_SUB_SEQ_NR_FLAG or PMF_MES_SEQ_NR_FLAG; -- Send ACKNACK stage_next <= SEND_HEADER; @@ -1921,9 +1962,9 @@ begin end if; end if; -- ACKNACK RESPONSE TIME - when 4 => - assert check_mask(current_pmf, PMF_ACKNACK_RES_TIME_FLAG) severity FAILURE; - assert (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + when 5 => + assert stable(clk, check_mask(current_pmf, PMF_ACKNACK_RES_TIME_FLAG)) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; -- ACKNACK Response Time Passed if (participant_data.acknack_res_time /= TIME_INVALID and participant_data.acknack_res_time <= time) then @@ -1931,14 +1972,15 @@ begin if (participant_data.acknack_res_time(1)(0) = '1') then mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG; res_time <= TIME_INVALID; -- Response Delay else mem_op_start <= '1'; mem_opcode <= GET_PARTICIPANT; - mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_EXTRA_FLAGS_FLAG; mem_addr_update <= mem_addr_base; + mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_EXTRA_FLAGS_FLAG; -- Send Requested Data stage_next <= SEND_HEADER; @@ -1947,10 +1989,7 @@ begin end if; else -- Continue Search - mem_op_start <= '1'; - mem_opcode <= GET_NEXT_PARTICIPANT; - mem_field_flags <= PMF_LEASE_DEADLINE_FLAG or PMF_ACKNACK_RES_TIME_FLAG or PMF_HEARTBEAT_RES_TIME_FLAG; - cnt_next <= 1; + cnt_next <= 0; -- Update Check Time if (participant_data.acknack_res_time /= TIME_INVALID and participant_data.acknack_res_time < check_time) then @@ -1958,8 +1997,8 @@ begin end if; end if; -- HELPER STAGE (Lacthes Participant GUID for removal) - when 5 => - assert check_mask(current_pmf, PMF_GUIDPREFIX_FLAG) severity FAILURE; + when 6 => + assert stable(clk, check_mask(current_pmf, PMF_GUIDPREFIX_FLAG)) severity FAILURE; -- Latch GUID Prefix guid_next(0) <= participant_data.guid_prefix(0); @@ -1968,13 +2007,15 @@ begin -- Remove Participant mem_op_start <= '1'; mem_opcode <= REMOVE_PARTICIPANT; + mem_addr_update <= mem_addr_base; stage_next <= INFORM_ENDPOINTS_PARTICIPANT_UNMATCH; cnt_next <= 0; -- POST-ACKNACK-SENT - when 6 => + when 7 => mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_HEARTBEAT_RES_TIME_FLAG; if (PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY /= DURATION_ZERO and PARTICIPANT_HEARTBEAT_SUPPRESSION_DELAY /= DURATION_INFINITE) then -- Set Heartbeat Suppression Time @@ -1988,13 +2029,14 @@ begin -- NOTE: The HEARTBEAT Time is re-checked in order to update the check_time -- Continue - cnt_next <= 3; + cnt_next <= 4; -- CHECK HERTBEAT Response Time -- POST-DATA-SENT - when 7 => - assert check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG) severity FAILURE; + when 8 => + assert stable(clk, check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_ACKNACK_RES_TIME_FLAG or PMF_EXTRA_FLAGS_FLAG; extra_flags <= participant_data.extra_flags and (not (EF_PUB_DATA_FLAG or EF_SUB_DATA_FLAG or EF_MES_DATA_FLAG)); if (PARTICIPANT_ACKNACK_SUPPRESSION_DELAY /= DURATION_ZERO and PARTICIPANT_ACKNACK_SUPPRESSION_DELAY /= DURATION_INFINITE) then @@ -2009,7 +2051,7 @@ begin -- NOTE: The ACKNACK Time is re-checked in order to update the check_time -- Continue - cnt_next <= 4; + cnt_next <= 5; -- CHECK ACKNACK Response Time when others => null; end case; @@ -2509,14 +2551,14 @@ begin string_length_next <= unsigned(data_in_swapped); stage_next <= COMPARE_STRING; compare_length_next <= to_unsigned(1,compare_length'length); - cnt_next <= 0; + string_cnt_next <= 0; end if; when COMPARE_STRING => -- Input FIFO Guard if (empty = '0') then rd_guard := '1'; compare_length_next <= compare_length + 1; - cnt_next <= cnt + 1; + string_cnt_next <= string_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" @@ -2525,18 +2567,18 @@ begin case (string_content) is when TOPIC_NAME_TYPE => for i in 0 to NUM_ENDPOINTS-1 loop - if (data_in /= ENDPOINT_TOPIC(i)(cnt)) then + if (data_in /= ENDPOINT_TOPIC(i)(string_cnt)) then endpoint_mask_next(i) <= '0'; end if; end loop; when TYPE_NAME_TYPE => for i in 0 to NUM_ENDPOINTS-1 loop - if (data_in /= ENDPOINT_TYPE(i)(cnt)) then + if (data_in /= ENDPOINT_TYPE(i)(string_cnt)) then endpoint_mask_next(i) <= '0'; end if; end loop; when DOMAIN_TAG_TYPE => - if (data_in /= DOMAIN_TAG(cnt)) then + if (data_in /= DOMAIN_TAG(string_cnt)) then participant_match_next <= '0'; end if; when others => @@ -3014,12 +3056,10 @@ begin -- Wait for Participant Search to finish if (mem_op_done = '1') then - assert_sn; - -- Participant not in Buffer if (mem_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then -- Participant Match - if (message_type = PDP and participant_match = '1') then + if (message_type = PDP and participant_match = '1' and mem_empty_head /= PARTICIPANT_MEMORY_MAX_ADDRESS) then -- Add participant in buffer mem_op_start <= '1'; mem_opcode <= INSERT_PARTICIPANT; @@ -3039,6 +3079,8 @@ begin end if; -- Participant in Buffer else + assert_sn; + -- Participant Announcement if (message_type = PDP) then -- Newer Sequence Number @@ -3048,6 +3090,7 @@ begin -- Remove participant from buffer mem_op_start <= '1'; mem_opcode <= REMOVE_PARTICIPANT; + mem_addr_update <= mem_addr_base; -- Inform ENDPOINTS stage_next <= INFORM_ENDPOINTS_PARTICIPANT_UNMATCH; cnt_next <= 0; @@ -3056,6 +3099,7 @@ begin -- Update Participant Data and Lease mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG or PMF_SPDP_SEQ_NR_FLAG or PMF_LEASE_DURATION_FLAG or PMF_LEASE_DEADLINE_FLAG; tmp_dw := time + lease_duration; deadline <= tmp_dw; @@ -3072,6 +3116,7 @@ begin -- Update Lease mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_LEASE_DEADLINE_FLAG; tmp_dw := time + lease_duration; deadline <= tmp_dw; @@ -3091,6 +3136,7 @@ begin -- Store new Sequence Number mem_op_start <= '1'; mem_opcode <= UPDATE_PARTICIPANT; + mem_addr_update <= mem_addr_base; if (is_subscriber = '0') then mem_field_flags <= PMF_PUB_SEQ_NR_FLAG; else @@ -3119,7 +3165,8 @@ begin -- Wait for Participant Data if (mem_op_done = '1') then - assert check_mask(current_pmf, PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_DEFAULT_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG)) severity FAILURE; -- Output FIFO Guard if ((endpoint_mask and full_rtps) = (full_rtps'range => '0')) then @@ -3253,7 +3300,7 @@ begin -- Currently in Stale Check if (stale_check = '1') then stage_next <= PARTICIPANT_STALE_CHECK; - cnt_next <= 0; -- GET NEXT PARTICIPANT + cnt_next <= 1; -- GET PARTICIPANT else -- DONE stage_next <= SKIP_PACKET; @@ -3268,7 +3315,8 @@ begin -- Wait for Participant Data if (mem_op_done = '1') then if (return_stage /= SEND_PARTICIPANT_ANNOUNCEMENT) then - assert check_mask(current_pmf, PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG)) severity FAILURE; end if; if (full_ro = '0') then @@ -3346,7 +3394,8 @@ begin -- Wait for Participant Data if (mem_op_done = '1') then - assert check_mask(current_pmf, PMF_PUB_SEQ_NR_FLAG or PMF_SUB_SEQ_NR_FLAG or PMF_MES_SEQ_NR_FLAG) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_PUB_SEQ_NR_FLAG or PMF_SUB_SEQ_NR_FLAG or PMF_MES_SEQ_NR_FLAG)) severity FAILURE; if (full_ro = '0') then wr_sig <= '1'; @@ -3460,7 +3509,7 @@ begin -- Continue stage_next <= PARTICIPANT_STALE_CHECK; - cnt_next <= 6; -- POST-ACKNACK-SENT + cnt_next <= 7; -- POST-ACKNACK-SENT when others => null; end case; @@ -3588,7 +3637,8 @@ begin -- Wait for Participant Data if (mem_op_done = '1') then - assert check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; -- If Publisher Data not scheduled for response or no Writers available, skip if (not check_mask(participant_data.extra_flags, EF_PUB_DATA_FLAG) or NUM_WRITERS = 0) then @@ -3611,7 +3661,7 @@ begin -- Currently in Stale Check elsif (stale_check = '1') then stage_next <= PARTICIPANT_STALE_CHECK; - cnt_next <= 7; -- POST-DATA-SENT + cnt_next <= 8; -- POST-DATA-SENT else -- DONE stage_next <= IDLE; @@ -3626,7 +3676,8 @@ begin -- Wait for Participant Data if (mem_op_done = '1') then - assert check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG) severity FAILURE; + assert stable(clk, mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_pmf, PMF_EXTRA_FLAGS_FLAG)) severity FAILURE; -- If Subscriber Data not scheduled for response or no Readers available, skip if (not check_mask(participant_data.extra_flags, EF_SUB_DATA_FLAG) or NUM_READERS = 0) then @@ -3650,7 +3701,7 @@ begin -- Currently in Stale Check elsif (stale_check = '1') then stage_next <= PARTICIPANT_STALE_CHECK; - cnt_next <= 7; -- POST-DATA-SENT + cnt_next <= 8; -- POST-DATA-SENT else -- DONE stage_next <= IDLE; @@ -3830,14 +3881,18 @@ begin -- If we are in the middle of a liveliness assertion, find the next Participant destination if (is_live_assert = '1') then + assert (mem_op_done = '1') severity FAILURE; + assert (mem_addr_base /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; + mem_op_start <= '1'; mem_opcode <= GET_NEXT_PARTICIPANT; + mem_addr_update <= mem_addr_base; mem_field_flags <= PMF_META_IPV4_ADDR_FLAG or PMF_UDP_PORT_FLAG; stage_next <= FIND_PARTICIPANT_DEST; -- Currently in Stale Check elsif (stale_check = '1') then stage_next <= PARTICIPANT_STALE_CHECK; - cnt_next <= 7; -- POST-DATA-SENT + cnt_next <= 8; -- POST-DATA-SENT else -- DONE stage_next <= IDLE; @@ -3922,6 +3977,8 @@ begin end if; end process; + empty_head_sig <= to_integer(mem_empty_head); + -- *Participant Memory Process* -- STATE DESCRIPTION -- IDLE Idle State. Done Signal is pulled high and Memory FSM accepts new memory operations @@ -3937,10 +3994,9 @@ begin -- DEFAULT Registered mem_stage_next <= mem_stage; mem_addr_base_next <= mem_addr_base; + mem_addr_latch_next <= mem_addr_latch; mem_empty_head_next <= mem_empty_head; mem_occupied_head_next <= mem_occupied_head; - mem_next_addr_base_next <= mem_next_addr_base; - mem_prev_addr_base_next <= mem_prev_addr_base; mem_cnt_next <= mem_cnt; participant_data_next <= participant_data; participant_latch_data_next <= participant_latch_data; @@ -3978,140 +4034,139 @@ begin case(mem_opcode) is when SEARCH_PARTICIPANT => -- Reset Data - current_pmf_next <= mem_field_flags; participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); + -- Memory Empty if (mem_occupied_head = PARTICIPANT_MEMORY_MAX_ADDRESS) then mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; else - mem_prev_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; mem_addr_base_next <= mem_occupied_head; mem_stage_next <= SEARCH_PARTICIPANT; mem_cnt_next <= 0; end if; when INSERT_PARTICIPANT => - -- Memory Full - if (mem_empty_head = PARTICIPANT_MEMORY_MAX_ADDRESS) then - report "Memory Full, Ignoring Participant Data" severity NOTE; - else - -- Reset Data - current_pmf_next <= (others => '1'); - participant_data_next <= ZERO_PARTICIPANT_DATA; + assert (mem_empty_head /= PARTICIPANT_MEMORY_MAX_ADDRESS) severity FAILURE; - mem_prev_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; - mem_next_addr_base_next <= mem_occupied_head; - mem_addr_base_next <= mem_empty_head; - mem_stage_next <= INSERT_PARTICIPANT; - mem_cnt_next <= 0; - end if; + -- Reset Data + participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); + + mem_addr_base_next <= mem_empty_head; + mem_stage_next <= INSERT_PARTICIPANT; + mem_cnt_next <= 0; when UPDATE_PARTICIPANT => - mem_stage_next <= UPDATE_PARTICIPANT; - current_pmf_next <= current_pmf or mem_field_flags; - - if check_mask(mem_field_flags,PMF_META_IPV4_ADDR_FLAG) then - mem_cnt_next <= 0; - elsif check_mask(mem_field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then - mem_cnt_next <= 1; - elsif check_mask(mem_field_flags,PMF_UDP_PORT_FLAG) then - mem_cnt_next <= 2; - elsif check_mask(mem_field_flags,PMF_SPDP_SEQ_NR_FLAG) then - mem_cnt_next <= 3; - elsif check_mask(mem_field_flags,PMF_LEASE_DURATION_FLAG) then - mem_cnt_next <= 5; - elsif check_mask(mem_field_flags,PMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 7; - elsif check_mask(mem_field_flags,PMF_EXTRA_FLAGS_FLAG) then - mem_cnt_next <= 9; - elsif check_mask(mem_field_flags,PMF_ACKNACK_RES_TIME_FLAG) then - mem_cnt_next <= 10; - elsif check_mask(mem_field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then - mem_cnt_next <= 12; - elsif check_mask(mem_field_flags,PMF_PUB_SEQ_NR_FLAG) then - mem_cnt_next <= 14; - elsif check_mask(mem_field_flags,PMF_SUB_SEQ_NR_FLAG) then - mem_cnt_next <= 16; - elsif check_mask(mem_field_flags,PMF_MES_SEQ_NR_FLAG) then - mem_cnt_next <= 18; - else - -- DONE - mem_stage_next <= IDLE; - end if; - when GET_FIRST_PARTICIPANT => - -- Reset - current_pmf_next <= mem_field_flags; - participant_data_next <= ZERO_PARTICIPANT_DATA; - - -- No Instances available - if (mem_occupied_head = PARTICIPANT_MEMORY_MAX_ADDRESS) then + if (mem_addr_update = PARTICIPANT_MEMORY_MAX_ADDRESS) then + -- Reset Data + participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; else - mem_prev_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; - mem_addr_base_next <= mem_occupied_head; - mem_stage_next <= GET_NEXT_PARTICIPANT; - mem_cnt_next <= 0; - end if; - when GET_NEXT_PARTICIPANT => - -- Reset - current_pmf_next <= mem_field_flags; - participant_data_next <= ZERO_PARTICIPANT_DATA; - - -- No Instances available - if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then - mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; - else - mem_prev_addr_base_next <= mem_addr_base; - mem_addr_base_next <= mem_next_addr_base; - mem_stage_next <= GET_NEXT_PARTICIPANT; - mem_cnt_next <= 0; + if (mem_addr_update /= mem_addr_base) then + participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); + end if; + + mem_addr_base_next <= mem_addr_update; + mem_stage_next <= UPDATE_PARTICIPANT; + if check_mask(mem_field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 0; + elsif check_mask(mem_field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 1; + elsif check_mask(mem_field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 2; + elsif check_mask(mem_field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(mem_field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(mem_field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 7; + elsif check_mask(mem_field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 9; + elsif check_mask(mem_field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(mem_field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(mem_field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 14; + elsif check_mask(mem_field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 16; + elsif check_mask(mem_field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 18; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; when REMOVE_PARTICIPANT => -- Reset - current_pmf_next <= (others => '0'); participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); - mem_stage_next <= REMOVE_PARTICIPANT; - mem_cnt_next <= 0; - when GET_PARTICIPANT => - mem_addr_base_next <= mem_addr_update; - if (mem_addr_base /= mem_addr_update) then - -- Reset - current_pmf_next <= mem_field_flags; - participant_data_next <= ZERO_PARTICIPANT_DATA; + if (mem_addr_update = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; else - current_pmf_next <= current_pmf or mem_field_flags; + mem_addr_base_next <= mem_addr_update; + mem_stage_next <= REMOVE_PARTICIPANT; + mem_cnt_next <= 0; end if; - -- Get Instance Data - mem_stage_next <= GET_PARTICIPANT_DATA; - if check_mask(mem_field_flags,PMF_GUIDPREFIX_FLAG) then - mem_cnt_next <= 0; - elsif check_mask(mem_field_flags,PMF_META_IPV4_ADDR_FLAG) then - mem_cnt_next <= 3; - elsif check_mask(mem_field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then - mem_cnt_next <= 4; - elsif check_mask(mem_field_flags,PMF_UDP_PORT_FLAG) then - mem_cnt_next <= 5; - elsif check_mask(mem_field_flags,PMF_SPDP_SEQ_NR_FLAG) then - mem_cnt_next <= 6; - elsif check_mask(mem_field_flags,PMF_LEASE_DURATION_FLAG) then - mem_cnt_next <= 8; - elsif check_mask(mem_field_flags,PMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 10; - elsif check_mask(mem_field_flags,PMF_EXTRA_FLAGS_FLAG) then - mem_cnt_next <= 12; - elsif check_mask(mem_field_flags,PMF_ACKNACK_RES_TIME_FLAG) then - mem_cnt_next <= 13; - elsif check_mask(mem_field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then - mem_cnt_next <= 15; - elsif check_mask(mem_field_flags,PMF_PUB_SEQ_NR_FLAG) then - mem_cnt_next <= 17; - elsif check_mask(mem_field_flags,PMF_SUB_SEQ_NR_FLAG) then - mem_cnt_next <= 19; - elsif check_mask(mem_field_flags,PMF_MES_SEQ_NR_FLAG) then - mem_cnt_next <= 21; + when GET_NEXT_PARTICIPANT => + -- Reset + participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); + + if (mem_addr_update = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; else - -- DONE - mem_stage_next <= IDLE; + mem_addr_base_next <= mem_addr_update; + mem_stage_next <= GET_NEXT_PARTICIPANT; + mem_cnt_next <= 0; + end if; + when GET_PARTICIPANT => + if (mem_addr_update = PARTICIPANT_MEMORY_MAX_ADDRESS) then + -- Reset Data + participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + else + if (mem_addr_update /= mem_addr_base) then + participant_data_next <= ZERO_PARTICIPANT_DATA; + current_pmf_next <= (others => '0'); + end if; + + mem_addr_base_next <= mem_addr_update; + mem_stage_next <= GET_PARTICIPANT_DATA; + if check_mask(mem_field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 0; + elsif check_mask(mem_field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(mem_field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(mem_field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(mem_field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(mem_field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(mem_field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(mem_field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(mem_field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(mem_field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(mem_field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(mem_field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(mem_field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; when others => null; @@ -4120,18 +4175,8 @@ begin when SEARCH_PARTICIPANT => case (mem_cnt) is - -- GET Next Participant - when 0 => - mem_valid_in <= '1'; - mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; - mem_read <= '1'; - - -- Memory Flow Control Guard - if (mem_ready_in = '1') then - mem_cnt_next <= mem_cnt + 1; - end if; -- GET GUID Prefix 1/3 - when 1 => + when 0 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET; mem_read <= '1'; @@ -4141,7 +4186,7 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- GET GUID Prefix 2/3 - when 2 => + when 1 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 1; mem_read <= '1'; @@ -4151,7 +4196,7 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- GET GUID Prefix 3/3 - when 3 => + when 2 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 2; mem_read <= '1'; @@ -4160,86 +4205,49 @@ begin if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- READ Next Participant - when 4 => - mem_ready_out <= '1'; - - -- Memory Flow Control Guard - if (mem_valid_out = '1') then - mem_next_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); - mem_cnt_next <= mem_cnt + 1; - end if; -- READ GUID Prefix 1/3 - when 5 => + when 3 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then -- No Match if (mem_read_data /= participant_latch_data.guid_prefix(0)) then - mem_abort_read <= '1'; - -- Reached List Tail, No Match - if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then - mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_prev_addr_base_next <= mem_addr_base; - mem_addr_base_next <= mem_next_addr_base; - mem_cnt_next <= 0; - end if; + mem_abort_read <= '1'; + mem_cnt_next <= 6; -- GET Next Participant else mem_cnt_next <= mem_cnt + 1; end if; end if; -- READ GUID Prefix 2/3 - when 6 => + when 4 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then -- No Match if (mem_read_data /= participant_latch_data.guid_prefix(1)) then - mem_abort_read <= '1'; - -- Reached List Tail, No Match - if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then - mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_prev_addr_base_next <= mem_addr_base; - mem_addr_base_next <= mem_next_addr_base; - mem_cnt_next <= 0; - end if; + mem_abort_read <= '1'; + mem_cnt_next <= 6; -- GET Next Participant else mem_cnt_next <= mem_cnt + 1; end if; end if; -- READ GUID Prefix 3/3 - when 7 => + when 5 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then -- No Match if (mem_read_data /= participant_latch_data.guid_prefix(2)) then - -- Reached List Tail, No Match - if (mem_next_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then - mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_prev_addr_base_next <= mem_addr_base; - mem_addr_base_next <= mem_next_addr_base; - mem_cnt_next <= 0; - end if; + mem_abort_read <= '1'; + mem_cnt_next <= 6; -- GET Next Participant else + mem_addr_base_next <= mem_addr_base; + -- Get Participant Data mem_stage_next <= GET_PARTICIPANT_DATA; - if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then mem_cnt_next <= 0; elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then @@ -4272,6 +4280,31 @@ begin end if; end if; end if; + -- GET Next Addr + when 6 => + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_read <= '1'; + mem_valid_in <= '1'; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Addr + when 7 => + mem_ready_out <= '1'; + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + -- No more Endpoints + if (resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH) = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; --No match + -- DONE + mem_stage_next <= IDLE; + else + -- Continue + mem_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + mem_cnt_next <= 0; + end if; + end if; when others => null; end case; @@ -4293,39 +4326,45 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then - mem_next_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); - -- Get Instance Data - mem_stage_next <= GET_PARTICIPANT_DATA; - - if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then - mem_cnt_next <= 0; - elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then - mem_cnt_next <= 3; - elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then - mem_cnt_next <= 4; - elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then - mem_cnt_next <= 5; - elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then - mem_cnt_next <= 6; - elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then - mem_cnt_next <= 8; - elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 10; - elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then - mem_cnt_next <= 12; - elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then - mem_cnt_next <= 13; - elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then - mem_cnt_next <= 15; - elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then - mem_cnt_next <= 17; - elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then - mem_cnt_next <= 19; - elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then - mem_cnt_next <= 21; - else + if (resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH) = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; -- DONE mem_stage_next <= IDLE; + else + mem_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + + -- Get Instance Data + mem_stage_next <= GET_PARTICIPANT_DATA; + if check_mask(participant_latch_data.field_flags,PMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 0; + elsif check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then + mem_cnt_next <= 3; + elsif check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then + mem_cnt_next <= 5; + elsif check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 10; + elsif check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then + mem_cnt_next <= 12; + elsif check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then + mem_cnt_next <= 13; + elsif check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then + mem_cnt_next <= 17; + elsif check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then + mem_cnt_next <= 19; + elsif check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; end if; when others => @@ -4948,6 +4987,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.guid_prefix(2) <= mem_read_data; + current_pmf_next <= current_pmf or PMF_GUIDPREFIX_FLAG; if check_mask(participant_latch_data.field_flags,PMF_META_IPV4_ADDR_FLAG) then mem_cnt_next <= 26; @@ -4985,6 +5025,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.meta_addr <= mem_read_data; + current_pmf_next <= current_pmf or PMF_META_IPV4_ADDR_FLAG; if check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then mem_cnt_next <= 27; @@ -5020,6 +5061,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.def_addr <= mem_read_data; + current_pmf_next <= current_pmf or PMF_DEFAULT_IPV4_ADDR_FLAG; if check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then mem_cnt_next <= 28; @@ -5054,6 +5096,7 @@ begin if (mem_valid_out = '1') then participant_data_next.meta_port <= mem_read_data(WORD_WIDTH-1 downto UDP_PORT_WIDTH); participant_data_next.def_port <= mem_read_data(UDP_PORT_WIDTH-1 downto 0); + current_pmf_next <= current_pmf or PMF_UDP_PORT_FLAG; if check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then mem_cnt_next <= 29; @@ -5094,6 +5137,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.spdp_seq_nr(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_SPDP_SEQ_NR_FLAG; if check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then mem_cnt_next <= 31; @@ -5132,6 +5176,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.lease_duration(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_LEASE_DURATION_FLAG; if check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then mem_cnt_next <= 33; @@ -5168,6 +5213,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.lease_deadline(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_LEASE_DEADLINE_FLAG; if check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then mem_cnt_next <= 35; @@ -5193,6 +5239,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.extra_flags <= mem_read_data(EF_FLAG_WIDTH-1 downto 0); + current_pmf_next <= current_pmf or PMF_EXTRA_FLAGS_FLAG; if check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then mem_cnt_next <= 36; @@ -5225,6 +5272,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.acknack_res_time(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_ACKNACK_RES_TIME_FLAG; if check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then mem_cnt_next <= 38; @@ -5255,6 +5303,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.heartbeat_res_time(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_HEARTBEAT_RES_TIME_FLAG; if check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then mem_cnt_next <= 40; @@ -5283,6 +5332,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.pub_seq_nr(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_PUB_SEQ_NR_FLAG; if check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then mem_cnt_next <= 42; @@ -5309,6 +5359,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.sub_seq_nr(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_SUB_SEQ_NR_FLAG; if check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then mem_cnt_next <= 44; @@ -5333,6 +5384,7 @@ begin -- Memory Flow Control Guard if (mem_valid_out = '1') then participant_data_next.mes_seq_nr(1) <= unsigned(mem_read_data); + current_pmf_next <= current_pmf or PMF_MES_SEQ_NR_FLAG; -- DONE mem_stage_next <= IDLE; @@ -5344,7 +5396,7 @@ begin -- Precondition: mem_addr_base set case (mem_cnt) is - -- GET Next Pointer + -- GET Next Addr when 0 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; @@ -5354,32 +5406,8 @@ begin if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- SET Next Pointer - when 1 => - mem_valid_in <= '1'; - mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; - mem_write_data <= std_logic_vector(resize(mem_occupied_head,WORD_WIDTH)); - - -- Memory Flow Control Guard - if (mem_ready_in = '1') then - -- Fix Occupied Head - mem_occupied_head_next <= mem_addr_base; - - mem_cnt_next <= mem_cnt + 1; - end if; - -- READ Next Pointer - when 2 => - mem_ready_out <= '1'; - - -- Memory Flow Control Guard - if (mem_valid_out = '1') then - -- Fix Empty List Head - mem_empty_head_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); - - mem_cnt_next <= mem_cnt + 1; - end if; -- SET GUID Prefix 1/3 - when 3 => + when 1 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET; mem_write_data <= participant_latch_data.guid_prefix(0); @@ -5390,7 +5418,7 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET GUID Prefix 2/3 - when 4 => + when 2 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 1; mem_write_data <= participant_latch_data.guid_prefix(1); @@ -5401,52 +5429,56 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET GUID Prefix 3/3 - when 5 => + when 3 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_GUIDPREFIX_OFFSET + 2; mem_write_data <= participant_latch_data.guid_prefix(2); participant_data_next.guid_prefix(2) <= participant_latch_data.guid_prefix(2); + current_pmf_next <= current_pmf or PMF_GUIDPREFIX_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Metatraffic IPv4 Address - when 6 => + when 4 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_META_IPV4_ADDR_OFFSET; mem_write_data <= participant_latch_data.meta_addr; participant_data_next.meta_addr <= participant_latch_data.meta_addr; + current_pmf_next <= current_pmf or PMF_META_IPV4_ADDR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Default IPv4 Address - when 7 => + when 5 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_DEFAULT_IPV4_ADDR_OFFSET; mem_write_data <= participant_latch_data.def_addr; participant_data_next.def_addr <= participant_latch_data.def_addr; + current_pmf_next <= current_pmf or PMF_DEFAULT_IPV4_ADDR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET UDP Ports - when 8 => + when 6 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_UDP_PORT_OFFSET; mem_write_data <= participant_latch_data.meta_port & participant_latch_data.def_port; participant_data_next.meta_port <= participant_latch_data.meta_port; participant_data_next.def_port <= participant_latch_data.def_port; + current_pmf_next <= current_pmf or PMF_UDP_PORT_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET SPDP Sequence Number 1/2 - when 9 => + when 7 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET; mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(0)); @@ -5457,18 +5489,19 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET SPDP Sequence Number 2/2 - when 10 => + when 8 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); participant_data_next.spdp_seq_nr(1) <= participant_latch_data.seq_nr(1); + current_pmf_next <= current_pmf or PMF_SPDP_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Lease Duration 1/2 - when 11 => + when 9 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET; mem_write_data <= std_logic_vector(participant_latch_data.lease_duration(0)); @@ -5479,18 +5512,19 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET Lease Duration 2/2 - when 12 => + when 10 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.lease_duration(1)); participant_data_next.lease_duration(1) <= participant_latch_data.lease_duration(1); + current_pmf_next <= current_pmf or PMF_LEASE_DURATION_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Lease Deadline 1/2 - when 13 => + when 11 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET; mem_write_data <= std_logic_vector(participant_latch_data.lease_deadline(0)); @@ -5501,30 +5535,32 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET Lease Deadline 2/2 - when 14 => + when 12 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.lease_deadline(1)); participant_data_next.lease_deadline(1) <= participant_latch_data.lease_deadline(1); + current_pmf_next <= current_pmf or PMF_LEASE_DEADLINE_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Extra Flags - when 15 => + when 13 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_EXTRA_FLAGS_OFFSET; mem_write_data <= (others => '0'); mem_write_data(EF_FLAG_WIDTH-1 downto 0) <= participant_latch_data.extra_flags; participant_data_next.extra_flags <= participant_latch_data.extra_flags; + current_pmf_next <= current_pmf or PMF_EXTRA_FLAGS_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET ACKNACK Response Time 1/2 - when 16 => + when 14 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET; mem_write_data <= std_logic_vector(TIME_INVALID(0)); @@ -5534,18 +5570,19 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET ACKNACK Response Time 2/2 - when 17 => + when 15 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET + 1; mem_write_data <= std_logic_vector(TIME_INVALID(1)); participant_data_next.acknack_res_time <= TIME_INVALID; + current_pmf_next <= current_pmf or PMF_ACKNACK_RES_TIME_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET HEARTBEAT Response Time 1/2 - when 18 => + when 16 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET; mem_write_data <= std_logic_vector(TIME_INVALID(0)); @@ -5555,18 +5592,19 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET HEARTBEAT Response Time 2/2 - when 19 => + when 17 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET + 1; mem_write_data <= std_logic_vector(TIME_INVALID(1)); participant_data_next.heartbeat_res_time <= TIME_INVALID; + current_pmf_next <= current_pmf or PMF_HEARTBEAT_RES_TIME_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Publication Sequence Number 1/2 - when 20 => + when 18 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); @@ -5576,18 +5614,19 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET Publication Sequence Number 2/2 - when 21 => + when 19 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); participant_data_next.pub_seq_nr <= FIRST_SEQUENCENUMBER; + current_pmf_next <= current_pmf or PMF_PUB_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Subscription Sequence Number 1/2 - when 22 => + when 20 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); @@ -5597,18 +5636,19 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET Subscription Sequence Number 2/2 - when 23 => + when 21 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); participant_data_next.sub_seq_nr <= FIRST_SEQUENCENUMBER; + current_pmf_next <= current_pmf or PMF_SUB_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; -- SET Message Sequence Number 1/2 - when 24 => + when 22 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); @@ -5618,17 +5658,62 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- SET Message Sequence Number 2/2 - when 25 => + when 23 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); participant_data_next.mes_seq_nr <= FIRST_SEQUENCENUMBER; + current_pmf_next <= current_pmf or PMF_MES_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Next Addr + when 24 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_occupied_head,WORD_WIDTH)); + + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Prev Addr + when 25 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PREV_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(PARTICIPANT_MEMORY_MAX_ADDRESS,WORD_WIDTH)); + + if (mem_ready_in = '1') then + if (mem_occupied_head = PARTICIPANT_MEMORY_MAX_ADDRESS) then + mem_cnt_next <= mem_cnt + 2; -- Skip Next Step + else + mem_cnt_next <= mem_cnt + 1; + end if; + end if; + -- SET Prev Addr (Occupied Head) + when 26 => + mem_valid_in <= '1'; + mem_addr <= mem_occupied_head + PMF_PREV_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_addr_base,WORD_WIDTH)); + + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Addr + when 27 => + mem_ready_out <= '1'; + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + + -- Update List Heads + mem_empty_head_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + mem_occupied_head_next <= mem_addr_base; + -- DONE mem_stage_next <= IDLE; end if; + when others => null; end case; @@ -5640,6 +5725,7 @@ begin mem_addr <= mem_addr_base + PMF_META_IPV4_ADDR_OFFSET; mem_write_data <= participant_latch_data.meta_addr; participant_data_next.meta_addr <= participant_latch_data.meta_addr; + current_pmf_next <= current_pmf or PMF_META_IPV4_ADDR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_DEFAULT_IPV4_ADDR_FLAG) then @@ -5675,6 +5761,7 @@ begin mem_addr <= mem_addr_base + PMF_DEFAULT_IPV4_ADDR_OFFSET; mem_write_data <= participant_latch_data.def_addr; participant_data_next.def_addr <= participant_latch_data.def_addr; + current_pmf_next <= current_pmf or PMF_DEFAULT_IPV4_ADDR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_UDP_PORT_FLAG) then @@ -5709,6 +5796,7 @@ begin mem_write_data <= participant_latch_data.meta_port & participant_latch_data.def_port; participant_data_next.meta_port <= participant_latch_data.meta_port; participant_data_next.def_port <= participant_latch_data.def_port; + current_pmf_next <= current_pmf or PMF_UDP_PORT_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_SPDP_SEQ_NR_FLAG) then @@ -5749,6 +5837,7 @@ begin mem_addr <= mem_addr_base + PMF_SPDP_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); participant_data_next.spdp_seq_nr <= participant_latch_data.seq_nr; + current_pmf_next <= current_pmf or PMF_SPDP_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_LEASE_DURATION_FLAG) then @@ -5787,6 +5876,7 @@ begin mem_addr <= mem_addr_base + PMF_LEASE_DURATION_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.lease_duration(1)); participant_data_next.lease_duration <= participant_latch_data.lease_duration; + current_pmf_next <= current_pmf or PMF_LEASE_DURATION_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_LEASE_DEADLINE_FLAG) then @@ -5823,6 +5913,7 @@ begin mem_addr <= mem_addr_base + PMF_LEASE_DEADLINE_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.lease_deadline(1)); participant_data_next.lease_deadline <= participant_latch_data.lease_deadline; + current_pmf_next <= current_pmf or PMF_LEASE_DEADLINE_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_EXTRA_FLAGS_FLAG) then @@ -5849,6 +5940,7 @@ begin mem_write_data <= (others => '0'); mem_write_data(EF_FLAG_WIDTH-1 downto 0) <= participant_latch_data.extra_flags; participant_data_next.extra_flags <= participant_latch_data.extra_flags; + current_pmf_next <= current_pmf or PMF_EXTRA_FLAGS_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_ACKNACK_RES_TIME_FLAG) then @@ -5881,6 +5973,7 @@ begin mem_addr <= mem_addr_base + PMF_ACKNACK_RES_TIME_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.res_time(1)); participant_data_next.acknack_res_time <= participant_latch_data.res_time; + current_pmf_next <= current_pmf or PMF_ACKNACK_RES_TIME_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_HEARTBEAT_RES_TIME_FLAG) then @@ -5911,6 +6004,7 @@ begin mem_addr <= mem_addr_base + PMF_HEARTBEAT_RES_TIME_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.res_time(1)); participant_data_next.heartbeat_res_time <= participant_latch_data.res_time; + current_pmf_next <= current_pmf or PMF_HEARTBEAT_RES_TIME_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_PUB_SEQ_NR_FLAG) then @@ -5939,6 +6033,7 @@ begin mem_addr <= mem_addr_base + PMF_PUB_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); participant_data_next.pub_seq_nr <= participant_latch_data.seq_nr; + current_pmf_next <= current_pmf or PMF_PUB_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_SUB_SEQ_NR_FLAG) then @@ -5965,6 +6060,7 @@ begin mem_addr <= mem_addr_base + PMF_SUB_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); participant_data_next.sub_seq_nr <= participant_latch_data.seq_nr; + current_pmf_next <= current_pmf or PMF_SUB_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(participant_latch_data.field_flags,PMF_MES_SEQ_NR_FLAG) then @@ -5989,6 +6085,7 @@ begin mem_addr <= mem_addr_base + PMF_MES_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(participant_latch_data.seq_nr(1)); participant_data_next.mes_seq_nr <= participant_latch_data.seq_nr; + current_pmf_next <= current_pmf or PMF_MES_SEQ_NR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then -- DONE @@ -5998,64 +6095,96 @@ begin null; end case; when REMOVE_PARTICIPANT => - -- Precondition: mem_addr_base set, mem_prev_addr_base set + -- Precondition: mem_addr_base set case (mem_cnt) is - -- GET Next Participant + -- GET Next Addr when 0 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; mem_read <= '1'; - -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- READ Next Participant + -- GET Prev Addr when 1 => - mem_ready_out <= '1'; - - -- Memory Flow Control Guard - if (mem_valid_out = '1') then - mem_next_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); - - -- Removed Participant is List Head - if (mem_prev_addr_base = PARTICIPANT_MEMORY_MAX_ADDRESS) then - assert (mem_addr_base = mem_occupied_head) severity FAILURE; - - -- Fix Occupied Head - mem_occupied_head_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); - - mem_cnt_next <= mem_cnt + 2; -- Skip Next Step - else - mem_cnt_next <= mem_cnt + 1; - end if; - end if; - -- SET Next Pointer (Previous Participant) - when 2 => - -- Point Previous Participant to Next Participant (Remove current Participant from inbetween) mem_valid_in <= '1'; - mem_addr <= mem_prev_addr_base + PMF_NEXT_ADDR_OFFSET; - mem_write_data <= std_logic_vector(resize(mem_next_addr_base,WORD_WIDTH)); - + mem_addr <= mem_addr_base + PMF_PREV_ADDR_OFFSET; + mem_read <= '1'; -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- SET Next Pointer (Current/Removed Instance) - when 3 => - -- Point Current Instance to Empty List Head (Make Removed Instance Head of the Empty List) + -- SET Next Addr + when 2 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; mem_write_data <= std_logic_vector(resize(mem_empty_head,WORD_WIDTH)); - -- Memory Flow Control Guard if (mem_ready_in = '1') then - -- Fix Empty List Head + -- Set New Empty Head mem_empty_head_next <= mem_addr_base; - -- Reset - mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Addr + when 3 => + mem_ready_out <= '1'; + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + mem_addr_latch_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Prev Addr + when 4 => + mem_ready_out <= '1'; + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + if (mem_addr_latch = PARTICIPANT_MEMORY_MAX_ADDRESS) then + if (resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH) = PARTICIPANT_MEMORY_MAX_ADDRESS) then + -- RESET Occupied List Head + mem_occupied_head_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + + mem_addr_base_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + -- DONE + mem_stage_next <= IDLE; + else + mem_addr_base_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + mem_cnt_next <= mem_cnt + 2; -- Skip Next Step + end if; + else + mem_addr_base_next <= mem_addr_latch; + mem_addr_latch_next <= resize(unsigned(mem_read_data),PARTICIPANT_MEMORY_ADDR_WIDTH); + mem_cnt_next <= mem_cnt + 1; + end if; + end if; + -- SET Prev Addr (Next Slot) + when 5 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PREV_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_addr_latch,WORD_WIDTH)); + + if (mem_ready_in = '1') then + if (mem_addr_latch = PARTICIPANT_MEMORY_MAX_ADDRESS) then + -- Set New Occupied List Head + mem_occupied_head_next <= mem_addr_base; + -- DONE + mem_stage_next <= IDLE; + else + mem_addr_base_next <= mem_addr_latch; + mem_addr_latch_next <= mem_addr_base; + mem_cnt_next <= mem_cnt + 1; + end if; + end if; + -- SET Next Addr (Previous Slot) + when 6 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_addr_latch,WORD_WIDTH)); + + if (mem_ready_in = '1') then + mem_addr_base_next <= mem_addr_latch; -- DONE mem_stage_next <= IDLE; end if; @@ -6064,12 +6193,8 @@ begin end case; when RESET_MEMORY => case (mem_cnt) is - -- Initialize + -- SET Next Pointer when 0 => - mem_addr_base_next <= FIRST_PARTICIPANT_ADDRESS; - mem_cnt_next <= mem_cnt + 1; - -- Set Next Pointer - when 1 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + PMF_NEXT_ADDR_OFFSET; if (mem_addr_base = MAX_PARTICIPANT_ADDRESS) then @@ -6078,14 +6203,29 @@ begin mem_write_data <= std_logic_vector(resize(mem_addr_base + PARTICIPANT_FRAME_SIZE,WORD_WIDTH)); end if; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Previous Pointer + when 1 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + PMF_PREV_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_addr_latch,WORD_WIDTH)); + -- Memory Flow Control Guard if (mem_ready_in = '1') then if (mem_addr_base = MAX_PARTICIPANT_ADDRESS) then + -- Initialize Empty and Occupied Heads + mem_empty_head_next <= FIRST_PARTICIPANT_ADDRESS; + mem_occupied_head_next <= PARTICIPANT_MEMORY_MAX_ADDRESS; + -- DONE - mem_stage_next <= IDLE; - mem_empty_head_next <= FIRST_PARTICIPANT_ADDRESS; + mem_stage_next <= IDLE; else + mem_addr_latch_next <= mem_addr_base; mem_addr_base_next <= mem_addr_base + PARTICIPANT_FRAME_SIZE; + mem_cnt_next <= 0; end if; end if; when others => @@ -6133,11 +6273,10 @@ begin guid <= GUID_UNKNOWN; src_entityid <= ENTITYID_UNKNOWN; dest_entityid <= ENTITYID_UNKNOWN; - mem_addr_base <= PARTICIPANT_MEMORY_MAX_ADDRESS; + mem_addr_base <= FIRST_PARTICIPANT_ADDRESS; + mem_addr_latch <= PARTICIPANT_MEMORY_MAX_ADDRESS; mem_empty_head <= PARTICIPANT_MEMORY_MAX_ADDRESS; mem_occupied_head <= PARTICIPANT_MEMORY_MAX_ADDRESS; - mem_next_addr_base <= PARTICIPANT_MEMORY_MAX_ADDRESS; - mem_prev_addr_base <= PARTICIPANT_MEMORY_MAX_ADDRESS; seq_nr <= SEQUENCENUMBER_UNKNOWN; next_seq_nr <= SEQUENCENUMBER_UNKNOWN; sn_latch_1 <= SEQUENCENUMBER_UNKNOWN; @@ -6161,6 +6300,7 @@ begin participant_data_cnt <= 0; publisher_data_cnt <= 0; subscriber_data_cnt <= 0; + string_cnt <= 0; participant_match <= '0'; is_subscriber <= '0'; is_meta_addr <= '0'; @@ -6202,10 +6342,9 @@ begin src_entityid <= src_entityid_next; dest_entityid <= dest_entityid_next; mem_addr_base <= mem_addr_base_next; + mem_addr_latch <= mem_addr_latch_next; mem_empty_head <= mem_empty_head_next; mem_occupied_head <= mem_occupied_head_next; - mem_next_addr_base <= mem_next_addr_base_next; - mem_prev_addr_base <= mem_prev_addr_base_next; seq_nr <= seq_nr_next; next_seq_nr <= next_seq_nr_next; sn_latch_1 <= sn_latch_1_next; @@ -6229,6 +6368,7 @@ begin participant_data_cnt <= participant_data_cnt_next; publisher_data_cnt <= publisher_data_cnt_next; subscriber_data_cnt <= subscriber_data_cnt_next; + string_cnt <= string_cnt_next; participant_match <= participant_match_next; is_subscriber <= is_subscriber_next; is_meta_addr <= is_meta_addr_next; diff --git a/src/rtps_test_package.vhd b/src/rtps_test_package.vhd index 60a454d..a0beb6d 100644 --- a/src/rtps_test_package.vhd +++ b/src/rtps_test_package.vhd @@ -22,7 +22,7 @@ package rtps_test_package is -- Frame Sizes have to be specified, so that direct memory probing is possible -- rtps_discovery_module Participant Frame Size - constant PARTICIPANT_FRAME_SIZE : natural := 24; + constant PARTICIPANT_FRAME_SIZE : natural := 25; -- rtps_reader Endpoint Frame Size (RELIABLE=TRUE) constant WRITER_ENDPOINT_FRAME_SIZE_A : natural := 17; -- rtps_reader Endpoint Frame Size (RELIABLE=FALSE) @@ -1871,28 +1871,28 @@ package body rtps_test_package is ret(i).addr := start + i; case (i) is -- GUID Prefix 1/3 - when 1 => + when 0 => ret(i).data := ref.guidPrefix(0); -- GUID Prefix 2/3 - when 2 => + when 1 => ret(i).data := ref.guidPrefix(1); -- GUID Prefix 3/3 - when 3 => + when 2 => ret(i).data := ref.guidPrefix(2); -- METATRAFFIC IPv4 Address - when 4 => + when 3 => ret(i).data := meta_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); -- DEFAULT IPv4 Address - when 5 => + when 4 => ret(i).data := user_loc.addr(IPv4_ADDRESS_WIDTH-1 downto 0); -- METATRAFFIC & DEFAULT UDP Port - when 6 => + when 5 => ret(i).data := meta_loc.portn(UDP_PORT_WIDTH-1 downto 0) & user_loc.portn(UDP_PORT_WIDTH-1 downto 0); -- Lease Duration 1/2 - when 9 => + when 8 => ret(i).data := std_logic_vector(ref.leaseDuration(0)); -- Lease Duration 2/2 - when 10 => + when 9 => ret(i).data := std_logic_vector(ref.leaseDuration(1)); -- Other Fields Ignored when others =>