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;