From f5e119f6ec8eec7afa85dfa04075f0d3d8c49c0c Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Wed, 4 Oct 2023 13:06:17 +0200 Subject: [PATCH] Verify beamlets data for multiple destinations. --- .../sdp/tb/vhdl/tb_sdp_beamformer_output.vhd | 181 +++++++++++++----- 1 file changed, 131 insertions(+), 50 deletions(-) diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_beamformer_output.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_beamformer_output.vhd index 8516ea9ef8..c70d84b4f7 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_beamformer_output.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_beamformer_output.vhd @@ -29,7 +29,7 @@ -- > run -a ------------------------------------------------------------------------------- -library IEEE, common_lib, dp_lib; +library IEEE, common_lib, dp_lib, reorder_lib; use IEEE.std_logic_1164.all; use common_lib.common_pkg.all; use common_lib.common_mem_pkg.all; @@ -37,6 +37,7 @@ use common_lib.tb_common_pkg.all; use common_lib.tb_common_mem_pkg.all; use common_lib.common_network_layers_pkg.all; use dp_lib.dp_stream_pkg.all; +use reorder_lib.reorder_pkg.all; use work.sdp_pkg.all; use work.sdp_bdo_pkg.all; use work.tb_sdp_pkg.all; @@ -75,12 +76,16 @@ architecture tb of tb_sdp_beamformer_output is func_sdp_gn_index_to_ip_15_0(c_gn_id); constant c_cep_udp_src_port : std_logic_vector(15 downto 0) := c_sdp_cep_udp_src_port_15_8 & c_id; - constant c_reorder_nof_blocks_arr : t_natural_arr(1 to g_nof_destinations_max) := + constant c_mdi_reorder_nof_blocks_arr : t_natural_arr(1 to g_nof_destinations_max) := func_sdp_bdo_reorder_nof_blocks_look_up_table(g_nof_destinations_max); + constant c_mdi_nof_blocks_per_packet : natural := c_mdi_reorder_nof_blocks_arr(g_nof_destinations); - constant c_nof_beamlets_per_block_first_destinations_arr : t_natural_arr(1 to g_nof_destinations_max) := + constant c_mdi_nof_beamlets_per_block_first_destinations_arr : t_natural_arr(1 to g_nof_destinations_max) := func_sdp_bdo_nof_beamlets_per_block_first_destinations_look_up_table(g_nof_destinations_max); - constant c_nof_beamlets_per_block : natural := c_nof_beamlets_per_block_first_destinations_arr(g_nof_destinations); + constant c_mdi_nof_beamlets_per_block_per_destination : natural := + c_mdi_nof_beamlets_per_block_first_destinations_arr(g_nof_destinations); + + constant c_mdi_nof_beamlets_all_destinations : natural := c_mdi_nof_blocks_per_packet * c_sdp_S_sub_bf; -- Checksum value obtained from rx_sdp_cep_header.ip.header_checksum in wave window constant c_exp_ip_header_checksum : natural := 16#5BDB#; @@ -128,23 +133,26 @@ architecture tb of tb_sdp_beamformer_output is signal rx_hdr_fields_raw : std_logic_vector(1023 downto 0) := (others => '0'); signal rx_beamlet_header : t_sdp_cep_header; - signal exp_beamlet_header : t_sdp_cep_header; - signal exp_beamlet_index : natural; - signal exp_nof_blocks_per_packet : natural; - signal exp_nof_beamlets_per_block : natural; - signal exp_dp_bsn : natural; + signal exp_beamlet_header : t_sdp_cep_header; + signal exp_dp_bsn : natural; + + signal mdi_exp_beamlet_header : t_sdp_cep_header; + signal mdi_exp_beamlet_index : natural; + signal mdi_exp_nof_beamlets_per_block : natural; + signal mdi_exp_dp_bsn : natural; signal rx_offload_sosi : t_dp_sosi := c_dp_sosi_rst; + signal rx_offload_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit signal rx_offload_sop_cnt : natural := 0; signal rx_DI : natural := 0; -- rx merge - signal rx_merge_sosi : t_dp_sosi := c_dp_sosi_rst; + signal rx_merge_sosi : t_dp_sosi := c_dp_sosi_rst; signal rx_merge_sop_cnt : natural := 0; -- Beamlets packets data - signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit signal rx_beamlet_sosi : t_dp_sosi := c_dp_sosi_rst; + signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit -- [0 : 3] = X, Y, X, Y signal rx_beamlet_arr_re : t_sdp_beamlet_part_arr; @@ -152,16 +160,23 @@ architecture tb of tb_sdp_beamformer_output is signal rx_beamlet_cnt : natural; signal rx_beamlet_valid : std_logic; - -- [0 : 4 * 488 * 2 - 1] = [0 : 3903] - signal rx_packet_list_re : t_sdp_beamlet_packet_list; - signal rx_packet_list_im : t_sdp_beamlet_packet_list; - signal rx_beamlet_list_re : t_sdp_beamlet_packet_list; - signal rx_beamlet_list_im : t_sdp_beamlet_packet_list; - signal rx_beamlet_list_val : std_logic := '0'; + -- g_nof_destinations = 1: [0 : 4 * 488 * 2 - 1] = [0 : 3903] + signal rx_packet_list_re : t_sdp_beamlet_packet_list; + signal rx_packet_list_im : t_sdp_beamlet_packet_list; + signal rx_beamlet_list_re : t_sdp_beamlet_packet_list; + signal rx_beamlet_list_im : t_sdp_beamlet_packet_list; + signal rx_beamlet_list_val : std_logic := '0'; + -- g_nof_destinations > 1: [0 : N * 488 * 2 - 1], where N = c_mdi_nof_blocks_per_packet + signal rx_mdi_packet_list_re : t_slv_8_arr(0 to c_mdi_nof_beamlets_all_destinations * c_sdp_N_pol_bf - 1); + signal rx_mdi_packet_list_im : t_slv_8_arr(0 to c_mdi_nof_beamlets_all_destinations * c_sdp_N_pol_bf - 1); + signal rx_mdi_beamlet_list_re : t_slv_8_arr(0 to c_mdi_nof_beamlets_all_destinations * c_sdp_N_pol_bf - 1); + signal rx_mdi_beamlet_list_im : t_slv_8_arr(0 to c_mdi_nof_beamlets_all_destinations * c_sdp_N_pol_bf - 1); + signal rx_mdi_beamlet_list_val : std_logic := '0'; + -- Use +c_beamlet_mod to ensure >= 0 to fit in natural, use mod c_beamlet_mod -- to fit count in c_sdp_W_beamlet bits - signal prev_re : natural := (c_init_re - 1 + c_beamlet_mod) mod c_beamlet_mod; - signal prev_im : natural := (c_init_im - 1 + c_beamlet_mod) mod c_beamlet_mod; + signal prev_re : natural := (c_init_re - 1 + c_beamlet_mod) mod c_beamlet_mod; + signal prev_im : natural := (c_init_im - 1 + c_beamlet_mod) mod c_beamlet_mod; begin dp_rst <= '1', '0' after c_dp_clk_period * 7; dp_clk <= (not dp_clk) or tb_end after c_dp_clk_period / 2; @@ -343,18 +358,6 @@ begin -- Destination index (DI) rx_DI <= rx_offload_sop_cnt mod g_nof_destinations; - -- Prepare exp_beamlet_header before rx_offload_sosi.eop, so that - -- p_verify_beamlet_header can verify it at rx_offload_sosi.eop. - exp_beamlet_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum, - c_exp_sdp_info, - c_gn_id, - c_exp_payload_error, - c_exp_beamlet_scale, - exp_beamlet_index, - exp_nof_blocks_per_packet, - exp_nof_beamlets_per_block, - exp_dp_bsn); - rx_beamlet_header <= func_sdp_map_cep_header(rx_hdr_fields_raw); gen_verify_one_destination : if g_nof_destinations_max = 1 generate @@ -363,13 +366,21 @@ begin rx_beamlet_sosi <= rx_offload_sosi; --------------------------------------------------------------------------- - -- Verify beamlet header + -- Verify one destination: beamlet header --------------------------------------------------------------------------- - exp_beamlet_index <= c_exp_beamlet_index; - exp_nof_blocks_per_packet <= c_sdp_cep_nof_blocks_per_packet; - exp_nof_beamlets_per_block <= c_sdp_cep_nof_beamlets_per_block; - - p_verify_beamlet_header : process + -- Prepare exp_beamlet_header before rx_offload_sosi.eop, so that + -- p_verify_beamlet_header can verify it at rx_offload_sosi.eop. + exp_beamlet_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum, + c_exp_sdp_info, + c_gn_id, + c_exp_payload_error, + c_exp_beamlet_scale, + c_exp_beamlet_index, + c_sdp_cep_nof_blocks_per_packet, + c_sdp_cep_nof_beamlets_per_block, + exp_dp_bsn); + + p_verify_one_beamlet_header : process variable v_bool : boolean; begin wait until rising_edge(dp_clk); @@ -386,7 +397,7 @@ begin end process; ----------------------------------------------------------------------------- - -- Verify beamlet data + -- Verify one destination: beamlet data ----------------------------------------------------------------------------- -- To view the 64 bit 10GbE offload data more easily in the Wave window rx_beamlet_data <= rx_beamlet_sosi.data(c_longword_w - 1 downto 0); @@ -400,7 +411,7 @@ begin rx_packet_list_re, rx_packet_list_im); - p_verify_rx_beamlet_list : process + p_verify_one_rx_beamlet_list : process -- Nof complex (= nof re = nof im = c_N) values in t_sdp_beamlet_packet_list constant c_N : natural := c_sdp_cep_nof_beamlets_per_packet * c_sdp_N_pol_bf; variable v_re : natural; @@ -464,11 +475,21 @@ begin ); --------------------------------------------------------------------------- - -- Verify beamlet header + -- Verify multiple destinations: beamlet header --------------------------------------------------------------------------- - exp_nof_blocks_per_packet <= c_reorder_nof_blocks_arr(g_nof_destinations_max); - - p_verify_beamlet_header : process + -- Prepare mdi_exp_beamlet_header before rx_offload_sosi.eop, so that + -- p_verify_beamlet_header can verify it at rx_offload_sosi.eop. + mdi_exp_beamlet_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum, + c_exp_sdp_info, + c_gn_id, + c_exp_payload_error, + c_exp_beamlet_scale, + mdi_exp_beamlet_index, + c_mdi_nof_blocks_per_packet, + mdi_exp_nof_beamlets_per_block, + mdi_exp_dp_bsn); + + p_verify_multi_beamlet_header : process variable v_nof_beamlets : natural; variable v_bool : boolean; begin @@ -476,26 +497,86 @@ begin -- Prepare exp_sdp_cep_header, so that it can be verified at rx_offload_sosi.eop if rx_offload_sosi.sop = '1' then -- Default expect nof_beamlets_per_block for first destinations - exp_nof_beamlets_per_block <= c_nof_beamlets_per_block; + mdi_exp_nof_beamlets_per_block <= c_mdi_nof_beamlets_per_block_per_destination; if rx_DI = g_nof_destinations - 1 then -- Remaining nof_beamlets_per_block for last destination - exp_nof_beamlets_per_block <= c_sdp_S_sub_bf - rx_DI * exp_nof_beamlets_per_block; + mdi_exp_nof_beamlets_per_block <= c_sdp_S_sub_bf - rx_DI * mdi_exp_nof_beamlets_per_block; end if; - -- Expected beamlet index increments by c_nof_beamlets_per_block per destination index - exp_beamlet_index <= rx_DI * c_nof_beamlets_per_block; + -- Expected beamlet index increments by c_mdi_nof_beamlets_per_block_per_destination per destination index + mdi_exp_beamlet_index <= rx_DI * c_mdi_nof_beamlets_per_block_per_destination; end if; if rx_merge_sosi.sop = '1' then - -- Expected BSN increments by exp_nof_blocks_per_packet, after every merged packet - exp_dp_bsn <= c_init_bsn + rx_merge_sop_cnt * exp_nof_blocks_per_packet; + -- Expected BSN increments by c_mdi_nof_blocks_per_packet, after every merged packet, + -- because packets for all g_nof_destinations have same BSN. + mdi_exp_dp_bsn <= c_init_bsn + rx_merge_sop_cnt * c_mdi_nof_blocks_per_packet; end if; -- Verify header at eop if rx_offload_sosi.eop = '1' then - v_bool := func_sdp_verify_cep_header(rx_beamlet_header, exp_beamlet_header); + v_bool := func_sdp_verify_cep_header(rx_beamlet_header, mdi_exp_beamlet_header); end if; end process; + --------------------------------------------------------------------------- + -- Verify multiple destinations: beamlet data + --------------------------------------------------------------------------- + -- Wires + rx_beamlet_sosi <= rx_merge_sosi; + + -- To view the 64 bit 10GbE offload data more easily in the Wave window + rx_offload_data <= rx_offload_sosi.data(c_longword_w - 1 downto 0); + rx_beamlet_data <= rx_beamlet_sosi.data(c_longword_w - 1 downto 0); + + proc_sdp_rx_beamlet_octets(c_mdi_nof_blocks_per_packet, + dp_clk, + rx_beamlet_sosi, + rx_beamlet_cnt, + rx_beamlet_valid, + rx_beamlet_arr_re, + rx_beamlet_arr_im, + rx_mdi_packet_list_re, + rx_mdi_packet_list_im); + + p_verify_multi_rx_beamlet_list : process + -- Nof complex (= nof re = nof im = c_N) values in packet_list + constant c_N : natural := c_mdi_nof_beamlets_all_destinations * c_sdp_N_pol_bf; + variable v_re : natural; + variable v_im : natural; + begin + -- Wait until end of a beamlet packet + -- . use at least one wait statement in process to avoid Modelsim warning: (vcom-1090) + wait until rising_edge(dp_clk); + proc_common_wait_until_hi_lo(dp_clk, rx_beamlet_sosi.eop); + -- Undo the beamlet output transpose, to have original beamlet order + rx_mdi_beamlet_list_re <= func_reorder_transpose_packet(c_sdp_S_sub_bf, + c_mdi_nof_blocks_per_packet, + c_sdp_N_pol_bf, + rx_mdi_packet_list_re); + rx_mdi_beamlet_list_im <= func_reorder_transpose_packet(c_sdp_S_sub_bf, + c_mdi_nof_blocks_per_packet, + c_sdp_N_pol_bf, + rx_mdi_packet_list_im); + rx_mdi_beamlet_list_val <= '1'; + + -- Wait until rx_beamlet_list is valid + wait until rising_edge(dp_clk); + rx_mdi_beamlet_list_val <= '0'; + -- Verify rx_beamlet_list + -- . get last values from previous block + v_re := prev_re; + v_im := prev_im; + for vI in 0 to c_N - 1 loop + -- Verify incrementing beamlets + v_re := (v_re + 1) mod c_beamlet_mod; + v_im := (v_im + 1) mod c_beamlet_mod; + assert to_uint(rx_mdi_beamlet_list_re(vI)) = v_re report "Wrong mdi re_beamlet." severity error; + assert to_uint(rx_mdi_beamlet_list_im(vI)) = v_im report "Wrong mdi im_beamlet." severity error; + end loop; + -- . hold last values for next block + prev_re <= v_re; + prev_im <= v_im; + end process; end generate; end tb; -- GitLab