diff --git a/applications/apertif/commissioning/tests/verify_db_correlator.py b/applications/apertif/commissioning/tests/verify_db_correlator.py
new file mode 100644
index 0000000000000000000000000000000000000000..9203a2f7b3175f7ff93da46eaa9910dbbae9e704
--- /dev/null
+++ b/applications/apertif/commissioning/tests/verify_db_correlator.py
@@ -0,0 +1,299 @@
+###############################################################################
+#
+# Copyright (C) 2018
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+###############################################################################
+
+# Author:
+# E. Kooistra        12 Mar 2018  Created
+
+"""Test BF - X 10G link and mesh
+
+   This test on hardware is equivalent to test bench tb_apertif_bf_xc_link.vhd in
+   simulation. In node_apertif_unb1_correlator_input the test uses:
+   
+   * RAM_DIAG_DATA_BUFFER_INPUT_POST to read the data per c_nof_10g = 3 input links
+   * RAM_DIAG_DATA_BUFFER_MESH to read the data after the mesh for N_tp = 24 input links
+   
+   The test verifies the read data and runs independently per PN.
+   
+   In node_apertif_unb1_correlator_input the test uses:
+   * RAM_DIAG_DATA_BUFFER_INPUT_POST to read the data for c_nof_10g = three 10G links per
+     node after the BSN aligner
+
+   In node_apertif_unb1_correlator_mesh the test uses:
+   * RAM_DIAG_DATA_BUFFER_MESH to read the data for N_tp = 24 TP per node after the mesh.
+
+   Usage:
+   # -v 5 or 6 for debugging
+   # -v 0, 1, 2 or 3 for regression test
+   # At dish set dp_force_data_parallel
+   > ssh lcu-rt4 -X "python $RADIOHDL/applications/apertif/commissioning/tests/force_bf_transpose.py -v 3 --tel 4 --unb 0:3 --fn 0:3 --mode 0 --switch 0"
+   
+   # At central correlator verify expected result via DB (for same --tel --mode and --switch)
+   > python $RADIOHDL/applications/apertif/commissioning/tests/verify.py -v 5 --tel 4 --unb 2 --fn 0 --mode 0 --switch 0"
+   
+"""
+
+###############################################################################
+# System imports
+import sys
+from common import *
+import test_case
+import node_io
+import pi_diag_data_buffer
+
+c_nof_fn       = 4        # 4 FN per UniBoard
+N_pol          = 2
+P_BF           = 4        # 4 BF units per FN
+c_width        = 8        # 8b mode
+N_clk          = 256
+N_blk          = 176      # 8b mode
+Q_interleave   = 2
+M_blk          = N_blk / Q_interleave   # = 88
+N_int_x        = 800000
+c_nof_10g      = 3        # 3 10G input links per PN
+nof_streams    = c_nof_10g*P_BF  # = 12
+c_dbSize       = 512
+
+###############################################################################
+# Instantiations
+tc = test_case.Testcase('VERIFY_DB_CORRELATOR - ', '')
+tc.set_result('PASSED')
+
+# Read switch setting
+switch = 0
+if tc.switch==1:
+    switch = 1
+    
+tc.append_log(3, '>>>')
+if switch==0:
+    tc.append_log(1, '>>> Title : Test case to verify T_int_x transpose in BF and 10G link to X for %s' % (tc.unb_nodes_string()))
+else:
+    tc.append_log(1, '>>> Title : Test case to verify bypass T_int_x transpose in BF and 10G link to X for %s' % (tc.unb_nodes_string()))
+tc.append_log(3, '>>>')
+tc.append_log(3, '')
+
+io = node_io.NodeIO(tc.nodeImages, tc.base_ip)
+
+# Create one DB object for all PN
+db_input_post = pi_diag_data_buffer.PiDiagDataBuffer(tc, io, nodeNr=fn, instanceName='INPUT_POST', nofStreams=nof_streams, ramSizePerStream=c_dbSize, version=1)
+
+###############################################################################
+# Stimuli 
+# Overwrite DB data to be able to recognize new data
+pattern = [13]*c_dbSize
+db_input_post.overwrite_all_data_buffers(data=pattern, vLevel=9)
+
+# Wait untit DB have been filled        
+tc.sleep(2)
+
+# Read DB for all PN
+dbdata = db_input_post.read_all_data_buffers()
+
+
+###############################################################################
+# Verify DB per FN BF unit
+#
+# Loop over all data in a sync interval and use dbInRange to detect where the
+# data_buffer will capture the dbSize. The check on dbInRange speeds up the
+# loop. The check on rdaddr actually detects the postion of the data buffer at
+# c_dbSyncDelay:c_dbSyncDelay+dbSize.
+#
+# Transpose input by dp_force_data_parallel per BF unit is:
+#   im: increments per sop and restarts at global u every sync
+#   re: 0 1 2 3 4 ................................................. 175 : 255
+#       <-------------------------------------------------------------------> N_clk = 255
+
+## For --switch 0 the expected T_int_x transpose via DDR3 output per BF unit is:
+##   im: 0 0 1 1         0 0 1 1             ...                         + global bf unit index MOD 256
+##   re: 0 1 0 1 ... 0 1 2 3 2 3 ... 2 3     ...                 174 175
+##       <-------------------------------------------------------------> N_blk = 176
+##       <-------------> <------------->                 <-------------> N_int_x = 800000 on hw
+##       <-> <-> <->                                                 <-> Q_interleave = 2
+#if switch==0:
+#    cntDbData = 0
+#    for fi,fn in enumerate(tc.nodeFnIndices):  # loop FN
+#        for u in range(P_BF):       # loop BF units
+#            bf_unit_offset = fn * P_BF
+#            for bui in range(M_blk):
+#                dbLo =  bui    * N_int_x * Q_interleave - c_dbSyncDelay
+#                dbHi = (bui+1) * N_int_x * Q_interleave - c_dbSyncDelay
+#                dbInRange = dbHi > 0 and dbLo < c_dbSize
+#                if dbInRange:
+#                    if u==0:
+#                        tc.append_log(tc.V_DEBUG, 'T bui = %d, dbLo = %d, dbHi = %d' % (bui, dbLo, dbHi))
+#                    for t in range(N_int_x):
+#                        dbLo = (bui * N_int_x + t) * Q_interleave - c_dbSyncDelay
+#                        dbHi = dbLo + c_dbSize
+#                        dbInRange = dbHi > 0 and dbLo < c_dbSize
+#                        if dbInRange:
+#                            if u==0:
+#                                tc.append_log(tc.V_DEBUG, 't = %d, dbLo = %d, dbHi = %d' % (t, dbLo, dbHi))
+#                            exp_im = (bf_unit_offset + u + t) % N_clk
+#                            for q in range(Q_interleave):
+#                                rdaddr = (bui * N_int_x + t) * Q_interleave + q - c_dbSyncDelay;
+#                                if rdaddr >= 0 and rdaddr < c_dbSize:
+#                                    if u==0:
+#                                        tc.append_log(tc.V_DEBUG, 'rdaddr : %d' % rdaddr)
+#                                    # Expected data
+#                                    exp_re = bui * Q_interleave + q
+#                                    exp_data = exp_im * 2**c_width + exp_re;
+#                                    # MM read data
+#                                    rddata = rddata_fn_u[fi][u][rdaddr]
+#                                    if rddata!=exp_data:
+#                                        tc.append_log(tc.V_ERRORS, 'fn = %2d, u = %d, rdaddr = %3d: read 0x%X != 0x%X expected' % (fn, u, rdaddr, rddata, exp_data))
+#                                        tc.set_result('FAILED');
+#                                    cntDbData += 1
+#                else:
+#                    if u==0:
+#                        tc.append_log(tc.V_DEBUG, '  bui = %d, dbLo = %d, dbHi = %d' % (bui, dbLo, dbHi))
+#                    
+## For --switch 1 the expected direct output per BF unit is (so bypass T_int_x transpose):
+#if switch==1:
+#    cntDbData = 0
+#    for fi,fn in enumerate(tc.nodeFnIndices):  # loop FN
+#        for u in range(P_BF):       # loop BF units
+#            bf_unit_offset = fn * P_BF
+#            for t in range(N_int_x):
+#                dbLo =  t    * N_clk - c_dbSyncDelay
+#                dbHi = (t+1) * N_clk - c_dbSyncDelay
+#                dbInRange = dbHi > 0 and dbLo < c_dbSize
+#                if dbInRange:
+#                    if u==0:
+#                        tc.append_log(tc.V_DEBUG, 't = %d, dbLo = %d, dbHi = %d' % (t, dbLo, dbHi))
+#                    exp_im = (bf_unit_offset + u + t) % N_clk
+#                    for bu in range(N_clk):
+#                        rdaddr = t * N_clk + bu - c_dbSyncDelay;
+#                        if rdaddr >= 0 and rdaddr < c_dbSize:
+#                            if u==0:
+#                                tc.append_log(tc.V_DEBUG, 'rdaddr = %d' % rdaddr)
+#                            # Expected data
+#                            exp_re = bu
+#                            exp_data = exp_im * 2**c_width + exp_re;
+#                            # MM read data
+#                            rddata = rddata_fn_u[fi][u][rdaddr]
+#                            if rddata!=exp_data:
+#                                tc.append_log(tc.V_ERRORS, 'fn = %2d, u = %d, rdaddr = %3d: read 0x%X != 0x%X expected' % (fn, u, rdaddr, rddata, exp_data))
+#                                tc.set_result('FAILED');
+#                            cntDbData += 1
+#
+#                
+#nofFn = len(tc.nodeFnIndices)
+#expCntDbData = nofFn * P_BF * c_dbSize
+#if cntDbData != expCntDbData:
+#    tc.append_log(tc.V_ERRORS, 'Unexpected number of DB data = %d != %d' % (cntDbData, expCntDbData))
+#    tc.set_result('FAILED');
+#    
+#
+#  p_mm_diag_data_buffer : PROCESS
+#    CONSTANT c_mm_file_ram_diag_data_buffer : STRING := mmf_unb_file_prefix(g_tb_index, c_central_unb_nr, c_central_unb_pn_nr) & "RAM_DIAG_DATA_BUFFER_INPUT_POST";
+#  
+#    CONSTANT N_clk        : NATURAL := c_bf.nof_weights;      -- = 256
+#    CONSTANT N_blk        : NATURAL := c_block_size_out;      -- = 176 (8 bit mode), 240 (6 bit mode)
+#    CONSTANT N_int_x      : NATURAL := c_nof_block_per_sync;  -- = e.g. 32 in sim, 800000 on hw (multiple of N_pre_tranpose = 16)
+#    CONSTANT Q_interleave : NATURAL := 2;                     -- = 8/4 = nof_pn / P_BF
+#    
+#    CONSTANT c_db_nof_words       : NATURAL := N_int_x * N_blk;
+#    CONSTANT c_db_nof_words_pow2  : NATURAL := true_log_pow2(c_db_nof_words);
+#  
+#    CONSTANT c_max_X    : NATURAL := c_nof_10g*c_bf.nof_bf_units;  -- = 12, accept maximum one write/read data conflict per BF unit
+#    
+#    VARIABLE v_I        : INTEGER;
+#    VARIABLE v_exp_re   : NATURAL;
+#    VARIABLE v_exp_im   : NATURAL;
+#    VARIABLE v_exp_data : NATURAL;
+#    VARIABLE v_rd_data  : NATURAL;
+#  BEGIN    
+#    -- Wait for DUT power up after reset
+#    WAIT FOR 1 us;
+#
+#    -- Wait for DB to have filled with beamlet data from first transpose sync interval,
+#    -- see i_beamlets_src_out_arr in node_apertif_unb1_fn_beamformer_transpose
+#    proc_common_wait_until_time(ext_clk, 200 us);
+#    
+#    ----------------------------------------------------------------------------
+#    -- Read and verify data buffer
+#    ----------------------------------------------------------------------------
+#    -- Verify DB
+#    --   Transpose input per BF unit is:
+#    --     im: fixed at global BF unit index when c_use_force_en=FALSE
+#    --         increments per sop and restarts at global u every sync when c_use_force_en=TRUE
+#    --     re: 0 1 2 3 4 ................................................. 175 : 255
+#    --         <-------------------------------------------------------------------> N_clk = 255
+#    --   Expected transpose via DDR3 output per BF unit is:
+#    --     im: fixed at global BF unit index when c_use_force_en=FALSE
+#    --         0 0 1 1      31 0 0 1 1      31     ...                  31  31 when c_use_force_en=TRUE
+#    --     re: 0 1 0 1 ... 0 1 2 3 2 3 ... 2 3     ...                 174 175
+#    --         <-------------------------------------------------------------> N_blk = 176
+#    --         <-------------> <------------->                 <-------------> N_int_x = 32 in sim, 800000 on hw
+#    --         <-> <-> <->                                                 <-> Q_interleave = 2
+#    FOR lp IN 0 TO c_nof_10g-1 LOOP  -- lp = link path
+#      FOR u IN 0 TO c_bf.nof_bf_units-1 LOOP
+#        -- Read data buffer per BF unit output
+#        v_exp_im := c_bf_unit_band_offset + u;   -- im when c_use_force_en = FALSE, so BG output
+#        v_I := 0;
+#        FOR bui IN 0 TO N_blk/Q_interleave-1 LOOP
+#          FOR t IN 0 TO N_int_x-1 LOOP
+#            IF c_use_force_en=TRUE THEN
+#              IF g_force_im_ctrl=0 THEN
+#                v_exp_im := c_bf_unit_band_offset + u + t;   -- im when c_use_force_en = TRUE
+#              ELSIF g_force_im_ctrl=1 THEN
+#                v_exp_im := c_telescope_path_offset + lp + t;   -- im when c_use_force_en = TRUE
+#              END IF;
+#            END IF;
+#            FOR q IN 0 TO Q_interleave-1 LOOP
+#              -- Expected data
+#              v_exp_re := bui * Q_interleave + q;  -- re is independent of c_use_force_en, because both BG and dp_force are set for same re data
+#              v_exp_data := v_exp_im * 2**c_transport_w + v_exp_re;
+#              -- MM read data
+#              mmf_mm_bus_rd(c_mm_file_ram_diag_data_buffer, (u + lp*c_bf.nof_bf_units)*c_db_nof_words_pow2 + v_I, rd_data_db, tb_clk);
+#              v_rd_data := TO_UINT(rd_data_db);
+#              IF v_rd_data/=v_exp_data THEN
+#                -- Count number of mismatches
+#                nof_rd_data_db_X <= nof_rd_data_db_X + 1;
+#              END IF;
+#              ASSERT v_rd_data=v_exp_data REPORT "DB unexpected data : " & int_to_str(v_rd_data) & " /= " & int_to_str(v_exp_data) SEVERITY NOTE;
+#              v_I := v_I + 1;
+#            END LOOP;
+#          END LOOP;     
+#        END LOOP;
+#        -- Leave gap between BF unit accesses, to ease view in Wave window
+#        proc_common_wait_some_cycles(ext_clk, 100);
+#      END LOOP;
+#      -- Leave gap between lp input link accesses, to ease view in Wave window
+#      proc_common_wait_some_cycles(ext_clk, 100);
+#    END LOOP;
+#
+#    -- Accept only a few mismatches when occasionaly MM read and internal firmware write occur at same address and then cause 'X'
+#    ASSERT nof_rd_data_db_X <= c_max_X REPORT "DB too many data MM read retries : " & int_to_str(nof_rd_data_db_X) & " > " & int_to_str(c_max_X) SEVERITY ERROR;
+#    proc_common_wait_some_cycles(ext_clk, 1000);
+#    
+#    -- Wait some more to check that tb_end can be released differently per tb in a multi tb
+#    proc_common_wait_some_cycles(ext_clk, 1000*g_tb_index);
+#    
+#    verify_db_done <= '1';
+#    WAIT;
+#  END PROCESS;
+
+
+
+###############################################################################
+# End
+tc.set_section_id('')
+tc.append_log(tc.V_RESULT, '>>> Test result: %s' % tc.get_result())