Skip to content
Snippets Groups Projects
Commit 43f096a5 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Added remnant signal input settings to also verify the BF summator.

parent 08d68af1
No related branches found
No related tags found
1 merge request!219No functional change. Use short index variables names in capitals, to ease...
...@@ -26,22 +26,29 @@ ...@@ -26,22 +26,29 @@
-- --
-- Description: -- Description:
-- This tb is a balance between verification coverage and keeping it simple: -- 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 -- - Use only one signal input (g_sp). Put same remnant WG signal on the
-- signal inputs. -- other signal inputs.
-- - Use different BF weight for the two beamlet polarizations (g_bf_*_gain, -- - Use different BF weight for the two beamlet polarizations (g_bf_x_gain,
-- and g_bf_*_phase) of signal input g_sp. Keep BF weight for the other -- g_bf_x_phase and g_bf_y_phase, g_bf_y_phase) of signal input g_sp.
-- signal inputs = 0 to block them from the beamlet. -- Using different BF weights for the N_pol_bf = 2 BF polarizations allows
-- - Select one beamlet for the subband (g_beamlet). -- 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. -- - Use same stimuli for both beamsets.
-- --
-- MM control actions: -- MM control actions:
-- --
-- 1) Enable calc mode for WG on signal input (si) g_sp via reg_diag_wg with: -- 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_subband = 102 --> 102 * f_sub = 19.921875 MHz
-- g_wg_ampl = 1.0 --> 1.0 yield WG ampl = 2**13 -- g_sp_ampl = 1.0 --> 1.0 yield WG ampl = 2**13
-- g_wg_phase --> subband phase -- g_sp_phase --> subband phase
-- Use g_unused_ampl = 0.1 and g_unused_phase = 0.0 for the other signal -- Use g_sp_remnant_ampl = 0.1 and g_sp_remnant_phase = 0.0 for the other
-- inputs, that are not used in the BF. -- 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 -- 2) Read current BSN from reg_bsn_scheduler_wg and write
-- reg_bsn_scheduler_wg to trigger start of WG at BSN. -- reg_bsn_scheduler_wg to trigger start of WG at BSN.
...@@ -95,6 +102,10 @@ ...@@ -95,6 +102,10 @@
-- View rx_beamlet_sosi -- View rx_beamlet_sosi
-- View rx_beamlet_cnt (in analog format) -- 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: -- Usage:
-- > as 7 # default -- > as 7 # default
-- > as 12 # for detailed debugging -- > as 12 # for detailed debugging
...@@ -129,37 +140,41 @@ USE tech_pll_lib.tech_pll_component_pkg.ALL; ...@@ -129,37 +140,41 @@ USE tech_pll_lib.tech_pll_component_pkg.ALL;
ENTITY tb_lofar2_unb2c_sdp_station_bf IS ENTITY tb_lofar2_unb2c_sdp_station_bf IS
GENERIC ( GENERIC (
g_sp : NATURAL := 3; -- WG signal path index in range(S_pn = 12) g_sp : NATURAL := 3; -- WG signal path (SP) index in range(S_pn = 12)
g_wg_ampl : REAL := 1.0; -- WG normalized amplitude g_sp_ampl : REAL := 0.5; -- WG normalized amplitude
g_wg_phase : REAL := 0.0; -- WG phase in degrees = subband phase g_sp_phase : REAL := -110.0; -- WG phase in degrees = subband phase
g_unused_ampl : REAL := 0.1; -- WG normalized amplitude for unused sp g_sp_remnant_ampl : REAL := 0.1; -- WG normalized amplitude for remnant sp
g_unused_phase : REAL := 0.0; -- WG phase in degrees for unused 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_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 : 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_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_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 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 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 g_bf_y_phase : REAL := 40.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_bf_remnant_x_gain : REAL := 0.05; -- g_beamlet X BF weight normalized gain for remnant sp
g_read_all_BST : BOOLEAN := FALSE -- when FALSE only read BST for g_beamlet, to save sim time 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; END tb_lofar2_unb2c_sdp_station_bf;
ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
CONSTANT c_sim : BOOLEAN := TRUE; CONSTANT c_sim : BOOLEAN := TRUE;
CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0
CONSTANT c_node_nr : NATURAL := 0; CONSTANT c_node_nr : NATURAL := 0;
CONSTANT c_gn_index : NATURAL := c_unb_nr * 4 + c_node_nr; -- this node GN 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_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_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_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00";
CONSTANT c_fw_version : t_unb2c_board_fw_version := (1, 0); 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_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_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_eth_clk_period : TIME := 8 ns; -- 125 MHz XO on UniBoard
CONSTANT c_ext_clk_period : TIME := 5 ns; CONSTANT c_ext_clk_period : TIME := 5 ns;
...@@ -212,67 +227,106 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS ...@@ -212,67 +227,106 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
-- .ampl -- .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_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_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_ampl : NATURAL := NATURAL(g_sp_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_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_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_exp_sp_ast : REAL := c_exp_sp_power * REAL(c_nof_clk_per_sync);
-- . phase -- . 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_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_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_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_phase : REAL := g_sp_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_remnant_phase : REAL := g_sp_remnant_phase + c_wg_phase_offset; -- WG phase in degrees
-- . freq -- . 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 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 -- WPFB
CONSTANT c_pol_index : NATURAL := g_sp MOD c_sdp_Q_fft; 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_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 sinus yields subband with -90 degrees phase (negative Im, zero Re)
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_gain : REAL := 1.0; -- use default unit subband weights CONSTANT c_subband_weight_phase : REAL := 0.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_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_sdp_wpfb_subband_sp_ampl_ratio * c_subband_weight_gain;
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 signal ampl, so no divide by 2
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_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;
TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL; 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_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 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 -- BF X-pol and Y-pol
-- . select -- . select
CONSTANT c_exp_beamlet_x_index : NATURAL := g_beamlet * c_sdp_N_pol_bf; -- 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; -- 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 -- . 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_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(g_bf_x_gain * REAL(c_sdp_unit_bf_weight) * SIN(g_bf_x_phase * MATH_2_PI / 360.0)); 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(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_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(g_bf_y_gain * REAL(c_sdp_unit_bf_weight) * SIN(g_bf_y_phase * MATH_2_PI / 360.0)); 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 -- . Beamlet internal
CONSTANT c_exp_beamlet_x_ampl : REAL := c_exp_subband_ampl * g_bf_x_gain; CONSTANT c_exp_beamlet_x_tuple : t_real_arr(0 TO 3) := bf_calculate_expected_beamlet(
CONSTANT c_exp_beamlet_x_phase : REAL := c_subband_phase_offset + c_subband_weight_phase + g_bf_x_phase; c_exp_subband_ampl, c_exp_subband_phase, g_bf_x_gain, 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); 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_im : REAL := c_exp_beamlet_x_ampl * SIN(c_exp_beamlet_x_phase * MATH_2_PI / 360.0); CONSTANT c_exp_beamlet_x_ampl : REAL := c_exp_beamlet_x_tuple(0);
CONSTANT c_exp_beamlet_y_ampl : REAL := c_exp_subband_ampl * g_bf_y_gain; CONSTANT c_exp_beamlet_x_phase : REAL := c_exp_beamlet_x_tuple(1);
CONSTANT c_exp_beamlet_y_phase : REAL := c_subband_phase_offset + c_subband_weight_phase + g_bf_y_phase; CONSTANT c_exp_beamlet_x_re : REAL := c_exp_beamlet_x_tuple(2);
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_x_im : REAL := c_exp_beamlet_x_tuple(3);
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_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 -- . 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_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_subband_sst * g_bf_x_gain**2.0; -- = c_exp_beamlet_x_power * REAL(c_nof_block_per_sync) 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, so no divide by 2 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_subband_sst * g_bf_y_gain**2.0; -- = c_exp_beamlet_y_power * REAL(c_nof_block_per_sync) CONSTANT c_exp_beamlet_y_bst : REAL := c_exp_beamlet_y_power * REAL(c_nof_block_per_sync);
-- . Beamlet output -- . Beamlet output
CONSTANT c_exp_beamlet_x_output_ampl : REAL := c_exp_beamlet_x_ampl * 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_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_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_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_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_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_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_y_output_im : REAL := c_exp_beamlet_y_im * g_beamlet_scale;
-- MM -- MM
-- . Address widths of a single MM instance -- . Address widths of a single MM instance
...@@ -588,7 +642,40 @@ BEGIN ...@@ -588,7 +642,40 @@ BEGIN
BEGIN BEGIN
-- Wait for DUT power up after reset -- Wait for DUT power up after reset
WAIT FOR 1 us; 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 -- Set and check SDP info
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
...@@ -722,7 +809,7 @@ BEGIN ...@@ -722,7 +809,7 @@ BEGIN
-- 1 : phase[15:0] -- 1 : phase[15:0]
-- 2 : freq[30:0] -- 2 : freq[30:0]
-- 3 : ampl[16: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 FOR S IN 0 TO c_sdp_S_pn-1 LOOP
v_offset := S * c_mm_span_reg_diag_wg; v_offset := S * c_mm_span_reg_diag_wg;
IF s = g_sp THEN IF s = g_sp THEN
...@@ -732,9 +819,9 @@ BEGIN ...@@ -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 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 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 + 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 + 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 IF;
END LOOP; END LOOP;
...@@ -769,8 +856,8 @@ BEGIN ...@@ -769,8 +856,8 @@ BEGIN
v_im := unpack_complex_im(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_re <= v_re;
sp_subband_weight_im <= v_im; 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_gain <= COMPLEX_RADIUS(v_re, v_im) / 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_phase <= COMPLEX_PHASE(v_re, v_im);
-- No need to write subband weight, because default it is unit weight -- No need to write subband weight, because default it is unit weight
...@@ -833,8 +920,12 @@ BEGIN ...@@ -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); v_weight := pack_complex(re => c_bf_y_weight_re, im => c_bf_y_weight_im, w => c_sdp_W_bf_weight);
END IF; END IF;
ELSE ELSE
-- default set all weights to zero -- use the remnant BF weights for the other SP
v_weight := 0; 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; END IF;
v_addr := g_beamlet; -- beamlet index v_addr := g_beamlet; -- beamlet index
v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset
...@@ -866,13 +957,13 @@ BEGIN ...@@ -866,13 +957,13 @@ BEGIN
IF PB = 0 THEN IF PB = 0 THEN
sp_bf_x_weights_re_arr(v_S) <= v_re; sp_bf_x_weights_re_arr(v_S) <= v_re;
sp_bf_x_weights_im_arr(v_S) <= v_im; 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_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / 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_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im);
ELSE ELSE
sp_bf_y_weights_re_arr(v_S) <= v_re; sp_bf_y_weights_re_arr(v_S) <= v_re;
sp_bf_y_weights_im_arr(v_S) <= v_im; 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_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / 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_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im);
END IF; END IF;
END LOOP; END LOOP;
END LOOP; END LOOP;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment