diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index a1a5d34b4ce149c69d421bf0a6a81a5d2187cd30..d3b6636991492670381e5d955d4d818016de6efb 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -78,10 +78,10 @@ PACKAGE sdp_pkg is CONSTANT c_sdp_W_adc : NATURAL := 14; CONSTANT c_sdp_W_fir_coef : NATURAL := 16; CONSTANT c_sdp_W_subband : NATURAL := 18; - CONSTANT c_sdp_P_pfb : NATURAL := c_sdp_S_pn/c_sdp_Q_fft; + CONSTANT c_sdp_P_pfb : NATURAL := c_sdp_S_pn / c_sdp_Q_fft; CONSTANT c_sdp_S_sub_bf : NATURAL := 488; CONSTANT c_sdp_f_adc_MHz : NATURAL := 200; - CONSTANT c_sdp_T_adc : TIME := (10**6/c_sdp_f_adc_MHz) * 1 ps; + CONSTANT c_sdp_T_adc : TIME := (10**6 / c_sdp_f_adc_MHz) * 1 ps; CONSTANT c_sdp_T_sub : TIME := c_sdp_N_fft * c_sdp_T_adc; CONSTANT c_sdp_W_sub_weight : NATURAL := 16; CONSTANT c_sdp_W_sub_magnitude : NATURAL := 2; diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd index 5b6e55b7926ffa3aaf2004a5531eadc5d7fa57be..7c8a9600e64088f9cfadc46e7542d69fa1d5b620 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd @@ -25,9 +25,10 @@ -- Purpose: -- . SDP statistics offload -- Description: --- --- https://support.astron.nl/confluence/pages/viewpage.action?spaceKey=L2M&title=L5+SDPFW+Design+Document%3A+Subband+filterbank +-- https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank +-- . See figure 4.3 -- https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD +-- . See 2.9.4 Station Control (L3-SC) - SDP Firmware (L4-SDPFW) -- ------------------------------------------------------------------------------- @@ -109,7 +110,6 @@ ARCHITECTURE str OF sdp_statistics_offload IS sel_a_b(g_statistics_type="XST", (c_sdp_S_pn * c_sdp_S_pn * c_nof_complex), c_sdp_N_sub)); -- SST - CONSTANT c_beamlet_id : NATURAL := g_beamset_id * c_sdp_S_sub_bf; TYPE t_reg IS RECORD @@ -140,19 +140,10 @@ ARCHITECTURE str OF sdp_statistics_offload IS --SIGNAL sdp_data_id : STD_LOGIC_VECTOR(31 DOWNTO 0); BEGIN - p_bsn_at_sync : PROCESS(in_sosi) - BEGIN - IF in_sosi.sync = '1' THEN - bsn_at_sync(63 DOWNTO 0) <= in_sosi.bsn(63 DOWNTO 0); - END IF; - END PROCESS; - -- get payload errors and keep them till next sync - p_payload_error : PROCESS(in_sosi) - BEGIN - - END PROCESS; + bsn_at_sync <= RESIZE_UVEC(in_sosi.bsn, 64) WHEN rising_edge(dp_clk) AND in_sosi.sync = '1'; + ------------------------------------------------------------------------------- -- Assemble offload header info ------------------------------------------------------------------------------- @@ -200,7 +191,10 @@ BEGIN d.interval_cnt <= 0; d.payload_err <= '0'; ELSE - d.payload_err <= r.payload_err OR in_sosi.err(0); + IF in_sosi.eop = '1' THEN + d.payload_err <= r.payload_err OR in_sosi.err(0); + END IF; + IF in_sosi.sop = '1' THEN d.interval_cnt <= r.interval_cnt + 1; END IF; diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd index 5588d7978d65ce789ab44734380800ab20dc1e34..26c9d34d80198d549e10073b4ba771d41b7db198 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd @@ -27,7 +27,7 @@ -- Description: -- -- https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank --- see Figure 4.8 +-- . See figure 4.8 -- -- Remark: -- . @@ -71,16 +71,18 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_hdr_dat_mm_addr_ip_src_addr : NATURAL := 13; CONSTANT c_hdr_dat_mm_addr_udp_src_port : NATURAL := 15; - -- SST RAM size and structure: c_nof_clk_per_block = c_nof_data * c_data_size * (c_step_size / c_data_size) => 512 * 2 * (4 / 2) = 2048 words per pair of signal inputs; - -- with 12 signal input, 6 pairs (blocks) we will fill 2 blocks for testing 2 * 2048 = 4096 words + -- Define SST RAM structure CONSTANT c_nof_data : NATURAL := 512; CONSTANT c_data_size : NATURAL := 2; CONSTANT c_step_size : NATURAL := 4; + + -- Define SST RAM size for g_nof_signal_inputs_per_pn CONSTANT c_ram_size : NATURAL := c_nof_data * c_data_size * g_nof_signal_inputs_per_pn; CONSTANT c_ram_w : NATURAL := ceil_log2(c_ram_size); --CONSTANT c_ram_buf : t_c_mem := (c_mem_ram_rd_latency, c_ram_w, 32, 2**c_ram_w, 'X'); CONSTANT c_ram_buf : t_c_mem := (1, c_ram_w, 32, 2**c_ram_w, 'X'); + -- Define block timing CONSTANT c_nof_block_per_sync : NATURAL := 20; -- sufficient to fit more than g_nof_signal_inputs_per_pn offload packets per sync interval CONSTANT c_nof_clk_per_block : NATURAL := c_nof_data * c_data_size; @@ -158,6 +160,8 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL ram_wr_en : STD_LOGIC; SIGNAL init_ram_done : STD_LOGIC := '0'; + SIGNAL rx_request : STD_LOGIC := '0'; + SIGNAL rx_prev_bsn : NATURAL := 0; SIGNAL rx_bsn : NATURAL := 0; SIGNAL rx_data_id : NATURAL := 0; SIGNAL rx_block_cnt : NATURAL := 0; @@ -210,7 +214,7 @@ BEGIN proc_common_wait_until_low(dp_clk, dp_rst); proc_common_wait_some_cycles(dp_clk, 10); in_sosi.valid <= '1'; - in_sosi.bsn <= x"0000000000010000"; + in_sosi.bsn <= TO_DP_BSN(16#10000#); proc_common_wait_some_cycles(dp_clk, 1); WHILE TRUE LOOP FOR i IN 0 TO c_nof_block_per_sync-1 LOOP @@ -223,7 +227,7 @@ BEGIN END IF; IF j = 0 THEN in_sosi.sop <= '1'; - in_sosi.bsn <= INCR_UVEC(in_sosi.bsn, 65536); + in_sosi.bsn <= INCR_UVEC(in_sosi.bsn, 16#10000#); -- = 2**16 = 65536 END IF; IF j = c_nof_clk_per_block-1 THEN in_sosi.eop <= '1'; @@ -310,44 +314,56 @@ BEGIN WAIT; END PROCESS; + -- Count number of blocks in a sync interval, rx_request is used to start counting from 0. + p_rx_block_cnt : PROCESS(dp_clk, test_offload_sosi) + BEGIN + IF rising_edge(dp_clk) THEN + IF test_offload_sosi.sop = '1' THEN + IF rx_request = '1' THEN + rx_block_cnt <= 0; + rx_request <= '0'; + ELSE + rx_block_cnt <= rx_block_cnt + 1; + END IF; + END IF; + IF in_sosi.sync = '1' THEN + rx_request <= '1'; + END IF; + END IF; + END PROCESS; + + -- Capture rx_bsn from header + rx_bsn <= TO_UINT(rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "dp_bsn") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "dp_bsn")+16)); + -- Keep rx_bsn from previous header + rx_prev_bsn <= rx_bsn WHEN rising_edge(dp_clk); + -- verify number of blocks between 2 syncs and between 2 changed bsn numbers - p_verify_nof_blocks : PROCESS(rx_bsn, rx_block_cnt, dp_clk, in_sosi.sync, test_offload_sosi, rx_hdr_fields_raw) - VARIABLE v_bsn : NATURAL; - VARIABLE v_block_cnt : NATURAL; + p_verify_nof_blocks : PROCESS(dp_clk, in_sosi, rx_block_cnt, rx_prev_bsn, rx_bsn, rx_hdr_fields_raw, test_offload_sosi) BEGIN - v_bsn := rx_bsn; - v_block_cnt := rx_block_cnt; IF rising_edge(dp_clk) THEN IF init_ram_done = '1' THEN IF in_sosi.sync = '1' AND rx_block_cnt > 0 THEN - ASSERT rx_block_cnt = g_nof_signal_inputs_per_pn REPORT "wrong number of blocks between 2 sync" SEVERITY ERROR; + ASSERT rx_block_cnt = g_nof_signal_inputs_per_pn - 1 REPORT "wrong number of blocks between 2 sync" SEVERITY ERROR; END IF; - v_bsn := TO_UINT(rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "dp_bsn") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "dp_bsn")+16)); - IF rx_bsn > 0 AND v_bsn > rx_bsn THEN - ASSERT (v_bsn - rx_bsn) = c_nof_block_per_sync REPORT "wrong number of blocks between 2 bsn numbers" SEVERITY ERROR; + -- rx_prev_bsn > 0 is needed for the first time , when there is no previous BSN. + -- rx_bsn > rx_prev_bsn is needed to detect a new rx_bsn. + IF rx_prev_bsn > 0 AND rx_bsn > rx_prev_bsn THEN + ASSERT (rx_bsn - rx_prev_bsn) = c_nof_block_per_sync REPORT "wrong number of blocks between 2 bsn numbers" SEVERITY ERROR; END IF; rx_data_id <= TO_UINT(rx_hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_data_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_data_id"))); IF test_offload_sosi.eop = '1' THEN - ASSERT rx_data_id = rx_block_cnt REPORT "block count number in sdp_data_id not same as counted blocks" SEVERITY ERROR; - END IF; - - IF test_offload_sosi.sop = '1' AND rx_block_cnt = g_nof_signal_inputs_per_pn THEN - v_block_cnt := 0; - ELSIF test_offload_sosi.eop = '1' THEN - v_block_cnt := v_block_cnt + 1; + ASSERT rx_data_id = rx_block_cnt REPORT "wrong block count number, received data_id not same as counted blocks" SEVERITY ERROR; END IF; END IF; test_offload_siso <= c_dp_siso_rdy; - rx_bsn <= v_bsn; - rx_block_cnt <= v_block_cnt; END IF; END PROCESS; - p_verify_valid : PROCESS(dp_clk) + p_verify_nof_valid : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN IF test_offload_sosi.sop = '1' THEN @@ -379,7 +395,7 @@ BEGIN p_dp_end : PROCESS BEGIN proc_common_wait_until_high(mm_clk, init_ram_done); - proc_common_wait_some_cycles(dp_clk, c_nof_sync * c_nof_clk_per_sync); -- will show 4 sync periods + proc_common_wait_some_cycles(dp_clk, c_nof_sync * c_nof_clk_per_sync); -- will show some sync periods tb_end <= '1'; WAIT; END PROCESS;