diff --git a/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd b/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd
index 6e60576827b6b82a8cf5868f626744dfcf28322a..ec0734db72a4f67002edba348bd84a163b39f5c6 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_pkg.vhd
@@ -502,6 +502,20 @@ PACKAGE tb_dp_pkg IS
                                 SIGNAL   dbg_accumulate   : OUT   NATURAL;
                                 SIGNAL   dbg_expected_bsn : OUT   NATURAL);
 
+  PROCEDURE proc_dp_verify_sync(CONSTANT c_start_bsn      : IN    NATURAL;
+                                CONSTANT c_sync_period    : IN    NATURAL;
+                                CONSTANT c_block_size     : IN    NATURAL;
+                                CONSTANT c_bsn_is_rsn     : IN    BOOLEAN;    -- increment BSN by 1 or by c_block_size for RSN
+                                SIGNAL   clk              : IN    STD_LOGIC;
+                                SIGNAL   verify_en        : IN    STD_LOGIC;
+                                SIGNAL   sync             : IN    STD_LOGIC;
+                                SIGNAL   sop              : IN    STD_LOGIC;
+                                SIGNAL   bsn              : IN    STD_LOGIC_VECTOR;
+                                -- for debug purposes
+                                SIGNAL   dbg_nof_blk      : OUT   NATURAL;
+                                SIGNAL   dbg_accumulate   : OUT   NATURAL;
+                                SIGNAL   dbg_expected_bsn : OUT   NATURAL);
+
   -- Verify the DUT output sop and eop
   PROCEDURE proc_dp_verify_sop_and_eop(CONSTANT c_ready_latency : IN    NATURAL;
                                        CONSTANT c_verify_valid  : IN    BOOLEAN;
@@ -2379,6 +2393,7 @@ PACKAGE BODY tb_dp_pkg IS
   -- . assume that the fractional sync period varies between N and N-1 blocks
   -- . the fractional sync period starts with N blocks and fits e.g.
   --   dp_bsn_source_v2, dp_bsn_sync_scheduler.
+  -- . Use block sequence number (BSN) in dbg_expected_bsn.
   ------------------------------------------------------------------------------
   PROCEDURE proc_dp_verify_sync(CONSTANT c_start_bsn      : IN    NATURAL;    -- BSN of first sync, start of fractional periods
                                 CONSTANT c_sync_period    : IN    NATURAL;    -- number of sample per sync period
@@ -2392,6 +2407,43 @@ PACKAGE BODY tb_dp_pkg IS
                                 SIGNAL   dbg_nof_blk      : OUT   NATURAL;
                                 SIGNAL   dbg_accumulate   : OUT   NATURAL;
                                 SIGNAL   dbg_expected_bsn : OUT   NATURAL) IS
+  BEGIN
+    proc_dp_verify_sync(c_start_bsn,
+                        c_sync_period,
+                        c_block_size,
+                        FALSE,
+                        clk,
+                        verify_en,
+                        sync,
+                        sop,
+                        bsn,
+                        dbg_nof_blk,
+                        dbg_accumulate,
+                        dbg_expected_bsn);
+  END proc_dp_verify_sync;
+
+  ------------------------------------------------------------------------------
+  -- PROCEDURE: Verify the DUT output sync
+  -- . sync is defined such that it can only be active at sop
+  -- . assume that the fractional sync period varies between N and N-1 blocks
+  -- . the fractional sync period starts with N blocks and fits e.g.
+  --   dp_bsn_source_v2, dp_bsn_sync_scheduler.
+  -- . support using block sequence number (BSN) in dbg_expected_bsn or using
+  --   raw samples sequence number (RSN) in dbg_expected_bsn
+  ------------------------------------------------------------------------------
+  PROCEDURE proc_dp_verify_sync(CONSTANT c_start_bsn      : IN    NATURAL;    -- BSN of first sync, start of fractional periods
+                                CONSTANT c_sync_period    : IN    NATURAL;    -- number of sample per sync period
+                                CONSTANT c_block_size     : IN    NATURAL;    -- number of sample per block
+                                CONSTANT c_bsn_is_rsn     : IN    BOOLEAN;    -- increment BSN by 1 or by c_block_size for RSN
+                                SIGNAL   clk              : IN    STD_LOGIC;
+                                SIGNAL   verify_en        : IN    STD_LOGIC;
+                                SIGNAL   sync             : IN    STD_LOGIC;
+                                SIGNAL   sop              : IN    STD_LOGIC;
+                                SIGNAL   bsn              : IN    STD_LOGIC_VECTOR;
+                                -- for debug purposes
+                                SIGNAL   dbg_nof_blk      : OUT   NATURAL;
+                                SIGNAL   dbg_accumulate   : OUT   NATURAL;
+                                SIGNAL   dbg_expected_bsn : OUT   NATURAL) IS
     CONSTANT c_bsn_w         : NATURAL := sel_a_b(bsn'LENGTH>31, 31, bsn'LENGTH);  -- use maximally c_natural_w = 31 bit of BSN slv to allow calculations with integers
     CONSTANT c_nof_blk_min   : NATURAL := c_sync_period / c_block_size;    -- minimum number of blocks in sync period
     CONSTANT c_extra         : NATURAL := c_sync_period MOD c_block_size;  -- number of extra samples in sync period
@@ -2405,12 +2457,21 @@ PACKAGE BODY tb_dp_pkg IS
     IF c_extra = 0 THEN
       -- The sync period contains an integer number of blocks (c_extra = 0)
       -- Determine directly whether the input bsn is expected to have a sync
-      v_expected_sync := ((v_bsn - c_start_bsn) MOD c_nof_blk_min = 0);
+      IF c_bsn_is_rsn THEN
+        v_expected_sync := ((v_bsn - c_start_bsn) MOD (c_nof_blk_min * c_block_size) = 0);
+      ELSE
+        v_expected_sync := ((v_bsn - c_start_bsn) MOD c_nof_blk_min = 0);
+      END IF;
     ELSE
       -- The sync period contains a fractional number of blocks
       -- Determine next expected BSN with sync until the input bsn is reached using a loop
       WHILE v_expected_bsn < v_bsn LOOP
-        v_expected_bsn := v_expected_bsn + v_nof_blk;  -- next expected BSN to have a sync
+        -- next expected BSN to have a sync
+        IF c_bsn_is_rsn THEN
+          v_expected_bsn := v_expected_bsn + v_nof_blk * c_block_size;
+        ELSE
+          v_expected_bsn := v_expected_bsn + v_nof_blk;
+        END IF;
 
         v_nof_blk := c_nof_blk_min;
         v_accumulate   := v_accumulate - c_extra;
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
new file mode 100644
index 0000000000000000000000000000000000000000..f0afc936e52f5e110b33a74b7e446a0cd8b05064
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_rsn_source.vhd
@@ -0,0 +1,97 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2023
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- Author: E. Kooistra
+-- Purpose: Multi dp for tb_dp_rsn_source
+-- Remark:
+-- . Derived from tb_tb_dp_bsn_source_v2
+-- Usage:
+-- > as 4
+-- > run -all --> OK
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE work.tb_dp_pkg.ALL;
+
+
+ENTITY tb_tb_dp_rsn_source IS
+END tb_tb_dp_rsn_source;
+
+
+ARCHITECTURE tb OF tb_tb_dp_rsn_source IS
+
+  SIGNAL tb_end : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+
+BEGIN
+  -- from tb_dp_rsn_source.vhd
+  --
+  -- g_pps_interval   : NATURAL := 240
+  -- g_bs_block_size  : NATURAL := 32
+  -- g_rs_block_size  : NATURAL := 5 --23
+
+  -----------------------------------------------------------------------------
+  -- Tests with g_rs_block_size /= g_bs_block_size
+  -----------------------------------------------------------------------------
+  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_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
+  u_9_5_4    : ENTITY work.tb_dp_rsn_source GENERIC MAP (9, 5, 4);  -- 2 g_bs_block_size > g_pps_interval > 2 g_rs_block_size
+  u_9_5_9    : ENTITY work.tb_dp_rsn_source GENERIC MAP (9, 5, 9);  -- 1 g_rs_block_size/g_pps_interval
+  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
+  -----------------------------------------------------------------------------
+  -- 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
+  u_22_11  : ENTITY work.tb_dp_rsn_source GENERIC MAP (22, 11, 11);  -- 22 // 11 = 2, 22 MOD 11 = 0, 22/11 = 2 block/sync
+  u_39_13  : ENTITY work.tb_dp_rsn_source GENERIC MAP (39, 13, 13);  -- 39 // 13 = 3, 39 MOD 13 = 0, 39/13 = 3 block/sync
+
+  -- test smallest nof block per sync
+  u_10_10  : ENTITY work.tb_dp_rsn_source GENERIC MAP (10, 10, 10);  -- 1 block/sync
+  u_5_5    : ENTITY work.tb_dp_rsn_source GENERIC MAP (5, 5, 5);    -- 1 block/sync
+
+  -- test smallest g_block_size case
+  u_3_3    : ENTITY work.tb_dp_rsn_source GENERIC MAP (3, 3, 3);  -- 3 // 3 = 1, 3 MOD 3 = 0, 3/3 = 1 block/sync
+  u_6_3    : ENTITY work.tb_dp_rsn_source GENERIC MAP (6, 3, 3);  -- 6 // 3 = 2, 6 MOD 3 = 0, 6/3 = 2 block/sync
+  u_7_3    : ENTITY work.tb_dp_rsn_source GENERIC MAP (7, 3, 3);  -- 7 // 3 = 2, 7 MOD 3 = 1, 7/3 = 2.33 block/sync
+
+  -- test lofar case with 0.5 fraction in average nof block/sync
+  u_20_8   : ENTITY work.tb_dp_rsn_source GENERIC MAP (20, 8, 8);  -- 20 // 8 = 2, 20 MOD 8 = 4, 20/8 = 2.5 block/sync
+
+  -- test fractional (corner) cases
+  u_18_9   : ENTITY work.tb_dp_rsn_source GENERIC MAP (18, 9, 9);  -- 18 MOD 9 = 0
+  u_17_9   : ENTITY work.tb_dp_rsn_source GENERIC MAP (17, 9, 9);  -- 17 MOD 9 = 8 = g_block_size - 1
+  u_19_9   : ENTITY work.tb_dp_rsn_source GENERIC MAP (19, 9, 9);  -- 19 MOD 9 = 1
+  u_20_9   : ENTITY work.tb_dp_rsn_source GENERIC MAP (20, 9, 9);  -- 20 MOD 9 = 2
+  u_25_9   : ENTITY work.tb_dp_rsn_source GENERIC MAP (25, 9, 9);  -- 25 MOD 9 = 7
+  u_26_9   : ENTITY work.tb_dp_rsn_source GENERIC MAP (26, 9, 9);  -- 26 MOD 9 = 8 = g_block_size - 1
+  u_27_9   : ENTITY work.tb_dp_rsn_source GENERIC MAP (27, 9, 9);  -- 27 MOD 9 = 0
+
+  -- test some prime values
+  u_17_3   : ENTITY work.tb_dp_rsn_source GENERIC MAP (17, 3, 3);    -- 17 // 3 = 5, 17 MOD 3 = 2, 17/3 = 5.66 block/sync
+  u_101_17 : ENTITY work.tb_dp_rsn_source GENERIC MAP (101, 17, 17);  -- 101 // 17 = 5, 101 MOD 17 = 16, 101/17 = 5.9411 block/sync
+
+END tb;
+