From 43f096a5f7dc205754f7bb9ca101876ec038507c Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Thu, 10 Mar 2022 09:09:45 +0100 Subject: [PATCH] Added remnant signal input settings to also verify the BF summator. --- .../tb_lofar2_unb2c_sdp_station_bf.vhd | 267 ++++++++++++------ 1 file changed, 179 insertions(+), 88 deletions(-) diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd index 890adcf128..c641685358 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd @@ -26,22 +26,29 @@ -- -- Description: -- This tb is a balance between verification coverage and keeping it simple: --- - Use only one signal input (g_sp), put small unused signal on the other --- signal inputs. --- - Use different BF weight for the two beamlet polarizations (g_bf_*_gain, --- and g_bf_*_phase) of signal input g_sp. Keep BF weight for the other --- signal inputs = 0 to block them from the beamlet. --- - Select one beamlet for the subband (g_beamlet). +-- - Use only one signal input (g_sp). Put same remnant WG signal on the +-- other signal inputs. +-- - Use different BF weight for the two beamlet polarizations (g_bf_x_gain, +-- g_bf_x_phase and g_bf_y_phase, g_bf_y_phase) of signal input g_sp. +-- Using different BF weights for the N_pol_bf = 2 BF polarizations allows +-- verification of the dual polarization beamlet. +-- - Use same remnant BF weight for the other S_pn - 1 = 11 signal inputs. +-- The remnant signal inputs and BF weights allow verifying the BF sum if +-- they are not 0. Using the same settings for all remnant SP simplyfies +-- the tb, while still testing the BF sum. +-- - Select one beamlet for the subband (g_beamlet). Selecting one beamlet +-- other than the default beamlet for the subband is sufficient to verify +-- the beamlet subband select. -- - Use same stimuli for both beamsets. -- -- MM control actions: -- -- 1) Enable calc mode for WG on signal input (si) g_sp via reg_diag_wg with: -- g_subband = 102 --> 102 * f_sub = 19.921875 MHz --- g_wg_ampl = 1.0 --> 1.0 yield WG ampl = 2**13 --- g_wg_phase --> subband phase --- Use g_unused_ampl = 0.1 and g_unused_phase = 0.0 for the other signal --- inputs, that are not used in the BF. +-- g_sp_ampl = 1.0 --> 1.0 yield WG ampl = 2**13 +-- g_sp_phase --> subband phase +-- Use g_sp_remnant_ampl = 0.1 and g_sp_remnant_phase = 0.0 for the other +-- S_pn-1 = 11 signal inputs, than g_sp, that are not used in the BF. -- -- 2) Read current BSN from reg_bsn_scheduler_wg and write -- reg_bsn_scheduler_wg to trigger start of WG at BSN. @@ -95,6 +102,10 @@ -- View rx_beamlet_sosi -- View rx_beamlet_cnt (in analog format) -- +-- Remark: +-- . 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) +-- -- Usage: -- > as 7 # default -- > as 12 # for detailed debugging @@ -129,37 +140,41 @@ USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY tb_lofar2_unb2c_sdp_station_bf IS GENERIC ( - g_sp : NATURAL := 3; -- WG signal path index in range(S_pn = 12) - g_wg_ampl : REAL := 1.0; -- WG normalized amplitude - g_wg_phase : REAL := 0.0; -- WG phase in degrees = subband phase - g_unused_ampl : REAL := 0.1; -- WG normalized amplitude for unused sp - g_unused_phase : REAL := 0.0; -- WG phase in degrees for unused sp - g_subband : NATURAL := 102; -- select g_subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz - g_beamlet : NATURAL := 10; -- map g_subband to g_beamlet index in beamset in range(c_sdp_S_sub_bf = 488) - g_beamlet_scale : REAL := 1.0 / 2.0**9; -- g_beamlet output scale factor - g_bf_x_gain : REAL := 0.7; -- g_beamlet X BF weight normalized gain - g_bf_y_gain : REAL := 0.6; -- g_beamlet Y BF weight normalized gain - g_bf_x_phase : REAL := 30.0; -- g_beamlet X BF weight phase rotation in degrees - g_bf_y_phase : REAL := 40.0; -- g_beamlet Y BF weight phase rotation in degrees - g_read_all_SST : BOOLEAN := FALSE; -- when FALSE only read SST for g_subband, to save sim time - g_read_all_BST : BOOLEAN := FALSE -- when FALSE only read BST for g_beamlet, to save sim time + g_sp : NATURAL := 3; -- WG signal path (SP) index in range(S_pn = 12) + g_sp_ampl : REAL := 0.5; -- WG normalized amplitude + g_sp_phase : REAL := -110.0; -- WG phase in degrees = subband phase + g_sp_remnant_ampl : REAL := 0.1; -- WG normalized amplitude for remnant sp + g_sp_remnant_phase : REAL := 15.0; -- WG phase in degrees for remnant sp + g_subband : NATURAL := 102; -- select g_subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz + g_beamlet : NATURAL := 10; -- map g_subband to g_beamlet index in beamset in range(c_sdp_S_sub_bf = 488) + g_beamlet_scale : REAL := 1.0 / 2.0**9; -- g_beamlet output scale factor + g_bf_x_gain : REAL := 0.7; -- g_beamlet X BF weight normalized gain for g_sp + g_bf_y_gain : REAL := 0.6; -- g_beamlet Y BF weight normalized gain for g_sp + g_bf_x_phase : REAL := 30.0; -- g_beamlet X BF weight phase rotation in degrees for g_sp + g_bf_y_phase : REAL := 40.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp + g_bf_remnant_x_gain : REAL := 0.05; -- g_beamlet X BF weight normalized gain for remnant sp + g_bf_remnant_y_gain : REAL := 0.04; -- g_beamlet Y BF weight normalized gain for remnant sp + g_bf_remnant_x_phase : REAL := 170.0; -- g_beamlet X BF weight phase rotation in degrees for g_sp + g_bf_remnant_y_phase : REAL := -135.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp + g_read_all_SST : BOOLEAN := FALSE; -- when FALSE only read SST for g_subband, to save sim time + g_read_all_BST : BOOLEAN := FALSE -- when FALSE only read BST for g_beamlet, to save sim time ); END tb_lofar2_unb2c_sdp_station_bf; ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS - CONSTANT c_sim : BOOLEAN := TRUE; - CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 - CONSTANT c_node_nr : NATURAL := 0; - CONSTANT c_gn_index : NATURAL := c_unb_nr * 4 + c_node_nr; -- this node GN - CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0 + CONSTANT c_sim : BOOLEAN := TRUE; + CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 + CONSTANT c_node_nr : NATURAL := 0; + CONSTANT c_gn_index : NATURAL := c_unb_nr * 4 + c_node_nr; -- this node GN + CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0 - CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_gn_index, 8); - CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; - CONSTANT c_fw_version : t_unb2c_board_fw_version := (1, 0); + CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_gn_index, 8); + CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; + CONSTANT c_fw_version : t_unb2c_board_fw_version := (1, 0); - CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr, 8); - CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr+1, 8); -- +1 to avoid IP = *.*.*.0 + CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr, 8); + CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr+1, 8); -- +1 to avoid IP = *.*.*.0 CONSTANT c_eth_clk_period : TIME := 8 ns; -- 125 MHz XO on UniBoard CONSTANT c_ext_clk_period : TIME := 5 ns; @@ -212,67 +227,106 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS -- .ampl CONSTANT c_wg_ampl_full_scale : NATURAL := 2**(c_sdp_W_adc-1); -- full scale (FS) of WG, will just cause clipping of +FS to +FS-1 CONSTANT c_wg_ampl_lsb : REAL := c_diag_wg_ampl_unit / REAL(c_wg_ampl_full_scale); -- amplitude in number of LSbit resolution steps - CONSTANT c_wg_ampl : NATURAL := NATURAL(g_wg_ampl * REAL(c_wg_ampl_full_scale)); -- in number of lsb - CONSTANT c_wg_unused_ampl : NATURAL := NATURAL(g_unused_ampl * REAL(c_wg_ampl_full_scale)); -- in number of lsb + CONSTANT c_wg_ampl : NATURAL := NATURAL(g_sp_ampl * REAL(c_wg_ampl_full_scale)); -- in number of lsb + CONSTANT c_wg_remnant_ampl : NATURAL := NATURAL(g_sp_remnant_ampl * REAL(c_wg_ampl_full_scale)); -- 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); -- . phase CONSTANT c_subband_freq : REAL := REAL(g_subband) / REAL(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate 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 := g_wg_phase + c_wg_phase_offset; -- WG phase in degrees - CONSTANT c_wg_unused_phase : REAL := g_unused_phase + c_wg_phase_offset; -- WG phase in degrees + CONSTANT c_wg_phase : REAL := g_sp_phase + c_wg_phase_offset; -- WG phase in degrees + CONSTANT c_wg_remnant_phase : REAL := g_sp_remnant_phase + c_wg_phase_offset; -- WG phase in degrees -- . freq CONSTANT c_wg_subband_freq_unit : REAL := c_diag_wg_freq_unit/REAL(c_sdp_N_fft); -- subband freq = Fs/1024 = 200 MSps/1024 = 195312.5 Hz sinus -- WPFB - 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_subband_phase : REAL := g_wg_phase; -- wanted subband phase in degrees = WG phase at sop - CONSTANT c_subband_phase_offset : REAL := -90.0; -- WG with zero phase sinues yields subband with -90 degrees phase (negative Im, zero Re) - CONSTANT c_subband_weight_gain : REAL := 1.0; -- use default unit subband weights - CONSTANT c_subband_weight_phase : REAL := 0.0; -- use default unit subband weights - CONSTANT c_exp_subband_sp_ampl_ratio : REAL := 8.0 * c_sdp_wpfb_fir_filter_dc_gain; -- ~= 8 for unit FIR DC gain, depends on internal WPFB quantization and FIR coefficients - CONSTANT c_exp_subband_ampl : REAL := REAL(c_wg_ampl) * c_exp_subband_sp_ampl_ratio * c_subband_weight_gain; - 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); - - TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL; + 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_subband_phase_offset : REAL := -90.0; -- WG with zero phase sinus yields subband with -90 degrees phase (negative Im, zero Re) + CONSTANT c_subband_weight_gain : REAL := 1.0; -- use default unit subband weights + 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_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; + CONSTANT c_exp_remnant_subband_ampl : REAL := REAL(c_wg_remnant_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio * c_subband_weight_gain; + + 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); -- 512 TYPE t_slv_64_beamlets_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_beamlets_sdp-1); -- 2*488 = 976 -- BF X-pol and Y-pol -- . select - CONSTANT c_exp_beamlet_x_index : NATURAL := g_beamlet * c_sdp_N_pol_bf; -- in beamset 0 - CONSTANT c_exp_beamlet_y_index : NATURAL := g_beamlet * c_sdp_N_pol_bf + 1; -- in beamset 0 + CONSTANT c_exp_beamlet_x_index : NATURAL := g_beamlet * c_sdp_N_pol_bf; -- X index in beamset 0 + CONSTANT c_exp_beamlet_y_index : NATURAL := g_beamlet * c_sdp_N_pol_bf + 1; -- Y index in beamset 0 -- . Beamlet weights for selected g_sp - CONSTANT c_bf_x_weight_re : INTEGER := INTEGER(g_bf_x_gain * REAL(c_sdp_unit_bf_weight) * COS(g_bf_x_phase * MATH_2_PI / 360.0)); - CONSTANT c_bf_x_weight_im : INTEGER := INTEGER(g_bf_x_gain * REAL(c_sdp_unit_bf_weight) * SIN(g_bf_x_phase * MATH_2_PI / 360.0)); - CONSTANT c_bf_y_weight_re : INTEGER := INTEGER(g_bf_y_gain * REAL(c_sdp_unit_bf_weight) * COS(g_bf_y_phase * MATH_2_PI / 360.0)); - CONSTANT c_bf_y_weight_im : INTEGER := INTEGER(g_bf_y_gain * REAL(c_sdp_unit_bf_weight) * SIN(g_bf_y_phase * MATH_2_PI / 360.0)); + CONSTANT c_bf_x_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_x_phase)); + CONSTANT c_bf_x_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_x_phase)); + CONSTANT c_bf_y_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_y_phase)); + CONSTANT c_bf_y_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_y_phase)); + CONSTANT c_bf_remnant_x_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_remnant_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_x_phase)); + CONSTANT c_bf_remnant_x_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_remnant_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_x_phase)); + CONSTANT c_bf_remnant_y_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase)); + CONSTANT c_bf_remnant_y_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase)); + + -- Model the SDP beamformer for one g_sp and S_pn-1 = 11 remnant signal inputs + FUNCTION bf_calculate_expected_beamlet(sp_subband_ampl, sp_subband_phase, sp_bf_gain, sp_bf_phase, + rem_subband_ampl, rem_subband_phase, rem_bf_gain, rem_bf_phase : REAL) RETURN t_real_arr IS -- 0:3 = ampl, phase, re, im + CONSTANT c_nof_rem : REAL := REAL(c_sdp_S_pn - 1); -- BF for one g_sp and 11 remnant signal inputs + VARIABLE v_sp_ampl, v_sp_phase, v_sp_re, v_sp_im : REAL; + VARIABLE v_rem_ampl, v_rem_phase, v_rem_re, v_rem_im : REAL; + VARIABLE v_sum_ampl, v_sum_phase, v_sum_re, v_sum_im : REAL; + VARIABLE v_tuple : t_real_arr(0 TO 3); + BEGIN + v_sp_ampl := sp_subband_ampl * sp_bf_gain; + v_sp_phase := sp_subband_phase + sp_bf_phase; + v_sp_re := COMPLEX_RE(v_sp_ampl, v_sp_phase); + v_sp_im := COMPLEX_IM(v_sp_ampl, v_sp_phase); + v_rem_ampl := rem_subband_ampl * rem_bf_gain; + v_rem_phase := rem_subband_phase + rem_bf_phase; + v_rem_re := COMPLEX_RE(v_rem_ampl, v_rem_phase); + v_rem_im := COMPLEX_IM(v_rem_ampl, v_rem_phase); + v_sum_re := v_sp_re + c_nof_rem * v_rem_re; -- BF sum re + v_sum_im := v_sp_im + c_nof_rem * v_rem_im; -- BF sum im + v_sum_ampl := COMPLEX_RADIUS(v_sum_re, v_sum_im); + v_sum_phase := COMPLEX_PHASE(v_sum_re, v_sum_im); + v_tuple := (0 => v_sum_ampl, 1 => v_sum_phase, 2 => v_sum_re, 3 => v_sum_im); + RETURN v_tuple; + END; + -- . Beamlet internal - CONSTANT c_exp_beamlet_x_ampl : REAL := c_exp_subband_ampl * g_bf_x_gain; - CONSTANT c_exp_beamlet_x_phase : REAL := c_subband_phase_offset + c_subband_weight_phase + g_bf_x_phase; - CONSTANT c_exp_beamlet_x_re : REAL := c_exp_beamlet_x_ampl * COS(c_exp_beamlet_x_phase * MATH_2_PI / 360.0); - CONSTANT c_exp_beamlet_x_im : REAL := c_exp_beamlet_x_ampl * SIN(c_exp_beamlet_x_phase * MATH_2_PI / 360.0); - CONSTANT c_exp_beamlet_y_ampl : REAL := c_exp_subband_ampl * g_bf_y_gain; - CONSTANT c_exp_beamlet_y_phase : REAL := c_subband_phase_offset + c_subband_weight_phase + g_bf_y_phase; - CONSTANT c_exp_beamlet_y_re : REAL := c_exp_beamlet_y_ampl * COS(c_exp_beamlet_y_phase * MATH_2_PI / 360.0); - CONSTANT c_exp_beamlet_y_im : REAL := c_exp_beamlet_y_ampl * SIN(c_exp_beamlet_y_phase * MATH_2_PI / 360.0); + CONSTANT c_exp_beamlet_x_tuple : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet( + c_exp_subband_ampl, c_exp_subband_phase, g_bf_x_gain, g_bf_x_phase, + c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_x_gain, g_bf_remnant_x_phase); + CONSTANT c_exp_beamlet_x_ampl : REAL := c_exp_beamlet_x_tuple(0); + CONSTANT c_exp_beamlet_x_phase : REAL := c_exp_beamlet_x_tuple(1); + CONSTANT c_exp_beamlet_x_re : REAL := c_exp_beamlet_x_tuple(2); + CONSTANT c_exp_beamlet_x_im : REAL := c_exp_beamlet_x_tuple(3); + + CONSTANT c_exp_beamlet_y_tuple : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet( + c_exp_subband_ampl, c_exp_subband_phase, g_bf_y_gain, g_bf_y_phase, + c_exp_remnant_subband_ampl, c_exp_remnant_subband_phase, g_bf_remnant_y_gain, g_bf_remnant_y_phase); + CONSTANT c_exp_beamlet_y_ampl : REAL := c_exp_beamlet_y_tuple(0); + CONSTANT c_exp_beamlet_y_phase : REAL := c_exp_beamlet_y_tuple(1); + CONSTANT c_exp_beamlet_y_re : REAL := c_exp_beamlet_y_tuple(2); + CONSTANT c_exp_beamlet_y_im : REAL := c_exp_beamlet_y_tuple(3); -- . BST - CONSTANT c_exp_beamlet_x_power : REAL := c_exp_beamlet_x_ampl**2.0; -- complex, so no divide by 2 - CONSTANT c_exp_beamlet_x_bst : REAL := c_exp_subband_sst * g_bf_x_gain**2.0; -- = c_exp_beamlet_x_power * REAL(c_nof_block_per_sync) - CONSTANT c_exp_beamlet_y_power : REAL := c_exp_beamlet_y_ampl**2.0; -- complex, so no divide by 2 - CONSTANT c_exp_beamlet_y_bst : REAL := c_exp_subband_sst * g_bf_y_gain**2.0; -- = c_exp_beamlet_y_power * REAL(c_nof_block_per_sync) + CONSTANT c_exp_beamlet_x_power : REAL := c_exp_beamlet_x_ampl**2.0; -- complex signal ampl, so no divide by 2 + CONSTANT c_exp_beamlet_x_bst : REAL := c_exp_beamlet_x_power * REAL(c_nof_block_per_sync); + CONSTANT c_exp_beamlet_y_power : REAL := c_exp_beamlet_y_ampl**2.0; -- complex signal ampl, so no divide by 2 + CONSTANT c_exp_beamlet_y_bst : REAL := c_exp_beamlet_y_power * REAL(c_nof_block_per_sync); -- . Beamlet output - CONSTANT c_exp_beamlet_x_output_ampl : REAL := c_exp_beamlet_x_ampl * g_beamlet_scale; - CONSTANT c_exp_beamlet_x_output_phase : REAL := c_exp_beamlet_x_phase; - CONSTANT c_exp_beamlet_x_output_re : REAL := c_exp_beamlet_x_re * g_beamlet_scale; - CONSTANT c_exp_beamlet_x_output_im : REAL := c_exp_beamlet_x_im * g_beamlet_scale; - CONSTANT c_exp_beamlet_y_output_ampl : REAL := c_exp_beamlet_y_ampl * g_beamlet_scale; - CONSTANT c_exp_beamlet_y_output_phase : REAL := c_exp_beamlet_y_phase; - CONSTANT c_exp_beamlet_y_output_re : REAL := c_exp_beamlet_y_re * g_beamlet_scale; - CONSTANT c_exp_beamlet_y_output_im : REAL := c_exp_beamlet_y_im * g_beamlet_scale; + CONSTANT c_exp_beamlet_x_output_ampl : REAL := c_exp_beamlet_x_ampl * g_beamlet_scale; + CONSTANT c_exp_beamlet_x_output_phase : REAL := c_exp_beamlet_x_phase; + CONSTANT c_exp_beamlet_x_output_re : REAL := c_exp_beamlet_x_re * g_beamlet_scale; + CONSTANT c_exp_beamlet_x_output_im : REAL := c_exp_beamlet_x_im * g_beamlet_scale; + CONSTANT c_exp_beamlet_y_output_ampl : REAL := c_exp_beamlet_y_ampl * g_beamlet_scale; + CONSTANT c_exp_beamlet_y_output_phase : REAL := c_exp_beamlet_y_phase; + CONSTANT c_exp_beamlet_y_output_re : REAL := c_exp_beamlet_y_re * g_beamlet_scale; + CONSTANT c_exp_beamlet_y_output_im : REAL := c_exp_beamlet_y_im * g_beamlet_scale; -- MM -- . Address widths of a single MM instance @@ -588,7 +642,40 @@ BEGIN 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 ---------------------------------------------------------------------------- @@ -722,7 +809,7 @@ BEGIN -- 1 : phase[15:0] -- 2 : freq[30:0] -- 3 : ampl[16:0] - -- . Put wanted signal on g_sp input and unused signal on the other inputs + -- . Put wanted signal on g_sp input and remnant signal on the other inputs FOR S IN 0 TO c_sdp_S_pn-1 LOOP v_offset := S * c_mm_span_reg_diag_wg; IF s = g_sp THEN @@ -732,9 +819,9 @@ BEGIN mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_ampl) * c_wg_ampl_lsb), tb_clk); -- ampl ELSE 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_unused_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_wg_remnant_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_wg_subband_freq_unit), tb_clk); -- freq - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_unused_ampl) * c_wg_ampl_lsb), tb_clk); -- ampl + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_remnant_ampl) * c_wg_ampl_lsb), tb_clk); -- ampl END IF; END LOOP; @@ -769,8 +856,8 @@ BEGIN 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_gain <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_sub_weight); + sp_subband_weight_phase <= COMPLEX_PHASE(v_re, v_im); -- No need to write subband weight, because default it is unit weight @@ -833,8 +920,12 @@ BEGIN v_weight := pack_complex(re => c_bf_y_weight_re, im => c_bf_y_weight_im, w => c_sdp_W_bf_weight); END IF; ELSE - -- default set all weights to zero - v_weight := 0; + -- use the remnant BF weights for the other SP + IF PB = 0 THEN + v_weight := pack_complex(re => c_bf_remnant_x_weight_re, im => c_bf_remnant_x_weight_im, w => c_sdp_W_bf_weight); + ELSE + v_weight := pack_complex(re => c_bf_remnant_y_weight_re, im => c_bf_remnant_y_weight_im, w => c_sdp_W_bf_weight); + END IF; END IF; v_addr := g_beamlet; -- beamlet index v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset @@ -866,13 +957,13 @@ BEGIN IF PB = 0 THEN sp_bf_x_weights_re_arr(v_S) <= v_re; sp_bf_x_weights_im_arr(v_S) <= v_im; - sp_bf_x_weights_gain_arr(v_S) <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_bf_weight); - sp_bf_x_weights_phase_arr(v_S) <= atan2(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI; + sp_bf_x_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight); + sp_bf_x_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im); ELSE sp_bf_y_weights_re_arr(v_S) <= v_re; sp_bf_y_weights_im_arr(v_S) <= v_im; - sp_bf_y_weights_gain_arr(v_S) <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_bf_weight); - sp_bf_y_weights_phase_arr(v_S) <= atan2(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI; + sp_bf_y_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight); + sp_bf_y_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im); END IF; END LOOP; END LOOP; -- GitLab