diff --git a/sim/L0_rtps_reader_test1_vrk.do b/sim/L0_rtps_reader_test1_vrk.do index 091978b..4ec02da 100644 --- a/sim/L0_rtps_reader_test1_vrk.do +++ b/sim/L0_rtps_reader_test1_vrk.do @@ -1,52 +1,52 @@ onerror {resume} quietly WaveActivateNextPane {} 0 add wave -noupdate -divider SYSTEM -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/clk -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/reset +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/clk +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/reset add wave -noupdate -divider INPUT -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/empty_meta -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/rd_meta -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/last_word_in_meta -add wave -noupdate -radix hexadecimal /l0_rtps_reader_test1_vrk/uut/data_in_meta +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/empty_meta +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/rd_meta +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/last_word_in_meta +add wave -noupdate -radix hexadecimal /l0_rtps_reader_test1_vbk/uut/data_in_meta add wave -noupdate -divider OUTPUT -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/start_hc -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/opcode_hc -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/ack_hc -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/done_hc -add wave -noupdate -radix hexadecimal /l0_rtps_reader_test1_vrk/uut/data_out_hc +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/start_hc +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/opcode_hc +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/ack_hc +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/done_hc +add wave -noupdate -radix hexadecimal /l0_rtps_reader_test1_vbk/uut/data_out_hc add wave -noupdate -divider {MAIN FSM} -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/stage -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/stage_next -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/cnt +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/stage +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/stage_next +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/cnt add wave -noupdate -divider {MEMORY FSM} -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/mem_op_done -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/mem_op_start -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/mem_opcode -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/mem_stage -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/mem_stage_next -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/mem_cnt -add wave -noupdate /l0_rtps_reader_test1_vrk/uut/mem_pos -add wave -noupdate -radix unsigned /l0_rtps_reader_test1_vrk/uut/mem_addr_base -add wave -noupdate -expand -group MEM_CTRL -radix unsigned /l0_rtps_reader_test1_vrk/uut/mem_addr -add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vrk/uut/mem_valid_in -add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vrk/uut/mem_ready_in -add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vrk/uut/mem_read -add wave -noupdate -expand -group MEM_CTRL -radix hexadecimal /l0_rtps_reader_test1_vrk/uut/mem_write_data -add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vrk/uut/abort_read -add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vrk/uut/mem_valid_out -add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vrk/uut/mem_ready_out -add wave -noupdate -expand -group MEM_CTRL -radix hexadecimal /l0_rtps_reader_test1_vrk/uut/mem_read_data +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/mem_op_done +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/mem_op_start +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/mem_opcode +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/mem_stage +add wave -noupdate /l0_rtps_reader_test1_vbk/uut/mem_cnt +add wave -noupdate -radix unsigned /l0_rtps_reader_test1_vbk/uut/mem_occupied_head +add wave -noupdate -radix unsigned /l0_rtps_reader_test1_vbk/uut/mem_empty_head +add wave -noupdate -radix unsigned /l0_rtps_reader_test1_vbk/uut/mem_addr_base +add wave -noupdate -expand -group MEM_CTRL -radix unsigned /l0_rtps_reader_test1_vbk/uut/mem_addr +add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vbk/uut/mem_valid_in +add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vbk/uut/mem_ready_in +add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vbk/uut/mem_read +add wave -noupdate -expand -group MEM_CTRL -radix hexadecimal /l0_rtps_reader_test1_vbk/uut/mem_write_data +add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vbk/uut/abort_read +add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vbk/uut/mem_valid_out +add wave -noupdate -expand -group MEM_CTRL /l0_rtps_reader_test1_vbk/uut/mem_ready_out +add wave -noupdate -expand -group MEM_CTRL -radix hexadecimal /l0_rtps_reader_test1_vbk/uut/mem_read_data add wave -noupdate -divider TESTBENCH -add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vrk/start -add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vrk/cnt_stim -add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vrk/packet_sent -add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vrk/mem_check_done -add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vrk/stim_done -add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vrk/test_done -add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vrk/uut/idle_sig +add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vbk/start +add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vbk/cnt_stim +add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vbk/packet_sent +add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vbk/mem_check_done +add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vbk/stim_done +add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vbk/test_done +add wave -noupdate -group TESTBENCH /l0_rtps_reader_test1_vbk/uut/idle_sig TreeUpdate [SetDefaultTree] -WaveRestoreCursors {Begin {8325000 ps} 1} {Error {9725000 ps} 1} {Cursor {9175000 ps} 0} -quietly wave cursor active 3 +WaveRestoreCursors {Cursor {8391550 ps} 0} +quietly wave cursor active 1 configure wave -namecolwidth 150 configure wave -valuecolwidth 100 configure wave -justifyvalue left @@ -61,4 +61,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {8888200 ps} {9912200 ps} +WaveRestoreZoom {7937 ns} {8961 ns} diff --git a/src/REF.txt b/src/REF.txt index 4d6545a..a993fc6 100644 --- a/src/REF.txt +++ b/src/REF.txt @@ -371,6 +371,12 @@ READER + RES_TIME + [Reliable Only] 13| | +---------------------------------------------------------------+ +14| WRITER_ID | + +---------------------------------------------------------------+ +15| NEXT_ADDR | + +---------------------------------------------------------------+ +16| PREV_ADDR | + +---------------------------------------------------------------+ WRITER ------ diff --git a/src/Tests/Level_0/L0_rtps_reader_test1_vbk.vhd b/src/Tests/Level_0/L0_rtps_reader_test1_vbk.vhd index 26a8b4c..e4216d6 100644 --- a/src/Tests/Level_0/L0_rtps_reader_test1_vbk.vhd +++ b/src/Tests/Level_0/L0_rtps_reader_test1_vbk.vhd @@ -118,6 +118,8 @@ begin variable p0, p1, participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; variable e0, e1, e2, e3, endpoint : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; + 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; @@ -189,6 +191,7 @@ begin wait until rising_edge(clk); wait until rising_edge(clk); reset <= '0'; + -- MEMORY STATE -/0,13,26 Log("Insert Endpoint 0 Participant 0", INFO); @@ -199,9 +202,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,0,0] + AlertIf(empty_head /= 13, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 0(P0E0)/13,26 Log("Insert Endpoint 1 Participant 0", INFO); endpoint := e1; @@ -211,9 +215,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,0] + AlertIf(empty_head /= 26, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 13(P0E1),0(P0E0)/26 Log("Insert Endpoint 2 Participant 1", INFO); endpoint := e2; @@ -223,9 +228,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,p1e2] + AlertIf(empty_head /= 38, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 26(P1E2),13(P0E1),0(P0E0)/- Log("Ignore Endpoint 3 Participant 1 [Memory Full]", INFO); endpoint := e3; @@ -246,22 +252,23 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,p1e3] + AlertIf(empty_head /= 38, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 26(P1E2),13(P0E1),0(P0E0)/- Log("Remove Endpoint 2 Participant 1", INFO); endpoint := e2; endpoint.nr := 2; endpoint.match := UNMATCH; gen_endpoint_match_frame(endpoint, stimulus); - SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,0] + AlertIf(empty_head /= 26, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 13(P0E1),0(P0E0)/26 Log("Insert Endpoint 3 Participant 1", INFO); endpoint := e3; @@ -271,31 +278,31 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,p1e3] + AlertIf(empty_head /= 38, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 26(P1E3),13(P0E1),0(P0E0)/- Log("Remove Participant 0", INFO); participant := p0; participant.match := UNMATCH; gen_participant_match_frame(participant, stimulus); - -- Remove Endpoint 0 - endpoint := e0; - endpoint.nr := 0; - endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); - SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); -- Remove Endpoint 1 endpoint := e1; endpoint.nr := 1; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); + SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); + -- Remove Endpoint 0 + endpoint := e0; + endpoint.nr := 0; + endpoint.match := UNMATCH; SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [0,0,p1e3] + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 26(P1E3)/0,13 Log("Insert Endpoint 2 Participant 1", INFO); endpoint := e2; @@ -305,9 +312,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p1e2,0,p1e3] + AlertIf(empty_head /= 13, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 0(P1E2),26(P1E3)/13 Log("Unknown Metatraffic Operation followed by insertion of Enpoint 0 Participant 0", INFO); for i in 0 to 9 loop @@ -334,9 +342,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p1e2,p0e0,p1e3] + AlertIf(empty_head /= 38, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 13(P0E0),0(P1E2),26(P1E3)/- Log("Update Endpoint 2 Participant 1", INFO); endpoint := e2; @@ -348,11 +357,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_b(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p1e2,p0e0,p1e3] - - + AlertIf(empty_head /= 38, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 13(P0E0),0(P1E2),26(P1E3)/- stim_done <= '1'; wait_on_completion; diff --git a/src/Tests/Level_0/L0_rtps_reader_test1_vrk.vhd b/src/Tests/Level_0/L0_rtps_reader_test1_vrk.vhd index 33102d2..a307da6 100644 --- a/src/Tests/Level_0/L0_rtps_reader_test1_vrk.vhd +++ b/src/Tests/Level_0/L0_rtps_reader_test1_vrk.vhd @@ -118,6 +118,8 @@ begin variable p0, p1, participant : PARTICIPANT_DATA_TYPE := DEFAULT_PARTICIPANT_DATA; variable e0, e1, e2, e3, endpoint : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; + 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; @@ -189,6 +191,7 @@ begin wait until rising_edge(clk); wait until rising_edge(clk); reset <= '0'; + -- MEMORY STATE -/0,17,34 Log("Insert Endpoint 0 Participant 0", INFO); @@ -199,9 +202,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,0,0] + AlertIf(empty_head /= 17, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 0(P0E0)/17,34 Log("Insert Endpoint 1 Participant 0", INFO); endpoint := e1; @@ -211,9 +215,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,0] + AlertIf(empty_head /= 34, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 17(P0E1),0(P0E0)/34 Log("Insert Endpoint 2 Participant 1", INFO); endpoint := e2; @@ -223,9 +228,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,p1e2] + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 34(P1E2),17(P0E1),0(P0E0)/- Log("Ignore Endpoint 3 Participant 1 [Memory Full]", INFO); endpoint := e3; @@ -246,22 +252,23 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,p1e3] + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 34(P1E2),17(P0E1),0(P0E0)/- Log("Remove Endpoint 2 Participant 1", INFO); endpoint := e2; endpoint.nr := 2; endpoint.match := UNMATCH; gen_endpoint_match_frame(endpoint, stimulus); - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,0] + AlertIf(empty_head /= 34, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 17(P0E1),0(P0E0)/34 Log("Insert Endpoint 3 Participant 1", INFO); endpoint := e3; @@ -271,31 +278,31 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p0e0,p0e1,p1e3] + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 34(P1E3),17(P0E1),0(P0E0)/- Log("Remove Participant 0", INFO); participant := p0; participant.match := UNMATCH; gen_participant_match_frame(participant, stimulus); - -- Remove Endpoint 0 - endpoint := e0; - endpoint.nr := 0; - endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); - SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); -- Remove Endpoint 1 endpoint := e1; endpoint.nr := 1; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); + SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); + -- Remove Endpoint 0 + endpoint := e0; + endpoint.nr := 0; + endpoint.match := UNMATCH; SB_out.Push(std_logic_vector(to_unsigned(endpoint.nr, WORD_WIDTH))); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [0,0,p1e3] + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 34(P1E3)/0,17 Log("Insert Endpoint 2 Participant 1", INFO); endpoint := e2; @@ -305,9 +312,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p1e2,0,p1e3] + AlertIf(empty_head /= 17, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 0(P1E2),34(P1E3)/17 Log("Unknown Metatraffic Operation followed by insertion of Enpoint 0 Participant 0", INFO); for i in 0 to 9 loop @@ -334,9 +342,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p1e2,p0e0,p1e3] + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 17(P0E0),0(P1E2),34(P1E3)/- Log("Update Endpoint 2 Participant 1", INFO); endpoint := e2; @@ -348,9 +357,10 @@ begin SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); start_test; wait_on_sent; - stimulus := EMPTY_TEST_PACKET; + stimulus := EMPTY_TEST_PACKET; wait_on_mem_check; - -- MEMORY STATE [p1e2,p0e0,p1e3] + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); + -- MEMORY STATE 17(P0E0),0(P1E2),34(P1E3)/- stim_done <= '1'; wait_on_completion; diff --git a/src/Tests/Level_0/L0_rtps_reader_test3_a.vhd b/src/Tests/Level_0/L0_rtps_reader_test3_a.vhd index 5c99948..93f37bc 100644 --- a/src/Tests/Level_0/L0_rtps_reader_test3_a.vhd +++ b/src/Tests/Level_0/L0_rtps_reader_test3_a.vhd @@ -107,6 +107,7 @@ begin alias mem_op_done is <>; alias idle_sig is <>; + alias empty_head is <>; -- Wrapper to use procedure as function impure function gen_rand_loc_2 return LOCATOR_TYPE is @@ -261,6 +262,7 @@ begin wait until rising_edge(clk); wait until rising_edge(clk); reset <= '0'; + -- MEMORY STATE -/0,17,34 Log("Current Time: 0 s", INFO); wait until rising_edge(clk); @@ -276,9 +278,11 @@ begin mem_check <= '1'; wait_on_mem_check; mem_check <= '0'; + AlertIf(empty_head /= 17, "Memory Empty List Head incorrect", FAILURE); stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 0(P0E0)/17,34 Log("Insert Endpoint 1 Participant 1", INFO); endpoint := e1; @@ -291,9 +295,11 @@ begin mem_check <= '1'; wait_on_mem_check; mem_check <= '0'; + AlertIf(empty_head /= 34, "Memory Empty List Head incorrect", FAILURE); stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 17(P1E1),0(P0E0)/34 Log("Insert Endpoint 2 Participant 2", INFO); endpoint := e2; @@ -306,9 +312,11 @@ begin mem_check <= '1'; wait_on_mem_check; mem_check <= '0'; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),17(P1E1),0(P0E0)/- wait_on_idle; Log("Current Time: 1 s", INFO); @@ -334,6 +342,7 @@ begin stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),17(P1E1),0(P0E0)/- wait_on_idle; Log("Current Time: 2 s", INFO); @@ -347,6 +356,7 @@ begin stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),17(P1E1),0(P0E0)/- wait_on_idle; Log("Current Time: 5 s", INFO); @@ -365,15 +375,16 @@ begin endpoint := e2; endpoint.nr := 2; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); SB_out.Push("0" & std_logic_vector(to_unsigned(2, WORD_WIDTH))); wait_on_out_check; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 34, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 17(P1E1),0(P0E0)/34 wait_on_idle; Log("Current Time: 6 s", INFO); @@ -384,7 +395,6 @@ begin endpoint := e0; endpoint.nr := 0; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e1; endpoint.nr := 1; endpoint.match := MATCH; @@ -392,15 +402,16 @@ begin endpoint := e2; endpoint.nr := 2; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); SB_out.Push("0" & std_logic_vector(to_unsigned(0, WORD_WIDTH))); wait_on_out_check; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 17(P1E1)/0,34 wait_on_idle; Log("Current Time: 7 s", INFO); @@ -411,23 +422,22 @@ begin endpoint := e0; endpoint.nr := 0; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e1; endpoint.nr := 1; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e2; endpoint.nr := 2; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); SB_out.Push("0" & std_logic_vector(to_unsigned(1, WORD_WIDTH))); wait_on_out_check; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 17, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE -/17,0,34 stim_done <= '1'; wait_on_completion; diff --git a/src/Tests/Level_0/L0_rtps_reader_test3_m.vhd b/src/Tests/Level_0/L0_rtps_reader_test3_m.vhd index 9381d5e..90a9d7b 100644 --- a/src/Tests/Level_0/L0_rtps_reader_test3_m.vhd +++ b/src/Tests/Level_0/L0_rtps_reader_test3_m.vhd @@ -107,6 +107,7 @@ begin alias mem_op_done is <>; alias idle_sig is <>; + alias empty_head is <>; -- Wrapper to use procedure as function impure function gen_rand_loc_2 return LOCATOR_TYPE is @@ -261,6 +262,7 @@ begin wait until rising_edge(clk); wait until rising_edge(clk); reset <= '0'; + -- MEMORY STATE -/0,17,34 Log("Current Time: 0 s", INFO); wait until rising_edge(clk); @@ -275,10 +277,12 @@ begin wait_on_meta_sent; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 17, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 0(P0E0)/17,34 Log("Insert Endpoint 1 Participant 1", INFO); endpoint := e1; @@ -290,10 +294,12 @@ begin wait_on_meta_sent; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 34, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 17(P1E1),0(P0E0)/34 Log("Insert Endpoint 2 Participant 2", INFO); endpoint := e2; @@ -305,10 +311,12 @@ begin wait_on_meta_sent; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 50, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),17(P1E1),0(P0E0)/- wait_on_idle; Log("Current Time: 1 s", INFO); @@ -334,6 +342,7 @@ begin stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),17(P1E1),0(P0E0)/- wait_on_idle; Log("Current Time: 2 s", INFO); @@ -347,6 +356,7 @@ begin stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),17(P1E1),0(P0E0)/- wait_on_idle; Log("Current Time: 3 s", INFO); @@ -368,6 +378,7 @@ begin stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),17(P1E1),0(P0E0)/- wait_on_idle; Log("Current Time: 5 s", INFO); @@ -382,7 +393,6 @@ begin endpoint := e1; endpoint.nr := 1; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e2; endpoint.nr := 2; endpoint.match := MATCH; @@ -391,10 +401,12 @@ begin wait_on_out_check; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 17, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2),0(P0E0)/17 wait_on_idle; Log("Current Time: 6 s", INFO); @@ -405,11 +417,9 @@ begin endpoint := e0; endpoint.nr := 0; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e1; endpoint.nr := 1; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e2; endpoint.nr := 2; endpoint.match := MATCH; @@ -418,10 +428,12 @@ begin wait_on_out_check; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 0, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE 34(P2E2)/0,17 wait_on_idle; Log("Current Time: 8 s", INFO); @@ -432,23 +444,22 @@ begin endpoint := e0; endpoint.nr := 0; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e1; endpoint.nr := 1; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); endpoint := e2; endpoint.nr := 2; endpoint.match := UNMATCH; - SB_mem.Push(gen_writer_endpoint_mem_frame_a(endpoint)); SB_out.Push("0" & std_logic_vector(to_unsigned(2, WORD_WIDTH))); wait_on_out_check; mem_check <= '1'; wait_on_mem_check; + AlertIf(empty_head /= 34, "Memory Empty List Head incorrect", FAILURE); mem_check <= '0'; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; reference := EMPTY_TEST_PACKET; + -- MEMORY STATE -/34,0,17 stim_done <= '1'; wait_on_completion; diff --git a/src/rtps_reader.vhd b/src/rtps_reader.vhd index c95bf18..cba5a35 100644 --- a/src/rtps_reader.vhd +++ b/src/rtps_reader.vhd @@ -69,9 +69,9 @@ architecture arch of rtps_reader is variable ret : natural := 0; begin if (qos = RELIABLE_RELIABILITY_QOS) then - ret := 14; + ret := 17; else - ret := 10; + ret := 13; end if; return ret; end function; @@ -89,7 +89,7 @@ architecture arch of rtps_reader is -- *ENDPOINT MEMORY FRAME FIELD FLAGS* -- Flags mapping to the respective Endpoint Memory Frame Fields - constant EMF_FLAG_WIDTH : natural := 8; + constant EMF_FLAG_WIDTH : natural := 9; constant EMF_ENTITYID_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (0 => '1', others => '0'); constant EMF_GUIDPREFIX_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (1 => '1', others => '0'); constant EMF_IPV4_ADDR_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (2 => '1', others => '0'); @@ -98,6 +98,7 @@ architecture arch of rtps_reader is constant EMF_LEASE_DEADLINE_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (5 => '1', others => '0'); constant EMF_LIFESPAN_DURATION_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (6 => '1', others => '0'); constant EMF_RES_TIME_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (7 => '1', others => '0'); + constant EMF_WRITER_ID_FLAG : std_logic_vector(0 to EMF_FLAG_WIDTH-1) := (8 => '1', others => '0'); -- *ENDPOINT MEMORY FRAME FIELD OFFSETS* -- 4-Byte Word Offsets to Beginning of Respective Fields in the Endpoint Memory Frame @@ -119,6 +120,19 @@ architecture arch of rtps_reader is constant EMF_LEASE_DEADLINE_OFFSET : natural := EMF_NEXT_SEQ_NR_OFFSET + 2; constant EMF_LIFESPAN_DURATION_OFFSET : natural := EMF_LEASE_DEADLINE_OFFSET + 2; constant EMF_RES_TIME_OFFSET : natural := EMF_LIFESPAN_DURATION_OFFSET + 2; + function gen_emf_writer_id_offset(qos : std_logic_vector(CDR_ENUMERATION_WIDTH-1 downto 0)) return natural is + variable ret : natural := 0; + begin + if (qos = RELIABLE_RELIABILITY_QOS) then + ret := EMF_RES_TIME_OFFSET + 2; + else + ret := EMF_RES_TIME_OFFSET; + end if; + return ret; + end function; + constant EMF_WRITER_ID_OFFSET : natural := gen_emf_writer_id_offset(RELIABILITY_QOS); + constant EMF_NEXT_ADDR_OFFSET : natural := EMF_WRITER_ID_OFFSET + 1; + constant EMF_PREV_ADDR_OFFSET : natural := EMF_NEXT_ADDR_OFFSET + 1; --*****TYPE DECLARATION***** @@ -128,24 +142,21 @@ architecture arch of rtps_reader is LATCH_KEY_HASH, LATCH_STATUS_INFO, INITIATE_ADD_CACHE_CHANGE_REQUEST, ADD_CACHE_CHANGE, PUSH_PAYLOAD, FINALIZE_ADD_CACHE_CHANGE_REQUEST, ENDPOINT_STALE_CHECK, SEND_HEADER, SEND_ACKNACK, SKIP_PARAMETER, SKIP_PACKET, SKIP_META_OPERATION); -- Memory FSM states. Explained below in detail - type MEM_STAGE_TYPE is (IDLE, SEARCH_ENDPOINT, GET_ENDPOINT_DATA, INSERT_ENDPOINT, UPDATE_ENDPOINT, REMOVE_ENDPOINT, FIND_EMPTY_SLOT, - RESET_MAX_POINTER, GET_NEXT_ENDPOINT, RESET_MEMORY); + type MEM_STAGE_TYPE is (IDLE, SEARCH_ENDPOINT, GET_ENDPOINT_DATA, INSERT_ENDPOINT, UPDATE_ENDPOINT, REMOVE_ENDPOINT, GET_NEXT_ENDPOINT, RESET_MEMORY); -- *Memory FSM Opcodes* -- OPCODE DESCRIPTION -- SEARCH_ENDPOINT Search memory for Endpoint with GUID equal to "guid" signal. -- Set "mem_addr_base" to base Address of found Endpoint, or ENDPOINT_MEMORY_MAX_ADDRESS if nothing found. -- "mem_endpoint_data" contains Endpoint Data according to "mem_field_flags". - -- INSERT_ENDPOINT Insert Endpoint to first available empty slot in memory - -- UPDATE_ENDPOINT Update Endpoint pointed by "mem_addr_base" according to "mem_field_flags". - -- REMOVE_ENDPOINT Remove Endpoint pointed by "mem_addr_base" - -- GET_FIRST_ENDPOINT Get Endpoint Data of first Endpoint stored in Memory according to "mem_field_flags". - -- Set "mem_addr_base" to Address of Endpoint, or ENDPOINT_MEMORY_MAX_ADDRESS if no Endpoint in Memory. - -- GET_NEXT_ENDPOINT Get Endpoint Data of next Endpoint (from the Endpoint pointed by "mem_addr_base") according to "mem_field_flags". + -- INSERT_ENDPOINT Insert Endpoint in memory + -- UPDATE_ENDPOINT Update Endpoint pointed by "mem_addr_update" according to "mem_field_flags". + -- REMOVE_ENDPOINT Remove Endpoint pointed by "mem_addr_update". + -- "mem_addr_base" is set to the next Endpoint (or ENDPOINT_MEMORY_MAX_ADDRESS if no next Endpoint exists) + -- GET_NEXT_ENDPOINT Get Endpoint Data of next Endpoint (from the Endpoint pointed by "mem_addr_update") according to "mem_field_flags". -- Set "mem_addr_base" to Address of Endpoint, or ENDPOINT_MEMORY_MAX_ADDRESS if no other Endpoint in Memory. -- GET_ENDPOINT Get Endpoint Data from Endpoint pointed by "mem_addr_update" according to "mem_field_flags". -- Already fetched data of the same Endpoint is not modified. - type MEM_OPCODE_TYPE is (NOP, SEARCH_ENDPOINT, INSERT_ENDPOINT, UPDATE_ENDPOINT, REMOVE_ENDPOINT, GET_FIRST_ENDPOINT, GET_NEXT_ENDPOINT, - GET_ENDPOINT); + type MEM_OPCODE_TYPE is (NOP, SEARCH_ENDPOINT, INSERT_ENDPOINT, UPDATE_ENDPOINT, REMOVE_ENDPOINT, GET_NEXT_ENDPOINT, GET_ENDPOINT); -- Record of Endpoint Data type ENDPOINT_DATA_TYPE is record guid : GUID_TYPE; @@ -155,6 +166,7 @@ architecture arch of rtps_reader is lease_deadline : TIME_TYPE; lifespan : DURATION_TYPE; res_time : TIME_TYPE; + writer_id : natural; end record; -- Zero initialized Endpoint Data constant ZERO_ENDPOINT_DATA : ENDPOINT_DATA_TYPE := ( @@ -163,8 +175,9 @@ architecture arch of rtps_reader is portn => UDP_PORT_INVALID, next_seq_nr => SEQUENCENUMBER_UNKNOWN, lease_deadline => TIME_INVALID, - lifespan => DURATION_INFINITE, - res_time => TIME_INVALID + lifespan => DURATION_INFINITE, + res_time => TIME_INVALID, + writer_id => 0 ); -- Endpoint Data Latch used as temporal cache by Memory Process type ENDPOINT_LATCH_DATA_TYPE is record @@ -274,26 +287,26 @@ architecture arch of rtps_reader is signal idle_sig : std_logic; -- Signal used to pass Endpoint Pointers to the Endpoint Memory Process signal mem_addr_update : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0); + -- Test signal used in testbenches for removal check + signal empty_head_sig : natural; -- *MEMORY PROCESS* -- Memory FSM state signal mem_stage, mem_stage_next : MEM_STAGE_TYPE; + -- Head of Occupied Memory Endpoint List + signal mem_occupied_head, mem_occupied_head_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0); + -- Head of Empty Memory Endpoint List + signal mem_empty_head, mem_empty_head_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0); -- Pointer to current relevant Endpoint Address signal mem_addr_base, mem_addr_base_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0); - -- Help signal used to reset the MAX Endpoint Memory Pointer - signal last_addr, last_addr_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0); -- General Memory Address Latch signal mem_addr_latch, mem_addr_latch_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0); - -- Highest Endpoint Memory Address (Points to first Address of last occupied Endpoint Frame) - signal max_endpoint_addr, max_endpoint_addr_next : unsigned(ENDPOINT_MEMORY_ADDR_WIDTH-1 downto 0); -- General Purpose Couter - signal mem_cnt, mem_cnt_next : natural range 0 to 27; + signal mem_cnt, mem_cnt_next : natural range 0 to 29; -- Latch for Endpoint Data from Memory signal mem_endpoint_data, mem_endpoint_data_next : ENDPOINT_DATA_TYPE; -- Latch for Endpoint Data from main process signal mem_endpoint_latch_data, mem_endpoint_latch_data_next : ENDPOINT_LATCH_DATA_TYPE; - -- Position (In Endpoint Memory Frame Granularity) of current relevant Endpoint - signal mem_pos, mem_pos_next : natural range 0 to MAX_REMOTE_ENDPOINTS-1; -- Endpoint Memory Flag Array denoting which mem_endpoint_data Fields are up-to-date with the respective fields of the Endpoint (Pointed by mem_addr_base) signal current_emf, current_emf_next : std_logic_vector(0 to EMF_FLAG_WIDTH-1); @@ -348,6 +361,17 @@ architecture arch of rtps_reader 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; + begin --*****COMPONENT INSTANTIATION***** @@ -484,10 +508,11 @@ begin if (mem_op_done = '1') then stale_check_next <= '1'; stage_next <= ENDPOINT_STALE_CHECK; - cnt_next <= 1; + cnt_next <= 2; -- CHECK Endpoint mem_op_start <= '1'; - mem_opcode <= GET_FIRST_ENDPOINT; - mem_field_flags <= EMF_LEASE_DEADLINE_FLAG or EMF_RES_TIME_FLAG; + mem_opcode <= GET_ENDPOINT; + mem_addr_update <= mem_occupied_head; + mem_field_flags <= EMF_LEASE_DEADLINE_FLAG or EMF_RES_TIME_FLAG or EMF_WRITER_ID_FLAG; -- Reset Timeout check_time_next <= TIME_INFINITE; end if; @@ -614,19 +639,21 @@ begin when EMO_ENDPOINT_UNMATCH => mem_op_start <= '1'; mem_opcode <= SEARCH_ENDPOINT; - mem_field_flags <= (others => '0'); + mem_field_flags <= EMF_WRITER_ID_FLAG; stage_next <= METATRAFFIC_OPERATION; when EMO_PARTICIPANT_UNMATCH => mem_op_start <= '1'; - mem_opcode <= GET_FIRST_ENDPOINT; - mem_field_flags <= EMF_GUIDPREFIX_FLAG; + mem_opcode <= GET_ENDPOINT; + mem_addr_update <= mem_occupied_head; + mem_field_flags <= EMF_GUIDPREFIX_FLAG or EMF_WRITER_ID_FLAG; stage_next <= METATRAFFIC_OPERATION; cnt_next <= 0; when EMO_LIVELINESS_UPDATE => -- Synthesis Guard if (LIVELINESS_QOS /= MANUAL_BY_TOPIC_LIVELINESS_QOS) then mem_op_start <= '1'; - mem_opcode <= GET_FIRST_ENDPOINT; + mem_opcode <= GET_ENDPOINT; + mem_addr_update <= mem_occupied_head; mem_field_flags <= EMF_GUIDPREFIX_FLAG; stage_next <= METATRAFFIC_OPERATION; cnt_next <= 0; @@ -641,7 +668,7 @@ begin case (opcode) is when SID_DATA => stage_next <= LATCH_EXTRA_DATA; - mem_field_flags <= EMF_NEXT_SEQ_NR_FLAG or EMF_LIFESPAN_DURATION_FLAG; + mem_field_flags <= EMF_NEXT_SEQ_NR_FLAG or EMF_LIFESPAN_DURATION_FLAG or EMF_WRITER_ID_FLAG; cnt_next <= 0; when SID_HEARTBEAT => stage_next <= LATCH_HEARTBEAT; @@ -698,6 +725,7 @@ begin -- NOTE: The Lease Duration is NOT updated in case of an update. That is the responsibility of the Liveliness Update mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_field_flags <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG or EMF_LIFESPAN_DURATION_FLAG; @@ -706,7 +734,13 @@ begin end if; -- DONE stage_next <= IDLE; + -- Endpoint Memory Full + elsif (mem_empty_head = ENDPOINT_MEMORY_MAX_ADDRESS) then + -- Ignore + stage_next <= IDLE; else + assert (mem_empty_head /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; + -- Insert Matched Remote Endpoint mem_op_start <= '1'; mem_opcode <= INSERT_ENDPOINT; @@ -730,53 +764,68 @@ begin -- Ignore stage_next <= IDLE; else + assert stable(clk, check_mask(current_emf, EMF_WRITER_ID_FLAG)) severity FAILURE; + -- Propagate Removal (Sent Memory Position as ID) start_hc <= '1'; opcode_hc <= REMOVE_WRITER; - data_out_hc <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH)); + data_out_hc <= std_logic_vector(to_unsigned(mem_endpoint_data.writer_id, WORD_WIDTH)); -- Wait for Operation Acknowledgement if (ack_hc = '1') then -- Remove Unmatched Remote Endpoint mem_op_start <= '1'; mem_opcode <= REMOVE_ENDPOINT; + mem_addr_update <= mem_addr_base; -- DONE stage_next <= IDLE; end if; end if; when EMO_PARTICIPANT_UNMATCH => - -- Precondition: mem_endpoint_data set (EMF_GUIDPREFIX_FLAG) + -- Precondition: mem_endpoint_data set (EMF_GUIDPREFIX_FLAG, EMF_WRITER_ID_FLAG) case (cnt) is when 0 => - assert check_mask(current_emf, EMF_GUIDPREFIX_FLAG) severity FAILURE; - -- Reached End of Endpoints if (mem_addr_base = ENDPOINT_MEMORY_MAX_ADDRESS) then -- DONE stage_next <= IDLE; else + assert stable(clk, check_mask(current_emf, EMF_GUIDPREFIX_FLAG or EMF_WRITER_ID_FLAG)) severity FAILURE; + -- Participant Match if (guid(0) = mem_endpoint_data.guid(0) and guid(1) = mem_endpoint_data.guid(1) and guid(2) = mem_endpoint_data.guid(2)) then -- Propagate Removal (Sent Memory Position as ID) start_hc <= '1'; opcode_hc <= REMOVE_WRITER; - data_out_hc <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH)); + data_out_hc <= std_logic_vector(to_unsigned(mem_endpoint_data.writer_id, WORD_WIDTH)); -- Wait for Operation Acknowledgement if (ack_hc = '1') then -- Remove Unmatched Remote Endpoint mem_op_start <= '1'; mem_opcode <= REMOVE_ENDPOINT; - cnt_next <= cnt + 1; + mem_addr_update <= mem_addr_base; + -- NOTE: After removal, mem_addr_base is pointing to the next slot (or ENDPOINT_MEMORY_MAX_ADDRESS) + cnt_next <= 2; -- GET end if; else - cnt_next <= cnt + 1; + cnt_next <= 1; -- GET NEXT end if; end if; + -- GET NEXT ENDPOINT when 1 => -- Continue Search mem_op_start <= '1'; mem_opcode <= GET_NEXT_ENDPOINT; - mem_field_flags <= EMF_GUIDPREFIX_FLAG; + mem_addr_update <= mem_addr_base; + mem_field_flags <= EMF_GUIDPREFIX_FLAG or EMF_WRITER_ID_FLAG; + cnt_next <= 0; + -- GET ENDPOINT + when 2 => + -- Continue Search + mem_op_start <= '1'; + mem_opcode <= GET_ENDPOINT; + mem_addr_update <= mem_addr_base; + mem_field_flags <= EMF_GUIDPREFIX_FLAG or EMF_WRITER_ID_FLAG; cnt_next <= 0; when others => null; @@ -788,18 +837,19 @@ begin if (LIVELINESS_QOS /= MANUAL_BY_TOPIC_LIVELINESS_QOS) then case (cnt) is when 0 => - assert check_mask(current_emf, EMF_GUIDPREFIX_FLAG) severity FAILURE; - -- No matches in memory if (mem_addr_base = ENDPOINT_MEMORY_MAX_ADDRESS) then -- DONE stage_next <= IDLE; else + assert stable(clk, check_mask(current_emf, EMF_GUIDPREFIX_FLAG)) severity FAILURE; + -- Participant Match if (guid(0) = mem_endpoint_data.guid(0) and guid(1) = mem_endpoint_data.guid(1) and guid(2) = mem_endpoint_data.guid(2)) then -- Renew Lease of Remote Endpoint mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; mem_field_flags <= EMF_LEASE_DEADLINE_FLAG; if (LEASE_DURATION /= DURATION_INFINITE) then lease_deadline <= time + LEASE_DURATION; @@ -819,6 +869,7 @@ begin -- Continue Search mem_op_start <= '1'; mem_opcode <= GET_NEXT_ENDPOINT; + mem_addr_update <= mem_addr_base; mem_field_flags <= EMF_GUIDPREFIX_FLAG; cnt_next <= 0; when others => @@ -906,13 +957,12 @@ begin -- Wait for Endpoint Search to finish if (mem_op_done = '1') then - assert check_mask(current_emf, EMF_RES_TIME_FLAG or EMF_NEXT_SEQ_NR_FLAG) severity FAILURE; - -- DEFAULT stage_next <= SKIP_PACKET; -- Endpoint in Buffer if (mem_addr_base /= ENDPOINT_MEMORY_MAX_ADDRESS) then + assert stable(clk, check_mask(current_emf, EMF_RES_TIME_FLAG or EMF_NEXT_SEQ_NR_FLAG)) severity FAILURE; -- Default tmp_flags := (others => '0'); @@ -922,6 +972,7 @@ begin if (liveliness_flag = '1') then mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; tmp_flags := tmp_flags or EMF_LEASE_DEADLINE_FLAG; if (LEASE_DURATION /= DURATION_INFINITE) then lease_deadline <= time + LEASE_DURATION; @@ -941,9 +992,10 @@ begin else next_seq_nr_next <= first_seq_nr; end if; - mem_op_start <= '1'; - mem_opcode <= UPDATE_ENDPOINT; - tmp_flags := tmp_flags or EMF_NEXT_SEQ_NR_FLAG or EMF_RES_TIME_FLAG; + mem_op_start <= '1'; + mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; + tmp_flags := tmp_flags or EMF_NEXT_SEQ_NR_FLAG or EMF_RES_TIME_FLAG; -- NOTE: Only response with ACKNACK if SN is available (Or no Final Flag) if (HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE and (first_seq_nr <= last_seq_nr or final_flag = '0')) then res_time <= time + HEARTBEAT_RESPONSE_DELAY; @@ -961,6 +1013,7 @@ begin next_seq_nr_next <= first_seq_nr; mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; tmp_flags := tmp_flags or EMF_NEXT_SEQ_NR_FLAG or EMF_RES_TIME_FLAG; -- NOTE: Only response with ACKNACK if SN is available (Or no Final Flag) if (HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE and (first_seq_nr <= last_seq_nr or final_flag = '0')) then @@ -978,6 +1031,7 @@ begin -- Set Response Delay mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; tmp_flags := tmp_flags or EMF_RES_TIME_FLAG; if (HEARTBEAT_RESPONSE_DELAY /= DURATION_INFINITE) then res_time <= time + HEARTBEAT_RESPONSE_DELAY; @@ -1001,6 +1055,7 @@ begin next_seq_nr_next <= first_seq_nr; mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; tmp_flags := tmp_flags or EMF_NEXT_SEQ_NR_FLAG; end if; end if; @@ -1062,13 +1117,13 @@ begin -- Wait for Endpoint Search if (mem_op_done = '1') then - assert check_mask(current_emf, EMF_NEXT_SEQ_NR_FLAG) severity FAILURE; - -- DEFAULT stage_next <= SKIP_PACKET; -- Known Remote Endpoint if (mem_addr_base /= ENDPOINT_MEMORY_MAX_ADDRESS) then + assert stable(clk, check_mask(current_emf, EMF_NEXT_SEQ_NR_FLAG)) severity FAILURE; + -- GAP is relevant if (gap_start <= mem_endpoint_data.next_seq_nr and mem_endpoint_data.next_seq_nr <= gap_list_end) then -- Next Expected is in GAP List @@ -1094,6 +1149,7 @@ begin -- Update next sequence number mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; mem_field_flags <= EMF_NEXT_SEQ_NR_FLAG; -- DONE stage_next <= SKIP_PACKET; @@ -1245,13 +1301,13 @@ begin -- Wait for Endpoint Data if (mem_op_done = '1') then - assert check_mask(current_emf, EMF_NEXT_SEQ_NR_FLAG or EMF_LIFESPAN_DURATION_FLAG) severity FAILURE; - -- Unknown Endpoint if (mem_addr_base = ENDPOINT_MEMORY_MAX_ADDRESS) then -- Ignore stage_next <= SKIP_PACKET; else + assert stable(clk, check_mask(current_emf, EMF_NEXT_SEQ_NR_FLAG or EMF_LIFESPAN_DURATION_FLAG)) severity FAILURE; + -- Data is Next expected Sequence Number if ((RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and seq_nr = mem_endpoint_data.next_seq_nr) or (RELIABILITY_QOS = BEST_EFFORT_RELIABILITY_QOS and seq_nr >= mem_endpoint_data.next_seq_nr) or (DURABILITY_QOS = VOLATILE_DURABILITY_QOS and mem_endpoint_data.next_seq_nr = SEQUENCENUMBER_UNKNOWN)) then -- SANITY CHECK: Skip if no Hash Key and no Payload @@ -1284,7 +1340,7 @@ begin -- Status Info when 0 => valid_out_hc <= '1'; - data_out_hc <= status_info; + data_out_hc <= status_info; if (WITH_KEY) then data_out_hc(SSI_KEY_HASH_FLAG) <= key_hash_rcvd; end if; @@ -1367,9 +1423,11 @@ begin when 9 => -- Wait for Endpoint Search if (mem_op_done = '1') then + assert stable(clk, mem_addr_base /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_emf, EMF_WRITER_ID_FLAG)) severity FAILURE; + valid_out_hc <= '1'; - -- TODO: Assert mem_pos range fits in CDR_LONG - data_out_hc <= std_logic_vector(to_unsigned(mem_pos, CDR_LONG_WIDTH)); + data_out_hc <= std_logic_vector(to_unsigned(mem_endpoint_data.writer_id, WORD_WIDTH)); -- Output Guard if (ready_out_hc = '1') then @@ -1418,6 +1476,7 @@ begin -- Update Endpoint mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; mem_field_flags <= EMF_LEASE_DEADLINE_FLAG; if (LEASE_DURATION /= DURATION_INFINITE) then lease_deadline <= time + LEASE_DURATION; @@ -1448,16 +1507,23 @@ begin -- Memory Operation Guard if (mem_op_done = '1') then case (cnt) is - -- Get Next Endpoint + -- GET Endpoint when 0 => mem_op_start <= '1'; - mem_opcode <= GET_NEXT_ENDPOINT; - mem_field_flags <= EMF_LEASE_DEADLINE_FLAG or EMF_RES_TIME_FLAG; - cnt_next <= cnt + 1; - -- Check Endpoint + mem_opcode <= GET_ENDPOINT; + mem_addr_update <= mem_addr_base; + mem_field_flags <= EMF_LEASE_DEADLINE_FLAG or EMF_RES_TIME_FLAG or EMF_WRITER_ID_FLAG; + cnt_next <= 2; -- CHECK Endpoint + -- GET NEXT Endpoint when 1 => - assert check_mask(current_emf, EMF_LEASE_DEADLINE_FLAG or EMF_RES_TIME_FLAG) severity FAILURE; - + mem_op_start <= '1'; + mem_opcode <= GET_NEXT_ENDPOINT; + mem_addr_update <= mem_addr_base; + mem_field_flags <= EMF_LEASE_DEADLINE_FLAG or EMF_RES_TIME_FLAG or EMF_WRITER_ID_FLAG; + cnt_next <= 2; -- CHECK Endpoint + -- CHECK Endpoint + when 2 => + -- End of Endpoints if (mem_addr_base = ENDPOINT_MEMORY_MAX_ADDRESS) then -- Reset @@ -1465,19 +1531,22 @@ begin -- DONE stage_next <= IDLE; else + assert stable(clk, check_mask(current_emf, EMF_LEASE_DEADLINE_FLAG or EMF_RES_TIME_FLAG or EMF_WRITER_ID_FLAG)) severity FAILURE; + -- Endpoint Lease Expired if (mem_endpoint_data.lease_deadline /= TIME_INVALID and mem_endpoint_data.lease_deadline <= time) then -- Propagate Removal (Sent Memory Position as ID) start_hc <= '1'; opcode_hc <= REMOVE_WRITER; - data_out_hc <= std_logic_vector(to_unsigned(mem_pos, WORD_WIDTH)); + data_out_hc <= std_logic_vector(to_unsigned(mem_endpoint_data.writer_id, WORD_WIDTH)); -- Wait for Operation Acknowledgement if (ack_hc = '1') then -- Remove Endpoint mem_op_start <= '1'; mem_opcode <= REMOVE_ENDPOINT; + mem_addr_update <= mem_addr_base; -- Continue Search - cnt_next <= 0; + cnt_next <= 0; -- GET Endpoint end if; -- Synthesis Guard/Response Time Reached elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and mem_endpoint_data.res_time /= TIME_INVALID and mem_endpoint_data.res_time <= time) then @@ -1486,18 +1555,20 @@ begin -- Disable Suppression mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; res_time <= TIME_INVALID; mem_field_flags <= EMF_RES_TIME_FLAG; -- Continue Search - cnt_next <= 0; + cnt_next <= 1; -- GET NEXT Endpoint -- If Response Delay Passed else -- Get Additional Data mem_op_start <= '1'; mem_opcode <= GET_ENDPOINT; + mem_addr_update <= mem_addr_base; mem_field_flags <= EMF_ENTITYID_FLAG or EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG or EMF_NEXT_SEQ_NR_FLAG; mem_addr_update <= mem_addr_base; - cnt_next <= 2; + cnt_next <= 3; -- UPDATE Endpoint end if; -- Update Check Time @@ -1521,12 +1592,16 @@ begin end if; -- Continue Search - cnt_next <= 0; + cnt_next <= 1; -- GET Endpoint end if; end if; - when 2 => + -- UPDATE Endpoint + when 3 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then + assert (mem_op_done = '1') severity FAILURE; + assert (mem_addr_base /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; + -- Set Heartbeat Suppression Time if (HEARTBEAT_SUPPRESSION_DELAY /= DURATION_INFINITE and HEARTBEAT_SUPPRESSION_DELAY /= DURATION_ZERO) then -- Set Heartbeat Suppression Time @@ -1549,6 +1624,7 @@ begin end if; mem_op_start <= '1'; mem_opcode <= UPDATE_ENDPOINT; + mem_addr_update <= mem_addr_base; mem_field_flags <= EMF_RES_TIME_FLAG; -- Send ACKNACK @@ -1567,7 +1643,8 @@ begin -- Synthesis Guard / Wait for Endpoint Data if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and mem_op_done = '1') then - assert check_mask(current_emf, EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG) severity FAILURE; + assert stable(clk, mem_addr_base /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_emf, EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG)) severity FAILURE; -- Output FIFO Guard if (full_ro = '0') then @@ -1616,7 +1693,8 @@ begin -- Synthesis Guard / Wait for Endpoint Data if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and mem_op_done = '1') then - assert check_mask(current_emf, EMF_ENTITYID_FLAG or EMF_NEXT_SEQ_NR_FLAG) severity FAILURE; + assert stable(clk, mem_addr_base /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; + assert stable(clk, check_mask(current_emf, EMF_ENTITYID_FLAG or EMF_NEXT_SEQ_NR_FLAG)) severity FAILURE; -- Output FIFO Guard if (full_ro = '0') then @@ -1663,7 +1741,7 @@ begin if (stale_check = '1') then -- Continue Search stage_next <= ENDPOINT_STALE_CHECK; - cnt_next <= 0; + cnt_next <= 1; -- GET NEXT Endpoint else -- DONE stage_next <= IDLE; @@ -1756,6 +1834,8 @@ begin end if; end process; + empty_head_sig <= to_integer(mem_empty_head); + -- *Memory State Machine* -- STATE DESCRIPTION -- IDLE Idle State. Done Signal is pulled high and Memory FSM accepts new memory operations @@ -1764,8 +1844,6 @@ begin -- INSERT_ENDPOINT See Memory OPCODE Description -- UPDATE_ENDPOINT See Memory OPCODE Description -- REMOVE_ENDPOINT See Memory OPCODE Description - -- FIND_EMPTY_SLOT Find first empty_user slot in memory. - -- RESET_MAX_POINTER Reset the max_endpoint_addr pointer to last occupied slot in memory. -- GET_NEXT_ENDPOINT See Memory OPCODE Description -- RESET_MEMORY Reset Endpoint Memory to Empty State mem_ctrl_prc : process(all) @@ -1773,13 +1851,12 @@ begin -- DEFAULT Registered mem_stage_next <= mem_stage; mem_addr_base_next <= mem_addr_base; + mem_empty_head_next <= mem_empty_head; + mem_occupied_head_next <= mem_occupied_head; mem_cnt_next <= mem_cnt; - last_addr_next <= last_addr; mem_addr_latch_next <= mem_addr_latch; mem_endpoint_data_next <= mem_endpoint_data; - max_endpoint_addr_next <= max_endpoint_addr; mem_endpoint_latch_data_next <= mem_endpoint_latch_data; - mem_pos_next <= mem_pos; current_emf_next <= current_emf; -- DEFAULT Unregistered mem_addr <= (others => '0'); @@ -1810,109 +1887,128 @@ begin case(mem_opcode) is when SEARCH_ENDPOINT => - current_emf_next <= mem_field_flags; mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; - - mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS; - mem_pos_next <= 0; - mem_stage_next <= SEARCH_ENDPOINT; - mem_cnt_next <= 0; - when INSERT_ENDPOINT => - current_emf_next <= (others => '1'); - -- Set Endpoint Data - mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; - mem_endpoint_data_next.guid <= guid_next; - mem_endpoint_data_next.addr <= addr_next; - mem_endpoint_data_next.portn <= portn_next; - if (DURABILITY_QOS = VOLATILE_DURABILITY_QOS) then - mem_endpoint_data_next.next_seq_nr <= SEQUENCENUMBER_UNKNOWN; + if (RELIABILITY_QOS /= RELIABLE_RELIABILITY_QOS) then + current_emf_next <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG or EMF_RES_TIME_FLAG; else - mem_endpoint_data_next.next_seq_nr <= FIRST_SEQUENCENUMBER; + current_emf_next <= (others => '0'); end if; - mem_endpoint_data_next.lease_deadline <= lease_deadline; - mem_endpoint_data_next.lifespan <= lifespan_next; - mem_endpoint_data_next.res_time <= TIME_INVALID; - mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS; - mem_pos_next <= 0; - mem_stage_next <= FIND_EMPTY_SLOT; + if (mem_occupied_head = ENDPOINT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; + else + mem_addr_base_next <= mem_occupied_head; + mem_stage_next <= SEARCH_ENDPOINT; + mem_cnt_next <= 0; + end if; + when INSERT_ENDPOINT => + assert (mem_empty_head /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; + + mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; + if (RELIABILITY_QOS /= RELIABLE_RELIABILITY_QOS) then + current_emf_next <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG or EMF_RES_TIME_FLAG; + else + current_emf_next <= (others => '0'); + end if; + + mem_addr_base_next <= mem_empty_head; + mem_stage_next <= INSERT_ENDPOINT; mem_cnt_next <= 0; when UPDATE_ENDPOINT => - current_emf_next <= current_emf or mem_field_flags; - mem_stage_next <= UPDATE_ENDPOINT; - - if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 0; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_UDP_PORT_FLAG)) then - mem_cnt_next <= 1; - elsif check_mask(mem_field_flags,EMF_NEXT_SEQ_NR_FLAG) then - mem_cnt_next <= 2; - elsif check_mask(mem_field_flags,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 4; - elsif check_mask(mem_field_flags,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 6; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 8; + if (mem_addr_update = ENDPOINT_MEMORY_MAX_ADDRESS) then + mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; + current_emf_next <= (others => '0'); + mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; else - -- DONE - mem_stage_next <= IDLE; + current_emf_next <= current_emf or mem_field_flags; + + mem_addr_base_next <= mem_addr_update; + mem_stage_next <= UPDATE_ENDPOINT; + if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_IPV4_ADDR_FLAG)) then + mem_cnt_next <= 0; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_UDP_PORT_FLAG)) then + mem_cnt_next <= 1; + elsif check_mask(mem_field_flags,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 2; + elsif check_mask(mem_field_flags,EMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 4; + elsif check_mask(mem_field_flags,EMF_LIFESPAN_DURATION_FLAG) then + mem_cnt_next <= 6; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_RES_TIME_FLAG)) then + mem_cnt_next <= 8; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; when REMOVE_ENDPOINT => mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; current_emf_next <= (others => '0'); - mem_stage_next <= REMOVE_ENDPOINT; - mem_cnt_next <= 0; - when GET_FIRST_ENDPOINT => - mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; - current_emf_next <= mem_field_flags; - - mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS; - mem_pos_next <= 0; - mem_stage_next <= GET_NEXT_ENDPOINT; - mem_cnt_next <= 0; - when GET_NEXT_ENDPOINT => - mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; - current_emf_next <= mem_field_flags; - - -- Memory Bound Guard - if (mem_addr_base >= max_endpoint_addr) then + if (mem_addr_update = ENDPOINT_MEMORY_MAX_ADDRESS) then mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; else - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; + mem_addr_base_next <= mem_addr_update; + mem_stage_next <= REMOVE_ENDPOINT; + mem_cnt_next <= 0; + end if; + when GET_NEXT_ENDPOINT => + mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; + if (RELIABILITY_QOS /= RELIABLE_RELIABILITY_QOS) then + current_emf_next <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG or EMF_RES_TIME_FLAG; + else + current_emf_next <= (others => '0'); + end if; + + if (mem_addr_update = ENDPOINT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; + else + mem_addr_base_next <= mem_addr_update; mem_stage_next <= GET_NEXT_ENDPOINT; mem_cnt_next <= 0; end if; when GET_ENDPOINT => - if (mem_addr_base /= mem_addr_update) then + if (mem_addr_update = ENDPOINT_MEMORY_MAX_ADDRESS) then mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; - current_emf_next <= mem_field_flags; + current_emf_next <= (others => '0'); + mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; else - current_emf_next <= current_emf or mem_field_flags; - end if; - - -- Fetch Endpoint Data - mem_stage_next <= GET_ENDPOINT_DATA; - if check_mask(mem_field_flags,EMF_ENTITYID_FLAG) then - mem_cnt_next <= 0; - elsif check_mask(mem_field_flags,EMF_GUIDPREFIX_FLAG) then - mem_cnt_next <= 1; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 4; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_UDP_PORT_FLAG)) then - mem_cnt_next <= 5; - elsif check_mask(mem_field_flags,EMF_NEXT_SEQ_NR_FLAG) then - mem_cnt_next <= 6; - elsif check_mask(mem_field_flags,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 8; - elsif check_mask(mem_field_flags,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 10; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 12; - else - -- DONE - mem_stage_next <= IDLE; + if (mem_addr_base /= mem_addr_update) then + mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; + if (RELIABILITY_QOS /= RELIABLE_RELIABILITY_QOS) then + current_emf_next <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG or EMF_RES_TIME_FLAG; + else + current_emf_next <= (others => '0'); + end if; + else + current_emf_next <= current_emf or mem_field_flags; + end if; + + -- Fetch Endpoint Data + mem_addr_base_next <= mem_addr_update; + mem_stage_next <= GET_ENDPOINT_DATA; + if check_mask(mem_field_flags,EMF_ENTITYID_FLAG) then + mem_cnt_next <= 0; + elsif check_mask(mem_field_flags,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 1; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_IPV4_ADDR_FLAG)) then + mem_cnt_next <= 4; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_UDP_PORT_FLAG)) then + mem_cnt_next <= 5; + elsif check_mask(mem_field_flags,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 6; + elsif check_mask(mem_field_flags,EMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 8; + elsif check_mask(mem_field_flags,EMF_LIFESPAN_DURATION_FLAG) then + mem_cnt_next <= 10; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_field_flags,EMF_RES_TIME_FLAG)) then + mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; when others => null; @@ -1964,17 +2060,7 @@ begin -- No Match if (mem_read_data /= mem_endpoint_latch_data.guid(3)) then abort_read <= '1'; - -- Reached End of Memory, No Match - if (mem_addr_base = max_endpoint_addr) then - mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; - mem_cnt_next <= 0; - end if; + mem_cnt_next <= 8; -- GET Next Addr else mem_cnt_next <= mem_cnt + 1; end if; @@ -1987,17 +2073,7 @@ begin -- No Match if (mem_read_data /= mem_endpoint_latch_data.guid(0)) then abort_read <= '1'; - -- Reached End of Memory, No Match - if (mem_addr_base = max_endpoint_addr) then - mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; - mem_cnt_next <= 0; - end if; + mem_cnt_next <= 8; -- GET Next Addr else mem_cnt_next <= mem_cnt + 1; end if; @@ -2010,17 +2086,7 @@ begin -- No Match if (mem_read_data /= mem_endpoint_latch_data.guid(1)) then abort_read <= '1'; - -- Reached End of Memory, No Match - if (mem_addr_base = max_endpoint_addr) then - mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; - mem_cnt_next <= 0; - end if; + mem_cnt_next <= 8; -- GET Next Addr else mem_cnt_next <= mem_cnt + 1; end if; @@ -2033,22 +2099,11 @@ begin -- No Match if (mem_read_data /= mem_endpoint_latch_data.guid(2)) then abort_read <= '1'; - -- Reached End of Memory, No Match - if (mem_addr_base = max_endpoint_addr) then - mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; - mem_cnt_next <= 0; - end if; + mem_cnt_next <= 8; -- GET Next Addr -- Match else -- Fetch Endpoint Data - mem_stage_next <= GET_ENDPOINT_DATA; - mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; + mem_stage_next <= GET_ENDPOINT_DATA; if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then mem_cnt_next <= 0; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then @@ -2065,12 +2120,39 @@ begin mem_cnt_next <= 10; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else -- DONE mem_stage_next <= IDLE; end if; end if; end if; + -- GET Next Addr + when 8 => + mem_addr <= mem_addr_base + EMF_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 9 => + mem_ready_out <= '1'; + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + -- No more Endpoints + if (resize(unsigned(mem_read_data),ENDPOINT_MEMORY_ADDR_WIDTH) = ENDPOINT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; --No match + -- DONE + mem_stage_next <= IDLE; + else + -- Continue + mem_addr_base_next <= resize(unsigned(mem_read_data),ENDPOINT_MEMORY_ADDR_WIDTH); + mem_cnt_next <= 0; + end if; + end if; when others => null; end case; @@ -2098,8 +2180,10 @@ begin mem_cnt_next <= 10; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; - else + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then mem_cnt_next <= 14; + else + mem_cnt_next <= 15; end if; end if; -- GET GUID Prefix 1/3 @@ -2139,11 +2223,13 @@ begin mem_cnt_next <= 10; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then - mem_cnt_next <= 14; - else mem_cnt_next <= 15; + else + mem_cnt_next <= 16; end if; end if; end if; @@ -2166,13 +2252,15 @@ begin mem_cnt_next <= 10; elsif ((RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then - mem_cnt_next <= 14; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then mem_cnt_next <= 15; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 16; else - mem_cnt_next <= 18; + mem_cnt_next <= 19; end if; end if; end if; @@ -2194,15 +2282,17 @@ begin mem_cnt_next <= 10; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then - mem_cnt_next <= 14; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then mem_cnt_next <= 15; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 16; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 18; - else mem_cnt_next <= 19; + else + mem_cnt_next <= 20; end if; end if; end if; @@ -2229,17 +2319,19 @@ begin mem_cnt_next <= 10; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then - mem_cnt_next <= 14; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then mem_cnt_next <= 15; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 16; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 18; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 19; - else + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 20; + else + mem_cnt_next <= 21; end if; end if; end if; @@ -2263,19 +2355,21 @@ begin mem_cnt_next <= 10; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then - mem_cnt_next <= 14; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then mem_cnt_next <= 15; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 16; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 18; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 19; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 20; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 21; else - mem_cnt_next <= 22; + mem_cnt_next <= 23; end if; end if; end if; @@ -2297,21 +2391,23 @@ begin if (mem_ready_in = '1') then if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then - mem_cnt_next <= 14; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then mem_cnt_next <= 15; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 16; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 18; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 19; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 20; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 21; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 22; + mem_cnt_next <= 23; else - mem_cnt_next <= 24; + mem_cnt_next <= 25; end if; end if; end if; @@ -2336,53 +2432,87 @@ begin mem_read <= '1'; -- Memory Flow Control Guard if (mem_ready_in = '1') then - if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then + if check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then mem_cnt_next <= 14; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then - mem_cnt_next <= 15; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 18; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then - mem_cnt_next <= 19; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then - mem_cnt_next <= 20; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 22; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 24; else - mem_cnt_next <= 26; + if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 16; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then + mem_cnt_next <= 19; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then + mem_cnt_next <= 20; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then + mem_cnt_next <= 25; + else + mem_cnt_next <= 27; + end if; end if; end if; end if; - -- READ Entity ID + -- GET Writer ID when 14 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_WRITER_ID_OFFSET; + mem_read <= '1'; + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then + mem_cnt_next <= 15; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then + mem_cnt_next <= 16; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then + mem_cnt_next <= 19; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then + mem_cnt_next <= 20; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 21; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then + mem_cnt_next <= 23; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then + mem_cnt_next <= 25; + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then + mem_cnt_next <= 27; + else + mem_cnt_next <= 29; + end if; + end if; + -- READ Entity ID + when 15 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.guid(3) <= mem_read_data; + current_emf_next <= current_emf or EMF_ENTITYID_FLAG; if check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then - mem_cnt_next <= 15; + mem_cnt_next <= 16; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 18; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 19; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 20; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 21; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 22; + mem_cnt_next <= 23; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 24; + mem_cnt_next <= 25; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 26; + mem_cnt_next <= 27; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; else -- DONE mem_stage_next <= IDLE; end if; end if; -- READ GUID Prefix 1/3 - when 15 => + when 16 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then @@ -2391,7 +2521,7 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- READ GUID Prefix 2/3 - when 16 => + when 17 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then @@ -2400,48 +2530,54 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- READ GUID Prefix 3/3 - when 17 => + when 18 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.guid(2) <= mem_read_data; + current_emf_next <= current_emf or EMF_GUIDPREFIX_FLAG; if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_IPV4_ADDR_FLAG)) then - mem_cnt_next <= 18; - elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 19; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then mem_cnt_next <= 20; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 21; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 22; + mem_cnt_next <= 23; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 24; + mem_cnt_next <= 25; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 26; + mem_cnt_next <= 27; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; else -- DONE mem_stage_next <= IDLE; end if; end if; -- READ IPv4 Address - when 18 => + when 19 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.addr <= mem_read_data; + current_emf_next <= current_emf or EMF_IPV4_ADDR_FLAG; if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then - mem_cnt_next <= 19; - elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then mem_cnt_next <= 20; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then + mem_cnt_next <= 21; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 22; + mem_cnt_next <= 23; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 24; + mem_cnt_next <= 25; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 26; + mem_cnt_next <= 27; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; else -- DONE mem_stage_next <= IDLE; @@ -2449,22 +2585,25 @@ begin end if; end if; -- READ UDP Port - when 19 => + when 20 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.portn <= mem_read_data(WORD_WIDTH-1 downto WORD_WIDTH-UDP_PORT_WIDTH); + current_emf_next <= current_emf or EMF_UDP_PORT_FLAG; if check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then - mem_cnt_next <= 20; + mem_cnt_next <= 21; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 22; + mem_cnt_next <= 23; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 24; + mem_cnt_next <= 25; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 26; + mem_cnt_next <= 27; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; else -- DONE mem_stage_next <= IDLE; @@ -2472,7 +2611,7 @@ begin end if; end if; -- READ Next Sequence Number 1/2 - when 20 => + when 21 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then @@ -2481,25 +2620,28 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- READ Next Sequence Number 2/2 - when 21 => + when 22 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.next_seq_nr(1) <= unsigned(mem_read_data); + current_emf_next <= current_emf or EMF_NEXT_SEQ_NR_FLAG; if check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then - mem_cnt_next <= 22; + mem_cnt_next <= 23; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 24; + mem_cnt_next <= 25; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 26; + mem_cnt_next <= 27; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; else -- DONE mem_stage_next <= IDLE; end if; end if; -- READ Lease Deadline 1/2 - when 22 => + when 23 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then @@ -2508,23 +2650,26 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- READ Lease Deadline 2/2 - when 23 => + when 24 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.lease_deadline(1) <= unsigned(mem_read_data); + current_emf_next <= current_emf or EMF_LEASE_DEADLINE_FLAG; if check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then - mem_cnt_next <= 24; + mem_cnt_next <= 25; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 26; + mem_cnt_next <= 27; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; else -- DONE mem_stage_next <= IDLE; end if; end if; -- READ Lifespan Duration 1/2 - when 24 => + when 25 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then @@ -2533,21 +2678,24 @@ begin mem_cnt_next <= mem_cnt + 1; end if; -- READ Lifespan Duration 2/2 - when 25 => + when 26 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.lifespan(1) <= unsigned(mem_read_data); + current_emf_next <= current_emf or EMF_LIFESPAN_DURATION_FLAG; if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then - mem_cnt_next <= 26; + mem_cnt_next <= 27; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; else -- DONE mem_stage_next <= IDLE; end if; end if; -- READ Response Time 1/2 - when 26 => + when 27 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_ready_out <= '1'; @@ -2559,83 +2707,131 @@ begin end if; end if; -- READ Response Time 2/2 - when 27 => + when 28 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then mem_endpoint_data_next.res_time(1) <= unsigned(mem_read_data); + current_emf_next <= current_emf or EMF_RES_TIME_FLAG; - -- DONE - mem_stage_next <= IDLE; + if check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 29; + else + -- DONE + mem_stage_next <= IDLE; + end if; end if; end if; + -- READ Writer ID + when 29 => + mem_ready_out <= '1'; + -- Memory Flow Control Guard + if (mem_valid_out = '1') then + mem_endpoint_data_next.writer_id <= to_integer(unsigned(mem_read_data)); + current_emf_next <= current_emf or EMF_WRITER_ID_FLAG; + + -- DONE + mem_stage_next <= IDLE; + end if; when others => null; end case; when INSERT_ENDPOINT => case (mem_cnt) is - -- Entity ID + -- GET Next Addr when 0 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_NEXT_ADDR_OFFSET; + mem_read <= '1'; + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Entity ID + when 1 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_ENTITYID_OFFSET; mem_write_data <= mem_endpoint_latch_data.guid(3); + mem_endpoint_data_next.guid(3) <= mem_endpoint_latch_data.guid(3); + current_emf_next <= current_emf or EMF_ENTITYID_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- GUID Prefix 1/3 - when 1 => + -- SET GUID Prefix 1/3 + when 2 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_GUIDPREFIX_OFFSET; mem_write_data <= mem_endpoint_latch_data.guid(0); + mem_endpoint_data_next.guid(0) <= mem_endpoint_latch_data.guid(0); + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- GUID Prefix 2/3 - when 2 => + -- SET GUID Prefix 2/3 + when 3 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_GUIDPREFIX_OFFSET + 1; mem_write_data <= mem_endpoint_latch_data.guid(1); + mem_endpoint_data_next.guid(1) <= mem_endpoint_latch_data.guid(1); + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- GUID Prefix 3/3 - when 3 => + -- SET GUID Prefix 3/3 + when 4 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_GUIDPREFIX_OFFSET + 2; mem_write_data <= mem_endpoint_latch_data.guid(2); + mem_endpoint_data_next.guid(2) <= mem_endpoint_latch_data.guid(2); + current_emf_next <= current_emf or EMF_GUIDPREFIX_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_cnt_next <= mem_cnt + 1; else - mem_cnt_next <= 6; + mem_cnt_next <= 7; -- SET Next Sequence Number 1/2 end if; end if; - -- IPv4 Address - when 4 => + -- SET IPv4 Address + when 5 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_IPV4_ADDR_OFFSET; mem_write_data <= mem_endpoint_latch_data.addr; + mem_endpoint_data_next.addr <= mem_endpoint_latch_data.addr; + current_emf_next <= current_emf or EMF_IPV4_ADDR_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; end if; - -- UDPv4 Ports - when 5 => + -- SET UDPv4 Ports + when 6 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_UDP_PORT_OFFSET; mem_write_data <= mem_endpoint_latch_data.portn & (0 to (mem_write_data'length-mem_endpoint_latch_data.portn'length-1) => '0'); + mem_endpoint_data_next.portn <= mem_endpoint_latch_data.portn; + current_emf_next <= current_emf or EMF_UDP_PORT_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; end if; - -- Next Sequence Number 1/2 - when 6 => + -- SET Next Sequence Number 1/2 + when 7 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_NEXT_SEQ_NR_OFFSET; if (DURABILITY_QOS = VOLATILE_DURABILITY_QOS) then @@ -2643,81 +2839,151 @@ begin else mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(0)); end if; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- Next Sequence Number 2/2 - when 7 => + -- SET Next Sequence Number 2/2 + when 8 => mem_write_data <= (others => '0'); mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_NEXT_SEQ_NR_OFFSET + 1; if (DURABILITY_QOS = VOLATILE_DURABILITY_QOS) then mem_write_data <= std_logic_vector(SEQUENCENUMBER_UNKNOWN(1)); + mem_endpoint_data_next.next_seq_nr <= SEQUENCENUMBER_UNKNOWN; else mem_write_data <= std_logic_vector(FIRST_SEQUENCENUMBER(1)); + mem_endpoint_data_next.next_seq_nr <= FIRST_SEQUENCENUMBER; end if; + current_emf_next <= current_emf or EMF_NEXT_SEQ_NR_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- Lease Deadline 1/2 - when 8 => + -- SET Lease Deadline 1/2 + when 9 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_LEASE_DEADLINE_OFFSET; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lease_deadline(0)); + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- Lease Deadline 2/2 - when 9 => + -- SET Lease Deadline 2/2 + when 10 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_LEASE_DEADLINE_OFFSET + 1; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lease_deadline(1)); + mem_endpoint_data_next.lease_deadline <= mem_endpoint_latch_data.lease_deadline; + current_emf_next <= current_emf or EMF_LEASE_DEADLINE_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- Lifespan Duration 1/2 - when 10 => + -- SET Lifespan Duration 1/2 + when 11 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_LIFESPAN_DURATION_OFFSET; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lifespan(0)); + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; - -- Lifespan Duration 2/2 - when 11 => + -- SET Lifespan Duration 2/2 + when 12 => mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_LIFESPAN_DURATION_OFFSET + 1; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lifespan(1)); + mem_endpoint_data_next.lifespan <= mem_endpoint_latch_data.lifespan; + current_emf_next <= current_emf or EMF_LIFESPAN_DURATION_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_cnt_next <= mem_cnt + 1; else - -- DONE - mem_stage_next <= IDLE; + mem_cnt_next <= 15; -- SET Next Addr end if; end if; - -- Response Time 1/2 - when 12 => + -- SET Response Time 1/2 + when 13 => -- Synthesis Guard if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_RES_TIME_OFFSET; mem_write_data <= std_logic_vector(TIME_INVALID(0)); + + -- Memory Flow Control Guard if (mem_ready_in = '1') then mem_cnt_next <= mem_cnt + 1; end if; end if; - -- Response Time 2/2 - when 13 => + -- SET Response Time 2/2 + when 14 => if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_RES_TIME_OFFSET + 1; mem_write_data <= std_logic_vector(TIME_INVALID(1)); + mem_endpoint_data_next.res_time <= TIME_INVALID; + current_emf_next <= current_emf or EMF_RES_TIME_FLAG; + + -- Memory Flow Control Guard if (mem_ready_in = '1') then - -- DONE - mem_stage_next <= IDLE; + mem_cnt_next <= mem_cnt + 1; end if; end if; + -- SET Next Addr + when 15 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_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 + mem_cnt_next <= mem_cnt + 1; + end if; + -- SET Prev Addr + when 16 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_PREV_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(ENDPOINT_MEMORY_MAX_ADDRESS,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + if (mem_occupied_head = ENDPOINT_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 17 => + mem_valid_in <= '1'; + mem_addr <= mem_occupied_head + EMF_PREV_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_addr_base,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + end if; + -- READ Next Addr + when 18 => + 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),ENDPOINT_MEMORY_ADDR_WIDTH); + mem_occupied_head_next <= mem_addr_base; + + -- DONE + mem_stage_next <= IDLE; + end if; when others => null; end case; @@ -2730,7 +2996,8 @@ begin mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_IPV4_ADDR_OFFSET; mem_write_data <= mem_endpoint_latch_data.addr; - mem_endpoint_data_next.addr <= mem_endpoint_latch_data.addr; + mem_endpoint_data_next.addr <= mem_endpoint_latch_data.addr; + current_emf_next <= current_emf or EMF_IPV4_ADDR_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_UDP_PORT_FLAG)) then @@ -2756,7 +3023,9 @@ begin mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_UDP_PORT_OFFSET; mem_write_data <= mem_endpoint_latch_data.portn & (0 to (mem_write_data'length-mem_endpoint_latch_data.portn'length-1) => '0'); - mem_endpoint_data_next.portn <= mem_endpoint_latch_data.portn; + mem_endpoint_data_next.portn <= mem_endpoint_latch_data.portn; + current_emf_next <= current_emf or EMF_UDP_PORT_FLAG; + -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(mem_endpoint_latch_data.field_flag,EMF_NEXT_SEQ_NR_FLAG) then @@ -2787,7 +3056,9 @@ begin mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_NEXT_SEQ_NR_OFFSET + 1; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.next_seq_nr(1)); - mem_endpoint_data_next.next_seq_nr <= mem_endpoint_latch_data.next_seq_nr; + mem_endpoint_data_next.next_seq_nr <= mem_endpoint_latch_data.next_seq_nr; + current_emf_next <= current_emf or EMF_NEXT_SEQ_NR_FLAG; + -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(mem_endpoint_latch_data.field_flag,EMF_LEASE_DEADLINE_FLAG) then @@ -2815,7 +3086,8 @@ begin mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_LEASE_DEADLINE_OFFSET + 1; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lease_deadline(1)); - mem_endpoint_data_next.lease_deadline <= mem_endpoint_latch_data.lease_deadline; + mem_endpoint_data_next.lease_deadline <= mem_endpoint_latch_data.lease_deadline; + current_emf_next <= current_emf or EMF_LEASE_DEADLINE_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if check_mask(mem_endpoint_latch_data.field_flag,EMF_LIFESPAN_DURATION_FLAG) then @@ -2842,6 +3114,7 @@ begin mem_addr <= mem_addr_base + EMF_LIFESPAN_DURATION_OFFSET + 1; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.lifespan(1)); mem_endpoint_data_next.lifespan <= mem_endpoint_latch_data.lifespan; + current_emf_next <= current_emf or EMF_LIFESPAN_DURATION_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then if (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then @@ -2870,7 +3143,8 @@ begin mem_valid_in <= '1'; mem_addr <= mem_addr_base + EMF_RES_TIME_OFFSET + 1; mem_write_data <= std_logic_vector(mem_endpoint_latch_data.res_time(1)); - mem_endpoint_data_next.res_time <= mem_endpoint_latch_data.res_time; + mem_endpoint_data_next.res_time <= mem_endpoint_latch_data.res_time; + current_emf_next <= current_emf or EMF_RES_TIME_FLAG; -- Memory Flow Control Guard if (mem_ready_in = '1') then -- DONE @@ -2881,154 +3155,127 @@ begin null; end case; when REMOVE_ENDPOINT => - -- Mark with ENTITYID_UNKNOWN to mark slot empty_user - mem_valid_in <= '1'; - mem_addr <= mem_addr_base + EMF_ENTITYID_OFFSET; - mem_write_data <= ENTITYID_UNKNOWN; - - -- Memory Flow Control Guard - if (mem_ready_in = '1') then - -- Reset MAX Endpoint Pointer - mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS; - mem_pos_next <= 0; - last_addr_next <= (others => '0'); - mem_stage_next <= RESET_MAX_POINTER; - mem_cnt_next <= 0; - -- Save Current Memory Position - mem_addr_latch_next <= mem_addr_base; - end if; - when FIND_EMPTY_SLOT => case (mem_cnt) is - -- *READ ADDRESS* - -- Entity ID + -- GET Next Addr when 0 => - mem_addr <= mem_addr_base + EMF_ENTITYID_OFFSET; - mem_read <= '1'; mem_valid_in <= '1'; - - -- Memory Control Flow Guard - if (mem_ready_in = '1') then - mem_cnt_next <= 1; - end if; - -- *READ DATA* - -- Entity ID - when 1 => - mem_ready_out <= '1'; - - -- Memory Control Flow Guard - if (mem_valid_out = '1') then - -- Slot Occupied - if (mem_read_data /= ENTITYID_UNKNOWN) then - -- Reached end of Endpoint Memory Area - if (mem_addr_base = max_endpoint_addr) then - -- MEMORY FULL - if (max_endpoint_addr = MAX_ENDPOINT_ADDRESS) then - report "Memory Full, Ignoring Endpoint Data" severity NOTE; - -- Ignore Insertion - mem_stage_next <= IDLE; - mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; - else - -- Extend Endpoint Memory Area - -- NOTE: "max_endpoint_addr" points to the first address of last Endpoint Frame - max_endpoint_addr_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - -- Populate Endpoint Slot - mem_stage_next <= INSERT_ENDPOINT; - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; - mem_cnt_next <= 0; - end if; - else - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; - mem_cnt_next <= 0; - end if; - -- Slot Empty - else - -- Populate Endpoint Slot - mem_stage_next <= INSERT_ENDPOINT; - mem_cnt_next <= 0; - end if; - end if; - when others => - null; - end case; - when RESET_MAX_POINTER => - case (mem_cnt) is - -- GET Entity ID - when 0 => - mem_addr <= mem_addr_base + EMF_ENTITYID_OFFSET; + mem_addr <= mem_addr_base + EMF_NEXT_ADDR_OFFSET; mem_read <= '1'; - mem_valid_in <= '1'; - - -- Memory Control Flow Guard + -- Memory Flow Control Guard if (mem_ready_in = '1') then - mem_cnt_next <= 1; + mem_cnt_next <= mem_cnt + 1; end if; - -- READ Entity ID + -- GET Prev Addr when 1 => - mem_ready_out <= '1'; + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_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 Addr + when 2 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_NEXT_ADDR_OFFSET; + mem_write_data <= std_logic_vector(resize(mem_empty_head,WORD_WIDTH)); - -- Memory Control Flow Guard + if (mem_ready_in = '1') then + -- Set New Empty Head + mem_empty_head_next <= mem_addr_base; + + 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 - -- Slot Occupied - if (mem_read_data /= ENTITYID_UNKNOWN) then - -- Reached end of Endpoint Memory Area - if (mem_addr_base = max_endpoint_addr) then - -- No Change - mem_stage_next <= IDLE; - -- Restore Memory Position - mem_addr_base_next <= mem_addr_latch; - else - -- Latch last occupied Endpoint Slot - last_addr_next <= mem_addr_base; - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_cnt_next <= 0; - end if; - -- Slot Empty - else - -- Make sure to iterate through complete Endpoint Area - if (mem_addr_base = max_endpoint_addr) then - -- Reset Pointer to last occupied Endpoint Slot - max_endpoint_addr_next <= last_addr; + mem_addr_latch_next <= resize(unsigned(mem_read_data),ENDPOINT_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 = ENDPOINT_MEMORY_MAX_ADDRESS) then + if (resize(unsigned(mem_read_data),ENDPOINT_MEMORY_ADDR_WIDTH) = ENDPOINT_MEMORY_MAX_ADDRESS) then + -- RESET Occupied List Head + mem_occupied_head_next <= ENDPOINT_MEMORY_MAX_ADDRESS; + + mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; -- DONE - mem_stage_next <= IDLE; - -- Restore Memory Position - mem_addr_base_next <= mem_addr_latch; + mem_stage_next <= IDLE; else - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_cnt_next <= 0; - end if; + mem_addr_base_next <= resize(unsigned(mem_read_data),ENDPOINT_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),ENDPOINT_MEMORY_ADDR_WIDTH); + mem_cnt_next <= mem_cnt + 1; end if; end if; - when others => + -- SET Prev Addr (Next Slot) + when 5 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_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 = ENDPOINT_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 + EMF_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; + when others => null; end case; when GET_NEXT_ENDPOINT => case (mem_cnt) is - -- GET Entity ID + -- GET Next Addr when 0 => mem_valid_in <= '1'; mem_read <= '1'; - mem_addr <= mem_addr_base + EMF_ENTITYID_OFFSET; + mem_addr <= mem_addr_base + EMF_NEXT_ADDR_OFFSET; -- Memory Flow Control Guard if (mem_ready_in = '1') then - mem_cnt_next <= 1; + mem_cnt_next <= mem_cnt + 1; end if; - -- READ Entity ID + -- READ Next Addr when 1 => mem_ready_out <= '1'; -- Memory Flow Control Guard if (mem_valid_out = '1') then - -- Slot Occupied - if (mem_read_data /= ENTITYID_UNKNOWN) then + if (resize(unsigned(mem_read_data),ENDPOINT_MEMORY_ADDR_WIDTH) = ENDPOINT_MEMORY_MAX_ADDRESS) then + mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; + -- DONE + mem_stage_next <= IDLE; + else -- Fetch Endpoint Data - mem_stage_next <= GET_ENDPOINT_DATA; - mem_endpoint_data_next <= ZERO_ENDPOINT_DATA; + mem_addr_base_next <= resize(unsigned(mem_read_data),ENDPOINT_MEMORY_ADDR_WIDTH); + + mem_stage_next <= GET_ENDPOINT_DATA; if check_mask(mem_endpoint_latch_data.field_flag,EMF_ENTITYID_FLAG) then mem_cnt_next <= 0; elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_GUIDPREFIX_FLAG) then @@ -3045,23 +3292,12 @@ begin mem_cnt_next <= 10; elsif (RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and check_mask(mem_endpoint_latch_data.field_flag,EMF_RES_TIME_FLAG)) then mem_cnt_next <= 12; + elsif check_mask(mem_endpoint_latch_data.field_flag,EMF_WRITER_ID_FLAG) then + mem_cnt_next <= 14; else -- DONE mem_stage_next <= IDLE; end if; - -- Slot Empty - else - -- Reached End of Memory, No Match - if (mem_addr_base = max_endpoint_addr) then - mem_addr_base_next <= ENDPOINT_MEMORY_MAX_ADDRESS; --No match - -- DONE - mem_stage_next <= IDLE; - else - -- Continue Search - mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; - mem_pos_next <= mem_pos + 1; - mem_cnt_next <= 0; - end if; end if; end if; when others => @@ -3069,25 +3305,53 @@ begin end case; when RESET_MEMORY => case (mem_cnt) is - -- Initiate Reset + -- SET Writer ID when 0 => - mem_addr_base_next <= FIRST_ENDPOINT_ADDRESS; - mem_cnt_next <= mem_cnt + 1; - -- Reset Memory - when 1 => mem_valid_in <= '1'; - mem_addr <= mem_addr_base + EMF_ENTITYID_OFFSET; - mem_write_data <= ENTITYID_UNKNOWN; + mem_addr <= mem_addr_base + EMF_WRITER_ID_OFFSET; + mem_write_data <= std_logic_vector(to_unsigned(mem_endpoint_data.writer_id,WORD_WIDTH)); + + -- Memory Flow Control Guard + if (mem_ready_in = '1') then + mem_cnt_next <= mem_cnt + 1; + mem_endpoint_data_next.writer_id <= mem_endpoint_data.writer_id + 1; + end if; + -- SET Next Pointer + when 1 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_NEXT_ADDR_OFFSET; + if (mem_addr_base = MAX_ENDPOINT_ADDRESS) then + mem_write_data <= std_logic_vector(resize(ENDPOINT_MEMORY_MAX_ADDRESS,WORD_WIDTH)); + else + mem_write_data <= std_logic_vector(resize(mem_addr_base + ENDPOINT_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 2 => + mem_valid_in <= '1'; + mem_addr <= mem_addr_base + EMF_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 - -- End of Memory if (mem_addr_base = MAX_ENDPOINT_ADDRESS) then + -- Initialize Empty and Occupied Heads + mem_empty_head_next <= FIRST_ENDPOINT_ADDRESS; + mem_occupied_head_next <= ENDPOINT_MEMORY_MAX_ADDRESS; + + -- Reset + mem_endpoint_data_next.writer_id <= 0; + -- DONE mem_stage_next <= IDLE; else - -- Next Endpoint Frame + mem_addr_latch_next <= mem_addr_base; mem_addr_base_next <= mem_addr_base + ENDPOINT_FRAME_SIZE; + mem_cnt_next <= 0; end if; end if; when others => @@ -3137,7 +3401,6 @@ begin cnt2 <= 0; bitmap_pos <= 0; mem_cnt <= 0; - mem_pos <= 0; is_meta <= '0'; key_hash_rcvd <= '0'; last_word_in_latch <= '0'; @@ -3146,10 +3409,10 @@ begin bitmap_cnt <= (others => '0'); meta_opcode <= EMO_NOP; status_info <= (others => '0'); - mem_addr_base <= (others => '0'); - last_addr <= (others => '0'); - mem_addr_latch <= (others => '0'); - max_endpoint_addr <= (others => '0'); + mem_addr_base <= FIRST_ENDPOINT_ADDRESS; + mem_empty_head <= ENDPOINT_MEMORY_MAX_ADDRESS; + mem_occupied_head <= ENDPOINT_MEMORY_MAX_ADDRESS; + mem_addr_latch <= ENDPOINT_MEMORY_MAX_ADDRESS; flags <= (others => '0'); opcode <= SID_PAD; count <= (others => '0'); @@ -3177,7 +3440,6 @@ begin cnt2 <= cnt2_next; bitmap_pos <= bitmap_pos_next; mem_cnt <= mem_cnt_next; - mem_pos <= mem_pos_next; is_meta <= is_meta_next; key_hash_rcvd <= key_hash_rcvd_next; last_word_in_latch <= last_word_in_latch_next; @@ -3187,9 +3449,9 @@ begin meta_opcode <= meta_opcode_next; status_info <= status_info_next; mem_addr_base <= mem_addr_base_next; - last_addr <= last_addr_next; + mem_empty_head <= mem_empty_head_next; + mem_occupied_head <= mem_occupied_head_next; mem_addr_latch <= mem_addr_latch_next; - max_endpoint_addr <= max_endpoint_addr_next; flags <= flags_next; opcode <= opcode_next; count <= count_next; diff --git a/src/rtps_test_package.vhd b/src/rtps_test_package.vhd index ac3a5dd..60a454d 100644 --- a/src/rtps_test_package.vhd +++ b/src/rtps_test_package.vhd @@ -24,9 +24,9 @@ package rtps_test_package is -- rtps_discovery_module Participant Frame Size constant PARTICIPANT_FRAME_SIZE : natural := 24; -- rtps_reader Endpoint Frame Size (RELIABLE=TRUE) - constant WRITER_ENDPOINT_FRAME_SIZE_A : natural := 14; + constant WRITER_ENDPOINT_FRAME_SIZE_A : natural := 17; -- rtps_reader Endpoint Frame Size (RELIABLE=FALSE) - constant WRITER_ENDPOINT_FRAME_SIZE_B : natural := 10; + constant WRITER_ENDPOINT_FRAME_SIZE_B : natural := 13; -- rtps_writer Endpoint Frame Size (RELIABLE=TRUE) constant READER_ENDPOINT_FRAME_SIZE_A : natural := 17; -- rtps_writer Endpoint Frame Size (RELIABLE=FALSE)