diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd index 24bb76e9513ce0d4c81e2494110c1d5b93f66b34..959d8eabf8f597ffe7215598f50f5c23f35a5b55 100644 --- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd @@ -20,7 +20,7 @@ ------------------------------------------------------------------------------- -- --- Author: R. van der Walle +-- Author: R. van der Walle, E. Kooistra -- Purpose: Self-checking testbench for simulating lofar2_unb2b_sdp_station_bf using WG data. -- -- Description: @@ -46,7 +46,7 @@ -- > as 7 # default -- > as 12 # for detailed debugging -- > run -a --- Takes about 45 m +-- Takes about 40 m -- ------------------------------------------------------------------------------- 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, lofar2_unb2b_sdp_station_lib; @@ -54,7 +54,9 @@ USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; USE IEEE.MATH_REAL.ALL; USE common_lib.common_pkg.ALL; -USE unb2b_board_lib.unb2b_board_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE common_lib.common_field_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; USE common_lib.tb_common_pkg.ALL; USE common_lib.common_str_pkg.ALL; USE mm_lib.mm_file_pkg.ALL; @@ -62,7 +64,9 @@ USE dp_lib.dp_stream_pkg.ALL; USE mm_lib.mm_file_unb_pkg.ALL; USE diag_lib.diag_pkg.ALL; USE wpfb_lib.wpfb_pkg.ALL; +USE unb2b_board_lib.unb2b_board_pkg.ALL; USE lofar2_sdp_lib.sdp_pkg.ALL; +USE lofar2_sdp_lib.tb_sdp_pkg.ALL; USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY tb_lofar2_unb2b_sdp_station_bf IS @@ -73,10 +77,18 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_bf IS CONSTANT c_sim : BOOLEAN := TRUE; CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 CONSTANT c_node_nr : NATURAL := 0; - CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; + CONSTANT c_gn_index : NATURAL := c_unb_nr * 4 + c_node_nr; -- this node GN + CONSTANT c_O_rn : NATURAL := 0; + CONSTANT c_N_rn : NATURAL := 16; + CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0 + + CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_gn_index, 8); CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; CONSTANT c_fw_version : t_unb2b_board_fw_version := (1, 0); + CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr, 8); + CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr+1, 8); -- +1 to avoid IP = *.*.*.0 + CONSTANT c_eth_clk_period : TIME := 8 ns; -- 125 MHz XO on UniBoard CONSTANT c_ext_clk_period : TIME := 5 ns; CONSTANT c_bck_ref_clk_period : TIME := 5 ns; @@ -94,9 +106,37 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_bf IS CONSTANT c_lo_factor : REAL := 1.0 - c_percentage; -- lower boundary CONSTANT c_hi_factor : REAL := 1.0 + c_percentage; -- higher boundary + -- header fields + CONSTANT c_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_dst_mac; -- 00074306C700 = DOP36-eth0 + CONSTANT c_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_dst_addr; -- C0A80001 = '192.168.0.1' = DOP36-eth0 + CONSTANT c_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_dst_port; -- 5000 + + CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & c_mac_15_0; -- x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node + CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & c_ip_15_0; -- C0A80001 = '192.168.0.1' = DOP36-eth0 + CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_id; -- D0 & c_id + + CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDE#; -- value obtained from rx_sdp_cep_header.ip.header_checksum in wave window + + CONSTANT c_exp_beamlet_scale : NATURAL := 2**15; + + CONSTANT c_exp_sdp_info : t_sdp_info := ( + TO_UVEC(601, 16), -- station_id + '0', -- antenna_band_index + x"7FFFFFFF", -- observation_id, use > 0 to avoid Warning: (vsim-151) NUMERIC_STD.TO_INTEGER: Value -2 is not in bounds of subtype NATURAL. + b"01", -- nyquist_zone_index, 0 = first, 1 = second, 2 = third + '1', -- f_adc, 0 = 160 MHz, 1 = 200 MHz + '0', -- fsub_type, 0 = critically sampled, 1 = oversampled + '0', -- beam_repositioning_flag + x"01", -- O_si, not used + x"02", -- N_si, not used + TO_UVEC(c_O_rn, 8), -- O_rn + TO_UVEC(c_N_rn, 8), -- N_rn + x"1400" -- block_period = 5120 + ); + -- WG CONSTANT c_full_scale_ampl : REAL := REAL(2**(14-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_bsn_start_wg : NATURAL := c_init_bsn + 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values CONSTANT c_ampl_sp_0 : 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 @@ -114,7 +154,27 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_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); TYPE t_slv_64_beamlets_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_S_sub_bf); + -- BF + CONSTANT c_exp_beamlet_index : NATURAL := NATURAL(c_subband_sp_0) * c_sdp_N_pol_bf; + CONSTANT c_exp_beamlet_re : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"81"; -- = -127, derived from simulation + CONSTANT c_exp_beamlet_im : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"7F"; -- = +127, derived from simulation + -- MM + -- . Address widths of a single MM instance + CONSTANT c_addr_w_ram_ss_ss_wide : NATURAL := ceil_log2(c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); + CONSTANT c_addr_w_ram_bf_weights : NATURAL := ceil_log2(c_sdp_N_pol * c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); + CONSTANT c_addr_w_reg_bf_scale : NATURAL := 1; + CONSTANT c_addr_w_reg_hdr_dat : NATURAL := ceil_log2(field_nof_words(c_sdp_cep_hdr_field_arr, c_word_w)); + CONSTANT c_addr_w_reg_dp_xonoff : NATURAL := 1; + CONSTANT c_addr_w_ram_st_bst : NATURAL := ceil_log2(c_sdp_S_sub_bf*c_sdp_N_pol*(c_longword_sz/c_word_sz)); + -- . Address spans of a single MM instance + CONSTANT c_mm_span_ram_ss_ss_wide : NATURAL := 2**c_addr_w_ram_ss_ss_wide; + CONSTANT c_mm_span_ram_bf_weights : NATURAL := 2**c_addr_w_ram_bf_weights; + CONSTANT c_mm_span_reg_bf_scale : NATURAL := 2**c_addr_w_reg_bf_scale; + CONSTANT c_mm_span_reg_hdr_dat : NATURAL := 2**c_addr_w_reg_hdr_dat; + CONSTANT c_mm_span_reg_dp_xonoff : NATURAL := 2**c_addr_w_reg_dp_xonoff; + CONSTANT c_mm_span_ram_st_bst : NATURAL := 2**c_addr_w_ram_st_bst; + 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"; @@ -122,13 +182,32 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_bf IS CONSTANT c_mm_file_ram_st_bst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_BST"; 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_ram_st_sst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST"; + CONSTANT c_mm_file_reg_sdp_info : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_SDP_INFO"; + CONSTANT c_mm_file_reg_bf_scale : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BF_SCALE"; + CONSTANT c_mm_file_reg_hdr_dat : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_HDR_DAT"; -- c_sdp_N_beamsets = 2 beamsets -- Tb + SIGNAL stimuli_done : STD_LOGIC := '0'; + SIGNAL tb_almost_end : STD_LOGIC := '0'; SIGNAL tb_end : STD_LOGIC := '0'; - SIGNAL sim_done : STD_LOGIC := '0'; SIGNAL tb_clk : STD_LOGIC := '0'; SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); + SIGNAL dest_rst : STD_LOGIC := '1'; -- use separate destination rst for Rx 10GbE in tb + SIGNAL pps_rst : STD_LOGIC := '1'; -- use separate reset to release the PPS generator + SIGNAL gen_pps : STD_LOGIC := '0'; + + SIGNAL in_sync : STD_LOGIC := '0'; + SIGNAL in_sync_cnt : NATURAL := 0; + SIGNAL test_sync_cnt : INTEGER := 0; + + -- MM + SIGNAL rd_sdp_info : t_sdp_info := c_sdp_info_rst; + SIGNAL rd_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0); + SIGNAL rd_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL rd_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL rd_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0); + -- WG SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); @@ -144,28 +223,39 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_bf IS SIGNAL sp_beamlet_power_leakage_sum_0 : REAL; -- 10GbE - CONSTANT c_exp_beamlet_index : NATURAL := NATURAL(c_subband_sp_0) * c_sdp_N_pol_bf; - CONSTANT c_exp_beamlet_re : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"81"; -- = -127, derived from simulation - CONSTANT c_exp_beamlet_im : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"7F"; -- = +127, derived from simulation + 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 dbg_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0] - SIGNAL dbg_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0] - SIGNAL dbg_beamlet_cnt : NATURAL; - SIGNAL dbg_beamlet_valid : STD_LOGIC; - - SIGNAL beamlet_arr2_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 beamlet_arr2_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] + 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] 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; + + SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0); + SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0'); + SIGNAL rx_sdp_cep_header : t_sdp_cep_header; + SIGNAL exp_sdp_cep_header : t_sdp_cep_header; + SIGNAL exp_dp_bsn : NATURAL; + -- DUT SIGNAL ext_clk : STD_LOGIC := '0'; - SIGNAL pps : STD_LOGIC := '0'; SIGNAL ext_pps : STD_LOGIC := '0'; - SIGNAL pps_rst : STD_LOGIC := '1'; SIGNAL WDI : STD_LOGIC; SIGNAL INTA : STD_LOGIC; @@ -200,6 +290,7 @@ BEGIN eth_clk <= NOT eth_clk AFTER c_eth_clk_period/2; -- Ethernet ref clock (125 MHz) JESD204B_REFCLK <= NOT JESD204B_REFCLK AFTER c_bck_ref_clk_period/2; -- JESD sample clock (200MHz) SA_CLK <= NOT SA_CLK AFTER c_sa_clk_period/2; -- Serial Gigabit IO sa clock (644 MHz) + dest_rst <= '0' AFTER c_ext_clk_period * 10; INTA <= 'H'; -- pull up INTB <= 'H'; -- pull up @@ -212,9 +303,9 @@ BEGIN ------------------------------------------------------------------------------ -- External PPS ------------------------------------------------------------------------------ - proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, pps); - jesd204b_sysref <= pps; - ext_pps <= pps; + proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, gen_pps); + jesd204b_sysref <= gen_pps; + ext_pps <= gen_pps; ------------------------------------------------------------------------------ -- DUT @@ -233,7 +324,7 @@ BEGIN PORT MAP ( -- GENERAL CLK => ext_clk, - PPS => pps, + PPS => ext_pps, WDI => WDI, INTA => INTA, INTB => INTB, @@ -274,50 +365,78 @@ BEGIN JESD204B_SYNC_N => jesd204b_sync_n ); - u_unb2_board_clk644_pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks - PORT MAP ( - refclk_644 => SA_CLK, - rst_in => pps_rst, - clk_156 => tr_ref_clk_156, - clk_312 => tr_ref_clk_312, - rst_156 => tr_ref_rst_156, - rst_312 => OPEN - ); - - u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE - GENERIC MAP ( - g_sim => TRUE, - g_sim_level => 1, - g_nof_macs => 1, - g_use_mdio => FALSE - ) - PORT MAP ( - -- Transceiver PLL reference clock - tr_ref_clk_644 => SA_CLK, - tr_ref_clk_312 => tr_ref_clk_312, -- 312.5 MHz for 10GBASE-R - tr_ref_clk_156 => tr_ref_clk_156, -- 156.25 MHz for 10GBASE-R or for XAUI - tr_ref_rst_156 => tr_ref_rst_156, -- for 10GBASE-R or for XAUI - - -- MM interface - mm_rst => pps_rst, - mm_clk => tb_clk, - - -- DP interface - dp_rst => pps_rst, - dp_clk => ext_clk, - - serial_rx_arr(0) => si_lpbk_0(0), - - src_out_arr(0) => tr_10GbE_src_out - - ); + u_unb2_board_clk644_pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks + PORT MAP ( + refclk_644 => SA_CLK, + rst_in => dest_rst, + clk_156 => tr_ref_clk_156, + clk_312 => tr_ref_clk_312, + rst_156 => tr_ref_rst_156, + rst_312 => OPEN + ); + + u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE + GENERIC MAP ( + g_sim => TRUE, + g_sim_level => 1, + g_nof_macs => 1, + g_use_mdio => FALSE + ) + PORT MAP ( + -- Transceiver PLL reference clock + tr_ref_clk_644 => SA_CLK, + tr_ref_clk_312 => tr_ref_clk_312, -- 312.5 MHz for 10GBASE-R + tr_ref_clk_156 => tr_ref_clk_156, -- 156.25 MHz for 10GBASE-R or for XAUI + tr_ref_rst_156 => tr_ref_rst_156, -- for 10GBASE-R or for XAUI + + -- MM interface + mm_rst => dest_rst, + mm_clk => tb_clk, + + -- DP interface + dp_rst => dest_rst, + dp_clk => ext_clk, + + serial_rx_arr(0) => si_lpbk_0(0), + + src_out_arr(0) => tr_10GbE_src_out, + src_in_arr(0) => tr_10GbE_src_in + ); + + + u_rx : ENTITY dp_lib.dp_offload_rx + GENERIC MAP ( + g_nof_streams => 1, + g_data_w => c_longword_w, + g_symbol_w => c_octet_w, + g_hdr_field_arr => c_sdp_cep_hdr_field_arr, + g_remove_crc => FALSE, + g_crc_nof_words => 0 + ) + PORT MAP ( + mm_rst => dest_rst, + mm_clk => tb_clk, + + 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, + snk_in_arr(0) => tr_10GbE_src_out, + snk_out_arr(0) => tr_10GbE_src_in, + + src_out_arr(0) => test_offload_sosi, + + hdr_fields_out_arr(0) => rx_hdr_fields_out, + hdr_fields_raw_arr(0) => rx_hdr_fields_raw + ); ------------------------------------------------------------------------------ -- MM slave accesses via file IO ------------------------------------------------------------------------------ tb_clk <= NOT tb_clk AFTER c_tb_clk_period/2; -- Testbench MM clock - + p_mm_stimuli : PROCESS VARIABLE v_bsn : NATURAL; VARIABLE v_sp_beamlet_power : REAL; @@ -325,21 +444,132 @@ BEGIN VARIABLE v_W, v_T, v_U, v_S, v_B : NATURAL; -- array indicies VARIABLE v_re, v_im : INTEGER; VARIABLE v_re_exp, v_im_exp : INTEGER; + VARIABLE v_offset : NATURAL; BEGIN -- Wait for DUT power up after reset WAIT FOR 1 us; ---------------------------------------------------------------------------- - -- Enable UDP offload (dp_xonoff) of beamset 0 + -- Set and check SDP info ---------------------------------------------------------------------------- - 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); + -- TYPE t_sdp_info IS RECORD + -- 11 station_id : STD_LOGIC_VECTOR(15 DOWNTO 0); + -- 10 antenna_band_index : STD_LOGIC; + -- 9 observation_id : STD_LOGIC_VECTOR(31 DOWNTO 0); + -- 8 nyquist_zone_index : STD_LOGIC_VECTOR(1 DOWNTO 0); + -- 7 f_adc : STD_LOGIC; + -- 6 fsub_type : STD_LOGIC; + -- 5 beam_repositioning_flag : STD_LOGIC; + -- 4 O_si : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 3 N_si : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 2 O_rn : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 1 N_rn : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 0 block_period : STD_LOGIC_VECTOR(15 DOWNTO 0); + -- END RECORD; + -- . Write + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 11, TO_UINT(c_exp_sdp_info.station_id), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 9, TO_UINT(c_exp_sdp_info.observation_id), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 8, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 5, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 4, TO_UINT(c_exp_sdp_info.O_si), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 3, TO_UINT(c_exp_sdp_info.N_si), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 2, TO_UINT(c_exp_sdp_info.O_rn), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 1, TO_UINT(c_exp_sdp_info.N_rn), tb_clk); + -- . Read + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 10, rd_data, tb_clk); rd_sdp_info.antenna_band_index <= rd_data(0); + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 7, rd_data, tb_clk); rd_sdp_info.f_adc <= rd_data(0); + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 6, rd_data, tb_clk); rd_sdp_info.fsub_type <= rd_data(0); + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 0, rd_data, tb_clk); rd_sdp_info.block_period <= rd_data(15 DOWNTO 0); + proc_common_wait_some_cycles(tb_clk, 1); + -- . Verify read + ASSERT c_exp_sdp_info.antenna_band_index = rd_sdp_info.antenna_band_index REPORT "Wrong MM read SDP info antenna_band_index" SEVERITY ERROR; + ASSERT c_exp_sdp_info.f_adc = rd_sdp_info.f_adc REPORT "Wrong MM read SDP info f_adc" SEVERITY ERROR; + ASSERT c_exp_sdp_info.fsub_type = rd_sdp_info.fsub_type REPORT "Wrong MM read SDP info fsub_type" SEVERITY ERROR; + ASSERT c_exp_sdp_info.block_period = rd_sdp_info.block_period REPORT "Wrong MM read SDP info block_period" SEVERITY ERROR; + + ------------------------------------------------------------------------------ + ---- Set and check BF per beamset + ------------------------------------------------------------------------------ + FOR bset IN 0 TO c_sdp_N_beamsets-1 LOOP + -- MM beamlet_scale + v_offset := bset * c_mm_span_reg_bf_scale; + 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; + + -- CEP beamlet output header + -- c_sdp_cep_hdr_field_arr : t_common_field_arr(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := ( + -- 40 "eth_dst_mac" ), "RW", 48, field_default(c_sdp_cep_eth_dst_mac) ), + -- 38 "eth_src_mac" ), "RW", 48, field_default(0) ), + -- 37 "eth_type" ), "RW", 16, field_default(x"0800") ), + -- + -- 36 "ip_version" ), "RW", 4, field_default(4) ), + -- 35 "ip_header_length" ), "RW", 4, field_default(5) ), + -- 34 "ip_services" ), "RW", 8, field_default(0) ), + -- 33 "ip_total_length" ), "RW", 16, field_default(c_sdp_cep_ip_total_length) ), + -- 32 "ip_identification" ), "RW", 16, field_default(0) ), + -- 31 "ip_flags" ), "RW", 3, field_default(2) ), + -- 30 "ip_fragment_offset" ), "RW", 13, field_default(0) ), + -- 29 "ip_time_to_live" ), "RW", 8, field_default(127) ), + -- 28 "ip_protocol" ), "RW", 8, field_default(17) ), + -- 27 "ip_header_checksum" ), "RW", 16, field_default(0) ), + -- 26 "ip_src_addr" ), "RW", 32, field_default(0) ), + -- 25 "ip_dst_addr" ), "RW", 32, field_default(c_sdp_cep_ip_dst_addr) ), + -- + -- 24 "udp_src_port" ), "RW", 16, field_default(0) ), + -- 23 "udp_dst_port" ), "RW", 16, field_default(c_sdp_cep_udp_dst_port) ), + -- 22 "udp_total_length" ), "RW", 16, field_default(c_sdp_cep_udp_total_length) ), + -- 21 "udp_checksum" ), "RW", 16, field_default(0) ), + -- + -- 20 "sdp_marker" ), "RW", 8, field_default(c_sdp_marker_beamlets) ), + -- 19 "sdp_version_id" ), "RW", 8, field_default(c_sdp_cep_version_id) ), + -- 18 "sdp_observation_id" ), "RW", 32, field_default(0) ), + -- 17 "sdp_station_id" ), "RW", 16, field_default(0) ), + -- + -- 16 "sdp_source_info_antenna_band_id" ), "RW", 1, field_default(0) ), + -- 15 "sdp_source_info_nyquist_zone_id" ), "RW", 2, field_default(0) ), + -- 14 "sdp_source_info_f_adc" ), "RW", 1, field_default(0) ), + -- 13 "sdp_source_info_fsub_type" ), "RW", 1, field_default(0) ), + -- 12 "sdp_source_info_payload_error" ), "RW", 1, field_default(0) ), + -- 11 "sdp_source_info_repositioning_flag" ), "RW", 1, field_default(0) ), + -- 10 "sdp_source_info_beamlet_width" ), "RW", 4, field_default(c_sdp_W_beamlet) ), + -- 9 "sdp_source_info_gn_id" ), "RW", 5, field_default(0) ), + -- + -- 7 "sdp_reserved" ), "RW", 40, field_default(0) ), + -- 6 "sdp_beamlet_scale" ), "RW", 16, field_default(c_sdp_beamlet_scale_default) ), + -- 5 "sdp_beamlet_index" ), "RW", 16, field_default(0) ), + -- 4 "sdp_nof_blocks_per_packet" ), "RW", 8, field_default(c_sdp_cep_nof_blocks_per_packet) ), + -- 3 "sdp_nof_beamlets_per_block" ), "RW", 16, field_default(c_sdp_cep_nof_beamlets_per_block) ), + -- 2 "sdp_block_period" ), "RW", 16, field_default(c_sdp_block_period) ), + -- + -- 0 "dp_bsn" ), "RW", 64, field_default(0) ) + -- ); + + v_offset := bset * c_mm_span_reg_hdr_dat; + -- . Use defaults, so no need to write + -- . Read + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); + proc_common_wait_some_cycles(tb_clk, 1); + -- verify read + ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 00074306C700 = DOP36-eth0 + ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- C0A80001 = '192.168.0.1' = DOP36-eth0 + ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 5000 + + ---------------------------------------------------------------------------- + -- Enable beamlet UDP offload (dp_xonoff) + ---------------------------------------------------------------------------- + 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); + END LOOP; ---------------------------------------------------------------------------- -- Enable BS ---------------------------------------------------------------------------- - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, 0, tb_clk); -- Init BSN = 0 + mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, c_init_bsn, tb_clk); -- Init BSN + mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); -- Write high part activates the init BSN mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_sync mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000003#, tb_clk); -- Enable BS at PPS @@ -373,10 +603,13 @@ BEGIN mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1, 0, tb_clk); -- assume v_bsn < 2**31-1 -- Wait for enough WG data and start of sync interval - mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low - "UNSIGNED", rd_data, ">=", c_nof_block_per_sync*3, -- this is the wait until condition + mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low + "UNSIGNED", rd_data, ">=", c_init_bsn + c_nof_block_per_sync*3, -- this is the wait until condition c_sdp_T_sub, tb_clk); + -- Stimuli done, now verify results at end of test + stimuli_done <= '1'; + --------------------------------------------------------------------------- -- Read subband statistics --------------------------------------------------------------------------- @@ -455,42 +688,6 @@ BEGIN proc_common_wait_some_cycles(tb_clk, 1); - --------------------------------------------------------------------------- - -- Read 10GbE Stream - --------------------------------------------------------------------------- - -- Wait until start of a beamlet packet, capture only first block in packet - proc_common_wait_until_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 - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid); - proc_common_wait_some_cycles(ext_clk, 1); - END LOOP; - - -- First word contains 1.5 dual pol (= XY, X) beamlets + 1 header part - beamlet_arr2_re(0) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- X - beamlet_arr2_im(0) <= tr_10GbE_src_out.data(15 DOWNTO 8); - beamlet_arr2_re(1) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- Y - beamlet_arr2_im(1) <= tr_10GbE_src_out.data(31 DOWNTO 24); - beamlet_arr2_re(2) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- X - beamlet_arr2_im(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); - -- 2 dual pol beamlets (= Y, XY, X) /64b data word - FOR I IN 1 TO (c_sdp_cep_nof_beamlets_per_block/2)-1 LOOP - beamlet_arr2_re(I*4 -1) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- Y - beamlet_arr2_im(I*4 -1) <= tr_10GbE_src_out.data(15 DOWNTO 8); - beamlet_arr2_re(I*4 +0) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- X - beamlet_arr2_im(I*4 +0) <= tr_10GbE_src_out.data(31 DOWNTO 24); - beamlet_arr2_re(I*4 +1) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- Y - beamlet_arr2_im(I*4 +1) <= tr_10GbE_src_out.data(47 DOWNTO 40); - beamlet_arr2_re(I*4 +2) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- X - beamlet_arr2_im(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); - END LOOP; - -- Last word contains last 0.5 (= Y) dual pol beamlet - beamlet_arr2_re(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- Y - beamlet_arr2_im(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1) <= tr_10GbE_src_out.data(63 DOWNTO 56); - --------------------------------------------------------------------------- -- Verify subband statistics --------------------------------------------------------------------------- @@ -535,80 +732,174 @@ BEGIN --------------------------------------------------------------------------- -- Verify 10GbE UDP offload --------------------------------------------------------------------------- - v_re := TO_SINT(beamlet_arr2_re(c_exp_beamlet_index)); v_re_exp := TO_SINT(c_exp_beamlet_re); - v_im := TO_SINT(beamlet_arr2_im(c_exp_beamlet_index)); v_im_exp := TO_SINT(c_exp_beamlet_im); + v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_index)); v_re_exp := TO_SINT(c_exp_beamlet_re); + v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_index)); v_im_exp := TO_SINT(c_exp_beamlet_im); ASSERT v_re = v_re_exp REPORT "Wrong 10GbE output (re) " & INTEGER'IMAGE(v_re) & " != " & INTEGER'IMAGE(v_re_exp) SEVERITY ERROR; ASSERT v_im = v_im_exp REPORT "Wrong 10GbE output (im) " & INTEGER'IMAGE(v_re) & " != " & INTEGER'IMAGE(v_re_exp) SEVERITY ERROR; --------------------------------------------------------------------------- -- End Simulation - --------------------------------------------------------------------------- - sim_done <= '1'; + --------------------------------------------------------------------------- + tb_almost_end <= '1'; proc_common_wait_some_cycles(ext_clk, 100); - proc_common_stop_simulation(TRUE, ext_clk, sim_done, tb_end); + proc_common_stop_simulation(TRUE, ext_clk, tb_almost_end, tb_end); WAIT; END PROCESS; ----------------------------------------------------------------------------- - -- Debugging signals + -- Verify beamlet offload packet header + ----------------------------------------------------------------------------- + + -- Counters to time expected exp_sdp_cep_header fields per offload packet + 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 + END IF; + IF test_offload_sosi.eop = '1' THEN + test_offload_eop_cnt <= test_offload_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 + 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 + + -- 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. + + p_exp_sdp_cep_header : PROCESS(exp_dp_bsn) + BEGIN + -- eth header + exp_sdp_cep_header.eth.dst_mac <= c_cep_eth_dst_mac; + exp_sdp_cep_header.eth.src_mac <= c_cep_eth_src_mac; + exp_sdp_cep_header.eth.eth_type <= x"0800"; + + -- ip header + exp_sdp_cep_header.ip.version <= TO_UVEC( 4, c_network_ip_version_w); + exp_sdp_cep_header.ip.header_length <= TO_UVEC( 5, c_network_ip_header_length_w); + exp_sdp_cep_header.ip.services <= TO_UVEC( 0, c_network_ip_services_w); + exp_sdp_cep_header.ip.total_length <= c_sdp_cep_ip_total_length; -- 7868, see ICD STAT-CEP + exp_sdp_cep_header.ip.identification <= TO_UVEC( 0, c_network_ip_identification_w); + exp_sdp_cep_header.ip.flags <= TO_UVEC( 2, c_network_ip_flags_w); + exp_sdp_cep_header.ip.fragment_offset <= TO_UVEC( 0, c_network_ip_fragment_offset_w); + exp_sdp_cep_header.ip.time_to_live <= TO_UVEC( 127, c_network_ip_time_to_live_w); + exp_sdp_cep_header.ip.protocol <= TO_UVEC( 17, c_network_ip_protocol_w); + exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w); + exp_sdp_cep_header.ip.src_ip_addr <= c_cep_ip_src_addr; -- c_network_ip_addr_w + exp_sdp_cep_header.ip.dst_ip_addr <= c_cep_ip_dst_addr; -- c_network_ip_addr_w + + -- udp header + exp_sdp_cep_header.udp.src_port <= c_cep_udp_src_port; + exp_sdp_cep_header.udp.dst_port <= c_cep_udp_dst_port; + exp_sdp_cep_header.udp.total_length <= c_sdp_cep_udp_total_length; -- 7848, see ICD STAT-CEP + exp_sdp_cep_header.udp.checksum <= TO_UVEC( 0, c_network_udp_checksum_w); + + -- app header + exp_sdp_cep_header.app.sdp_marker <= TO_UVEC(c_sdp_marker_beamlets, 8); -- 98 = x"62" = 'b' + exp_sdp_cep_header.app.sdp_version_id <= TO_UVEC(c_sdp_cep_version_id, 8); -- 5 + exp_sdp_cep_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id; + exp_sdp_cep_header.app.sdp_station_id <= c_exp_sdp_info.station_id; + + exp_sdp_cep_header.app.sdp_source_info_antenna_band_id <= slv(c_exp_sdp_info.antenna_band_index); + exp_sdp_cep_header.app.sdp_source_info_nyquist_zone_id <= c_exp_sdp_info.nyquist_zone_index; + exp_sdp_cep_header.app.sdp_source_info_f_adc <= slv(c_exp_sdp_info.f_adc); + exp_sdp_cep_header.app.sdp_source_info_fsub_type <= slv(c_exp_sdp_info.fsub_type); + exp_sdp_cep_header.app.sdp_source_info_payload_error <= TO_UVEC(0, 1); + exp_sdp_cep_header.app.sdp_source_info_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag); + exp_sdp_cep_header.app.sdp_source_info_beamlet_width <= TO_UVEC(c_sdp_W_beamlet, 4); + exp_sdp_cep_header.app.sdp_source_info_gn_id <= TO_UVEC(c_gn_index, 5); + + exp_sdp_cep_header.app.sdp_reserved <= TO_UVEC( 0, 40); + exp_sdp_cep_header.app.sdp_beamlet_scale <= TO_UVEC( c_exp_beamlet_scale, 16); + exp_sdp_cep_header.app.sdp_beamlet_index <= TO_UVEC( 0, 16); -- depends on bset + exp_sdp_cep_header.app.sdp_nof_blocks_per_packet <= TO_UVEC( c_sdp_cep_nof_blocks_per_packet, 8); + exp_sdp_cep_header.app.sdp_nof_beamlets_per_block <= TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16); + exp_sdp_cep_header.app.sdp_block_period <= c_exp_sdp_info.block_period; + + exp_sdp_cep_header.app.dp_bsn <= TO_UVEC(exp_dp_bsn, 64); -- depends on bset and time + END PROCESS; + + rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw); + + p_verify_cep_header : PROCESS + VARIABLE v_bool : BOOLEAN; + 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 + -- 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; + END IF; + END IF; + + -- Verify header at eop + -- . The expected beamlet_index 0 or S_sub_bf = 488 depends on beamset 0 + -- 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 + v_bool := func_sdp_verify_cep_header(rx_sdp_cep_header, exp_sdp_cep_header); + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- CEP Read Rx 10GbE Stream ----------------------------------------------------------------------------- -- Show received beamlets from 10GbE stream in Wave Window - -- . expect c_nof_block_per_sync / c_sdp_cep_nof_blocks_per_packet * c_sdp_N_beamsets - -- = 16 / 4 * 2 = 4 * 2 = 8 packets per sync interval + -- . The packet header is 9.25 longwords wide. The dp_offload_rx has stripped + -- the header and has realigned the payload at a longword boundary. + -- . expect c_nof_block_per_sync / c_sdp_cep_nof_blocks_per_packet * + -- c_sdp_N_beamsets = 16 / 4 * 2 = 4 * 2 = 8 packets per sync interval -- . 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. - p_dbg_10GbE_beamlets : PROCESS + -- . Beamlets array is stored big endian in the data, so X index 0 first in + -- MSByte of test_offload_sosi.data. + p_rx_cep_beamlets : PROCESS BEGIN - -- Wait until start of (next) beamlet packet - dbg_beamlet_cnt <= 0; - dbg_beamlet_valid <= '0'; - proc_common_wait_until_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 - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.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. + 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); + rx_beamlet_valid <= '1'; + -- Capture rx beamlets per longword in rx_beamlet_arr + 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 + -- 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); + 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); + 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); + 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); + rx_beamlet_list_im(I*4 + 3) <= test_offload_sosi.data(15 DOWNTO 8); + END IF; + proc_common_wait_until_high(ext_clk, test_offload_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 END LOOP; - - -- First word contains 1.5 dual pol (= XY, X) beamlets + 1 header part - dbg_beamlet_arr_re(0) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- X - dbg_beamlet_arr_im(0) <= tr_10GbE_src_out.data(15 DOWNTO 8); - dbg_beamlet_arr_re(1) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- Y - dbg_beamlet_arr_im(1) <= tr_10GbE_src_out.data(31 DOWNTO 24); - dbg_beamlet_arr_re(2) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- X - dbg_beamlet_arr_im(2) <= tr_10GbE_src_out.data(47 DOWNTO 40); - dbg_beamlet_arr_re(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_cnt <= dbg_beamlet_cnt + 3; - dbg_beamlet_valid <= '1'; - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid); - proc_common_wait_some_cycles(ext_clk, 1); - -- 2 dual pol beamlets (= Y, XY, X) /64b data word - FOR I IN 1 TO (c_sdp_cep_nof_beamlets_per_block*c_sdp_cep_nof_blocks_per_packet/2)-1 LOOP - dbg_beamlet_arr_re(0) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- Y - dbg_beamlet_arr_im(0) <= tr_10GbE_src_out.data(15 DOWNTO 8); - dbg_beamlet_arr_re(1) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- X - dbg_beamlet_arr_im(1) <= tr_10GbE_src_out.data(31 DOWNTO 24); - dbg_beamlet_arr_re(2) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- Y - dbg_beamlet_arr_im(2) <= tr_10GbE_src_out.data(47 DOWNTO 40); - dbg_beamlet_arr_re(3) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- X - dbg_beamlet_arr_im(3) <= tr_10GbE_src_out.data(63 DOWNTO 56); - dbg_beamlet_cnt <= (dbg_beamlet_cnt + 4) MOD c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet - dbg_beamlet_valid <= '1'; - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid); - proc_common_wait_some_cycles(ext_clk, 1); - END LOOP; - -- Last word contains last 0.5 (= Y) dual pol beamlet - dbg_beamlet_arr_re(0) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- Y - dbg_beamlet_arr_im(0) <= tr_10GbE_src_out.data(63 DOWNTO 56); - dbg_beamlet_arr_re(1) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(1) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_re(2) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(2) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_re(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_cnt <= dbg_beamlet_cnt + 1; - dbg_beamlet_valid <= '1'; 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); END tb; diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd index be921d69725e723ca1cc8c42cd2cfb3c6f22f0b5..f00a6c10ef0ac8ddfcfff3f27a1ea5975db8445f 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd @@ -20,7 +20,7 @@ ------------------------------------------------------------------------------- -- --- Author: R. van der Walle +-- Author: R. van der Walle, E. Kooistra -- Purpose: Self-checking testbench for simulating lofar2_unb2c_sdp_station_bf using WG data. -- -- Description: @@ -46,7 +46,7 @@ -- > as 7 # default -- > as 12 # for detailed debugging -- > run -a --- Takes about 45 m +-- Takes about 40 m -- ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, unb2c_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, tech_pll_lib, tr_10GbE_lib, lofar2_unb2c_sdp_station_lib; @@ -54,7 +54,9 @@ USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; USE IEEE.MATH_REAL.ALL; USE common_lib.common_pkg.ALL; -USE unb2c_board_lib.unb2c_board_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE common_lib.common_field_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; USE common_lib.tb_common_pkg.ALL; USE common_lib.common_str_pkg.ALL; USE mm_lib.mm_file_pkg.ALL; @@ -62,7 +64,9 @@ USE dp_lib.dp_stream_pkg.ALL; USE mm_lib.mm_file_unb_pkg.ALL; USE diag_lib.diag_pkg.ALL; USE wpfb_lib.wpfb_pkg.ALL; +USE unb2c_board_lib.unb2c_board_pkg.ALL; USE lofar2_sdp_lib.sdp_pkg.ALL; +USE lofar2_sdp_lib.tb_sdp_pkg.ALL; USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY tb_lofar2_unb2c_sdp_station_bf IS @@ -73,10 +77,18 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS CONSTANT c_sim : BOOLEAN := TRUE; CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 CONSTANT c_node_nr : NATURAL := 0; - CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; + CONSTANT c_gn_index : NATURAL := c_unb_nr * 4 + c_node_nr; -- this node GN + CONSTANT c_O_rn : NATURAL := 0; + CONSTANT c_N_rn : NATURAL := 16; + CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0 + + CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_gn_index, 8); CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; CONSTANT c_fw_version : t_unb2c_board_fw_version := (1, 0); + CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr, 8); + CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr+1, 8); -- +1 to avoid IP = *.*.*.0 + CONSTANT c_eth_clk_period : TIME := 8 ns; -- 125 MHz XO on UniBoard CONSTANT c_ext_clk_period : TIME := 5 ns; CONSTANT c_bck_ref_clk_period : TIME := 5 ns; @@ -94,9 +106,37 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS CONSTANT c_lo_factor : REAL := 1.0 - c_percentage; -- lower boundary CONSTANT c_hi_factor : REAL := 1.0 + c_percentage; -- higher boundary + -- header fields + CONSTANT c_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_dst_mac; -- 00074306C700 = DOP36-eth0 + CONSTANT c_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_dst_addr; -- C0A80001 = '192.168.0.1' = DOP36-eth0 + CONSTANT c_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_dst_port; -- 5000 + + CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & c_mac_15_0; -- x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node + CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & c_ip_15_0; -- C0A80001 = '192.168.0.1' = DOP36-eth0 + CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_id; -- D0 & c_id + + CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDE#; -- value obtained from rx_sdp_cep_header.ip.header_checksum in wave window + + CONSTANT c_exp_beamlet_scale : NATURAL := 2**15; + + CONSTANT c_exp_sdp_info : t_sdp_info := ( + TO_UVEC(601, 16), -- station_id + '0', -- antenna_band_index + x"7FFFFFFF", -- observation_id, use > 0 to avoid Warning: (vsim-151) NUMERIC_STD.TO_INTEGER: Value -2 is not in bounds of subtype NATURAL. + b"01", -- nyquist_zone_index, 0 = first, 1 = second, 2 = third + '1', -- f_adc, 0 = 160 MHz, 1 = 200 MHz + '0', -- fsub_type, 0 = critically sampled, 1 = oversampled + '0', -- beam_repositioning_flag + x"01", -- O_si, not used + x"02", -- N_si, not used + TO_UVEC(c_O_rn, 8), -- O_rn + TO_UVEC(c_N_rn, 8), -- N_rn + x"1400" -- block_period = 5120 + ); + -- WG CONSTANT c_full_scale_ampl : REAL := REAL(2**(14-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_bsn_start_wg : NATURAL := c_init_bsn + 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values CONSTANT c_ampl_sp_0 : 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 @@ -114,7 +154,27 @@ 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); TYPE t_slv_64_beamlets_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_S_sub_bf); - -- MM + -- BF + CONSTANT c_exp_beamlet_index : NATURAL := NATURAL(c_subband_sp_0) * c_sdp_N_pol_bf; + CONSTANT c_exp_beamlet_re : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"81"; -- = -127, derived from simulation + CONSTANT c_exp_beamlet_im : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"7F"; -- = +127, derived from simulation + + -- MM + -- . Address widths of a single MM instance + CONSTANT c_addr_w_ram_ss_ss_wide : NATURAL := ceil_log2(c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); + CONSTANT c_addr_w_ram_bf_weights : NATURAL := ceil_log2(c_sdp_N_pol * c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); + CONSTANT c_addr_w_reg_bf_scale : NATURAL := 1; + CONSTANT c_addr_w_reg_hdr_dat : NATURAL := ceil_log2(field_nof_words(c_sdp_cep_hdr_field_arr, c_word_w)); + CONSTANT c_addr_w_reg_dp_xonoff : NATURAL := 1; + CONSTANT c_addr_w_ram_st_bst : NATURAL := ceil_log2(c_sdp_S_sub_bf*c_sdp_N_pol*(c_longword_sz/c_word_sz)); + -- . Address spans of a single MM instance + CONSTANT c_mm_span_ram_ss_ss_wide : NATURAL := 2**c_addr_w_ram_ss_ss_wide; + CONSTANT c_mm_span_ram_bf_weights : NATURAL := 2**c_addr_w_ram_bf_weights; + CONSTANT c_mm_span_reg_bf_scale : NATURAL := 2**c_addr_w_reg_bf_scale; + CONSTANT c_mm_span_reg_hdr_dat : NATURAL := 2**c_addr_w_reg_hdr_dat; + CONSTANT c_mm_span_reg_dp_xonoff : NATURAL := 2**c_addr_w_reg_dp_xonoff; + CONSTANT c_mm_span_ram_st_bst : NATURAL := 2**c_addr_w_ram_st_bst; + 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"; @@ -122,13 +182,32 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS CONSTANT c_mm_file_ram_st_bst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_BST"; 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_ram_st_sst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST"; + CONSTANT c_mm_file_reg_sdp_info : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_SDP_INFO"; + CONSTANT c_mm_file_reg_bf_scale : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BF_SCALE"; + CONSTANT c_mm_file_reg_hdr_dat : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_HDR_DAT"; -- c_sdp_N_beamsets = 2 beamsets -- Tb + SIGNAL stimuli_done : STD_LOGIC := '0'; + SIGNAL tb_almost_end : STD_LOGIC := '0'; SIGNAL tb_end : STD_LOGIC := '0'; - SIGNAL sim_done : STD_LOGIC := '0'; - SIGNAL tb_clk : STD_LOGIC := '0'; + SIGNAL tb_clk : STD_LOGIC := '0'; SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); + SIGNAL dest_rst : STD_LOGIC := '1'; -- use separate destination rst for Rx 10GbE in tb + SIGNAL pps_rst : STD_LOGIC := '1'; -- use separate reset to release the PPS generator + SIGNAL gen_pps : STD_LOGIC := '0'; + + SIGNAL in_sync : STD_LOGIC := '0'; + SIGNAL in_sync_cnt : NATURAL := 0; + SIGNAL test_sync_cnt : INTEGER := 0; + + -- MM + SIGNAL rd_sdp_info : t_sdp_info := c_sdp_info_rst; + SIGNAL rd_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0); + SIGNAL rd_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL rd_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL rd_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0); + -- WG SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); @@ -144,28 +223,39 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS SIGNAL sp_beamlet_power_leakage_sum_0 : REAL; -- 10GbE - CONSTANT c_exp_beamlet_index : NATURAL := NATURAL(c_subband_sp_0) * c_sdp_N_pol_bf; - CONSTANT c_exp_beamlet_re : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"81"; -- = -127, derived from simulation - CONSTANT c_exp_beamlet_im : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"7F"; -- = +127, derived from simulation - - SIGNAL dbg_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0] - SIGNAL dbg_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet-1 DOWNTO 0); -- [3:0] - SIGNAL dbg_beamlet_cnt : NATURAL; - SIGNAL dbg_beamlet_valid : STD_LOGIC; + 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 beamlet_arr2_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 beamlet_arr2_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] + 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] 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; + + SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0); + SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0'); + SIGNAL rx_sdp_cep_header : t_sdp_cep_header; + SIGNAL exp_sdp_cep_header : t_sdp_cep_header; + SIGNAL exp_dp_bsn : NATURAL; + -- DUT SIGNAL ext_clk : STD_LOGIC := '0'; - SIGNAL pps : STD_LOGIC := '0'; SIGNAL ext_pps : STD_LOGIC := '0'; - SIGNAL pps_rst : STD_LOGIC := '1'; SIGNAL WDI : STD_LOGIC; SIGNAL INTA : STD_LOGIC; @@ -195,7 +285,7 @@ BEGIN eth_clk(0) <= NOT eth_clk(0) AFTER c_eth_clk_period/2; -- Ethernet ref clock (125 MHz) JESD204B_REFCLK <= NOT JESD204B_REFCLK AFTER c_bck_ref_clk_period/2; -- JESD sample clock (200MHz) SA_CLK <= NOT SA_CLK AFTER c_sa_clk_period/2; -- Serial Gigabit IO sa clock (644 MHz) - pps_rst <= '0' AFTER c_ext_clk_period*2; + dest_rst <= '0' AFTER c_ext_clk_period * 10; INTA <= 'H'; -- pull up INTB <= 'H'; -- pull up @@ -203,9 +293,9 @@ BEGIN ------------------------------------------------------------------------------ -- External PPS ------------------------------------------------------------------------------ - proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, pps); - jesd204b_sysref <= pps; - ext_pps <= pps; + proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, gen_pps); + jesd204b_sysref <= gen_pps; + ext_pps <= gen_pps; ------------------------------------------------------------------------------ -- DUT @@ -224,7 +314,7 @@ BEGIN PORT MAP ( -- GENERAL CLK => ext_clk, - PPS => pps, + PPS => ext_pps, WDI => WDI, INTA => INTA, INTB => INTB, @@ -257,44 +347,72 @@ BEGIN JESD204B_SYNC_N => jesd204b_sync_n ); - u_unb2_board_clk644_pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks - PORT MAP ( - refclk_644 => SA_CLK, - rst_in => pps_rst, - clk_156 => tr_ref_clk_156, - clk_312 => tr_ref_clk_312, - rst_156 => tr_ref_rst_156, - rst_312 => OPEN - ); - - u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE - GENERIC MAP ( - g_sim => TRUE, - g_sim_level => 1, - g_nof_macs => 1, - g_use_mdio => FALSE - ) - PORT MAP ( - -- Transceiver PLL reference clock - tr_ref_clk_644 => SA_CLK, - tr_ref_clk_312 => tr_ref_clk_312, -- 312.5 MHz for 10GBASE-R - tr_ref_clk_156 => tr_ref_clk_156, -- 156.25 MHz for 10GBASE-R or for XAUI - tr_ref_rst_156 => tr_ref_rst_156, -- for 10GBASE-R or for XAUI - - -- MM interface - mm_rst => pps_rst, - mm_clk => tb_clk, - - -- DP interface - dp_rst => pps_rst, - dp_clk => ext_clk, - - serial_rx_arr(0) => si_lpbk_0(0), - - src_out_arr(0) => tr_10GbE_src_out - - ); + u_unb2_board_clk644_pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks + PORT MAP ( + refclk_644 => SA_CLK, + rst_in => dest_rst, + clk_156 => tr_ref_clk_156, + clk_312 => tr_ref_clk_312, + rst_156 => tr_ref_rst_156, + rst_312 => OPEN + ); + + u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE + GENERIC MAP ( + g_sim => TRUE, + g_sim_level => 1, + g_nof_macs => 1, + g_use_mdio => FALSE + ) + PORT MAP ( + -- Transceiver PLL reference clock + tr_ref_clk_644 => SA_CLK, + tr_ref_clk_312 => tr_ref_clk_312, -- 312.5 MHz for 10GBASE-R + tr_ref_clk_156 => tr_ref_clk_156, -- 156.25 MHz for 10GBASE-R or for XAUI + tr_ref_rst_156 => tr_ref_rst_156, -- for 10GBASE-R or for XAUI + + -- MM interface + mm_rst => dest_rst, + mm_clk => tb_clk, + + -- DP interface + dp_rst => dest_rst, + dp_clk => ext_clk, + + serial_rx_arr(0) => si_lpbk_0(0), + + src_out_arr(0) => tr_10GbE_src_out, + src_in_arr(0) => tr_10GbE_src_in + ); + + + u_rx : ENTITY dp_lib.dp_offload_rx + GENERIC MAP ( + g_nof_streams => 1, + g_data_w => c_longword_w, + g_symbol_w => c_octet_w, + g_hdr_field_arr => c_sdp_cep_hdr_field_arr, + g_remove_crc => FALSE, + g_crc_nof_words => 0 + ) + PORT MAP ( + mm_rst => dest_rst, + mm_clk => tb_clk, + 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, + + snk_in_arr(0) => tr_10GbE_src_out, + snk_out_arr(0) => tr_10GbE_src_in, + + src_out_arr(0) => test_offload_sosi, + + hdr_fields_out_arr(0) => rx_hdr_fields_out, + hdr_fields_raw_arr(0) => rx_hdr_fields_raw + ); ------------------------------------------------------------------------------ -- MM slave accesses via file IO @@ -308,23 +426,134 @@ BEGIN VARIABLE v_W, v_T, v_U, v_S, v_B : NATURAL; -- array indicies VARIABLE v_re, v_im : INTEGER; VARIABLE v_re_exp, v_im_exp : INTEGER; + VARIABLE v_offset : NATURAL; BEGIN -- Wait for DUT power up after reset WAIT FOR 1 us; ---------------------------------------------------------------------------- - -- Enable UDP offload (dp_xonoff) of beamset 0 + -- Set and check SDP info ---------------------------------------------------------------------------- - 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); + -- TYPE t_sdp_info IS RECORD + -- 11 station_id : STD_LOGIC_VECTOR(15 DOWNTO 0); + -- 10 antenna_band_index : STD_LOGIC; + -- 9 observation_id : STD_LOGIC_VECTOR(31 DOWNTO 0); + -- 8 nyquist_zone_index : STD_LOGIC_VECTOR(1 DOWNTO 0); + -- 7 f_adc : STD_LOGIC; + -- 6 fsub_type : STD_LOGIC; + -- 5 beam_repositioning_flag : STD_LOGIC; + -- 4 O_si : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 3 N_si : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 2 O_rn : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 1 N_rn : STD_LOGIC_VECTOR(7 DOWNTO 0); + -- 0 block_period : STD_LOGIC_VECTOR(15 DOWNTO 0); + -- END RECORD; + -- . Write + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 11, TO_UINT(c_exp_sdp_info.station_id), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 9, TO_UINT(c_exp_sdp_info.observation_id), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 8, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 5, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 4, TO_UINT(c_exp_sdp_info.O_si), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 3, TO_UINT(c_exp_sdp_info.N_si), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 2, TO_UINT(c_exp_sdp_info.O_rn), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 1, TO_UINT(c_exp_sdp_info.N_rn), tb_clk); + -- . Read + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 10, rd_data, tb_clk); rd_sdp_info.antenna_band_index <= rd_data(0); + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 7, rd_data, tb_clk); rd_sdp_info.f_adc <= rd_data(0); + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 6, rd_data, tb_clk); rd_sdp_info.fsub_type <= rd_data(0); + mmf_mm_bus_rd(c_mm_file_reg_sdp_info, 0, rd_data, tb_clk); rd_sdp_info.block_period <= rd_data(15 DOWNTO 0); + proc_common_wait_some_cycles(tb_clk, 1); + -- . Verify read + ASSERT c_exp_sdp_info.antenna_band_index = rd_sdp_info.antenna_band_index REPORT "Wrong MM read SDP info antenna_band_index" SEVERITY ERROR; + ASSERT c_exp_sdp_info.f_adc = rd_sdp_info.f_adc REPORT "Wrong MM read SDP info f_adc" SEVERITY ERROR; + ASSERT c_exp_sdp_info.fsub_type = rd_sdp_info.fsub_type REPORT "Wrong MM read SDP info fsub_type" SEVERITY ERROR; + ASSERT c_exp_sdp_info.block_period = rd_sdp_info.block_period REPORT "Wrong MM read SDP info block_period" SEVERITY ERROR; + + ------------------------------------------------------------------------------ + ---- Set and check BF per beamset + ------------------------------------------------------------------------------ + FOR bset IN 0 TO c_sdp_N_beamsets-1 LOOP + -- MM beamlet_scale + v_offset := bset * c_mm_span_reg_bf_scale; + 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; + + -- CEP beamlet output header + -- c_sdp_cep_hdr_field_arr : t_common_field_arr(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := ( + -- 40 "eth_dst_mac" ), "RW", 48, field_default(c_sdp_cep_eth_dst_mac) ), + -- 38 "eth_src_mac" ), "RW", 48, field_default(0) ), + -- 37 "eth_type" ), "RW", 16, field_default(x"0800") ), + -- + -- 36 "ip_version" ), "RW", 4, field_default(4) ), + -- 35 "ip_header_length" ), "RW", 4, field_default(5) ), + -- 34 "ip_services" ), "RW", 8, field_default(0) ), + -- 33 "ip_total_length" ), "RW", 16, field_default(c_sdp_cep_ip_total_length) ), + -- 32 "ip_identification" ), "RW", 16, field_default(0) ), + -- 31 "ip_flags" ), "RW", 3, field_default(2) ), + -- 30 "ip_fragment_offset" ), "RW", 13, field_default(0) ), + -- 29 "ip_time_to_live" ), "RW", 8, field_default(127) ), + -- 28 "ip_protocol" ), "RW", 8, field_default(17) ), + -- 27 "ip_header_checksum" ), "RW", 16, field_default(0) ), + -- 26 "ip_src_addr" ), "RW", 32, field_default(0) ), + -- 25 "ip_dst_addr" ), "RW", 32, field_default(c_sdp_cep_ip_dst_addr) ), + -- + -- 24 "udp_src_port" ), "RW", 16, field_default(0) ), + -- 23 "udp_dst_port" ), "RW", 16, field_default(c_sdp_cep_udp_dst_port) ), + -- 22 "udp_total_length" ), "RW", 16, field_default(c_sdp_cep_udp_total_length) ), + -- 21 "udp_checksum" ), "RW", 16, field_default(0) ), + -- + -- 20 "sdp_marker" ), "RW", 8, field_default(c_sdp_marker_beamlets) ), + -- 19 "sdp_version_id" ), "RW", 8, field_default(c_sdp_cep_version_id) ), + -- 18 "sdp_observation_id" ), "RW", 32, field_default(0) ), + -- 17 "sdp_station_id" ), "RW", 16, field_default(0) ), + -- + -- 16 "sdp_source_info_antenna_band_id" ), "RW", 1, field_default(0) ), + -- 15 "sdp_source_info_nyquist_zone_id" ), "RW", 2, field_default(0) ), + -- 14 "sdp_source_info_f_adc" ), "RW", 1, field_default(0) ), + -- 13 "sdp_source_info_fsub_type" ), "RW", 1, field_default(0) ), + -- 12 "sdp_source_info_payload_error" ), "RW", 1, field_default(0) ), + -- 11 "sdp_source_info_repositioning_flag" ), "RW", 1, field_default(0) ), + -- 10 "sdp_source_info_beamlet_width" ), "RW", 4, field_default(c_sdp_W_beamlet) ), + -- 9 "sdp_source_info_gn_id" ), "RW", 5, field_default(0) ), + -- + -- 7 "sdp_reserved" ), "RW", 40, field_default(0) ), + -- 6 "sdp_beamlet_scale" ), "RW", 16, field_default(c_sdp_beamlet_scale_default) ), + -- 5 "sdp_beamlet_index" ), "RW", 16, field_default(0) ), + -- 4 "sdp_nof_blocks_per_packet" ), "RW", 8, field_default(c_sdp_cep_nof_blocks_per_packet) ), + -- 3 "sdp_nof_beamlets_per_block" ), "RW", 16, field_default(c_sdp_cep_nof_beamlets_per_block) ), + -- 2 "sdp_block_period" ), "RW", 16, field_default(c_sdp_block_period) ), + -- + -- 0 "dp_bsn" ), "RW", 64, field_default(0) ) + -- ); + + v_offset := bset * c_mm_span_reg_hdr_dat; + -- . Use defaults, so no need to write + -- . Read + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); + proc_common_wait_some_cycles(tb_clk, 1); + -- verify read + ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 00074306C700 = DOP36-eth0 + ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- C0A80001 = '192.168.0.1' = DOP36-eth0 + ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 5000 + + ---------------------------------------------------------------------------- + -- Enable beamlet UDP offload (dp_xonoff) + ---------------------------------------------------------------------------- + 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); + END LOOP; ---------------------------------------------------------------------------- -- Enable BS ---------------------------------------------------------------------------- - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, 0, tb_clk); -- Init BSN = 0 + mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, c_init_bsn, tb_clk); -- Init BSN + mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); -- Write high part activates the init BSN mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_sync - mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000003#, tb_clk); -- Enable BS at PPS + mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000003#, tb_clk); -- Enable BS at PPS -- Release PPS pulser, to get first PPS now and to start BSN source WAIT FOR 1 us; @@ -356,10 +585,13 @@ BEGIN mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1, 0, tb_clk); -- assume v_bsn < 2**31-1 -- Wait for enough WG data and start of sync interval - mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low - "UNSIGNED", rd_data, ">=", c_nof_block_per_sync*3, -- this is the wait until condition + mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0, -- read BSN low + "UNSIGNED", rd_data, ">=", c_init_bsn + c_nof_block_per_sync*3, -- this is the wait until condition c_sdp_T_sub, tb_clk); + -- Stimuli done, now verify results at end of test + stimuli_done <= '1'; + --------------------------------------------------------------------------- -- Read subband statistics --------------------------------------------------------------------------- @@ -438,42 +670,6 @@ BEGIN proc_common_wait_some_cycles(tb_clk, 1); - --------------------------------------------------------------------------- - -- Read 10GbE Stream - --------------------------------------------------------------------------- - -- Wait until start of a beamlet packet, capture only first block in packet - proc_common_wait_until_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 - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid); - proc_common_wait_some_cycles(ext_clk, 1); - END LOOP; - - -- First word contains 1.5 dual pol (= XY, X) beamlets + 1 header part - beamlet_arr2_re(0) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- X - beamlet_arr2_im(0) <= tr_10GbE_src_out.data(15 DOWNTO 8); - beamlet_arr2_re(1) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- Y - beamlet_arr2_im(1) <= tr_10GbE_src_out.data(31 DOWNTO 24); - beamlet_arr2_re(2) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- X - beamlet_arr2_im(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); - -- 2 dual pol beamlets (= Y, XY, X) /64b data word - FOR I IN 1 TO (c_sdp_cep_nof_beamlets_per_block/2)-1 LOOP - beamlet_arr2_re(I*4 -1) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- Y - beamlet_arr2_im(I*4 -1) <= tr_10GbE_src_out.data(15 DOWNTO 8); - beamlet_arr2_re(I*4 +0) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- X - beamlet_arr2_im(I*4 +0) <= tr_10GbE_src_out.data(31 DOWNTO 24); - beamlet_arr2_re(I*4 +1) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- Y - beamlet_arr2_im(I*4 +1) <= tr_10GbE_src_out.data(47 DOWNTO 40); - beamlet_arr2_re(I*4 +2) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- X - beamlet_arr2_im(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); - END LOOP; - -- Last word contains last 0.5 (= Y) dual pol beamlet - beamlet_arr2_re(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- Y - beamlet_arr2_im(c_sdp_cep_nof_beamlets_per_block * c_sdp_N_pol_bf-1) <= tr_10GbE_src_out.data(63 DOWNTO 56); - --------------------------------------------------------------------------- -- Verify subband statistics --------------------------------------------------------------------------- @@ -518,80 +714,174 @@ BEGIN --------------------------------------------------------------------------- -- Verify 10GbE UDP offload --------------------------------------------------------------------------- - v_re := TO_SINT(beamlet_arr2_re(c_exp_beamlet_index)); v_re_exp := TO_SINT(c_exp_beamlet_re); - v_im := TO_SINT(beamlet_arr2_im(c_exp_beamlet_index)); v_im_exp := TO_SINT(c_exp_beamlet_im); + v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_index)); v_re_exp := TO_SINT(c_exp_beamlet_re); + v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_index)); v_im_exp := TO_SINT(c_exp_beamlet_im); ASSERT v_re = v_re_exp REPORT "Wrong 10GbE output (re) " & INTEGER'IMAGE(v_re) & " != " & INTEGER'IMAGE(v_re_exp) SEVERITY ERROR; ASSERT v_im = v_im_exp REPORT "Wrong 10GbE output (im) " & INTEGER'IMAGE(v_re) & " != " & INTEGER'IMAGE(v_re_exp) SEVERITY ERROR; --------------------------------------------------------------------------- -- End Simulation --------------------------------------------------------------------------- - sim_done <= '1'; + tb_almost_end <= '1'; proc_common_wait_some_cycles(ext_clk, 100); - proc_common_stop_simulation(TRUE, ext_clk, sim_done, tb_end); + proc_common_stop_simulation(TRUE, ext_clk, tb_almost_end, tb_end); WAIT; END PROCESS; ----------------------------------------------------------------------------- - -- Debugging signals + -- Verify beamlet offload packet header + ----------------------------------------------------------------------------- + + -- Counters to time expected exp_sdp_cep_header fields per offload packet + 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 + END IF; + IF test_offload_sosi.eop = '1' THEN + test_offload_eop_cnt <= test_offload_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 + 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 + + -- 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. + + p_exp_sdp_cep_header : PROCESS(exp_dp_bsn) + BEGIN + -- eth header + exp_sdp_cep_header.eth.dst_mac <= c_cep_eth_dst_mac; + exp_sdp_cep_header.eth.src_mac <= c_cep_eth_src_mac; + exp_sdp_cep_header.eth.eth_type <= x"0800"; + + -- ip header + exp_sdp_cep_header.ip.version <= TO_UVEC( 4, c_network_ip_version_w); + exp_sdp_cep_header.ip.header_length <= TO_UVEC( 5, c_network_ip_header_length_w); + exp_sdp_cep_header.ip.services <= TO_UVEC( 0, c_network_ip_services_w); + exp_sdp_cep_header.ip.total_length <= c_sdp_cep_ip_total_length; -- 7868, see ICD STAT-CEP + exp_sdp_cep_header.ip.identification <= TO_UVEC( 0, c_network_ip_identification_w); + exp_sdp_cep_header.ip.flags <= TO_UVEC( 2, c_network_ip_flags_w); + exp_sdp_cep_header.ip.fragment_offset <= TO_UVEC( 0, c_network_ip_fragment_offset_w); + exp_sdp_cep_header.ip.time_to_live <= TO_UVEC( 127, c_network_ip_time_to_live_w); + exp_sdp_cep_header.ip.protocol <= TO_UVEC( 17, c_network_ip_protocol_w); + exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w); + exp_sdp_cep_header.ip.src_ip_addr <= c_cep_ip_src_addr; -- c_network_ip_addr_w + exp_sdp_cep_header.ip.dst_ip_addr <= c_cep_ip_dst_addr; -- c_network_ip_addr_w + + -- udp header + exp_sdp_cep_header.udp.src_port <= c_cep_udp_src_port; + exp_sdp_cep_header.udp.dst_port <= c_cep_udp_dst_port; + exp_sdp_cep_header.udp.total_length <= c_sdp_cep_udp_total_length; -- 7848, see ICD STAT-CEP + exp_sdp_cep_header.udp.checksum <= TO_UVEC( 0, c_network_udp_checksum_w); + + -- app header + exp_sdp_cep_header.app.sdp_marker <= TO_UVEC(c_sdp_marker_beamlets, 8); -- 98 = x"62" = 'b' + exp_sdp_cep_header.app.sdp_version_id <= TO_UVEC(c_sdp_cep_version_id, 8); -- 5 + exp_sdp_cep_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id; + exp_sdp_cep_header.app.sdp_station_id <= c_exp_sdp_info.station_id; + + exp_sdp_cep_header.app.sdp_source_info_antenna_band_id <= slv(c_exp_sdp_info.antenna_band_index); + exp_sdp_cep_header.app.sdp_source_info_nyquist_zone_id <= c_exp_sdp_info.nyquist_zone_index; + exp_sdp_cep_header.app.sdp_source_info_f_adc <= slv(c_exp_sdp_info.f_adc); + exp_sdp_cep_header.app.sdp_source_info_fsub_type <= slv(c_exp_sdp_info.fsub_type); + exp_sdp_cep_header.app.sdp_source_info_payload_error <= TO_UVEC(0, 1); + exp_sdp_cep_header.app.sdp_source_info_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag); + exp_sdp_cep_header.app.sdp_source_info_beamlet_width <= TO_UVEC(c_sdp_W_beamlet, 4); + exp_sdp_cep_header.app.sdp_source_info_gn_id <= TO_UVEC(c_gn_index, 5); + + exp_sdp_cep_header.app.sdp_reserved <= TO_UVEC( 0, 40); + exp_sdp_cep_header.app.sdp_beamlet_scale <= TO_UVEC( c_exp_beamlet_scale, 16); + exp_sdp_cep_header.app.sdp_beamlet_index <= TO_UVEC( 0, 16); -- depends on bset + exp_sdp_cep_header.app.sdp_nof_blocks_per_packet <= TO_UVEC( c_sdp_cep_nof_blocks_per_packet, 8); + exp_sdp_cep_header.app.sdp_nof_beamlets_per_block <= TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16); + exp_sdp_cep_header.app.sdp_block_period <= c_exp_sdp_info.block_period; + + exp_sdp_cep_header.app.dp_bsn <= TO_UVEC(exp_dp_bsn, 64); -- depends on bset and time + END PROCESS; + + rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw); + + p_verify_cep_header : PROCESS + VARIABLE v_bool : BOOLEAN; + 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 + -- 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; + END IF; + END IF; + + -- Verify header at eop + -- . The expected beamlet_index 0 or S_sub_bf = 488 depends on beamset 0 + -- 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 + v_bool := func_sdp_verify_cep_header(rx_sdp_cep_header, exp_sdp_cep_header); + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- CEP Read Rx 10GbE Stream ----------------------------------------------------------------------------- -- Show received beamlets from 10GbE stream in Wave Window - -- . expect c_nof_block_per_sync / c_sdp_cep_nof_blocks_per_packet * c_sdp_N_beamsets - -- = 16 / 4 * 2 = 4 * 2 = 8 packets per sync interval + -- . The packet header is 9.25 longwords wide. The dp_offload_rx has stripped + -- the header and has realigned the payload at a longword boundary. + -- . expect c_nof_block_per_sync / c_sdp_cep_nof_blocks_per_packet * + -- c_sdp_N_beamsets = 16 / 4 * 2 = 4 * 2 = 8 packets per sync interval -- . 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. - p_dbg_10GbE_beamlets : PROCESS + -- . Beamlets array is stored big endian in the data, so X index 0 first in + -- MSByte of test_offload_sosi.data. + p_rx_cep_beamlets : PROCESS BEGIN - -- Wait until start of (next) beamlet packet - dbg_beamlet_cnt <= 0; - dbg_beamlet_valid <= '0'; - proc_common_wait_until_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 - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.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. + 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); + rx_beamlet_valid <= '1'; + -- Capture rx beamlets per longword in rx_beamlet_arr + 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 + -- 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); + 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); + 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); + 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); + rx_beamlet_list_im(I*4 + 3) <= test_offload_sosi.data(15 DOWNTO 8); + END IF; + proc_common_wait_until_high(ext_clk, test_offload_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 END LOOP; - - -- First word contains 1.5 dual pol (= XY, X) beamlets + 1 header part - dbg_beamlet_arr_re(0) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- X - dbg_beamlet_arr_im(0) <= tr_10GbE_src_out.data(15 DOWNTO 8); - dbg_beamlet_arr_re(1) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- Y - dbg_beamlet_arr_im(1) <= tr_10GbE_src_out.data(31 DOWNTO 24); - dbg_beamlet_arr_re(2) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- X - dbg_beamlet_arr_im(2) <= tr_10GbE_src_out.data(47 DOWNTO 40); - dbg_beamlet_arr_re(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_cnt <= dbg_beamlet_cnt + 3; - dbg_beamlet_valid <= '1'; - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid); - proc_common_wait_some_cycles(ext_clk, 1); - -- 2 dual pol beamlets (= Y, XY, X) /64b data word - FOR I IN 1 TO (c_sdp_cep_nof_beamlets_per_block*c_sdp_cep_nof_blocks_per_packet/2)-1 LOOP - dbg_beamlet_arr_re(0) <= tr_10GbE_src_out.data(7 DOWNTO 0); -- Y - dbg_beamlet_arr_im(0) <= tr_10GbE_src_out.data(15 DOWNTO 8); - dbg_beamlet_arr_re(1) <= tr_10GbE_src_out.data(23 DOWNTO 16); -- X - dbg_beamlet_arr_im(1) <= tr_10GbE_src_out.data(31 DOWNTO 24); - dbg_beamlet_arr_re(2) <= tr_10GbE_src_out.data(39 DOWNTO 32); -- Y - dbg_beamlet_arr_im(2) <= tr_10GbE_src_out.data(47 DOWNTO 40); - dbg_beamlet_arr_re(3) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- X - dbg_beamlet_arr_im(3) <= tr_10GbE_src_out.data(63 DOWNTO 56); - dbg_beamlet_cnt <= (dbg_beamlet_cnt + 4) MOD c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet - dbg_beamlet_valid <= '1'; - proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid); - proc_common_wait_some_cycles(ext_clk, 1); - END LOOP; - -- Last word contains last 0.5 (= Y) dual pol beamlet - dbg_beamlet_arr_re(0) <= tr_10GbE_src_out.data(55 DOWNTO 48); -- Y - dbg_beamlet_arr_im(0) <= tr_10GbE_src_out.data(63 DOWNTO 56); - dbg_beamlet_arr_re(1) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(1) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_re(2) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(2) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_re(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_arr_im(3) <= (OTHERS => '1'); -- mark unused octet by 0xFF = -1 - dbg_beamlet_cnt <= dbg_beamlet_cnt + 1; - dbg_beamlet_valid <= '1'; 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); END tb; diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd index 9d6215cc77615e82e00c636b1ca09be158d39060..c82f450ad9525890f4a7ba21931f133b48df1123 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd @@ -77,12 +77,14 @@ ENTITY node_sdp_beamformer IS sdp_info : IN t_sdp_info; gn_id : IN STD_LOGIC_VECTOR(c_sdp_W_gn_id-1 DOWNTO 0); - eth_src_mac : IN STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0); - ip_src_addr : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0); - udp_src_port : IN STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0); + -- beamlet data output + bdo_eth_src_mac : IN STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0); + bdo_ip_src_addr : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0); + bdo_udp_src_port : IN STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0); - hdr_fields_out : OUT STD_LOGIC_VECTOR(1023 DOWNTO 0); -- Needed by nw_10GbE for PING/ARP + bdo_hdr_fields_out : OUT STD_LOGIC_VECTOR(1023 DOWNTO 0); -- Needed by nw_10GbE for PING/ARP + -- beamlet statistics offload stat_eth_src_mac : IN STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0); stat_ip_src_addr : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0); stat_udp_src_port : IN STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0) @@ -220,11 +222,11 @@ BEGIN sdp_info => sdp_info, gn_id => gn_id, - eth_src_mac => eth_src_mac, - ip_src_addr => ip_src_addr, - udp_src_port => udp_src_port, + eth_src_mac => bdo_eth_src_mac, + ip_src_addr => bdo_ip_src_addr, + udp_src_port => bdo_udp_src_port, - hdr_fields_out => hdr_fields_out, + hdr_fields_out => bdo_hdr_fields_out, reg_hdr_dat_mosi => reg_hdr_dat_mosi, reg_hdr_dat_miso => reg_hdr_dat_miso, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd index de8c07ed0fbdd9d3704df5e35c01be6d0c81c17b..2a7d53aedc234b28cc2e2a929add7cd0bfbf6a5c 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd @@ -76,7 +76,7 @@ END sdp_beamformer_output; ARCHITECTURE str OF sdp_beamformer_output IS CONSTANT c_data_w : NATURAL := c_nof_complex*c_sdp_W_beamlet; --16b - CONSTANT c_beamlet_id : NATURAL := g_beamset_id * c_sdp_S_sub_bf; + CONSTANT c_beamlet_index : NATURAL := g_beamset_id * c_sdp_S_sub_bf; -- call beamset 'id' and beamlet 'index' -- c_fifo_fill must be the exact size of a packet such that no packet gets stuck in the FIFO or the FIFO gets read out too soon. -- For packets of variable length, dp_fifo_fill_eop must be used. In this case we can use the standard fill fifo. @@ -217,7 +217,7 @@ BEGIN dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id" )) <= gn_id; dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_reserved" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_reserved" )) <= (OTHERS => '0'); dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale" )) <= beamlet_scale; - dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_id" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_id" )) <= TO_UVEC(c_beamlet_id, c_halfword_w); + dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" )) <= TO_UVEC(c_beamlet_index, c_halfword_w); dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_block_period" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_block_period" )) <= sdp_info.block_period; dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "dp_bsn" )) <= dp_fifo_sc_src_out.bsn(63 DOWNTO 0); diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index 71b4c59b9d0b89a495a77dc51fc895376485f140..22487eba06f823026aba9d2da9807accd3124a39 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -347,7 +347,7 @@ PACKAGE sdp_pkg is ( field_name_pad("sdp_reserved" ), "RW", 40, field_default(0) ), ( field_name_pad("sdp_beamlet_scale" ), "RW", 16, field_default(c_sdp_beamlet_scale_default) ), - ( field_name_pad("sdp_beamlet_id" ), "RW", 16, field_default(0) ), + ( field_name_pad("sdp_beamlet_index" ), "RW", 16, field_default(0) ), ( field_name_pad("sdp_nof_blocks_per_packet" ), "RW", 8, field_default(c_sdp_cep_nof_blocks_per_packet) ), ( field_name_pad("sdp_nof_beamlets_per_block" ), "RW", 16, field_default(c_sdp_cep_nof_beamlets_per_block) ), ( field_name_pad("sdp_block_period" ), "RW", 16, field_default(c_sdp_block_period) ), @@ -373,7 +373,7 @@ PACKAGE sdp_pkg is sdp_reserved : STD_LOGIC_VECTOR(39 DOWNTO 0); sdp_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0); - sdp_beamlet_id : STD_LOGIC_VECTOR(15 DOWNTO 0); + sdp_beamlet_index : STD_LOGIC_VECTOR(15 DOWNTO 0); sdp_nof_blocks_per_packet : STD_LOGIC_VECTOR( 7 DOWNTO 0); sdp_nof_beamlets_per_block : STD_LOGIC_VECTOR(15 DOWNTO 0); sdp_block_period : STD_LOGIC_VECTOR(15 DOWNTO 0); @@ -778,7 +778,7 @@ PACKAGE BODY sdp_pkg IS v.app.sdp_reserved := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_reserved") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_reserved")); v.app.sdp_beamlet_scale := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale")); - v.app.sdp_beamlet_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_id")); + v.app.sdp_beamlet_index := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index")); v.app.sdp_nof_blocks_per_packet := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet")); v.app.sdp_nof_beamlets_per_block := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block")); v.app.sdp_block_period := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_block_period") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_block_period")); diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd index e9d91c101111914ea9298a7e0c22f619e077dcb4..71f21d3af762da9c2cb40f337554d1f3000899e5 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd @@ -842,14 +842,15 @@ BEGIN sdp_info => sdp_info, gn_id => gn_id, - eth_src_mac => cep_eth_src_mac, - ip_src_addr => cep_ip_src_addr, - udp_src_port => cep_udp_src_port, - stat_eth_src_mac => stat_eth_src_mac, + + bdo_eth_src_mac => cep_eth_src_mac, + bdo_ip_src_addr => cep_ip_src_addr, + bdo_udp_src_port => cep_udp_src_port, + bdo_hdr_fields_out => bf_10GbE_hdr_fields_out_arr(beamset_id), + + stat_eth_src_mac => stat_eth_src_mac, stat_ip_src_addr => stat_ip_src_addr, - stat_udp_src_port => bst_udp_src_port, - - hdr_fields_out => bf_10GbE_hdr_fields_out_arr(beamset_id) + stat_udp_src_port => bst_udp_src_port ); END GENERATE; diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd index cfdb39d35709b4e99f9ea643efc8c136819a15c9..d905af1d81408584d7240267628053baee46f4a5 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd @@ -34,19 +34,19 @@ PACKAGE tb_sdp_pkg is ----------------------------------------------------------------------------- -- Statistics offload ----------------------------------------------------------------------------- - FUNCTION func_sdp_verify_stat_header(g_statistics_type : STRING; in_hdr, exp_hdr : t_sdp_stat_header; sdp_info : t_sdp_info) RETURN BOOLEAN; + FUNCTION func_sdp_verify_stat_header(g_statistics_type : STRING; in_hdr, exp_hdr : t_sdp_stat_header) RETURN BOOLEAN; ----------------------------------------------------------------------------- -- Beamlet output via 10GbE to CEP (= central processor) ----------------------------------------------------------------------------- - FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header; sdp_info : t_sdp_info) RETURN BOOLEAN; + FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header) RETURN BOOLEAN; END PACKAGE tb_sdp_pkg; PACKAGE BODY tb_sdp_pkg IS - FUNCTION func_sdp_verify_stat_header(g_statistics_type : STRING; in_hdr, exp_hdr : t_sdp_stat_header; sdp_info : t_sdp_info) RETURN BOOLEAN IS + FUNCTION func_sdp_verify_stat_header(g_statistics_type : STRING; in_hdr, exp_hdr : t_sdp_stat_header) RETURN BOOLEAN IS BEGIN -- eth header ASSERT in_hdr.eth.dst_mac = exp_hdr.eth.dst_mac REPORT "Wrong " & g_statistics_type & " eth.dst_mac" SEVERITY ERROR; @@ -74,20 +74,20 @@ PACKAGE BODY tb_sdp_pkg IS ASSERT in_hdr.udp.checksum = exp_hdr.udp.checksum REPORT "Wrong " & g_statistics_type & " udp.checksum" SEVERITY ERROR; -- app header - ASSERT in_hdr.app.sdp_marker = exp_hdr.app.sdp_marker REPORT "Wrong " & g_statistics_type & " app.sdp_marker" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_version_id = exp_hdr.app.sdp_version_id REPORT "Wrong " & g_statistics_type & " app.sdp_version_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_observation_id = sdp_info.observation_id REPORT "Wrong " & g_statistics_type & " app.sdp_observation_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_station_id = sdp_info.station_id REPORT "Wrong " & g_statistics_type & " app.sdp_station_id" SEVERITY ERROR; - - ASSERT in_hdr.app.sdp_source_info_antenna_band_id = slv(sdp_info.antenna_band_index) REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_antenna_band_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_nyquist_zone_id = sdp_info.nyquist_zone_index REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_nyquist_zone_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_f_adc = slv(sdp_info.f_adc) REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_f_adc" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_fsub_type = slv(sdp_info.fsub_type) REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_fsub_type" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_payload_error = exp_hdr.app.sdp_source_info_payload_error REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_payload_error" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_beam_repositioning_flag = slv(sdp_info.beam_repositioning_flag) REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_beam_repositioning_flag" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_subband_calibrated_flag = exp_hdr.app.sdp_source_info_subband_calibrated_flag REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_subband_calibrated_flag" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_reserved = exp_hdr.app.sdp_source_info_reserved REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_reserved" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_gn_id = exp_hdr.app.sdp_source_info_gn_id REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_gn_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_marker = exp_hdr.app.sdp_marker REPORT "Wrong " & g_statistics_type & " app.sdp_marker" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_version_id = exp_hdr.app.sdp_version_id REPORT "Wrong " & g_statistics_type & " app.sdp_version_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_observation_id = exp_hdr.app.sdp_observation_id REPORT "Wrong " & g_statistics_type & " app.sdp_observation_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_station_id = exp_hdr.app.sdp_station_id REPORT "Wrong " & g_statistics_type & " app.sdp_station_id" SEVERITY ERROR; + + ASSERT in_hdr.app.sdp_source_info_antenna_band_id = exp_hdr.app.sdp_source_info_antenna_band_id REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_antenna_band_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_nyquist_zone_id = exp_hdr.app.sdp_source_info_nyquist_zone_id REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_nyquist_zone_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_f_adc = exp_hdr.app.sdp_source_info_f_adc REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_f_adc" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_fsub_type = exp_hdr.app.sdp_source_info_fsub_type REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_fsub_type" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_payload_error = exp_hdr.app.sdp_source_info_payload_error REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_payload_error" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_beam_repositioning_flag = exp_hdr.app.sdp_source_info_beam_repositioning_flag REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_beam_repositioning_flag" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_subband_calibrated_flag = exp_hdr.app.sdp_source_info_subband_calibrated_flag REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_subband_calibrated_flag" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_reserved = exp_hdr.app.sdp_source_info_reserved REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_reserved" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_gn_id = exp_hdr.app.sdp_source_info_gn_id REPORT "Wrong " & g_statistics_type & " app.sdp_source_info_gn_id" SEVERITY ERROR; ASSERT in_hdr.app.sdp_reserved = exp_hdr.app.sdp_reserved REPORT "Wrong " & g_statistics_type & " app.sdp_reserved" SEVERITY ERROR; ASSERT in_hdr.app.sdp_integration_interval = exp_hdr.app.sdp_integration_interval REPORT "Wrong " & g_statistics_type & " app.sdp_integration_interval" SEVERITY ERROR; @@ -109,14 +109,15 @@ PACKAGE BODY tb_sdp_pkg IS ASSERT in_hdr.app.sdp_nof_signal_inputs = exp_hdr.app.sdp_nof_signal_inputs REPORT "Wrong " & g_statistics_type & " app.sdp_nof_signal_inputs" SEVERITY ERROR; ASSERT in_hdr.app.sdp_nof_bytes_per_statistic = exp_hdr.app.sdp_nof_bytes_per_statistic REPORT "Wrong " & g_statistics_type & " app.sdp_nof_bytes_per_statistic" SEVERITY ERROR; ASSERT in_hdr.app.sdp_nof_statistics_per_packet = exp_hdr.app.sdp_nof_statistics_per_packet REPORT "Wrong " & g_statistics_type & " app.sdp_nof_statistics_per_packet" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_block_period = sdp_info.block_period REPORT "Wrong " & g_statistics_type & " app.sdp_block_period" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_block_period = exp_hdr.app.sdp_block_period REPORT "Wrong " & g_statistics_type & " app.sdp_block_period" SEVERITY ERROR; ASSERT in_hdr.app.dp_bsn = exp_hdr.app.dp_bsn REPORT "Wrong " & g_statistics_type & " app.dp_bsn" SEVERITY ERROR; RETURN TRUE; END func_sdp_verify_stat_header; - FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header; sdp_info : t_sdp_info) RETURN BOOLEAN IS + FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header) RETURN BOOLEAN IS + VARIABLE v_beamlet_index : NATURAL; BEGIN -- eth header ASSERT in_hdr.eth.dst_mac = exp_hdr.eth.dst_mac REPORT "Wrong beamlet eth.dst_mac" SEVERITY ERROR; @@ -144,26 +145,28 @@ PACKAGE BODY tb_sdp_pkg IS ASSERT in_hdr.udp.checksum = exp_hdr.udp.checksum REPORT "Wrong beamlet udp.checksum" SEVERITY ERROR; -- app header - ASSERT in_hdr.app.sdp_marker = exp_hdr.app.sdp_marker REPORT "Wrong beamlet app.sdp_marker" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_version_id = exp_hdr.app.sdp_version_id REPORT "Wrong beamlet app.sdp_version_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_observation_id = sdp_info.observation_id REPORT "Wrong beamlet app.sdp_observation_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_station_id = sdp_info.station_id REPORT "Wrong beamlet app.sdp_station_id" SEVERITY ERROR; - - ASSERT in_hdr.app.sdp_source_info_antenna_band_id = slv(sdp_info.antenna_band_index) REPORT "Wrong beamlet app.sdp_source_info_antenna_band_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_nyquist_zone_id = sdp_info.nyquist_zone_index REPORT "Wrong beamlet app.sdp_source_info_nyquist_zone_id" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_f_adc = slv(sdp_info.f_adc) REPORT "Wrong beamlet app.sdp_source_info_f_adc" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_fsub_type = slv(sdp_info.fsub_type) REPORT "Wrong beamlet app.sdp_source_info_fsub_type" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_payload_error = exp_hdr.app.sdp_source_info_payload_error REPORT "Wrong beamlet app.sdp_source_info_payload_error" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_repositioning_flag = slv(sdp_info.beam_repositioning_flag) REPORT "Wrong beamlet app.sdp_source_info_repositioning_flag" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_beamlet_width = exp_hdr.app.sdp_source_info_beamlet_width REPORT "Wrong beamlet app.sdp_source_info_beamlet_width" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_source_info_gn_id = exp_hdr.app.sdp_source_info_gn_id REPORT "Wrong beamlet app.sdp_source_info_gn_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_marker = exp_hdr.app.sdp_marker REPORT "Wrong beamlet app.sdp_marker" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_version_id = exp_hdr.app.sdp_version_id REPORT "Wrong beamlet app.sdp_version_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_observation_id = exp_hdr.app.sdp_observation_id REPORT "Wrong beamlet app.sdp_observation_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_station_id = exp_hdr.app.sdp_station_id REPORT "Wrong beamlet app.sdp_station_id" SEVERITY ERROR; + + ASSERT in_hdr.app.sdp_source_info_antenna_band_id = exp_hdr.app.sdp_source_info_antenna_band_id REPORT "Wrong beamlet app.sdp_source_info_antenna_band_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_nyquist_zone_id = exp_hdr.app.sdp_source_info_nyquist_zone_id REPORT "Wrong beamlet app.sdp_source_info_nyquist_zone_id" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_f_adc = exp_hdr.app.sdp_source_info_f_adc REPORT "Wrong beamlet app.sdp_source_info_f_adc" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_fsub_type = exp_hdr.app.sdp_source_info_fsub_type REPORT "Wrong beamlet app.sdp_source_info_fsub_type" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_payload_error = exp_hdr.app.sdp_source_info_payload_error REPORT "Wrong beamlet app.sdp_source_info_payload_error" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_repositioning_flag = exp_hdr.app.sdp_source_info_repositioning_flag REPORT "Wrong beamlet app.sdp_source_info_repositioning_flag" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_beamlet_width = exp_hdr.app.sdp_source_info_beamlet_width REPORT "Wrong beamlet app.sdp_source_info_beamlet_width" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_source_info_gn_id = exp_hdr.app.sdp_source_info_gn_id REPORT "Wrong beamlet app.sdp_source_info_gn_id" SEVERITY ERROR; ASSERT in_hdr.app.sdp_reserved = exp_hdr.app.sdp_reserved REPORT "Wrong beamlet app.sdp_reserved" SEVERITY ERROR; ASSERT in_hdr.app.sdp_beamlet_scale = exp_hdr.app.sdp_beamlet_scale REPORT "Wrong beamlet app.sdp_beamlet_scale" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_beamlet_id = exp_hdr.app.sdp_beamlet_id REPORT "Wrong beamlet app.sdp_beamlet_id" SEVERITY ERROR; + -- Treat beamlet_index modulo c_sdp_S_sub_bf, because the beamlet packets from different beamsets may arrive in arbitrary order + v_beamlet_index := TO_UINT(in_hdr.app.sdp_beamlet_index) MOD c_sdp_S_sub_bf; + ASSERT v_beamlet_index = TO_UINT(exp_hdr.app.sdp_beamlet_index) REPORT "Wrong beamlet app.sdp_beamlet_index" SEVERITY ERROR; ASSERT in_hdr.app.sdp_nof_blocks_per_packet = exp_hdr.app.sdp_nof_blocks_per_packet REPORT "Wrong beamlet app.sdp_nof_blocks_per_packet" SEVERITY ERROR; ASSERT in_hdr.app.sdp_nof_beamlets_per_block = exp_hdr.app.sdp_nof_beamlets_per_block REPORT "Wrong beamlet app.sdp_nof_beamlets_per_block" SEVERITY ERROR; - ASSERT in_hdr.app.sdp_block_period = sdp_info.block_period REPORT "Wrong beamlet app.sdp_block_period" SEVERITY ERROR; + ASSERT in_hdr.app.sdp_block_period = exp_hdr.app.sdp_block_period REPORT "Wrong beamlet app.sdp_block_period" SEVERITY ERROR; ASSERT in_hdr.app.dp_bsn = exp_hdr.app.dp_bsn REPORT "Wrong beamlet app.dp_bsn" SEVERITY ERROR; RETURN TRUE; diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd index d6bc51aad26a62d52ef006b75f6a569653b16743..24e9ea2bd2849c2ac9bce59626b9caa68c9a95eb 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd @@ -94,6 +94,20 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_nof_signal_inputs : NATURAL := func_sdp_get_stat_nof_signal_inputs(g_statistics_type); CONSTANT c_nof_packets_max : NATURAL := func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, c_sdp_N_crosslets_max); + CONSTANT c_exp_sdp_info : t_sdp_info := (TO_UVEC(601, 16), -- station_id + '0', -- antenna_band_index + x"FFFFFFFF", -- observation_id + b"01", -- nyquist_zone_index, 0 = first, 1 = second, 2 = third + '1', -- f_adc, 0 = 160 MHz, 1 = 200 MHz + '0', -- fsub_type, 0 = critically sampled, 1 = oversampled + '0', -- beam_repositioning_flag + x"01", -- O_si, not used + x"02", -- N_si, not used + TO_UVEC(g_O_rn, 8), -- O_rn + TO_UVEC(g_N_rn, 8), -- N_rn + x"1400" -- block_period = 5120 + ); + CONSTANT c_beamlet_index : NATURAL := g_beamset_id * c_sdp_S_sub_bf; CONSTANT c_crosslets_info_rec : t_sdp_crosslets_info := (offset_arr => (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), step => 16); @@ -183,26 +197,10 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL rx_data : NATURAL; SIGNAL exp_data : NATURAL; - -- Signals used to change settings of sdp_info. - SIGNAL sdp_info : t_sdp_info := ( - TO_UVEC(601, 16), -- station_id - '0', -- antenna_band_index - x"FFFFFFFF", -- observation_id - b"01", -- nyquist_zone_index, 0 = first, 1 = second, 2 = third - '1', -- f_adc, 0 = 160 MHz, 1 = 200 MHz - '0', -- fsub_type, 0 = critically sampled, 1 = oversampled - '0', -- beam_repositioning_flag - x"01", -- O_si, not used - x"02", -- N_si, not used - TO_UVEC(g_O_rn, 8), -- O_rn - TO_UVEC(g_N_rn, 8), -- N_rn - x"1400" -- block_period = 5120 - ); - - SIGNAL gn_index : NATURAL := g_gn_index; -- this node GN - SIGNAL rn_index : NATURAL := g_gn_index - g_O_rn; -- this node RN - SIGNAL source_rn : NATURAL; -- source node RN - SIGNAL source_gn : NATURAL; -- source node GN + SIGNAL gn_index : NATURAL := g_gn_index; -- this node GN + SIGNAL rn_index : NATURAL := g_gn_index - g_O_rn; -- this node RN + SIGNAL source_rn : NATURAL; -- source node RN + SIGNAL source_gn : NATURAL; -- source node GN SIGNAL subband_calibrated_flag : STD_LOGIC := '0'; @@ -364,7 +362,7 @@ BEGIN -- . prepare expected XST signal_input_B index, assume crosslet transport in positive direction exp_xst_signal_input_B <= (source_gn MOD c_sdp_N_pn_max) * c_sdp_S_pn; - p_exp_sdp_stat_header : PROCESS(sdp_info, subband_calibrated_flag, gn_index, exp_dp_bsn, exp_sst_signal_input, exp_subband_index, exp_xst_signal_input_A, exp_xst_signal_input_B) + p_exp_sdp_stat_header : PROCESS(subband_calibrated_flag, gn_index, exp_dp_bsn, exp_sst_signal_input, exp_subband_index, exp_xst_signal_input_A, exp_xst_signal_input_B) BEGIN -- eth header exp_sdp_stat_header.eth.dst_mac <= c_sdp_stat_eth_dst_mac; @@ -394,15 +392,15 @@ BEGIN -- app header exp_sdp_stat_header.app.sdp_marker <= TO_UVEC(c_marker, 8); exp_sdp_stat_header.app.sdp_version_id <= TO_UVEC(c_sdp_stat_version_id, 8); - exp_sdp_stat_header.app.sdp_observation_id <= sdp_info.observation_id; - exp_sdp_stat_header.app.sdp_station_id <= sdp_info.station_id; + exp_sdp_stat_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id; + exp_sdp_stat_header.app.sdp_station_id <= c_exp_sdp_info.station_id; - exp_sdp_stat_header.app.sdp_source_info_antenna_band_id <= slv(sdp_info.antenna_band_index); - exp_sdp_stat_header.app.sdp_source_info_nyquist_zone_id <= sdp_info.nyquist_zone_index; - exp_sdp_stat_header.app.sdp_source_info_f_adc <= slv(sdp_info.f_adc); - exp_sdp_stat_header.app.sdp_source_info_fsub_type <= slv(sdp_info.fsub_type); + exp_sdp_stat_header.app.sdp_source_info_antenna_band_id <= slv(c_exp_sdp_info.antenna_band_index); + exp_sdp_stat_header.app.sdp_source_info_nyquist_zone_id <= c_exp_sdp_info.nyquist_zone_index; + exp_sdp_stat_header.app.sdp_source_info_f_adc <= slv(c_exp_sdp_info.f_adc); + exp_sdp_stat_header.app.sdp_source_info_fsub_type <= slv(c_exp_sdp_info.fsub_type); exp_sdp_stat_header.app.sdp_source_info_payload_error <= TO_UVEC(0, 1); - exp_sdp_stat_header.app.sdp_source_info_beam_repositioning_flag <= slv(sdp_info.beam_repositioning_flag); + exp_sdp_stat_header.app.sdp_source_info_beam_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag); exp_sdp_stat_header.app.sdp_source_info_subband_calibrated_flag <= slv(subband_calibrated_flag); exp_sdp_stat_header.app.sdp_source_info_reserved <= TO_UVEC(0, 3); exp_sdp_stat_header.app.sdp_source_info_gn_id <= TO_UVEC(gn_index, 5); @@ -424,7 +422,7 @@ BEGIN exp_sdp_stat_header.app.sdp_nof_signal_inputs <= TO_UVEC( c_nof_signal_inputs, 8); exp_sdp_stat_header.app.sdp_nof_bytes_per_statistic <= TO_UVEC(c_sdp_nof_bytes_per_statistic, 8); exp_sdp_stat_header.app.sdp_nof_statistics_per_packet <= TO_UVEC( c_nof_statistics_per_packet, 16); - exp_sdp_stat_header.app.sdp_block_period <= sdp_info.block_period; + exp_sdp_stat_header.app.sdp_block_period <= c_exp_sdp_info.block_period; exp_sdp_stat_header.app.dp_bsn <= exp_dp_bsn; END PROCESS; @@ -436,7 +434,7 @@ BEGIN BEGIN -- Prepare exp_sdp_stat_header before test_offload_sosi.eop, so that it can be verified at test_offload_sosi.eop IF test_offload_sosi.eop = '1' THEN - v_bool := func_sdp_verify_stat_header(g_statistics_type, rx_sdp_stat_header, exp_sdp_stat_header, sdp_info); + v_bool := func_sdp_verify_stat_header(g_statistics_type, rx_sdp_stat_header, exp_sdp_stat_header); END IF; END PROCESS; @@ -705,7 +703,7 @@ BEGIN gn_index => gn_index, - sdp_info => sdp_info, + sdp_info => c_exp_sdp_info, subband_calibrated_flag => subband_calibrated_flag, nof_crosslets => c_mm_nof_crosslets, crosslets_info => in_crosslets_info_slv diff --git a/libraries/base/dp/src/vhdl/dp_offload_rx.vhd b/libraries/base/dp/src/vhdl/dp_offload_rx.vhd index d2eef67a136e6909bbd10ec6bd3f44ef19de2ac1..ff1a52c71575982bedcdecf3eaa95edac477d7e2 100644 --- a/libraries/base/dp/src/vhdl/dp_offload_rx.vhd +++ b/libraries/base/dp/src/vhdl/dp_offload_rx.vhd @@ -130,8 +130,11 @@ BEGIN src_out_arr => dp_split_src_out_2arr(i) ); - dp_split_src_in_2arr(i)(1) <= c_dp_siso_rdy; - + -- In dp_split index 0 is head and index 1 is tail, but dp_split uses 0 TO + -- 1 range and dp_split_src_in_2arr()() uses 1 DOWNTO 0 range, so: + -- . dp_split_src_in_2arr()(1) is the header part, and + -- . dp_split_src_in_2arr()(0) is the tail part. + dp_split_src_in_2arr(i)(1) <= c_dp_siso_rdy; -- flow control for rx header to MM is always ready END GENERATE; --------------------------------------------------------------------------------------- @@ -186,7 +189,7 @@ BEGIN st_clk => dp_clk, snk_out => dp_split_src_in_2arr(i)(0), - snk_in => dp_split_src_out_2arr(i)(0), + snk_in => dp_split_src_out_2arr(i)(0), -- tail part src_in => dp_tail_remove_src_in_arr(i), src_out => dp_tail_remove_src_out_arr(i) diff --git a/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd b/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd index 70d6538309705161c9cd4870c762f448b08d57a2..d9655314345a6c555289ed4311f9e17f4fd52b52 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd @@ -74,7 +74,8 @@ ENTITY tb_dp_offload_tx_v3 IS g_print_en : BOOLEAN := TRUE; -- specific g_data_w : NATURAL := 64; - g_symbol_w : NATURAL := 32; + g_symbol_w : NATURAL := 8; + g_empty : NATURAL := 6; -- number of empty symbols in header when g_symbol_w < g_data_w, must be < c_nof_symbols_per_data g_pkt_len : NATURAL := 240; g_pkt_gap : NATURAL := 16 ); @@ -95,7 +96,7 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS CONSTANT c_nof_symbols_per_bsn : NATURAL := c_dp_stream_bsn_w / g_symbol_w; -- = 64 / g_symbol_w CONSTANT c_bsn_w : NATURAL := sel_a_b(c_nof_symbols_per_data = 1, g_symbol_w * c_nof_symbols_per_bsn, - g_symbol_w * (c_nof_symbols_per_bsn - 1)); + g_symbol_w * (c_nof_symbols_per_bsn - g_empty)); CONSTANT c_use_shortened_header : BOOLEAN := c_bsn_w <= c_word_w; -- dp_stream_stimuli @@ -116,6 +117,7 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS CONSTANT c_expected_pkt_len : NATURAL := g_pkt_len; CONSTANT c_sync_period : NATURAL := 5; CONSTANT c_sync_offset : NATURAL := 2; + CONSTANT c_data_init : NATURAL := 17; CONSTANT c_bsn_init : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := TO_DP_BSN(0); CONSTANT c_nof_sync : NATURAL := 3; CONSTANT c_nof_packets : NATURAL := c_sync_period * c_nof_sync; @@ -190,7 +192,7 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS X"0000001B"); -- 25 = eth_dst_mac[47:32] CONSTANT c_expected_tx_hdr_word_arr_shortened : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words_shortened-1) := ( -- word address - X"00000000", -- 0 = dp_bsn[31:0] -- readback is MM value, not the logic value + X"00000000", -- 0 = dp_bsn[c_bsn_w-1:0] -- readback is MM value, not the logic value X"00000000", -- 1 = dp_sync X"03040506", -- 2 = dp_reserved[31:0] X"00000102", -- 3 = dp_reserved[47:32] @@ -246,7 +248,7 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS X"0000001B"); -- 25 = eth_dst_mac[47:32] CONSTANT c_expected_rx_hdr_word_arr_shortened : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words_shortened-1) := ( -- word address - X"00000002", -- 0 = dp_bsn[31:0] -- dynamic value obtained from simulation + X"00000002", -- 0 = dp_bsn[c_bsn_w-1:0] -- dynamic value obtained from simulation X"00000001", -- 1 = dp_sync -- dynamic value obtained from simulation X"03040506", -- 2 = dp_reserved[31:0] X"00000102", -- 3 = dp_reserved[47:32] @@ -366,6 +368,7 @@ BEGIN -- initializations g_sync_period => c_sync_period, g_sync_offset => c_sync_offset, + g_data_init => c_data_init, g_bsn_init => c_bsn_init, -- specific g_in_dat_w => g_data_w, @@ -563,7 +566,16 @@ BEGIN link_offload_sosi_arr(0).sop <= tx_offload_sosi_arr(0).sop; link_offload_sosi_arr(0).eop <= tx_offload_sosi_arr(0).eop; - tx_offload_siso_arr <= (OTHERS=>c_dp_siso_rdy); + -- The dp_offload_tx_v3 cannot accept flow control via its src_in_arr + -- however the dp_offload_rx only lowers ready at eop, to request a + -- one cycle gap between rx packets. The dp_offload_tx_v3 output via + -- src_out_arr has a gap, when g_flow_control_stimuli is e_pulse or when + -- g_pkt_gap > 0. The dp_offload_tx_v3 output has gaps, even when the + -- input stimuli have no gaps. Hence the flow control from dp_offload_rx + -- at the eop has no impact. However the tb will still eventually fail + -- the stimuli is always active, because then the u_dp_fifo_sc will run + -- full. + tx_offload_siso_arr <= link_offload_siso_arr; --(OTHERS=>c_dp_siso_rdy); END PROCESS; ------------------------------------------------------------------------------ @@ -664,16 +676,18 @@ BEGIN END PROCESS; p_verify_snk_in_data : PROCESS + VARIABLE v_data : INTEGER; BEGIN -- Note: This verification overlaps with u_dp_stream_verify because that also verifies incrementing valid data. WAIT UNTIL rising_edge(dp_clk); prev_verify_snk_in_data <= verify_snk_in.data(g_data_w-1 DOWNTO 0); + v_data := TO_UINT(verify_snk_in.data) - c_data_init; IF verify_snk_in.sop = '1' THEN - ASSERT TO_UINT(verify_snk_in.data) MOD g_pkt_len = 0 REPORT "Wrong decoded data at sop." SEVERITY ERROR; + ASSERT v_data MOD g_pkt_len = 0 REPORT "Wrong decoded data at sop." SEVERITY ERROR; ELSIF verify_snk_in.eop = '1' THEN - ASSERT TO_UINT(verify_snk_in.data) MOD g_pkt_len = g_pkt_len - 1 REPORT "Wrong decoded data at eop." SEVERITY ERROR; + ASSERT v_data MOD g_pkt_len = g_pkt_len - 1 REPORT "Wrong decoded data at eop." SEVERITY ERROR; ELSIF verify_snk_in.valid = '1' THEN - ASSERT TO_UINT(verify_snk_in.data) = TO_UINT(prev_verify_snk_in_data) + 1 REPORT "Wrong decoded data at valid." SEVERITY ERROR; + ASSERT v_data = TO_UINT(prev_verify_snk_in_data) - c_data_init + 1 REPORT "Wrong decoded data at valid." SEVERITY ERROR; END IF; END PROCESS; diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_offload_tx_v3.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_offload_tx_v3.vhd index f55d74d6584f394a5bbe5326a81c6eafd0abb84e..39cc44db3e71495b5b6c4c6389ba3ee0af678046 100644 --- a/libraries/base/dp/tb/vhdl/tb_tb_dp_offload_tx_v3.vhd +++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_offload_tx_v3.vhd @@ -44,17 +44,21 @@ BEGIN -- -- specific -- g_data_w : NATURAL := 64; -- g_symbol_w : NATURAL := 16; + -- g_empty : NATURAL := 6; -- number of empty symbols in header when g_symbol_w < g_data_w, must be < c_nof_symbols_per_data -- g_pkt_len : NATURAL := 240; -- g_pkt_gap : NATURAL := 16 - u_pls_act_data_w_64 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_pulse, e_active, FALSE, 64, 64, 240, 16); - u_pls_act_data_w_64_no_gap : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_pulse, e_active, FALSE, 64, 64, 240, 0); - u_rnd_act_data_w_64 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 64, 240, 16); - u_rnd_act_data_w_32 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 32, 32, 240, 16); - --u_act_rnd_data_w : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_active, e_random, FALSE, 64, 64, 240, 16); - u_rnd_act_data_64_symbol_16 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 16, 240, 16); - u_rnd_act_data_64_symbol_32 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 32, 240, 16); - u_rnd_act_data_32_symbol_8 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 32, 8, 240, 16); - u_rnd_act_data_32_symbol_16 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 32, 16, 240, 16); + u_pls_act_data_w_64 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_pulse, e_active, FALSE, 64, 64, 0, 240, 16); + u_act_act_data_w_64_no_gap : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_active, e_active, FALSE, 64, 64, 0, 240, 0); -- u_dp_fifo_sc does run almost full + u_pls_act_data_w_64_no_gap : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_pulse, e_active, FALSE, 64, 64, 0, 240, 0); + u_rnd_act_data_w_64 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 64, 0, 240, 16); + u_rnd_act_data_w_32 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 32, 32, 0, 240, 16); + --u_act_rnd_data_w : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_active, e_random, FALSE, 64, 64, 0, 240, 16); -- dp_offload_rx requires e_active + u_rnd_act_data_64_symbol_8_empty_1 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 8, 1, 240, 16); + u_rnd_act_data_64_symbol_8_empty_6 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 8, 6, 240, 16); + u_rnd_act_data_64_symbol_16 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 16, 1, 240, 16); + u_rnd_act_data_64_symbol_32 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 64, 32, 1, 240, 16); + u_rnd_act_data_32_symbol_8 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 32, 8, 1, 240, 16); + u_rnd_act_data_32_symbol_16 : ENTITY work.tb_dp_offload_tx_v3 GENERIC MAP (e_random, e_active, FALSE, 32, 16, 1, 240, 16); END tb;