diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd index 5cebe5272409933708979acc0b1fa26439599ff6..863ff56e473c2638b3d35b380c3474201e60badf 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd @@ -34,6 +34,13 @@ -- Usage: -- > as 7 # default -- > as 12 # for detailed debugging +-- And add more missing sosi_arr signals or constants via sim tab, entity instance in hierarchy and +-- then select from objects window, e.g. for: +-- > add wave -position insertpoint \ +-- sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/ait_sosi_arr \ +-- sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/pfb_sosi_arr \ +-- sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/fsub_sosi_arr \ +-- sim:/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload/u_lofar_unb2c_sdp_station_xsub_one/u_sdp_station/bs_sosi -- > run -a -- Takes about 10 m -- @@ -79,15 +86,23 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload IS CONSTANT c_nof_crosslets : NATURAL := 3; -- not too large, so that offload still fits in c_nof_block_per_sync CONSTANT c_subband_select_arr : t_natural_arr(0 TO c_sdp_N_crosslets_max-1) := (10, 11, 12, 13, 14, 15, 16); CONSTANT c_subband_step : NATURAL := 3; -- e.g. 0 or c_nof_crosslets - CONSTANT c_nof_sync : NATURAL := 5; + CONSTANT c_nof_sync : NATURAL := 3; + + CONSTANT c_max_ratio : REAL := 0.0001; -- ratio that actual value may differ from expected value -- WG CONSTANT c_bsn_start_wg : NATURAL := 2; CONSTANT c_sp_ampl : REAL := 0.5; -- WG normalized amplitude, 1.0 = FS (full scale), use <= 0.5 to avoid XST overflow CONSTANT c_wg_ampl : NATURAL := NATURAL(c_sp_ampl * REAL(c_sdp_FS_adc)); -- in number of lsb - CONSTANT c_wg_subband : REAL := 15.0; + CONSTANT c_wg_subband : NATURAL := 12; + + -- WPFB + CONSTANT c_exp_subband_ampl : REAL := REAL(c_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio; -- = c_wg_ampl * 0.994817 * 8 + CONSTANT c_exp_subband_power : REAL := c_exp_subband_ampl**2.0; -- complex, so no divide by 2 + CONSTANT c_exp_subband_sst : REAL := c_exp_subband_power * REAL(c_nof_block_per_sync); + CONSTANT c_exp_subband_xst : REAL := c_exp_subband_sst; -- all signal inputs use same WG, and auto correlation XST = SST - -- MM + -- MM CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2"; CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER"; CONSTANT c_mm_file_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG"; @@ -352,7 +367,7 @@ BEGIN rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw); -- . View / verify XST packet payload - p_rx_sdp_stat_data : PROCESS(eth_clk(0)) + p_rx_sdp_view_stat_data : PROCESS(eth_clk(0)) BEGIN IF rising_edge(eth_clk(0)) THEN rx_sdp_stat_re_val <= '0'; @@ -373,17 +388,50 @@ BEGIN WHEN 2 => rx_sdp_stat_data <= rx_offload_sosi.data(c_32-1 DOWNTO 0); WHEN 3 => rx_sdp_stat_im <= rx_sdp_stat_data & rx_offload_sosi.data(c_32-1 DOWNTO 0); rx_sdp_stat_im_val <= '1'; - rx_sdp_stat_index <= rx_sdp_stat_index + 1; WHEN OTHERS => NULL; END CASE; END IF; + -- Count the complex statistics + IF rx_sdp_stat_im_val <= '1' THEN + rx_sdp_stat_index <= rx_sdp_stat_index + 1; + END IF; + IF rx_offload_sosi.sop = '1' THEN rx_sdp_stat_index <= 0; -- restart per Rx packet END IF; END IF; END PROCESS; + p_rx_sdp_verify_stat_data : PROCESS(eth_clk(0)) + VARIABLE v_subband_ix : NATURAL; -- _ix = index + BEGIN + IF rising_edge(eth_clk(0)) THEN + v_subband_ix := TO_UINT(rx_sdp_stat_header.app.sdp_data_id_xst_subband_index); + -- real part + IF rx_sdp_stat_re_val = '1' THEN + IF v_subband_ix = c_wg_subband THEN + -- Expect the strong XST value at the WG subband + ASSERT almost_equal(TO_SREAL(rx_sdp_stat_re) / c_exp_subband_xst, 1.0, c_max_ratio) REPORT "Wrong XST real value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR; + ELSE + -- WG is only in one subband, so expect almost zero in the other subbands + ASSERT almost_zero(TO_SREAL(rx_sdp_stat_re) / c_exp_subband_xst, c_max_ratio) REPORT "Too large XST real value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR; + END IF; + END IF; + IF rx_sdp_stat_im_val = '1' THEN + -- All WG have same phase, so expect zero imaginary part. + -- . The imag part is exactly zero for signal inputs a and b that are both connected to the corresponding input of the WPFB. + -- . The imag part is almost zero for signal inputs a and b that are both connected to the opposite inputs of the WPFB, due + -- to crosstalk rounding difference from input a to b or from input b to a of the complex FFT. + IF (rx_a_sp MOD c_sdp_Q_fft) = (rx_b_sp MOD c_sdp_Q_fft) THEN + ASSERT SIGNED(rx_sdp_stat_im) = 0 REPORT "Non zero XST imaginary value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR; + ELSE + ASSERT almost_zero(TO_SREAL(rx_sdp_stat_im) / c_exp_subband_xst, c_max_ratio) REPORT "Too large XST imaginary value at subband = " & int_to_str(v_subband_ix) SEVERITY ERROR; + END IF; + END IF; + END IF; + END PROCESS; + -- rx_sdp_stat_index counts the S_pn * S_pn = X_sq = 12 * 12 = 144 complex statistics rx_a_sp <= rx_sdp_stat_index / c_sdp_S_pn; -- signal input A rx_b_sp <= rx_sdp_stat_index MOD c_sdp_S_pn; -- signal input B