diff --git a/sim/L1_rtps_writer_test2_vrkdn.do b/sim/L1_rtps_writer_test2_vrkdn.do new file mode 100644 index 0000000..502080d --- /dev/null +++ b/sim/L1_rtps_writer_test2_vrkdn.do @@ -0,0 +1,86 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate -divider SYSTEM +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/clk +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/reset +add wave -noupdate -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/time +add wave -noupdate -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/heartbeat_time +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/assert_liveliness +add wave -noupdate -divider INPUT +add wave -noupdate -group META /l1_rtps_writer_test2_vrkdn/uut/empty_meta +add wave -noupdate -group META /l1_rtps_writer_test2_vrkdn/uut/rd_meta +add wave -noupdate -group META /l1_rtps_writer_test2_vrkdn/uut/last_word_in_meta +add wave -noupdate -group META -radix hexadecimal /l1_rtps_writer_test2_vrkdn/uut/data_in_meta +add wave -noupdate -group USER /l1_rtps_writer_test2_vrkdn/uut/empty_user +add wave -noupdate -group USER /l1_rtps_writer_test2_vrkdn/uut/rd_user +add wave -noupdate -group USER -radix hexadecimal /l1_rtps_writer_test2_vrkdn/uut/data_in_user +add wave -noupdate -group USER /l1_rtps_writer_test2_vrkdn/uut/last_word_in_user +add wave -noupdate -divider HC +add wave -noupdate -expand -group HC /l1_rtps_writer_test2_vrkdn/uut/data_available +add wave -noupdate -expand -group HC /l1_rtps_writer_test2_vrkdn/uut/start_hc +add wave -noupdate -expand -group HC /l1_rtps_writer_test2_vrkdn/uut/opcode_hc +add wave -noupdate -expand -group HC /l1_rtps_writer_test2_vrkdn/uut/ack_hc +add wave -noupdate -expand -group HC -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/seq_nr_hc +add wave -noupdate -expand -group HC /l1_rtps_writer_test2_vrkdn/uut/done_hc +add wave -noupdate -expand -group HC /l1_rtps_writer_test2_vrkdn/uut/ret_hc +add wave -noupdate -expand -group HC -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/cc_seq_nr +add wave -noupdate -divider OUTPUT +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/full_rtps +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/wr_rtps +add wave -noupdate -radix hexadecimal /l1_rtps_writer_test2_vrkdn/uut/data_out_rtps +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/last_word_out_rtps +add wave -noupdate /l1_rtps_writer_test2_vrkdn/rtps_out_inst/wr +add wave -noupdate -radix hexadecimal /l1_rtps_writer_test2_vrkdn/rtps_out_inst/data_out +add wave -noupdate -divider {MAIN FSM} +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/stage +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/stage_next +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/cnt +add wave -noupdate -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/last_seq_nr +add wave -noupdate -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/global_ack_seq_nr_base +add wave -noupdate -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/next_seq_nr +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/assert_liveliness_latch +add wave -noupdate -divider {MEMORY FSM} +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/mem_op_done +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/mem_op_start +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/mem_opcode +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/mem_stage +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/mem_stage_next +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/mem_cnt +add wave -noupdate /l1_rtps_writer_test2_vrkdn/uut/mem_pos +add wave -noupdate -radix unsigned -childformat {{/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(6) -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(5) -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(4) -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(3) -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(2) -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(1) -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(0) -radix unsigned}} -subitemconfig {/l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(6) {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(5) {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(4) {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(3) {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(2) {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(1) {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_addr_base(0) {-height 15 -radix unsigned}} /l1_rtps_writer_test2_vrkdn/uut/mem_addr_base +add wave -noupdate -childformat {{/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.guid -radix hexadecimal} {/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.addr -radix hexadecimal} {/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.portn -radix hexadecimal} {/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.lease_deadline -radix hexadecimal} {/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.res_time -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.ack_seq_nr_base -radix unsigned} {/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.req_seq_nr_base -radix unsigned}} -subitemconfig {/l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.guid {-height 15 -radix hexadecimal} /l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.addr {-height 15 -radix hexadecimal} /l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.portn {-height 15 -radix hexadecimal} /l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.lease_deadline {-height 15 -radix hexadecimal} /l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.res_time {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.ack_seq_nr_base {-height 15 -radix unsigned} /l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data.req_seq_nr_base {-height 15 -radix unsigned}} /l1_rtps_writer_test2_vrkdn/uut/mem_endpoint_data +add wave -noupdate -group MEM_CTRL -radix unsigned /l1_rtps_writer_test2_vrkdn/uut/mem_addr +add wave -noupdate -group MEM_CTRL /l1_rtps_writer_test2_vrkdn/uut/mem_valid_in +add wave -noupdate -group MEM_CTRL /l1_rtps_writer_test2_vrkdn/uut/mem_ready_in +add wave -noupdate -group MEM_CTRL /l1_rtps_writer_test2_vrkdn/uut/mem_read +add wave -noupdate -group MEM_CTRL -radix hexadecimal /l1_rtps_writer_test2_vrkdn/uut/mem_write_data +add wave -noupdate -group MEM_CTRL /l1_rtps_writer_test2_vrkdn/uut/abort_read +add wave -noupdate -group MEM_CTRL /l1_rtps_writer_test2_vrkdn/uut/mem_valid_out +add wave -noupdate -group MEM_CTRL /l1_rtps_writer_test2_vrkdn/uut/mem_ready_out +add wave -noupdate -group MEM_CTRL -radix hexadecimal /l1_rtps_writer_test2_vrkdn/uut/mem_read_data +add wave -noupdate -divider TESTBENCH +add wave -noupdate -group TESTBENCH /l1_rtps_writer_test2_vrkdn/start_meta +add wave -noupdate -group TESTBENCH /l1_rtps_writer_test2_vrkdn/packet_sent_meta +add wave -noupdate -group TESTBENCH /l1_rtps_writer_test2_vrkdn/stage_hc +add wave -noupdate -group TESTBENCH /l1_rtps_writer_test2_vrkdn/out_check_done +add wave -noupdate -group TESTBENCH /l1_rtps_writer_test2_vrkdn/stim_done +add wave -noupdate -group TESTBENCH /l1_rtps_writer_test2_vrkdn/test_done +add wave -noupdate -divider MISC +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {Begin {49575000 ps} 1} {Error {7325000 ps} 1} {Cursor {12825000 ps} 0} +quietly wave cursor active 3 +configure wave -namecolwidth 150 +configure wave -valuecolwidth 135 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +configure wave -timelineunits ns +update +WaveRestoreZoom {12324048 ps} {13325952 ps} diff --git a/src/Tests/Level_1/L1_rtps_writer_test2_vrkdn.vhd b/src/Tests/Level_1/L1_rtps_writer_test2_vrkdn.vhd new file mode 100644 index 0000000..86a36c1 --- /dev/null +++ b/src/Tests/Level_1/L1_rtps_writer_test2_vrkdn.vhd @@ -0,0 +1,692 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library osvvm; -- Utility Library +context osvvm.OsvvmContext; + +use work.rtps_package.all; +use work.user_config.all; +use work.rtps_config_package.all; +use work.rtps_test_package.all; + +-- This testbench tests the RTPS Message generation of the RTPS Writer (HEARTBEAT Generation). +-- This testbench covers following: +-- * (Best Effort/Transient Local/Expecting Inline Qos) Remote Readers +-- * HEARTBEAT Handling +-- * Manual By Topic Liveliness Assertion + +entity L1_rtps_writer_test2_vrkdn is +end entity; + +architecture testbench of L1_rtps_writer_test2_vrkdn is + + -- *CONSTANT DECLARATION* + constant MAX_REMOTE_ENDPOINTS : natural := 5; + constant MAX_CC : natural := 10; + + -- *TYPE DECLARATION* + type SEND_STAGE_TYPE is (IDLE, BUSY); + type TEST_CC_ARRAY_TYPE is array (0 to MAX_CC-1) of CACHE_CHANGE_TYPE; + type HC_STAGE_TYPE is (IDLE, DONE); + + -- *SIGNAL DECLARATION* + signal clk, empty_user, empty_meta, rd_meta, last_word_in_meta, last_word_in_hc, last_word_out_rtps : std_logic := '0'; + signal reset : std_logic := '1'; + signal data_in_meta, data_out, data_in_hc : std_logic_vector(WORD_WIDTH-1 downto 0) := (others => '0'); + signal wr_sig, full, data_available, assert_liveliness : std_logic := '0'; + signal ready_in_hc, valid_in_hc, ack_hc, done_hc, get_data_hc, start_hc : std_logic := '0'; + signal seq_nr_hc : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN; + signal stim_stage_meta : SEND_STAGE_TYPE := IDLE; + signal opcode_hc : HISTORY_CACHE_OPCODE_TYPE := NOP; + signal ret_hc : HISTORY_CACHE_RESPONSE_TYPE := ERROR; + signal cc_instance_handle : INSTANCE_HANDLE_TYPE := HANDLE_NIL; + signal cc_kind : CACHE_CHANGE_KIND_TYPE := ALIVE; + signal cc_source_timestamp : TIME_TYPE := TIME_INVALID; + signal cc_seq_nr : SEQUENCENUMBER_TYPE := SEQUENCENUMBER_UNKNOWN; + shared variable stimulus_meta, reference : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; + signal packet_sent_meta : std_logic := '0'; + signal cnt_stim_meta, count : natural := 0; + signal start_meta : std_logic := '0'; + shared variable SB_out : osvvm.ScoreBoardPkg_slv.ScoreBoardPType; + signal stim_done, out_check_done, test_done : std_logic := '0'; + signal test_time : TIME_TYPE := TIME_ZERO; + signal fifo_in, fifo_out : std_logic_vector(WORD_WIDTH downto 0) := (others => '0'); + signal fifo_wr, fifo_empty, fifo_full : std_logic := '0'; + signal rtps_out_data : RTPS_OUT_DATA_TYPE := (others => (others => '0')); + 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_TYPE := (others => DEFAULT_CACHE_CHANGE); + -- Signal containing the current fill level of the test_cc array + signal test_cc_fill : natural := 0; + signal stage_hc : HC_STAGE_TYPE := IDLE; + signal new_cc : std_logic := '0'; + signal cnt : natural := 0; + + -- *FUNCTION DECLARATION* + function gen_sn(input : natural) return SEQUENCENUMBER_TYPE is + variable ret : SEQUENCENUMBER_TYPE; + begin + ret(0) := (others => '0'); + ret(1) := unsigned(int(input, WORD_WIDTH)); + return ret; + end function; + +begin + + -- Unit Under Test + uut : entity work.rtps_writer(arch) + generic map ( + RELIABILTY_QOS => RELIABLE_RELIABILITY_QOS, + LIVELINESS_QOS => MANUAL_BY_TOPIC_LIVELINESS_QOS, + DURABILITY_QOS => VOLATILE_DURABILITY_QOS, + DESTINATION_ORDER_QOS => BY_RECEPTION_TIMESTAMP_DESTINATION_ORDER_QOS, + ACKNACK_RESPONSE_DELAY => DURATION_ZERO, + ACKNACK_SUPPRESSION_DELAY => DURATION_ZERO, + LEASE_DURATION => DURATION_INFINITE, + HEARTBEAT_PERIOD => gen_duration(1,0), + ENTITYID => DEFAULT_WRITER_ENTITYID, + WITH_KEY => TRUE, + PUSH_MODE => FALSE, + INLINE_QOS => gen_inline_qos(NUM_READERS+7), + MAX_REMOTE_ENDPOINTS => MAX_REMOTE_ENDPOINTS + ) + port map ( + clk => clk, + reset => reset, + time => test_time, + empty_user => '1', + rd_user => open, + data_in_user => (others => '0'), + last_word_in_user => '0', + empty_meta => empty_meta or packet_sent_meta, + rd_meta => rd_meta, + data_in_meta => data_in_meta, + last_word_in_meta => last_word_in_meta, + alive_sig => open, + wr_rtps => fifo_wr, + full_rtps => fifo_full, + last_word_out_rtps => fifo_in(WORD_WIDTH), + data_out_rtps => fifo_in(WORD_WIDTH-1 downto 0), + assert_liveliness => assert_liveliness, + data_available => data_available, + start_hc => start_hc, + opcode_hc => opcode_hc, + ack_hc => ack_hc, + seq_nr_hc => seq_nr_hc, + done_hc => done_hc, + ret_hc => ret_hc, + get_data_hc => get_data_hc, + data_in_hc => data_in_hc, + valid_in_hc => valid_in_hc, + ready_in_hc => ready_in_hc, + last_word_in_hc => last_word_in_hc, + cc_instance_handle => cc_instance_handle, + cc_kind => cc_kind, + cc_source_timestamp => cc_source_timestamp, + cc_seq_nr => cc_seq_nr + ); + + fifo_inst : entity work.FWFT_FIFO(arch) + generic map ( + FIFO_DEPTH => 2, + DATA_WIDTH => WORD_WIDTH+1 + ) + port map + ( + reset => reset, + clk => clk, + data_in => fifo_in, + write => fifo_wr, + read => rtps_out_rd(0), + data_out => fifo_out, + empty => fifo_empty, + full => fifo_full, + free => open + ); + + rtps_out_data <= (0 => fifo_out(WORD_WIDTH-1 downto 0), others => (others => '0')); + rtps_out_last_word_in <= (0 => fifo_out(WORD_WIDTH), others => '0'); + rtps_out_empty <= (0 => fifo_empty, others => '1'); + + rtps_out_inst : entity work.rtps_out(arch) + port map ( + clk => clk, + reset => reset, + data_in => rtps_out_data, + last_word_in=> rtps_out_last_word_in, + rd => rtps_out_rd, + empty => rtps_out_empty, + data_out => data_out, + wr => wr_sig, + full => full + ); + + + stimulus_prc : process + variable RV : RandomPType; + variable e0, e1, e2, e3, e4, endpoint : ENDPOINT_DATA_TYPE := DEFAULT_ENDPOINT_DATA; + variable sub : RTPS_SUBMESSAGE_TYPE := DEFAULT_RTPS_SUBMESSAGE; + variable cc : CACHE_CHANGE_TYPE := DEFAULT_CACHE_CHANGE; + variable OUT_HEADER : OUTPUT_HEADER_TYPE := DEFAULT_OUTPUT_HEADER; + variable rtps_header : RTPS_HEADER_TYPE := DEFAULT_RTPS_HEADER; + + alias idle_sig is <>; + + -- Wrapper to use procedure as function + impure function gen_rand_loc_2 return LOCATOR_TYPE is + variable ret : LOCATOR_TYPE := EMPTY_LOCATOR; + begin + gen_rand_loc(RV, ret); + return ret; + end function; + + impure function gen_rand_entityid_2(reader : boolean) return std_logic_vector is + variable ret : std_logic_vector(ENTITYID_WIDTH-1 downto 0) := (others => '0'); + begin + gen_rand_entityid(RV, reader, ret); + return ret; + end function; + + impure function gen_rand_guid_prefix return GUIDPREFIX_TYPE is + variable ret : GUIDPREFIX_TYPE; + begin + ret := (0 => RV.RandSlv(WORD_WIDTH), 1 => RV.RandSlv(WORD_WIDTH), 2 => RV.RandSlv(WORD_WIDTH)); + return ret; + end function; + + impure function gen_key_hash return KEY_HASH_TYPE is + variable ret : KEY_HASH_TYPE := (others => (others => '0')); + begin + for i in 0 to KEY_HASH_TYPE'length-1 loop + ret(i) := RV.RandSlv(WORD_WIDTH); + end loop; + return ret; + end function; + + impure function gen_payload return TEST_PACKET_TYPE is + variable ret : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; + begin + for i in 0 to RV.RandInt(1,10) loop + ret.data(ret.length) := RV.RandSlv(WORD_WIDTH); + ret.length := ret.length + 1; + end loop; + ret.last(ret.length-1) := '1'; + return ret; + end function; + + procedure start_meta_test is + begin + start_meta <= '1'; + wait until rising_edge(clk); + start_meta <= '0'; + wait until rising_edge(clk); + end procedure; + + procedure wait_on_meta_sent is + begin + wait until rising_edge(packet_sent_meta); + end procedure; + + procedure wait_on_out_check is + begin + if (out_check_done /= '1') then + wait until out_check_done = '1'; + end if; + end procedure; + + procedure wait_on_completion is + begin + if (test_done /= '1') then + wait until test_done = '1'; + end if; + end procedure; + + procedure wait_on_idle is + begin + if (idle_sig /= '1') then + wait until idle_sig = '1'; + end if; + end procedure; + + procedure push_hb(endpoint : in ENDPOINT_DATA_TYPE; first : in SEQUENCENUMBER_TYPE; last : in SEQUENCENUMBER_TYPE; assert_liveliness : in boolean) 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 := DEFAULT_WRITER_ENTITYID; + sub.readerId := ENTITYID_UNKNOWN; + sub.firstSN := first; + sub.lastSN := last; + sub.flags(SUBMESSAGE_LIVELINESS_FLAG_POS) := '1' when (assert_liveliness) else '0'; + sub.count := std_logic_vector(to_unsigned(count, CDR_LONG_WIDTH)); + 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; + + begin + + SetAlertLogName("rtps_writer (Volatile, Reliable, Keyed, By Reception Timestamp, Pull Mode) - Level 1 - RTPS Output (HEARTBEAT)"); + SetAlertEnable(FAILURE, TRUE); + SetAlertEnable(ERROR, TRUE); + SetAlertEnable(WARNING, TRUE); + SetLogEnable(DEBUG, FALSE); + SetLogEnable(PASSED, FALSE); + SetLogEnable(INFO, TRUE); + RV.InitSeed(RV'instance_name); + + -- Endpoint 0 + e0 := DEFAULT_ENDPOINT_DATA; + e0.nr := 0; + e0.match := MATCH; + e0.entityid := RV.RandSlv(ENTITYID_WIDTH); + e0.participant.guidPrefix := gen_rand_guid_prefix; + e0.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + -- Endpoint 1 + e1 := DEFAULT_ENDPOINT_DATA; + e1.nr := 1; + e1.match := MATCH; + e1.entityid := RV.RandSlv(ENTITYID_WIDTH); + e1.participant.guidPrefix := gen_rand_guid_prefix; + e1.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + e1.reliability := BEST_EFFORT_RELIABILITY_QOS; + -- Endpoint 2 + e2 := DEFAULT_ENDPOINT_DATA; + e2.nr := 2; + e2.match := MATCH; + e2.entityid := RV.RandSlv(ENTITYID_WIDTH); + e2.participant.guidPrefix := gen_rand_guid_prefix; + e2.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + e2.expectsInlineQoS(0) := '1'; + -- Endpoint 3 + e3 := DEFAULT_ENDPOINT_DATA; + e3.nr := 3; + e3.match := MATCH; + e3.entityid := RV.RandSlv(ENTITYID_WIDTH); + e3.participant.guidPrefix := gen_rand_guid_prefix; + e3.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + e3.durability := TRANSIENT_LOCAL_DURABILITY_QOS; + -- Endpoint 4 + e4 := DEFAULT_ENDPOINT_DATA; + e4.nr := 4; + e4.match := MATCH; + e4.entityid := RV.RandSlv(ENTITYID_WIDTH); + e4.participant.guidPrefix := gen_rand_guid_prefix; + e4.unicastLocatorList := (numLocators => int(1,CDR_LONG_WIDTH), locator => (0 => gen_rand_loc_2, others => EMPTY_LOCATOR)); + e4.expectsInlineQoS(0) := '1'; + e4.durability := TRANSIENT_LOCAL_DURABILITY_QOS; + e4.reliability := BEST_EFFORT_RELIABILITY_QOS; + + Log("Initiating Test", INFO); + Log("Current Time: 0s", INFO); + count <= 1; + test_time <= TIME_ZERO; + new_cc <= '0'; + stim_done <= '0'; + start_meta <= '0'; + assert_liveliness <= '0'; + reset <= '1'; + wait until rising_edge(clk); + wait until rising_edge(clk); + reset <= '0'; + + Log("Insert Endpoint 0,1", INFO); + gen_endpoint_match_frame(e0, stimulus_meta); + gen_endpoint_match_frame(e1, stimulus_meta); + start_meta_test; + wait_on_meta_sent; + stimulus_meta := EMPTY_TEST_PACKET; + wait_on_idle; + + Log("Current Time: 1s", INFO); + Log("Send HEARTBEAT to Endpoint 0,1", INFO); + test_time <= gen_duration(1,0); + wait until rising_edge(clk); + wait until rising_edge(clk); -- Allow idle_sig to go low + push_hb(e0, gen_sn(1), gen_sn(0), FALSE); + push_hb(e1, gen_sn(1), gen_sn(0), FALSE); + count <= count + 1; + wait_on_out_check; + wait_on_idle; + + Log("Add Cache Change [SN 1]", INFO); + test_cc(0).kind <= ALIVE; + test_cc(0).instance <= gen_key_hash; + test_cc(0).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(0).seq_nr <= gen_sn(1); + test_cc(0).src_timestamp <= gen_duration(1,0); + test_cc(0).payload <= gen_payload; + test_cc_fill <= 1; + new_cc <= '1'; + wait until rising_edge(clk); + new_cc <= '0'; + wait until rising_edge(clk); + + Log("Current Time: 2s", INFO); + Log("Send HEARTBEAT to Endpoint 0,1", INFO); + test_time <= gen_duration(2,0); + wait until rising_edge(clk); + wait until rising_edge(clk); -- Allow idle_sig to go low + push_hb(e0, gen_sn(1), gen_sn(1), FALSE); + push_hb(e1, gen_sn(1), gen_sn(1), FALSE); + count <= count + 1; + wait_on_out_check; + wait_on_idle; + + Log("Add Cache Change [SN 2,3], Assert Liveliness", INFO); + test_cc(1).kind <= ALIVE; + test_cc(1).instance <= gen_key_hash; + test_cc(1).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(1).seq_nr <= gen_sn(2); + test_cc(1).src_timestamp <= gen_duration(2,0); + test_cc(1).payload <= gen_payload; + test_cc(2).kind <= ALIVE; + test_cc(2).instance <= gen_key_hash; + test_cc(2).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(2).seq_nr <= gen_sn(3); + test_cc(2).src_timestamp <= gen_duration(3,0); + test_cc(2).payload <= gen_payload; + test_cc_fill <= 3; + new_cc <= '1'; + assert_liveliness <= '1'; + wait until rising_edge(clk); + new_cc <= '0'; + assert_liveliness <= '0'; + wait until rising_edge(clk); + + Log("Send HEARTBEAT to Endpoint 0,1 [Liveliness Flag]", INFO); + push_hb(e0, gen_sn(1), gen_sn(3), TRUE); + push_hb(e1, gen_sn(1), gen_sn(3), TRUE); + count <= count + 1; + wait_on_out_check; + wait_on_idle; + + Log("Insert Endpoint 2,3", INFO); + gen_endpoint_match_frame(e2, stimulus_meta); + gen_endpoint_match_frame(e3, stimulus_meta); + start_meta_test; + wait_on_meta_sent; + stimulus_meta := EMPTY_TEST_PACKET; + wait_on_idle; + + Log("Current Time: 3s", INFO); + Log("Send HEARTBEAT to Endpoint 0,1,2,3 [Liveliness Flag]", INFO); + test_time <= gen_duration(3,0); + wait until rising_edge(clk); + wait until rising_edge(clk); -- Allow idle_sig to go low + push_hb(e0, gen_sn(1), gen_sn(3), FALSE); + push_hb(e1, gen_sn(1), gen_sn(3), FALSE); + push_hb(e2, gen_sn(1), gen_sn(3), FALSE); + push_hb(e3, gen_sn(1), gen_sn(3), FALSE); + count <= count + 1; + wait_on_out_check; + wait_on_idle; + + Log("Insert Endpoint 4", INFO); + gen_endpoint_match_frame(e4, stimulus_meta); + start_meta_test; + wait_on_meta_sent; + stimulus_meta := EMPTY_TEST_PACKET; + wait_on_idle; + + Log("Add Cache Change [SN 10,11,15,46,50], Remove Cache Change [SN 1,2,3]", INFO); + test_cc(0).kind <= ALIVE; + test_cc(0).instance <= gen_key_hash; + test_cc(0).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(0).seq_nr <= gen_sn(10); + test_cc(0).src_timestamp <= gen_duration(5,0); + test_cc(0).payload <= gen_payload; + test_cc(1).kind <= NOT_ALIVE_DISPOSED; + test_cc(1).instance <= gen_key_hash; + test_cc(1).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(1).seq_nr <= gen_sn(11); + test_cc(1).src_timestamp <= gen_duration(6,0); + test_cc(1).payload <= gen_payload; + test_cc(2).kind <= NOT_ALIVE_UNREGISTERED; + test_cc(2).instance <= gen_key_hash; + test_cc(2).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(2).seq_nr <= gen_sn(15); + test_cc(2).src_timestamp <= gen_duration(7,0); + test_cc(2).payload <= gen_payload; + test_cc(3).kind <= NOT_ALIVE_DISPOSED; + test_cc(3).instance <= gen_key_hash; + test_cc(3).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(3).seq_nr <= gen_sn(37); + test_cc(3).src_timestamp <= gen_duration(8,0); + test_cc(3).payload <= gen_payload; + test_cc(4).kind <= ALIVE; + test_cc(4).instance <= gen_key_hash; + test_cc(4).writer_guid <= to_guid(GUIDPREFIX, DEFAULT_WRITER_ENTITYID); + test_cc(4).seq_nr <= gen_sn(50); + test_cc(4).src_timestamp <= gen_duration(9,0); + test_cc(4).payload <= gen_payload; + test_cc_fill <= 5; + new_cc <= '1'; + wait until rising_edge(clk); + new_cc <= '0'; + wait until rising_edge(clk); + + Log("Current Time: 4s", INFO); + Log("Send HEARTBEAT to Endpoint 0,1,2,3,4", INFO); + test_time <= gen_duration(4,0); + wait until rising_edge(clk); + wait until rising_edge(clk); -- Allow idle_sig to go low + push_hb(e0, gen_sn(10), gen_sn(50), FALSE); + push_hb(e1, gen_sn(10), gen_sn(50), FALSE); + push_hb(e2, gen_sn(10), gen_sn(50), FALSE); + push_hb(e3, gen_sn(10), gen_sn(50), FALSE); + push_hb(e4, gen_sn(10), gen_sn(50), FALSE); + count <= count + 1; + wait_on_out_check; + wait_on_idle; + + Log("Remove All Cache Changes", INFO); + test_cc_fill <= 0; + wait until rising_edge(clk); + wait until rising_edge(clk); + + Log("Current Time: 5s", INFO); + Log("Send HEARTBEAT to Endpoint 0,1,2,3,4", INFO); + test_time <= gen_duration(5,0); + wait until rising_edge(clk); + wait until rising_edge(clk); -- Allow idle_sig to go low + push_hb(e0, gen_sn(51), gen_sn(50), FALSE); + push_hb(e1, gen_sn(51), gen_sn(50), FALSE); + push_hb(e2, gen_sn(51), gen_sn(50), FALSE); + push_hb(e3, gen_sn(51), gen_sn(50), FALSE); + push_hb(e4, gen_sn(51), gen_sn(50), FALSE); + count <= count + 1; + wait_on_out_check; + wait_on_idle; + + Log("Assert Liveliness", INFO); + assert_liveliness <= '1'; + wait until rising_edge(clk); + assert_liveliness <= '0'; + wait until rising_edge(clk); + + Log("Send HEARTBEAT to Endpoint 0,1,2,3,4", INFO); + push_hb(e0, gen_sn(51), gen_sn(50), TRUE); + push_hb(e1, gen_sn(51), gen_sn(50), TRUE); + push_hb(e2, gen_sn(51), gen_sn(50), TRUE); + push_hb(e3, gen_sn(51), gen_sn(50), TRUE); + push_hb(e4, gen_sn(51), gen_sn(50), TRUE); + count <= count + 1; + wait_on_out_check; + wait_on_idle; + + stim_done <= '1'; + wait_on_completion; + TranscriptOpen(RESULTS_FILE, APPEND_MODE); + SetTranscriptMirror; + ReportAlerts; + TranscriptClose; + std.env.stop; + wait; + end process; + + clock_prc : process + begin + clk <= '0'; + wait for 25 ns; + clk <= '1'; + wait for 25 ns; + end process; + + empty_meta_prc : process + begin + empty_meta <= '0'; + wait until rd_meta = '1'; + wait until rising_edge(clk); + empty_meta <= '1'; + wait until rising_edge(clk); + end process; + + rtps_full_prc : process + begin + full <= '0'; + wait until wr_sig = '1'; + wait until rising_edge(clk); + full <= '1'; + wait until rising_edge(clk); + end process; + + alert_prc : process(all) + begin + if rising_edge(clk) then + alertif(empty_meta = '1' and rd_meta = '1', "Input FIFO read signal high while empty signal high (meta)", ERROR); + alertif(full = '1' and wr_sig = '1', "Output FIFO write signal high while full signal high", ERROR); + end if; + end process; + + input_meta_prc : process(all) + begin + data_in_meta <= stimulus_meta.data(cnt_stim_meta); + last_word_in_meta <= stimulus_meta.last(cnt_stim_meta); + + if rising_edge(clk) then + if (reset = '1') then + cnt_stim_meta <= 0; + stim_stage_meta <= IDLE; + packet_sent_meta <= '1'; + else + case (stim_stage_meta) is + when IDLE => + if (start_meta = '1' and stimulus_meta.length /= 0) then + stim_stage_meta <= BUSY; + packet_sent_meta <= '0'; + end if; + when BUSY => + if (rd_meta = '1') then + if (cnt_stim_meta = stimulus_meta.length-1) then + stim_stage_meta <= IDLE; + packet_sent_meta <= '1'; + cnt_stim_meta <= 0; + else + cnt_stim_meta <= cnt_stim_meta + 1; + end if; + end if; + end case; + end if; + end if; + end process; + + done_proc : process(clk) + begin + if rising_edge(clk) then + if (stim_done = '1' and SB_out.empty) then + test_done <= '1'; + else + test_done <= '0'; + end if; + end if; + end process; + + hc_prc : process (all) + variable stimulus : TEST_PACKET_TYPE := EMPTY_TEST_PACKET; + variable bool : boolean := FALSE; + begin + if (new_cc = '1') then + data_available <= '1'; + end if; + + if rising_edge(clk) then + case (stage_hc) is + when IDLE => + if (start_hc = '1') then + ack_hc <= '1'; + case (opcode_hc) is + when GET_MIN_SN => + stimulus := EMPTY_TEST_PACKET; + cc_seq_nr <= test_cc(0).seq_nr when (test_cc_fill /= 0) else SEQUENCENUMBER_UNKNOWN; + stage_hc <= DONE; + when GET_MAX_SN => + data_available <= '0'; + stimulus := EMPTY_TEST_PACKET; + cc_seq_nr <= test_cc(test_cc_fill-1).seq_nr when (test_cc_fill /= 0) else SEQUENCENUMBER_UNKNOWN; + stage_hc <= DONE; + when others => + Alert("Unexpected HC Operation.", FAILURE); + end case; + end if; + when DONE => + stage_hc <= IDLE; + when others => + null; + end case; + end if; + + -- DEFAULT + ack_hc <= '0'; + valid_in_hc <= '0'; + data_in_hc <= (others => '0'); + last_word_in_hc <= '0'; + done_hc <= '0'; + ret_hc <= ERROR; + + case (stage_hc) is + when IDLE => + if (start_hc = '1') then + ack_hc <= '1'; + end if; + when DONE => + done_hc <= '1'; + ret_hc <= OK; + when others => + null; + end case; + end process; + + output_check_prc : process(all) + begin + if (SB_out.empty) then + out_check_done <= '1'; + else + out_check_done <= '0'; + end if; + if rising_edge(clk) then + if (wr_sig = '1') then + SB_out.Check(data_out); + end if; + end if; + end process; + + watchdog : process + begin + wait for 1 ms; + Alert("Test timeout", FAILURE); + std.env.stop; + end process; + +end architecture; \ No newline at end of file diff --git a/src/Tests/testbench.pro b/src/Tests/testbench.pro index a8ebccb..859e66a 100644 --- a/src/Tests/testbench.pro +++ b/src/Tests/testbench.pro @@ -51,6 +51,7 @@ analyze Level_1/L1_rtps_writer_test1_vrndp.vhd analyze Level_1/L1_rtps_writer_test1_vrksp.vhd analyze Level_1/L1_rtps_writer_test1_vrkdn.vhd analyze Level_1/L1_rtps_writer_test1_trkdn.vhd +analyze Level_1/L1_rtps_writer_test2_vrkdn.vhd #simulate L0_rtps_handler_test1 #simulate L0_rtps_handler_test2 @@ -77,11 +78,12 @@ analyze Level_1/L1_rtps_writer_test1_trkdn.vhd #simulate L1_rtps_reader_test1_trk #simulate L0_rtps_writer_test1_vrkdp #simulate L0_rtps_writer_test1_vbkdp -simulate L1_rtps_writer_test1_vrkdp +#simulate L1_rtps_writer_test1_vrkdp #simulate L1_rtps_writer_test1_trkdp #simulate L1_rtps_writer_test1_tbkdp #simulate L1_rtps_writer_test1_vbkdp #simulate L1_rtps_writer_test1_vrndp #simulate L1_rtps_writer_test1_vrksp #simulate L1_rtps_writer_test1_vrkdn -#simulate L1_rtps_writer_test1_trkdn \ No newline at end of file +#simulate L1_rtps_writer_test1_trkdn +simulate L1_rtps_writer_test2_vrkdn \ No newline at end of file