diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index 521d6753de27da8f29ca2d24d0edfb29bdd8eaa2..098d6d381b01823000c3e01c3cccaee5e8b57105 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -61,6 +61,7 @@ synth_files =
     src/vhdl/dp_fifo_from_mm_reg.vhd
     src/vhdl/dp_fifo_monitor.vhd
     src/vhdl/dp_fifo_monitor_arr.vhd
+    src/vhdl/dp_block_validate_err.vhd
     src/vhdl/mms_dp_fifo_to_mm.vhd
     src/vhdl/mms_dp_fifo_from_mm.vhd
     src/vhdl/mms_dp_fifo_fill.vhd
@@ -195,6 +196,7 @@ test_bench_files =
     
     tb/vhdl/tb_dp_block_select.vhd
     tb/vhdl/tb_dp_block_validate_length.vhd
+    tb/vhdl/tb_dp_block_validate_err.vhd
     tb/vhdl/tb_dp_block_reshape.vhd
     tb/vhdl/tb_dp_block_reshape_sync.vhd
     tb/vhdl/tb_dp_block_gen.vhd
@@ -275,6 +277,7 @@ test_bench_files =
 
     tb/vhdl/tb_tb_dp_block_select.vhd
     tb/vhdl/tb_tb_dp_block_validate_length.vhd
+    tb/vhdl/tb_tb_dp_block_validate_err.vhd
     tb/vhdl/tb_tb_dp_block_reshape.vhd
     tb/vhdl/tb_tb_dp_block_reshape_sync.vhd
     tb/vhdl/tb_tb_dp_block_gen.vhd
@@ -341,6 +344,7 @@ regression_test_vhdl =
     
     tb/vhdl/tb_tb_dp_block_select.vhd
     tb/vhdl/tb_tb_dp_block_validate_length.vhd
+    tb/vhdl/tb_tb_dp_block_validate_err.vhd
     tb/vhdl/tb_tb_dp_block_reshape.vhd
     tb/vhdl/tb_tb_dp_block_reshape_sync.vhd
     tb/vhdl/tb_tb_dp_block_gen.vhd
diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd
index ff4f40a6cad3f03bd41ce08cf4548e05f639e016..dd3ce64854e4f42124a9787d1a0ae0bbcfc5ef0f 100644
--- a/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd
+++ b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd
@@ -21,116 +21,272 @@
 -------------------------------------------------------------------------------
 -- Author: R vd Walle
 -- Purpose:
---   Validate the length of a DP block.
+--   Validate the error field of a DP block.
 -- Description:
--- The dp_block_validate_length.vhd checks whether the in_sosi block has the 
--- expected length given by g_expected_length. The block length is defined by 
--- the number of valid from sop to eop. The tasks of the 
--- dp_block_validate_length.vhd are:
--- . Default all in_sosi fields are passed on to the out_sosi.
--- . If the input block length differs from g_expected_length, then the bit at
---   bit index g_err_bi in the out_sosi.err field is forced to 1, else the 
---   out_sosi.err field passes on the in_sosi.err field.
--- . If the input block length > g_expected_length, then the out_sosi block 
---   length is restricted to g_expected_length, by inserting an eop and 
---   discarding the remaining data and eop information from the in_sosi.
+--  . The dp_block_validate_err.vhd checks the in_sosi.err field at the end of a
+--    block. Therefore the block needs to be stored, before it can be validated. 
+--    The stored block is then either forwarded when the in_sosi.err = 0, or else 
+--    it is discarded. 
+--  . The dp_block_validate_err.vhd has to maintain the a total number of in_sosi 
+--    blocks counter and a number of discarded blocks counter per bit in the 
+--    in_sosi.err field. The counters can be read via the MM interface. 
 -- Remarks:
--- - This component supports flow control and was designed by keeping the functional
---   state registers and the pipeline registers seperate. Therefore the function is 
---   implemented using combinatorial logic and local state registers to keep its
---   state. The combinatorial function output preserves the snk_in ready latency and
---   is pipelined using dp_pipeline to ease timing closure on the output.
+--   . Note that a block can have more than one bit set in the err field. This can
+--     result in multiple counters increasing per block. Therefore, it should not be 
+--     assumed that the sum of the err counters is the total amount of discarded
+--     blocks.
+--   . Note that dp_fifo_fill_eop cannot handle continues stream of blocks without 
+--     a gap between blocks the dp_fifo_fill_eop needs 1 cycle to process a block.
+--     Streaming without gaps may cause the fifo to overflow. Bursts of blocks
+--     can be handled by increasing g_fifo_size.
+-------------------------------------------------------------------------------
+-- REGMAP
+-------------------------------------------------------------------------------
+--  wi                  Bits    R/W Name                                 Default                                         
+--  ====================================================================================
+--  0                   [31..0] RO  err_count_index_0                     0x0    
+--  1                   [31..0] RO  err_count_index_1                     0x0   
+--  .                    .      .   .                                     . 
+--  .                    .      .   .                                     . 
+--  .                    .      .   .                                     . 
+--  g_nof_err_counts-1  [31..0] RO  err_count_index_[g_nof_err_counts-1]  0x0           
+--  g_nof_err_counts    [31..0] RO  total_block_count                     0x0           
+--  ====================================================================================
 -------------------------------------------------------------------------------
-
 LIBRARY IEEE, common_lib;
 USE IEEE.std_logic_1164.all;
+USE IEEE.numeric_std.all;
 USE work.dp_stream_pkg.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
 
-ENTITY dp_block_validate_length IS
+ENTITY dp_block_validate_err IS
   GENERIC (
-    g_err_bi          : NATURAL := 0;   -- bit index in error field
-    g_expected_length : NATURAL := 255 
+    g_cnt_w              : NATURAL  := c_word_w; -- max is c_word_w due to mm word width
+    g_max_block_size     : POSITIVE := 250;
+    g_min_block_size     : POSITIVE := 1;
+    g_nof_err_counts     : NATURAL  := 8;
+    -- fifo generics
+    g_fifo_size          : POSITIVE := 256;
+    g_data_w             : NATURAL  := 16;
+    g_bsn_w              : NATURAL  := 1;
+    g_empty_w            : NATURAL  := 1;
+    g_channel_w          : NATURAL  := 1;
+    g_use_bsn            : BOOLEAN  := FALSE;
+    g_use_empty          : BOOLEAN  := FALSE;
+    g_use_channel        : BOOLEAN  := FALSE;
+    g_use_sync           : BOOLEAN  := FALSE;
+    g_use_complex        : BOOLEAN  := FALSE
   );
   PORT (
-    rst          : IN  STD_LOGIC;
-    clk          : IN  STD_LOGIC;
+    dp_rst       : IN  STD_LOGIC;
+    dp_clk       : IN  STD_LOGIC;
     -- ST sink
-    snk_out      : OUT t_dp_siso;
+    snk_out      : OUT t_dp_siso := c_dp_siso_rdy;
     snk_in       : IN  t_dp_sosi;
     -- ST source
     src_in       : IN  t_dp_siso := c_dp_siso_rdy;
-    src_out      : OUT t_dp_sosi
+    src_out      : OUT t_dp_sosi;
+
+    mm_rst       : IN  STD_LOGIC;
+    mm_clk       : IN  STD_LOGIC;
+
+    reg_mosi     : IN  t_mem_mosi := c_mem_mosi_rst;
+    reg_miso     : OUT t_mem_miso := c_mem_miso_rst
   );
-END dp_block_validate_length;
+END dp_block_validate_err;
 
+ARCHITECTURE rtl OF dp_block_validate_err IS
 
-LIBRARY IEEE, common_lib;
-USE IEEE.std_logic_1164.all;
-USE work.dp_stream_pkg.ALL;
+  CONSTANT c_max_cnt    : STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0) := (OTHERS => '1');
+  CONSTANT c_nof_err_ok : NATURAL := ceil_div(g_max_block_size, g_min_block_size);
+
+  TYPE t_cnt_err_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0);
+
+  -- Define the actual size of the MM slave register
+  CONSTANT c_mm_reg : t_c_mem := (latency  => 1,
+                                  adr_w    => ceil_log2(g_nof_err_counts+1),
+                                  dat_w    => c_word_w,       -- Use MM bus data width = c_word_w = 32 for all MM registers
+                                  nof_dat  => g_nof_err_counts+1,
+                                  init_sl  => '0');
+
+  -- Registers in st_clk domain
+  SIGNAL count_reg     : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
 
-ARCHITECTURE rtl OF dp_block_validate_length IS
+  SIGNAL cnt_clr      : STD_LOGIC;
+  SIGNAL cnt_blk      : STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0);
+  SIGNAL cnt_blk_en   : STD_LOGIC;
+  SIGNAL cnt_err      : t_cnt_err_arr(g_nof_err_counts-1 DOWNTO 0);
+  SIGNAL cnt_err_en   : STD_LOGIC_VECTOR(g_nof_err_counts-1 DOWNTO 0);
 
-  SIGNAL cnt_reg      : NATURAL;
-  SIGNAL cnt          : NATURAL;
-  SIGNAL block_sosi   : t_dp_sosi;
+  SIGNAL err_ok          : STD_LOGIC;
+  SIGNAL err_ok_reg      : STD_LOGIC;
+  SIGNAL fifo_err_ok     : STD_LOGIC;
+  SIGNAL fifo_err_ok_val : STD_LOGIC;
+  SIGNAL out_valid       : STD_LOGIC;
+  SIGNAL out_valid_reg   : STD_LOGIC;
+
+  SIGNAL block_sosi       : t_dp_sosi;
+  SIGNAL block_siso       : t_dp_siso;
+  SIGNAL block_sosi_piped : t_dp_sosi;
   
 BEGIN
 
-  p_clk : PROCESS(rst, clk)
-  BEGIN
-    IF rst='1' THEN
-      cnt_reg      <= 0;
-    ELSIF rising_edge(clk) THEN
-      cnt_reg      <= cnt;
-    END IF;
-  END PROCESS;
+  u_common_spulse_cnt_clr : ENTITY common_lib.common_spulse
+  PORT MAP (
+    in_rst    => mm_rst,
+    in_clk    => mm_clk,
+    in_pulse  => reg_mosi.rd,
+    in_busy   => OPEN,
+    out_rst   => dp_rst,
+    out_clk   => dp_clk,
+    out_pulse => cnt_clr
+  );
 
-  -- Count valid per block
-  p_cnt : PROCESS(snk_in, cnt_reg)
-  BEGIN
-    cnt <= cnt_reg;
-    IF snk_in.sop='1' THEN
-      cnt <= 0;
-    ELSIF snk_in.valid='1' THEN
-      cnt <= cnt_reg + 1;
-    END IF;
-  END PROCESS;
+  -- block counter
+  cnt_blk_en <= snk_in.eop WHEN UNSIGNED(cnt_blk) < UNSIGNED(c_max_cnt) ELSE '0';
+  u_blk_counter : ENTITY common_lib.common_counter
+  GENERIC MAP (
+    g_width => g_cnt_w
+  )
+  PORT MAP ( 
+    rst => dp_rst,
+    clk => dp_clk,
 
-  -- Resize snk_in combinatorially into block_sosi, so no impact on RL
-  p_block_sosi : PROCESS(snk_in, cnt)
-  BEGIN
-    -- Default keep snk_in info and data fields
-    block_sosi       <= snk_in;
-    IF snk_in.valid='1' THEN
-      -- Set output eop, info @ eop gets lost if g_expected_length < actual block size
-      IF snk_in.eop = '1' XOR cnt = g_expected_length-1 THEN
-        block_sosi.err(g_err_bi) <= '1';
-      END IF;
-        
-      IF cnt = g_expected_length-1 THEN
-        block_sosi.eop   <= '1';
-      END IF;
-
-      IF cnt > g_expected_length-1 THEN
-        block_sosi <= c_dp_sosi_rst;
-      END IF;
-    END IF;
-  END PROCESS;
+    cnt_clr => cnt_clr, 
+    cnt_en  => cnt_blk_en,
+    count   => cnt_blk
+  );
+
+  -- error counters
+  gen_err_counters : FOR I IN 0 TO g_nof_err_counts-1 GENERATE
+    cnt_err_en(I) <= snk_in.eop AND snk_in.err(I) WHEN UNSIGNED(cnt_err(I)) < UNSIGNED(c_max_cnt) ELSE '0';
+    u_blk_counter : ENTITY common_lib.common_counter
+    GENERIC MAP (
+      g_width => g_cnt_w
+    )
+    PORT MAP ( 
+      rst => dp_rst,
+      clk => dp_clk,
+  
+      cnt_clr => cnt_clr, 
+      cnt_en  => cnt_err_en(I),
+      count   => cnt_err(I)
+    );
+  END GENERATE;
+
+  -- Register mapping
+  -- first registers are the error counters
+  gen_reg : FOR I IN 0 TO g_nof_err_counts-1 GENERATE
+    count_reg((I + 1) * c_word_w - 1 DOWNTO I * c_word_w) <= RESIZE_UVEC(cnt_err(I), c_word_w);
+  END GENERATE;
+  -- The last register is the block counter.
+  count_reg((g_nof_err_counts+1) * c_word_w - 1 DOWNTO g_nof_err_counts * c_word_w ) <= RESIZE_UVEC(cnt_blk, c_word_w);  
+
+  u_reg : ENTITY common_lib.common_reg_r_w_dc
+  GENERIC MAP (
+    g_cross_clock_domain => TRUE,
+    g_readback           => FALSE,
+    g_reg                => c_mm_reg
+  )
+  PORT MAP (
+    -- Clocks and reset
+    mm_rst      => mm_rst,
+    mm_clk      => mm_clk,
+    st_rst      => dp_rst,
+    st_clk      => dp_clk,
+    
+    -- Memory Mapped Slave in mm_clk domain
+    sla_in      => reg_mosi,
+    sla_out     => reg_miso,
+    
+    -- MM registers in st_clk domain
+    reg_wr_arr  => OPEN,
+    reg_rd_arr  => OPEN,
+    in_reg      => count_reg,   -- read only
+    out_reg     => OPEN       -- no write
+  );
+
+  u_fifo_fill_eop : ENTITY work.dp_fifo_fill_eop
+  GENERIC MAP (
+    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_use_bsn      => g_use_bsn,  
+    g_use_empty    => g_use_empty,  
+    g_use_channel  => g_use_channel,  
+    g_use_sync     => g_use_sync,  
+    g_use_complex  => g_use_complex,  
+    g_fifo_fill    => g_max_block_size,  
+    g_fifo_size    => g_fifo_size  
+  )
+  PORT MAP (
+    wr_rst => dp_rst,        
+    wr_clk => dp_clk,     
+    rd_rst => dp_rst,     
+    rd_clk => dp_clk,     
+    
+    -- ST sink
+    snk_out => snk_out,    
+    snk_in  => snk_in,    
+    -- ST source
+    src_in  => block_siso,    
+    src_out => block_sosi  
+  );
 
-  -- Register block_sosi to easy timing closure
   u_pipeline : ENTITY work.dp_pipeline
   GENERIC MAP (
     g_pipeline   => 1  -- 0 for wires, > 0 for registers, 
   )
   PORT MAP (
-    rst          => rst,
-    clk          => clk,
+    rst          => dp_rst,
+    clk          => dp_clk,
     -- ST sink
-    snk_out      => snk_out,
+    snk_out      => block_siso,
     snk_in       => block_sosi,
     -- ST source
     src_in       => src_in,
-    src_out      => src_out
+    src_out      => block_sosi_piped
   );
+
+  p_dp_clk : PROCESS(dp_rst, dp_clk)
+  BEGIN
+    IF dp_rst='1' THEN
+      err_ok_reg      <= '0';
+      out_valid_reg   <= '0';
+    ELSIF rising_edge(dp_clk) THEN
+      err_ok_reg      <= err_ok;
+      out_valid_reg   <= out_valid;
+    END IF;
+  END PROCESS;
+
+  err_ok <= NOT vector_or(snk_in.err(g_nof_err_counts-1 DOWNTO 0)) WHEN snk_in.eop = '1' ELSE err_ok_reg;
+
+  u_fifo_err_ok : ENTITY common_lib.common_fifo_sc
+  GENERIC MAP (
+    g_dat_w => 1,
+    g_nof_words => c_nof_err_ok
+  )
+  PORT MAP (
+    rst       => dp_rst,
+    clk       => dp_clk,
+    wr_dat(0) => err_ok,
+    wr_req    => snk_in.eop,
+    rd_req    => block_sosi.sop,
+    rd_dat(0) => fifo_err_ok,
+    rd_val    => fifo_err_ok_val
+  );
+
+  out_valid <= fifo_err_ok WHEN fifo_err_ok_val = '1' ELSE out_valid_reg;
+
+  p_src_out : PROCESS(block_sosi_piped, out_valid)
+  BEGIN
+    src_out       <= block_sosi_piped;
+    src_out.valid <= block_sosi_piped.valid AND out_valid;
+    src_out.sop   <= block_sosi_piped.sop   AND out_valid;
+    src_out.eop   <= block_sosi_piped.eop   AND out_valid;
+    src_out.sync  <= block_sosi_piped.sync  AND out_valid;
+  END PROCESS;
   
 END rtl;
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_err.vhd b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_err.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..a560cf8d1ec0ea5b08a46769060b62adf48c7bdf
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_err.vhd
@@ -0,0 +1,241 @@
+-------------------------------------------------------------------------------
+--
+-- 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:
+-- Test bench for dp_block_validate_err.
+-- Description:
+-- Verifies the output sosi of the DUT with the expected sosi. 
+-- The TB also reads the register values via MM and verifies them against the 
+-- expected values.  
+-- Usage:
+-- . as 5
+-- . run -all
+
+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 common_lib.tb_common_mem_pkg.ALL;
+USE common_lib.common_str_pkg.ALL;
+USE common_lib.common_lfsr_sequences_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+
+ENTITY tb_dp_block_validate_err IS
+  GENERIC (
+    g_nof_blocks_per_sync  : NATURAL := 5;
+    g_nof_data_per_blk     : NATURAL := 9; 
+    g_max_block_size       : NATURAL := 9;
+    g_nof_err_counts       : NATURAL := 8;
+    g_gap_size             : NATURAL := 4;
+    g_cnt_w                : NATURAL := 3 
+  );
+END tb_dp_block_validate_err;
+
+
+ARCHITECTURE tb OF tb_dp_block_validate_err IS
+
+  ------------------------------------------------------------------------------
+  -- Clock & reset
+  ------------------------------------------------------------------------------
+  CONSTANT c_dp_clk_period  : TIME := 5 ns;
+  CONSTANT c_mm_clk_period  : TIME := 10 ns;
+
+  CONSTANT c_dut_pipeline             : NATURAL := g_nof_data_per_blk + 3;
+  CONSTANT c_nof_sync                 : NATURAL := 5;
+  CONSTANT c_nof_blk                  : NATURAL := g_nof_blocks_per_sync * c_nof_sync;
+  CONSTANT c_max_cnt                  : NATURAL := 2**g_cnt_w -1;
+  CONSTANT c_mm_addr_dp_blk_cnt       : NATURAL := g_nof_err_counts;
+  CONSTANT c_exp_blk_cnt : NATURAL := sel_a_b(c_nof_blk < c_max_cnt, c_nof_blk, c_max_cnt);
+  
+  SIGNAL dp_clk            : STD_LOGIC := '1';
+  SIGNAL mm_clk            : STD_LOGIC := '1';
+  SIGNAL rst            : STD_LOGIC := '1';
+  SIGNAL tb_end         : STD_LOGIC := '0';
+  
+  SIGNAL stimuli_end         : STD_LOGIC;
+  SIGNAL stimuli_sosi        : t_dp_sosi;
+  SIGNAL stimuli_siso        : t_dp_siso;
+  SIGNAL stimuli_cnt_reg     : NATURAL;
+  SIGNAL stimuli_cnt         : NATURAL;
+  SIGNAL verify_sosi         : t_dp_sosi;
+  SIGNAL verify_siso         : t_dp_siso := c_dp_siso_rdy;
+  SIGNAL reference_cnt       : NATURAL;
+  SIGNAL reference_cnt_reg   : NATURAL;
+  SIGNAL reference_sosi      : t_dp_sosi;
+  SIGNAL reference_siso      : t_dp_siso := c_dp_siso_rdy;
+  SIGNAL reg_mosi            : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL reg_miso            : t_mem_miso := c_mem_miso_rst;
+BEGIN
+  
+  ------------------------------------------------------------------------------
+  -- Clock & reset
+  ------------------------------------------------------------------------------
+  dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2;
+  mm_clk <= (NOT mm_clk) OR tb_end AFTER c_mm_clk_period/2;
+  rst <= '1', '0' AFTER c_dp_clk_period*7;
+  
+  ------------------------------------------------------------------------------
+  -- Stimuli: 
+  ------------------------------------------------------------------------------
+
+  -- Generate snk_in with data frames
+  u_stimuli : ENTITY work.dp_stream_stimuli
+  GENERIC MAP (
+    g_sync_period => g_nof_blocks_per_sync,
+    g_nof_repeat  => g_nof_blocks_per_sync * c_nof_sync,
+    g_pkt_len     => g_nof_data_per_blk,
+    g_pkt_gap     => g_gap_size,
+    g_err_init    => 0,
+    g_err_incr    => 1
+  )
+  PORT MAP (
+    rst               => rst,
+    clk               => dp_clk,
+  
+    -- Generate stimuli
+    src_in            => stimuli_siso,
+    src_out           => stimuli_sosi,
+
+    -- End of stimuli
+    tb_end            => stimuli_end
+  );
+
+  ------------------------------------------------------------------------------
+  -- DUT
+  ------------------------------------------------------------------------------     
+  u_dut : ENTITY work.dp_block_validate_err
+  GENERIC MAP (
+    g_cnt_w           => g_cnt_w,
+    g_max_block_size  => g_max_block_size,
+    g_nof_err_counts  => g_nof_err_counts,
+    g_data_w          => c_word_w,
+    g_bsn_w           => c_dp_stream_bsn_w,
+    g_empty_w         => c_dp_stream_empty_w,
+    g_channel_w       => c_dp_stream_channel_w,
+    g_use_bsn         => TRUE, 
+    g_use_empty       => TRUE, 
+    g_use_channel     => TRUE, 
+    g_use_sync        => TRUE 
+  )
+  PORT MAP (
+    dp_rst       => rst,
+    dp_clk       => dp_clk,
+
+    mm_rst       => rst,
+    mm_clk       => mm_clk,
+    -- ST sink
+    snk_out      => stimuli_siso,
+    snk_in       => stimuli_sosi,
+    -- ST source
+    src_in       => verify_siso,
+    src_out      => verify_sosi,
+
+    reg_mosi     => reg_mosi,
+    reg_miso     => reg_miso
+  );
+
+  
+  ------------------------------------------------------------------------------
+  -- Verification
+  ------------------------------------------------------------------------------
+  
+  u_pipeline : ENTITY work.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => c_dut_pipeline
+  )
+  PORT MAP (
+    rst         => rst,
+    clk         => dp_clk,
+    -- ST sink
+    snk_out     => OPEN,
+    snk_in      => stimuli_sosi,
+    -- ST source
+    src_in      => reference_siso,
+    src_out     => reference_sosi 
+  );
+  
+  reference_cnt_reg <= reference_cnt WHEN rising_edge(dp_clk);
+  reference_cnt     <= 0           WHEN reference_sosi.eop='1' AND ((reference_cnt_reg+1) MOD 2**g_nof_err_counts) = 0 ELSE
+             reference_cnt_reg + 1 WHEN reference_sosi.eop='1' ELSE
+             reference_cnt_reg;
+  
+  p_verify : PROCESS(dp_clk)
+  BEGIN
+    IF rising_edge(dp_clk) THEN
+      IF reference_cnt_reg = 0 THEN -- no errors so we expect a block
+        ASSERT verify_sosi.valid   = reference_sosi.valid   REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+        ASSERT verify_sosi.sop     = reference_sosi.sop     REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+        ASSERT verify_sosi.eop     = reference_sosi.eop     REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+        ASSERT verify_sosi.data    = reference_sosi.data    REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+        ASSERT verify_sosi.channel = reference_sosi.channel REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+        ASSERT verify_sosi.bsn     = reference_sosi.bsn     REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+        ASSERT verify_sosi.empty   = reference_sosi.empty   REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+        ASSERT verify_sosi.sync    = reference_sosi.sync    REPORT "Unexpected difference between in / out sosi" SEVERITY ERROR;
+      ELSE -- we expect no block as there are errors
+        ASSERT verify_sosi.valid = '0' REPORT "Wrong, valid is not '0' which is unexpected." SEVERITY ERROR; 
+        ASSERT verify_sosi.sop   = '0' REPORT "Wrong, sop is not '0' which is unexpected." SEVERITY ERROR; 
+        ASSERT verify_sosi.eop   = '0' REPORT "Wrong, eop is not '0' which is unexpected." SEVERITY ERROR; 
+      END IF;
+    END IF;
+  END PROCESS;
+
+  p_verify_mm : PROCESS
+    VARIABLE v_X : INTEGER := 0; -- variable to hold 2**I * ((c_nof_blk-1) / 2**(I+1))
+    VARIABLE v_Y : INTEGER := 0; -- variable to hold (c_nof_blk-1) + 1 - (2 * v_X) - 2**I
+    -- v_N is a variable to hold the expectet cnt number for the error counter registers = v_X + v_Y for v_Y > 0, else = v_x.
+    -- this can be calculated as the dp error field is a counter up to c_nof_blk - 1.
+    VARIABLE v_N : INTEGER := 0;
+  BEGIN
+    proc_common_wait_until_lo_hi(dp_clk, stimuli_end);
+    proc_common_wait_some_cycles(dp_clk, c_dut_pipeline + 1);
+    proc_common_wait_until_lo_hi(mm_clk, mm_clk);
+    proc_mem_mm_bus_rd(c_mm_addr_dp_blk_cnt, mm_clk, reg_miso, reg_mosi);
+    proc_mem_mm_bus_rd_latency(1, mm_clk);
+    ASSERT c_exp_blk_cnt = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong total block count" SEVERITY ERROR;
+    FOR I IN 0 TO g_nof_err_counts-1 LOOP
+      v_X := 2**I * ((c_nof_blk-1) / 2**(I+1));
+      v_Y := c_nof_blk - 2*v_X - 2**I;
+      IF v_Y < 0 THEN -- v_N = v_X + v_Y only holds for v_Y > 0.
+        v_N := v_X;
+      ELSE
+        v_N := v_X + v_Y;
+      END IF;
+
+      IF v_N > c_max_cnt THEN
+        v_N := c_max_cnt; -- the DUT clips the counters
+      END IF;
+
+      proc_mem_mm_bus_rd(I, mm_clk, reg_miso, reg_mosi);
+      proc_mem_mm_bus_rd_latency(1, mm_clk);
+      ASSERT v_N = TO_UINT(reg_miso.rddata(c_word_w-1 DOWNTO 0)) REPORT "Wrong error count" SEVERITY ERROR;
+    END LOOP;
+    proc_common_wait_some_cycles(dp_clk, 10);
+    tb_end <= '1';
+    WAIT;
+  END PROCESS;
+  
+  tb_end <= '0', stimuli_end AFTER (1 + 10*c_dut_pipeline)*c_dp_clk_period;
+  
+END tb;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_err.vhd b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_err.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..800a23d1ea1485892223e9a5d6db79e97dedf032
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_dp_block_validate_err.vhd
@@ -0,0 +1,61 @@
+-------------------------------------------------------------------------------
+--
+-- 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:
+-- Verify multiple variations of tb_dp_block_validate_err
+-- Usage:
+-- > as 3
+-- > run -all
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+
+ENTITY tb_tb_dp_block_validate_err IS
+END tb_tb_dp_block_validate_err;
+
+
+ARCHITECTURE tb OF tb_tb_dp_block_validate_err IS
+
+  SIGNAL tb_end : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+  
+  CONSTANT c_blk_per_sync   : NATURAL := 5;
+  CONSTANT c_data_per_blk   : NATURAL := 9;
+  CONSTANT c_max_block_size : NATURAL := 9;
+  CONSTANT c_nof_err_counts : NATURAL := 5;
+
+BEGIN
+--    g_nof_blocks_per_sync  : NATURAL := 5;
+--    g_nof_data_per_blk     : NATURAL := 9; 
+--    g_max_block_size       : NATURAL := 9;
+--    g_nof_err_counts       : NATURAL := 8;
+--    g_gap_size             : NATURAL := 4;
+--    g_cnt_w                : NATURAL := 3 
+
+  u_normal      : ENTITY work.tb_dp_block_validate_err GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_max_block_size, c_nof_err_counts, 4,   3); 
+  u_clip        : ENTITY work.tb_dp_block_validate_err GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_max_block_size, c_nof_err_counts, 4,   3); 
+  u_small_cnt_w : ENTITY work.tb_dp_block_validate_err GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_max_block_size, c_nof_err_counts, 4,   1); 
+  u_large_cnt_w : ENTITY work.tb_dp_block_validate_err GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_max_block_size, c_nof_err_counts, 4,   30); 
+  u_small_gap   : ENTITY work.tb_dp_block_validate_err GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_max_block_size, c_nof_err_counts, 1,   16); 
+  u_large_gap   : ENTITY work.tb_dp_block_validate_err GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_max_block_size, c_nof_err_counts, 100, 16); 
+  u_low_nof_cnt : ENTITY work.tb_dp_block_validate_err GENERIC MAP(c_blk_per_sync, c_data_per_blk, c_max_block_size, 1,                1,   16); 
+  
+END tb;