diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index db256bdb9cd2f3ffc724528270bada72fce038f3..48865ad1dbd81ac2513b08448297ce8eb0e75d85 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -308,6 +308,7 @@ test_bench_files =
     tb/vhdl/tb_tb_dp_bsn_align.vhd
     tb/vhdl/tb_tb_dp_bsn_align_v2.vhd
     tb/vhdl/tb_tb_mmp_dp_bsn_align_v2.vhd
+    tb/vhdl/tb_tb_dp_rsn_source.vhd
     tb/vhdl/tb_tb_dp_bsn_source_v2.vhd
     tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
     tb/vhdl/tb_tb_dp_concat.vhd
@@ -382,6 +383,7 @@ regression_test_vhdl =
     tb/vhdl/tb_tb_dp_block_validate_channel.vhd
     tb/vhdl/tb_tb_dp_bsn_align_v2.vhd
     tb/vhdl/tb_tb_mmp_dp_bsn_align_v2.vhd
+    tb/vhdl/tb_tb_dp_rsn_source.vhd
     tb/vhdl/tb_tb_dp_bsn_source_v2.vhd
     tb/vhdl/tb_tb_dp_bsn_sync_scheduler.vhd
     tb/vhdl/tb_tb_dp_concat.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_rsn_source.vhd b/libraries/base/dp/src/vhdl/dp_rsn_source.vhd
index 2fe9e62030cac214eae839ccb7656e7e637df9c5..61ec23f9dff8e62a108b7af363387a3f0a105d7f 100644
--- a/libraries/base/dp/src/vhdl/dp_rsn_source.vhd
+++ b/libraries/base/dp/src/vhdl/dp_rsn_source.vhd
@@ -1,6 +1,6 @@
 -------------------------------------------------------------------------------
 --
--- Copyright 2022
+-- Copyright 2023
 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
 -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
 --
@@ -32,11 +32,12 @@
 --   The bs_sosi can stop and restart. It (re)starts with bs_sosi.sync and
 --   bs_sosi.sop when bs_sosi.valid becomes '1' and it stops when
 --   bs_sosi.valid becomes '0' immediately after a bs_sosi.eop.
---   The rs_sosi block size is g_block_size.
+--   The rs_sosi block size is g_rs_block_size.
 --   The rs_sosi sync interval has g_nof_clk_per_sync. If g_nof_clk_per_sync
---   is not a multiple of g_block_size, then the rs_sosi.sync will occur at
+--   is not a multiple of g_rs_block_size, then the rs_sosi.sync will occur at
 --   the next start of block.
---   The initial RSN in rs_sosi.bsn is bs_sosi.bsn * g_block_size.
+--   The initial RSN in rs_sosi.bsn is bs_sosi.bsn * g_bs_block_size, where
+--   g_bs_block_size is the input block size of bs_sosi.
 --   The rs_sosi starts when the bs_sosi starts, so when bs_sosi.sync = '1'
 --   and bs_sosi.valid becomes '1'.
 --   The rs_sosi ends after the rs_sosi.eop, when the bs_sosi ends. There
@@ -56,7 +57,8 @@ USE work.dp_stream_pkg.ALL;
 
 ENTITY dp_rsn_source IS
   GENERIC (
-    g_block_size        : NATURAL := 256;  -- >= 3, see state machine
+    g_bs_block_size     : NATURAL := 256;  -- input bs_sosi block size, >= 3, see state machine
+    g_rs_block_size     : NATURAL := 256;  -- output rs_sosi block size, >= 3, see state machine
     g_nof_clk_per_sync  : NATURAL := 200 * 10**6;
     g_bsn_w             : NATURAL := 64
   );
@@ -69,7 +71,7 @@ ENTITY dp_rsn_source IS
 
     -- Output stream sosi control using RSN
     nof_clk_per_sync    : IN  STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_clk_per_sync, c_word_w);
-    rs_sosi             : OUT t_dp_sosi;  -- output stream using RSN and g_block_size, g_nof_clk_per_sync
+    rs_sosi             : OUT t_dp_sosi;  -- output stream using RSN and g_rs_block_size, g_nof_clk_per_sync
     rs_restart          : OUT STD_LOGIC;  -- = rs_sosi.sync for first sync after bs_sosi.valid went high
     rs_new_interval     : OUT STD_LOGIC   -- = active during first rs_sosi.sync interval
   );
@@ -78,8 +80,9 @@ END dp_rsn_source;
 
 ARCHITECTURE rtl OF dp_rsn_source IS
 
-  CONSTANT c_block_size_cnt_w : NATURAL := ceil_log2(g_block_size);
-  CONSTANT c_rsn_product_w    : NATURAL := g_bsn_w + c_block_size_cnt_w;
+  CONSTANT c_bs_block_size_cnt_w : NATURAL := ceil_log2(g_bs_block_size) + 1;  -- +1 because value 2**n requires n + 1 bits
+  CONSTANT c_rs_block_size_cnt_w : NATURAL := ceil_log2(g_rs_block_size) + 1;  -- +1 because value 2**n requires n + 1 bits
+  CONSTANT c_rsn_product_w       : NATURAL := g_bsn_w + c_bs_block_size_cnt_w;
 
   TYPE t_state_enum IS (s_off, s_on_sop, s_on, s_on_eop);
 
@@ -91,11 +94,11 @@ ARCHITECTURE rtl OF dp_rsn_source IS
 
   SIGNAL nxt_sync            : STD_LOGIC;
   SIGNAL sync                : STD_LOGIC;
-  SIGNAL nxt_sync_size_cnt   : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
   SIGNAL sync_size_cnt       : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL nxt_sync_size_cnt   : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
 
-  SIGNAL block_size_cnt      : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0);
-  SIGNAL nxt_block_size_cnt  : STD_LOGIC_VECTOR(c_block_size_cnt_w-1 DOWNTO 0);
+  SIGNAL rs_block_size_cnt      : STD_LOGIC_VECTOR(c_rs_block_size_cnt_w-1 DOWNTO 0);
+  SIGNAL nxt_rs_block_size_cnt  : STD_LOGIC_VECTOR(c_rs_block_size_cnt_w-1 DOWNTO 0);
   
   SIGNAL i_rs_sosi           : t_dp_sosi := c_dp_sosi_init;
   SIGNAL nxt_rs_sosi         : t_dp_sosi;
@@ -111,11 +114,11 @@ BEGIN
   rs_restart <= i_rs_restart;
   rs_new_interval <= i_rs_new_interval;
 
-  rsn <= MULT_UVEC(bs_sosi.bsn(g_bsn_w-1 DOWNTO 0), TO_UVEC(g_block_size, c_block_size_cnt_w));
+  rsn <= MULT_UVEC(bs_sosi.bsn(g_bsn_w-1 DOWNTO 0), TO_UVEC(g_bs_block_size, c_bs_block_size_cnt_w));
 
-  p_state : PROCESS(bs_sosi, sync, sync_size_cnt, nof_clk_per_sync,
+  p_state : PROCESS(bs_sosi, nxt_sync, sync, sync_size_cnt, nof_clk_per_sync,
                     state, prev_state,
-                    i_rs_sosi, block_size_cnt, rsn)
+                    i_rs_sosi, rs_block_size_cnt, rsn)
   BEGIN  
     -- Maintain sync_size_cnt for nof_clk_per_sync
     -- . nof_clk_per_sync is the number of clk per sync interval and the
@@ -131,6 +134,9 @@ BEGIN
       nxt_sync <= '1';  -- will set rs_sosi.sync on next rs_sosi.sop
       nxt_sync_size_cnt <= (OTHERS=>'0');
     END IF;
+    IF i_rs_sosi.sync = '1' THEN
+      nxt_sync <= '0';  -- clear when sync has been applied in rs_sosi
+    END IF;
 
     -- State machine for rs_sosi
     nxt_state                   <= state;
@@ -139,7 +145,7 @@ BEGIN
     nxt_rs_sosi.valid           <= '0';
     nxt_rs_sosi.sop             <= '0';
     nxt_rs_sosi.eop             <= '0';
-    nxt_block_size_cnt          <= block_size_cnt;
+    nxt_rs_block_size_cnt       <= rs_block_size_cnt;
 
     CASE state IS
       WHEN s_off =>
@@ -147,7 +153,7 @@ BEGIN
         nxt_rs_sosi.bsn <= RESIZE_DP_BSN(rsn);  -- RSN fits in g_bsn_w
         nxt_sync <= '0';
         nxt_sync_size_cnt <= (OTHERS=>'0');
-        nxt_block_size_cnt <= (OTHERS=>'0');
+        nxt_rs_block_size_cnt <= (OTHERS=>'0');
         IF bs_sosi.sync = '1' THEN
           nxt_rs_sosi.sync <= '1';
           nxt_rs_sosi.sop <= '1';
@@ -156,31 +162,30 @@ BEGIN
         END IF;
 
       -- using separate states s_on_sop and s_on_eop instead of only
-      -- s_on state and block_size_cnt, cause that g_block_size must be
+      -- s_on state and rs_block_size_cnt, cause that g_rs_block_size must be
       -- >= 3, but that is fine.
       WHEN s_on_sop =>
         -- Start of block
         nxt_rs_sosi.sop <= '1';
         nxt_rs_sosi.valid  <= '1';
         nxt_state <= s_on;
-        -- block_size_cnt = 0 at rs_sosi.sop
-        nxt_block_size_cnt <= (OTHERS=>'0');
+        -- rs_block_size_cnt = 0 at rs_sosi.sop
+        nxt_rs_block_size_cnt <= (OTHERS=>'0');
         -- after first block, increment bsn per block
         IF prev_state = s_on_eop THEN
-          nxt_rs_sosi.bsn <= INCR_DP_BSN(i_rs_sosi.bsn, g_block_size, g_bsn_w);  -- RSN
+          nxt_rs_sosi.bsn <= INCR_DP_BSN(i_rs_sosi.bsn, g_rs_block_size, g_bsn_w);  -- RSN
         END IF;
         -- check for pending sync
-        IF sync = '1' THEN
+        IF nxt_sync = '1' THEN
           nxt_rs_sosi.sync <= '1';
-          nxt_sync <= '0';
         END IF;
 
       WHEN s_on =>
         -- During block
         nxt_rs_sosi.valid <= '1';
-        -- block_size_cnt increments to determine end of block
-        nxt_block_size_cnt <= INCR_UVEC(block_size_cnt, 1);
-        IF UNSIGNED(block_size_cnt) >= g_block_size - 3 THEN
+        -- rs_block_size_cnt increments to determine end of block
+        nxt_rs_block_size_cnt <= INCR_UVEC(rs_block_size_cnt, 1);
+        IF UNSIGNED(rs_block_size_cnt) >= g_rs_block_size - 3 THEN
           nxt_state <= s_on_eop;
         END IF;
 
@@ -189,7 +194,8 @@ BEGIN
         nxt_rs_sosi.eop <= '1';
         nxt_rs_sosi.valid <= '1';
         nxt_state <= s_on_sop;
-        -- block_size_cnt is dont care at at rs_sosi.eop
+        nxt_rs_block_size_cnt <= INCR_UVEC(rs_block_size_cnt, 1);
+        -- rs_block_size_cnt is dont care at at rs_sosi.eop
         -- accept dp_off after eop, to avoid fractional blocks
         IF bs_sosi.valid = '0' THEN
           nxt_state <= s_off;
@@ -216,7 +222,7 @@ BEGIN
       i_rs_sosi           <= c_dp_sosi_rst;
       sync_size_cnt       <= (OTHERS=>'0');
       sync                <= '0';
-      block_size_cnt      <= (OTHERS=>'0');
+      rs_block_size_cnt   <= (OTHERS=>'0');
       i_rs_restart        <= '0';
       reg_rs_new_interval <= '0';
     ELSIF rising_edge(clk) THEN
@@ -225,7 +231,7 @@ BEGIN
       i_rs_sosi           <= nxt_rs_sosi;
       sync_size_cnt       <= nxt_sync_size_cnt;
       sync                <= nxt_sync;
-      block_size_cnt      <= nxt_block_size_cnt;
+      rs_block_size_cnt   <= nxt_rs_block_size_cnt;
       i_rs_restart        <= nxt_rs_restart;
       reg_rs_new_interval <= i_rs_new_interval;
     END IF;
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_rsn_source.vhd b/libraries/base/dp/tb/vhdl/tb_dp_rsn_source.vhd
index 774c0fe8f1c3164b9d87df2f1d3123dad9d1f4b5..b1521fa311897defd073be9385793a3ba8a746c4 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_rsn_source.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_rsn_source.vhd
@@ -1,6 +1,6 @@
 -------------------------------------------------------------------------------
 --
--- Copyright 2022
+-- Copyright 2023
 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
 -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
 --
@@ -24,7 +24,10 @@
 --   Use dp_bsn_source_v2 to create bs_sosi and extending it with dut =
 --   dp_rsn_source to create and verify rs_sosi.
 -- Remark:
--- * This tb is made based on tb_dp_bsn_source_v2.
+-- * This tb is made based on tb_dp_bsn_source_v2. Difference is that bs_sosi
+--   has block grid that starts at t_epoch = 0, whereas rs_sosi has block
+--   grid that can start at any bs_sosi.sync. Therefore p_exp_grid_rs is
+--   needed
 
 LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
@@ -36,9 +39,9 @@ USE dp_lib.tb_dp_pkg.ALL;
 
 ENTITY tb_dp_rsn_source IS
   GENERIC (
-    g_pps_interval   : NATURAL := 16; --101;
-    g_bs_block_size  : NATURAL := 5; --23
-    g_rs_block_size  : NATURAL := 5 --23
+    g_pps_interval   : NATURAL := 40; --101;
+    g_bs_block_size  : NATURAL := 10; --23, input BSN block size <= g_pps_interval
+    g_rs_block_size  : NATURAL := 10 --23, output RSN block size <= g_pps_interval
   );
 END tb_dp_rsn_source;
 
@@ -62,7 +65,7 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
   -- choose c_nof_pps and c_nof_repeat > c_min_nof_pps_interval, because the
   -- fractional sync pattern will repeat every c_min_nof_pps_interval number
   -- of g_pps_intervals.
-  CONSTANT c_factor            : NATURAL := 3;
+  CONSTANT c_factor            : NATURAL := 5;
   CONSTANT c_nof_pps           : NATURAL := c_min_nof_pps_interval * c_factor;
   CONSTANT c_nof_repeat        : NATURAL := c_min_nof_pps_interval * c_factor;
 
@@ -71,7 +74,9 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
   CONSTANT c_bsn_time_offset_w : NATURAL := ceil_log2(g_bs_block_size);
 
   -- Minimum latency between sync and PPS, due to logic in DUT
-  CONSTANT c_dut_latency       : NATURAL := 3;
+  CONSTANT c_dp_bsn_latency    : NATURAL := 3;
+  CONSTANT c_dp_rsn_latency    : NATURAL := 1;
+  CONSTANT c_dut_latency       : NATURAL := c_dp_bsn_latency + c_dp_rsn_latency;
 
   -- The state name tells what kind of test is being done
   TYPE t_state_enum IS (
@@ -90,45 +95,51 @@ ARCHITECTURE tb OF tb_dp_rsn_source IS
     eop  : STD_LOGIC;  -- end of block
   END RECORD;
 
-  CONSTANT c_time_grid_rst : t_time_grid := ('0', 0, 0, '0', '0', '0');
+  CONSTANT c_time_grid_rst  : t_time_grid := ('0', 0, 0, '0', '0', '0');
 
   -- Reference grid
-  SIGNAL ref_grid        : t_time_grid := c_time_grid_rst;
-  SIGNAL ssn_eop         : STD_LOGIC := '0';
-  SIGNAL hold_pps        : STD_LOGIC := '0';
-  SIGNAL nxt_hold_pps    : STD_LOGIC := '0';
+  SIGNAL ref_grid_bs        : t_time_grid := c_time_grid_rst;
+  SIGNAL ssn_eop            : STD_LOGIC := '0';
+  SIGNAL hold_pps           : STD_LOGIC := '0';
+  SIGNAL nxt_hold_pps       : STD_LOGIC := '0';
 
   -- Tb
-  SIGNAL tb_end       : STD_LOGIC := '0';
-  SIGNAL rst          : STD_LOGIC := '1';
-  SIGNAL clk          : STD_LOGIC := '1';
-  SIGNAL tb_state        : t_state_enum := s_disable;
+  SIGNAL tb_end             : STD_LOGIC := '0';
+  SIGNAL rst                : STD_LOGIC := '1';
+  SIGNAL clk                : STD_LOGIC := '1';
+  SIGNAL tb_state           : t_state_enum := s_disable;
 
   -- BSN source
-  SIGNAL dp_on           : STD_LOGIC := '0';
-  SIGNAL dp_on_pps       : STD_LOGIC := '0';
-  SIGNAL dp_on_status    : STD_LOGIC;
-  SIGNAL bs_restart      : STD_LOGIC;
-  SIGNAL bs_new_interval : STD_LOGIC;
-  SIGNAL tb_new_interval : STD_LOGIC := '0';
-  SIGNAL bsn_init        : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');
-  SIGNAL bsn_time_offset : STD_LOGIC_VECTOR(c_bsn_time_offset_w-1 DOWNTO 0) := (OTHERS=>'0');
-  SIGNAL bs_sosi         : t_dp_sosi;
+  SIGNAL dp_on              : STD_LOGIC := '0';
+  SIGNAL dp_on_pps          : STD_LOGIC := '0';
+  SIGNAL dp_on_status       : STD_LOGIC;
+  SIGNAL bs_restart         : STD_LOGIC;
+  SIGNAL bs_new_interval    : STD_LOGIC;
+  SIGNAL tb_new_interval    : STD_LOGIC := '0';
+  SIGNAL bsn_init           : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL bsn_time_offset    : STD_LOGIC_VECTOR(c_bsn_time_offset_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL bs_sosi            : t_dp_sosi;
+  SIGNAL exp_grid_bs        : t_time_grid;  -- to check with bs_sosi.bsn, sync, sop, eop
 
   -- RSN source
-  SIGNAL rs_restart      : STD_LOGIC;
-  SIGNAL rs_new_interval : STD_LOGIC;
-  SIGNAL rs_sosi         : t_dp_sosi;
+  SIGNAL rs_restart         : STD_LOGIC;
+  SIGNAL rs_new_interval    : STD_LOGIC;
+  SIGNAL rs_sosi            : t_dp_sosi;
+  SIGNAL exp_grid_rs        : t_time_grid;  -- to verify rs_sosi.bsn, sync, sop, eop
 
   -- Verify
-  SIGNAL exp_grid           : t_time_grid;
-  SIGNAL unexpected_bs_sync : STD_LOGIC;
+  SIGNAL exp_rs_start_bsn   : NATURAL;
+  SIGNAL exp_rs_sync_cnt    : NATURAL;
+  SIGNAL exp_rs_block_cnt   : NATURAL;
+  SIGNAL hold_exp_rs_sync   : STD_LOGIC := '0';
+
+  SIGNAL unexpected_rs_sync : STD_LOGIC;
   SIGNAL sl0                : STD_LOGIC := '0';
   SIGNAL verify_en          : STD_LOGIC := '0';
   SIGNAL verify_sync        : STD_LOGIC := '0';
-  SIGNAL hold_bs_sop        : STD_LOGIC;
-  SIGNAL prev_bs_valid      : STD_LOGIC;
-  SIGNAL bs_starts_cnt      : NATURAL := 0;
+  SIGNAL hold_rs_sop        : STD_LOGIC := '0';
+  SIGNAL prev_rs_valid      : STD_LOGIC;
+  SIGNAL rs_starts_cnt      : NATURAL := 0;
 
   SIGNAL dbg_c_nof_pps      : NATURAL := c_nof_pps;
   SIGNAL dbg_c_nof_repeat   : NATURAL := c_nof_repeat;
@@ -143,32 +154,32 @@ BEGIN
   clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
 
   -----------------------------------------------------------------------------
-  -- Generate reference time grid
+  -- Generate reference time grid for bs_sosi
   -----------------------------------------------------------------------------
-  proc_common_gen_pulse(1, g_pps_interval, '1', sl0, clk, ref_grid.pps);
-  proc_common_gen_pulse(1, g_bs_block_size, '1', sl0, clk, ref_grid.sop);
-  ref_grid.eop <= ref_grid.sop'DELAYED((g_bs_block_size - 1) * c_clk_period);
-  ssn_eop <= ref_grid.pps'DELAYED((g_pps_interval - 1) * c_clk_period);
-  ref_grid.ssn <= ref_grid.ssn + 1 WHEN rising_edge(clk) AND ssn_eop = '1';
-  ref_grid.bsn <= ref_grid.bsn + 1 WHEN rising_edge(clk) AND ref_grid.eop = '1';
+  proc_common_gen_pulse(1, g_pps_interval, '1', sl0, clk, ref_grid_bs.pps);
+  proc_common_gen_pulse(1, g_bs_block_size, '1', sl0, clk, ref_grid_bs.sop);
+  ref_grid_bs.eop <= ref_grid_bs.sop'DELAYED((g_bs_block_size - 1) * c_clk_period);
+  ssn_eop <= ref_grid_bs.pps'DELAYED((g_pps_interval - 1) * c_clk_period);
+  ref_grid_bs.ssn <= ref_grid_bs.ssn + 1 WHEN rising_edge(clk) AND ssn_eop = '1';
+  ref_grid_bs.bsn <= ref_grid_bs.bsn + 1 WHEN rising_edge(clk) AND ref_grid_bs.eop = '1';
 
   -- Issue sync at start of block
-  p_ref_grid_sync : PROCESS(ref_grid, hold_pps)
+  p_ref_grid_bs_sync : PROCESS(ref_grid_bs, hold_pps)
   BEGIN
-    ref_grid.sync <= '0';
+    ref_grid_bs.sync <= '0';
     nxt_hold_pps <= hold_pps;
 
-    IF ref_grid.pps = '1' THEN
-      IF ref_grid.sop = '1' THEN
-        ref_grid.sync <= '1';  -- immediately issue sync
+    IF ref_grid_bs.pps = '1' THEN
+      IF ref_grid_bs.sop = '1' THEN
+        ref_grid_bs.sync <= '1';  -- immediately issue sync
       ELSE
         nxt_hold_pps <= '1';  -- wait until next block
       END IF;
     END IF;
 
     IF hold_pps = '1' THEN
-      IF ref_grid.sop = '1' THEN
-        ref_grid.sync <= '1';  -- issue pending sync
+      IF ref_grid_bs.sop = '1' THEN
+        ref_grid_bs.sync <= '1';  -- issue pending sync
         nxt_hold_pps <= '0';
       END IF;
     END IF;
@@ -176,7 +187,71 @@ BEGIN
 
   hold_pps <= nxt_hold_pps WHEN rising_edge(clk);
 
-  exp_grid <= ref_grid'DELAYED(c_dut_latency * c_clk_period);
+  exp_grid_bs <= ref_grid_bs'DELAYED(c_dp_bsn_latency * c_clk_period);
+
+  -----------------------------------------------------------------------------
+  -- Generate reference time grid for rs_sosi
+  -----------------------------------------------------------------------------
+
+  -- using clk process accounts for c_dp_rsn_latency = 1
+  p_exp_grid_rs : PROCESS(clk)
+    VARIABLE v_sop : STD_LOGIC;
+  BEGIN
+    IF rising_edge(clk) THEN
+      v_sop := '0';
+
+      -- same pps, ssn
+      exp_grid_rs.pps <= exp_grid_bs.pps;
+      exp_grid_rs.ssn <= exp_grid_bs.ssn;
+      exp_grid_rs.sync <= '0';
+      exp_grid_rs.sop <= '0';
+      exp_grid_rs.eop <= '0';
+
+      -- bs blocks start at t_epoch = 0, but rs sync and blocks start at
+      -- bs_restart, so not necessarily at t_epoch = 0
+      IF bs_restart = '1' THEN
+        exp_rs_sync_cnt <= 0;
+        exp_rs_block_cnt <= 0;
+        exp_grid_rs.sync <= '1';
+        exp_grid_rs.sop <= '1';
+        exp_grid_rs.bsn <= exp_grid_bs.bsn * g_bs_block_size;
+        exp_rs_start_bsn <= exp_grid_bs.bsn * g_bs_block_size;
+        hold_exp_rs_sync <= '0';
+      ELSE
+        -- expected rs_sosi sop, eop
+        IF exp_rs_block_cnt < g_rs_block_size-2 THEN
+          exp_rs_block_cnt <= exp_rs_block_cnt + 1;
+        ELSIF exp_rs_block_cnt = g_rs_block_size-2 THEN
+          exp_rs_block_cnt <= exp_rs_block_cnt + 1;
+          exp_grid_rs.eop <= '1';
+        ELSIF exp_rs_block_cnt = g_rs_block_size-1 THEN
+          v_sop := '1';
+          exp_rs_block_cnt <= 0;
+          exp_grid_rs.sop <= '1';
+          exp_grid_rs.bsn <= exp_grid_rs.bsn + g_rs_block_size;
+          -- check for pending rs_sosi sync
+          IF hold_exp_rs_sync = '1' THEN
+            exp_grid_rs.sync <= '1';
+            hold_exp_rs_sync <= '0';
+          END IF;
+        END IF;
+
+        -- expected rs_sosi sync
+        IF exp_rs_sync_cnt < g_pps_interval-1 THEN
+          exp_rs_sync_cnt <= exp_rs_sync_cnt + 1;
+        ELSE
+          exp_rs_sync_cnt <= 0;
+          IF v_sop = '1' THEN
+            exp_grid_rs.sync <= '1';  -- issue sync immediately at this exp_grid_rs.sop
+          ELSE
+            hold_exp_rs_sync <= '1';  -- pend sync until next exp_grid_rs.sop
+          END IF;
+        END IF;
+      END IF;
+
+    END IF;
+  END PROCESS;
+
 
   -----------------------------------------------------------------------------
   -- Stimuli
@@ -199,7 +274,9 @@ BEGIN
     tb_state <= s_disable;
     dp_on <= '0';
     dp_on_pps <= '0';
-    proc_common_wait_some_cycles(clk, 10);
+
+    -- Wait sufficient until bs_sosi is idle again
+    proc_common_wait_some_cycles(clk, 5*g_pps_interval);
 
     -- Start synchronously by making dp_on and dp_on_pps high
     verify_en <= '1';  -- verify automatically in test bench
@@ -207,17 +284,17 @@ BEGIN
     FOR I IN 0 TO c_nof_repeat-1 LOOP
       -- Wait some variable time between tests, to enforce testing different
       -- bsn_time_offset values
-      proc_common_wait_some_cycles(clk, 20);
+      proc_common_wait_some_cycles(clk, 5*g_pps_interval);
       proc_common_wait_some_cycles(clk, I*g_pps_interval);
 
       -- Wait until in the beginning of PPS interval
-      proc_common_wait_until_hi_lo(clk, ref_grid.pps);
-      proc_common_wait_some_cycles(clk, c_dut_latency);
+      proc_common_wait_until_hi_lo(clk, ref_grid_bs.pps);
+      proc_common_wait_some_cycles(clk, c_dp_bsn_latency);
 
       -- Determine bsn_init and bsn_time_offset for BSN source start
       -- . bsn_init = BSN at sync
       -- . bsn_time_offset = number of clk that sync occurs after PPS
-      v_ssn := ref_grid.ssn + 1;  -- +1 to prepare start in next PPS interval
+      v_ssn := ref_grid_bs.ssn + 1;  -- +1 to prepare start in next PPS interval
       v_bsn_init := ceil_div(v_SSN * g_pps_interval, g_bs_block_size);  -- Equation 3.6 in [1]
       v_bsn_time_offset := v_bsn_init * g_bs_block_size - v_SSN * g_pps_interval;  -- Equation 3.7 in [1]
       bsn_init <= TO_UVEC(v_bsn_init, c_bsn_w);  --
@@ -233,7 +310,7 @@ BEGIN
     END LOOP;
 
     proc_common_wait_some_cycles(clk, 10);
-    ASSERT bs_starts_cnt = 1 + c_nof_repeat REPORT "Wrong number of BSN source starts." SEVERITY ERROR;
+    ASSERT rs_starts_cnt = 1 + c_nof_repeat REPORT "Wrong number of BSN source starts." SEVERITY ERROR;
 
     tb_end <= '1';
     WAIT;
@@ -242,79 +319,80 @@ BEGIN
 
   -----------------------------------------------------------------------------
   -- Verification
-  -- . Some aspects of bs_sosi are verified multiple times in different ways,
+  -- . Some aspects of rs_sosi are verified multiple times in different ways,
   --   this overlap is fine, because the tb and DUT are rather complicated, so
   --   using different approaches also helpt to verify the tb itself.
   -----------------------------------------------------------------------------
-  verify_sync <= verify_en AND bs_sosi.valid;
+  verify_sync <= verify_en AND rs_sosi.valid;
 
-  proc_dp_verify_sop_and_eop(clk, bs_sosi.valid, bs_sosi.sop, bs_sosi.eop, hold_bs_sop);  -- Verify that sop and eop come in pairs
-  --proc_dp_verify_sync(clk, verify_sync, bs_sosi.sync, exp_grid.sop, exp_grid.sync);  -- Verify sync at sop and at expected_sync
+  proc_dp_verify_sop_and_eop(clk, rs_sosi.valid, rs_sosi.sop, rs_sosi.eop, hold_rs_sop);  -- Verify that sop and eop come in pairs
+  --proc_dp_verify_sync(clk, verify_sync, rs_sosi.sync, exp_grid_rs.sop, exp_grid_rs.sync);  -- Verify sync at sop and at expected_sync
 
   -- Verify sync at sop and at expected_sync
-  proc_dp_verify_sync(0,  -- start bsn of PPS grid and BSN grid is 0, see [1]
+  proc_dp_verify_sync(exp_rs_start_bsn,
                       g_pps_interval,
-                      g_bs_block_size,
+                      g_rs_block_size,
+                      TRUE,   -- use BSN as RSN
                       clk,
                       verify_en,
-                      bs_sosi.sync,
-                      bs_sosi.sop,
-                      bs_sosi.bsn,
+                      rs_sosi.sync,
+                      rs_sosi.sop,
+                      rs_sosi.bsn,
                       dbg_nof_blk,
                       dbg_accumulate,
                       dbg_expected_bsn);
 
-  -- Verify bs_sosi by comparing with exp_grid, this again verifies bs_sosi.sync, sop and bsn
-  p_verify_bs_sosi_grid : PROCESS(clk)
+  -- Verify rs_sosi by comparing with exp_grid_rs, this again verifies rs_sosi.sync, sop and bsn
+  p_verify_rs_sosi_grid : PROCESS(clk)
   BEGIN
     IF rising_edge(clk) THEN
-      unexpected_bs_sync <= '0';
-      IF verify_en = '1' AND bs_sosi.valid = '1' THEN
-        ASSERT TO_UINT(bs_sosi.bsn) = exp_grid.bsn REPORT "Wrong bs_sosi.bsn /= exp_grid.bsn" SEVERITY ERROR;
-        ASSERT bs_sosi.sync = exp_grid.sync REPORT "Wrong bs_sosi.sync /= exp_grid.sync" SEVERITY ERROR;
-        ASSERT bs_sosi.sop = exp_grid.sop REPORT "Wrong bs_sosi.sop /= exp_grid.sop" SEVERITY ERROR;
-        ASSERT bs_sosi.eop = exp_grid.eop REPORT "Wrong bs_sosi.eop /= exp_grid.eop" SEVERITY ERROR;
+      unexpected_rs_sync <= '0';
+      IF verify_en = '1' AND rs_sosi.valid = '1' THEN
+        ASSERT TO_UINT(rs_sosi.bsn) = exp_grid_rs.bsn REPORT "Wrong rs_sosi.bsn /= exp_grid_rs.bsn" SEVERITY ERROR;
+        ASSERT rs_sosi.sync = exp_grid_rs.sync REPORT "Wrong rs_sosi.sync /= exp_grid_rs.sync" SEVERITY ERROR;
+        ASSERT rs_sosi.sop = exp_grid_rs.sop REPORT "Wrong rs_sosi.sop /= exp_grid_rs.sop" SEVERITY ERROR;
+        ASSERT rs_sosi.eop = exp_grid_rs.eop REPORT "Wrong rs_sosi.eop /= exp_grid_rs.eop" SEVERITY ERROR;
         -- Mark error in Wave window
-        IF bs_sosi.sync = '1' AND bs_sosi.sync /= exp_grid.sync THEN
-          unexpected_bs_sync <= '1';
+        IF rs_sosi.sync = '1' AND rs_sosi.sync /= exp_grid_rs.sync THEN
+          unexpected_rs_sync <= '1';
         END IF;
       END IF;
     END IF;
   END PROCESS;
 
-  -- Verify that bs_sosi.valid = '1' did happen after dp_on by verifying bs_start
-  prev_bs_valid <= bs_sosi.valid WHEN rising_edge(clk);
-  bs_starts_cnt <= bs_starts_cnt + 1 WHEN rising_edge(clk) AND bs_sosi.valid = '1' AND prev_bs_valid = '0';
+  -- Verify that rs_sosi.valid = '1' did happen after dp_on by verifying rs_start
+  prev_rs_valid <= rs_sosi.valid WHEN rising_edge(clk);
+  rs_starts_cnt <= rs_starts_cnt + 1 WHEN rising_edge(clk) AND rs_sosi.valid = '1' AND prev_rs_valid = '0';
 
-  p_verify_bs_restart : PROCESS(clk)
+  p_verify_rs_restart : PROCESS(clk)
   BEGIN
     IF rising_edge(clk) THEN
-      IF bs_restart = '1' THEN
-        ASSERT bs_sosi.sync = '1' REPORT "Unexpected bs_start while bs_sosi.sync /= 1" SEVERITY ERROR;
-        ASSERT prev_bs_valid = '0' REPORT "Unexpected bs_start while prev_bs_valid /= 0" SEVERITY ERROR;
+      IF rs_restart = '1' THEN
+        ASSERT rs_sosi.sync = '1' REPORT "Unexpected rs_start while rs_sosi.sync /= 1" SEVERITY ERROR;
+        ASSERT prev_rs_valid = '0' REPORT "Unexpected rs_start while prev_rs_valid /= 0" SEVERITY ERROR;
       END IF;
     END IF;
   END PROCESS;
 
-  p_verify_bs_new_interval : PROCESS(clk)
+  p_verify_rs_new_interval : PROCESS(clk)
   BEGIN
     IF rising_edge(clk) THEN
-      IF bs_restart = '1' THEN
-        ASSERT bs_new_interval = '1' REPORT "Wrong begin of bs_new_interval" SEVERITY ERROR;
+      IF rs_restart = '1' THEN
+        ASSERT rs_new_interval = '1' REPORT "Wrong begin of rs_new_interval" SEVERITY ERROR;
         tb_new_interval <= '1';
-      ELSIF bs_sosi.sync = '1' THEN
-        ASSERT bs_new_interval = '0' REPORT "Wrong end of bs_new_interval" SEVERITY ERROR;
+      ELSIF rs_sosi.sync = '1' THEN
+        ASSERT rs_new_interval = '0' REPORT "Wrong end of rs_new_interval" SEVERITY ERROR;
         tb_new_interval <= '0';
       ELSIF tb_new_interval = '1' THEN
-        ASSERT bs_new_interval = '1' REPORT "Wrong level during bs_new_interval" SEVERITY ERROR;
+        ASSERT rs_new_interval = '1' REPORT "Wrong level during rs_new_interval" SEVERITY ERROR;
       ELSE
-        ASSERT bs_new_interval = '0' REPORT "Unexpected bs_new_interval" SEVERITY ERROR;
+        ASSERT rs_new_interval = '0' REPORT "Unexpected rs_new_interval" SEVERITY ERROR;
       END IF;
     END IF;
   END PROCESS;
 
   -----------------------------------------------------------------------------
-  -- DUT: dp_bsn_source_v2
+  -- DUT: dp_bsn_source_v2 --> dp_rsn_source
   -----------------------------------------------------------------------------
 
   u_bsn : ENTITY work.dp_bsn_source_v2
@@ -327,7 +405,7 @@ BEGIN
   PORT MAP (
     rst              => rst,
     clk              => clk,
-    pps              => ref_grid.pps,
+    pps              => ref_grid_bs.pps,
     -- MM control
     dp_on            => dp_on,
     dp_on_pps        => dp_on_pps,
@@ -345,7 +423,8 @@ BEGIN
 
   u_rsn : ENTITY work.dp_rsn_source
   GENERIC MAP (
-    g_block_size        => g_rs_block_size,
+    g_bs_block_size     => g_bs_block_size,
+    g_rs_block_size     => g_rs_block_size,
     g_nof_clk_per_sync  => g_pps_interval,
     g_bsn_w             => c_bsn_w
   )
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_rsn_source.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_rsn_source.vhd
index f0afc936e52f5e110b33a74b7e446a0cd8b05064..377dd47e96a0117119fb4ab1c9fd09196cd5f468 100644
--- a/libraries/base/dp/tb/vhdl/tb_tb_dp_rsn_source.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_rsn_source.vhd
@@ -52,6 +52,7 @@ BEGIN
   -----------------------------------------------------------------------------
   u_12_3_3   : ENTITY work.tb_dp_rsn_source GENERIC MAP (12,  3,  3);  -- smallest block size
   u_16_8_4   : ENTITY work.tb_dp_rsn_source GENERIC MAP (16,  8,  4);  -- integer number of blocks per g_pps_interval
+  u_25_5     : ENTITY work.tb_dp_rsn_source GENERIC MAP (25,  5,  5);
   u_29_17_23 : ENTITY work.tb_dp_rsn_source GENERIC MAP (29, 17, 23);  -- fractional number of blocks per g_pps_interval
 
   u_9_4_5    : ENTITY work.tb_dp_rsn_source GENERIC MAP (9, 4, 5);  -- 2 g_bs_block_size < g_pps_interval < 2 g_rs_block_size
@@ -60,8 +61,7 @@ BEGIN
   u_9_9_5    : ENTITY work.tb_dp_rsn_source GENERIC MAP (9, 9, 5);  -- 1 g_bs_block_size/g_pps_interval
 
   -----------------------------------------------------------------------------
-  -- Same tests as with tb_dp_bsn_source_v2
-  -- . g_rs_block_size /= g_bs_block_size
+  -- Same tests as with tb_dp_bsn_source_v2 with g_rs_block_size = g_bs_block_size
   -----------------------------------------------------------------------------
   -- test integer case
   u_20_10  : ENTITY work.tb_dp_rsn_source GENERIC MAP (20, 10, 10);  -- 20 // 10 = 2, 20 MOD 10 = 0, 20/10 = 2 block/sync