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

Use g_bf_x_gain and g_bf_y_gain to verify dual pol BF beamlet.

parent 7acfc509
No related branches found
No related tags found
1 merge request!219No functional change. Use short index variables names in capitals, to ease...
Pipeline #26184 passed
......@@ -21,37 +21,87 @@
-------------------------------------------------------------------------------
--
-- Author: R. van der Walle (original), E. Kooistra (updates)
-- Purpose: Self-checking testbench for simulating lofar2_unb2c_sdp_station_bf using WG data.
-- Purpose: Self-checking testbench for simulating lofar2_unb2c_sdp_station_bf
-- using WG data.
--
-- 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 same stimuli for both beamsets.
--
-- MM control actions:
--
-- 1) Enable calc mode for WG on signal input g_sp via reg_diag_wg with:
-- g_subband = 102 --> WG freq = 19.921875MHz
-- g_ampl = 1.0 --> WG ampl = 2**13
-- 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.
--
-- 2) Read current BSN from reg_bsn_scheduler_wg and write
-- reg_bsn_scheduler_wg to trigger start of WG at BSN.
--
-- 3) Read and verify subband statistics (SST) for g_sp. This also reads the
-- SST of the other signal input of the WPFB that processes g_sp.
--
-- 2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg
-- to trigger start of WG at BSN.
-- 4) Select subband g_subband for beamlets in g_beamlet
--
-- 3) Read and verify subband statistics (SST)
-- 5) Apply BF weight to g_beamlet X beam and Y beam, so for example if g_sp
-- = 3, then w_x3 = g_bf_x_gain/phase and w_y3 = = g_bf_x_gain/phase. The
-- other BF weights are 0.
--
-- 4) Select subband g_subband for beamlet g_beamlet
-- WG BF BF
-- si weight weight
-- X Y
-- 0 -----> * w_x0 ..+
-- \--------------|----> * w_y0 ..+
-- 1 -----> * w_x1 ..+ |
-- \--------------|----> * w_y1 ..+
-- 2 -----> * w_x2 ..+ |
-- \--------------|----> * w_y2 ..+
-- 3 -----> * w_x3 ..+ |
-- \--------------|----> * w_y3 ..+
-- 4 -----> * w_x4 ..+ |
-- \--------------|----> * w_y4 ..+
-- 5 -----> * w_x5 ..+ |
-- \--------------|----> * w_y5 ..+
-- 6 -----> * w_x6 ..+ |
-- \--------------|----> * w_y6 ..+
-- 7 -----> * w_x7 ..+ |
-- \--------------|----> * w_y7 ..+
-- 8 -----> * w_x8 ..+ |
-- \--------------|----> * w_y8 ..+
-- 9 -----> * w_x9 ..+ |
-- \--------------|----> * w_y9 ..+
-- 10 -----> * w_x10 ..+ |
-- \--------------|----> * w_y10 ..+
-- 11 -----> * w_x11 ..+ |
-- \--------------|----> * w_y11 ..+
-- | |
-- \----------------|---> beamlet_x
-- \--> beamlet_y
--
-- 5) Apply BF weight (g_bf_gain, g_bf_phase) to g_beamlet X beam and Y beam
--
-- 6) Read and verify beamlet statistics (BST)
-- View sp_subband_sst in Wave window
-- View pol_beamlet_bst in Wave window
-- View sp_sst in Wave window
-- View bst_x_arr, bst_y_arr in Wave window
--
-- 7) Verify 10GbE output header and output payload for g_beamlet.
-- View rx_beamlet_sosi
-- View rx_beamlet_cnt (in analog format)
--
-- Usage:
-- > as 7 # default
-- > as 12 # for detailed debugging
-- # Manually add missing signal
-- > add wave -position insertpoint \
-- sim:/tb_lofar2_unb2c_sdp_station_bf/sp_subband_ssts_arr2 \
-- sim:/tb_lofar2_unb2c_sdp_station_bf/pol_beamlet_bsts_arr2
-- sim:/tb_lofar2_unb2c_sdp_station_bf/sp_ssts_arr2 \
-- sim:/tb_lofar2_unb2c_sdp_station_bf/bsts_arr2
-- > run -a
-- Takes about 40 m when g_read_all_* = FALSE
-- Takes about 1h 5 m when g_read_all_* = TRUE
......@@ -79,13 +129,18 @@ USE tech_pll_lib.tech_pll_component_pkg.ALL;
ENTITY tb_lofar2_unb2c_sdp_station_bf IS
GENERIC (
g_sp : NATURAL := 0; -- WG signal path index in range(S_pn = 12)
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_gain : REAL := 1.0; -- g_beamlet BF weight normalized gain
g_bf_phase : REAL := 30.0; -- g_beamlet BF weight phase rotation in degrees
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
);
......@@ -124,6 +179,8 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
CONSTANT c_stat_lo_factor : REAL := 1.0 - c_stat_percentage; -- lower boundary
CONSTANT c_stat_hi_factor : REAL := 1.0 + c_stat_percentage; -- higher boundary
CONSTANT c_nof_beamlets_per_data : NATURAL := 2; -- 2 dual pol beamlets (= XY, XY) per 64b data word
CONSTANT c_beamlet_output_delta : INTEGER := 2; -- +-delta margin
-- header fields
......@@ -156,20 +213,22 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
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_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_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 = 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 := c_subband_phase + c_wg_phase_offset; -- WG phase in degrees
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
-- . 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
......@@ -182,25 +241,38 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
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
-- BF X-pol and Y-pol
-- . select
CONSTANT c_exp_beamlet_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; -- in beamset 0
CONSTANT c_exp_beamlet_y_index : NATURAL := g_beamlet * c_sdp_N_pol_bf + 1; -- in beamset 0
-- . Beamlet weights for selected g_sp
CONSTANT c_bf_weight_re : INTEGER := INTEGER(g_bf_gain * REAL(c_sdp_unit_bf_weight) * COS(g_bf_phase * MATH_2_PI / 360.0));
CONSTANT c_bf_weight_im : INTEGER := INTEGER(g_bf_gain * REAL(c_sdp_unit_bf_weight) * SIN(g_bf_phase * MATH_2_PI / 360.0));
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));
-- . Beamlet internal
CONSTANT c_exp_beamlet_ampl : REAL := c_exp_subband_ampl * g_bf_gain;
CONSTANT c_exp_beamlet_phase : REAL := c_subband_phase_offset + c_subband_weight_phase + g_bf_phase;
CONSTANT c_exp_beamlet_re : REAL := c_exp_beamlet_ampl * COS(c_exp_beamlet_phase * MATH_2_PI / 360.0);
CONSTANT c_exp_beamlet_im : REAL := c_exp_beamlet_ampl * SIN(c_exp_beamlet_phase * MATH_2_PI / 360.0);
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);
-- . BST
CONSTANT c_exp_beamlet_power : REAL := c_exp_beamlet_ampl**2.0; -- complex, so no divide by 2
CONSTANT c_exp_beamlet_bst : REAL := c_exp_subband_sst * g_bf_gain**2.0; -- = c_exp_beamlet_power * REAL(c_nof_block_per_sync)
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)
-- . Beamlet output
CONSTANT c_exp_beamlet_output_ampl : REAL := c_exp_beamlet_ampl * g_beamlet_scale;
CONSTANT c_exp_beamlet_output_phase : REAL := c_exp_beamlet_phase;
CONSTANT c_exp_beamlet_output_re : REAL := c_exp_beamlet_re * g_beamlet_scale;
CONSTANT c_exp_beamlet_output_im : REAL := c_exp_beamlet_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
......@@ -265,13 +337,13 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
-- FSUB
-- . Read sp_subband_ssts_arr2 = SST for one WPFB unit that processes g_sp
SIGNAL sp_subband_ssts_arr2 : t_slv_64_subbands_arr(c_sdp_N_pol-1 DOWNTO 0); -- [pol][sub], for X,Y pair of A, B
SIGNAL sp_subband_sst : REAL := 0.0;
-- . Read sp_ssts_arr2 = SST for one WPFB unit that processes g_sp
SIGNAL sp_ssts_arr2 : t_slv_64_subbands_arr(c_sdp_N_pol-1 DOWNTO 0); -- [pol][sub], for X,Y pair of A, B
SIGNAL sp_sst : REAL := 0.0;
SIGNAL stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0);
-- . Selector
SIGNAL sst_offload_weighted_subbands : STD_LOGIC;
SIGNAL sst_weighted_subbands_flag : STD_LOGIC;
-- . Subband equalizer
SIGNAL sp_subband_weight_re : INTEGER := 0;
......@@ -280,48 +352,60 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS
SIGNAL sp_subband_weight_phase : REAL := 0.0;
-- 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_bf_weights_re_arr : t_integer_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_weights_im_arr : t_integer_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_weights_gain_arr : t_real_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0.0);
SIGNAL sp_bf_weights_phase_arr : t_real_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0.0);
SIGNAL pol_beamlet_bsts_arr2 : t_slv_64_beamlets_arr(c_sdp_N_pol_bf-1 DOWNTO 0); -- [pol_bf][blet]
SIGNAL pol_beamlet_bst_X_arr : t_real_arr(0 TO c_sdp_N_beamsets-1) := (OTHERS => 0.0); -- [bset]
SIGNAL pol_beamlet_bst_Y_arr : t_real_arr(0 TO c_sdp_N_beamsets-1) := (OTHERS => 0.0); -- [bset]
-- 10GbE
SIGNAL rx_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0]
SIGNAL rx_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0]
SIGNAL rx_beamlet_cnt : NATURAL;
SIGNAL rx_beamlet_valid : STD_LOGIC;
-- . beamlet X-pol
SIGNAL sp_bf_x_weights_re_arr : t_integer_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_x_weights_im_arr : t_integer_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_x_weights_gain_arr : t_real_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0.0);
SIGNAL sp_bf_x_weights_phase_arr : t_real_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0.0);
-- . beamlet Y-pol
SIGNAL sp_bf_y_weights_re_arr : t_integer_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_y_weights_im_arr : t_integer_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0);
SIGNAL sp_bf_y_weights_gain_arr : t_real_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0.0);
SIGNAL sp_bf_y_weights_phase_arr : t_real_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0.0);
SIGNAL rx_beamlet_list_re : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1 DOWNTO 0); -- [488 * 2-1:0] = [975:0]
SIGNAL rx_beamlet_list_im : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1 DOWNTO 0); -- [488 * 2-1:0] = [975:0]
-- . BST
SIGNAL bsts_arr2 : t_slv_64_beamlets_arr(c_sdp_N_pol_bf-1 DOWNTO 0); -- [pol_bf][blet]
SIGNAL bst_x_arr : t_real_arr(0 TO c_sdp_N_beamsets-1) := (OTHERS => 0.0); -- [bset] for BF X pol
SIGNAL bst_y_arr : t_real_arr(0 TO c_sdp_N_beamsets-1) := (OTHERS => 0.0); -- [bset] for BF Y pol
-- CEP model
-- . 10GbE
SIGNAL tr_10GbE_src_out : t_dp_sosi;
SIGNAL tr_10GbE_src_in : t_dp_siso;
SIGNAL tr_ref_clk_312 : STD_LOGIC := '0';
SIGNAL tr_ref_clk_156 : STD_LOGIC := '0';
SIGNAL tr_ref_rst_156 : STD_LOGIC := '0';
-- dp_offload_rx
SIGNAL offload_rx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL offload_rx_hdr_dat_miso : t_mem_miso;
SIGNAL test_offload_en : STD_LOGIC := '0';
SIGNAL test_offload_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); -- 64 bit
SIGNAL test_offload_sosi : t_dp_sosi := c_dp_sosi_rst;
SIGNAL test_offload_sop_cnt : NATURAL := 0;
SIGNAL test_offload_eop_cnt : NATURAL := 0;
-- . dp_offload_rx
SIGNAL rx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst;
SIGNAL rx_hdr_dat_miso : t_mem_miso;
SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0);
SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0');
-- Beamlets packets header
SIGNAL rx_sdp_cep_header : t_sdp_cep_header;
SIGNAL exp_sdp_cep_header : t_sdp_cep_header;
SIGNAL exp_dp_bsn : NATURAL;
-- Beamlets packets data
SIGNAL rx_beamlet_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); -- 64 bit
SIGNAL rx_beamlet_sosi : t_dp_sosi := c_dp_sosi_rst;
SIGNAL rx_beamlet_sop_cnt : NATURAL := 0;
SIGNAL rx_beamlet_eop_cnt : NATURAL := 0;
SIGNAL rx_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0]
SIGNAL rx_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0]
SIGNAL rx_beamlet_cnt : NATURAL;
SIGNAL rx_beamlet_valid : STD_LOGIC;
SIGNAL rx_beamlet_list_re : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1 DOWNTO 0); -- [488 * 2-1:0] = [975:0]
SIGNAL rx_beamlet_list_im : t_slv_8_arr(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1 DOWNTO 0); -- [488 * 2-1:0] = [975:0]
-- DUT
SIGNAL ext_clk : STD_LOGIC := '0';
SIGNAL ext_pps : STD_LOGIC := '0';
......@@ -416,6 +500,9 @@ BEGIN
JESD204B_SYNC_N => jesd204b_sync_n
);
------------------------------------------------------------------------------
-- CEP model
------------------------------------------------------------------------------
u_unb2_board_clk644_pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks
PORT MAP (
refclk_644 => SA_CLK,
......@@ -471,13 +558,13 @@ BEGIN
dp_rst => dest_rst,
dp_clk => ext_clk,
reg_hdr_dat_mosi => offload_rx_hdr_dat_mosi,
reg_hdr_dat_miso => offload_rx_hdr_dat_miso,
reg_hdr_dat_mosi => rx_hdr_dat_mosi,
reg_hdr_dat_miso => rx_hdr_dat_miso,
snk_in_arr(0) => tr_10GbE_src_out,
snk_out_arr(0) => tr_10GbE_src_in,
src_out_arr(0) => test_offload_sosi,
src_out_arr(0) => rx_beamlet_sosi,
hdr_fields_out_arr(0) => rx_hdr_fields_out,
hdr_fields_raw_arr(0) => rx_hdr_fields_raw
......@@ -490,12 +577,12 @@ BEGIN
p_mm_stimuli : PROCESS
VARIABLE v_bsn : NATURAL;
VARIABLE v_sp_subband_sst : REAL := 0.0;
VARIABLE v_pol_beamlet_bst : REAL := 0.0;
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
VARIABLE v_W, v_P, v_S, v_A, v_B, v_G : NATURAL; -- array indicies
VARIABLE v_W, v_P, v_PB, v_S, v_A, v_B, v_G : NATURAL; -- array indicies
VARIABLE v_re, v_im, v_weight : INTEGER;
VARIABLE v_re_exp, v_im_exp : REAL := 0.0;
BEGIN
......@@ -635,12 +722,21 @@ BEGIN
-- 1 : phase[15:0]
-- 2 : freq[30:0]
-- 3 : ampl[16:0]
-- . Put wanted signal on g_sp input
v_offset := g_sp * c_mm_span_reg_diag_wg;
-- . Put wanted signal on g_sp input and unused 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
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 + 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_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 + 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
END IF;
END LOOP;
-- Read current BSN
mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk);
......@@ -658,7 +754,7 @@ BEGIN
-- Read weighted subband selector
----------------------------------------------------------------------------
mmf_mm_bus_rd(c_mm_file_reg_dp_selector, 0, rd_data, tb_clk);
sst_offload_weighted_subbands <= NOT rd_data(0);
sst_weighted_subbands_flag <= NOT rd_data(0);
proc_common_wait_some_cycles(tb_clk, 1);
----------------------------------------------------------------------------
......@@ -716,7 +812,7 @@ BEGIN
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
----------------------------------------------------------------------------
-- Write beamlet weight for g_beamlet
-- Write beamlet weight for g_beamlet in S_sub_bf
----------------------------------------------------------------------------
-- . MM format: (cint16)RAM_BF_WEIGHTS[N_beamsets][N_pol_bf][A_pn]_[N_pol][S_sub_bf]
......@@ -724,38 +820,61 @@ BEGIN
v_span := true_log_pow2(c_sdp_N_pol * c_sdp_S_sub_bf); -- = 1024
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
-- Same BF weights for both beamsets
FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP
-- Same 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 := A * c_sdp_N_pol + P;
IF v_S = g_sp THEN
-- use generic BF weight for g_sp in g_beamlet
v_weight := pack_complex(re => c_bf_weight_re, im => c_bf_weight_im, w => c_sdp_W_bf_weight);
IF PB = 0 THEN
v_weight := pack_complex(re => c_bf_x_weight_re, im => c_bf_x_weight_im, w => c_sdp_W_bf_weight);
ELSE
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;
END IF;
v_addr := g_beamlet + A * v_span + U * c_mm_span_ram_bf_weights;
v_addr := v_addr + P * c_sdp_S_sub_bf;
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
v_addr := v_addr + PB * c_sdp_A_pn * v_span; -- beamlet polarization address offset
v_addr := v_addr + U * c_mm_span_ram_bf_weights; -- beamset address offset
mmf_mm_bus_wr(c_mm_file_ram_bf_weights, v_addr, v_weight, tb_clk);
END LOOP;
END LOOP;
END LOOP;
END LOOP;
-- . read back BF weights for g_beamlet
-- . read back BF weights for g_beamlet in S_sub_bf
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP
FOR A IN 0 TO c_sdp_A_pn-1 LOOP
FOR P IN 0 TO c_sdp_N_pol-1 LOOP
v_addr := g_beamlet + A * v_span + U * c_mm_span_ram_bf_weights;
v_addr := v_addr + P * c_sdp_S_sub_bf;
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
v_addr := v_addr + PB * c_sdp_A_pn * v_span; -- beamlet polarization address offset
v_addr := v_addr + U * c_mm_span_ram_bf_weights; -- beamset address offset
mmf_mm_bus_rd(c_mm_file_ram_bf_weights, v_addr, rd_data, tb_clk);
v_re := unpack_complex_re(rd_data, c_sdp_W_bf_weight);
v_im := unpack_complex_im(rd_data, c_sdp_W_bf_weight);
-- same BF weights for both beamsets, so fine to use only one sp_bf_weights_*_arr()
-- same BF weights for both beamsets and both beamlet polarizations,
-- so fine to use only one sp_bf_x_weights_*_arr()
v_S := A * c_sdp_N_pol + P;
sp_bf_weights_re_arr(v_S) <= v_re;
sp_bf_weights_im_arr(v_S) <= v_im;
sp_bf_weights_gain_arr(v_S) <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_bf_weight);
sp_bf_weights_phase_arr(v_S) <= atan2(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI;
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;
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;
END IF;
END LOOP;
END LOOP;
END LOOP;
END LOOP;
......@@ -804,7 +923,7 @@ BEGIN
v_data_hi := rd_data;
v_stat_data := v_data_hi & v_data_lo;
sp_subband_ssts_arr2(v_P)(v_B) <= v_stat_data;
sp_ssts_arr2(v_P)(v_B) <= v_stat_data;
stat_data <= v_stat_data; -- for time series view in Wave window
END IF;
END IF;
......@@ -812,10 +931,7 @@ BEGIN
proc_common_wait_some_cycles(tb_clk, 1);
-- Subband power of g_subband in g_sp
-- . For the selected g_subband in g_sp the sp_subband_sst will be close
-- to sp_subband_sst_sum_arr(c_pol_index), because the input is a
-- sinus, so most power will be in 1 subband.
sp_subband_sst <= TO_UREAL(sp_subband_ssts_arr2(c_pol_index)(g_subband));
sp_sst <= TO_UREAL(sp_ssts_arr2(c_pol_index)(g_subband));
proc_common_wait_some_cycles(tb_clk, 1);
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
......@@ -832,7 +948,7 @@ BEGIN
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
FOR I IN 0 TO v_len-1 LOOP
v_W := I MOD c_stat_data_sz; -- 0, 1 per statistics word, word index
v_P := (I / c_stat_data_sz) MOD c_sdp_N_pol_bf; -- 0, 1 per BF pol, polarization index
v_PB := (I / c_stat_data_sz) MOD c_sdp_N_pol_bf; -- 0, 1 per BF pol, polarization index
v_B := I / (c_sdp_N_pol_bf * c_stat_data_sz); -- beamlet index in beamset, range(S_sub_bf = 488) per dual pol
v_G := v_B + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
v_addr := I + U * v_span; -- MM address
......@@ -848,7 +964,7 @@ BEGIN
v_data_hi := rd_data;
v_stat_data := v_data_hi & v_data_lo;
pol_beamlet_bsts_arr2(v_P)(v_G) <= v_stat_data;
bsts_arr2(v_PB)(v_G) <= v_stat_data;
stat_data <= v_stat_data; -- for time series view in Wave window
END IF;
END IF;
......@@ -859,8 +975,8 @@ BEGIN
-- Beamlet power of g_beamlet X and Y, same for both beamsets
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
v_G := g_beamlet + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
pol_beamlet_bst_X_arr(U) <= TO_UREAL(pol_beamlet_bsts_arr2(0)(v_G)); -- X pol beamlet
pol_beamlet_bst_Y_arr(U) <= TO_UREAL(pol_beamlet_bsts_arr2(1)(v_G)); -- Y pol beamlet
bst_x_arr(U) <= TO_UREAL(bsts_arr2(0)(v_G)); -- X pol beamlet
bst_y_arr(U) <= TO_UREAL(bsts_arr2(1)(v_G)); -- Y pol beamlet
END LOOP;
proc_common_wait_some_cycles(tb_clk, 1);
proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window
......@@ -875,10 +991,6 @@ BEGIN
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 selector:");
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));
......@@ -886,69 +998,88 @@ BEGIN
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_subband_sst = " & real_to_str(sp_subband_sst, 20, 1));
print_str(". sp_subband_sst / c_exp_subband_sst = " & real_to_str(sp_subband_sst / c_exp_subband_sst, 20, 6));
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_ampl = " & int_to_str(NATURAL(c_exp_beamlet_ampl)));
print_str(". c_exp_beamlet_power = " & real_to_str(c_exp_beamlet_power, 20, 1));
print_str(". c_exp_beamlet_bst = " & real_to_str(c_exp_beamlet_bst, 20, 1));
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("");
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
v_G := g_beamlet + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
print_str(". pol_beamlet_bst_X beamlet(" & INTEGER'IMAGE(v_G) & ") = " & real_to_str(pol_beamlet_bst_X_arr(U), 20, 1));
print_str(". pol_beamlet_bst_Y beamlet(" & INTEGER'IMAGE(v_G) & ") = " & real_to_str(pol_beamlet_bst_Y_arr(U), 20, 1));
print_str(". bst_x_arr(" & INTEGER'IMAGE(v_G) & ") = " & real_to_str(bst_x_arr(U), 20, 1));
print_str(". bst_y_arr(" & INTEGER'IMAGE(v_G) & ") = " & real_to_str(bst_y_arr(U), 20, 1));
END LOOP;
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
v_G := g_beamlet + U * c_sdp_S_sub_bf; -- global beamlet index, range(c_sdp_N_beamlets_sdp)
print_str(". pol_beamlet_bst_X beamlet(" & INTEGER'IMAGE(v_G) & ") / c_exp_beamlet_bst = " & real_to_str(pol_beamlet_bst_X_arr(U) / c_exp_beamlet_bst, 20, 6));
print_str(". pol_beamlet_bst_Y beamlet(" & INTEGER'IMAGE(v_G) & ") / c_exp_beamlet_bst = " & real_to_str(pol_beamlet_bst_Y_arr(U) / c_exp_beamlet_bst, 20, 6));
print_str(". bst_x_arr(" & INTEGER'IMAGE(v_G) & ") / c_exp_beamlet_x_bst = " & real_to_str(bst_x_arr(U) / c_exp_beamlet_x_bst, 20, 6));
print_str(". bst_y_arr(" & INTEGER'IMAGE(v_G) & ") / c_exp_beamlet_y_bst = " & real_to_str(bst_y_arr(U) / c_exp_beamlet_y_bst, 20, 6));
END LOOP;
print_str("");
print_str("Beamlet output:");
print_str(". rd_beamlet_scale = " & int_to_str(TO_UINT(rd_beamlet_scale)));
print_str(". c_exp_beamlet_output_ampl = " & int_to_str(NATURAL(c_exp_beamlet_output_ampl)));
print_str(". c_exp_beamlet_scale = " & int_to_str(c_exp_beamlet_scale));
print_str("");
print_str(". c_exp_beamlet_x_output_ampl = " & int_to_str(NATURAL(c_exp_beamlet_x_output_ampl)));
print_str(". c_exp_beamlet_x_output_phase = " & int_to_str(INTEGER(c_exp_beamlet_x_output_phase)));
print_str(". c_exp_beamlet_x_output_re = " & int_to_str(INTEGER(c_exp_beamlet_x_output_re)));
print_str(". c_exp_beamlet_x_output_im = " & int_to_str(INTEGER(c_exp_beamlet_x_output_im)));
print_str("");
print_str(". c_exp_beamlet_y_output_ampl = " & int_to_str(NATURAL(c_exp_beamlet_y_output_ampl)));
print_str(". c_exp_beamlet_y_output_phase = " & int_to_str(INTEGER(c_exp_beamlet_y_output_phase)));
print_str(". c_exp_beamlet_y_output_re = " & int_to_str(INTEGER(c_exp_beamlet_y_output_re)));
print_str(". c_exp_beamlet_y_output_im = " & int_to_str(INTEGER(c_exp_beamlet_y_output_im)));
---------------------------------------------------------------------------
-- Verify SST and BST
-- Verify SST
---------------------------------------------------------------------------
-- verify expected subband power based on WG power
ASSERT sp_subband_sst > c_stat_lo_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
ASSERT sp_subband_sst < c_stat_hi_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
ASSERT sp_sst > c_stat_lo_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
ASSERT sp_sst < c_stat_hi_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
---------------------------------------------------------------------------
-- Verify BST
---------------------------------------------------------------------------
-- verify expected beamlet power based on WG power and BF weigths
--
-- All co and cross polarization weights are equal: w = w_xx = w_xy = w_yx = w_yy
-- With one g_sp either SP X or SP Y is used, so the other antenna polarization is 0
-- Hence the c_exp_beamlet_bst will be the same for beamlet X and Y independent of whether g_sp is an X or Y signal input:
-- g_sp = X --> w_xx --> beamlet X = c_exp_beamlet_bst
-- g_sp = Y --> w_xy --> beamlet X = c_exp_beamlet_bst
-- g_sp = X --> w_yx --> beamlet Y = c_exp_beamlet_bst
-- g_sp = Y --> w_yy --> beamlet Y = c_exp_beamlet_bst
--
FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP
ASSERT pol_beamlet_bst_X_arr(U) > c_stat_lo_factor * c_exp_beamlet_bst REPORT "Wrong beamlet power for X in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
ASSERT pol_beamlet_bst_X_arr(U) < c_stat_hi_factor * c_exp_beamlet_bst REPORT "Wrong beamlet power for X in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
ASSERT pol_beamlet_bst_Y_arr(U) > c_stat_lo_factor * c_exp_beamlet_bst REPORT "Wrong beamlet power for Y in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
ASSERT pol_beamlet_bst_Y_arr(U) < c_stat_hi_factor * c_exp_beamlet_bst REPORT "Wrong beamlet power for Y in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
-- X-pol
ASSERT bst_x_arr(U) < c_stat_hi_factor * c_exp_beamlet_x_bst REPORT "Wrong beamlet X power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
ASSERT bst_x_arr(U) > c_stat_lo_factor * c_exp_beamlet_x_bst REPORT "Wrong beamlet X power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
-- Y-pol
ASSERT bst_y_arr(U) > c_stat_lo_factor * c_exp_beamlet_y_bst REPORT "Wrong beamlet Y power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
ASSERT bst_y_arr(U) < c_stat_hi_factor * c_exp_beamlet_y_bst REPORT "Wrong beamlet Y power in beamset " & NATURAL'IMAGE(U) SEVERITY ERROR;
END LOOP;
---------------------------------------------------------------------------
-- Verify beamlet output in 10GbE UDP offload
---------------------------------------------------------------------------
v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_index)); v_re_exp := c_exp_beamlet_output_re;
v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_index)); v_im_exp := c_exp_beamlet_output_im;
ASSERT v_re > INTEGER(v_re_exp) - c_beamlet_output_delta REPORT "Wrong 10GbE output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_re < INTEGER(v_re_exp) + c_beamlet_output_delta REPORT "Wrong 10GbE output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_im > INTEGER(v_im_exp) - c_beamlet_output_delta REPORT "Wrong 10GbE output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
ASSERT v_im < INTEGER(v_im_exp) + c_beamlet_output_delta REPORT "Wrong 10GbE output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
-- X-pol
v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_x_index)); v_re_exp := c_exp_beamlet_x_output_re;
v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_x_index)); v_im_exp := c_exp_beamlet_x_output_im;
ASSERT v_re > INTEGER(v_re_exp) - c_beamlet_output_delta REPORT "Wrong beamlet X output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_re < INTEGER(v_re_exp) + c_beamlet_output_delta REPORT "Wrong beamlet X output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_im > INTEGER(v_im_exp) - c_beamlet_output_delta REPORT "Wrong beamlet X output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
ASSERT v_im < INTEGER(v_im_exp) + c_beamlet_output_delta REPORT "Wrong beamlet X output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
-- Y-pol
v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_y_index)); v_re_exp := c_exp_beamlet_y_output_re;
v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_y_index)); v_im_exp := c_exp_beamlet_y_output_im;
ASSERT v_re > INTEGER(v_re_exp) - c_beamlet_output_delta REPORT "Wrong beamlet Y output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_re < INTEGER(v_re_exp) + c_beamlet_output_delta REPORT "Wrong beamlet Y output (re) " & INTEGER'IMAGE(v_re) & " != " & REAL'IMAGE(v_re_exp) SEVERITY ERROR;
ASSERT v_im > INTEGER(v_im_exp) - c_beamlet_output_delta REPORT "Wrong beamlet Y output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
ASSERT v_im < INTEGER(v_im_exp) + c_beamlet_output_delta REPORT "Wrong beamlet Y output (im) " & INTEGER'IMAGE(v_im) & " != " & REAL'IMAGE(v_im_exp) SEVERITY ERROR;
---------------------------------------------------------------------------
-- End Simulation
......@@ -967,22 +1098,22 @@ BEGIN
p_test_counters : PROCESS(ext_clk)
BEGIN
IF rising_edge(ext_clk) THEN
-- Count test_offload_sosi packets
IF test_offload_sosi.sop = '1' THEN
test_offload_sop_cnt <= test_offload_sop_cnt + 1; -- early count
-- Count rx_beamlet_sosi packets
IF rx_beamlet_sosi.sop = '1' THEN
rx_beamlet_sop_cnt <= rx_beamlet_sop_cnt + 1; -- early count
END IF;
IF test_offload_sosi.eop = '1' THEN
test_offload_eop_cnt <= test_offload_eop_cnt + 1; -- after count
IF rx_beamlet_sosi.eop = '1' THEN
rx_beamlet_eop_cnt <= rx_beamlet_eop_cnt + 1; -- after count
END IF;
END IF;
END PROCESS;
-- Count sync intervals using in_sosi.sync, because there is no test_offload_sosi.sync
-- Count sync intervals using in_sosi.sync, because there is no rx_beamlet_sosi.sync
in_sync_cnt <= in_sync_cnt + 1 WHEN rising_edge(ext_clk) AND in_sync = '1';
test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit test_offload_sosi
test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit rx_beamlet_sosi
-- Prepare exp_sdp_cep_header before test_offload_sosi.eop, so that
-- p_exp_sdp_cep_header can verify it at test_offload_sosi.eop.
-- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that
-- p_exp_sdp_cep_header can verify it at rx_beamlet_sosi.eop.
p_exp_sdp_cep_header : PROCESS(exp_dp_bsn)
BEGIN
......@@ -1044,10 +1175,10 @@ BEGIN
WAIT UNTIL rising_edge(ext_clk);
-- Prepare exp_sdp_cep_header at sop, so that it can be verified at eop
IF test_offload_sosi.sop = '1' THEN
IF rx_beamlet_sosi.sop = '1' THEN
-- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet
IF test_offload_sop_cnt MOD c_sdp_N_beamsets = 0 THEN
exp_dp_bsn <= c_init_bsn + (test_offload_sop_cnt / c_sdp_N_beamsets) * c_sdp_cep_nof_blocks_per_packet;
IF rx_beamlet_sop_cnt MOD c_sdp_N_beamsets = 0 THEN
exp_dp_bsn <= c_init_bsn + (rx_beamlet_sop_cnt / c_sdp_N_beamsets) * c_sdp_cep_nof_blocks_per_packet;
END IF;
END IF;
......@@ -1056,7 +1187,7 @@ BEGIN
-- or 1, but the order in which the packets arrive is undetermined.
-- Therefore accept any beamlet_index MOD c_sdp_S_sub_bf = 0 as correct
-- in func_sdp_verify_cep_header().
IF test_offload_sosi.eop = '1' THEN
IF rx_beamlet_sosi.eop = '1' THEN
v_bool := func_sdp_verify_cep_header(rx_sdp_cep_header, exp_sdp_cep_header);
END IF;
END PROCESS;
......@@ -1072,47 +1203,47 @@ BEGIN
-- . expect c_sdp_cep_nof_beamlets_per_block = c_sdp_S_sub_bf = 488 dual pol
-- and complex beamlets per packet, so 2 dual pol beamlets/64b data word.
-- . Beamlets array is stored big endian in the data, so X index 0 first in
-- MSByte of test_offload_sosi.data.
-- MSByte of rx_beamlet_sosi.data.
p_rx_cep_beamlets : PROCESS
BEGIN
rx_beamlet_cnt <= 0;
rx_beamlet_valid <= '0';
-- Wait until start of a beamlet packet, capture only first block in packet
proc_common_wait_until_high(ext_clk, test_offload_sosi.sop);
-- 2 dual pol beamlets (= XY, XY) per 64b data word
FOR I IN 0 TO (c_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block/2)-1 LOOP
proc_common_wait_until_high(ext_clk, test_offload_sosi.valid);
proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.sop);
-- c_nof_beamlets_per_data = 2 dual pol beamlets (= XY, XY) per 64b data word
FOR I IN 0 TO (c_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data)-1 LOOP
proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid);
rx_beamlet_valid <= '1';
-- Capture rx beamlets per longword in rx_beamlet_arr, for time series view in Wave window
rx_beamlet_arr_re(0) <= test_offload_sosi.data(55 DOWNTO 48); -- X
rx_beamlet_arr_im(0) <= test_offload_sosi.data(63 DOWNTO 56);
rx_beamlet_arr_re(1) <= test_offload_sosi.data(39 DOWNTO 32); -- Y
rx_beamlet_arr_im(1) <= test_offload_sosi.data(47 DOWNTO 40);
rx_beamlet_arr_re(2) <= test_offload_sosi.data(23 DOWNTO 16); -- X
rx_beamlet_arr_im(2) <= test_offload_sosi.data(31 DOWNTO 24);
rx_beamlet_arr_re(3) <= test_offload_sosi.data( 7 DOWNTO 0); -- Y
rx_beamlet_arr_im(3) <= test_offload_sosi.data(15 DOWNTO 8);
IF I < c_sdp_cep_nof_beamlets_per_block/2 THEN
rx_beamlet_arr_re(0) <= rx_beamlet_sosi.data(55 DOWNTO 48); -- X
rx_beamlet_arr_im(0) <= rx_beamlet_sosi.data(63 DOWNTO 56);
rx_beamlet_arr_re(1) <= rx_beamlet_sosi.data(39 DOWNTO 32); -- Y
rx_beamlet_arr_im(1) <= rx_beamlet_sosi.data(47 DOWNTO 40);
rx_beamlet_arr_re(2) <= rx_beamlet_sosi.data(23 DOWNTO 16); -- X
rx_beamlet_arr_im(2) <= rx_beamlet_sosi.data(31 DOWNTO 24);
rx_beamlet_arr_re(3) <= rx_beamlet_sosi.data( 7 DOWNTO 0); -- Y
rx_beamlet_arr_im(3) <= rx_beamlet_sosi.data(15 DOWNTO 8);
IF I < c_sdp_cep_nof_beamlets_per_block / c_nof_beamlets_per_data THEN
-- Only capture the first beamlets block of each packet in rx_beamlet_list
rx_beamlet_list_re(I*4 + 0) <= test_offload_sosi.data(55 DOWNTO 48); -- X
rx_beamlet_list_im(I*4 + 0) <= test_offload_sosi.data(63 DOWNTO 56);
rx_beamlet_list_re(I*4 + 1) <= test_offload_sosi.data(39 DOWNTO 32); -- Y
rx_beamlet_list_im(I*4 + 1) <= test_offload_sosi.data(47 DOWNTO 40);
rx_beamlet_list_re(I*4 + 2) <= test_offload_sosi.data(23 DOWNTO 16); -- X
rx_beamlet_list_im(I*4 + 2) <= test_offload_sosi.data(31 DOWNTO 24);
rx_beamlet_list_re(I*4 + 3) <= test_offload_sosi.data( 7 DOWNTO 0); -- Y
rx_beamlet_list_im(I*4 + 3) <= test_offload_sosi.data(15 DOWNTO 8);
rx_beamlet_list_re(I*4 + 0) <= rx_beamlet_sosi.data(55 DOWNTO 48); -- X
rx_beamlet_list_im(I*4 + 0) <= rx_beamlet_sosi.data(63 DOWNTO 56);
rx_beamlet_list_re(I*4 + 1) <= rx_beamlet_sosi.data(39 DOWNTO 32); -- Y
rx_beamlet_list_im(I*4 + 1) <= rx_beamlet_sosi.data(47 DOWNTO 40);
rx_beamlet_list_re(I*4 + 2) <= rx_beamlet_sosi.data(23 DOWNTO 16); -- X
rx_beamlet_list_im(I*4 + 2) <= rx_beamlet_sosi.data(31 DOWNTO 24);
rx_beamlet_list_re(I*4 + 3) <= rx_beamlet_sosi.data( 7 DOWNTO 0); -- Y
rx_beamlet_list_im(I*4 + 3) <= rx_beamlet_sosi.data(15 DOWNTO 8);
END IF;
proc_common_wait_until_high(ext_clk, test_offload_sosi.valid);
proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid);
-- Use at least one WAIT instead of proc_common_wait_some_cycles() to
-- avoid Modelsim warning: (vcom-1090) Possible infinite loop: Process
-- contains no WAIT statement.
WAIT UNTIL rising_edge(ext_clk);
rx_beamlet_valid <= '0';
rx_beamlet_cnt <= (rx_beamlet_cnt + 4) MOD c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet
rx_beamlet_cnt <= (rx_beamlet_cnt + c_nof_beamlets_per_data) MOD c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet
END LOOP;
END PROCESS;
-- To view the 64 bit 10GbE offload data more easily in the Wave window
test_offload_data <= test_offload_sosi.data(c_longword_w-1 DOWNTO 0);
rx_beamlet_data <= rx_beamlet_sosi.data(c_longword_w-1 DOWNTO 0);
END tb;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment