diff --git a/src/Tests/Level_0/L0_rtps_writer_test1.vhd b/src/Tests/Level_0/L0_rtps_writer_test1.vhd index 0aeadaa..eeba3cf 100644 --- a/src/Tests/Level_0/L0_rtps_writer_test1.vhd +++ b/src/Tests/Level_0/L0_rtps_writer_test1.vhd @@ -116,10 +116,10 @@ begin data_available => (others => '0'), start_hc => start_hc, opcode_hc => open, - ack_hc => (others => '0'), + ack_hc => (others => '1'), seq_nr_hc => open, - done_hc => (others => '0'), - ret_hc => (others => ERROR), + done_hc => (others => '1'), + ret_hc => (others => OK), get_data_hc => open, data_in_hc => (others => (others => '0')), valid_in_hc => (others => '0'), @@ -439,7 +439,6 @@ begin begin if rising_edge(clk) then alertif(empty_meta = (empty_meta'range => '1') and rd_meta = '1', "Input FIFO read signal high while empty signal high", FAILURE); - alertif(start_hc /= (start_hc'range => '0'), "Unexpected History Cache Operation initiated", FAILURE); end if; end process; diff --git a/src/Tests/Level_0/L0_rtps_writer_test2.vhd b/src/Tests/Level_0/L0_rtps_writer_test2.vhd index 01ff07d..00f6234 100644 --- a/src/Tests/Level_0/L0_rtps_writer_test2.vhd +++ b/src/Tests/Level_0/L0_rtps_writer_test2.vhd @@ -119,10 +119,10 @@ begin data_available => (others => '0'), start_hc => start_hc, opcode_hc => open, - ack_hc => (others => '0'), + ack_hc => (others => '1'), seq_nr_hc => open, - done_hc => (others => '0'), - ret_hc => (others => ERROR), + done_hc => (others => '1'), + ret_hc => (others => OK), get_data_hc => open, data_in_hc => (others => (others => '0')), valid_in_hc => (others => '0'), @@ -454,7 +454,6 @@ begin if rising_edge(clk) then alertif(empty_meta = (empty_meta'range => '1') and rd_meta = '1', "Input FIFO read signal high while empty signal high (meta)", FAILURE); alertif(empty_user = (empty_user'range => '1') and rd_user = '1', "Input FIFO read signal high while empty signal high (user)", FAILURE); - alertif(start_hc /= (start_hc'range => '0'), "Unexpected History Cache Operation initiated", FAILURE); end if; end process; diff --git a/src/Tests/Level_1/L1_rtps_writer_test1.vhd b/src/Tests/Level_1/L1_rtps_writer_test1.vhd index 626987b..5cae391 100644 --- a/src/Tests/Level_1/L1_rtps_writer_test1.vhd +++ b/src/Tests/Level_1/L1_rtps_writer_test1.vhd @@ -158,7 +158,7 @@ architecture testbench of L1_rtps_writer_test1 is signal rtps_out_rd, rtps_out_last_word_in, rtps_out_empty : std_logic_vector(0 to NUM_ENDPOINTS) := (others => '0'); signal test_cc : TEST_CC_ARRAY_ARRAY_TYPE := (others => (others => DEFAULT_CACHE_CHANGE)); -- Signal containing the current fill level of the test_cc array - signal test_cc_fill : TEST_CC_FILL_ARRAY_TYPE := (others => 0); + signal test_cc_fill, hb_count : TEST_CC_FILL_ARRAY_TYPE := (others => 0); signal stage_hc : HC_STAGE_TYPE := IDLE; signal new_cc : std_logic := '0'; signal cnt : natural := 0; @@ -443,6 +443,35 @@ begin end loop; end procedure; + procedure push_hb(endpoint : in ENDPOINT_DATA_TYPE; first : in SEQUENCENUMBER_TYPE; last : in SEQUENCENUMBER_TYPE; liveliness_assertion : in boolean; i : natural) is + begin + reference := EMPTY_TEST_PACKET; + -- OUTPUT HEADER + OUT_HEADER := DEFAULT_OUTPUT_HEADER; + OUT_HEADER := (dest => get_loc(endpoint), src => DEST_LOC.user.locator(1)); + gen_output_header(OUT_HEADER, reference); + -- RTPS HEADER + rtps_header := DEFAULT_RTPS_HEADER; + rtps_header.guidPrefix := GUIDPREFIX; + gen_rtps_header(rtps_header, reference); + -- HEARTBEAT + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_HEARTBEAT; + sub.writerId := ENTITYID(i); + sub.readerId := ENTITYID_UNKNOWN; + sub.firstSN := first; + sub.lastSN := last; + sub.flags(SUBMESSAGE_LIVELINESS_FLAG_POS) := '1' when (liveliness_assertion) else '0'; + sub.count := std_logic_vector(to_unsigned(hb_count(i), CDR_LONG_WIDTH)); + hb_count(i) <= hb_count(i) + 1; + wait for 0 ns; -- Latch Signal + gen_rtps_submessage(sub, reference); + fix_output_packet(reference); + for i in 0 to reference.length-1 loop + SB_out.Push(reference.data(i)); + end loop; + end procedure; + procedure check_gsn(ref : SEQUENCENUMBER_TYPE; i : natural) is begin AffirmIf(gsn(i) = ref, "Global ACK SN: " & to_hstring(to_unsigned(gsn(i))) & " Expected: " & to_hstring(to_unsigned(ref))); @@ -508,6 +537,7 @@ begin Log("Initiating Test", INFO); Log("Current Time: 0s", INFO); + hb_count <= (others => 1); count <= 1; test_time <= TIME_ZERO; new_cc <= '0'; @@ -533,10 +563,18 @@ begin gen_endpoint_match_frame(e1, stimulus_meta); w_map <= "11111111"; start_meta_test; + + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,0); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,1); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,4); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,5); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,6); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,7); wait_on_sig(packet_sent_meta); + wait_on_sig(out_check_done); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(SEQUENCENUMBER_UNKNOWN,0); check_gsn(SEQUENCENUMBER_UNKNOWN,1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -552,10 +590,18 @@ begin gen_endpoint_match_frame(e3, stimulus_meta); w_map <= "11001111"; start_meta_test; + + push_hb(e3, gen_sn(1), gen_sn(0), FALSE,0); + push_hb(e3, gen_sn(1), gen_sn(0), FALSE,1); + push_hb(e3, gen_sn(1), gen_sn(0), FALSE,4); + push_hb(e3, gen_sn(1), gen_sn(0), FALSE,5); + push_hb(e3, gen_sn(1), gen_sn(0), FALSE,6); + push_hb(e3, gen_sn(1), gen_sn(0), FALSE,7); wait_on_sig(packet_sent_meta); + wait_on_sig(out_check_done); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(0),0); check_gsn(gen_sn(0),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -659,6 +705,7 @@ begin sub.readerSNState := (base => gen_sn(2), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; push_hc(REMOVE_CACHE_CHANGE, gen_sn(1),0); push_hc(ACK_CACHE_CHANGE, gen_sn(1),1); push_hc(REMOVE_CACHE_CHANGE, gen_sn(1),4); @@ -668,10 +715,9 @@ begin w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),0); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -812,9 +858,9 @@ begin w_map <= "11001111"; start_meta_test; wait_on_sig(packet_sent_meta); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -836,6 +882,7 @@ begin sub.readerSNState := (base => gen_sn(3), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; push_hc(REMOVE_CACHE_CHANGE, gen_sn(2),0); push_hc(ACK_CACHE_CHANGE, gen_sn(2),1); push_hc(REMOVE_CACHE_CHANGE, gen_sn(2),4); @@ -845,10 +892,9 @@ begin w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(2),0); check_gsn(gen_sn(2),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -871,9 +917,9 @@ begin w_map <= "11001111"; start_meta_test; wait_on_sig(packet_sent_meta); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(SEQUENCENUMBER_UNKNOWN,0); check_gsn(SEQUENCENUMBER_UNKNOWN,1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -900,10 +946,15 @@ begin push_hc(NACK_CACHE_CHANGE, gen_sn(3),7); w_map <= "11001111"; start_meta_test; - wait_on_sig(packet_sent_meta); - stimulus_meta := EMPTY_TEST_PACKET; - stimulus_user := EMPTY_TEST_PACKET; + push_hb(e1, gen_sn(1), gen_sn(3), FALSE,0); + push_hb(e1, gen_sn(1), gen_sn(3), FALSE,1); + push_hb(e1, gen_sn(1), gen_sn(3), FALSE,4); + push_hb(e1, gen_sn(1), gen_sn(3), FALSE,5); + push_hb(e1, gen_sn(1), gen_sn(3), FALSE,6); + push_hb(e1, gen_sn(1), gen_sn(3), FALSE,7); + push_hb(e3, gen_sn(1), gen_sn(3), FALSE,0); + push_hb(e3, gen_sn(1), gen_sn(3), FALSE,1); -- W1 gen_header(e3); gen_data(e3, test_cc(1)(0)); @@ -914,8 +965,16 @@ begin gen_header(e3); gen_data(e3, test_cc(1)(2)); push_reference; + -- + push_hb(e3, gen_sn(1), gen_sn(3), FALSE,4); + push_hb(e3, gen_sn(1), gen_sn(3), FALSE,5); + push_hb(e3, gen_sn(1), gen_sn(3), FALSE,6); + push_hb(e3, gen_sn(1), gen_sn(3), FALSE,7); + wait_on_sig(packet_sent_meta); wait_on_sig(out_check_done); wait_on_idle; + stimulus_meta := EMPTY_TEST_PACKET; + stimulus_user := EMPTY_TEST_PACKET; check_gsn(gen_sn(3),0); check_gsn(gen_sn(0),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -937,15 +996,15 @@ begin sub.readerSNState := (base => gen_sn(2), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; push_hc(ACK_CACHE_CHANGE, gen_sn(1),1); push_hc(ACK_CACHE_CHANGE, gen_sn(1),7); w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(3),0); check_gsn(gen_sn(1),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -961,10 +1020,24 @@ begin gen_endpoint_match_frame(e2, stimulus_meta); w_map <= "11001111"; start_meta_test; + + push_hb(e0, gen_sn(1), gen_sn(3), FALSE,0); + push_hb(e0, gen_sn(1), gen_sn(3), FALSE,1); + push_hb(e0, gen_sn(1), gen_sn(3), FALSE,4); + push_hb(e0, gen_sn(1), gen_sn(3), FALSE,5); + push_hb(e0, gen_sn(1), gen_sn(3), FALSE,6); + push_hb(e0, gen_sn(1), gen_sn(3), FALSE,7); + push_hb(e2, gen_sn(1), gen_sn(3), FALSE,0); + push_hb(e2, gen_sn(1), gen_sn(3), FALSE,1); + push_hb(e2, gen_sn(1), gen_sn(3), FALSE,4); + push_hb(e2, gen_sn(1), gen_sn(3), FALSE,5); + push_hb(e2, gen_sn(1), gen_sn(3), FALSE,6); + push_hb(e2, gen_sn(1), gen_sn(3), FALSE,7); wait_on_sig(packet_sent_meta); + wait_on_sig(out_check_done); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(3),0); check_gsn(gen_sn(1),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1161,13 +1234,13 @@ begin sub.readerSNState := (base => gen_sn(5), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(3),0); check_gsn(gen_sn(1),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1188,13 +1261,13 @@ begin sub.readerSNState := (base => gen_sn(6), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(3),0); check_gsn(gen_sn(1),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1216,6 +1289,7 @@ begin sub.readerSNState := (base => gen_sn(6), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; push_hc(REMOVE_CACHE_CHANGE, gen_sn(4),0); push_hc(ACK_CACHE_CHANGE, gen_sn(2),1); push_hc(ACK_CACHE_CHANGE, gen_sn(3),1); @@ -1229,10 +1303,9 @@ begin w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(4),0); check_gsn(gen_sn(4),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1254,6 +1327,7 @@ begin sub.readerSNState := (base => gen_sn(6), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; push_hc(REMOVE_CACHE_CHANGE, gen_sn(5),0); push_hc(ACK_CACHE_CHANGE, gen_sn(5),1); push_hc(REMOVE_CACHE_CHANGE, gen_sn(5),4); @@ -1263,10 +1337,9 @@ begin w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(5),0); check_gsn(gen_sn(5),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1555,13 +1628,13 @@ begin sub.readerSNState := (base => gen_sn(16), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(5),0); check_gsn(gen_sn(5),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1582,13 +1655,13 @@ begin sub.readerSNState := (base => gen_sn(16), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(5),0); check_gsn(gen_sn(5),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1610,6 +1683,7 @@ begin sub.readerSNState := (base => gen_sn(16), numBits => int(0, CDR_LONG_WIDTH), bitmap => (others => '0')); sub.flags(SUBMESSAGE_FINAL_FLAG_POS) := '1'; gen_rtps_handler_out(sub, get_loc(endpoint), FALSE, TIME_INVALID, endpoint.participant.guidPrefix, stimulus_user); + count <= count + 1; push_hc(REMOVE_CACHE_CHANGE, gen_sn(6),0); push_hc(REMOVE_CACHE_CHANGE, gen_sn(7),0); push_hc(REMOVE_CACHE_CHANGE, gen_sn(8),0); @@ -1673,10 +1747,9 @@ begin w_map <= "11001111"; start_user_test; wait_on_sig(packet_sent_user); - count <= count + 1; + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(15),0); check_gsn(gen_sn(15),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1692,10 +1765,9 @@ begin gen_endpoint_match_frame(e4, stimulus_meta); w_map <= "11111111"; start_meta_test; - wait_on_sig(packet_sent_meta); - stimulus_meta := EMPTY_TEST_PACKET; - stimulus_user := EMPTY_TEST_PACKET; + push_hb(e4, gen_sn(3), gen_sn(15), FALSE,0); + push_hb(e4, gen_sn(3), gen_sn(15), FALSE,1); -- W1 gen_header(e4); gen_data(e4, test_cc(1)(0)); @@ -1738,8 +1810,16 @@ begin gen_gap(gen_sn(12), gen_sn(15),2); gen_data(e4, test_cc(2)(5)); push_reference; + -- + push_hb(e4, gen_sn(3), gen_sn(15), FALSE,4); + push_hb(e4, gen_sn(3), gen_sn(15), FALSE,5); + push_hb(e4, gen_sn(3), gen_sn(15), FALSE,6); + push_hb(e4, gen_sn(3), gen_sn(15), FALSE,7); + wait_on_sig(packet_sent_meta); wait_on_sig(out_check_done); wait_on_idle; + stimulus_meta := EMPTY_TEST_PACKET; + stimulus_user := EMPTY_TEST_PACKET; check_gsn(gen_sn(15),0); check_gsn(gen_sn(15),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1760,9 +1840,9 @@ begin w_map <= "11001111"; start_meta_test; wait_on_sig(packet_sent_meta); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(SEQUENCENUMBER_UNKNOWN,0); check_gsn(SEQUENCENUMBER_UNKNOWN,1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1873,9 +1953,9 @@ begin w_map <= "11111111"; start_meta_test; wait_on_sig(packet_sent_meta); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(SEQUENCENUMBER_UNKNOWN,0); check_gsn(SEQUENCENUMBER_UNKNOWN,1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1913,10 +1993,18 @@ begin gen_endpoint_match_frame(e0, stimulus_meta); w_map <= "11001111"; start_meta_test; + + push_hb(e0, gen_sn(16), gen_sn(16), FALSE,0); + push_hb(e0, gen_sn(16), gen_sn(16), FALSE,1); + push_hb(e0, gen_sn(16), gen_sn(16), FALSE,4); + push_hb(e0, gen_sn(16), gen_sn(16), FALSE,5); + push_hb(e0, gen_sn(16), gen_sn(16), FALSE,6); + push_hb(e0, gen_sn(16), gen_sn(16), FALSE,7); wait_on_sig(packet_sent_meta); + wait_on_sig(out_check_done); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(16),0); check_gsn(gen_sn(16),1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); @@ -1934,9 +2022,9 @@ begin w_map <= "11001111"; start_meta_test; wait_on_sig(packet_sent_meta); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(SEQUENCENUMBER_UNKNOWN,0); check_gsn(SEQUENCENUMBER_UNKNOWN,1); check_gsn(SEQUENCENUMBER_UNKNOWN,2); diff --git a/src/Tests/Level_1/L1_rtps_writer_test2.vhd b/src/Tests/Level_1/L1_rtps_writer_test2.vhd index 3e3d150..1ca9cb6 100644 --- a/src/Tests/Level_1/L1_rtps_writer_test2.vhd +++ b/src/Tests/Level_1/L1_rtps_writer_test2.vhd @@ -91,7 +91,7 @@ architecture testbench of L1_rtps_writer_test2 is signal rtps_out_rd, rtps_out_last_word_in, rtps_out_empty : std_logic_vector(0 to NUM_ENDPOINTS) := (others => '0'); signal test_cc : TEST_CC_ARRAY_ARRAY_TYPE := (others => (others => DEFAULT_CACHE_CHANGE)); -- Signal containing the current fill level of the test_cc array - signal test_cc_fill : TEST_CC_FILL_ARRAY_TYPE := (others => 0); + signal test_cc_fill, hb_count : TEST_CC_FILL_ARRAY_TYPE := (others => 0); signal stage_hc : HC_STAGE_TYPE := IDLE; signal new_cc : std_logic := '0'; signal cnt : natural := 0; @@ -368,6 +368,35 @@ begin gen_rtps_submessage(sub, reference); end procedure; + procedure push_hb(endpoint : in ENDPOINT_DATA_TYPE; first : in SEQUENCENUMBER_TYPE; last : in SEQUENCENUMBER_TYPE; liveliness_assertion : in boolean; i : natural) is + begin + reference := EMPTY_TEST_PACKET; + -- OUTPUT HEADER + OUT_HEADER := DEFAULT_OUTPUT_HEADER; + OUT_HEADER := (dest => get_loc(endpoint), src => DEST_LOC.user.locator(1)); + gen_output_header(OUT_HEADER, reference); + -- RTPS HEADER + rtps_header := DEFAULT_RTPS_HEADER; + rtps_header.guidPrefix := GUIDPREFIX; + gen_rtps_header(rtps_header, reference); + -- HEARTBEAT + sub := DEFAULT_RTPS_SUBMESSAGE; + sub.submessageID := SID_HEARTBEAT; + sub.writerId := ENTITYID(i); + sub.readerId := ENTITYID_UNKNOWN; + sub.firstSN := first; + sub.lastSN := last; + sub.flags(SUBMESSAGE_LIVELINESS_FLAG_POS) := '1' when (liveliness_assertion) else '0'; + sub.count := std_logic_vector(to_unsigned(hb_count(i), CDR_LONG_WIDTH)); + hb_count(i) <= hb_count(i) + 1; + wait for 0 ns; -- Latch Signal + gen_rtps_submessage(sub, reference); + fix_output_packet(reference); + for i in 0 to reference.length-1 loop + SB_out.Push(reference.data(i)); + end loop; + end procedure; + procedure push_reference is begin fix_output_packet(reference); @@ -423,6 +452,7 @@ begin Log("Initiating Test", INFO); Log("Current Time: 0s", INFO); + hb_count <= (others => 1); count <= 1; test_time <= TIME_ZERO; new_cc <= '0'; @@ -461,10 +491,17 @@ begin gen_endpoint_match_frame(e2, stimulus_meta); w_map <= "11"; start_meta_test; + + push_hb(e0, gen_sn(1), gen_sn(1), FALSE,0); + push_hb(e0, gen_sn(1), gen_sn(1), FALSE,1); + push_hb(e1, gen_sn(1), gen_sn(1), FALSE,0); + push_hb(e1, gen_sn(1), gen_sn(1), FALSE,1); + push_hb(e2, gen_sn(1), gen_sn(1), FALSE,0); + push_hb(e2, gen_sn(1), gen_sn(1), FALSE,1); wait_on_sig(packet_sent_meta); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),1); @@ -482,9 +519,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),1); @@ -516,9 +553,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),1); @@ -586,9 +623,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),1); @@ -607,9 +644,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),1); @@ -627,9 +664,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(1),0); check_gsn(gen_sn(1),1); @@ -676,9 +713,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(2),0); check_gsn(gen_sn(2),1); @@ -696,9 +733,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(2),0); check_gsn(gen_sn(2),1); @@ -719,9 +756,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(3),0); check_gsn(gen_sn(3),1); @@ -767,9 +804,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(3),0); check_gsn(gen_sn(3),1); @@ -847,9 +884,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(3),0); check_gsn(gen_sn(3),1); @@ -873,9 +910,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(9),0); check_gsn(gen_sn(9),1); @@ -902,9 +939,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(9),0); check_gsn(gen_sn(9),1); @@ -924,9 +961,9 @@ begin w_map <= "11"; start_user_test; wait_on_sig(packet_sent_user); + wait_on_idle; stimulus_meta := EMPTY_TEST_PACKET; stimulus_user := EMPTY_TEST_PACKET; - wait_on_idle; check_gsn(gen_sn(10),0); check_gsn(gen_sn(10),1); diff --git a/src/Tests/Level_1/L1_rtps_writer_test3.vhd b/src/Tests/Level_1/L1_rtps_writer_test3.vhd index ddf746b..cdff970 100644 --- a/src/Tests/Level_1/L1_rtps_writer_test3.vhd +++ b/src/Tests/Level_1/L1_rtps_writer_test3.vhd @@ -354,6 +354,12 @@ begin wait until rising_edge(clk); end procedure; + procedure inc_count(i : natural) is + begin + count(i) <= count(i) + 1; + wait for 0 ns; -- Latch Signal + end procedure; + begin SetAlertLogName("L1_rtps_writer_test3 - RTPS Output (HEARTBEAT)"); @@ -431,9 +437,17 @@ begin gen_endpoint_match_frame(e1, stimulus_meta); w_map <= "110"; start_meta_test; + push_hb(e0, gen_sn(1), gen_sn(0), FALSE,0); + inc_count(0); + push_hb(e0, gen_sn(1), gen_sn(0), FALSE,1); + inc_count(1); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,0); + inc_count(0); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE,1); + inc_count(1); wait_on_sig(packet_sent_meta); - stimulus_meta := EMPTY_TEST_PACKET; wait_on_idle; + stimulus_meta := EMPTY_TEST_PACKET; Log("Current Time: 1s", INFO); @@ -443,11 +457,11 @@ begin wait until rising_edge(clk); -- Allow idle_sig to go low push_hb(e1, gen_sn(1), gen_sn(0), FALSE,0); push_hb(e0, gen_sn(1), gen_sn(0), FALSE,0); - count(0) <= count(0) + 1; + inc_count(0); push_hb(e1, gen_sn(1), gen_sn(0), FALSE,1); push_hb(e0, gen_sn(1), gen_sn(0), FALSE,1); - count(1) <= count(1) + 1; - count(2) <= count(2) + 1; + inc_count(1); + inc_count(2); wait_on_sig(out_check_done); wait_on_idle; @@ -468,11 +482,11 @@ begin wait until rising_edge(clk); -- Allow idle_sig to go low push_hb(e1, gen_sn(1), gen_sn(1), FALSE,0); push_hb(e0, gen_sn(1), gen_sn(1), FALSE,0); - count(0) <= count(0) + 1; + inc_count(0); push_hb(e1, gen_sn(1), gen_sn(0), FALSE,1); push_hb(e0, gen_sn(1), gen_sn(0), FALSE,1); - count(1) <= count(1) + 1; - count(2) <= count(2) + 1; + inc_count(1); + inc_count(2); wait_on_sig(out_check_done); wait_on_idle; @@ -494,7 +508,7 @@ begin Log("W0: Send HEARTBEAT to Endpoint 0,1 [Liveliness Flag]", INFO); push_hb(e1, gen_sn(1), gen_sn(3), TRUE,0); push_hb(e0, gen_sn(1), gen_sn(3), TRUE,0); - count(0) <= count(0) + 1; + inc_count(0); wait_on_sig(out_check_done); wait_on_idle; @@ -504,9 +518,13 @@ begin gen_endpoint_match_frame(e3, stimulus_meta); w_map <= "100"; start_meta_test; + push_hb(e2, gen_sn(1), gen_sn(3), FALSE,0); + inc_count(0); + push_hb(e3, gen_sn(1), gen_sn(3), FALSE,0); + inc_count(0); wait_on_sig(packet_sent_meta); - stimulus_meta := EMPTY_TEST_PACKET; wait_on_idle; + stimulus_meta := EMPTY_TEST_PACKET; Log("Current Time: 3s", INFO); @@ -519,11 +537,11 @@ begin push_hb(e2, gen_sn(1), gen_sn(3), FALSE,0); push_hb(e1, gen_sn(1), gen_sn(3), FALSE,0); push_hb(e0, gen_sn(1), gen_sn(3), FALSE,0); - count(0) <= count(0) + 1; + inc_count(0); push_hb(e1, gen_sn(1), gen_sn(1), FALSE,1); push_hb(e0, gen_sn(1), gen_sn(1), FALSE,1); - count(1) <= count(1) + 1; - count(2) <= count(2) + 1; + inc_count(1); + inc_count(2); wait_on_sig(out_check_done); wait_on_idle; @@ -532,9 +550,15 @@ begin gen_endpoint_match_frame(e4, stimulus_meta); w_map <= "111"; start_meta_test; + push_hb(e4, gen_sn(1), gen_sn(3), FALSE,0); + inc_count(0); + push_hb(e4, gen_sn(1), gen_sn(1), FALSE,1); + inc_count(1); + push_hb(e4, gen_sn(1), gen_sn(0), FALSE,2); + inc_count(2); wait_on_sig(packet_sent_meta); - stimulus_meta := EMPTY_TEST_PACKET; wait_on_idle; + stimulus_meta := EMPTY_TEST_PACKET; Log("W0: Remove Cache Change [SN 1,2,3], Add Cache Change [SN 10,11,15,46,50]", INFO); @@ -567,13 +591,13 @@ begin push_hb(e2, gen_sn(10), gen_sn(50), FALSE,0); push_hb(e1, gen_sn(10), gen_sn(50), FALSE,0); push_hb(e0, gen_sn(10), gen_sn(50), FALSE,0); - count(0) <= count(0) + 1; + inc_count(0); push_hb(e4, gen_sn(1), gen_sn(3), FALSE,1); push_hb(e1, gen_sn(1), gen_sn(3), FALSE,1); push_hb(e0, gen_sn(1), gen_sn(3), FALSE,1); - count(1) <= count(1) + 1; + inc_count(1); push_hb(e4, gen_sn(1), gen_sn(0), FALSE,2); - count(2) <= count(2) + 1; + inc_count(2); wait_on_sig(out_check_done); wait_on_idle; @@ -598,13 +622,13 @@ begin push_hb(e2, gen_sn(51), gen_sn(50), FALSE,0); push_hb(e1, gen_sn(51), gen_sn(50), FALSE,0); push_hb(e0, gen_sn(51), gen_sn(50), FALSE,0); - count(0) <= count(0) + 1; + inc_count(0); push_hb(e4, gen_sn(4), gen_sn(3), FALSE,1); push_hb(e1, gen_sn(4), gen_sn(3), FALSE,1); push_hb(e0, gen_sn(4), gen_sn(3), FALSE,1); - count(1) <= count(1) + 1; + inc_count(1); push_hb(e4, gen_sn(1), gen_sn(0), FALSE,2); - count(2) <= count(2) + 1; + inc_count(2); wait_on_sig(out_check_done); wait_on_idle; @@ -617,7 +641,7 @@ begin push_hb(e4, gen_sn(4), gen_sn(3), TRUE,1); push_hb(e1, gen_sn(4), gen_sn(3), TRUE,1); push_hb(e0, gen_sn(4), gen_sn(3), TRUE,1); - count(1) <= count(1) + 1; + inc_count(1); wait_on_sig(out_check_done); wait_on_idle; diff --git a/src/ros2/Tests/Level_2/L2_Fibonacci_ros_action_test1.vhd b/src/ros2/Tests/Level_2/L2_Fibonacci_ros_action_test1.vhd index 30ab1e7..04e66f9 100644 --- a/src/ros2/Tests/Level_2/L2_Fibonacci_ros_action_test1.vhd +++ b/src/ros2/Tests/Level_2/L2_Fibonacci_ros_action_test1.vhd @@ -299,7 +299,7 @@ begin watchdog : process begin - wait for 1 ms; + wait for 1.5 ms; Alert("Test timeout", FAILURE); std.env.stop; end process; diff --git a/src/rtps_writer.vhd b/src/rtps_writer.vhd index 377ba96..f635253 100644 --- a/src/rtps_writer.vhd +++ b/src/rtps_writer.vhd @@ -279,6 +279,8 @@ architecture arch of rtps_writer is signal gap_in_progress, gap_in_progress_next : std_logic; -- Signifies that the GAP is the Last Submessage signal gap_is_last, gap_is_last_next : std_logic; + -- Signifies that an initial Heartbeat is sent to a remote Endpoint + signal initial_heartbeat_next, initial_heartbeat : std_logic; -- Signal containing the RTPS Heartbeat Count Field signal count, count_next : HEARTBEAT_COUNT_ARRAY; -- Signal containing the lowest common Sequence Number ACKed by ALL remote Readers @@ -546,6 +548,7 @@ begin last_seq_nr_next <= last_seq_nr; new_push_next <= new_push; historical_push_next <= historical_push; + initial_heartbeat_next <= initial_heartbeat; assert_liveliness_latch_next<= assert_liveliness_latch; w_assert_liveliness_next <= w_assert_liveliness; bitmap_cnt_next <= bitmap_cnt; @@ -967,81 +970,126 @@ begin if (mem_op_done = '1') then case (meta_opcode) is when EMO_ENDPOINT_MATCH => - -- Endpoint already in Memory - if (mem_endpoint_data.addr /= ENDPOINT_MEMORY_MAX_ADDRESS) then - -- Update the Endpoint Data - -- NOTE: The Lease is NOT renewed in case of an update. That is the responsibility of the Liveliness Update - mem_op_start <= '1'; - mem_opcode <= UPDATE_ENDPOINT; - mem_r.i <= ind; - mem_r.addr <= mem_endpoint_data.addr; - mem_r.field_flags <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG; - mem_r.ip_addr <= addr; - mem_r.portn <= portn; - mem_r.reader_flags <= reader_flags; - - -- Continue - stage_next <= INITIATE_ENDPOINT_SEARCH; - cnt_next <= 1; -- GET NEXT WRITER - -- Endpoint Memory Full - elsif (mem_empty_head(ind) = ENDPOINT_MEMORY_MAX_ADDRESS) then - -- Ignore - stage_next <= INITIATE_ENDPOINT_SEARCH; - cnt_next <= 1; -- GET NEXT WRITER - else - assert stable(clk, mem_empty_head(ind) /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; - - -- Insert Matched Remote Endpoint - mem_op_start <= '1'; - mem_opcode <= INSERT_ENDPOINT; - mem_r.i <= ind; - mem_r.guid <= guid; - mem_r.ip_addr <= addr; - mem_r.portn <= portn; - mem_r.reader_flags <= reader_flags; - - if (CONFIG_ARRAY_T(ind).RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and CONFIG_ARRAY_T(ind).LEASE_DURATION /= DURATION_INFINITE and reader_flags(READER_IS_BEST_EFFORT_FLAG) = '0') then - tmp_dw := time + CONFIG_ARRAY_T(ind).LEASE_DURATION; - mem_r.lease_deadline <= tmp_dw; + case (cnt) is + -- ENDPOINT MATCH + when 0 => + -- Endpoint already in Memory + if (mem_endpoint_data.addr /= ENDPOINT_MEMORY_MAX_ADDRESS) then + -- Update the Endpoint Data + -- NOTE: The Lease is NOT renewed in case of an update. That is the responsibility of the Liveliness Update + mem_op_start <= '1'; + mem_opcode <= UPDATE_ENDPOINT; + mem_r.i <= ind; + mem_r.addr <= mem_endpoint_data.addr; + mem_r.field_flags <= EMF_IPV4_ADDR_FLAG or EMF_UDP_PORT_FLAG; + mem_r.ip_addr <= addr; + mem_r.portn <= portn; + mem_r.reader_flags <= reader_flags; + + -- Continue + stage_next <= INITIATE_ENDPOINT_SEARCH; + cnt_next <= 1; -- GET NEXT WRITER + -- Endpoint Memory Full + elsif (mem_empty_head(ind) = ENDPOINT_MEMORY_MAX_ADDRESS) then + -- Ignore + stage_next <= INITIATE_ENDPOINT_SEARCH; + cnt_next <= 1; -- GET NEXT WRITER + else + assert stable(clk, mem_empty_head(ind) /= ENDPOINT_MEMORY_MAX_ADDRESS) severity FAILURE; + + -- Insert Matched Remote Endpoint + mem_op_start <= '1'; + mem_opcode <= INSERT_ENDPOINT; + mem_r.i <= ind; + mem_r.guid <= guid; + mem_r.ip_addr <= addr; + mem_r.portn <= portn; + mem_r.reader_flags <= reader_flags; + + if (CONFIG_ARRAY_T(ind).RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS and CONFIG_ARRAY_T(ind).LEASE_DURATION /= DURATION_INFINITE and reader_flags(READER_IS_BEST_EFFORT_FLAG) = '0') then + tmp_dw := time + CONFIG_ARRAY_T(ind).LEASE_DURATION; + mem_r.lease_deadline <= tmp_dw; + + -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) + -- Update Check Time + if (tmp_dw < check_time) then + check_time_next <= tmp_dw; + end if; + else + mem_r.lease_deadline <= TIME_INVALID; + end if; + -- Initialize ACK Sequence Number + if (CONFIG_ARRAY_T(ind).RELIABILITY_QOS /= RELIABLE_RELIABILITY_QOS or reader_flags(READER_IS_BEST_EFFORT_FLAG) = '1') then + mem_r.ack_seq_nr_base <= SEQUENCENUMBER_UNKNOWN; + elsif (CONFIG_ARRAY_T(ind).DURABILITY_QOS /= VOLATILE_DURABILITY_QOS and reader_flags(READER_EXPECTS_HISTORICAL_DATA_FLAG) = '1') then + mem_r.ack_seq_nr_base <= ZERO_SEQUENCENUMBER; + -- Initialize Global ACK + if (global_ack_seq_nr_base(ind) = SEQUENCENUMBER_UNKNOWN) then + global_ack_seq_nr_base_next(ind) <= ZERO_SEQUENCENUMBER; + end if; + else + mem_r.ack_seq_nr_base <= last_seq_nr(ind); + -- Initialize Global ACK + if (global_ack_seq_nr_base(ind) = SEQUENCENUMBER_UNKNOWN) then + global_ack_seq_nr_base_next(ind) <= last_seq_nr(ind); + end if; + end if; + + if (CONFIG_ARRAY_T(ind).RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS) then + cnt_next <= cnt + 1; + else + cnt_next <= 3; -- POST-HEARTBEAT + end if; + end if; + -- GET MIN_SN + when 1 => + start_hc(ind) <= '1'; + opcode_hc(ind) <= GET_MIN_SN; - -- XXX: Possible Worst Case Path (64-bit addition and comparison in same clock) - -- Update Check Time - if (tmp_dw < check_time) then - check_time_next <= tmp_dw; + if (ack_hc(ind) = '1') then + -- Increment Heartbeat Count + count_next(ind) <= count(ind) + 1; + + cnt_next <= cnt + 1; end if; - else - mem_r.lease_deadline <= TIME_INVALID; - end if; - -- Initialize ACK Sequence Number - if (CONFIG_ARRAY_T(ind).RELIABILITY_QOS /= RELIABLE_RELIABILITY_QOS or reader_flags(READER_IS_BEST_EFFORT_FLAG) = '1') then - mem_r.ack_seq_nr_base <= SEQUENCENUMBER_UNKNOWN; - elsif (CONFIG_ARRAY_T(ind).DURABILITY_QOS /= VOLATILE_DURABILITY_QOS and reader_flags(READER_EXPECTS_HISTORICAL_DATA_FLAG) = '1') then - mem_r.ack_seq_nr_base <= ZERO_SEQUENCENUMBER; - -- Initialize Global ACK - if (global_ack_seq_nr_base(ind) = SEQUENCENUMBER_UNKNOWN) then - global_ack_seq_nr_base_next(ind) <= ZERO_SEQUENCENUMBER; + -- SEND HEARTBEAT + when 2 => + -- Wait for HC + if (done_hc(ind) = '1') then + assert (ret_hc(ind) = OK) severity FAILURE; + + -- HC Empty (No cache Changes Available) + if (cc_seq_nr(ind) = SEQUENCENUMBER_UNKNOWN) then + -- NOTE: Identifies the lowest SN that is yet to be written by the writter. + min_sn_next <= last_seq_nr(ind) + 1; + else + min_sn_next <= cc_seq_nr(ind); + end if; + + -- Send Initial Heartbeat + initial_heartbeat_next <= '1'; + stage_next <= SEND_HEADER; + cnt_next <= 0; + return_stage_next <= SEND_HEARTBEAT; + return_cnt_next <= 0; end if; - else - mem_r.ack_seq_nr_base <= last_seq_nr(ind); - -- Initialize Global ACK - if (global_ack_seq_nr_base(ind) = SEQUENCENUMBER_UNKNOWN) then - global_ack_seq_nr_base_next(ind) <= last_seq_nr(ind); + -- POST-HEARTBEAT + when 3 => + -- Reader needs Historical Data + if (CONFIG_ARRAY_T(ind).DURABILITY_QOS /= VOLATILE_DURABILITY_QOS and reader_flags(READER_EXPECTS_HISTORICAL_DATA_FLAG) = '1') then + -- Send Historical Data + historical_push_next <= '1'; + + stage_next <= HANDLE_HISTORICAL; + cnt_next <= 0; -- GET MIN_SN + else + -- Continue + stage_next <= INITIATE_ENDPOINT_SEARCH; + cnt_next <= 1; -- GET NEXT WRITER end if; - end if; - - -- Reader needs Historical Data - if (CONFIG_ARRAY_T(ind).DURABILITY_QOS /= VOLATILE_DURABILITY_QOS and reader_flags(READER_EXPECTS_HISTORICAL_DATA_FLAG) = '1') then - -- Send Historical Data - historical_push_next <= '1'; - - stage_next <= HANDLE_HISTORICAL; - cnt_next <= 0; -- GET MIN_SN - else - -- Continue - stage_next <= INITIATE_ENDPOINT_SEARCH; - cnt_next <= 1; -- GET NEXT WRITER - end if; - end if; + when others => + null; + end case; when EMO_ENDPOINT_UNMATCH => -- Endpoint not in Memory @@ -1605,8 +1653,6 @@ begin end case; end if; when HANDLE_HEARTBEATS => - assert (CONFIG_ARRAY_T(ind).RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS or CONFIG_ARRAY_T(ind).LIVELINESS_QOS = MANUAL_BY_TOPIC_LIVELINESS_QOS) severity FAILURE; - -- Memory Operation Guard if (mem_op_done = '1') then case (cnt) is @@ -1628,6 +1674,8 @@ begin -- GET MIN_SN when 1 => if (w_map(ind) = '1') then + assert (CONFIG_ARRAY_T(ind).RELIABILITY_QOS = RELIABLE_RELIABILITY_QOS or CONFIG_ARRAY_T(ind).LIVELINESS_QOS = MANUAL_BY_TOPIC_LIVELINESS_QOS) severity FAILURE; + start_hc(ind) <= '1'; opcode_hc(ind) <= GET_MIN_SN; @@ -2449,8 +2497,18 @@ begin data_out_ro <= std_logic_vector(count(ind)); last_word_out_ro <= '1'; - stage_next <= HANDLE_HEARTBEATS; - cnt_next <= 5; -- GET NEXT Endpoint + if (initial_heartbeat = '1') then + assert (meta_opcode = EMO_ENDPOINT_MATCH) severity FAILURE; + + -- Reset + initial_heartbeat_next <= '0'; + + stage_next <= METATRAFFIC_OPERATION; + cnt_next <= 3; -- POST-HEARTBEAT + else + stage_next <= HANDLE_HEARTBEATS; + cnt_next <= 5; -- GET NEXT Endpoint + end if; when others => null; end case; @@ -3957,6 +4015,7 @@ begin gap_in_progress <= '0'; new_push <= '0'; historical_push <= '0'; + initial_heartbeat <= '0'; assert_liveliness_latch <= (others => '0'); w_assert_liveliness <= (others => '0'); bitmap_cnt <= (others => '0'); @@ -4005,6 +4064,7 @@ begin gap_in_progress <= gap_in_progress_next; new_push <= new_push_next; historical_push <= historical_push_next; + initial_heartbeat <= initial_heartbeat_next; bitmap_cnt <= bitmap_cnt_next; assert_liveliness_latch <= assert_liveliness_latch_next; w_assert_liveliness <= w_assert_liveliness_next;