diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.fpga.yaml b/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.fpga.yaml
index 35ca819e6d42eb2f958e072ed62251d636cd526d..80766f3196f427ce134a766ca36eeccbb897c65e 100644
--- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.fpga.yaml
+++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.fpga.yaml
@@ -204,27 +204,27 @@ peripherals:
     mm_port_names:
       - REG_STAT_HDR_DAT_SST
   
-#  #############################################################################
-#  # Xsub = Subband Correlator (from node_sdp_correlator.vhd)
-#  #############################################################################
-#  
-#  - peripheral_name: dp/dp_bsn_scheduler
-#    peripheral_group: xsub
-#    mm_port_names:
-#      - REG_BSN_SCHEDULER_XSUB
-#      
-#  - peripheral_name: dp/dp_sync_insert_v2
-#    mm_port_names:
-#      - REG_DP_SYNC_INSERT_V2   
-#      
-#  - peripheral_name: st/st_xst
-#    mm_port_names:
-#      - RAM_ST_XSQ
-#      
-#  - peripheral_name: sdp/sdp_crosslets_subband_select
-#    mm_port_names:
-#      - REG_CROSSLETS_INFO
-#
+  #############################################################################
+  # Xsub = Subband Correlator (from node_sdp_correlator.vhd)
+  #############################################################################
+  
+  - peripheral_name: dp/dp_bsn_scheduler
+    peripheral_group: xsub
+    mm_port_names:
+      - REG_BSN_SCHEDULER_XSUB
+      
+  - peripheral_name: dp/dp_sync_insert_v2
+    mm_port_names:
+      - REG_DP_SYNC_INSERT_V2   
+      
+  - peripheral_name: st/st_xst_for_sdp
+    mm_port_names:
+      - RAM_ST_XSQ
+      
+  - peripheral_name: sdp/sdp_crosslets_subband_select
+    mm_port_names:
+      - REG_CROSSLETS_INFO
+
   #############################################################################
   # BF = Beamformer (from node_sdp_beamformer.vhd)
   #############################################################################
diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/quartus/lofar2_unb2b_sdp_station.sdc b/applications/lofar2/designs/lofar2_unb2b_sdp_station/quartus/lofar2_unb2b_sdp_station.sdc
index a041aae6d83c1972821b3e27f333568006a8c93e..82c0df011c95f6503ba618f2fbe419b37c5765ab 100644
--- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/quartus/lofar2_unb2b_sdp_station.sdc
+++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/quartus/lofar2_unb2b_sdp_station.sdc
@@ -97,8 +97,8 @@ set_clock_groups -asynchronous -group [get_clocks {*xcvr_native_a10_0|g_xcvr_nat
 #-group [get_clocks {inst2|xcvr_4ch_native_phy_inst|xcvr_native_a10_0|g_xcvr_native_insts[?]|rx_pma_clk}] \
 #-group [get_clocks {inst2|xcvr_pll_inst|xcvr_fpll_a10_0|tx_bonding_clocks[0]}]
 
-# false paths added for the jesd test design
-set_false_path -from [get_clocks {*xcvr_fpll_a10_0|outclk2}] -to [get_clocks {*core_pll|link_clk}]
-set_false_path -from [get_clocks {*core_pll|link_clk}] -to [get_clocks {*xcvr_fpll_a10_0|outclk2}]
-set_false_path -from [get_clocks {*xcvr_fpll_a10_0|outclk2}] -to [get_clocks {*core_pll|frame_clk}]
-set_false_path -from [get_clocks {*core_pll|frame_clk}] -to [get_clocks {*xcvr_fpll_a10_0|outclk2}]
+# false paths added for the jesd interface as these clocks are independent.
+set_false_path -from [get_clocks {*xcvr_fpll_a10_0|outclk2}] -to [get_clocks {*iopll_0|link_clk}]
+set_false_path -from [get_clocks {*iopll_0|link_clk}] -to [get_clocks {*xcvr_fpll_a10_0|outclk2}]
+set_false_path -from [get_clocks {*xcvr_fpll_a10_0|outclk2}] -to [get_clocks {*iopll_0|frame_clk}]
+set_false_path -from [get_clocks {*iopll_0|frame_clk}] -to [get_clocks {*xcvr_fpll_a10_0|outclk2}]
diff --git a/applications/lofar2/libraries/sdp/sdp.peripheral.yaml b/applications/lofar2/libraries/sdp/sdp.peripheral.yaml
index d4b798dea57721a7e72ffd009397235d6e6ae11b..66cc0cc8cc6071bfb160780ab3c8db14694e8a7e 100644
--- a/applications/lofar2/libraries/sdp/sdp.peripheral.yaml
+++ b/applications/lofar2/libraries/sdp/sdp.peripheral.yaml
@@ -6,7 +6,7 @@ hdl_library_name: sdp
 hdl_library_description: "Station Digital Processor (SDP) for LOFAR2.0"
 
 peripherals:
-  - peripheral_name: sdp_info    # pi_sdp_info.py ?
+  - peripheral_name: sdp_info    # pi_sdp_info.py
     peripheral_description: "SDP info."
     mm_ports:
       # MM port for sdp_info.vhd
@@ -32,6 +32,23 @@ peripherals:
           - - { field_name: block_period,            mm_width: 16, access_mode: RO, address_offset: 0x4  }
           - - { field_name: beamlet_scale,           mm_width: 16, access_mode: RW, address_offset: 0x0  }
 
+
+  - peripheral_name: sdp_crosslets_subband_select    # pi_sdp_crosslets_info.py 
+    peripheral_description: "SDP crosslets info."
+    mm_ports:
+      # MM port for sdp_info.vhd
+      - mm_port_name: REG_CROSSLETS_INFO
+        mm_port_type: REG
+        mm_port_description: |
+          "The SDP crosslets info contains the step size and 15 offsets, that are used to select a new 
+           crosslet subband for every integration interval"
+        fields:
+          - - { field_name: step, access_mode: RW, address_offset: 0x3C }
+          - - field_name: offset
+              number_of_fields: 15  
+              address_offset: 0x0
+
+
   - peripheral_name: sdp_subband_equalizer    # pi_sdp_subband_equalizer.py
     peripheral_description: "SDP Subband equalizer coefficients."
     parameters:
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd
index ab3d08b91f394964b07440c87d29a487bbe350b4..ae271ee613332fceee60cd871908b4d6690bd0a9 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd
@@ -18,7 +18,7 @@
 --
 -------------------------------------------------------------------------------
 
--- Authors : J Hargreaves, L Hiemstra
+-- Authors : J Hargreaves, L Hiemstra, R van der Walle
 -- Purpose:  
 --   AIT - ADC (Jesd) receiver, input, timing and associated diagnostic blocks
 -- Description:
@@ -124,7 +124,6 @@ ARCHITECTURE str OF node_sdp_adc_input_and_timing IS
   SIGNAL rx_rst                     : STD_LOGIC; 
   SIGNAL rx_sysref                  : STD_LOGIC; 
 
-  SIGNAL arst                       : STD_LOGIC;
   SIGNAL rx_bsn_source_restart      : STD_LOGIC;
 
   -- Sosis and sosi arrays
@@ -213,7 +212,7 @@ BEGIN
   GENERIC MAP (
     g_nof_streams => c_sdp_S_pn, 
     g_nof_words   => c_sdp_V_sample_delay,
-    g_data_w      => c_sdp_W_adc_jesd, 
+    g_data_w      => c_sdp_W_adc, 
     g_use_sync_in => TRUE
   )
   PORT MAP (
@@ -393,7 +392,7 @@ BEGIN
   GENERIC MAP (
     g_cross_clock_domain   => TRUE,
     g_nof_streams          => c_sdp_S_pn,
-    g_symbol_w             => c_sdp_W_adc_jesd,  
+    g_symbol_w             => c_sdp_W_adc,  
     g_nof_symbols_per_data => 1,          -- Wideband factor is 1          
     g_nof_accumulations    => g_bsn_nof_clk_per_sync
   )
@@ -423,7 +422,7 @@ BEGIN
   GENERIC MAP (
     g_technology   => g_technology,
     g_nof_streams  => c_sdp_S_pn,
-    g_data_w       => c_sdp_W_adc_jesd,
+    g_data_w       => c_sdp_W_adc,
     g_buf_nof_data => g_buf_nof_data,
     g_buf_use_sync => TRUE -- when TRUE start filling the buffer at the in_sync, else after the last word was read
   )
@@ -447,47 +446,31 @@ BEGIN
   -- Output Stage
   --   . Thin dual clock fifo to cross from jesd frame clock (rx_clk) to dp_clk domain
   -----------------------------------------------------------------------------
- 
-  gen_dp_fifo_dc : FOR I IN 0 TO c_sdp_S_pn-1 GENERATE
-    u_dp_fifo_dc : ENTITY dp_lib.dp_fifo_dc
-      GENERIC MAP (
-        g_data_w         => c_sdp_W_adc_jesd,
-        g_bsn_w          => c_bs_bsn_w,
-        g_use_empty      => FALSE, --TRUE,
-        g_use_ctrl       => TRUE,
-        g_use_sync       => TRUE,
-        g_use_bsn        => TRUE,
-        g_fifo_size      => c_dp_fifo_dc_size
-      )
-      PORT MAP (
-        wr_rst           => rx_rst,
-        wr_clk           => rx_clk,
-        rd_rst           => dp_rst,
-        rd_clk           => dp_clk,
-        snk_in           => st_sosi_arr(I),
-        src_out          => out_sosi_arr(I)
-      );
-  END GENERATE;
-
-  -- use common dc fifo for restart signal
-  u_common_fifo_dc_restart : ENTITY common_lib.common_fifo_dc
-  GENERIC MAP (
-    g_dat_w     => 1,
-    g_nof_words => c_dp_fifo_dc_size
-  )
-  PORT MAP (
-    rst     => arst,
-    wr_clk  => rx_clk,
-    wr_dat(0)  => rx_bsn_source_restart,
-    wr_req  => bs_sosi.valid,
-    rd_clk  => dp_clk,
-    rd_dat(0)  => dp_bsn_source_restart,
-    rd_req  => '1'
-  );
-
-  arst <= rx_rst OR dp_rst;
+  u_dp_fifo_dc_arr : ENTITY dp_lib.dp_fifo_dc_arr
+    GENERIC MAP (
+      g_nof_streams    => c_sdp_S_pn,
+      g_data_w         => c_sdp_W_adc,
+      g_bsn_w          => c_bs_bsn_w,
+      g_use_empty      => FALSE,
+      g_use_ctrl       => TRUE,
+      g_use_sync       => TRUE,
+      g_use_bsn        => TRUE,
+      g_use_aux        => TRUE,
+      g_fifo_size      => c_dp_fifo_dc_size
+    )
+    PORT MAP (
+      wr_rst           => rx_rst,
+      wr_clk           => rx_clk,
+      rd_rst           => dp_rst,
+      rd_clk           => dp_clk,
+      snk_in_arr       => st_sosi_arr,
+      src_out_arr      => out_sosi_arr,
+      in_aux(0)        => rx_bsn_source_restart,
+      out_aux(0)       => dp_bsn_source_restart
+    );
 
-  -----------------------------------------------------------------------------
+  
+-----------------------------------------------------------------------------
   -- JESD Control register
   -----------------------------------------------------------------------------
   u_mm_jesd_ctrl_reg : ENTITY common_lib.common_reg_r_w
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
index 69356104b26cf09270a30ac75a2be71193b51ce8..a30bf342f7766974952a2bc51bdb9824b95d587d 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
@@ -181,7 +181,8 @@ BEGIN
     g_use_prefilter          => TRUE,
     g_stats_ena              => FALSE,
     g_use_bg                 => FALSE,
-    g_coefs_file_prefix      => c_coefs_file_prefix 
+    g_coefs_file_prefix      => c_coefs_file_prefix,
+    g_restart_on_valid       => FALSE 
   )
   PORT MAP (
     dp_rst             => dp_rst, 
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd
index 5400b70e891a44d1835da0be6150ebb100f02824..6186496de7639b08c7c70444aa041e917c994603 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_crosslets_subband_select.vhd
@@ -167,6 +167,7 @@ BEGIN
   BEGIN
     v := r;
     v.col_select_mosi := c_mem_mosi_rst;
+    v_offsets := r.offsets;
 
     -- start/restart
     IF start_trigger = '1' THEN
diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd
index 79591b0b305fbab6107ee2acb05afe6e709a73ef..ba09970a6f98b5f6896ef7036894ca27fa5b024f 100644
--- a/libraries/base/common/src/vhdl/common_pkg.vhd
+++ b/libraries/base/common/src/vhdl/common_pkg.vhd
@@ -325,36 +325,42 @@ PACKAGE common_pkg IS
   -- . Note that using func_slv_concat() without the BOOLEAN use_* is equivalent to using the 
   --   slv concatenation operator & directly. However this overloaded func_slv_concat() is
   --   still nice to have, because it shows the relation with the inverse func_slv_extract().
-  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a, b, c, d, e, f, g : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e, use_f        : BOOLEAN; a, b, c, d, e, f    : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e               : BOOLEAN; a, b, c, d, e       : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d                      : BOOLEAN; a, b, c, d          : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(  use_a, use_b, use_c                             : BOOLEAN; a, b, c             : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(  use_a, use_b                                    : BOOLEAN; a, b                : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(                                                             a, b, c, d, e, f, g : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(                                                             a, b, c, d, e, f    : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(                                                             a, b, c, d, e       : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(                                                             a, b, c, d          : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(                                                             a, b, c             : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat(                                                             a, b                : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL) RETURN NATURAL;
-  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f        : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w      : NATURAL) RETURN NATURAL;
-  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e               : BOOLEAN; a_w, b_w, c_w, d_w, e_w           : NATURAL) RETURN NATURAL;
-  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d                      : BOOLEAN; a_w, b_w, c_w, d_w                : NATURAL) RETURN NATURAL;
-  FUNCTION func_slv_concat_w(use_a, use_b, use_c                             : BOOLEAN; a_w, b_w, c_w                     : NATURAL) RETURN NATURAL;
-  FUNCTION func_slv_concat_w(use_a, use_b                                    : BOOLEAN; a_w, b_w                          : NATURAL) RETURN NATURAL;
-  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e, use_f        : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w      : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e               : BOOLEAN; a_w, b_w, c_w, d_w, e_w           : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d                      : BOOLEAN; a_w, b_w, c_w, d_w                : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract( use_a, use_b, use_c                             : BOOLEAN; a_w, b_w, c_w                     : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract( use_a, use_b                                    : BOOLEAN; a_w, b_w                          : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract(                                                            a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract(                                                            a_w, b_w, c_w, d_w, e_w, f_w      : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract(                                                            a_w, b_w, c_w, d_w, e_w           : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract(                                                            a_w, b_w, c_w, d_w                : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract(                                                            a_w, b_w, c_w                     : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
-  FUNCTION func_slv_extract(                                                            a_w, b_w                          : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+
+  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e, use_f, use_g, use_h : BOOLEAN; a, b, c, d, e, f, g, h : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e, use_f, use_g        : BOOLEAN; a, b, c, d, e, f, g    : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e, use_f               : BOOLEAN; a, b, c, d, e, f       : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d, use_e                      : BOOLEAN; a, b, c, d, e          : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(  use_a, use_b, use_c, use_d                             : BOOLEAN; a, b, c, d             : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(  use_a, use_b, use_c                                    : BOOLEAN; a, b, c                : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(  use_a, use_b                                           : BOOLEAN; a, b                   : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(                                                                    a, b, c, d, e, f, g, h : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(                                                                    a, b, c, d, e, f, g    : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(                                                                    a, b, c, d, e, f       : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(                                                                    a, b, c, d, e          : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(                                                                    a, b, c, d             : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(                                                                    a, b, c                : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat(                                                                    a, b                   : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g, use_h : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w, h_w : NATURAL) RETURN NATURAL;
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g        : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w      : NATURAL) RETURN NATURAL;
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f               : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w           : NATURAL) RETURN NATURAL;
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e                      : BOOLEAN; a_w, b_w, c_w, d_w, e_w                : NATURAL) RETURN NATURAL;
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d                             : BOOLEAN; a_w, b_w, c_w, d_w                     : NATURAL) RETURN NATURAL;
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c                                    : BOOLEAN; a_w, b_w, c_w                          : NATURAL) RETURN NATURAL;
+  FUNCTION func_slv_concat_w(use_a, use_b                                           : BOOLEAN; a_w, b_w                               : NATURAL) RETURN NATURAL;
+  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e, use_f, use_g, use_h : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w, h_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e, use_f, use_g        : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w      : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e, use_f               : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w           : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d, use_e                      : BOOLEAN; a_w, b_w, c_w, d_w, e_w                : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract( use_a, use_b, use_c, use_d                             : BOOLEAN; a_w, b_w, c_w, d_w                     : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract( use_a, use_b, use_c                                    : BOOLEAN; a_w, b_w, c_w                          : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract( use_a, use_b                                           : BOOLEAN; a_w, b_w                               : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract(                                                                   a_w, b_w, c_w, d_w, e_w, f_w, g_w, h_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract(                                                                   a_w, b_w, c_w, d_w, e_w, f_w, g_w      : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract(                                                                   a_w, b_w, c_w, d_w, e_w, f_w           : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract(                                                                   a_w, b_w, c_w, d_w, e_w                : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract(                                                                   a_w, b_w, c_w, d_w                     : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract(                                                                   a_w, b_w, c_w                          : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
+  FUNCTION func_slv_extract(                                                                   a_w, b_w                               : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR;
   
   FUNCTION TO_UINT(vec : STD_LOGIC_VECTOR) RETURN NATURAL;  -- beware: NATURAL'HIGH = 2**31-1, not 2*32-1, use TO_SINT to avoid warning
   FUNCTION TO_SINT(vec : STD_LOGIC_VECTOR) RETURN INTEGER;
@@ -1508,10 +1514,9 @@ PACKAGE BODY common_pkg IS
     RETURN v_mat;
   END;
   
-  
-  -- Support concatenation of up to 7 slv into 1 slv
-  FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a, b, c, d, e, f, g : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
-    CONSTANT c_max_w : NATURAL := a'LENGTH + b'LENGTH + c'LENGTH + d'LENGTH + e'LENGTH + f'LENGTH + g'LENGTH;
+  -- Support concatenation of up to 8 slv into 1 slv
+  FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, use_g, use_h : BOOLEAN; a, b, c, d, e, f, g, h : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+    CONSTANT c_max_w : NATURAL := a'LENGTH + b'LENGTH + c'LENGTH + d'LENGTH + e'LENGTH + f'LENGTH + g'LENGTH + h'LENGTH;
     VARIABLE v_res   : STD_LOGIC_VECTOR(c_max_w-1 DOWNTO 0) := (OTHERS=>'0');
     VARIABLE v_len   : NATURAL := 0;
   BEGIN
@@ -1522,34 +1527,45 @@ PACKAGE BODY common_pkg IS
     IF use_e = TRUE THEN v_res(e'LENGTH-1 + v_len DOWNTO v_len) := e; v_len := v_len + e'LENGTH; END IF;
     IF use_f = TRUE THEN v_res(f'LENGTH-1 + v_len DOWNTO v_len) := f; v_len := v_len + f'LENGTH; END IF;
     IF use_g = TRUE THEN v_res(g'LENGTH-1 + v_len DOWNTO v_len) := g; v_len := v_len + g'LENGTH; END IF;
+    IF use_h = TRUE THEN v_res(h'LENGTH-1 + v_len DOWNTO v_len) := h; v_len := v_len + h'LENGTH; END IF;
     RETURN v_res(v_len-1 DOWNTO 0);
   END func_slv_concat;
-  
+    
+  FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a, b, c, d, e, f, g : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+  BEGIN
+    RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, use_g, FALSE, a, b, c, d, e, f, g, "0");
+  END func_slv_concat;
+
   FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f : BOOLEAN; a, b, c, d, e, f : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, a, b, c, d, e, f, "0");
+    RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, FALSE, a, b, c, d, e, f, "0", "0");
   END func_slv_concat;
   
   FUNCTION func_slv_concat(use_a, use_b, use_c, use_d, use_e : BOOLEAN; a, b, c, d, e : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, a, b, c, d, e, "0", "0");
+    RETURN func_slv_concat(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, FALSE, a, b, c, d, e, "0", "0", "0");
   END func_slv_concat;
   
   FUNCTION func_slv_concat(use_a, use_b, use_c, use_d : BOOLEAN; a, b, c, d : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_concat(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, a, b, c, d, "0", "0", "0");
+    RETURN func_slv_concat(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, FALSE, a, b, c, d, "0", "0", "0", "0");
   END func_slv_concat;
   
   FUNCTION func_slv_concat(use_a, use_b, use_c : BOOLEAN; a, b, c : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_concat(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, a, b, c, "0", "0", "0", "0");
+    RETURN func_slv_concat(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, FALSE, a, b, c, "0", "0", "0", "0", "0");
   END func_slv_concat;
   
   FUNCTION func_slv_concat(use_a, use_b : BOOLEAN; a, b : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_concat(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a, b, "0", "0", "0", "0", "0");
+    RETURN func_slv_concat(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, a, b, "0", "0", "0", "0", "0", "0");
   END func_slv_concat;
-  
+    
+  FUNCTION func_slv_concat(a, b, c, d, e, f, g, h : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+  BEGIN
+    RETURN func_slv_concat(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, a, b, c, d, e, f, g, h);
+  END func_slv_concat;
+
   FUNCTION func_slv_concat(a, b, c, d, e, f, g : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
   BEGIN
     RETURN func_slv_concat(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, a, b, c, d, e, f, g);
@@ -1580,7 +1596,7 @@ PACKAGE BODY common_pkg IS
     RETURN func_slv_concat(TRUE, TRUE, a, b);
   END func_slv_concat;
   
-  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL) RETURN NATURAL IS
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g, use_h : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w, h_w : NATURAL) RETURN NATURAL IS
     VARIABLE v_len : NATURAL := 0;
   BEGIN
     IF use_a = TRUE THEN v_len := v_len + a_w; END IF;
@@ -1590,36 +1606,42 @@ PACKAGE BODY common_pkg IS
     IF use_e = TRUE THEN v_len := v_len + e_w; END IF;
     IF use_f = TRUE THEN v_len := v_len + f_w; END IF;
     IF use_g = TRUE THEN v_len := v_len + g_w; END IF;
+    IF use_h = TRUE THEN v_len := v_len + h_w; END IF;
     RETURN v_len;
   END func_slv_concat_w;
-  
+    
+  FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL) RETURN NATURAL IS
+  BEGIN
+    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, use_g, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, g_w, 0);
+  END func_slv_concat_w;
+
   FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w : NATURAL) RETURN NATURAL IS
   BEGIN
-    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, 0);
+    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, 0, 0);
   END func_slv_concat_w;
   
   FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d, use_e : BOOLEAN; a_w, b_w, c_w, d_w, e_w : NATURAL) RETURN NATURAL IS
   BEGIN
-    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, 0, 0);
+    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, 0, 0, 0);
   END func_slv_concat_w;
   
   FUNCTION func_slv_concat_w(use_a, use_b, use_c, use_d : BOOLEAN; a_w, b_w, c_w, d_w : NATURAL) RETURN NATURAL IS
   BEGIN
-    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, 0, 0, 0);
+    RETURN func_slv_concat_w(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, 0, 0, 0, 0);
   END func_slv_concat_w;
   
   FUNCTION func_slv_concat_w(use_a, use_b, use_c : BOOLEAN; a_w, b_w, c_w : NATURAL) RETURN NATURAL IS
   BEGIN
-    RETURN func_slv_concat_w(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, 0, 0, 0, 0);
+    RETURN func_slv_concat_w(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, 0, 0, 0, 0, 0);
   END func_slv_concat_w;
   
   FUNCTION func_slv_concat_w(use_a, use_b : BOOLEAN; a_w, b_w : NATURAL) RETURN NATURAL IS
   BEGIN
-    RETURN func_slv_concat_w(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0);
+    RETURN func_slv_concat_w(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0, 0);
   END func_slv_concat_w;
-  
+
   -- extract slv
-  FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
+  FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, use_g, use_h : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w, h_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
     VARIABLE v_w  : NATURAL := 0;
     VARIABLE v_lo : NATURAL := 0;
   BEGIN
@@ -1660,36 +1682,55 @@ PACKAGE BODY common_pkg IS
         IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF;
         IF use_e = TRUE THEN v_lo := v_lo + e_w; END IF;
         IF use_f = TRUE THEN v_lo := v_lo + f_w; END IF;
+      WHEN 7 =>
+        IF use_h = TRUE THEN v_w := h_w; ELSE RETURN c_slv0(h_w-1 DOWNTO 0); END IF;
+        IF use_a = TRUE THEN v_lo := v_lo + a_w; END IF;
+        IF use_b = TRUE THEN v_lo := v_lo + b_w; END IF;
+        IF use_c = TRUE THEN v_lo := v_lo + c_w; END IF;
+        IF use_d = TRUE THEN v_lo := v_lo + d_w; END IF;
+        IF use_e = TRUE THEN v_lo := v_lo + e_w; END IF;
+        IF use_f = TRUE THEN v_lo := v_lo + f_w; END IF;
+        IF use_g = TRUE THEN v_lo := v_lo + g_w; END IF;
       WHEN OTHERS => REPORT "Unknown common_pkg func_slv_extract argument" SEVERITY FAILURE;
     END CASE;
     RETURN vec(v_w-1 + v_lo DOWNTO v_lo);  -- extracted slv
   END func_slv_extract;
-  
+    
+  FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, use_g : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
+  BEGIN
+    RETURN func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, use_g, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, g_w, 0, vec, sel);
+  END func_slv_extract;
+
   FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f : BOOLEAN; a_w, b_w, c_w, d_w, e_w, f_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, 0, vec, sel);
+    RETURN func_slv_extract(use_a, use_b, use_c, use_d, use_e, use_f, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, f_w, 0, 0, vec, sel);
   END func_slv_extract;
   
   FUNCTION func_slv_extract(use_a, use_b, use_c, use_d, use_e : BOOLEAN; a_w, b_w, c_w, d_w, e_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_extract(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, 0, 0, vec, sel);
+    RETURN func_slv_extract(use_a, use_b, use_c, use_d, use_e, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, e_w, 0, 0, 0, vec, sel);
   END func_slv_extract;
   
   FUNCTION func_slv_extract(use_a, use_b, use_c, use_d : BOOLEAN; a_w, b_w, c_w, d_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_extract(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, 0, 0, 0, vec, sel);
+    RETURN func_slv_extract(use_a, use_b, use_c, use_d, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, d_w, 0, 0, 0, 0, vec, sel);
   END func_slv_extract;
   
   FUNCTION func_slv_extract(use_a, use_b, use_c : BOOLEAN; a_w, b_w, c_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_extract(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, 0, 0, 0, 0, vec, sel);
+    RETURN func_slv_extract(use_a, use_b, use_c, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, c_w, 0, 0, 0, 0, 0, vec, sel);
   END func_slv_extract;
   
   FUNCTION func_slv_extract(use_a, use_b : BOOLEAN; a_w, b_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
   BEGIN
-    RETURN func_slv_extract(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0, vec, sel);
+    RETURN func_slv_extract(use_a, use_b, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, a_w, b_w, 0, 0, 0, 0, 0, 0, vec, sel);
   END func_slv_extract;
-  
+    
+  FUNCTION func_slv_extract(a_w, b_w, c_w, d_w, e_w, f_w, g_w, h_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
+  BEGIN
+    RETURN func_slv_extract(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, a_w, b_w, c_w, d_w, e_w, f_w, g_w, h_w, vec, sel);
+  END func_slv_extract;
+
   FUNCTION func_slv_extract(a_w, b_w, c_w, d_w, e_w, f_w, g_w : NATURAL; vec : STD_LOGIC_VECTOR; sel : NATURAL) RETURN STD_LOGIC_VECTOR IS
   BEGIN
     RETURN func_slv_extract(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, a_w, b_w, c_w, d_w, e_w, f_w, g_w, vec, sel);
diff --git a/libraries/base/dp/dp.peripheral.yaml b/libraries/base/dp/dp.peripheral.yaml
index fe7dacf6457d681bd0a7a90f0b4642790b4b3715..c8bdf04b6953d06ddbf0e68f0e4817b8fda350fb 100644
--- a/libraries/base/dp/dp.peripheral.yaml
+++ b/libraries/base/dp/dp.peripheral.yaml
@@ -338,3 +338,18 @@ peripherals:
               address_offset: 0x0
               mm_width: 1
               access_mode: RW
+
+
+  - peripheral_name: dp_sync_insert_v2     # pi_dp_sync_insert_v2.py
+    peripheral_description: "Every nof_blk_per_sync block a sync pulse is created at the output."
+    mm_ports:
+      # MM port for dp_sync_insert_v2.vhd
+      - mm_port_name: REG_DP_SYNC_INSERT_V2
+        mm_port_type: REG
+        mm_port_description: ""
+        fields:
+          - - field_name: nof_blk_per_sync
+              field_description: |
+                "The block counter resets if a sync arrives at the input or when nof_blk_per_sync is reached."
+              address_offset: 0x0
+              access_mode: RW
diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index 35eb45f99ba31ed7867ddb948437b64012e445f1..39ca669c8f184bc1e880bf341840641e720fd402 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -43,8 +43,10 @@ synth_files =
     src/vhdl/dp_shiftreg.vhd
     src/vhdl/dp_fifo_info.vhd
     src/vhdl/dp_fifo_core.vhd
+    src/vhdl/dp_fifo_core_arr.vhd
     src/vhdl/dp_fifo_sc.vhd
     src/vhdl/dp_fifo_dc.vhd
+    src/vhdl/dp_fifo_dc_arr.vhd
     src/vhdl/dp_fifo_dc_mixed_widths.vhd
     src/vhdl/dp_fifo_fill_core.vhd
     src/vhdl/dp_fifo_fill_sc.vhd
@@ -219,6 +221,7 @@ test_bench_files =
     tb/vhdl/tb_dp_fifo_fill_sc.vhd
     tb/vhdl/tb_dp_fifo_info.vhd
     tb/vhdl/tb_dp_fifo_dc.vhd
+    tb/vhdl/tb_dp_fifo_dc_arr.vhd
     tb/vhdl/tb_dp_fifo_dc_mixed_widths.vhd
     tb/vhdl/tb_dp_fifo_sc.vhd
     tb/vhdl/tb_dp_fifo_to_mm.vhd
@@ -291,6 +294,7 @@ test_bench_files =
     tb/vhdl/tb_tb_dp_fifo_fill_sc.vhd
     tb/vhdl/tb_tb_dp_fifo_fill_eop.vhd
     tb/vhdl/tb_tb_dp_fifo_dc.vhd
+    tb/vhdl/tb_tb_dp_fifo_dc_arr.vhd
     tb/vhdl/tb_tb_dp_fifo_dc_mixed_widths.vhd
     tb/vhdl/tb_tb_dp_frame_scheduler.vhd
     tb/vhdl/tb_tb_dp_latency_fifo.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_bsn_source_reg_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_source_reg_v2.vhd
index eb5600b1832a4b802f2271f09ce347e7b3efb083..94535504404868246c757a796885e8c6f53738db 100644
--- a/libraries/base/dp/src/vhdl/dp_bsn_source_reg_v2.vhd
+++ b/libraries/base/dp/src/vhdl/dp_bsn_source_reg_v2.vhd
@@ -82,7 +82,7 @@ ARCHITECTURE rtl OF dp_bsn_source_reg_v2 IS
   CONSTANT c_mm_reg : t_c_mem := (latency  => 1,
                                   adr_w    => 3,
                                   dat_w    => c_word_w,  -- Use MM bus data width = c_word_w = 32 for all MM registers
-                                  nof_dat  => 3**2,
+                                  nof_dat  => 2**3,
                                   init_sl  => '0');
   
   -- Registers in mm_clk domain
diff --git a/libraries/base/dp/src/vhdl/dp_fifo_core_arr.vhd b/libraries/base/dp/src/vhdl/dp_fifo_core_arr.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..83964e22b64cf0a3cdc95ad955082f8752e7d713
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_fifo_core_arr.vhd
@@ -0,0 +1,308 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- 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: R. van der Walle
+-- Purpose:
+--   Provide input ready control and use output ready control to the FIFO.
+--   Pass sop and eop along with the data through the FIFO if g_use_ctrl=TRUE.
+--   Default the RL=1, use g_fifo_rl=0 for a the show ahead FIFO.
+-- Description:
+--   Similar to dp_fifo_core but for multiple synchronous inputs. All data fields
+--   of the in sosi's are concatenated in addition to the the control signals of 
+--   in_sosi_arr(0) and in_aux. So the control signals of in_sosi_arr(1 TO g_nof_streams-1) 
+--   are not used. It is useful to have dp_fifo_core_arr to ensure that all inputs
+--   are crossed over to the rd_clk domain on the same clock cycle, this cannot
+--   be guaranteed when using multiple dp_fifo_core instances. For single clock, 
+--   dp_fifo_core_arr is also useful as it saves logic on the control signals since
+--   it only uses the control signals of in_sosi_arr(0).
+-- Remark:
+-- . dp_fifo_core_arr is not built on top of dp_fifo_core as the input of dp_fifo_core
+--   is of type t_dp_sosi which has a limited size and could cause issues when concatenating
+--   multiple input streams. 
+-- . It is assumed all inputs are synchronous (identical control signals).
+--   If the inputs are asynchronous, better use multiple instances of 
+--   dp_fifo_core.
+-- . It is possible to add additonal signals to the fifo using in_aux/out_aux.
+
+LIBRARY IEEE, common_lib, technology_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+
+ENTITY dp_fifo_core_arr IS
+  GENERIC (
+    g_technology     : NATURAL := c_tech_select_default;
+    g_nof_streams    : NATURAL := 1;
+    g_note_is_ful    : BOOLEAN := TRUE;   -- when TRUE report NOTE when FIFO goes full, fifo overflow is always reported as FAILURE
+    g_use_dual_clock : BOOLEAN := FALSE;
+    g_use_lut_sc     : BOOLEAN := FALSE;  -- when TRUE then force using LUTs instead of block RAM for single clock FIFO (bot available for dual clock FIFO)
+    g_data_w         : NATURAL := 16; -- Should be 2 times the c_complex_w if g_use_complex = TRUE
+    g_data_signed    : BOOLEAN := FALSE; -- TRUE extends g_data_w bits with the sign bit, FALSE pads g_data_w bits with zeros.
+    g_bsn_w          : NATURAL := 1;
+    g_empty_w        : NATURAL := 1;
+    g_channel_w      : NATURAL := 1;
+    g_error_w        : NATURAL := 1;
+    g_aux_w          : NATURAL := 1;
+    g_use_bsn        : BOOLEAN := FALSE;
+    g_use_empty      : BOOLEAN := FALSE;
+    g_use_channel    : BOOLEAN := FALSE;
+    g_use_error      : BOOLEAN := FALSE;
+    g_use_sync       : BOOLEAN := FALSE;
+    g_use_aux        : BOOLEAN := FALSE; -- extra signal in_aux/out_aux
+    g_use_ctrl       : BOOLEAN := TRUE;  -- sop & eop
+    g_use_complex    : BOOLEAN := FALSE; -- TRUE feeds the concatenated complex fields (im & re) through the FIFO instead of the data field.
+    g_fifo_size      : NATURAL := 512;   -- (16+2) * 512 = 1 M9K, g_data_w+2 for sop and eop
+    g_fifo_af_margin : NATURAL := 4;     -- >=4, Nof words below max (full) at which fifo is considered almost full
+    g_fifo_rl        : NATURAL := 1
+  );
+  PORT (
+    wr_rst      : IN  STD_LOGIC;
+    wr_clk      : IN  STD_LOGIC;
+    rd_rst      : IN  STD_LOGIC;
+    rd_clk      : IN  STD_LOGIC;
+    -- Monitor FIFO filling
+    wr_ful      : OUT STD_LOGIC;  -- corresponds to the carry bit of wr_usedw when FIFO is full
+    wr_usedw    : OUT STD_LOGIC_VECTOR(ceil_log2(g_fifo_size)-1 DOWNTO 0);
+    rd_usedw    : OUT STD_LOGIC_VECTOR(ceil_log2(g_fifo_size)-1 DOWNTO 0);
+    rd_emp      : OUT STD_LOGIC;
+    -- ST sink
+    snk_out_arr : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+    snk_in_arr  : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    in_aux      : IN  STD_LOGIC_VECTOR(g_aux_w-1 DOWNTO 0) := (OTHERS => '0');
+    -- ST source
+    src_in_arr  : IN  t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+    src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    out_aux     : OUT STD_LOGIC_VECTOR(g_aux_w-1 DOWNTO 0)
+  );
+END dp_fifo_core_arr;
+
+
+ARCHITECTURE str OF dp_fifo_core_arr IS
+
+  CONSTANT c_use_data         : BOOLEAN := TRUE;
+  CONSTANT c_total_data_w     : NATURAL := g_nof_streams * g_data_w;
+  CONSTANT c_ctrl_w           : NATURAL := 2;  -- sop and eop
+
+  CONSTANT c_complex_w        : NATURAL := smallest(c_dp_stream_dsp_data_w, g_data_w/2);  -- needed to cope with g_data_w > 2*c_dp_stream_dsp_data_w
+   
+  CONSTANT c_fifo_almost_full : NATURAL := g_fifo_size-g_fifo_af_margin;  -- FIFO almost full level for snk_out.ready
+  CONSTANT c_fifo_dat_w       : NATURAL := func_slv_concat_w(c_use_data,     g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux,
+                                                             c_total_data_w, g_bsn_w,   g_empty_w,   g_channel_w,   g_error_w,   1,          c_ctrl_w,   g_aux_w);  -- concat via FIFO
+  
+  SIGNAL nxt_snk_out   : t_dp_siso := c_dp_siso_rst;
+  
+  SIGNAL arst          : STD_LOGIC;
+    
+  TYPE t_wr_data_complex_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(2*c_complex_w-1 DOWNTO 0);
+  TYPE t_rd_data_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
+
+  SIGNAL wr_data_complex_arr : t_wr_data_complex_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL wr_data             : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0);
+  SIGNAL rd_data             : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0);
+  SIGNAL rd_data_arr         : t_rd_data_arr(g_nof_streams-1 DOWNTO 0);
+
+  SIGNAL fifo_wr_dat   : STD_LOGIC_VECTOR(c_fifo_dat_w-1 DOWNTO 0);
+  SIGNAL fifo_wr_req   : STD_LOGIC;
+  SIGNAL fifo_wr_ful   : STD_LOGIC;
+  SIGNAL fifo_wr_usedw : STD_LOGIC_VECTOR(wr_usedw'RANGE);
+  
+  SIGNAL fifo_rd_dat   : STD_LOGIC_VECTOR(c_fifo_dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL fifo_rd_val   : STD_LOGIC;
+  SIGNAL fifo_rd_req   : STD_LOGIC;
+  SIGNAL fifo_rd_emp   : STD_LOGIC;
+  SIGNAL fifo_rd_usedw : STD_LOGIC_VECTOR(rd_usedw'RANGE);
+  
+  SIGNAL wr_sync       : STD_LOGIC_VECTOR(0 DOWNTO 0);
+  SIGNAL rd_sync       : STD_LOGIC_VECTOR(0 DOWNTO 0);
+  SIGNAL wr_ctrl       : STD_LOGIC_VECTOR(1 DOWNTO 0);
+  SIGNAL rd_ctrl       : STD_LOGIC_VECTOR(1 DOWNTO 0);
+  SIGNAL wr_aux        : STD_LOGIC_VECTOR(g_aux_w-1 DOWNTO 0);
+ 
+  SIGNAL rd_siso_arr   : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL rd_sosi_arr   : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);  -- initialize default values for unused sosi fields
+
+  SIGNAL in_aux_sosi   : t_dp_sosi := c_dp_sosi_rst; 
+  SIGNAL out_aux_sosi  : t_dp_sosi := c_dp_sosi_rst; 
+  
+BEGIN
+
+  -- Output monitor FIFO filling
+  wr_ful   <= fifo_wr_ful;
+  wr_usedw <= fifo_wr_usedw;
+  rd_usedw <= fifo_rd_usedw;
+  rd_emp   <= fifo_rd_emp;
+  
+  p_wr_clk: PROCESS(wr_clk, wr_rst)
+  BEGIN
+    IF wr_rst='1' THEN
+      snk_out_arr <= (OTHERS => c_dp_siso_rst);
+    ELSIF rising_edge(wr_clk) THEN
+      FOR I IN 0 TO g_nof_streams-1 LOOP
+        snk_out_arr(I) <= nxt_snk_out;
+      END LOOP;
+    END IF;
+  END PROCESS;
+  
+  wr_sync(0) <= snk_in_arr(0).sync;
+  wr_ctrl    <= snk_in_arr(0).sop & snk_in_arr(0).eop;
+  wr_aux     <= in_aux;
+
+  -- Assign the snk_in_arr data field or concatenated complex fields to the FIFO wr_data depending on g_use_complex
+  gen_streams : FOR I IN 0 TO g_nof_streams-1 GENERATE
+    wr_data_complex_arr(I) <= snk_in_arr(I).im(c_complex_w-1 DOWNTO 0) & snk_in_arr(I).re(c_complex_w-1 DOWNTO 0);  
+    wr_data((I+1) * g_data_w -1 DOWNTO I * g_data_w) <= snk_in_arr(I).data(g_data_w-1 DOWNTO 0) WHEN g_use_complex = FALSE ELSE RESIZE_UVEC(wr_data_complex_arr(I), g_data_w);
+  END GENERATE;
+  -- fifo wr wires
+  fifo_wr_req <= snk_in_arr(0).valid;
+  fifo_wr_dat <= func_slv_concat(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux,
+                                 wr_data,
+                                 snk_in_arr(0).bsn(        g_bsn_w-1 DOWNTO 0),
+                                 snk_in_arr(0).empty(    g_empty_w-1 DOWNTO 0),
+                                 snk_in_arr(0).channel(g_channel_w-1 DOWNTO 0),
+                                 snk_in_arr(0).err(      g_error_w-1 DOWNTO 0),
+                                 wr_sync,
+                                 wr_ctrl,
+                                 wr_aux);
+  
+  -- pass on frame level flow control
+  nxt_snk_out.xon <= src_in_arr(0).xon;
+
+  -- up stream use fifo almost full to control snk_out.ready
+  nxt_snk_out.ready <= '1' WHEN UNSIGNED(fifo_wr_usedw)<c_fifo_almost_full ELSE '0';    
+    
+  gen_common_fifo_sc : IF g_use_dual_clock=FALSE GENERATE
+    u_common_fifo_sc : ENTITY common_lib.common_fifo_sc
+    GENERIC MAP (
+      g_technology => g_technology,
+      g_note_is_ful => g_note_is_ful,
+      g_use_lut   => g_use_lut_sc,
+      g_dat_w     => c_fifo_dat_w,
+      g_nof_words => g_fifo_size
+    )
+    PORT MAP (
+      rst      => rd_rst,
+      clk      => rd_clk,
+      wr_dat   => fifo_wr_dat,
+      wr_req   => fifo_wr_req,
+      wr_ful   => fifo_wr_ful,
+      rd_dat   => fifo_rd_dat,
+      rd_req   => fifo_rd_req,
+      rd_emp   => fifo_rd_emp,
+      rd_val   => fifo_rd_val,
+      usedw    => fifo_rd_usedw
+    );
+    
+    fifo_wr_usedw <= fifo_rd_usedw;
+  END GENERATE;
+  
+  gen_common_fifo_dc : IF g_use_dual_clock=TRUE GENERATE
+    u_common_fifo_dc : ENTITY common_lib.common_fifo_dc
+    GENERIC MAP (
+      g_technology => g_technology,
+      g_dat_w     => c_fifo_dat_w,
+      g_nof_words => g_fifo_size
+    )
+    PORT MAP (
+      rst     => arst,
+      wr_clk  => wr_clk,
+      wr_dat  => fifo_wr_dat,
+      wr_req  => fifo_wr_req,
+      wr_ful  => fifo_wr_ful,
+      wrusedw => fifo_wr_usedw,
+      rd_clk  => rd_clk,
+      rd_dat  => fifo_rd_dat,
+      rd_req  => fifo_rd_req,
+      rd_emp  => fifo_rd_emp,
+      rdusedw => fifo_rd_usedw,
+      rd_val  => fifo_rd_val
+    );
+    
+    arst <= wr_rst OR rd_rst;
+  END GENERATE;
+
+  -- Extract the data from the wide FIFO output SLV. rd_data will be assigned to rd_sosi.data or rd_sosi.im & rd_sosi.re depending on g_use_complex.
+  rd_data <= func_slv_extract(c_use_data,     g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, 
+                              c_total_data_w, g_bsn_w,   g_empty_w,   g_channel_w,   g_error_w,            1, c_ctrl_w,   g_aux_w, 
+                              fifo_rd_dat, 0);
+  
+  -- fifo rd wires
+  -- SISO
+  fifo_rd_req <= rd_siso_arr(0).ready;
+  rd_sync           <= func_slv_extract(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, c_total_data_w, g_bsn_w, g_empty_w, g_channel_w, g_error_w, 1, c_ctrl_w, g_aux_w, fifo_rd_dat, 5);
+  rd_ctrl           <= func_slv_extract(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, c_total_data_w, g_bsn_w, g_empty_w, g_channel_w, g_error_w, 1, c_ctrl_w, g_aux_w, fifo_rd_dat, 6);
+
+  -- AUX
+  in_aux_sosi.data  <= RESIZE_DP_DATA(func_slv_extract(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, c_total_data_w, g_bsn_w, g_empty_w, g_channel_w, g_error_w, 1, c_ctrl_w, g_aux_w, fifo_rd_dat, 7));
+  in_aux_sosi.valid <= fifo_rd_val;
+  out_aux           <= out_aux_sosi.data(g_aux_w-1 DOWNTO 0);
+
+  -- SOSI
+  gen_rd_streams : FOR I IN 0 TO g_nof_streams-1 GENERATE
+    rd_data_arr(I)         <= rd_data( (I+1) * g_data_w -1 DOWNTO I * g_data_w);
+    rd_sosi_arr(I).data    <= RESIZE_DP_SDATA(rd_data_arr(I)) WHEN g_data_signed=TRUE ELSE RESIZE_DP_DATA(rd_data_arr(I));
+    rd_sosi_arr(I).re      <= RESIZE_DP_DSP_DATA(rd_data_arr(I)(  c_complex_w-1 DOWNTO 0));
+    rd_sosi_arr(I).im      <= RESIZE_DP_DSP_DATA(rd_data_arr(I)(2*c_complex_w-1 DOWNTO c_complex_w));
+    rd_sosi_arr(I).bsn     <= RESIZE_DP_BSN(func_slv_extract(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, c_total_data_w, g_bsn_w, g_empty_w, g_channel_w, g_error_w, 1, c_ctrl_w, g_aux_w, fifo_rd_dat, 1));
+    rd_sosi_arr(I).empty   <= RESIZE_DP_EMPTY(func_slv_extract(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, c_total_data_w, g_bsn_w, g_empty_w, g_channel_w, g_error_w, 1, c_ctrl_w, g_aux_w, fifo_rd_dat, 2));
+    rd_sosi_arr(I).channel <= RESIZE_DP_CHANNEL(func_slv_extract(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, c_total_data_w, g_bsn_w, g_empty_w, g_channel_w, g_error_w, 1, c_ctrl_w, g_aux_w, fifo_rd_dat, 3));
+    rd_sosi_arr(I).err     <= RESIZE_DP_ERROR(func_slv_extract(c_use_data, g_use_bsn, g_use_empty, g_use_channel, g_use_error, g_use_sync, g_use_ctrl, g_use_aux, c_total_data_w, g_bsn_w, g_empty_w, g_channel_w, g_error_w, 1, c_ctrl_w, g_aux_w, fifo_rd_dat, 4));
+    rd_sosi_arr(I).sync    <= fifo_rd_val AND rd_sync(0);
+    rd_sosi_arr(I).valid   <= fifo_rd_val;
+    rd_sosi_arr(I).sop     <= fifo_rd_val AND rd_ctrl(1);
+    rd_sosi_arr(I).eop     <= fifo_rd_val AND rd_ctrl(0);
+    
+    u_ready_latency : ENTITY work.dp_latency_adapter
+    GENERIC MAP (
+      g_in_latency  => 1,
+      g_out_latency => g_fifo_rl
+    )
+    PORT MAP (
+      rst       => rd_rst,
+      clk       => rd_clk,
+      -- ST sink
+      snk_out   => rd_siso_arr(I),
+      snk_in    => rd_sosi_arr(I),
+      -- ST source
+      src_in    => src_in_arr(I),
+      src_out   => src_out_arr(I)
+    );
+  END GENERATE;
+
+  -- Using extra dp_latency_adapter for aux signal
+  u_ready_latency_aux : ENTITY work.dp_latency_adapter
+  GENERIC MAP (
+    g_in_latency  => 1,
+    g_out_latency => g_fifo_rl
+  )
+  PORT MAP (
+    rst       => rd_rst,
+    clk       => rd_clk,
+    -- ST sink
+    snk_in    => in_aux_sosi,
+    -- ST source
+    src_in    => src_in_arr(0),
+    src_out   => out_aux_sosi
+  );
+
+END str;
diff --git a/libraries/base/dp/src/vhdl/dp_fifo_dc_arr.vhd b/libraries/base/dp/src/vhdl/dp_fifo_dc_arr.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..e788c2b57913f8cef7638e3288e83aa7ef55da3c
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_fifo_dc_arr.vhd
@@ -0,0 +1,124 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- 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: R. van der Walle
+-- Purpose: DP FIFO array for dual clock (= dc) domain wr and rd.
+-- Description: See dp_fifo_core_arr.vhd.
+
+LIBRARY IEEE,common_lib, technology_lib;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+
+ENTITY dp_fifo_dc_arr IS
+  GENERIC (
+    g_technology     : NATURAL := c_tech_select_default;
+    g_nof_streams    : NATURAL := 1;
+    g_data_w         : NATURAL := 16; -- Should be 2 times the c_complex_w if g_use_complex = TRUE
+    g_bsn_w          : NATURAL := 1;
+    g_empty_w        : NATURAL := 1;
+    g_channel_w      : NATURAL := 1;
+    g_error_w        : NATURAL := 1;
+    g_aux_w          : NATURAL := 1;
+    g_use_bsn        : BOOLEAN := FALSE;
+    g_use_empty      : BOOLEAN := FALSE;
+    g_use_channel    : BOOLEAN := FALSE;
+    g_use_error      : BOOLEAN := FALSE;
+    g_use_sync       : BOOLEAN := FALSE;
+    g_use_aux        : BOOLEAN := FALSE; 
+    g_use_ctrl       : BOOLEAN := TRUE;  -- sop & eop
+    g_use_complex    : BOOLEAN := FALSE; -- TRUE feeds the concatenated complex fields (im & re) through the FIFO instead of the data field.
+    g_fifo_size      : NATURAL := 512;   -- (16+2) * 512 = 1 M9K, g_data_w+2 for sop and eop
+    g_fifo_af_margin : NATURAL := 4;     -- >=4, Nof words below max (full) at which fifo is considered almost full
+    g_fifo_rl        : NATURAL := 1
+  );
+  PORT (
+    wr_rst      : IN  STD_LOGIC;
+    wr_clk      : IN  STD_LOGIC;
+    rd_rst      : IN  STD_LOGIC;
+    rd_clk      : IN  STD_LOGIC;
+    -- Monitor FIFO filling
+    wr_ful      : OUT STD_LOGIC;
+    wr_usedw    : OUT STD_LOGIC_VECTOR(ceil_log2(g_fifo_size)-1 DOWNTO 0);
+    rd_usedw    : OUT STD_LOGIC_VECTOR(ceil_log2(g_fifo_size)-1 DOWNTO 0);
+    rd_emp      : OUT STD_LOGIC;
+    -- ST sink
+    snk_out_arr : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+    snk_in_arr  : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    in_aux      : IN  STD_LOGIC_VECTOR(g_aux_w-1 DOWNTO 0);    
+    -- ST source
+    src_in_arr  : IN  t_dp_siso_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
+    src_out_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    out_aux     : OUT STD_LOGIC_VECTOR(g_aux_w-1 DOWNTO 0)
+  );
+END dp_fifo_dc_arr;
+
+
+ARCHITECTURE str OF dp_fifo_dc_arr IS
+BEGIN
+
+  u_dp_fifo_core_arr : ENTITY work.dp_fifo_core_arr 
+  GENERIC MAP (
+    g_technology     => g_technology,
+    g_nof_streams    => g_nof_streams,
+    g_use_dual_clock => TRUE,
+    g_data_w         => g_data_w,
+    g_bsn_w          => g_bsn_w,
+    g_empty_w        => g_empty_w,
+    g_channel_w      => g_channel_w,
+    g_error_w        => g_error_w,
+    g_aux_w          => g_aux_w,
+    g_use_bsn        => g_use_bsn, 
+    g_use_empty      => g_use_empty,
+    g_use_channel    => g_use_channel,
+    g_use_error      => g_use_error,
+    g_use_sync       => g_use_sync,
+    g_use_aux        => g_use_aux,
+    g_use_ctrl       => g_use_ctrl,
+    g_use_complex    => g_use_complex,
+    g_fifo_size      => g_fifo_size,
+    g_fifo_af_margin => g_fifo_af_margin,
+    g_fifo_rl        => g_fifo_rl
+  )
+  PORT MAP (
+    wr_rst      => wr_rst,
+    wr_clk      => wr_clk,
+    rd_rst      => rd_rst,
+    rd_clk      => rd_clk,
+    -- Monitor FIFO filling
+    wr_ful      => wr_ful,
+    wr_usedw    => wr_usedw,
+    rd_usedw    => rd_usedw,
+    rd_emp      => rd_emp,
+    -- ST sink
+    snk_out_arr => snk_out_arr,
+    snk_in_arr  => snk_in_arr,
+    in_aux      => in_aux,
+    -- ST source
+    src_in_arr  => src_in_arr,
+    src_out_arr => src_out_arr,
+    out_aux     => out_aux
+  );
+
+END str;
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_fifo_dc_arr.vhd b/libraries/base/dp/tb/vhdl/tb_dp_fifo_dc_arr.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..514ebe5def34235e3eab48d0502a83b7c860190d
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_dp_fifo_dc_arr.vhd
@@ -0,0 +1,251 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- 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: R. van der Walle
+-- Purpose: Test dp_fifo_dc_arr.
+-- Description:
+-- Verifies output data and ctrl signals of DUT. This is configurable using generics.
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+
+ENTITY tb_dp_fifo_dc_arr IS
+  GENERIC (
+    -- Try FIFO settings
+    g_dut_nof_streams  : NATURAL := 3;
+    g_dut_wr_clk_freq  : POSITIVE := 2;      -- normalized write clock frequency
+    g_dut_rd_clk_freq  : POSITIVE := 3;      -- normalized read  clock frequency
+    g_dut_use_bsn      : BOOLEAN := TRUE;
+    g_dut_use_empty    : BOOLEAN := TRUE;
+    g_dut_use_channel  : BOOLEAN := TRUE;
+    g_dut_use_sync     : BOOLEAN := TRUE;
+    g_dut_use_ctrl     : BOOLEAN := TRUE;
+    g_dut_use_aux      : BOOLEAN := TRUE;
+    g_dut_out_latency  : NATURAL := 1       -- selectable for dp_fifo_dc_arr: default 1 or 0 for look ahead FIFO
+  );
+END tb_dp_fifo_dc_arr;
+
+
+ARCHITECTURE tb OF tb_dp_fifo_dc_arr IS
+
+  -- See tb_dp_pkg.vhd for explanation and run time, increase the run time by g_dut_rd_clk_freq/g_dut_wr_clk_freq if g_dut_rd_clk_freq>g_dut_wr_clk_freq
+
+  -- DUT
+  CONSTANT c_dut_fifo_size   : NATURAL := 64;
+  CONSTANT c_dut_in_latency  : NATURAL := 1;                 -- fixed for dp_fifo_dc_arr
+  
+  -- Stimuli
+  CONSTANT c_tx_latency     : NATURAL := c_dut_in_latency;   -- TX ready latency of TB
+  CONSTANT c_tx_void        : NATURAL := sel_a_b(c_tx_latency, 1, 0);  -- used to avoid empty range VHDL warnings when c_tx_latency=0
+  CONSTANT c_tx_offset_sop  : NATURAL := 3;
+  CONSTANT c_tx_period_sop  : NATURAL := 7;                  -- sop in data valid cycle 3,  10,  17, ...
+  CONSTANT c_tx_offset_eop  : NATURAL := 5;                  -- eop in data valid cycle   5,  12,  19, ...
+  CONSTANT c_tx_period_eop  : NATURAL := c_tx_period_sop;
+  CONSTANT c_tx_offset_sync : NATURAL := 3;                  -- sync in data valid cycle 3, 20, 37, ...
+  CONSTANT c_tx_period_sync : NATURAL := 17;
+  CONSTANT c_rx_latency     : NATURAL := g_dut_out_latency;  -- RX ready latency from DUT
+  CONSTANT c_verify_en_wait : NATURAL := 20;                 -- wait some cycles before asserting verify enable
+  
+  CONSTANT c_bsn_offset     : NATURAL := 1;
+  CONSTANT c_empty_offset   : NATURAL := 2;
+  CONSTANT c_channel_offset : NATURAL := 3;
+  
+  CONSTANT c_random_w       : NATURAL := 19;
+  
+  SIGNAL tb_end         : STD_LOGIC := '0';
+  SIGNAL wr_clk         : STD_LOGIC := '0';
+  SIGNAL rd_clk         : STD_LOGIC := '0';
+  SIGNAL rst            : STD_LOGIC;
+  SIGNAL sync           : STD_LOGIC;
+  SIGNAL lfsr1          : STD_LOGIC_VECTOR(c_random_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL lfsr2          : STD_LOGIC_VECTOR(c_random_w   DOWNTO 0) := (OTHERS=>'0');
+  
+  SIGNAL cnt_dat        : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
+  SIGNAL cnt_val        : STD_LOGIC;
+  SIGNAL cnt_en         : STD_LOGIC;
+  
+  SIGNAL tx_data        : t_dp_data_arr(0 TO c_tx_latency + c_tx_void)    := (OTHERS=>(OTHERS=>'0'));
+  SIGNAL tx_val         : STD_LOGIC_VECTOR(0 TO c_tx_latency + c_tx_void) := (OTHERS=>'0');
+  
+  SIGNAL in_ready       : STD_LOGIC;
+  SIGNAL in_data        : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL in_bsn         : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL in_empty       : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL in_channel     : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL in_sync        : STD_LOGIC;
+  SIGNAL in_val         : STD_LOGIC;
+  SIGNAL in_sop         : STD_LOGIC;
+  SIGNAL in_eop         : STD_LOGIC;
+  SIGNAL in_aux         : STD_LOGIC;
+  
+  SIGNAL in_siso_arr    : t_dp_siso_arr(g_dut_nof_streams-1 DOWNTO 0);
+  SIGNAL in_sosi_arr    : t_dp_sosi_arr(g_dut_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL out_siso_arr   : t_dp_siso_arr(g_dut_nof_streams-1 DOWNTO 0);
+  SIGNAL out_sosi_arr   : t_dp_sosi_arr(g_dut_nof_streams-1 DOWNTO 0);
+  
+  SIGNAL out_ready      : STD_LOGIC;
+  SIGNAL prev_out_ready : STD_LOGIC_VECTOR(0 TO c_rx_latency);
+  SIGNAL out_data       : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0);
+  SIGNAL out_bsn        : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL out_empty      : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL out_channel    : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL out_sync       : STD_LOGIC;
+  SIGNAL out_val        : STD_LOGIC;
+  SIGNAL out_sop        : STD_LOGIC;
+  SIGNAL out_eop        : STD_LOGIC;
+  SIGNAL out_aux        : STD_LOGIC;
+  SIGNAL prev_out_data  : STD_LOGIC_VECTOR(out_data'RANGE);
+  
+  SIGNAL state          : t_dp_state_enum;
+  
+  SIGNAL verify_en      : STD_LOGIC;
+  SIGNAL verify_done    : STD_LOGIC;
+  
+  SIGNAL exp_data       : STD_LOGIC_VECTOR(c_dp_data_w-1 DOWNTO 0) := TO_UVEC(19000/g_dut_wr_clk_freq, c_dp_data_w);
+  
+  SIGNAL usedw          : STD_LOGIC_VECTOR(ceil_log2(c_dut_fifo_size)-1 DOWNTO 0);
+  
+BEGIN
+
+  wr_clk <= NOT wr_clk OR tb_end AFTER g_dut_rd_clk_freq*clk_period/2;
+  rd_clk <= NOT rd_clk OR tb_end AFTER g_dut_wr_clk_freq*clk_period/2;
+  rst <= '1', '0' AFTER clk_period*7;
+  
+  -- Sync interval
+  proc_dp_sync_interval(wr_clk, sync);
+  
+  -- Input data
+  cnt_val <= in_ready AND cnt_en;
+  
+  proc_dp_cnt_dat(rst, wr_clk, cnt_val, cnt_dat);
+  proc_dp_tx_data(c_tx_latency, rst, wr_clk, cnt_val, cnt_dat, tx_data, tx_val, in_data, in_val);
+  proc_dp_tx_ctrl(c_tx_offset_sync, c_tx_period_sync, in_data, in_val, in_sync);
+  proc_dp_tx_ctrl(c_tx_offset_sop, c_tx_period_sop, in_data, in_val, in_sop);
+  proc_dp_tx_ctrl(c_tx_offset_eop, c_tx_period_eop, in_data, in_val, in_eop);
+
+  in_bsn     <= INCR_UVEC(in_data, c_bsn_offset);
+  in_empty   <= INCR_UVEC(in_data, c_empty_offset);
+  in_channel <= INCR_UVEC(in_data, c_channel_offset);
+  
+  -- Stimuli control
+  proc_dp_count_en(rst, wr_clk, sync, lfsr1, state, verify_done, tb_end, cnt_en);
+  proc_dp_out_ready(rst, wr_clk, sync, lfsr2, out_ready);
+  
+  -- Output verify
+  proc_dp_verify_en(c_verify_en_wait, rst, rd_clk, sync, verify_en);
+  proc_dp_verify_data("out_sosi.data", c_rx_latency, rd_clk, verify_en, out_ready, out_val, out_data, prev_out_data);
+  proc_dp_verify_valid(c_rx_latency, rd_clk, verify_en, out_ready, prev_out_ready, out_val);
+  
+  gen_verify_sync : IF g_dut_use_sync=TRUE GENERATE
+    proc_dp_verify_ctrl(c_tx_offset_sync, c_tx_period_sync, "sync", rd_clk, verify_en, out_data, out_val, out_sync);
+  END GENERATE;
+
+  gen_verify_aux : IF g_dut_use_aux=TRUE GENERATE
+    proc_dp_verify_ctrl(c_tx_offset_sync, c_tx_period_sync, "aux", rd_clk, verify_en, out_data, out_val, out_aux);
+  END GENERATE;  
+
+  gen_verify_ctrl : IF g_dut_use_ctrl=TRUE GENERATE
+    proc_dp_verify_ctrl(c_tx_offset_sop, c_tx_period_sop, "sop", rd_clk, verify_en, out_data, out_val, out_sop);
+    proc_dp_verify_ctrl(c_tx_offset_eop, c_tx_period_eop, "eop", rd_clk, verify_en, out_data, out_val, out_eop);
+  END GENERATE;
+  
+  gen_verify_bsn : IF g_dut_use_bsn=TRUE GENERATE
+    proc_dp_verify_other_sosi("bsn", INCR_UVEC(out_data, c_bsn_offset), rd_clk, verify_en, out_bsn);
+  END GENERATE;
+  
+  gen_verify_empty : IF g_dut_use_empty=TRUE GENERATE
+    proc_dp_verify_other_sosi("empty", INCR_UVEC(out_data, c_empty_offset), rd_clk, verify_en, out_empty);
+  END GENERATE;
+  
+  gen_verify_channel : IF g_dut_use_channel=TRUE GENERATE
+    proc_dp_verify_other_sosi("channel", INCR_UVEC(out_data, c_channel_offset), rd_clk, verify_en, out_channel);
+  END GENERATE;
+  
+  -- Check that the test has ran at all
+  proc_dp_verify_value(e_at_least, rd_clk, verify_done, exp_data, out_data);
+  
+  ------------------------------------------------------------------------------
+  -- DUT dp_fifo_dc_arr
+  ------------------------------------------------------------------------------
+  
+  -- map sl, slv to record
+  in_ready <= in_siso_arr(0).ready;                           -- SISO
+  in_aux   <= in_sync;  -- use sync to test aux data
+  gen_streams : FOR I IN 0 TO g_dut_nof_streams -1 GENERATE
+    in_sosi_arr(I).data(c_dp_data_w-1 DOWNTO 0) <= in_data;     -- SOSI
+    in_sosi_arr(I).bsn(c_dp_bsn_w-1 DOWNTO 0)   <= in_bsn(c_dp_bsn_w-1 DOWNTO 0);
+    in_sosi_arr(I).empty                        <= in_empty(c_dp_empty_w-1 DOWNTO 0);
+    in_sosi_arr(I).channel                      <= in_channel(c_dp_channel_w-1 DOWNTO 0);
+    in_sosi_arr(I).sync                         <= in_sync;
+    in_sosi_arr(I).valid                        <= in_val;
+    in_sosi_arr(I).sop                          <= in_sop;
+    in_sosi_arr(I).eop                          <= in_eop;
+    out_siso_arr(I).ready                       <= out_ready;                               -- SISO
+  END GENERATE;
+  out_data                               <= out_sosi_arr(0).data(c_dp_data_w-1 DOWNTO 0);   -- SOSI
+  out_bsn(c_dp_bsn_w-1 DOWNTO 0)         <= out_sosi_arr(0).bsn(c_dp_bsn_w-1 DOWNTO 0);
+  out_empty(c_dp_empty_w-1 DOWNTO 0)     <= out_sosi_arr(0).empty;
+  out_channel(c_dp_channel_w-1 DOWNTO 0) <= out_sosi_arr(0).channel;
+  out_sync                               <= out_sosi_arr(0).sync;
+  out_val                                <= out_sosi_arr(0).valid;
+  out_sop                                <= out_sosi_arr(0).sop;
+  out_eop                                <= out_sosi_arr(0).eop;
+  
+  dut : ENTITY work.dp_fifo_dc_arr
+  GENERIC MAP (
+    g_nof_streams => g_dut_nof_streams,
+    g_data_w      => c_dp_data_w,
+    g_bsn_w       => c_dp_bsn_w,
+    g_empty_w     => c_dp_empty_w,
+    g_channel_w   => c_dp_channel_w,
+    g_error_w     => 1,
+    g_aux_w       => 1,
+    g_use_bsn     => g_dut_use_bsn,
+    g_use_empty   => g_dut_use_empty,
+    g_use_channel => g_dut_use_channel,
+    g_use_error   => FALSE,
+    g_use_sync    => g_dut_use_sync,
+    g_use_aux     => g_dut_use_aux,
+    g_use_ctrl    => g_dut_use_ctrl,
+    g_fifo_size   => c_dut_fifo_size,
+    g_fifo_rl     => g_dut_out_latency
+  )
+  PORT MAP (
+    wr_rst      => rst,
+    wr_clk      => wr_clk,
+    rd_rst      => rst,
+    rd_clk      => rd_clk,
+    snk_out_arr => in_siso_arr,     -- OUT = request to upstream ST source
+    snk_in_arr  => in_sosi_arr,
+    in_aux(0)   => in_aux,
+    wr_usedw    => usedw,
+    rd_usedw    => OPEN,
+    src_in_arr  => out_siso_arr,    -- IN  = request from downstream ST sink
+    src_out_arr => out_sosi_arr,
+    out_aux(0)  => out_aux
+  );
+
+END tb;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_fifo_dc_arr.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_fifo_dc_arr.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..a5a8429a8e0cefa5eae73755b8df3b083df2b55b
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_fifo_dc_arr.vhd
@@ -0,0 +1,67 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- 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: R. van der Walle
+-- Purpose: Test multiple instances of tb_dp_fifo_dc_arr.
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+
+
+ENTITY tb_tb_dp_fifo_dc_arr IS
+END tb_tb_dp_fifo_dc_arr;
+
+
+ARCHITECTURE tb OF tb_tb_dp_fifo_dc_arr IS
+  SIGNAL tb_end : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+BEGIN
+
+  -- > as 10
+  -- > run g_dut_rd_clk_freq * 330 us                 --> OK
+
+  -- Try FIFO settings : GENERIC MAP (g_dut_wr_clk_freq, g_dut_rd_clk_freq, g_dut_use_bsn, g_dut_use_empty, g_dut_use_channel, g_dut_use_sync, g_dut_use_ctrl, g_dut_out_latency)
+
+  u_use_all_rl_0          : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  0);
+  u_use_all_rl_0_clk_2_1  : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 2, 1, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  0);
+  u_use_all_rl_0_clk_1_2  : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 2, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  0);
+  u_use_all_rl_0_clk_3_2  : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 3, 2, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  0);
+  u_use_all_rl_0_clk_2_3  : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 2, 3, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  0);
+  
+  u_use_all               : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (1, 1, 1, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  1);
+  u_use_all_clk_3_1       : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 3, 1, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  1);
+  u_use_all_clk_1_3       : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 3, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  1);
+  
+  u_use_ctrl_rl_0         : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (1, 1, 1, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  0);
+  u_use_ctrl_rl_0_clk_1_3 : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 3, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  0);
+  u_use_ctrl_rl_0_clk_3_1 : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 3, 1, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  0);
+  u_use_ctrl              : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  1);
+  u_use_ctrl_clk_1_2      : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 2, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  1);
+  u_use_ctrl_clk_2_1      : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 2, 1, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  1);
+  
+  u_no_bsn                : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, FALSE, TRUE,  TRUE,  TRUE,   TRUE,  TRUE,  1);
+  u_no_empty              : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, TRUE,  FALSE, TRUE,  TRUE,   TRUE,  TRUE,  1);
+  u_no_channel            : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, TRUE,  TRUE,  FALSE, TRUE,   TRUE,  TRUE,  1);
+  u_no_sync               : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, TRUE,  TRUE,  TRUE,  FALSE,  TRUE,  TRUE,  1);
+  u_no_ctrl               : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, TRUE,  TRUE,  TRUE,  TRUE,   FALSE, TRUE,  1);
+  u_no_aux                : ENTITY work.tb_dp_fifo_dc_arr GENERIC MAP (3, 1, 1, TRUE,  TRUE,  TRUE,  TRUE,   TRUE,  FALSE, 1);
+  
+END tb;
diff --git a/libraries/dsp/st/src/vhdl/st_xsq_mm_to_dp.vhd b/libraries/dsp/st/src/vhdl/st_xsq_mm_to_dp.vhd
index 0327d6162cd04d63f778800b4d4b2b04422743c3..7ba4f77b717a704897571900528cc7eba1ad8d99 100644
--- a/libraries/dsp/st/src/vhdl/st_xsq_mm_to_dp.vhd
+++ b/libraries/dsp/st/src/vhdl/st_xsq_mm_to_dp.vhd
@@ -62,17 +62,17 @@ ARCHITECTURE rtl OF st_xsq_mm_to_dp IS
     crosslets_index : NATURAL;
     in_a_index      : NATURAL;
     in_b_index      : NATURAL;
+    mm_mosi         : t_mem_mosi;
   END RECORD;
 
-  CONSTANT c_reg_rst : t_reg := (c_dp_sosi_rst, c_dp_sosi_rst, '0', 0, 0, 0);
+  CONSTANT c_reg_rst : t_reg := (c_dp_sosi_rst, c_dp_sosi_rst, '0', 0, 0, 0, c_mem_mosi_rst);
 
   SIGNAL r       : t_reg;
   SIGNAL nxt_r   : t_reg;
-  SIGNAL mm_mosi : t_mem_mosi := c_mem_mosi_rst;
 
 BEGIN
 
-  mm_mosi_arr <= (OTHERS => mm_mosi); -- all mosi are identical.
+  mm_mosi_arr <= (OTHERS => nxt_r.mm_mosi); -- all mosi are identical.
 
   u_sosi : PROCESS(r, mm_miso_arr)
   BEGIN
@@ -98,7 +98,7 @@ BEGIN
   BEGIN
     v := r;
     v.out_sosi_ctrl := c_dp_sosi_rst;
-    mm_mosi.rd <= '0';
+    v.mm_mosi.rd := '0';
 
     -- initiate next block and capture in_sosi strobe
     IF r.busy = '0' AND in_sosi.sop = '1' THEN
@@ -106,8 +106,8 @@ BEGIN
       v.in_sosi_strobe := in_sosi;
     ELSIF r.busy = '1' THEN
       -- continue with block
-      mm_mosi.rd <= '1';
-      mm_mosi.address <= TO_MEM_ADDRESS(r.crosslets_index * g_nof_signal_inputs + r.in_b_index); -- streams iterate over in_b_index
+      v.mm_mosi.rd := '1';
+      v.mm_mosi.address := TO_MEM_ADDRESS(r.crosslets_index * g_nof_signal_inputs + r.in_b_index); -- streams iterate over in_b_index
 
       -- Indices counters to select data order
       IF r.in_b_index < g_nof_signal_inputs - 1 THEN
diff --git a/libraries/dsp/st/src/vhdl/st_xst.vhd b/libraries/dsp/st/src/vhdl/st_xst.vhd
index 6a03cbdc49a6395e090e4222ad068707e7ecdf5b..1a0e75770b67e3cbe3710b95062940c087bf3a82 100644
--- a/libraries/dsp/st/src/vhdl/st_xst.vhd
+++ b/libraries/dsp/st/src/vhdl/st_xst.vhd
@@ -69,9 +69,12 @@ ARCHITECTURE str OF st_xst IS
     busy            : STD_LOGIC;
     in_a_index      : NATURAL;
     in_b_index      : NATURAL;
+    x_sosi_0_re     : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
+    x_sosi_0_im     : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
+    in_a_sosi_arr   : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
   END RECORD;
 
-  CONSTANT c_reg_rst : t_reg := ('0', 0, 0);
+  CONSTANT c_reg_rst : t_reg := ('0', 0, 0, (OTHERS=>(OTHERS => '0')), (OTHERS=>(OTHERS => '0')), (OTHERS => c_dp_sosi_rst) );
 
   SIGNAL r     : t_reg;
   SIGNAL nxt_r : t_reg;
@@ -80,8 +83,6 @@ ARCHITECTURE str OF st_xst IS
   SIGNAL in_b_sosi_arr :  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
   SIGNAL x_sosi_arr :  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
   
-  SIGNAL reg_x_sosi_0_re : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
-  SIGNAL reg_x_sosi_0_im : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
 BEGIN
 
   -- MM -> DP
@@ -103,20 +104,7 @@ BEGIN
 
   -- in_b_sosi_arr = x_sosi_arr
   in_b_sosi_arr <= x_sosi_arr;
-
-  -- Capture x_sosi_arr(0) data
-  reg_x_sosi_0_re(nxt_r.in_b_index) <= x_sosi_arr(0).re;
-  reg_x_sosi_0_im(nxt_r.in_b_index) <= x_sosi_arr(0).im;
-
-  -- reorder x_sosi_arr(0) data to follow in_a_index instead of in_b_index. All sosi in in_a_sosi_arr are identical.
-  p_in_a : PROCESS(x_sosi_arr, reg_x_sosi_0_re, reg_x_sosi_0_im, nxt_r.in_a_index)
-  BEGIN
-    FOR I IN 0 TO g_nof_streams-1 LOOP
-      in_a_sosi_arr(I) <= x_sosi_arr(0);
-      in_a_sosi_arr(I).re <= reg_x_sosi_0_re(nxt_r.in_a_index);
-      in_a_sosi_arr(I).im <= reg_x_sosi_0_im(nxt_r.in_a_index);
-    END LOOP;
-  END PROCESS;
+  in_a_sosi_arr <= nxt_r.in_a_sosi_arr;
 
   -- Register process
   p_reg : PROCESS(dp_rst, dp_clk)
@@ -128,11 +116,19 @@ BEGIN
     END IF;
   END PROCESS;
 
-  -- Combinatorial process to create in_a_index and in_b_index for reoredering x_sosi_arr(0) data.
+  -- Combinatorial process to create in_a_index and in_b_index and reoredering x_sosi_arr(0) data.
   p_comb : PROCESS(r, x_sosi_arr)
     VARIABLE v : t_reg;
+    VARIABLE v_in_a_index      : NATURAL;
+    VARIABLE v_in_b_index      : NATURAL;
+    VARIABLE v_x_sosi_0_re : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
+    VARIABLE v_x_sosi_0_im : t_slv_64_arr(g_nof_signal_inputs-1 DOWNTO 0);
   BEGIN
     v := r;
+    v_in_a_index := r.in_a_index;
+    v_in_b_index := r.in_b_index;
+    v_x_sosi_0_re := r.x_sosi_0_re;
+    v_x_sosi_0_im := r.x_sosi_0_im;
     -- initiate next block
     IF r.busy = '0' AND x_sosi_arr(0).sop = '1' THEN
       v.busy := '1';
@@ -140,22 +136,39 @@ BEGIN
     ELSIF r.busy = '1' THEN
       -- Indices counters to select data order
       IF r.in_b_index < g_nof_signal_inputs - 1 THEN
-        v.in_b_index := r.in_b_index + 1;
+        v_in_b_index := r.in_b_index + 1;
       ELSE
-        v.in_b_index := 0;
+        v_in_b_index := 0;
         IF r.in_a_index < g_nof_signal_inputs - 1 THEN
-          v.in_a_index := r.in_a_index + 1;
+          v_in_a_index := r.in_a_index + 1;
         ELSE
-          v.in_a_index := 0;    
+          v_in_a_index := 0;    
         END IF;      
       END IF;
     END IF;
     -- End of block
     IF x_sosi_arr(0).eop = '1' THEN
       v.busy := '0';
-      v.in_a_index := 0;
-      v.in_b_index := 0;
+      v_in_a_index := 0;
+      v_in_b_index := 0;
     END IF;
+
+    -- Capture x_sosi_arr(0) data
+    v_x_sosi_0_re(v_in_b_index) := x_sosi_arr(0).re;
+    v_x_sosi_0_im(v_in_b_index) := x_sosi_arr(0).im;
+
+    -- reorder x_sosi_arr(0) data to follow in_a_index instead of in_b_index. All sosi in in_a_sosi_arr are identical.
+    FOR I IN 0 TO g_nof_streams-1 LOOP
+      v.in_a_sosi_arr(I) := x_sosi_arr(0);
+      v.in_a_sosi_arr(I).re := v_x_sosi_0_re(v_in_a_index);
+      v.in_a_sosi_arr(I).im := v_x_sosi_0_im(v_in_a_index);
+    END LOOP;
+
+    v.in_a_index := v_in_a_index;
+    v.in_b_index := v_in_b_index;
+    v.x_sosi_0_re := v_x_sosi_0_re;
+    v.x_sosi_0_im := v_x_sosi_0_im;
+
     nxt_r <= v;
   END PROCESS;
 
diff --git a/libraries/dsp/st/st.peripheral.yaml b/libraries/dsp/st/st.peripheral.yaml
index d812b3ac307a4df560f42471719512de0907a2c2..23b11ddf8086194ade628fc1ec8e98d84e14d0b3 100644
--- a/libraries/dsp/st/st.peripheral.yaml
+++ b/libraries/dsp/st/st.peripheral.yaml
@@ -104,3 +104,36 @@ peripherals:
               mm_width: 32
               user_width: g_stat_data_w
               radix: uint64
+
+
+  - peripheral_name: st_xst_for_sdp  # pi_st_xst.py
+    peripheral_description: |
+       "Calculate Crosslets Statistics during a sync interval for the crosslets statistics (XST) in LOFAR2.0 SDP"
+    parameters:
+      # Parameters of pi_st_xst.py, fixed in node_sdp_correlator.vhd / sdp_pkg.vhd
+      - { name: g_nof_streams, value: 9 } # P_sq
+      # Parameters of st_xst.vhd, fixed in node_sdp_correlator.vhd / sdp_pkg.vhd
+      - { name: g_nof_crosslets, value: 1 }  # N_crosslets
+      - { name: g_nof_signal_inputs, value: 12 }  # S_pn = 12
+      - { name: g_in_data_w, value: 16 }  # W_crosslet = 16
+      - { name: g_stat_data_w, value: 64 }  # W_statistic = 64
+      - { name: g_stat_data_sz, value: 2 }  # W_statistic_sz = 2
+    mm_ports:
+      # MM port for st_sst.vhd
+      - mm_port_name: RAM_ST_XSQ
+        mm_port_type: RAM
+        mm_port_description: |
+          "The crosslets statistics per PN are stored in 1 block of 
+           g_nof_crosslets * g_nof_signal_inputs**2 * c_nof_complex * g_stat_data_sz = 1 * 12 * 12 * 2 * 2 = 576 values as:
+
+           (cint64)XST[] = (cint64)XST[crosslets][in A][in B][complex][word]"
+
+        number_of_mm_ports: 1
+        fields:
+          - - field_name: power
+              field_description: ""
+              number_of_fields: 576
+              address_offset: 0x0
+              mm_width: 32
+              user_width: g_stat_data_w
+              radix: cint64_ir
diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
index 5188d93bd2cc1cc01f51cedbd5974a3e48a9eb5e..e63d1860dc244929c83b99be41d886fefff7c7cf 100644
--- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
+++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
@@ -365,7 +365,8 @@ entity wpfb_unit_dev is
     g_use_prefilter     : boolean           := TRUE;
     g_stats_ena         : boolean           := TRUE;    -- Enables the statistics unit
     g_use_bg            : boolean           := FALSE;
-    g_coefs_file_prefix : string            := "data/coefs_wide" -- File prefix for the coefficients files.
+    g_coefs_file_prefix : string            := "data/coefs_wide"; -- File prefix for the coefficients files.
+    g_restart_on_valid  : boolean           := TRUE
    );
   port (
     dp_rst                : in  std_logic := '0';
@@ -383,7 +384,7 @@ entity wpfb_unit_dev is
     in_sosi_arr           : in  t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
     fil_sosi_arr          : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
     out_sosi_arr          : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-    dp_bsn_source_restart : in  std_logic
+    dp_bsn_source_restart : in  std_logic := '0'
   );
 end entity wpfb_unit_dev;
 
@@ -466,7 +467,11 @@ begin
   begin
     v                    := r;
     v.in_sosi_arr        := in_sosi_arr;
-    v.bsn_source_restart := dp_bsn_source_restart;
+    IF g_restart_on_valid THEN
+      v.bsn_source_restart := (NOT r.in_sosi_arr(0).valid) AND in_sosi_arr(0).valid;
+    ELSE
+      v.bsn_source_restart := dp_bsn_source_restart;
+    END IF;
     rin                  <= v;
   end process comb;
 
diff --git a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd
index 61eb02d33154f9d5913df6b2ca23e7f768f61a5b..f789359e1d3410443b43e3e84fa048ff4c21290c 100644
--- a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd
+++ b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd
@@ -330,8 +330,7 @@ BEGIN
     ram_bg_data_mosi   => ram_diag_bg_pfb_mosi,
     ram_bg_data_miso   => ram_diag_bg_pfb_miso,
     in_sosi_arr        => bg_sosi_arr,     
-    out_sosi_arr       => out_sosi_arr,
-    dp_bsn_source_restart => bg_sosi_arr(0).sync
+    out_sosi_arr       => out_sosi_arr
   ); 
 
   time_map : process is
diff --git a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd
index bf8e6cb17e5dfd61f20376510f7a5174c379d400..d385e8f7cfe41cbcfee9ae6e1713c7d263d71383 100644
--- a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd
+++ b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd
@@ -486,8 +486,7 @@ begin
     ram_bg_data_miso   => open,
     in_sosi_arr        => in_sosi_arr,
     fil_sosi_arr       => fil_sosi_arr,
-    out_sosi_arr       => out_sosi_arr,
-    dp_bsn_source_restart => in_sosi_arr(0).sync
+    out_sosi_arr       => out_sosi_arr
   );
   
   p_fil_sosi_arr : process(fil_sosi_arr)