diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd
index 44f22b5dbe0e4c6e6190adda0914f29621adfb2d..ef1bd83f987c514f911651c6752052c0fb215fe6 100644
--- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd
+++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd
@@ -78,7 +78,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
   CONSTANT c_tb_clk_period       : TIME := 100 ps; -- use fast tb_clk to speed up M&C
 
   CONSTANT c_nof_block_per_sync  : NATURAL := 16;
-  CONSTANT c_nof_clk_per_sync    : NATURAL := c_nof_block_per_sync*c_sdp_N_fft; 
+  CONSTANT c_nof_clk_per_sync    : NATURAL := c_nof_block_per_sync*c_sdp_N_fft - (c_sdp_N_fft/2); --15.5 block per sync
   CONSTANT c_pps_period          : NATURAL := c_nof_clk_per_sync;
   CONSTANT c_wpfb_sim            : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync);
    
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 c2b6942f2a7a57349ae260b8f17091191d80ac55..11e331a80e0267d8ef97720e36756d7f188a7426 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
@@ -446,6 +446,7 @@ BEGIN
     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,
diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index 9bceeae7d50a99e04c724a62f37821888af5a23f..07fb20fc3763feb3845b327bf748ccf5e033f7d4 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -134,6 +134,7 @@ synth_files =
     src/vhdl/dp_offload_tx_len_calc.vhd  
     src/vhdl/dp_sync_insert.vhd
     src/vhdl/dp_sync_insert_v2.vhd
+    src/vhdl/dp_sync_recover.vhd
 
     src/vhdl/dp_field_blk.vhd
     src/vhdl/dp_concat_field_blk.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_sync_recover.vhd b/libraries/base/dp/src/vhdl/dp_sync_recover.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..9b556fdb5bdedca21e00ed889a8cba701cd5eda5
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_sync_recover.vhd
@@ -0,0 +1,119 @@
+-------------------------------------------------------------------------------
+--
+-- 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 vd Walle
+-- Purpose : * Insert extra sync pulses. 
+-- Description:
+--   Every nof_blk_per_sync block a sync pulse is created at the output. The block
+--   counter resets if a sync arrives at the input or when nof_blk_per_sync is reached.
+--   nof_blk_per_sync is controllable using M&C.
+--
+-- Remarks:
+-- . There is no support for back pressure. 
+-- . It does not compensate for missing data or extra data. There is NO reset function. It assumes that the 
+--   incoming data is perfectly aligned. Use a dp_sync_checker to assure the incoming data is perfect.      
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE work.dp_stream_pkg.ALL; 
+
+ENTITY dp_sync_recover IS
+  GENERIC (
+    g_initial_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w -1 DOWNTO 0) := (OTHERS => '0');
+    g_nof_data_per_block : POSITIVE := 1
+  );
+  PORT (    
+
+    -- Clocks and reset
+    dp_rst     : IN  STD_LOGIC;
+    dp_clk     : IN  STD_LOGIC;
+    
+    in_sosi    : IN  t_dp_sosi := c_dp_sosi_rst;
+    val        : IN  STD_LOGIC; -- valid at the output
+    -- Streaming source
+    out_sosi   : OUT t_dp_sosi
+  );
+END dp_sync_recover;
+
+
+ARCHITECTURE rtl OF dp_sync_recover IS
+
+  TYPE t_reg IS RECORD  -- local registers
+    bsn_at_sync : STD_LOGIC_VECTOR(c_dp_stream_bsn_w -1 DOWNTO 0);
+    data_cnt    : NATURAL RANGE 0 TO g_nof_data_per_block;
+    out_bsn     : STD_LOGIC_VECTOR(c_dp_stream_bsn_w -1 DOWNTO 0);
+    out_sosi    : t_dp_sosi;
+  END RECORD;
+
+  CONSTANT c_reg_rst  : t_reg := ( (OTHERS => '0'), 0, g_initial_bsn, c_dp_sosi_rst);  
+
+  -- Define the local registers in t_reg record
+  SIGNAL r         : t_reg;
+  SIGNAL nxt_r     : t_reg;
+
+BEGIN
+  
+  out_sosi <= nxt_r.out_sosi;
+  
+  p_clk : PROCESS(dp_rst, dp_clk)
+  BEGIN
+    IF dp_rst='1' THEN
+      r <= c_reg_rst;
+    ELSIF rising_edge(dp_clk) THEN
+      r <= nxt_r;
+    END IF;
+  END PROCESS;  
+
+  p_comb : PROCESS(r, in_sosi, val)
+    VARIABLE v : t_reg;
+  BEGIN
+    v := r;
+    v.out_sosi       := c_dp_sosi_rst;
+    v.out_sosi.valid := val;
+    v.out_sosi.bsn   := r.out_sosi.bsn;
+
+    IF in_sosi.sync = '1' THEN
+      v.bsn_at_sync  := in_sosi.bsn;        
+    END IF;
+    IF val = '1' THEN
+      v.data_cnt := r.data_cnt + 1;
+      IF r.data_cnt = 0 THEN
+        v.out_sosi.sop := '1';
+        v.out_bsn := STD_LOGIC_VECTOR(UNSIGNED(r.out_bsn) + 1);
+        v.out_sosi.bsn := r.out_bsn;
+        IF r.out_bsn = r.bsn_at_sync THEN
+        v.out_sosi.sync := '1';
+        END IF;
+      END IF;
+      IF r.data_cnt = g_nof_data_per_block-1 THEN
+        v.data_cnt := 0;
+        v.out_sosi.eop := '1';
+      END IF;
+    END IF;
+ 
+    nxt_r <= v;
+  END PROCESS;  
+
+END rtl;
diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
index 67d65dac3c7cb640832ca576997c8cf46634ec0f..071a6785a0266c3da24ea15d4c09cd7ffcf9f831 100644
--- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
+++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
@@ -451,6 +451,7 @@ architecture str of wpfb_unit_dev is
   signal fft_out_sosi_arr    : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst);
   
   signal pfb_out_sosi_arr    : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst);
+  signal ctrl_pfb_out_sosi   : t_dp_sosi := c_dp_sosi_rst;
   
   type reg_type is record
     in_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
@@ -624,32 +625,29 @@ begin
     fft_out_sosi.bsn   <= r.in_sosi_arr(0).bsn;   
     fft_out_sosi.valid <= fft_out_val_arr(0);     
     
-    wire_fft_out_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate
-      fft_out_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(fft_out_re_arr(I));
-      fft_out_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(fft_out_im_arr(I));
-      fft_out_sosi_arr(I).valid <=                    fft_out_val_arr(I);
-    end generate;
-    
-    u_dp_block_gen_valid_arr : ENTITY dp_lib.dp_block_gen_valid_arr
-    GENERIC MAP (
-      g_nof_streams         => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
-      g_nof_data_per_block  => c_nof_valid_per_block,
-      g_nof_blk_per_sync    => g_wpfb.nof_blk_per_sync,
-      g_check_input_sync    => false,
-      g_nof_pages_bsn       => 1,
-      g_restore_global_bsn  => true
+    u_dp_sync_recover : ENTITY dp_lib.dp_sync_recover
+    GENERIC MAP(
+      g_nof_data_per_block => c_nof_valid_per_block
     )
     PORT MAP (
-      rst         => dp_rst,
-      clk         => dp_clk,
-      -- Streaming sink
-      snk_in      => fft_out_sosi,
-      snk_in_arr  => fft_out_sosi_arr,
-      -- Streaming source
-      src_out_arr => pfb_out_sosi_arr,
-      -- Control
-      enable      => '1'
+      dp_rst => dp_rst,
+      dp_clk => dp_clk,
+
+      in_sosi => fft_out_sosi,
+      val     => fft_out_sosi.valid,
+
+      out_sosi => ctrl_pfb_out_sosi
     );
+
+    wire_pfb_out_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate
+      pfb_out_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(fft_out_re_arr(I));
+      pfb_out_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(fft_out_im_arr(I));
+      pfb_out_sosi_arr(I).valid <= ctrl_pfb_out_sosi.valid;
+      pfb_out_sosi_arr(I).sync  <= ctrl_pfb_out_sosi.sync;
+      pfb_out_sosi_arr(I).bsn   <= ctrl_pfb_out_sosi.bsn;
+      pfb_out_sosi_arr(I).sop   <= ctrl_pfb_out_sosi.sop;
+      pfb_out_sosi_arr(I).eop   <= ctrl_pfb_out_sosi.eop;
+    end generate;
   end generate;
 
   ----------------------------------------------------------------------------