From 7d6ce481d9157dd3605842bfa3a2bafe9c857d75 Mon Sep 17 00:00:00 2001 From: Eric Kooistra <kooistra@astron.nl> Date: Tue, 26 Sep 2023 14:58:55 +0200 Subject: [PATCH] Use procedure proc_sdp_cep_rx_beamlets(). --- .../tb_lofar2_unb2b_sdp_station_bf.vhd | 202 +++++++----------- .../tb_lofar2_unb2c_sdp_station_bf.vhd | 45 +--- 2 files changed, 84 insertions(+), 163 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 b941058df2..7954aaa40d 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 @@ -293,14 +293,6 @@ architecture tb of tb_lofar2_unb2b_sdp_station_bf is signal pol_beamlet_bst_Y_arr : t_real_arr(0 to c_sdp_N_beamsets - 1) := (others => 0.0); -- [bset] -- 10GbE - signal rx_beamlet_arr_re : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet - 1 downto 0); -- [3:0] - signal rx_beamlet_arr_im : t_slv_8_arr(c_sdp_cep_nof_blocks_per_packet - 1 downto 0); -- [3:0] - signal rx_beamlet_cnt : natural; - signal rx_beamlet_valid : std_logic; - - 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'; @@ -311,17 +303,27 @@ architecture tb of tb_lofar2_unb2b_sdp_station_bf is 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; + signal exp_payload_error : std_logic := '0'; + + signal rx_beamlet_en : std_logic := '0'; + signal rx_beamlet_data : std_logic_vector(c_longword_w - 1 downto 0); -- 64 bit + signal rx_beamlet_sosi : t_dp_sosi := c_dp_sosi_rst; + signal rx_beamlet_sop_cnt : natural := 0; + signal rx_beamlet_eop_cnt : natural := 0; + + -- [0 : 3] = X, Y, X, Y + signal rx_beamlet_arr_re : t_sdp_beamlet_part_arr; + signal rx_beamlet_arr_im : t_sdp_beamlet_part_arr; + signal rx_beamlet_cnt : natural; + signal rx_beamlet_valid : std_logic; + -- [0 : 4 * 488 * 2 - 1] = [0 : 3903] + signal rx_packet_list_re : t_sdp_beamlet_packet_list; + signal rx_packet_list_im : t_sdp_beamlet_packet_list; -- DUT signal ext_clk : std_logic := '0'; @@ -493,7 +495,7 @@ begin snk_in_arr(0) => tr_10GbE_src_out, snk_out_arr(0) => tr_10GbE_src_in, - src_out_arr(0) => test_offload_sosi, + src_out_arr(0) => rx_beamlet_sosi, hdr_fields_out_arr(0) => rx_hdr_fields_out, hdr_fields_raw_arr(0) => rx_hdr_fields_raw @@ -998,8 +1000,8 @@ begin --------------------------------------------------------------------------- -- Verify beamlet output in 10GbE UDP offload --------------------------------------------------------------------------- - v_re := TO_SINT(rx_beamlet_list_re(c_exp_beamlet_index)); v_re_exp := c_exp_beamlet_output_re; - v_im := TO_SINT(rx_beamlet_list_im(c_exp_beamlet_index)); v_im_exp := c_exp_beamlet_output_im; + v_re := TO_SINT(rx_packet_list_re(c_exp_beamlet_index)); v_re_exp := c_exp_beamlet_output_re; + v_im := TO_SINT(rx_packet_list_im(c_exp_beamlet_index)); v_im_exp := c_exp_beamlet_output_im; assert v_re > integer(v_re_exp) - c_beamlet_output_delta report "Wrong 10GbE output (re) " & integer'image(v_re) & " != " & real'image(v_re_exp) severity ERROR; assert v_re < integer(v_re_exp) + c_beamlet_output_delta report "Wrong 10GbE output (re) " & integer'image(v_re) & " != " & real'image(v_re_exp) severity ERROR; assert v_im > integer(v_im_exp) - c_beamlet_output_delta report "Wrong 10GbE output (im) " & integer'image(v_im) & " != " & real'image(v_im_exp) severity ERROR; @@ -1022,87 +1024,66 @@ begin p_test_counters : process(ext_clk) begin if rising_edge(ext_clk) then - -- Count test_offload_sosi packets - if test_offload_sosi.sop = '1' then - test_offload_sop_cnt <= test_offload_sop_cnt + 1; -- early count + -- Count rx_beamlet_sosi packets + if rx_beamlet_sosi.sop = '1' then + rx_beamlet_sop_cnt <= rx_beamlet_sop_cnt + 1; -- early count end if; - if test_offload_sosi.eop = '1' then - test_offload_eop_cnt <= test_offload_eop_cnt + 1; -- after count + if rx_beamlet_sosi.eop = '1' then + rx_beamlet_eop_cnt <= rx_beamlet_eop_cnt + 1; -- after count end if; end if; end process; - -- Count sync intervals using in_sosi.sync, because there is no test_offload_sosi.sync + -- Count sync intervals using in_sosi.sync, because there is no rx_beamlet_sosi.sync in_sync_cnt <= in_sync_cnt + 1 when rising_edge(ext_clk) and in_sync = '1'; - test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit test_offload_sosi - - -- 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_sdp_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_sdp_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_sdp_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_info <= c_exp_sdp_info.antenna_field_index & 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_beam_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; + test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit rx_beamlet_sosi + + -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that + -- p_exp_sdp_cep_header can verify it at rx_beamlet_sosi.eop. + exp_sdp_cep_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum, + c_exp_sdp_info, + c_gn_index, + exp_payload_error, + c_exp_beamlet_scale, + c_exp_beamlet_index, + exp_dp_bsn); rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw); p_verify_cep_header : process - variable v_bool : boolean; + variable v_pkt_cnt : natural; + variable v_new_pkt : boolean; + variable v_error : std_logic := '0'; + variable v_bsn : natural := 0; + variable v_bool : boolean; begin wait until rising_edge(ext_clk); + -- Count packets per beamset + v_pkt_cnt := rx_beamlet_sop_cnt / c_sdp_N_beamsets; + v_new_pkt := rx_beamlet_sop_cnt mod c_sdp_N_beamsets = 0; -- 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; + if rx_beamlet_sosi.sop = '1' then + -- Expected BSN increments by c_sdp_cep_nof_blocks_per_packet = 4 blocks per packet, + -- both beamsets are outputting packets. + if v_new_pkt then + -- Default expected + v_error := '0'; + v_bsn := c_init_bsn + v_pkt_cnt * c_sdp_cep_nof_blocks_per_packet; + + -- Expected due to bsn and payload_error stimuli in sdp_beamformer_output.vhd. + if v_pkt_cnt = 1 then + v_error := '1'; + elsif v_pkt_cnt = 2 or v_pkt_cnt = 3 then + v_bsn := v_bsn + 1; + elsif v_pkt_cnt = 4 then + v_bsn := v_bsn + 1; + v_error := '1'; + end if; + + -- Apply expected values + exp_payload_error <= v_error; + exp_dp_bsn <= v_bsn; end if; end if; @@ -1111,7 +1092,7 @@ begin -- or 1, but the order in which the packets arrive is undetermined. -- Therefore accept any beamlet_index MOD c_sdp_S_sub_bf = 0 as correct -- in func_sdp_verify_cep_header(). - if test_offload_sosi.eop = '1' then + if rx_beamlet_sosi.eop = '1' then v_bool := func_sdp_verify_cep_header(rx_sdp_cep_header, exp_sdp_cep_header); end if; end process; @@ -1127,47 +1108,16 @@ begin -- . expect c_sdp_cep_nof_beamlets_per_block = c_sdp_S_sub_bf = 488 dual pol -- and complex beamlets per packet, so 2 dual pol beamlets/64b data word. -- . Beamlets array is stored big endian in the data, so X.real index 0 first - -- in MSByte of test_offload_sosi.data. - p_rx_cep_beamlets : process - begin - rx_beamlet_cnt <= 0; - rx_beamlet_valid <= '0'; - -- Wait until start of a beamlet packet, capture only first block in packet - proc_common_wait_until_high(ext_clk, test_offload_sosi.sop); - -- 2 dual pol beamlets (= XY, XY) per 64b data word - for I in 0 to (c_sdp_cep_nof_blocks_per_packet * c_sdp_cep_nof_beamlets_per_block / 2) - 1 loop - proc_common_wait_until_high(ext_clk, test_offload_sosi.valid); - rx_beamlet_valid <= '1'; - -- Capture rx beamlets per longword in rx_beamlet_arr, for time series view in Wave window - rx_beamlet_arr_re(0) <= test_offload_sosi.data(63 downto 56); -- X - rx_beamlet_arr_im(0) <= test_offload_sosi.data(55 downto 48); - rx_beamlet_arr_re(1) <= test_offload_sosi.data(47 downto 40); -- Y - rx_beamlet_arr_im(1) <= test_offload_sosi.data(39 downto 32); - rx_beamlet_arr_re(2) <= test_offload_sosi.data(31 downto 24); -- X - rx_beamlet_arr_im(2) <= test_offload_sosi.data(23 downto 16); - rx_beamlet_arr_re(3) <= test_offload_sosi.data(15 downto 8); -- Y - rx_beamlet_arr_im(3) <= test_offload_sosi.data( 7 downto 0); - 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(63 downto 56); -- X - rx_beamlet_list_im(I * 4 + 0) <= test_offload_sosi.data(55 downto 48); - rx_beamlet_list_re(I * 4 + 1) <= test_offload_sosi.data(47 downto 40); -- Y - rx_beamlet_list_im(I * 4 + 1) <= test_offload_sosi.data(39 downto 32); - rx_beamlet_list_re(I * 4 + 2) <= test_offload_sosi.data(31 downto 24); -- X - rx_beamlet_list_im(I * 4 + 2) <= test_offload_sosi.data(23 downto 16); - rx_beamlet_list_re(I * 4 + 3) <= test_offload_sosi.data(15 downto 8); -- Y - rx_beamlet_list_im(I * 4 + 3) <= test_offload_sosi.data( 7 downto 0); - 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; - end process; + -- in MSByte of rx_beamlet_sosi.data. + proc_sdp_cep_rx_beamlets(ext_clk, + rx_beamlet_sosi, + rx_beamlet_cnt, + rx_beamlet_valid, + rx_beamlet_arr_re, + rx_beamlet_arr_im, + rx_packet_list_re, + rx_packet_list_im); -- To view the 64 bit 10GbE offload data more easily in the Wave window - test_offload_data <= test_offload_sosi.data(c_longword_w - 1 downto 0); + rx_beamlet_data <= rx_beamlet_sosi.data(c_longword_w - 1 downto 0); end tb; 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 b1d36877af..14d00d4ca8 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 @@ -1367,43 +1367,14 @@ begin -- and complex beamlets per packet, so 2 dual pol beamlets/64b data word. -- . Beamlets array is stored big endian in the data, so X.real index 0 first -- in MSByte of rx_beamlet_sosi.data. - p_rx_cep_beamlets : process - begin - rx_beamlet_cnt <= 0; - rx_beamlet_valid <= '0'; - -- Wait until start of a beamlet packet - proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.sop); - -- c_sdp_nof_beamlets_per_longword = 2 dual pol beamlets (= XY, XY) per 64b data word - for I in 0 to (c_sdp_cep_nof_beamlets_per_packet / c_sdp_nof_beamlets_per_longword) - 1 loop - proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid); - rx_beamlet_valid <= '1'; - -- Capture rx beamlets per longword in rx_beamlet_arr, for time series view in Wave window - rx_beamlet_arr_re(0) <= rx_beamlet_sosi.data(63 downto 56); -- X - rx_beamlet_arr_im(0) <= rx_beamlet_sosi.data(55 downto 48); - rx_beamlet_arr_re(1) <= rx_beamlet_sosi.data(47 downto 40); -- Y - rx_beamlet_arr_im(1) <= rx_beamlet_sosi.data(39 downto 32); - rx_beamlet_arr_re(2) <= rx_beamlet_sosi.data(31 downto 24); -- X - rx_beamlet_arr_im(2) <= rx_beamlet_sosi.data(23 downto 16); - rx_beamlet_arr_re(3) <= rx_beamlet_sosi.data(15 downto 8); -- Y - rx_beamlet_arr_im(3) <= rx_beamlet_sosi.data( 7 downto 0); - -- Capture the beamlets block of each packet in rx_packet_list - rx_packet_list_re(I * 4 + 0) <= rx_beamlet_sosi.data(63 downto 56); -- X - rx_packet_list_im(I * 4 + 0) <= rx_beamlet_sosi.data(55 downto 48); - rx_packet_list_re(I * 4 + 1) <= rx_beamlet_sosi.data(47 downto 40); -- Y - rx_packet_list_im(I * 4 + 1) <= rx_beamlet_sosi.data(39 downto 32); - rx_packet_list_re(I * 4 + 2) <= rx_beamlet_sosi.data(31 downto 24); -- X - rx_packet_list_im(I * 4 + 2) <= rx_beamlet_sosi.data(23 downto 16); - rx_packet_list_re(I * 4 + 3) <= rx_beamlet_sosi.data(15 downto 8); -- Y - rx_packet_list_im(I * 4 + 3) <= rx_beamlet_sosi.data( 7 downto 0); - proc_common_wait_until_high(ext_clk, rx_beamlet_sosi.valid); - -- Use at least one WAIT instead of proc_common_wait_some_cycles() to - -- avoid Modelsim warning: (vcom-1090) Possible infinite loop: Process - -- contains no WAIT statement. - wait until rising_edge(ext_clk); - rx_beamlet_valid <= '0'; - rx_beamlet_cnt <= (rx_beamlet_cnt + c_sdp_nof_beamlets_per_longword) mod c_sdp_cep_nof_beamlets_per_block; -- 4 blocks/packet - end loop; - end process; + proc_sdp_cep_rx_beamlets(ext_clk, + rx_beamlet_sosi, + rx_beamlet_cnt, + rx_beamlet_valid, + rx_beamlet_arr_re, + rx_beamlet_arr_im, + rx_packet_list_re, + rx_packet_list_im); -- Undo the beamlet output transpose, to have original beamlet order p_rx_reordered_list : process -- GitLab