Skip to content
Snippets Groups Projects

Correct beamlet output indexing in tr_10GbE_src_out.data. Verify exact beamlet...

Merged Eric Kooistra requested to merge L2SDP-911 into master
1 file
+ 6
2
Compare changes
  • Side-by-side
  • Inline
@@ -27,25 +27,40 @@
-- MM control actions:
--
-- 1) Enable calc mode for WG via reg_diag_wg with:
-- 1.
-- freq = 19.921875MHz (subband 102)
-- ampl = 0.5 * 2**13
-- 2.
-- freg = 19.43359375 MHz (subband 99.5)
-- ampl = 0.5 * 2**13
-- 1. freq = 19.921875MHz (subband 102, at mid of normal beamlet)
-- 2. freg = 19.43359375 MHz (subband 99.5, at mid of shifted beamlet)
-- Use same ampl for both WG. Use c_beamlet_scale such that beamlet output
-- will fit in W_beamlet = 8 bits.
--
-- 2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg
-- to trigger start of WG at BSN.
--
-- 3) Verify 10GbE output.
--
-- 3) Verify beamlet data in 10GbE output for beamset 0 (with the normal
-- beamlets) and beamset 1 (with the frequency shifted beamlets).
-- . verify subband 102 in beamset 0
-- . verify subband 99.5 in beamset 1
-- . These subbands also appear at about half power in the other beamset
-- but these values are not verified, because they are at the edge of
-- the subband and will in practise not be used. Therefore choose WG
-- c_wg_ampl_sp_2 = c_wg_ampl_sp_0 / 3 to distinghuis them.
-- The purpose of the 2x oversampled filterbank is to only use the
-- beamlet frequencies that are around the center of the subband, so
-- the half of the subbands from beamset 0 and half of the subbands
-- from beamset 1.
--
-- Usage:
-- > as 7 # default
-- > as 12 # for detailed debugging
-- > run -a
-- Remark: TB based on tb_lofar2_unb2b_beamformer.vhd
-- . manually add missing beamlet_arr2_im/re to wave window, and manually
-- copy beamlet_arr2_im[195:215] and [1170:1190] and the rx_beamlet_*
-- index signals to have a more compact view of the relevant indices.
-- . If c_subband_phase = 0.0 then beamlet_arr2_re entries are 0.
-- . manually add top level generics/constants to wave window.
--
-- Remark: TB is based on tb_lofar2_unb2c_sdp_station_bf.
-------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, tech_pll_lib, tr_10GbE_lib;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
@@ -89,25 +104,65 @@ ARCHITECTURE tb OF tb_disturb2_unb2b_sdp_station_full_wg IS
CONSTANT c_wpfb_complex_sim : t_wpfb := func_wpfb_map_real_input_wpfb_parameters_to_complex_input(c_wpfb_sim);
-- WG
CONSTANT c_full_scale_ampl : REAL := REAL(2**(c_sdp_W_adc-1)-1); -- = full scale of WG
CONSTANT c_bsn_start_wg : NATURAL := 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values
CONSTANT c_ampl_sp : NATURAL := 2**(c_sdp_W_adc-1) / 2; -- in number of lsb
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_freq_offset : REAL := 0.0/11.0; -- in freq_unit
CONSTANT c_subband_sp_0 : REAL := 102.0; -- Select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
CONSTANT c_subband_sp_1 : REAL := 99.5; -- Select subband at index 99.5 = 99.5/1024 * 200MHz = 19.43359375 MHz
CONSTANT c_wg_ampl_lsb : REAL := c_diag_wg_ampl_unit / c_full_scale_ampl; -- amplitude in number of LSbit resolution steps
CONSTANT c_exp_wg_power_sp : REAL := REAL(c_ampl_sp**2)/2.0 * REAL(c_sdp_N_fft*c_nof_block_per_sync);
-- . ampl
CONSTANT c_beamlet_scale : REAL := 1.0 / 2.0**9;
CONSTANT c_wg_ampl_sp_0 : NATURAL := NATURAL(7.0 / c_beamlet_scale); -- choose < 8.0 to have no beamlet output overflow with unit weights and unit beamlet scale
CONSTANT c_wg_ampl_sp_2 : NATURAL := c_wg_ampl_sp_0 / 3; -- use different ampl for sp_0 and sp_2 to distinghuis them
-- . phase
CONSTANT c_subband_phase : REAL := 0.0; -- wanted subband phase in degrees = WG phase at sop
CONSTANT c_wg_latency : INTEGER := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency
CONSTANT c_subband_sp_0 : REAL := 102.0; -- use WG at sp-0 for subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
CONSTANT c_subband_sp_2 : REAL := 99.5; -- use WG at sp-2 for subband at index 99.5 = 99.5/1024 * 200MHz = 19.43359375 MHz
CONSTANT c_subband_freq_sp_0 : REAL := REAL(c_subband_sp_0) / REAL(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate
CONSTANT c_subband_freq_sp_2 : REAL := REAL(c_subband_sp_2) / REAL(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate
CONSTANT c_wg_phase_offset_sp_0 : REAL := 360.0 * REAL(c_wg_latency) * c_subband_freq_sp_0; -- c_diag_wg_latency is in dp_clk cycles
CONSTANT c_wg_phase_offset_sp_2 : REAL := 360.0 * REAL(c_wg_latency) * c_subband_freq_sp_2; -- c_diag_wg_latency is in dp_clk cycles
CONSTANT c_wg_phase_sp_0 : REAL := c_subband_phase + c_wg_phase_offset_sp_0; -- WG phase in degrees
CONSTANT c_wg_phase_sp_2 : REAL := c_subband_phase + c_wg_phase_offset_sp_2; -- WG phase in degrees
-- WPFB, use default unit subband weights (= 1.0 + 0j)
CONSTANT c_exp_subband_ampl_sp_0 : REAL := REAL(c_wg_ampl_sp_0) * c_sdp_wpfb_subband_sp_ampl_ratio;
CONSTANT c_exp_subband_ampl_sp_2 : REAL := REAL(c_wg_ampl_sp_2) * c_sdp_wpfb_subband_sp_ampl_ratio;
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_exp_subband_phase : REAL := c_subband_phase + c_subband_phase_offset;
-- BF
-- . use one active WG per subband, so beamlet_sum of one subband
-- . use default unit BF weights (= 1.0 + 0j), so beamlet_sum = subband
-- . use beamlet output = beamlet_sum * c_beamlet_scale
CONSTANT c_exp_beamlet_scale : NATURAL := NATURAL(c_beamlet_scale * REAL(c_sdp_unit_beamlet_scale)); -- c_sdp_unit_beamlet_scale = 2**15;
CONSTANT c_exp_beamlet_ampl_sp_0 : REAL := c_exp_subband_ampl_sp_0 * c_beamlet_scale;
CONSTANT c_exp_beamlet_ampl_sp_2 : REAL := c_exp_subband_ampl_sp_2 * c_beamlet_scale;
CONSTANT c_exp_beamlet_phase : REAL := c_exp_subband_phase;
CONSTANT c_exp_beamlet_re_sp_0 : INTEGER := INTEGER(COMPLEX_RE(c_exp_beamlet_ampl_sp_0, c_exp_beamlet_phase));
CONSTANT c_exp_beamlet_re_sp_2 : INTEGER := INTEGER(COMPLEX_RE(c_exp_beamlet_ampl_sp_2, c_exp_beamlet_phase));
CONSTANT c_exp_beamlet_im_sp_0 : INTEGER := INTEGER(COMPLEX_IM(c_exp_beamlet_ampl_sp_0, c_exp_beamlet_phase));
CONSTANT c_exp_beamlet_im_sp_2 : INTEGER := INTEGER(COMPLEX_IM(c_exp_beamlet_ampl_sp_2, c_exp_beamlet_phase));
CONSTANT c_exp_beamlet_index : NATURAL := NATURAL(c_subband_sp_0) * c_sdp_N_pol;
CONSTANT c_exp_beamlet_index_os : NATURAL := c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block + NATURAL(ROUND(c_subband_sp_2)) * c_sdp_N_pol;
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_S_sub_bf);
-- MM
-- MM
-- . Address widths of a single MM instance
CONSTANT c_addr_w_reg_diag_wg : NATURAL := 2;
CONSTANT c_addr_w_reg_dp_xonoff : NATURAL := 1;
CONSTANT c_addr_w_reg_bf_scale : NATURAL := 1;
-- . Address spans of a single MM instance
CONSTANT c_mm_span_reg_diag_wg : NATURAL := 2**c_addr_w_reg_diag_wg;
CONSTANT c_mm_span_reg_dp_xonoff : NATURAL := 2**c_addr_w_reg_dp_xonoff;
CONSTANT c_mm_span_reg_bf_scale : NATURAL := 2**c_addr_w_reg_bf_scale;
CONSTANT c_mm_file_reg_ppsh : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS";
CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER";
CONSTANT c_mm_file_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG";
CONSTANT c_mm_file_reg_dp_xonoff : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_XONOFF";
CONSTANT c_mm_file_reg_bf_scale : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BF_SCALE";
-- Tb
SIGNAL tb_end : STD_LOGIC := '0';
@@ -116,16 +171,25 @@ ARCHITECTURE tb OF tb_disturb2_unb2b_sdp_station_full_wg IS
SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0);
-- WG
SIGNAL dbg_c_exp_wg_power_sp : REAL := c_exp_wg_power_sp;
SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
-- BF
SIGNAL rd_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0);
-- 10GbE
CONSTANT c_exp_beamlet_index : NATURAL := NATURAL(c_subband_sp_0) * c_sdp_N_pol;
CONSTANT c_exp_beamlet_index_os : NATURAL := c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block + NATURAL(ROUND(c_subband_sp_1)) * c_sdp_N_pol;
CONSTANT c_exp_beamlet_re : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"7F"; --Derived from simulation
CONSTANT c_exp_beamlet_im : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"81"; --Derived from simulation
SIGNAL dbg_beamlet_index_offset : NATURAL := 0;
-- . header fields
SIGNAL rx_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL rx_beamlet_index_offset : NATURAL := 0;
SIGNAL rx_blocks_per_packet : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL rx_beamlets_per_block : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL rx_block_period : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL rx_bsn : STD_LOGIC_VECTOR(63 DOWNTO 0);
-- . payload indices and data arrays
SIGNAL rx_beamlet_blk : NATURAL := 0;
SIGNAL rx_beamlet_cnt : NATURAL := 0;
SIGNAL rx_beamlet_valid : STD_LOGIC := '0';
SIGNAL rx_beamlet_sop : STD_LOGIC := '0';
SIGNAL beamlet_arr2_re : t_slv_8_arr(c_sdp_R_os * c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block-1 DOWNTO 0);
SIGNAL beamlet_arr2_im : t_slv_8_arr(c_sdp_R_os * c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block-1 DOWNTO 0);
@@ -274,7 +338,8 @@ BEGIN
p_mm_stimuli : PROCESS
VARIABLE v_bsn : NATURAL;
VARIABLE v_beamlet_index_offset : NATURAL;
VARIABLE v_offset : NATURAL;
VARIABLE v_beamlet_index_offset : NATURAL;
BEGIN
-- Wait for DUT power up after reset
WAIT FOR 1 us;
@@ -282,10 +347,25 @@ BEGIN
proc_common_wait_until_hi_lo(ext_clk, ext_pps);
----------------------------------------------------------------------------
-- Enable UDP offload (dp_xonoff) of beamset 0
-- Use both beamsets, 0 for BF with normal subbands, 1 for BF with shifted subbands
----------------------------------------------------------------------------
mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff,0 , 1, tb_clk);
mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff,2 , 1, tb_clk);
FOR bset IN 0 TO c_sdp_N_beamsets-1 LOOP
-- Enable beamlet output
v_offset := bset * c_mm_span_reg_dp_xonoff;
mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff, v_offset + 0, 1, tb_clk);
-- MM beamlet_scale
-- . write
v_offset := bset * c_mm_span_reg_bf_scale;
mmf_mm_bus_wr(c_mm_file_reg_bf_scale, v_offset + 0, c_exp_beamlet_scale, tb_clk);
proc_common_wait_cross_clock_domain_latency(c_tb_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2);
-- . readback
mmf_mm_bus_rd(c_mm_file_reg_bf_scale, v_offset + 0, rd_data, tb_clk);
rd_beamlet_scale <= rd_data(15 DOWNTO 0);
proc_common_wait_some_cycles(tb_clk, 1);
ASSERT TO_UINT(rd_beamlet_scale) = c_exp_beamlet_scale REPORT "Wrong MM read beamlet_scale for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR;
END LOOP;
----------------------------------------------------------------------------
-- Enable BS
@@ -303,14 +383,18 @@ BEGIN
-- 1 : phase[15:0]
-- 2 : freq[30:0]
-- 3 : ampl[16:0]
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 1, INTEGER( 0.0 * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 2, INTEGER((c_subband_sp_0+c_wg_freq_offset) * c_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 3, INTEGER(REAL(c_ampl_sp) * c_wg_ampl_lsb), tb_clk); -- ampl
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 8, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 9, INTEGER( 0.0 * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 10, INTEGER((c_subband_sp_1+c_wg_freq_offset) * c_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 11, INTEGER(REAL(c_ampl_sp) * c_wg_ampl_lsb), tb_clk); -- ampl
-- WG at signal input 0
v_offset := 0 * c_mm_span_reg_diag_wg;
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_wg_phase_sp_0 * 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(c_subband_sp_0 * c_sdp_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_ampl_sp_0) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl
-- WG at signal input 2
v_offset := 2 * c_mm_span_reg_diag_wg;
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_wg_phase_sp_2 * 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(c_subband_sp_2 * c_sdp_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_ampl_sp_2) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl
-- Read current BSN
mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk);
@@ -332,50 +416,114 @@ BEGIN
---------------------------------------------------------------------------
-- Read 10GbE Stream
---------------------------------------------------------------------------
FOR BS IN 0 TO 2 LOOP -- Read 3 blocks to make sure we get 1 from each beamset. It can happen that two blocks (but not three) from the same beamset are received back to back.
proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.sop);
-- Read 3 packets to make sure we get 1 from each beamset. It can happen that two packets
-- (but not three) from the same beamset are received back to back.
FOR packet IN 0 TO 2 LOOP
-- Get beamlet_index from packet header
proc_common_wait_until_clk_and_high(ext_clk, tr_10GbE_src_out.sop);
FOR I IN 0 TO 8 LOOP -- Packet header is 9.25 words wide, which can be discarded
IF I = 7 THEN
v_beamlet_index_offset := c_sdp_N_pol_bf * TO_UINT(tr_10GbE_src_out.data(39 DOWNTO 24)); -- Read beamlet index
dbg_beamlet_index_offset <= v_beamlet_index_offset;
rx_beamlet_scale <= tr_10GbE_src_out.data(55 DOWNTO 40);
v_beamlet_index_offset := c_sdp_N_pol_bf * TO_UINT(tr_10GbE_src_out.data(39 DOWNTO 24)); -- Read beamlet index
rx_beamlet_index_offset <= v_beamlet_index_offset;
rx_blocks_per_packet <= tr_10GbE_src_out.data(23 DOWNTO 16);
rx_beamlets_per_block <=tr_10GbE_src_out.data(15 DOWNTO 0);
END IF;
IF I = 8 THEN
rx_block_period <= tr_10GbE_src_out.data(63 DOWNTO 48);
rx_bsn(63 DOWNTO 16) <= tr_10GbE_src_out.data(47 DOWNTO 0);
END IF;
proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid);
proc_common_wait_some_cycles(ext_clk, 1);
proc_common_wait_until_clk_and_high(ext_clk, tr_10GbE_src_out.valid);
END LOOP;
-- First word contains 3 beamlets + 1 header part
beamlet_arr2_re(v_beamlet_index_offset + 0) <= tr_10GbE_src_out.data(7 DOWNTO 0);
beamlet_arr2_im(v_beamlet_index_offset + 0) <= tr_10GbE_src_out.data(15 DOWNTO 8);
beamlet_arr2_re(v_beamlet_index_offset + 1) <= tr_10GbE_src_out.data(23 DOWNTO 16);
beamlet_arr2_im(v_beamlet_index_offset + 1) <= tr_10GbE_src_out.data(31 DOWNTO 24);
beamlet_arr2_re(v_beamlet_index_offset + 2) <= tr_10GbE_src_out.data(39 DOWNTO 32);
beamlet_arr2_im(v_beamlet_index_offset + 2) <= tr_10GbE_src_out.data(47 DOWNTO 40);
proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid);
proc_common_wait_some_cycles(ext_clk, 1);
FOR I IN 1 TO (c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block/4)-1 LOOP
beamlet_arr2_re(v_beamlet_index_offset + I*4 -1) <= tr_10GbE_src_out.data(7 DOWNTO 0);
beamlet_arr2_im(v_beamlet_index_offset + I*4 -1) <= tr_10GbE_src_out.data(15 DOWNTO 8);
beamlet_arr2_re(v_beamlet_index_offset + I*4 +0) <= tr_10GbE_src_out.data(23 DOWNTO 16);
beamlet_arr2_im(v_beamlet_index_offset + I*4 +0) <= tr_10GbE_src_out.data(31 DOWNTO 24);
beamlet_arr2_re(v_beamlet_index_offset + I*4 +1) <= tr_10GbE_src_out.data(39 DOWNTO 32);
beamlet_arr2_im(v_beamlet_index_offset + I*4 +1) <= tr_10GbE_src_out.data(47 DOWNTO 40);
beamlet_arr2_re(v_beamlet_index_offset + I*4 +2) <= tr_10GbE_src_out.data(55 DOWNTO 48);
beamlet_arr2_im(v_beamlet_index_offset + I*4 +2) <= tr_10GbE_src_out.data(63 DOWNTO 56);
proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid);
proc_common_wait_some_cycles(ext_clk, 1);
rx_bsn(15 DOWNTO 0) <= tr_10GbE_src_out.data(63 DOWNTO 48);
-- Get all c_sdp_cep_nof_blocks_per_packet = 4 blocks from the packet
FOR blk IN 0 TO c_sdp_cep_nof_blocks_per_packet-1 LOOP
-- . First word contains 1 header part of two bytes and 3 beamlets [0:2].
-- . 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 tr_10GbE_src_out.data.
rx_beamlet_blk <= blk;
rx_beamlet_cnt <= 0;
rx_beamlet_valid <= '1';
rx_beamlet_sop <= '1';
beamlet_arr2_im(v_beamlet_index_offset + 0) <= tr_10GbE_src_out.data(47 DOWNTO 40);
beamlet_arr2_re(v_beamlet_index_offset + 0) <= tr_10GbE_src_out.data(39 DOWNTO 32);
beamlet_arr2_im(v_beamlet_index_offset + 1) <= tr_10GbE_src_out.data(31 DOWNTO 24);
beamlet_arr2_re(v_beamlet_index_offset + 1) <= tr_10GbE_src_out.data(23 DOWNTO 16);
beamlet_arr2_im(v_beamlet_index_offset + 2) <= tr_10GbE_src_out.data(15 DOWNTO 8);
beamlet_arr2_re(v_beamlet_index_offset + 2) <= tr_10GbE_src_out.data(7 DOWNTO 0);
proc_common_wait_until_clk_and_high(ext_clk, tr_10GbE_src_out.valid);
rx_beamlet_cnt <= rx_beamlet_cnt + 1;
rx_beamlet_sop <= '0';
-- . get beamlets during block, there are 4 complex beamlets per 64b word
FOR I IN 1 TO (c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block/4)-1 LOOP
beamlet_arr2_im(v_beamlet_index_offset + I*4 -1) <= tr_10GbE_src_out.data(63 DOWNTO 56);
beamlet_arr2_re(v_beamlet_index_offset + I*4 -1) <= tr_10GbE_src_out.data(55 DOWNTO 48);
beamlet_arr2_im(v_beamlet_index_offset + I*4 +0) <= tr_10GbE_src_out.data(47 DOWNTO 40);
beamlet_arr2_re(v_beamlet_index_offset + I*4 +0) <= tr_10GbE_src_out.data(39 DOWNTO 32);
beamlet_arr2_im(v_beamlet_index_offset + I*4 +1) <= tr_10GbE_src_out.data(31 DOWNTO 24);
beamlet_arr2_re(v_beamlet_index_offset + I*4 +1) <= tr_10GbE_src_out.data(23 DOWNTO 16);
beamlet_arr2_im(v_beamlet_index_offset + I*4 +2) <= tr_10GbE_src_out.data(15 DOWNTO 8);
beamlet_arr2_re(v_beamlet_index_offset + I*4 +2) <= tr_10GbE_src_out.data(7 DOWNTO 0);
proc_common_wait_until_clk_and_high(ext_clk, tr_10GbE_src_out.valid);
rx_beamlet_cnt <= rx_beamlet_cnt + 1;
END LOOP;
-- . get last beamlet of block
beamlet_arr2_im(v_beamlet_index_offset + c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block-1) <= tr_10GbE_src_out.data(63 DOWNTO 56);
beamlet_arr2_re(v_beamlet_index_offset + c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block-1) <= tr_10GbE_src_out.data(55 DOWNTO 48);
-- Loop for next block in packet
END LOOP;
-- Make rx_beamlet_valid low for next header or after loop during verify.
-- Cannot wait one ext_clk cycle here to include last beamlet of block,
-- because next packet sop may follow immediately after this packet eop.
rx_beamlet_valid <= '0';
beamlet_arr2_re(v_beamlet_index_offset + c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block-1) <= tr_10GbE_src_out.data(55 DOWNTO 48);
beamlet_arr2_im(v_beamlet_index_offset + c_sdp_N_pol_bf * c_sdp_cep_nof_beamlets_per_block-1) <= tr_10GbE_src_out.data(63 DOWNTO 56);
-- Loop and wait for next packet.
END LOOP;
---------------------------------------------------------------------------
-- Verify 10GbE UDP offload
---------------------------------------------------------------------------
ASSERT beamlet_arr2_re(c_exp_beamlet_index) = c_exp_beamlet_re REPORT "Wrong 10GbE output (re) on beamset 0" SEVERITY ERROR;
ASSERT beamlet_arr2_im(c_exp_beamlet_index) = c_exp_beamlet_im REPORT "Wrong 10GbE output (im) on beamset 0" SEVERITY ERROR;
ASSERT beamlet_arr2_re(c_exp_beamlet_index_os) = c_exp_beamlet_re REPORT "Wrong 10GbE output (re) on beamset 1 (shifted subbands)" SEVERITY ERROR;
ASSERT beamlet_arr2_im(c_exp_beamlet_index_os) = c_exp_beamlet_im REPORT "Wrong 10GbE output (im) on beamset 1 (shifted subbands)" SEVERITY ERROR;
print_str("");
print_str("WG:");
print_str(". sp_0 at mid subband,");
print_str(". sp_2 at subband edge, so at mid of os subband.");
print_str(". c_wg_ampl_sp_0 = " & int_to_str(c_wg_ampl_sp_0));
print_str(". c_wg_ampl_sp_2 = " & int_to_str(c_wg_ampl_sp_2));
print_str(". c_subband_sp_0 = " & real_to_str(c_subband_sp_0, 20, 6));
print_str(". c_subband_sp_2 = " & real_to_str(c_subband_sp_2, 20, 6));
print_str("WPFB:");
print_str(". c_exp_subband_ampl_sp_0 = " & real_to_str(c_exp_subband_ampl_sp_0, 20, 6));
print_str(". c_exp_subband_ampl_sp_2 = " & real_to_str(c_exp_subband_ampl_sp_2, 20, 6));
print_str("");
print_str("Beamlet output: (sp_0 at mid subband, sp_2 at subband edge, so at mid of os subband):");
print_str(". c_exp_beamlet_index = " & int_to_str(c_exp_beamlet_index));
print_str(". c_exp_beamlet_index_os = " & int_to_str(c_exp_beamlet_index_os));
print_str(". c_exp_beamlet_ampl_sp_0 = " & real_to_str(c_exp_beamlet_ampl_sp_0, 20, 6));
print_str(". c_exp_beamlet_ampl_sp_2 = " & real_to_str(c_exp_beamlet_ampl_sp_2, 20, 6));
print_str(". c_exp_beamlet_phase = " & real_to_str(c_exp_beamlet_phase, 20, 6));
print_str("");
print_str(". c_beamlet_re at index = " & int_to_str(TO_SINT(beamlet_arr2_re(c_exp_beamlet_index))));
print_str(". c_beamlet_re at index_os = " & int_to_str(TO_SINT(beamlet_arr2_re(c_exp_beamlet_index_os))));
print_str(". c_exp_beamlet_re_sp_0 = " & int_to_str(INTEGER(c_exp_beamlet_re_sp_0)));
print_str(". c_exp_beamlet_re_sp_2 = " & int_to_str(INTEGER(c_exp_beamlet_re_sp_2)));
print_str("");
print_str(". c_beamlet_im at index = " & int_to_str(TO_SINT(beamlet_arr2_im(c_exp_beamlet_index))));
print_str(". c_beamlet_im at index_os = " & int_to_str(TO_SINT(beamlet_arr2_im(c_exp_beamlet_index_os))));
print_str(". c_exp_beamlet_im_sp_0 = " & int_to_str(INTEGER(c_exp_beamlet_im_sp_0)));
print_str(". c_exp_beamlet_im_sp_2 = " & int_to_str(INTEGER(c_exp_beamlet_im_sp_2)));
-- WG at subband center will yield same subband value in every subband period
ASSERT SIGNED(beamlet_arr2_re(c_exp_beamlet_index)) = c_exp_beamlet_re_sp_0 REPORT "Wrong 10GbE beamlet output /= c_exp_beamlet_re_sp_0 in beamset 0" SEVERITY ERROR;
ASSERT SIGNED(beamlet_arr2_im(c_exp_beamlet_index)) = c_exp_beamlet_im_sp_0 REPORT "Wrong 10GbE beamlet output /= c_exp_beamlet_im_sp_0 in beamset 0" SEVERITY ERROR;
-- WG at subband edge will change phase 180 degrees in every subband period, so expect factor +-1
ASSERT SIGNED(beamlet_arr2_re(c_exp_beamlet_index_os)) = c_exp_beamlet_re_sp_2 OR
SIGNED(beamlet_arr2_re(c_exp_beamlet_index_os)) = -c_exp_beamlet_re_sp_2 REPORT "Wrong 10GbE beamlet output /= c_exp_beamlet_re_sp_2 in beamset 1 (shifted subbands)" SEVERITY ERROR;
ASSERT SIGNED(beamlet_arr2_im(c_exp_beamlet_index_os)) = c_exp_beamlet_im_sp_2 OR
SIGNED(beamlet_arr2_im(c_exp_beamlet_index_os)) = -c_exp_beamlet_im_sp_2 REPORT "Wrong 10GbE beamlet output /= c_exp_beamlet_im_sp_2 in beamset 1 (shifted subbands)" SEVERITY ERROR;
---------------------------------------------------------------------------
-- End Simulation
Loading