From 8c8bd65b8fae0910ffbf9cb664789cb9be6bdbd4 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Mon, 21 Aug 2023 15:43:51 +0200 Subject: [PATCH] Align tb with tb_lofar2_unb2c_sdp_station_bf.vhd. --- .../tb_lofar2_unb2c_sdp_station_bf_ring.vhd | 241 ++++++++++++------ 1 file changed, 162 insertions(+), 79 deletions(-) diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd index 879bc4cfe1..d0a62d8144 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd @@ -21,7 +21,8 @@ ------------------------------------------------------------------------------- -- -- Author: R. van der Walle (original), E. Kooistra (updates) --- Purpose: Self-checking testbench for simulating lofar2_unb2c_sdp_station_bf_ring +-- Purpose: +-- Self-checking testbench for simulating lofar2_unb2c_sdp_station_bf_ring -- using WG data. -- -- Description: @@ -105,6 +106,12 @@ -- * The c_wg_phase_offset and c_subband_phase_offset are used to tune the WG -- phase reference to 0.0 degrees at the start (sop) -- * Use g_beamlet_scale = 2**10, for full scale WG and N_ant = 1, see [1] +-- * Using g_beamlet = c_sdp_S_sub_bf-1 = 487 puts g_subband = 102 at the last +-- beamlet in the beamset, so at index 974,975 of rx_beamlet_list_re/im. +-- * Default beamlet 102 also contains g_subband = 102. On HW the BF weights +-- are default 0, but in sim the BF weights in node_sdp_beamformer.vhd +-- are default unit weights. Therefore also write the BF weight for default +-- beamlet 102 to define it value, in case g_beamlet /= 102. -- * A simulation only section in sdp_beamformer_output.vhd disturbs the BSN, -- to cause a merged payload error, so that sdp_source_info_payload_error -- can be verified here. @@ -115,7 +122,11 @@ -- # Manually add missing signals and constants using objects in GUI -- > add wave -position insertpoint \ -- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/sp_ssts_arr2 \ --- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/bsts_arr2 +-- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/bsts_arr2 \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/rx_packet_list_re \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/rx_packet_list_im \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/rx_reordered_list_re \ +-- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/rx_reordered_list_im -- > run -a -- Takes about 2h 25m when g_read_all_* = FALSE -- @@ -143,6 +154,7 @@ use unb2c_board_lib.unb2c_board_pkg.all; use lofar2_sdp_lib.sdp_pkg.all; use lofar2_sdp_lib.tb_sdp_pkg.all; use tech_pll_lib.tech_pll_component_pkg.all; +use lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station_pkg.all; entity tb_lofar2_unb2c_sdp_station_bf_ring is generic ( @@ -172,6 +184,10 @@ end tb_lofar2_unb2c_sdp_station_bf_ring; architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is + -- Revision parameters + constant c_design_name : string := "lofar2_unb2c_sdp_station_bf_ring"; + constant c_revision_select : t_lofar2_unb2c_sdp_station_config := func_sel_revision_rec(c_design_name); + constant c_sim : boolean := true; constant c_first_unb_nr : natural := g_first_gn / c_quad; -- c_quad = 4 FPGAs per UniBoard2 constant c_first_node_nr : natural := g_first_gn mod c_quad; -- first node_nr in range(c_quad) = [0:3] on c_first_unb_nr @@ -188,6 +204,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is constant c_init_bsn : natural := 17; -- some recognizable value >= 0 constant c_nof_lanes : natural := c_sdp_N_beamsets; + constant c_use_bdo_transpose : boolean := c_revision_select.use_bdo_transpose; constant c_last_id : std_logic_vector(7 downto 0) := TO_UVEC(c_last_gn, 8); constant c_version : std_logic_vector(1 downto 0) := "00"; @@ -211,8 +228,6 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is constant c_stat_lo_factor : real := 1.0 - c_stat_percentage; -- lower boundary constant c_stat_hi_factor : real := 1.0 + c_stat_percentage; -- higher boundary - constant c_nof_beamlets_per_data : natural := 2; -- 2 dual pol beamlets (= XY, XY) per 64b data word - constant c_beamlet_output_delta : integer := 2; -- +-delta margin -- header fields @@ -263,7 +278,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is constant c_subband_weight_phase : real := 0.0; -- use default unit subband weights constant c_exp_subband_phase : real := g_sp_phase + c_subband_phase_offset + c_subband_weight_phase; constant c_exp_subband_ampl : real := real(c_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio * c_subband_weight_gain; - constant c_exp_subband_power : real := c_exp_subband_ampl**2.0; -- complex signal ampl, so no divide by 2 + constant c_exp_subband_power : real := c_exp_subband_ampl**2.0; -- complex signal ampl, so power is A**2 (not A**2 / 2 as for real) constant c_exp_subband_sst : real := c_exp_subband_power * real(c_nof_block_per_sync); constant c_exp_remnant_subband_phase : real := g_sp_remnant_phase + c_subband_phase_offset + c_subband_weight_phase; @@ -359,12 +374,17 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is constant c_mm_file_reg_bf_scale : string := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_BF_SCALE"; -- readback constant c_mm_file_reg_hdr_dat : string := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_HDR_DAT"; -- control beamlet output + -- Tb BSN moments + constant c_stimuli_done_bsn : natural := c_init_bsn + c_bsn_latency + c_nof_block_per_sync * 3; + constant c_verify_rx_beamlet_list_bsn : natural := c_stimuli_done_bsn - c_nof_block_per_sync; + -- Tb signal stimuli_done : std_logic := '0'; signal tb_almost_end : std_logic := '0'; signal tb_end : std_logic := '0'; signal tb_clk : std_logic := '0'; signal rd_data : std_logic_vector(c_32 - 1 downto 0); + signal rd_data_bsn : std_logic_vector(c_32 - 1 downto 0); signal dest_rst : std_logic := '1'; -- use separate destination rst for Rx 10GbE in tb signal pps_rst : std_logic := '1'; -- use separate reset to release the PPS generator @@ -450,13 +470,34 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is signal rx_beamlet_sop_cnt : natural := 0; signal rx_beamlet_eop_cnt : natural := 0; - signal rx_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet - 1 downto 0); -- [3:0] - signal rx_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet - 1 downto 0); -- [3:0] + -- [0 : 3] = X, Y, X, Y + signal rx_beamlet_arr_re : t_sdp_beamlet_part_arr; + signal rx_beamlet_arr_im : t_sdp_beamlet_part_arr; signal rx_beamlet_cnt : natural; signal rx_beamlet_valid : std_logic; - signal rx_beamlet_list_re : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1 downto 0); -- [488 * 2-1:0] = [975:0] - signal rx_beamlet_list_im : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf - 1 downto 0); -- [488 * 2-1:0] = [975:0] + -- [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_reordered_list_re : t_sdp_beamlet_packet_list; + signal rx_reordered_list_im : t_sdp_beamlet_packet_list; + + -- Recover original beamlet order per block, either by using c_use_bdo_transpose + -- = false or by using c_use_bdo_transpose and func_sdp_bdo_transpose_packet(). + -- List: [0 : 488 * 2 - 1] = [0 : 975] + -- . X part at even indices + -- . Y part at odd indices + signal prev_rx_beamlet_list_re : t_sdp_beamlet_block_list; + signal prev_rx_beamlet_list_im : t_sdp_beamlet_block_list; + signal rx_beamlet_list_re : t_sdp_beamlet_block_list; + signal rx_beamlet_list_im : t_sdp_beamlet_block_list; + signal rx_beamlet_list_val : std_logic; + signal verify_rx_beamlet_list : std_logic := '0'; + + signal rx_beamlet_x_output_re : integer; + signal rx_beamlet_x_output_im : integer; + signal rx_beamlet_y_output_re : integer; + signal rx_beamlet_y_output_im : integer; -- DUT signal ext_clk : std_logic := '0'; @@ -514,7 +555,7 @@ begin gen_dut : for RN in 0 to c_last_rn generate u_lofar_unb2c_sdp_station_bf : entity lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station generic map ( - g_design_name => "lofar2_unb2c_sdp_station_bf_ring", + g_design_name => c_design_name, g_design_note => "", g_sim => c_sim, g_sim_unb_nr => (g_first_gn + RN) / c_quad, @@ -675,39 +716,6 @@ begin -- Wait for DUT power up after reset wait for 1 us; - print_str(""); - print_str("WG:"); - print_str(". c_wg_ampl = " & int_to_str(c_wg_ampl)); - print_str(". c_exp_sp_power = " & real_to_str(c_exp_sp_power, 20, 1)); - print_str(". c_exp_sp_ast = " & real_to_str(c_exp_sp_ast, 20, 1)); - - print_str(""); - print_str("Subband weight:"); - print_str(". sp_subband_weight_gain = " & real_to_str(sp_subband_weight_gain, 20, 6)); - print_str(". sp_subband_weight_phase = " & real_to_str(sp_subband_weight_phase, 20, 6)); - - print_str(""); - print_str("SST results:"); - print_str(". sst_weighted_subbands_flag = " & sl_to_str(sst_weighted_subbands_flag)); - print_str(""); - print_str(". c_exp_subband_ampl = " & int_to_str(natural(c_exp_subband_ampl))); - print_str(". c_exp_subband_power = " & real_to_str(c_exp_subband_power, 20, 1)); - print_str(". c_exp_subband_sst = " & real_to_str(c_exp_subband_sst, 20, 1)); - print_str(""); - print_str(". sp_sst = " & real_to_str(sp_sst, 20, 1)); - print_str(". sp_sst / c_exp_subband_sst = " & real_to_str(sp_sst / c_exp_subband_sst, 20, 6)); - - print_str(""); - print_str("BST results:"); - print_str(". c_exp_beamlet_x_ampl = " & int_to_str(natural(c_exp_beamlet_x_ampl))); - print_str(". c_exp_beamlet_x_power = " & real_to_str(c_exp_beamlet_x_power, 20, 1)); - print_str(". c_exp_beamlet_x_bst = " & real_to_str(c_exp_beamlet_x_bst, 20, 1)); - print_str(""); - print_str(". c_exp_beamlet_y_ampl = " & int_to_str(natural(c_exp_beamlet_y_ampl))); - print_str(". c_exp_beamlet_y_power = " & real_to_str(c_exp_beamlet_y_power, 20, 1)); - print_str(". c_exp_beamlet_y_bst = " & real_to_str(c_exp_beamlet_y_bst, 20, 1)); - print_str(""); - ---------------------------------------------------------------------------- -- Set and check SDP info ---------------------------------------------------------------------------- @@ -723,7 +731,6 @@ begin -- 0 block_period : STD_LOGIC_VECTOR(15 DOWNTO 0); -- END RECORD; -- . Write - for RN in 0 to c_last_rn loop v_gn := g_first_gn + RN; mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn mod c_quad) & "REG_SDP_INFO", 8, TO_UINT(c_exp_sdp_info.antenna_field_index), tb_clk); @@ -1133,8 +1140,9 @@ begin ---------------------------------------------------------------------------- -- Wait for enough WG data and start of sync interval ---------------------------------------------------------------------------- - mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low - "UNSIGNED", rd_data, ">=", c_init_bsn + c_nof_block_per_sync * 3, -- this is the wait until condition + -- read BSN low, this is the wait until condition + mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, + "UNSIGNED", rd_data_bsn, ">=", c_stimuli_done_bsn, c_sdp_T_sub, tb_clk); -- Stimuli done, now verify results at end of test @@ -1235,18 +1243,18 @@ begin --------------------------------------------------------------------------- print_str(""); - print_str("WG:"); + print_str("* WG:"); print_str(". c_wg_ampl = " & int_to_str(c_wg_ampl)); print_str(". c_exp_sp_power = " & real_to_str(c_exp_sp_power, 20, 1)); print_str(". c_exp_sp_ast = " & real_to_str(c_exp_sp_ast, 20, 1)); print_str(""); - print_str("Subband weight:"); + print_str("* Subband weight:"); print_str(". sp_subband_weight_gain = " & real_to_str(sp_subband_weight_gain, 20, 6)); print_str(". sp_subband_weight_phase = " & real_to_str(sp_subband_weight_phase, 20, 6)); print_str(""); - print_str("SST results:"); + print_str("* SST results:"); print_str(". sst_weighted_subbands_flag = " & sl_to_str(sst_weighted_subbands_flag)); print_str(""); print_str(". c_exp_subband_ampl = " & int_to_str(natural(c_exp_subband_ampl))); @@ -1257,7 +1265,7 @@ begin print_str(". sp_sst / c_exp_subband_sst = " & real_to_str(sp_sst / c_exp_subband_sst, 20, 6)); print_str(""); - print_str("BST results:"); + print_str("* BST results:"); print_str(". c_exp_beamlet_x_ampl = " & int_to_str(natural(c_exp_beamlet_x_ampl))); print_str(". c_exp_beamlet_x_power = " & real_to_str(c_exp_beamlet_x_power, 20, 1)); print_str(". c_exp_beamlet_x_bst = " & real_to_str(c_exp_beamlet_x_bst, 20, 1)); @@ -1271,6 +1279,7 @@ begin print_str(". bst_x_arr(" & integer'image(v_G) & ") = " & real_to_str(bst_x_arr(U), 20, 1)); print_str(". bst_y_arr(" & integer'image(v_G) & ") = " & real_to_str(bst_y_arr(U), 20, 1)); end loop; + print_str(""); for U in 0 to c_sdp_N_beamsets - 1 loop v_G := g_beamlet + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp) print_str(". bst_x_arr(" & integer'image(v_G) & ") / c_exp_beamlet_x_bst = " & real_to_str(bst_x_arr(U) / c_exp_beamlet_x_bst, 20, 6)); @@ -1278,19 +1287,27 @@ begin end loop; print_str(""); - print_str("Beamlet output:"); + print_str("* Beamlet scale:"); print_str(". rd_beamlet_scale = " & int_to_str(TO_UINT(rd_beamlet_scale))); print_str(". c_exp_beamlet_scale = " & int_to_str(c_exp_beamlet_scale)); print_str(""); - print_str(". c_exp_beamlet_x_output_ampl = " & int_to_str(natural(c_exp_beamlet_x_output_ampl))); - print_str(". c_exp_beamlet_x_output_phase = " & int_to_str(integer(c_exp_beamlet_x_output_phase))); - print_str(". c_exp_beamlet_x_output_re = " & int_to_str(integer(c_exp_beamlet_x_output_re))); - print_str(". c_exp_beamlet_x_output_im = " & int_to_str(integer(c_exp_beamlet_x_output_im))); + print_str("* Beamlet output:"); + print_str(" . c_exp_beamlet_x_output_ampl = " & int_to_str(natural(c_exp_beamlet_x_output_ampl))); + print_str(" . c_exp_beamlet_x_output_phase = " & int_to_str(integer(c_exp_beamlet_x_output_phase))); + print_str(" . rx_beamlet_x_output_re = " & int_to_str(rx_beamlet_x_output_re)); + print_str(" . c_exp_beamlet_x_output_re = " & int_to_str(integer(c_exp_beamlet_x_output_re))); + print_str(" . rx_beamlet_x_output_im = " & int_to_str(rx_beamlet_x_output_im)); + print_str(" . c_exp_beamlet_x_output_im = " & int_to_str(integer(c_exp_beamlet_x_output_im))); + print_str(""); + print_str(" . c_exp_beamlet_y_output_ampl = " & int_to_str(natural(c_exp_beamlet_y_output_ampl))); + print_str(" . c_exp_beamlet_y_output_phase = " & int_to_str(integer(c_exp_beamlet_y_output_phase))); + print_str(" . rx_beamlet_y_output_re = " & int_to_str(rx_beamlet_y_output_re)); + print_str(" . c_exp_beamlet_y_output_re = " & int_to_str(integer(c_exp_beamlet_y_output_re))); + print_str(" . rx_beamlet_y_output_im = " & int_to_str(rx_beamlet_y_output_im)); + print_str(" . c_exp_beamlet_y_output_im = " & int_to_str(integer(c_exp_beamlet_y_output_im))); + print_str(""); + print_str(" . c_beamlet_output_delta (+- margin) = " & int_to_str(integer(c_beamlet_output_delta))); print_str(""); - print_str(". c_exp_beamlet_y_output_ampl = " & int_to_str(natural(c_exp_beamlet_y_output_ampl))); - print_str(". c_exp_beamlet_y_output_phase = " & int_to_str(integer(c_exp_beamlet_y_output_phase))); - print_str(". c_exp_beamlet_y_output_re = " & int_to_str(integer(c_exp_beamlet_y_output_re))); - print_str(". c_exp_beamlet_y_output_im = " & int_to_str(integer(c_exp_beamlet_y_output_im))); --------------------------------------------------------------------------- -- Verify SST @@ -1316,15 +1333,15 @@ begin -- Verify beamlet output in 10GbE UDP offload --------------------------------------------------------------------------- -- X-pol - v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_x_index)); v_re_exp := c_exp_beamlet_x_output_re; - v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_x_index)); v_im_exp := c_exp_beamlet_x_output_im; + v_re := rx_beamlet_x_output_re; v_re_exp := c_exp_beamlet_x_output_re; + v_im := rx_beamlet_x_output_im; v_im_exp := c_exp_beamlet_x_output_im; assert v_re > integer(v_re_exp) - c_beamlet_output_delta report "Wrong beamlet X output (re) " & integer'image(v_re) & " != " & real'image(v_re_exp) severity ERROR; assert v_re < integer(v_re_exp) + c_beamlet_output_delta report "Wrong beamlet X output (re) " & integer'image(v_re) & " != " & real'image(v_re_exp) severity ERROR; assert v_im > integer(v_im_exp) - c_beamlet_output_delta report "Wrong beamlet X output (im) " & integer'image(v_im) & " != " & real'image(v_im_exp) severity ERROR; assert v_im < integer(v_im_exp) + c_beamlet_output_delta report "Wrong beamlet X output (im) " & integer'image(v_im) & " != " & real'image(v_im_exp) severity ERROR; -- Y-pol - v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_y_index)); v_re_exp := c_exp_beamlet_y_output_re; - v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_y_index)); v_im_exp := c_exp_beamlet_y_output_im; + v_re := rx_beamlet_y_output_re; v_re_exp := c_exp_beamlet_y_output_re; + v_im := rx_beamlet_y_output_im; v_im_exp := c_exp_beamlet_y_output_im; assert v_re > integer(v_re_exp) - c_beamlet_output_delta report "Wrong beamlet Y output (re) " & integer'image(v_re) & " != " & real'image(v_re_exp) severity ERROR; assert v_re < integer(v_re_exp) + c_beamlet_output_delta report "Wrong beamlet Y output (re) " & integer'image(v_re) & " != " & real'image(v_re_exp) severity ERROR; assert v_im > integer(v_im_exp) - c_beamlet_output_delta report "Wrong beamlet Y output (im) " & integer'image(v_im) & " != " & real'image(v_im_exp) severity ERROR; @@ -1437,10 +1454,10 @@ begin begin rx_beamlet_cnt <= 0; rx_beamlet_valid <= '0'; - -- Wait until start of a beamlet packet, capture only first block in packet + -- Wait until start of a beamlet packet proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.sop); - -- c_nof_beamlets_per_data = 2 dual pol beamlets (= XY, XY) per 64b data word - for I in 0 to (c_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data) - 1 loop + -- c_sdp_cep_nof_beamlets_per_longword = 2 dual pol beamlets (= XY, XY) per 64b data word + for I in 0 to (c_sdp_cep_nof_beamlets_per_packet / c_sdp_cep_nof_beamlets_per_longword) - 1 loop proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid); rx_beamlet_valid <= '1'; -- Capture rx beamlets per longword in rx_beamlet_arr, for time series view in Wave window @@ -1452,28 +1469,94 @@ begin rx_beamlet_arr_im(2) <= rx_beamlet_sosi.data(23 downto 16); rx_beamlet_arr_re(3) <= rx_beamlet_sosi.data(15 downto 8); -- Y rx_beamlet_arr_im(3) <= rx_beamlet_sosi.data( 7 downto 0); - if I < c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data then - -- Only capture the first beamlets block of each packet in rx_beamlet_list - rx_beamlet_list_re(I * 4 + 0) <= rx_beamlet_sosi.data(63 downto 56); -- X - rx_beamlet_list_im(I * 4 + 0) <= rx_beamlet_sosi.data(55 downto 48); - rx_beamlet_list_re(I * 4 + 1) <= rx_beamlet_sosi.data(47 downto 40); -- Y - rx_beamlet_list_im(I * 4 + 1) <= rx_beamlet_sosi.data(39 downto 32); - rx_beamlet_list_re(I * 4 + 2) <= rx_beamlet_sosi.data(31 downto 24); -- X - rx_beamlet_list_im(I * 4 + 2) <= rx_beamlet_sosi.data(23 downto 16); - rx_beamlet_list_re(I * 4 + 3) <= rx_beamlet_sosi.data(15 downto 8); -- Y - rx_beamlet_list_im(I * 4 + 3) <= rx_beamlet_sosi.data( 7 downto 0); - end if; + -- Capture the beamlets block of each packet in rx_packet_list + rx_packet_list_re(I * 4 + 0) <= rx_beamlet_sosi.data(63 downto 56); -- X + rx_packet_list_im(I * 4 + 0) <= rx_beamlet_sosi.data(55 downto 48); + rx_packet_list_re(I * 4 + 1) <= rx_beamlet_sosi.data(47 downto 40); -- Y + rx_packet_list_im(I * 4 + 1) <= rx_beamlet_sosi.data(39 downto 32); + rx_packet_list_re(I * 4 + 2) <= rx_beamlet_sosi.data(31 downto 24); -- X + rx_packet_list_im(I * 4 + 2) <= rx_beamlet_sosi.data(23 downto 16); + rx_packet_list_re(I * 4 + 3) <= rx_beamlet_sosi.data(15 downto 8); -- Y + rx_packet_list_im(I * 4 + 3) <= rx_beamlet_sosi.data( 7 downto 0); proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid); -- Use at least one WAIT instead of proc_common_wait_some_cycles() to -- avoid Modelsim warning: (vcom-1090) Possible infinite loop: Process -- contains no WAIT statement. wait until rising_edge(ext_clk); rx_beamlet_valid <= '0'; - rx_beamlet_cnt <= (rx_beamlet_cnt + c_nof_beamlets_per_data) mod c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet + rx_beamlet_cnt <= (rx_beamlet_cnt + c_sdp_cep_nof_beamlets_per_longword) mod c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet + end loop; + end process; + + -- Undo the beamlet output transpose, to have original beamlet order + p_rx_reordered_list : process + begin + -- Wait until end of a beamlet packet + wait until rising_edge(ext_clk); -- to avoid Modelsim warning: (vcom-1090) + proc_common_wait_until_hi_lo(ext_clk, rx_beamlet_sosi.eop); -- to reduce simulation effort + rx_reordered_list_re <= func_sdp_bdo_transpose_packet(c_sdp_cep_nof_blocks_per_packet, + c_sdp_cep_nof_beamlets_per_block, + rx_packet_list_re); + rx_reordered_list_im <= func_sdp_bdo_transpose_packet(c_sdp_cep_nof_blocks_per_packet, + c_sdp_cep_nof_beamlets_per_block, + rx_packet_list_im); + end process; + + p_rx_beamlet_list : process + constant c_N : natural := c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf; + begin + rx_beamlet_list_val <= '0'; + + -- Wait until after p_rx_reordered_list has updated + proc_common_wait_until_hi_lo(ext_clk, rx_beamlet_sosi.eop); + wait until rising_edge(ext_clk); + + -- Use same rx_beamlet_list to show all 4 blocks of a packet in time, to + -- ease viewing the blocks in the wave window. + for blk in 0 to c_sdp_cep_nof_blocks_per_packet - 1 loop + -- Copy block blk from rx_packet_list into rx_beamlet_list of one block. + if c_use_bdo_transpose then + -- undone transposed beamlet output order + rx_beamlet_list_re <= rx_reordered_list_re(blk * c_N to (blk + 1) * c_N - 1); + rx_beamlet_list_im <= rx_reordered_list_im(blk * c_N to (blk + 1) * c_N - 1); + else + -- identity beamlet output order + rx_beamlet_list_re <= rx_packet_list_re(blk * c_N to (blk + 1) * c_N - 1); + rx_beamlet_list_im <= rx_packet_list_im(blk * c_N to (blk + 1) * c_N - 1); + end if; + rx_beamlet_list_val <= '1'; + wait until rising_edge(ext_clk); end loop; end process; + -- Verify that beamlet values remain stable in time, so same beamlet value in each time block + verify_rx_beamlet_list <= '1' when unsigned(rd_data_bsn) > c_verify_rx_beamlet_list_bsn else '0'; + + p_verify_rx_beamlet_list : process(ext_clk) + begin + if rising_edge(ext_clk) then + -- Wait until p_rx_beamlet_list is valid + if rx_beamlet_list_val = '1' then + -- Maintain previous x_beamlet_list for comparision + prev_rx_beamlet_list_re <= rx_beamlet_list_re; + prev_rx_beamlet_list_im <= rx_beamlet_list_im; + -- After some time all rx blocks should have same beamlet values, so + -- then rx_beamlet_list then does not change in time and the other + -- blocks should be the same as the first block. + if verify_rx_beamlet_list = '1' then + assert rx_beamlet_list_re = prev_rx_beamlet_list_re report "Wrong: rx_beamlet_list_re differs from previous block" severity ERROR; + assert rx_beamlet_list_im = prev_rx_beamlet_list_im report "Wrong: rx_beamlet_list_im differs from previous block" severity ERROR; + end if; + end if; + end if; + end process; + + -- get rx_beamlet for comparision with c_exp_beamlet + rx_beamlet_x_output_re <= TO_SINT(rx_beamlet_list_re(c_exp_beamlet_x_index)); + rx_beamlet_x_output_im <= TO_SINT(rx_beamlet_list_im(c_exp_beamlet_x_index)); + rx_beamlet_y_output_re <= TO_SINT(rx_beamlet_list_re(c_exp_beamlet_y_index)); + rx_beamlet_y_output_im <= TO_SINT(rx_beamlet_list_im(c_exp_beamlet_y_index)); + -- 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); - end tb; -- GitLab