diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd index a11dac56788bf43d7cbb73d8bfba830f7a65832e..5cebe5272409933708979acc0b1fa26439599ff6 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload.vhd @@ -76,13 +76,21 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload IS CONSTANT c_pps_period : NATURAL := c_nof_clk_per_sync; CONSTANT c_wpfb_sim : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync); CONSTANT c_ctrl_interval_size : NATURAL := c_nof_clk_per_sync; + CONSTANT c_nof_crosslets : NATURAL := 3; -- not too large, so that offload still fits in c_nof_block_per_sync CONSTANT c_subband_select_arr : t_natural_arr(0 TO c_sdp_N_crosslets_max-1) := (10, 11, 12, 13, 14, 15, 16); - CONSTANT c_subband_step : NATURAL := 0; - CONSTANT c_nof_crosslets : NATURAL := 3; - CONSTANT c_nof_sync : NATURAL := 2; + CONSTANT c_subband_step : NATURAL := 3; -- e.g. 0 or c_nof_crosslets + CONSTANT c_nof_sync : NATURAL := 5; + + -- WG + CONSTANT c_bsn_start_wg : NATURAL := 2; + CONSTANT c_sp_ampl : REAL := 0.5; -- WG normalized amplitude, 1.0 = FS (full scale), use <= 0.5 to avoid XST overflow + CONSTANT c_wg_ampl : NATURAL := NATURAL(c_sp_ampl * REAL(c_sdp_FS_adc)); -- in number of lsb + CONSTANT c_wg_subband : REAL := 15.0; -- MM CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2"; + CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER"; + CONSTANT c_mm_file_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG"; CONSTANT c_mm_file_reg_crosslets_info : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_CROSSLETS_INFO"; CONSTANT c_mm_file_reg_nof_crosslets : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_NOF_CROSSLETS"; CONSTANT c_mm_file_reg_bsn_sync_scheduler_xsub : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SYNC_SCHEDULER_XSUB"; @@ -113,22 +121,38 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one_xst_offload IS SIGNAL INTA : STD_LOGIC; SIGNAL INTB : STD_LOGIC; - SIGNAL eth_clk : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0'); - SIGNAL eth_txp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0'); - SIGNAL eth_rxp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0) := (OTHERS => '0'); + SIGNAL eth_clk : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL eth_txp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL eth_rxp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 DOWNTO 0) := (OTHERS => '0'); + + -- WG + SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- Rx packets SIGNAL eth_rx_sosi : t_dp_sosi; - SIGNAL eth_rx_data : STD_LOGIC_VECTOR(c_32-1 downto 0); + SIGNAL eth_rx_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); -- Decode packets SIGNAL rx_offload_sosi : t_dp_sosi; + + -- . view payload statistics data + SIGNAL rx_word_cnt : NATURAL := 0; + SIGNAL rx_sdp_stat_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); + SIGNAL rx_sdp_stat_re : STD_LOGIC_VECTOR(c_64-1 DOWNTO 0); + SIGNAL rx_sdp_stat_im : STD_LOGIC_VECTOR(c_64-1 DOWNTO 0); + SIGNAL rx_sdp_stat_re_val : STD_LOGIC := '0'; + SIGNAL rx_sdp_stat_im_val : STD_LOGIC := '0'; + SIGNAL rx_sdp_stat_index : NATURAL := 0; + SIGNAL rx_a_sp : NATURAL := 0; + SIGNAL rx_b_sp : NATURAL := 0; + + -- . view header 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_stat_header : t_sdp_stat_header; -- back transceivers - SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0); + SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 DOWNTO 0); SIGNAL JESD204B_REFCLK : STD_LOGIC := '1'; -- jesd204b syncronization signals @@ -203,6 +227,7 @@ BEGIN tb_clk <= NOT tb_clk AFTER c_tb_clk_period/2; -- Testbench MM clock p_mm_stimuli : PROCESS + VARIABLE v_bsn : NATURAL; BEGIN -- Wait for DUT power up after reset WAIT FOR 1 us; @@ -219,6 +244,32 @@ BEGIN WAIT FOR 1 us; pps_rst <= '0'; + ---------------------------------------------------------------------------- + -- Enable and start WG + ---------------------------------------------------------------------------- + -- 0 : mode[7:0] --> off=0, calc=1, repeat=2, single=3) + -- nof_samples[31:16] --> <= c_ram_wg_size=1024 + -- 1 : phase[15:0] + -- 2 : freq[30:0] + -- 3 : ampl[16:0] + FOR I IN 0 TO c_sdp_S_pn-1 LOOP + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 1, INTEGER(0.0 * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 2, INTEGER(REAL(c_wg_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq + mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl + END LOOP; + + -- Read current BSN + mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk); + mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 1, current_bsn_wg(63 DOWNTO 32), tb_clk); + proc_common_wait_some_cycles(tb_clk, 1); + + -- Write scheduler BSN to trigger start of WG at next block + v_bsn := TO_UINT(current_bsn_wg) + 2; + ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR; + mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, c_bsn_start_wg, tb_clk); -- first write low then high part + mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1, 0, tb_clk); -- assume v_bsn < 2**31-1 + ---------------------------------------------------------------------------- -- Setup and enable xsub ---------------------------------------------------------------------------- @@ -274,14 +325,14 @@ BEGIN eth_rx_data <= eth_rx_sosi.data(c_32-1 DOWNTO 0); - -- . Verify XST packet header + -- . View / verify XST packet header u_rx_statistics : ENTITY dp_lib.dp_offload_rx GENERIC MAP ( g_nof_streams => 1, g_data_w => c_word_w, g_hdr_field_arr => c_sdp_stat_hdr_field_arr, - g_remove_crc => FALSE, - g_crc_nof_words => 0 + g_remove_crc => TRUE, + g_crc_nof_words => 1 ) PORT MAP ( mm_rst => pps_rst, @@ -300,4 +351,41 @@ BEGIN rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw); + -- . View / verify XST packet payload + p_rx_sdp_stat_data : PROCESS(eth_clk(0)) + BEGIN + IF rising_edge(eth_clk(0)) THEN + rx_sdp_stat_re_val <= '0'; + rx_sdp_stat_im_val <= '0'; + IF rx_offload_sosi.valid = '1' THEN + -- Count words 0, 1, 2, 3 + rx_word_cnt <= 0; + IF rx_word_cnt < c_sdp_N_pol * c_nof_complex - 1 THEN + rx_word_cnt <= rx_word_cnt + 1; + END IF; + + -- Count words for the complex statistics with two 32bits words per 64 bit statistic, + -- high word part and real data received first. + CASE rx_word_cnt IS + WHEN 0 => rx_sdp_stat_data <= rx_offload_sosi.data(c_32-1 DOWNTO 0); + WHEN 1 => rx_sdp_stat_re <= rx_sdp_stat_data & rx_offload_sosi.data(c_32-1 DOWNTO 0); + rx_sdp_stat_re_val <= '1'; + WHEN 2 => rx_sdp_stat_data <= rx_offload_sosi.data(c_32-1 DOWNTO 0); + WHEN 3 => rx_sdp_stat_im <= rx_sdp_stat_data & rx_offload_sosi.data(c_32-1 DOWNTO 0); + rx_sdp_stat_im_val <= '1'; + rx_sdp_stat_index <= rx_sdp_stat_index + 1; + WHEN OTHERS => NULL; + END CASE; + END IF; + + IF rx_offload_sosi.sop = '1' THEN + rx_sdp_stat_index <= 0; -- restart per Rx packet + END IF; + END IF; + END PROCESS; + + -- rx_sdp_stat_index counts the S_pn * S_pn = X_sq = 12 * 12 = 144 complex statistics + rx_a_sp <= rx_sdp_stat_index / c_sdp_S_pn; -- signal input A + rx_b_sp <= rx_sdp_stat_index MOD c_sdp_S_pn; -- signal input B + END tb;