diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd index 322ebe95addbe9d3bfa6b4b75a559be9f9a22445..72d65882396fecb24585fe49f4cff215d85f03e2 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd @@ -33,11 +33,11 @@ -- 2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg -- to trigger start of WG at BSN. -- --- 3) Read subband statistics (SST) via MM and verify with exp_subband_sst at g_subband. +-- 3) Read subband statistics (SST) via MM and verify with exp_sp_subband_sst at g_subband. -- . use weighted subbands (default selected by MM) --- . g_use_cross_weight = TRUE, then use g_cross_weight_gain/phase and c_cross_sp +-- . g_use_cross_weight = TRUE, then use g_sp_cross_subband_weight_gain/phase and c_cross_sp -- . g_use_cross_weight = FALSE, then do not use c_cross_sp, so only use g_sp and --- g_subband_weight_gain/phase +-- g_co_subband_weight_gain/phase -- -- 4) View in wave window -- . in_sosi.sop and in_data in u_si_arr(g_sp) to check that: @@ -45,10 +45,10 @@ -- - WG amplitude = 8191 (is full scale - 1) when wg_ampl = 1.0 -- . pfb_sosi_arr(c_pfb_index).im/re and fsub_sosi_arr(c_pfb_index).im/re -- in u_fsub in decimal radix and analog format to check that subband --- phase is g_subband_weight_phase phase as set by the subband weight. +-- phase is g_co_subband_weight_phase phase as set by the subband weight. -- - Raw: pfb_sosi_arr = atan2(-65195 / 0) = -90 degrees -- - Weighted: fsub_sosi_arr = atan2(-56457 / 32598) = -60 degrees --- --> rotated expected g_subband_weight_phase = -60 - -90 = +30 degrees. +-- --> rotated expected g_co_subband_weight_phase = -60 - -90 = +30 degrees. -- -- Usage: -- > as 7 # default @@ -79,15 +79,17 @@ USE unb2c_board_lib.unb2c_board_pkg.ALL; ENTITY tb_lofar2_unb2c_sdp_station_fsub IS GENERIC ( - g_sp : NATURAL := 3; -- signal path index in range(S_pn = 12) - g_wg_ampl : REAL := 0.5; -- WG normalized amplitude, use same WG settings for both polarizations (g_sp and c_cross_sp) - g_subband : NATURAL := 102; -- select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz - g_subband_weight_gain : REAL := 1.0; -- subband weight normalized gain, for co-polarization in g_sp - g_subband_weight_phase : REAL := 30.0; -- subband weight phase rotation in degrees, for co-polarization in g_sp - g_use_cross_weight : BOOLEAN := TRUE; - g_cross_weight_gain : REAL := 0.5; -- subband weight normalized gain, for cross polarization of g_sp - g_cross_weight_phase : REAL := 30.0; -- subband weight phase rotation in degrees, for cross polarization of g_sp - g_read_all_SST : BOOLEAN := TRUE -- when FALSE only read SST for g_subband, to save sim time + g_sp : NATURAL := 3; -- signal path index in range(S_pn = 12) of co-polarization + g_co_wg_ampl : REAL := 0.5; -- WG normalized amplitude, use same WG settings for both polarizations (g_sp and c_cross_sp) + g_cross_wg_ampl : REAL := 0.4; -- WG normalized amplitude, use same WG settings for both polarizations (g_sp and c_cross_sp) + g_cross_wg_phase : REAL := 90.0; -- WG phase in degrees for cross-sp, relative to co-sp + g_subband : NATURAL := 102; -- select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz + g_co_subband_weight_gain : REAL := 1.0; -- subband weight normalized gain, for co-polarization in g_sp + g_co_subband_weight_phase : REAL := 30.0; -- subband weight phase rotation in degrees, for co-polarization in g_sp + g_use_cross_weight : BOOLEAN := TRUE; + g_sp_cross_subband_weight_gain : REAL := 0.5; -- subband weight normalized gain, for cross polarization of g_sp + g_sp_cross_subband_weight_phase : REAL := -10.0; -- subband weight phase rotation in degrees, for cross polarization of g_sp + g_read_all_SST : BOOLEAN := TRUE -- when FALSE only read SST for g_subband, to save sim time ); END tb_lofar2_unb2c_sdp_station_fsub; @@ -97,6 +99,8 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_fsub IS CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 CONSTANT c_node_nr : NATURAL := 0; CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0 + + -- signal path index of cross-polarization CONSTANT c_cross_sp : NATURAL := sel_a_b(g_sp MOD c_sdp_N_pol = 0, g_sp + 1, g_sp - 1); CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; @@ -122,46 +126,62 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_fsub IS -- WG CONSTANT c_bsn_start_wg : NATURAL := c_init_bsn + 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values -- .ampl - CONSTANT c_wg_ampl : NATURAL := NATURAL(g_wg_ampl * REAL(c_sdp_FS_adc)); -- in number of lsb - CONSTANT c_exp_sp_power : REAL := REAL(c_wg_ampl**2) / 2.0; - CONSTANT c_exp_sp_ast : REAL := c_exp_sp_power * REAL(c_nof_clk_per_sync); + CONSTANT c_co_wg_ampl : NATURAL := NATURAL(g_co_wg_ampl * REAL(c_sdp_FS_adc)); -- in number of lsb + CONSTANT c_cross_wg_ampl : NATURAL := NATURAL(g_cross_wg_ampl * REAL(c_sdp_FS_adc)); -- in number of lsb + CONSTANT c_exp_co_sp_power : REAL := REAL(c_co_wg_ampl**2) / 2.0; + CONSTANT c_exp_cross_sp_power : REAL := REAL(c_cross_wg_ampl**2) / 2.0; + CONSTANT c_exp_co_sp_ast : REAL := c_exp_co_sp_power * REAL(c_nof_clk_per_sync); + CONSTANT c_exp_cross_sp_ast : REAL := c_exp_cross_sp_power * REAL(c_nof_clk_per_sync); + -- . freq + CONSTANT c_subband_freq : REAL := REAL(g_subband) / REAL(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz is dp_clk -- . phase CONSTANT c_subband_phase : REAL := 0.0; -- wanted subband phase in degrees = WG phase at sop - CONSTANT c_subband_freq : REAL := REAL(g_subband) / REAL(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz is dp_clk CONSTANT c_wg_latency : INTEGER := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency CONSTANT c_wg_phase_offset : REAL := 360.0 * REAL(c_wg_latency) * c_subband_freq; -- c_diag_wg_latency is in dp_clk cycles CONSTANT c_wg_phase : REAL := c_subband_phase + c_wg_phase_offset; -- WG phase in degrees + CONSTANT c_co_wg_phase : REAL := c_wg_phase; + CONSTANT c_cross_wg_phase : REAL := c_wg_phase + g_cross_wg_phase; + CONSTANT c_subband_phase_offset : REAL := -90.0; -- WG with zero phase sinus yields subband with -90 degrees phase (negative Im, zero Re) + CONSTANT c_co_subband_phase : REAL := c_subband_phase_offset + c_co_wg_phase; + CONSTANT c_cross_subband_phase : REAL := c_subband_phase_offset + c_cross_wg_phase; -- FSUB - CONSTANT c_pol_index : NATURAL := g_sp MOD c_sdp_Q_fft; - CONSTANT c_pfb_index : NATURAL := g_sp / c_sdp_Q_fft; -- only read used WPFB unit out of range(c_sdp_P_pfb = 6) - - CONSTANT c_exp_subband_ampl_raw : REAL := REAL(c_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio; - CONSTANT c_exp_subband_tuple : t_real_arr(0 TO 3) := func_sdp_subband_equalizer( - c_exp_subband_ampl_raw, c_subband_phase, g_subband_weight_gain, g_subband_weight_phase, - c_exp_subband_ampl_raw, c_subband_phase, g_cross_weight_gain, g_cross_weight_phase); - CONSTANT c_exp_subband_ampl_weighted : REAL := sel_a_b(g_use_cross_weight, c_exp_subband_tuple(0), c_exp_subband_ampl_raw * g_subband_weight_gain); - - CONSTANT c_exp_subband_power_raw : REAL := c_exp_subband_ampl_raw**2.0; -- complex signal ampl, so power is A**2 (not A**2 / 2 as for real) - CONSTANT c_exp_subband_power_weighted : REAL := c_exp_subband_ampl_weighted**2.0; -- complex signal ampl, so power is A**2 (not A**2 / 2 as for real) - CONSTANT c_exp_subband_sst_raw : REAL := c_exp_subband_power_raw * REAL(c_nof_block_per_sync); - CONSTANT c_exp_subband_sst_weighted : REAL := c_exp_subband_power_weighted * REAL(c_nof_block_per_sync); + CONSTANT c_pol_index : NATURAL := g_sp MOD c_sdp_Q_fft; + CONSTANT c_pfb_index : NATURAL := g_sp / c_sdp_Q_fft; -- only read used WPFB unit out of range(c_sdp_P_pfb = 6) + + CONSTANT c_exp_co_subband_ampl_raw : REAL := REAL(c_co_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio; + CONSTANT c_exp_cross_subband_ampl_raw : REAL := REAL(c_cross_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio; + CONSTANT c_exp_co_subband_ampl_weighted : REAL := c_exp_co_subband_ampl_raw * g_co_subband_weight_gain; + CONSTANT c_exp_cross_subband_ampl_weighted : REAL := c_exp_cross_subband_ampl_raw * 1.0; -- unit gain, this is co gain for cross sp + CONSTANT c_exp_jones_subband_tuple : t_real_arr(0 TO 3) := func_sdp_subband_equalizer( + c_exp_co_subband_ampl_raw, c_co_subband_phase, g_co_subband_weight_gain, g_co_subband_weight_phase, + c_exp_cross_subband_ampl_raw, c_cross_subband_phase, g_sp_cross_subband_weight_gain, g_sp_cross_subband_weight_phase); + CONSTANT c_exp_sp_subband_ampl_weighted : REAL := sel_a_b(g_use_cross_weight, c_exp_jones_subband_tuple(0), c_exp_co_subband_ampl_weighted); + + CONSTANT c_exp_co_subband_power_raw : REAL := c_exp_co_subband_ampl_raw**2.0; -- complex signal ampl, so power is A**2 (not A**2 / 2 as for real) + CONSTANT c_exp_cross_subband_power_raw : REAL := c_exp_cross_subband_ampl_raw**2.0; + CONSTANT c_exp_sp_subband_power_weighted : REAL := c_exp_sp_subband_ampl_weighted**2.0; + CONSTANT c_exp_cross_subband_power_weighted : REAL := c_exp_cross_subband_ampl_weighted**2.0; + CONSTANT c_exp_co_subband_sst_raw : REAL := c_exp_co_subband_power_raw * REAL(c_nof_block_per_sync); + CONSTANT c_exp_cross_subband_sst_raw : REAL := c_exp_cross_subband_power_raw * REAL(c_nof_block_per_sync); + CONSTANT c_exp_sp_subband_sst_weighted : REAL := c_exp_sp_subband_power_weighted * REAL(c_nof_block_per_sync); + CONSTANT c_exp_cross_subband_sst_weighted : REAL := c_exp_cross_subband_power_weighted * REAL(c_nof_block_per_sync); -- . expected limit values, obtained with print_str() for g_subband = 102, - -- g_wg_ampl = 1.0, g_subband_weight_gain = 1.0, g_subband_weight_phase = 30.0 - CONSTANT c_exp_subband_sst_leakage_snr_dB : REAL := 70.0; -- < 74.913 - CONSTANT c_exp_subband_sst_crosstalk_snr_dB : REAL := 90.0; -- < 96.284 + -- g_co_wg_ampl = 1.0, g_co_subband_weight_gain = 1.0, g_co_subband_weight_phase = 30.0 + CONSTANT c_exp_sp_subband_sst_leakage_snr_dB : REAL := 70.0; -- < 74.913 + CONSTANT c_exp_sp_subband_sst_crosstalk_snr_dB : REAL := 90.0; -- < 96.284 TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL; TyPE t_slv_64_subbands_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_sub-1); -- . Subband weights for selected g_sp - CONSTANT c_subband_weight_re : INTEGER := INTEGER(g_subband_weight_gain * REAL(c_sdp_unit_sub_weight) * COS(g_subband_weight_phase * MATH_2_PI / 360.0)); - CONSTANT c_subband_weight_im : INTEGER := INTEGER(g_subband_weight_gain * REAL(c_sdp_unit_sub_weight) * SIN(g_subband_weight_phase * MATH_2_PI / 360.0)); + CONSTANT c_co_subband_weight_re : INTEGER := INTEGER(g_co_subband_weight_gain * REAL(c_sdp_unit_sub_weight) * COS(g_co_subband_weight_phase * MATH_2_PI / 360.0)); + CONSTANT c_co_subband_weight_im : INTEGER := INTEGER(g_co_subband_weight_gain * REAL(c_sdp_unit_sub_weight) * SIN(g_co_subband_weight_phase * MATH_2_PI / 360.0)); -- . Subband weights cross for selected g_sp - CONSTANT c_cross_subband_weight_re : INTEGER := INTEGER(g_cross_weight_gain * REAL(c_sdp_unit_sub_weight) * COS(g_cross_weight_phase * MATH_2_PI / 360.0)); - CONSTANT c_cross_subband_weight_im : INTEGER := INTEGER(g_cross_weight_gain * REAL(c_sdp_unit_sub_weight) * SIN(g_cross_weight_phase * MATH_2_PI / 360.0)); + CONSTANT c_sp_cross_subband_weight_re : INTEGER := INTEGER(g_sp_cross_subband_weight_gain * REAL(c_sdp_unit_sub_weight) * COS(g_sp_cross_subband_weight_phase * MATH_2_PI / 360.0)); + CONSTANT c_sp_cross_subband_weight_im : INTEGER := INTEGER(g_sp_cross_subband_weight_gain * REAL(c_sdp_unit_sub_weight) * SIN(g_sp_cross_subband_weight_phase * MATH_2_PI / 360.0)); -- MM -- . Address widths of a single MM instance @@ -169,13 +189,13 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_fsub IS -- . Address spans of a single MM instance CONSTANT c_mm_span_reg_diag_wg : NATURAL := 2**c_addr_w_reg_diag_wg; - 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"; - CONSTANT c_mm_file_ram_equalizer_gains : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_EQUALIZER_GAINS"; + 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"; + CONSTANT c_mm_file_ram_equalizer_gains : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_EQUALIZER_GAINS"; CONSTANT c_mm_file_ram_equalizer_gains_cross : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_EQUALIZER_GAINS_CROSS"; - CONSTANT c_mm_file_reg_dp_selector : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_SELECTOR"; - CONSTANT c_mm_file_ram_st_sst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST"; + CONSTANT c_mm_file_reg_dp_selector : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_SELECTOR"; + CONSTANT c_mm_file_ram_st_sst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST"; -- Tb SIGNAL tb_end : STD_LOGIC := '0'; @@ -194,32 +214,33 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_fsub IS SIGNAL sp_subband_ssts_arr2 : t_slv_64_subbands_arr(c_sdp_N_pol-1 DOWNTO 0); -- [pol][sub] SIGNAL sp_subband_sst_sum_arr : t_real_arr(c_sdp_N_pol-1 DOWNTO 0) := (OTHERS => 0.0); SIGNAL sp_subband_sst : REAL := 0.0; + SIGNAL sp_cross_subband_sst : REAL := 0.0; SIGNAL sp_subband_sst_leakage : REAL := 0.0; SIGNAL sp_subband_sst_leakage_snr_dB : REAL := 0.0; -- signal to noise (leakage) ratio - SIGNAL sp_subband_sst_cross : REAL := 0.0; SIGNAL sp_subband_sst_crosstalk : REAL := 0.0; SIGNAL sp_subband_sst_crosstalk_snr_dB : REAL := 0.0; -- signal to noise (crosstalk) ration - SIGNAL exp_subband_ampl : REAL := 0.0; - SIGNAL exp_subband_power : REAL := 0.0; - SIGNAL exp_subband_sst : REAL := 0.0; - SIGNAL stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); + SIGNAL exp_sp_subband_ampl : REAL := 0.0; + SIGNAL exp_sp_subband_power : REAL := 0.0; + SIGNAL exp_sp_subband_sst : REAL := 0.0; + SIGNAL exp_cross_subband_sst : REAL := 0.0; + SIGNAL stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); -- . Selector SIGNAL sst_offload_weighted_subbands : STD_LOGIC; -- . Subband equalizer - SIGNAL sp_subband_weight_re : INTEGER := 0; - SIGNAL sp_subband_weight_im : INTEGER := 0; - SIGNAL sp_subband_weight_gain : REAL := 0.0; - SIGNAL sp_subband_weight_phase : REAL := 0.0; - SIGNAL sp_subband_weight_val : STD_LOGIC := '0'; - - SIGNAL cross_subband_weight_re : INTEGER := 0; - SIGNAL cross_subband_weight_im : INTEGER := 0; - SIGNAL cross_subband_weight_gain : REAL := 0.0; - SIGNAL cross_subband_weight_phase : REAL := 0.0; - SIGNAL cross_subband_weight_val : STD_LOGIC := '0'; + SIGNAL sp_co_subband_weight_re : INTEGER := 0; + SIGNAL sp_co_subband_weight_im : INTEGER := 0; + SIGNAL sp_co_subband_weight_gain : REAL := 0.0; + SIGNAL sp_co_subband_weight_phase : REAL := 0.0; + SIGNAL sp_co_subband_weight_val : STD_LOGIC := '0'; + + SIGNAL sp_cross_subband_weight_re : INTEGER := 0; + SIGNAL sp_cross_subband_weight_im : INTEGER := 0; + SIGNAL sp_cross_subband_weight_gain : REAL := 0.0; + SIGNAL sp_cross_subband_weight_phase : REAL := 0.0; + SIGNAL sp_cross_subband_weight_val : STD_LOGIC := '0'; -- DUT SIGNAL ext_clk : STD_LOGIC := '0'; @@ -304,9 +325,10 @@ BEGIN ); -- Raw or weighted subbands - exp_subband_ampl <= sel_a_b(sst_offload_weighted_subbands = '0', c_exp_subband_ampl_raw, c_exp_subband_ampl_weighted); - exp_subband_power <= sel_a_b(sst_offload_weighted_subbands = '0', c_exp_subband_power_raw, c_exp_subband_power_weighted); - exp_subband_sst <= sel_a_b(sst_offload_weighted_subbands = '0', c_exp_subband_sst_raw, c_exp_subband_sst_weighted); + exp_sp_subband_ampl <= sel_a_b(sst_offload_weighted_subbands = '0', c_exp_co_subband_ampl_raw, c_exp_sp_subband_ampl_weighted); + exp_sp_subband_power <= sel_a_b(sst_offload_weighted_subbands = '0', c_exp_co_subband_power_raw, c_exp_sp_subband_power_weighted); + exp_sp_subband_sst <= sel_a_b(sst_offload_weighted_subbands = '0', c_exp_co_subband_sst_raw, c_exp_sp_subband_sst_weighted); + exp_cross_subband_sst <= sel_a_b(sst_offload_weighted_subbands = '0', c_exp_cross_subband_sst_raw, c_exp_cross_subband_sst_weighted); ------------------------------------------------------------------------------ -- MM slave accesses via file IO @@ -355,17 +377,17 @@ BEGIN -- g_sp is co-polarization v_offset := g_sp * c_mm_span_reg_diag_wg; mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_co_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_co_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl IF g_use_cross_weight THEN -- c_cross_sp is cross-polarization for g_sp, use same WG settings for c_cross_sp as for g_sp v_offset := c_cross_sp * c_mm_span_reg_diag_wg; mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_cross_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_cross_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl END IF; -- Read current BSN @@ -390,27 +412,29 @@ BEGIN mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains, v_addr, rd_data, tb_clk); v_re := unpack_complex_re(rd_data, c_sdp_W_sub_weight); v_im := unpack_complex_im(rd_data, c_sdp_W_sub_weight); - sp_subband_weight_re <= v_re; - sp_subband_weight_im <= v_im; - sp_subband_weight_gain <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_sub_weight); - sp_subband_weight_phase <= atan2(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI; - sp_subband_weight_val <= '1'; + sp_co_subband_weight_re <= v_re; + sp_co_subband_weight_im <= v_im; + sp_co_subband_weight_gain <= COMPLEX_RADIUS(REAL(v_re), REAL(v_im)) / REAL(c_sdp_unit_sub_weight); + sp_co_subband_weight_phase <= COMPLEX_PHASE(REAL(v_re), REAL(v_im)); + sp_co_subband_weight_val <= '1'; proc_common_wait_some_cycles(tb_clk, 1); - ASSERT sp_subband_weight_re = c_sdp_unit_sub_weight REPORT "Default sp_subband_weight_re /= c_sdp_unit_sub_weight" SEVERITY ERROR; - ASSERT sp_subband_weight_im = 0 REPORT "Default sp_subband_weight_im /= 0" SEVERITY ERROR; + ASSERT sp_co_subband_weight_re = c_sdp_unit_sub_weight REPORT "Default sp_co_subband_weight_re /= c_sdp_unit_sub_weight" SEVERITY ERROR; + ASSERT sp_co_subband_weight_im = 0 REPORT "Default sp_co_subband_weight_im /= 0" SEVERITY ERROR; -- . write - v_weight := pack_complex(re => c_subband_weight_re, im => c_subband_weight_im, w => c_sdp_W_sub_weight); -- c_sdp_W_sub_weight = 16 bit + v_weight := pack_complex(re => c_co_subband_weight_re, im => c_co_subband_weight_im, w => c_sdp_W_sub_weight); -- c_sdp_W_sub_weight = 16 bit mmf_mm_bus_wr(c_mm_file_ram_equalizer_gains, v_addr, v_weight, tb_clk); + proc_common_wait_cross_clock_domain_latency(c_tb_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2); -- . read back mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains, v_addr, rd_data, tb_clk); v_re := unpack_complex_re(rd_data, c_sdp_W_sub_weight); v_im := unpack_complex_im(rd_data, c_sdp_W_sub_weight); - sp_subband_weight_re <= v_re; - sp_subband_weight_im <= v_im; - sp_subband_weight_gain <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_sub_weight); - sp_subband_weight_phase <= atan2(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI; - ASSERT sp_subband_weight_re = c_subband_weight_re REPORT "Readback sp_subband_weight_re /= c_subband_weight_re" SEVERITY ERROR; - ASSERT sp_subband_weight_im = c_subband_weight_im REPORT "Readback sp_subband_weight_im /= c_subband_weight_im" SEVERITY ERROR; + sp_co_subband_weight_re <= v_re; + sp_co_subband_weight_im <= v_im; + sp_co_subband_weight_gain <= COMPLEX_RADIUS(REAL(v_re), REAL(v_im)) / REAL(c_sdp_unit_sub_weight); + sp_co_subband_weight_phase <= COMPLEX_PHASE(REAL(v_re), REAL(v_im)); + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT sp_co_subband_weight_re = c_co_subband_weight_re REPORT "Readback sp_co_subband_weight_re /= c_co_subband_weight_re" SEVERITY ERROR; + ASSERT sp_co_subband_weight_im = c_co_subband_weight_im REPORT "Readback sp_co_subband_weight_im /= c_co_subband_weight_im" SEVERITY ERROR; IF g_use_cross_weight THEN -- Cross-polarization subband weight for g_sp @@ -420,27 +444,29 @@ BEGIN mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains_cross, v_addr, rd_data, tb_clk); v_re := unpack_complex_re(rd_data, c_sdp_W_sub_weight); v_im := unpack_complex_im(rd_data, c_sdp_W_sub_weight); - cross_subband_weight_re <= v_re; - cross_subband_weight_im <= v_im; - cross_subband_weight_gain <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_sub_weight); - cross_subband_weight_phase <= atan2(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI; - cross_subband_weight_val <= '1'; + sp_cross_subband_weight_re <= v_re; + sp_cross_subband_weight_im <= v_im; + sp_cross_subband_weight_gain <= COMPLEX_RADIUS(REAL(v_re), REAL(v_im)) / REAL(c_sdp_unit_sub_weight); + sp_cross_subband_weight_phase <= COMPLEX_PHASE(REAL(v_re), REAL(v_im)); + sp_cross_subband_weight_val <= '1'; proc_common_wait_some_cycles(tb_clk, 1); - ASSERT cross_subband_weight_re = 0 REPORT "Default cross_subband_weight_re /= 0" SEVERITY ERROR; - ASSERT cross_subband_weight_im = 0 REPORT "Default cross_subband_weight_im /= 0" SEVERITY ERROR; + ASSERT sp_cross_subband_weight_re = 0 REPORT "Default sp_cross_subband_weight_re /= 0" SEVERITY ERROR; + ASSERT sp_cross_subband_weight_im = 0 REPORT "Default sp_cross_subband_weight_im /= 0" SEVERITY ERROR; -- . write - v_weight := pack_complex(re => c_cross_subband_weight_re, im => c_cross_subband_weight_im, w => c_sdp_W_sub_weight); -- c_sdp_W_sub_weight = 16 bit + v_weight := pack_complex(re => c_sp_cross_subband_weight_re, im => c_sp_cross_subband_weight_im, w => c_sdp_W_sub_weight); -- c_sdp_W_sub_weight = 16 bit mmf_mm_bus_wr(c_mm_file_ram_equalizer_gains_cross, v_addr, v_weight, tb_clk); + proc_common_wait_cross_clock_domain_latency(c_tb_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2); -- . read back mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains_cross, v_addr, rd_data, tb_clk); v_re := unpack_complex_re(rd_data, c_sdp_W_sub_weight); v_im := unpack_complex_im(rd_data, c_sdp_W_sub_weight); - cross_subband_weight_re <= v_re; - cross_subband_weight_im <= v_im; - cross_subband_weight_gain <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_sub_weight); - cross_subband_weight_phase <= atan2(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI; - ASSERT cross_subband_weight_re = c_cross_subband_weight_re REPORT "Readback cross_subband_weight_re /= c_cross_subband_weight_re" SEVERITY ERROR; - ASSERT cross_subband_weight_im = c_cross_subband_weight_im REPORT "Readback cross_subband_weight_im /= c_cross_subband_weight_im" SEVERITY ERROR; + sp_cross_subband_weight_re <= v_re; + sp_cross_subband_weight_im <= v_im; + sp_cross_subband_weight_gain <= COMPLEX_RADIUS(REAL(v_re), REAL(v_im)) / REAL(c_sdp_unit_sub_weight); + sp_cross_subband_weight_phase <= COMPLEX_PHASE(REAL(v_re), REAL(v_im)); + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT sp_cross_subband_weight_re = c_sp_cross_subband_weight_re REPORT "Readback sp_cross_subband_weight_re /= c_sp_cross_subband_weight_re" SEVERITY ERROR; + ASSERT sp_cross_subband_weight_im = c_sp_cross_subband_weight_im REPORT "Readback sp_cross_subband_weight_im /= c_sp_cross_subband_weight_im" SEVERITY ERROR; END IF; ---------------------------------------------------------------------------- @@ -498,7 +524,7 @@ BEGIN -- sinus, so most power will be in 1 subband. sp_subband_sst <= TO_UREAL(sp_subband_ssts_arr2(c_pol_index)(g_subband)); -- Subband power of g_subband in c_cross_sp - sp_subband_sst_cross <= TO_UREAL(sp_subband_ssts_arr2(not_int(c_pol_index))(g_subband)); + sp_cross_subband_sst <= TO_UREAL(sp_subband_ssts_arr2(not_int(c_pol_index))(g_subband)); proc_common_wait_some_cycles(tb_clk, 1); -- The sp_subband_sst_leakage shows how much power from the input sinus at a specific @@ -533,61 +559,67 @@ BEGIN --------------------------------------------------------------------------- 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(". c_co_wg_ampl for g_sp = " & int_to_str(c_co_wg_ampl)); + print_str(". c_cross_wg_ampl for c_cross_sp = " & int_to_str(c_cross_wg_ampl)); print_str(""); print_str("Subband selector:"); - print_str(". sst_offload_weighted_subbands = " & sl_to_str(sst_offload_weighted_subbands)); + print_str(". sst_offload_weighted_subbands = " & sl_to_str(sst_offload_weighted_subbands)); 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("Subband weights for g_sp:"); + print_str(". sp_co_subband_weight_gain = " & real_to_str(sp_co_subband_weight_gain, 20, 6)); + print_str(". sp_co_subband_weight_phase = " & real_to_str(sp_co_subband_weight_phase, 20, 6)); IF g_use_cross_weight THEN - print_str(". cross_subband_weight_gain = " & real_to_str(cross_subband_weight_gain, 20, 6)); - print_str(". cross_subband_weight_phase = " & real_to_str(cross_subband_weight_phase, 20, 6)); + print_str(". sp_cross_subband_weight_gain = " & real_to_str(sp_cross_subband_weight_gain, 20, 6)); + print_str(". sp_cross_subband_weight_phase = " & real_to_str(sp_cross_subband_weight_phase, 20, 6)); END IF; print_str(""); print_str("SST results:"); - print_str(". exp_subband_ampl = " & int_to_str(NATURAL(exp_subband_ampl))); - print_str(". exp_subband_power = " & real_to_str(exp_subband_power, 20, 1)); - print_str(". exp_subband_sst = " & real_to_str(exp_subband_sst, 20, 1)); + print_str(". exp_sp_subband_ampl = " & int_to_str(NATURAL(exp_sp_subband_ampl))); + print_str(". exp_sp_subband_power = " & real_to_str(exp_sp_subband_power, 20, 1)); + print_str(". exp_sp_subband_sst = " & real_to_str(exp_sp_subband_sst, 20, 1)); + print_str(". exp_cross_subband_sst = " & real_to_str(exp_cross_subband_sst, 20, 1)); print_str(""); - print_str(". sp_subband_sst = " & real_to_str(sp_subband_sst, 20, 1)); - print_str(". sp_subband_sst / exp_subband_sst = " & real_to_str(sp_subband_sst / exp_subband_sst, 20, 6)); + print_str(". sp_subband_sst = " & real_to_str(sp_subband_sst, 20, 1)); + print_str(". sp_subband_sst / exp_sp_subband_sst = " & real_to_str(sp_subband_sst / exp_sp_subband_sst, 20, 6)); + print_str(". sp_cross_subband_sst = " & real_to_str(sp_cross_subband_sst, 20, 1)); + print_str(". sp_cross_subband_sst / exp_cross_subband_sst = " & real_to_str(sp_cross_subband_sst / exp_cross_subband_sst, 20, 6)); IF g_read_all_SST THEN -- Log WPFB details, these are allready verified in tb of wpfb_unit_dev.vhd, so here -- quality indicators like leakage and crosstalk are also reported out of interest. print_str(""); print_str("SST quality indicators"); - print_str(". sp_subband_sst_leakage = " & real_to_str(sp_subband_sst_leakage, 20, 0)); - print_str(". sp_subband_sst_leakage_snr_dB = " & real_to_str(sp_subband_sst_leakage_snr_dB, 20, 3)); - print_str(". sp_subband_sst_crosstalk = " & real_to_str(sp_subband_sst_crosstalk, 20, 0)); - print_str(". sp_subband_sst_crosstalk_snr_db = " & real_to_str(sp_subband_sst_crosstalk_snr_db, 20, 3)); + print_str(". sp_subband_sst_leakage = " & real_to_str(sp_subband_sst_leakage, 20, 0)); + print_str(". sp_subband_sst_leakage_snr_dB = " & real_to_str(sp_subband_sst_leakage_snr_dB, 20, 3)); + IF NOT g_use_cross_weight THEN + print_str(". sp_subband_sst_crosstalk = " & real_to_str(sp_subband_sst_crosstalk, 20, 0)); + print_str(". sp_subband_sst_crosstalk_snr_db = " & real_to_str(sp_subband_sst_crosstalk_snr_db, 20, 3)); + END IF; END IF; --------------------------------------------------------------------------- -- Verify SST --------------------------------------------------------------------------- -- Verify expected subband power based on WG power for g_sp - ASSERT sp_subband_sst > c_lo_factor * exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; - ASSERT sp_subband_sst < c_hi_factor * exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; + ASSERT sp_subband_sst > c_lo_factor * exp_sp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; + ASSERT sp_subband_sst < c_hi_factor * exp_sp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; IF g_use_cross_weight THEN -- Verify expected subband power based on WG power for c_cross_sp -- The other WPFB input WG at c_cross_sp is used as cross polarization input, with default -- unit co-polarization subband weight and zero cross-polarization subband weight. - ASSERT sp_subband_sst_cross > c_lo_factor * c_exp_subband_sst_raw REPORT "Wrong subband power for cross SP " & NATURAL'IMAGE(c_cross_sp) SEVERITY ERROR; - ASSERT sp_subband_sst_cross < c_hi_factor * c_exp_subband_sst_raw REPORT "Wrong subband power for cross SP " & NATURAL'IMAGE(c_cross_sp) SEVERITY ERROR; + ASSERT sp_cross_subband_sst > c_lo_factor * exp_cross_subband_sst REPORT "Wrong subband power for cross SP " & NATURAL'IMAGE(c_cross_sp) SEVERITY ERROR; + ASSERT sp_cross_subband_sst < c_hi_factor * exp_cross_subband_sst REPORT "Wrong subband power for cross SP " & NATURAL'IMAGE(c_cross_sp) SEVERITY ERROR; END IF; IF g_read_all_SST THEN -- Verify expected SNR quality measures - ASSERT sp_subband_sst_leakage = 0.0 OR sp_subband_sst_leakage_snr_dB > c_exp_subband_sst_leakage_snr_dB REPORT "Wrong too much leakage for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; - ASSERT sp_subband_sst_crosstalk = 0.0 OR sp_subband_sst_crosstalk_snr_dB > c_exp_subband_sst_crosstalk_snr_dB REPORT "Wrong too much crosstalk for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; + ASSERT sp_subband_sst_leakage = 0.0 OR sp_subband_sst_leakage_snr_dB > c_exp_sp_subband_sst_leakage_snr_dB REPORT "Wrong too much leakage for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; + IF NOT g_use_cross_weight THEN + ASSERT sp_subband_sst_crosstalk = 0.0 OR sp_subband_sst_crosstalk_snr_dB > c_exp_sp_subband_sst_crosstalk_snr_dB REPORT "Wrong too much crosstalk for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; + END IF; END IF; ---------------------------------------------------------------------------