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 35a57bab059e9e8d89908fe1e66f2191a6beef32..9243cd4d17697912183c0f60883cbede0a6c117e 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 @@ -138,9 +138,9 @@ USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY tb_lofar2_unb2c_sdp_station_bf_ring IS GENERIC ( - g_first_gn : NATURAL := 0; -- first global node (GN) in ring + g_first_gn : NATURAL := 1; -- first global node (GN) in ring g_nof_rn : NATURAL := 2; -- nof ring nodes (RN) in ring - g_global_sp : NATURAL := 3; -- WG gloabl signal path (SP) index in range(g_first_gn * S_pn, (g_first_gn + g_nof_rn) * S_pn - 1), S_pn = 12 + g_global_sp : NATURAL := 15; -- WG global signal path (SP) index in range [c_first_sp : c_last_sp] 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 @@ -156,6 +156,7 @@ ENTITY tb_lofar2_unb2c_sdp_station_bf_ring IS 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 remnant sp g_bf_remnant_y_phase : REAL := -135.0; -- g_beamlet Y BF weight phase rotation in degrees for remnant sp + g_read_all_sub_sel : BOOLEAN := FALSE; -- when FALSE only read subband selection for g_beamlet, to save sim time 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 ); @@ -174,6 +175,8 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS CONSTANT c_local_sp : NATURAL := g_global_sp MOD c_sdp_S_pn; -- local SP index of g_global_sp on c_global_sp_gn CONSTANT c_global_sp_unb_nr : NATURAL := c_global_sp_gn / c_quad; -- unb_nr of where g_global_sp is located CONSTANT c_global_sp_node_nr : NATURAL := c_global_sp_gn MOD c_quad; -- unb_nr of where g_global_sp is located + CONSTANT c_first_sp : NATURAL := g_first_gn * c_sdp_S_pn; + CONSTANT c_last_sp : NATURAL := c_first_sp + g_nof_rn * c_sdp_S_pn - 1; CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0 CONSTANT c_nof_lanes : NATURAL := c_sdp_N_beamsets; @@ -205,11 +208,15 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS CONSTANT c_beamlet_output_delta : INTEGER := 2; -- +-delta margin -- header fields + -- . Use gn = 1 for c_cep_ip_src_addr to have fixed c_exp_ip_header_checksum CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & func_sdp_gn_index_to_mac_15_0(c_last_gn); - CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & func_sdp_gn_index_to_ip_15_0(c_last_gn); + CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & func_sdp_gn_index_to_ip_15_0(1); CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_last_id; -- D0 & c_last_id - - CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDD#; -- value obtained from rx_sdp_cep_header.ip.header_checksum in wave window for g_nof_rn = 2. + -- . The ip_header_checksum depends on src IP, and therefore on the c_last_gn. The expected + -- value is obtained from rx_sdp_cep_header.ip.header_checksum in wave window for + -- c_last_gn = 1. Therefore in this tb use func_sdp_gn_index_to_ip_15_0(1) to have fixed + -- c_exp_ip_header_checksum, independent of actual c_last_gn. + CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDD#; CONSTANT c_exp_beamlet_scale : NATURAL := NATURAL(g_beamlet_scale * REAL(c_sdp_unit_beamlet_scale)); -- c_sdp_unit_beamlet_scale = 2**15; CONSTANT c_exp_beamlet_index : NATURAL := 0; -- depends on beamset bset * c_sdp_S_sub_bf @@ -411,18 +418,18 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS -- BF -- . beamlet subband selection SIGNAL sp_subband_select : NATURAL := 0; - SIGNAL sp_subband_select_arr : t_natural_arr(0 TO c_sdp_S_sub_bf * c_sdp_N_pol-1) := (OTHERS => 0); -- Q_fft = N_pol = 2 + SIGNAL sp_subband_select_arr : t_integer_arr(0 TO c_sdp_S_sub_bf * c_sdp_N_pol-1) := (OTHERS => -1); -- Q_fft = N_pol = 2 -- . beamlet X-pol - SIGNAL sp_bf_x_weights_re_arr : t_integer_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_x_weights_im_arr : t_integer_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_x_weights_gain_arr : t_real_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); - SIGNAL sp_bf_x_weights_phase_arr : t_real_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); + SIGNAL sp_bf_x_weights_re_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_x_weights_im_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_x_weights_gain_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); + SIGNAL sp_bf_x_weights_phase_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); -- . beamlet Y-pol - SIGNAL sp_bf_y_weights_re_arr : t_integer_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_y_weights_im_arr : t_integer_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_y_weights_gain_arr : t_real_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); - SIGNAL sp_bf_y_weights_phase_arr : t_real_arr(0 TO g_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); + SIGNAL sp_bf_y_weights_re_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_y_weights_im_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_y_weights_gain_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); + SIGNAL sp_bf_y_weights_phase_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); -- . BST SIGNAL bsts_arr2 : t_slv_64_beamlets_arr(c_sdp_N_pol_bf-1 DOWNTO 0); -- [pol_bf][blet] @@ -665,8 +672,6 @@ BEGIN p_mm_stimuli : PROCESS VARIABLE v_gn : NATURAL; VARIABLE v_bsn : NATURAL; - VARIABLE v_sp_sst : REAL := 0.0; - VARIABLE v_bst : REAL := 0.0; VARIABLE v_data_lo, v_data_hi : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); VARIABLE v_stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); VARIABLE v_len, v_span, v_offset, v_addr, v_sel : NATURAL; -- address ranges, indices @@ -674,6 +679,12 @@ BEGIN VARIABLE v_re, v_im, v_weight : INTEGER; VARIABLE v_re_exp, v_im_exp : REAL := 0.0; BEGIN + -- Check g_global_sp + IF g_global_sp < c_first_sp OR g_global_sp > c_last_sp THEN + ASSERT FALSE REPORT "g_global_sp not in ring GN range." SEVERITY ERROR; + ASSERT FALSE REPORT "g_global_sp not in ring GN range." SEVERITY FAILURE; + END IF; + -- Wait for DUT power up after reset WAIT FOR 1 us; @@ -920,9 +931,8 @@ BEGIN END LOOP; -- Access scheme 1 for beamformer. - -- Use transport_nof_hops = 0 on last nodes to stop remote input for first node. The - -- alternative is to use transport_nof_hops = 1 on all nodes and let the BSN aligner - -- on the first node disable its remote input. + -- Use transport_nof_hops = 0 on last node to stop remote input for first node. No + -- need to also disable the remote input of the BSN aligner on the first node. FOR RN IN 0 TO c_last_rn LOOP v_gn := g_first_gn + RN; FOR I IN 0 TO c_nof_lanes-1 LOOP @@ -948,7 +958,7 @@ BEGIN FOR RN IN 0 TO c_last_rn LOOP v_gn := g_first_gn + RN; FOR S IN 0 TO c_sdp_S_pn-1 LOOP - IF RN * c_sdp_S_pn + S = g_global_sp THEN + IF v_gn * c_sdp_S_pn + S = g_global_sp THEN -- Strong WG signal at g_global_sp mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees @@ -1032,15 +1042,18 @@ BEGIN FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP -- Same selection for both beamsets, so fine to use only one sp_subband_select_arr() FOR B IN 0 TO c_sdp_S_sub_bf-1 LOOP - -- Same selection for all SP, so fine to only read subband selection for c_local_sp on last node - v_addr := v_P + B * c_sdp_N_pol + v_A * v_span + U * c_mm_span_ram_ss_ss_wide; - mmf_mm_bus_rd(c_mm_file_ram_ss_ss_wide, v_addr, rd_data, tb_clk); - v_sel := (TO_UINT(rd_data) - v_P) / c_sdp_N_pol; - sp_subband_select_arr(B) <= v_sel; - sp_subband_select <= v_sel; -- for time series view in Wave window + IF g_read_all_sub_sel OR B = g_beamlet THEN + -- Same selection for all SP, so fine to only read subband selection for c_local_sp on last node + v_addr := v_P + B * c_sdp_N_pol + v_A * v_span + U * c_mm_span_ram_ss_ss_wide; + mmf_mm_bus_rd(c_mm_file_ram_ss_ss_wide, v_addr, rd_data, tb_clk); + v_sel := (TO_UINT(rd_data) - v_P) / c_sdp_N_pol; + sp_subband_select_arr(B * c_sdp_N_pol + v_P) <= v_sel; + sp_subband_select <= v_sel; -- for time series view in Wave window + END IF; END LOOP; END LOOP; proc_common_wait_some_cycles(tb_clk, 1); + ASSERT sp_subband_select_arr(g_beamlet * c_sdp_N_pol + v_P) = g_subband REPORT "Wrong subband select at beamlet index." SEVERITY ERROR; proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window ---------------------------------------------------------------------------- @@ -1058,7 +1071,7 @@ BEGIN -- Different BF weights for both beamlet polarizations FOR A IN 0 TO c_sdp_A_pn-1 LOOP FOR P IN 0 TO c_sdp_N_pol-1 LOOP - v_S := RN * c_sdp_S_pn + A * c_sdp_N_pol + P; + v_S := v_gn * c_sdp_S_pn + A * c_sdp_N_pol + P; -- Different BF weights for g_global_sp and the remnant sp IF v_S = g_global_sp THEN -- use generic BF weight for g_global_sp in g_beamlet @@ -1075,7 +1088,7 @@ BEGIN 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; - -- Only need to set BF weight for g_beamlet, keep other beamlet BF weights at zero rst default. + -- Only need to set BF weight for g_beamlet, keep other beamlet BF weights at zero rst default. 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 + A * v_span; -- antenna input address offset @@ -1105,7 +1118,7 @@ BEGIN v_im := unpack_complex_im(rd_data, c_sdp_W_bf_weight); -- same BF weights for both beamsets and both beamlet polarizations, -- so fine to use only one sp_bf_x_weights_*_arr() - v_S := RN * c_sdp_S_pn + A * c_sdp_N_pol + P; + v_S := v_gn * c_sdp_S_pn + A * c_sdp_N_pol + P; IF PB = 0 THEN sp_bf_x_weights_re_arr(v_S) <= v_re; sp_bf_x_weights_im_arr(v_S) <= v_im;