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 296222df4dc16c22a0e6cb9934415f86e7326f18..1418586567e224c4fb80266bdd835038af5b44b8 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd @@ -82,6 +82,17 @@ -- BST (Xh, Xl), (Yh, Yl), 2 keep X, Y parts order -- XST (Rh, Rl), (Ih, Il), 2 keep Re, Im parts order -- +-- . g_P_sq and nof_used_P_sq +-- The g_P_sq defines the number of correlator cells that is available in +-- the SDPFW. Use generic to support P_sq = 1 for one node and P_sq = +-- c_sdp_P_sq for multiple nodes (with ring). +-- The nof_used_P_sq is the number of correlator cells that is actually +-- used and that will output XST packets. Unused correlator cells yield +-- zero data that should not be output. The nof_used_P_sq is the smallest +-- of g_P_sq and ring_info.N_rn/2 + 1. In this way the XST offload can work +-- with g_P_sq = 1 when N_rn > 1 and also in a ring with N_rn < N_pn when +-- g_P_sq = 9. +-- ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, mm_lib, dp_lib, ring_lib; @@ -99,8 +110,8 @@ ENTITY sdp_statistics_offload IS g_statistics_type : STRING := "SST"; g_offload_time : NATURAL := c_sdp_offload_time; g_beamset_id : NATURAL := 0; - g_P_sq : NATURAL := c_sdp_P_sq; -- use generic to support P_sq = 1 for one node and P_sq = c_sdp_P_sq for multiple nodes (with ring) - g_crosslets_direction : NATURAL := 1; -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction + g_P_sq : NATURAL := c_sdp_P_sq; -- number of available correlator cells, + g_crosslets_direction : NATURAL := 1; -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction g_reverse_word_order : BOOLEAN := TRUE -- default word order is MSB after LSB, we need to stream LSB after MSB. ); PORT ( @@ -198,7 +209,10 @@ ARCHITECTURE str OF sdp_statistics_offload IS SIGNAL remote_pn : NATURAL; -- index of remote node in antenna band SIGNAL remote_si_offset : NATURAL; -- index of first signal input on remote node SIGNAL nof_cycles_dly : NATURAL; -- trigger_offload delay for this node - SIGNAL nof_packets : NATURAL; -- nof packets per integration interval + SIGNAL offset_rn : NATURAL; -- = ring_info.O_rn, GN index of first ring node + SIGNAL nof_rn : NATURAL; -- = ring_info.N_rn, number of GN in the ring + SIGNAL nof_used_P_sq : NATURAL; -- number of used correlator cells <= g_P_sq (is number of available correlator cells) + SIGNAL nof_packets : NATURAL; -- nof XST offload packets per integration interval SIGNAL data_id_rec : t_sdp_stat_data_id; SIGNAL data_id_slv : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0'); @@ -295,13 +309,16 @@ BEGIN -- Derive and pipeline dynamic parameters gn_index_reg <= gn_index WHEN rising_edge(dp_clk); pn_index <= func_sdp_gn_index_to_pn_index(gn_index) WHEN rising_edge(dp_clk); - rn_index <= gn_index - TO_UINT(ring_info.O_rn) WHEN rising_edge(dp_clk); + offset_rn <= TO_UINT(ring_info.O_rn) WHEN rising_edge(dp_clk); + rn_index <= gn_index - offset_rn WHEN rising_edge(dp_clk); local_si_offset <= pn_index * c_sdp_S_pn WHEN rising_edge(dp_clk); nof_cycles_dly <= gn_index * g_offload_time WHEN rising_edge(dp_clk); - nof_packets <= func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, r.nof_crosslets) WHEN rising_edge(dp_clk); + nof_rn <= TO_UINT(ring_info.N_rn) WHEN rising_edge(dp_clk); + nof_used_P_sq <= smallest(nof_rn / 2 + 1, g_P_sq) WHEN rising_edge(dp_clk); + nof_packets <= func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, nof_used_P_sq, r.nof_crosslets) WHEN rising_edge(dp_clk); - remote_rn <= func_ring_nof_hops_to_source_rn(r.instance_count, rn_index, TO_UINT(ring_info.N_rn), g_crosslets_direction); - remote_gn <= TO_UINT(ring_info.O_rn) + remote_rn; + remote_rn <= func_ring_nof_hops_to_source_rn(r.instance_count, rn_index, nof_rn, g_crosslets_direction) WHEN rising_edge(dp_clk); + remote_gn <= offset_rn + remote_rn WHEN rising_edge(dp_clk); remote_pn <= func_sdp_gn_index_to_pn_index(remote_gn) WHEN rising_edge(dp_clk); remote_si_offset <= remote_pn * c_sdp_S_pn WHEN rising_edge(dp_clk); 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 e586a5294dfdbad484a746f6198468e1b5abc133..d3e8ea79f510f428d3550ecc8ccefe21028da6e8 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 @@ -54,17 +54,17 @@ USE work.tb_sdp_pkg.ALL; ENTITY tb_sdp_statistics_offload IS GENERIC ( -- All - g_statistics_type : STRING := "SST"; + g_statistics_type : STRING := "XST"; g_offload_time : NATURAL := 50; g_reverse_word_order : BOOLEAN := TRUE; -- when TRUE then stream LSB word after MSB word. - g_gn_index : NATURAL := 5; -- global node (GN) index, must be in range(O_rn, O_rn + N_rn), use > 0 to see effect of g_offload_time + g_gn_index : NATURAL := 0; -- global node (GN) index, must be in range(O_rn, O_rn + N_rn), use > 0 to see effect of g_offload_time -- BST - g_beamset_id : NATURAL := 1; -- < c_sdp_N_beamsets + g_beamset_id : NATURAL := 0; -- < c_sdp_N_beamsets -- XST - g_O_rn : NATURAL := 4; -- GN index of first ring node (RN) + g_O_rn : NATURAL := 0; -- GN index of first ring node (RN) g_N_rn : NATURAL := 8; -- <= c_sdp_N_rn_max = 16, number of nodes in ring - g_P_sq : NATURAL := 4; -- <= c_sdp_P_sq - g_nof_crosslets : NATURAL := 3; -- <= c_sdp_N_crosslets_max + g_P_sq : NATURAL := 9; -- <= c_sdp_P_sq, nof available correlator cells + g_nof_crosslets : NATURAL := 7; -- <= c_sdp_N_crosslets_max g_crosslets_direction : NATURAL := 1 -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction ); END tb_sdp_statistics_offload; @@ -117,7 +117,8 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS -- Crosslets settings CONSTANT c_mm_nof_crosslets : STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0) := TO_UVEC(g_nof_crosslets, c_sdp_nof_crosslets_reg_w); - CONSTANT c_mm_nof_packets : NATURAL := func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, g_nof_crosslets); + CONSTANT c_nof_used_P_sq : NATURAL := smallest(g_N_rn / 2 + 1, g_P_sq); -- number of used correlator cells <= g_P_sq + CONSTANT c_rx_nof_packets : NATURAL := func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, c_nof_used_P_sq, g_nof_crosslets); -- payload data CONSTANT c_packet_size : NATURAL := c_nof_statistics_per_packet * c_sdp_W_statistic_sz; @@ -225,6 +226,7 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL dbg_c_marker : NATURAL := c_marker; SIGNAL dbg_c_nof_signal_inputs : NATURAL := c_nof_signal_inputs; SIGNAL dbg_c_nof_packets_max : NATURAL := c_nof_packets_max; + SIGNAL dbg_c_rx_nof_packets : NATURAL := c_rx_nof_packets; SIGNAL dbg_c_beamlet_index : NATURAL := c_beamlet_index; SIGNAL dbg_c_packet_size : NATURAL := c_packet_size; SIGNAL dbg_c_mm_user_size : NATURAL := c_mm_user_size; @@ -337,7 +339,7 @@ BEGIN test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit test_offload_sosi -- derive current X_sq correlator cell index - cur_X_sq_cell <= (test_offload_eop_cnt / g_nof_crosslets) MOD g_P_sq; + cur_X_sq_cell <= (test_offload_eop_cnt / g_nof_crosslets) MOD c_nof_used_P_sq; -- derive current N_crosslets index index cur_crosslet <= test_offload_eop_cnt MOD g_nof_crosslets; @@ -460,7 +462,7 @@ BEGIN BEGIN IF rising_edge(dp_clk) THEN IF in_sosi.sync = '1' AND in_sync_cnt > 1 THEN - ASSERT rx_packet_cnt = c_mm_nof_packets REPORT "Wrong number of packets per sync interval" SEVERITY ERROR; + ASSERT rx_packet_cnt = c_rx_nof_packets REPORT "Wrong number of packets per sync interval" SEVERITY ERROR; END IF; END IF; END PROCESS; @@ -557,7 +559,7 @@ BEGIN ASSERT v_exp_data = v_rx_data REPORT "Wrong BST payload data Rx" SEVERITY ERROR; ELSIF g_statistics_type = "XST" THEN - -- . g_P_sq = 4 + -- . c_nof_used_P_sq = 4 -- . g_nof_crosslets = 3 -- . c_sdp_N_crosslets_max = 7 --> c_mm_Xsq_span = 2**ceil_log2(7 * 576) = 4096 -- @@ -587,9 +589,9 @@ BEGIN -- c_mm_data_size / c_sdp_W_statistic_sz = 2 = c_nof_complex X := D; -- range c_sdp_X_sq = 144 complex XST values I := W MOD c_mm_user_size; -- range c_mm_user_size = c_sdp_W_statistic_sz = 2 words - P := rx_packet_cnt; -- range c_mm_nof_packets + P := rx_packet_cnt; -- range c_rx_nof_packets J := P MOD g_nof_crosslets; -- range g_nof_crosslets - K := P / g_nof_crosslets; -- range g_P_sq + K := P / g_nof_crosslets; -- range c_nof_used_P_sq v_exp_data := S * c_mm_user_size; -- c_mm_user_size = 2 IF g_reverse_word_order = FALSE THEN diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd index a688d26acd7d88aba8f60ca51f3409710bf0c36e..0d3f42ce3fd8ebfd344e86d101ddc1a301d05b49 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd @@ -63,5 +63,7 @@ BEGIN u_xst_P9_N3_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, FALSE, 1, 0, 0, 16, 9, 3, 1); u_xst_P9_N3_neg : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 9, 3, 0); u_xst_P8_N7_RN1_15 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 1, 15, 8, 7, 0); + u_xst_P1_N7_RN0_7 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 3, 0, 0, 8, 1, 7, 1); -- P_sq = 1 < N_rn/2+1 = 5 + u_xst_P9_N7_RN0_7 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 3, 0, 0, 8, 9, 7, 1); -- P_sq = 9 > N_rn/2+1 = 5 END tb;