diff --git a/applications/apertif/designs/apertif_unb1_correlator/tb/vhdl/tb_apertif_unb1_correlator_nodes.vhd b/applications/apertif/designs/apertif_unb1_correlator/tb/vhdl/tb_apertif_unb1_correlator_nodes.vhd index a9b61e4dcf44ab90f59071d728418b7a76ce0d7d..57c5a08e6b37384c57967d2a0637759bf2c417d6 100644 --- a/applications/apertif/designs/apertif_unb1_correlator/tb/vhdl/tb_apertif_unb1_correlator_nodes.vhd +++ b/applications/apertif/designs/apertif_unb1_correlator/tb/vhdl/tb_apertif_unb1_correlator_nodes.vhd @@ -23,18 +23,36 @@ -- Author: Eric Kooistra -- Purpose: Testbench for apertif_unb1_correlator_nodes -- Description: +-- This tb verifies: +-- +-- 1) p_mm_stimuli : set offload src MAC and dest MAC +-- p_mm_diag_data_buffer_output : verify offload src MAC, dest MAC, and +-- verify BSN timestamp, channel and beamlet +-- 2) p_mm_stimuli : set phasor waveform into BG and start BG +-- p_mm_diag_data_buffer_output :verify expected channel data at offload +-- interface for Fchan +-- 3) u_eth_statistics : verify number of offloaded visibility packet data +-- +-- Remark: +-- This tb is nearly equivalent to tb_node_apertif_unb1_correlator_processing_output.vhd, +-- but this tb uses MM file IO so it operates at the FPGA top level design. -- Usage: +-- > as 12 +-- > run -a +-- View dbg_* signals in Wave Window -LIBRARY IEEE, common_lib, unb1_board_lib, eth_lib, mm_lib, wpfb_lib; +LIBRARY IEEE, common_lib, unb1_board_lib, eth_lib, mm_lib, fft_lib, wpfb_lib; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; USE common_lib.common_pkg.ALL; USE common_lib.common_math_pkg.ALL; +USE common_lib.common_str_pkg.ALL; USE unb1_board_lib.unb1_board_pkg.ALL; USE mm_lib.mm_file_pkg.ALL; USE mm_lib.mm_file_unb_pkg.ALL; USE common_lib.tb_common_pkg.ALL; USE work.apertif_unb1_correlator_pkg.ALL; +USE fft_lib.fft_pkg.ALL; USE wpfb_lib.wpfb_pkg.ALL; ENTITY tb_apertif_unb1_correlator_nodes IS @@ -59,6 +77,12 @@ ARCHITECTURE tb OF tb_apertif_unb1_correlator_nodes IS CONSTANT c_fpga_nr : NATURAL := 5; -- FPGA 0:7 on a UniBoard, FPGA 0:3 = FN 0:3, FPGA 4:7 = BN 0:3 CONSTANT c_pn_nr : NATURAL := c_unb_nr * 8 + c_fpga_nr; -- Processing Node 0 : 127 CONSTANT c_pn_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_pn_nr, 8); + CONSTANT c_dst_mac_hi : INTEGER := 16#00001234#; + CONSTANT c_dst_mac_lo : INTEGER := 16#56789ABC#; + CONSTANT c_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := TO_UVEC(c_dst_mac_hi, 16) & TO_UVEC(c_dst_mac_lo, 32); -- = X"123456789ABC"; + CONSTANT c_src_mac_hi : INTEGER := 16#00228608#; + CONSTANT c_src_mac_lo : INTEGER := c_unb_nr * 256 + c_fpga_nr; + CONSTANT c_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := TO_UVEC(c_src_mac_hi, 32) & TO_UVEC(c_src_mac_lo, 16); -- = X"00228608" & unb & fpga; CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; @@ -103,7 +127,7 @@ ARCHITECTURE tb OF tb_apertif_unb1_correlator_nodes IS CONSTANT c_bg_block_size : NATURAL := c_frame_size; -- [mi] CONSTANT c_bg_nof_blocks_per_sync : NATURAL := c_nof_frames_per_sync; -- [bsn] = [ti], is 10 * 64 = 640 in tb, 12500 * 64 = 800000 on HW - CONSTANT c_bg_duty_cycle_gap : NATURAL := N_clk - c_frame_size * Q_interleave; + CONSTANT c_bg_duty_cycle_gap : NATURAL := 54; -- N_clk - c_frame_size * Q_interleave; CONSTANT c_bg_block_period : NATURAL := c_frame_size * Q_interleave + c_bg_duty_cycle_gap; CONSTANT c_bg_nof_clk_per_sync : NATURAL := c_nof_blocks_per_sync * c_bg_block_period; @@ -119,10 +143,21 @@ ARCHITECTURE tb OF tb_apertif_unb1_correlator_nodes IS c_phasor_ampl, g_phasor_freq, c_phasor_phase); + -- g_use_prefilter=TRUE, g_use_prefilter_ones=FALSE: (application coefficients) + -- . using hex/run_pfir_coeff_m_flat_hp_fircls1_8taps_64points_9b_1wb + CONSTANT c_exp_pfb_channel_vis_re : t_nat_natural_arr := (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 510760, 10, 0, 0, 0, 10, 0, 40, 0, 10, 10, 10, 10, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + CONSTANT c_exp_pfb_channel_vis_im : t_nat_natural_arr := (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); -- . correlator DUT input CONSTANT c_nof_tp : NATURAL := g_nof_pn * c_nof_10GbE_streams; -- number of telescope paths CONSTANT c_nof_visibilities : NATURAL := c_nof_tp * (c_nof_tp+1) / 2; + CONSTANT c_nof_visibility_streams : NATURAL := 1; -- . DUT output DB CONSTANT c_vis_header_size : NATURAL := 21; -- (pad(2) + eth(14) + ip(20) + udp(8) + app_id(16) + app_flags(24)) / 4 = 84 bytes / 4 = 21 words @@ -147,8 +182,28 @@ ARCHITECTURE tb OF tb_apertif_unb1_correlator_nodes IS -- Testbench SIGNAL i_tb_end : STD_LOGIC := '0'; SIGNAL tb_clk : STD_LOGIC := '0'; + SIGNAL bg_start_done : STD_LOGIC := '0'; SIGNAL eth_done : STD_LOGIC := '0'; + SIGNAL packet_done : STD_LOGIC := '0'; SIGNAL verify_done : STD_LOGIC := '0'; + + -- . read DB + SIGNAL rd_data_db : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); + SIGNAL dbg_v_addr : NATURAL; + SIGNAL dbg_c_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_dst_mac; + SIGNAL dbg_v_rd_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL dbg_c_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_src_mac; + SIGNAL dbg_v_rd_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL dbg_v_exp_beamlet : NATURAL; -- interleaved beamlet index + SIGNAL dbg_v_rd_beamlet : NATURAL; + SIGNAL dbg_v_exp_channel : NATURAL; -- channel index in visibility offload packet + SIGNAL dbg_v_rd_channel : NATURAL; + SIGNAL dbg_v_exp_timestamp : STD_LOGIC_VECTOR(63 DOWNTO 0); + SIGNAL dbg_v_rd_timestamp : STD_LOGIC_VECTOR(63 DOWNTO 0); + SIGNAL dbg_v_exp_vis_re : INTEGER; + SIGNAL dbg_v_exp_vis_im : INTEGER; + SIGNAL dbg_v_rd_vis_re : INTEGER; + SIGNAL dbg_v_rd_vis_im : INTEGER; -- DUT SIGNAL ext_clk : STD_LOGIC := '0'; @@ -245,33 +300,13 @@ BEGIN SI_FN_3_RX => no_si_fn_tx ); - -- Stop simulation using severity FAILURE - verify_done <= eth_done; - - proc_common_stop_simulation(g_tb_end, ext_clk, verify_done, i_tb_end); - - ------------------------------------------------------------------------------ - -- Verify proper DUT output using Ethernet packet statistics - ------------------------------------------------------------------------------ - u_eth_statistics : ENTITY eth_lib.eth_statistics - GENERIC MAP ( - g_runtime_nof_packets => c_eth_check_nof_packets, - g_runtime_timeout => c_eth_runtime_timeout, - g_check_nof_valid => TRUE, - g_check_nof_valid_ref => c_eth_check_nof_packets*c_eth_packet_size - ) - PORT MAP ( - eth_serial_in => eth_txp, - tb_end => eth_done - ); - ---------------------------------------------------------------------------- -- MM control ---------------------------------------------------------------------------- p_mm_stimuli : PROCESS CONSTANT c_mm_file_reg_dp_xonoff_output : STRING := mmf_unb_file_prefix(g_tb_index, c_unb_nr, c_fpga_nr) & "REG_DP_XONOFF_OUTPUT"; + CONSTANT c_mm_file_reg_dp_offload_tx_hdr_dat : STRING := mmf_unb_file_prefix(g_tb_index, c_unb_nr, c_fpga_nr) & "REG_DP_OFFLOAD_TX_HDR_DAT"; CONSTANT c_mm_file_reg_diag_data_buffer_output : STRING := mmf_unb_file_prefix(g_tb_index, c_unb_nr, c_fpga_nr) & "REG_DIAG_DATA_BUFFER_OUTPUT"; - CONSTANT c_mm_file_ram_diag_data_buffer_output : STRING := mmf_unb_file_prefix(g_tb_index, c_unb_nr, c_fpga_nr) & "RAM_DIAG_DATA_BUFFER_OUTPUT"; CONSTANT c_mm_file_reg_diag_bg_input : STRING := mmf_unb_file_prefix(g_tb_index, c_unb_nr, c_fpga_nr) & "REG_DIAG_BG_PROC_INPUT"; CONSTANT c_mm_file_ram_diag_bg_input : STRING := mmf_unb_file_prefix(g_tb_index, c_unb_nr, c_fpga_nr) & "RAM_DIAG_BG_PROC_INPUT"; BEGIN @@ -281,6 +316,10 @@ BEGIN -- Offload enable mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff_output, 0, 1, tb_clk); + -- Offload header write dst MAC just to check the MM address order (top down list is 36 DOWNTO 0) + mmf_mm_bus_wr(c_mm_file_reg_dp_offload_tx_hdr_dat, 35, c_dst_mac_hi, tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_dp_offload_tx_hdr_dat, 34, c_dst_mac_lo, tb_clk); + -- Arm output DB mmf_mm_bus_wr(c_mm_file_reg_diag_data_buffer_output, 3, c_db_sync_delay, tb_clk); IF c_db_sync_delay>0 THEN @@ -296,8 +335,217 @@ BEGIN -- Start the BG mmf_mm_bus_wr(c_mm_file_reg_diag_bg_input, 3, c_bg_duty_cycle_gap, tb_clk); -- gap mmf_mm_bus_wr(c_mm_file_reg_diag_bg_input, 0, 1, tb_clk); -- enable - + bg_start_done <= '1'; + WAIT; + END PROCESS; + + ------------------------------------------------------------------------------ + -- Verify packet header using output DB + ------------------------------------------------------------------------------ + p_mm_diag_data_buffer_output : PROCESS + CONSTANT c_mm_file_ram_diag_data_buffer_output : STRING := mmf_unb_file_prefix(g_tb_index, c_unb_nr, c_fpga_nr) & "RAM_DIAG_DATA_BUFFER_OUTPUT"; + VARIABLE v_addr : NATURAL; + VARIABLE v_rd_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + VARIABLE v_rd_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + VARIABLE v_rd_beamlet : NATURAL; + VARIABLE v_rd_channel : NATURAL; + VARIABLE v_rd_vis_re : INTEGER; + VARIABLE v_rd_vis_im : INTEGER; + VARIABLE v_rd_timestamp : STD_LOGIC_VECTOR(63 DOWNTO 0); + VARIABLE v_exp_beamlet : NATURAL; -- interleaved beamlet index + VARIABLE v_exp_channel : NATURAL; -- channel index in visibility offload packet + VARIABLE v_exp_vis_re : INTEGER; + VARIABLE v_exp_vis_im : INTEGER; + VARIABLE v_exp_timestamp : STD_LOGIC_VECTOR(63 DOWNTO 0); + VARIABLE v_nxt_timestamp : STD_LOGIC_VECTOR(63 DOWNTO 0); + BEGIN + -- Wait for DB to have filled with visibility packets + proc_common_wait_until_lo_hi(tb_clk, bg_start_done); + proc_common_wait_until_lo_hi(tb_clk, eth_done); + + -- The DB read is hard to timed roughly using eth_done, but is hard to exactly time at the start of a sync interval. + -- For the packet header and data this is no problem, because they remain the same across sync intervals, except + -- for the BSN. Therefore also accept v_nxt_timestamp as correct BSN. + + ---------------------------------------------------------------------------- + -- Read and verify output data buffer + ---------------------------------------------------------------------------- + v_exp_timestamp := TO_UVEC(1 * c_nof_blocks_per_sync, 64); -- second sync interval + v_nxt_timestamp := TO_UVEC(2 * c_nof_blocks_per_sync, 64); -- third sync interval + FOR vB IN 0 TO c_nof_beamlets-1 LOOP + -- Beamlet mapping as specified in SP-062 table 6 (SC1), 9 (SC4): + -- + -- u bi dest bu_i + -- 0 0 0 FN0 0 2 ... + -- 1 0 1 FN1 256 258 ... + -- 2 0 2 FN2 512 514 ... + -- 3 0 3 FN3 768 770 ... + -- 0 1 4 BN0 1 3 ... + -- 1 1 5 BN1 257 259 ... + -- 2 1 6 BN2 513 515 ... + -- 3 1 7 BN3 769 771 ... + -- + -- Beamlet mapping as implemented in Apertif X due to reordered_sosi_arr wiring in node_apertif_unb1_correlator_mesh.vhd: + -- + -- u bi dest bu_i + -- 0 0 0 FN0 0 2 ... + -- 1 0 1 FN1 1 3 ... + -- 2 0 2 FN2 256 258 ... + -- 3 0 3 FN3 257 259 ... + -- 0 1 4 BN0 512 514 ... + -- 1 1 5 BN1 513 515 ... + -- 2 1 6 BN2 768 770 ... + -- 3 1 7 BN3 769 771 ... + v_exp_beamlet := N_slot * c_unb_nr; -- offset for UniBoard band + v_exp_beamlet := v_exp_beamlet + N_clk * (c_fpga_nr / Q_interleave) + (c_fpga_nr MOD Q_interleave); -- offset for Local PN + v_exp_beamlet := v_exp_beamlet + vB * Q_interleave; -- offset serial beamlets + FOR vC IN 0 TO c_nof_channels-1 LOOP + v_addr := ((vB * c_nof_channels) + vC) * c_vis_packet_size; + v_exp_channel := flip(vC, c_nof_channels_w); + v_exp_channel := fft_shift(v_exp_channel, c_nof_channels_w); + ----------------------------------------------------------------------- + -- Verify header fields + -- 0 gap(16) + ETH dst mac hi(16) + -- 1 ETH dst mac lo + -- 2 ETH src mac hi + -- 3 ETH src mac lo(16) + type(16) + -- 4 IP + -- 5 IP + -- 6 IP + -- 7 IP src addr + -- 8 IP dst addr + -- 9 UDP src port(16) + dst port(16) + -- 10 UDP total len(16) + checksum(16) + -- 11 ID marker(8) + version(8) + beamlet(16) + -- 12 ID channel(16) + rsvd(16) + -- 13 ID timestamp hi + -- 14 ID timestamp lo + -- 15 FLAG + -- 16 FLAG + -- 17 FLAG + -- 18 FLAG + -- 19 FLAG + -- 20 FLAG + ----------------------------------------------------------------------- + -- . dst mac + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 0, rd_data_db, tb_clk); + v_rd_dst_mac(47 DOWNTO 32) := rd_data_db(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 1, rd_data_db, tb_clk); + v_rd_dst_mac(31 DOWNTO 0) := rd_data_db; + ASSERT v_rd_dst_mac = c_dst_mac REPORT "Wrong dst MAC in packet header: " & + slv_to_hex(c_dst_mac) & " /= " & slv_to_hex(v_rd_dst_mac) SEVERITY ERROR; + -- . src mac + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 2, rd_data_db, tb_clk); + v_rd_src_mac(47 DOWNTO 16) := rd_data_db(31 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 3, rd_data_db, tb_clk); + v_rd_src_mac(15 DOWNTO 0) := rd_data_db(31 DOWNTO 16); + ASSERT v_rd_src_mac = c_src_mac REPORT "Wrong src MAC in packet header: " & + slv_to_hex(c_src_mac) & " /= " & slv_to_hex(v_rd_src_mac) SEVERITY ERROR; + -- . beamlet + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 11, rd_data_db, tb_clk); + v_rd_beamlet := TO_UINT(rd_data_db(15 DOWNTO 0)); + -- . channel + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 12, rd_data_db, tb_clk); + v_rd_channel := TO_UINT(rd_data_db(31 DOWNTO 16)); + ASSERT v_rd_beamlet = v_exp_beamlet AND v_rd_channel = v_exp_channel REPORT "Wrong beamlet, channel index in packet header: " & + "(" & int_to_str(v_exp_beamlet) & ", " & int_to_str(v_exp_channel) & ") /= " & + "(" & int_to_str(v_rd_beamlet) & ", " & int_to_str(v_rd_channel) & ")" SEVERITY ERROR; + + -- . timestamp (= bsn) + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 13, rd_data_db, tb_clk); + v_rd_timestamp(63 DOWNTO 32) := rd_data_db; + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 14, rd_data_db, tb_clk); + v_rd_timestamp(31 DOWNTO 0) := rd_data_db; + ASSERT v_rd_timestamp = v_exp_timestamp OR + v_rd_timestamp = v_nxt_timestamp REPORT "Wrong timestamp in packet header: " & + slv_to_hex(v_rd_timestamp) & " /= " & slv_to_hex(v_exp_timestamp) SEVERITY ERROR; + + -- Show read header fields in wave window + proc_common_wait_some_cycles(tb_clk, 1); + dbg_v_addr <= v_addr; + dbg_v_rd_dst_mac <= v_rd_dst_mac; + dbg_v_rd_src_mac <= v_rd_src_mac; + dbg_v_exp_beamlet <= v_exp_beamlet; + dbg_v_rd_beamlet <= v_rd_beamlet; + dbg_v_exp_channel <= v_exp_channel; + dbg_v_rd_channel <= v_rd_channel; + dbg_v_exp_timestamp <= v_exp_timestamp; + dbg_v_rd_timestamp <= v_rd_timestamp; + + ----------------------------------------------------------------------- + -- Verify payload data + -- 0 vis real(0,0) + -- 1 vis imag(0,0) + -- 2 vis real(0,1) 48 vis real(1,1) + -- 3 vis imag(0,1) 49 vis imag(1,1) + -- 4 vis real(0,2) 48 vis real(1,2) 94 vis real(2,2) + -- 5 vis imag(0,2) 49 vis imag(1,2) 95 vis imag(2,2) + -- ... ... ... + -- 46 vis real(0,23) 92 vis real(1,23) 136 vis real(2,23) ... 298 vis real(23,23) + -- 47 vis imag(0,23) 93 vis imag(1,23) 137 vis imag(2,23) ... 299 vis imag(23,23) + -- + -- 2 * (24 + 23 + 22 ... + 1) + -- 2 * (12 * 25) = 2 * 300 = 600 + -- + -- All visibilities have the same value per channel, because all TP + -- carry the same BG phasor waveform. + -- Per beamlet all visibilities are also the same, because the BG + -- phasor waveform continues across beamlets and per beamlet the + -- phasor period fits. + ----------------------------------------------------------------------- + v_addr := v_addr + c_vis_header_size; + FOR vV IN 0 TO c_nof_visibility_streams-1 LOOP + -- . MM read and swap endian (to account for p_connect in apertif_unb1_correlator_vis_offload) + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 2*vV, rd_data_db, tb_clk); + v_rd_vis_re := TO_SINT(ntoh(rd_data_db)); + mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer_output, v_addr + 2*vV+1, rd_data_db, tb_clk); + v_rd_vis_im := TO_SINT(ntoh(rd_data_db)); + -- . expected using prefilter with application coefficients + v_exp_vis_re := c_exp_pfb_channel_vis_re(vC); + v_exp_vis_im := c_exp_pfb_channel_vis_im(vC); + -- . verify + ASSERT v_rd_vis_re = v_exp_vis_re REPORT "Wrong real visibility for beamlet, channel index in packet payload " & + "(" & int_to_str(v_exp_beamlet) & ", " & int_to_str(v_exp_channel) & ") : " & + int_to_str(v_rd_vis_re) & " /= " & int_to_str(v_exp_vis_re) SEVERITY ERROR; + ASSERT v_rd_vis_im = v_exp_vis_im REPORT "Wrong imag visibility for beamlet, channel index in packet payload " & + "(" & int_to_str(v_exp_beamlet) & ", " & int_to_str(v_exp_channel) & ") : " & + int_to_str(v_rd_vis_im) & " /= " & int_to_str(v_exp_vis_im) SEVERITY ERROR; + + -- Show read payload re/im fields in wave window + proc_common_wait_some_cycles(tb_clk, 1); + dbg_v_addr <= v_addr + 2*vV; + dbg_v_exp_vis_re <= v_exp_vis_re; + dbg_v_exp_vis_im <= v_exp_vis_im; + dbg_v_rd_vis_re <= v_rd_vis_re; + dbg_v_rd_vis_im <= v_rd_vis_im; + END LOOP; + END LOOP; + END LOOP; + + packet_done <= '1'; WAIT; END PROCESS; + + ------------------------------------------------------------------------------ + -- Verify proper DUT output using Ethernet packet statistics + ------------------------------------------------------------------------------ + u_eth_statistics : ENTITY eth_lib.eth_statistics + GENERIC MAP ( + g_runtime_nof_packets => c_eth_check_nof_packets, + g_runtime_timeout => c_eth_runtime_timeout, + g_check_nof_valid => TRUE, + g_check_nof_valid_ref => c_eth_check_nof_packets*c_eth_packet_size + ) + PORT MAP ( + eth_serial_in => eth_txp, + tb_end => eth_done + ); + + ------------------------------------------------------------------------------ + -- Stop simulation using severity FAILURE dependend on g_tb_end + ------------------------------------------------------------------------------ + verify_done <= eth_done AND packet_done; + + proc_common_stop_simulation(g_tb_end, ext_clk, verify_done, i_tb_end); END tb;