From bc824119f14c255aef97b335c3b57b82547b0c87 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Wed, 26 Jan 2022 17:23:31 +0100 Subject: [PATCH] Added header verification. --- .../tb_lofar2_unb2b_sdp_station_bf.vhd | 611 ++++++++++++----- .../tb_lofar2_unb2c_sdp_station_bf.vhd | 614 +++++++++++++----- 2 files changed, 903 insertions(+), 322 deletions(-) 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 24bb76e951..959d8eabf8 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 be921d6972..f00a6c10ef 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; -- GitLab