diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg
index ca25589a29083e166f4d1bf4f0f87483bebddfc2..3567f0d5d02b2ca3164d74771f1fffe7a8db9749 100644
--- a/libraries/base/dp/hdllib.cfg
+++ b/libraries/base/dp/hdllib.cfg
@@ -28,6 +28,9 @@ synth_files =
     src/vhdl/dp_pipeline.vhd
     src/vhdl/dp_pipeline_arr.vhd
     src/vhdl/dp_pipeline_ready.vhd
+    src/vhdl/dp_force_data.vhd
+    src/vhdl/mms_dp_force_data.vhd
+    src/vhdl/mms_dp_force_data_arr.vhd
     src/vhdl/dp_paged_sop_eop_reg.vhd
     src/vhdl/dp_packet_detect.vhd
     src/vhdl/dp_shiftreg.vhd
@@ -204,6 +207,7 @@ test_bench_files =
     tb/vhdl/tb_dp_folder.vhd
     tb/vhdl/tb_dp_switch.vhd
     tb/vhdl/tb_dp_counter_func.vhd
+    tb/vhdl/tb_mms_dp_force_data_arr.vhd
     tb/vhdl/tb_mms_dp_gain_arr.vhd
     tb/vhdl/tb_mms_dp_gain_serial_arr.vhd
 
@@ -238,6 +242,7 @@ test_bench_files =
     tb/vhdl/tb_tb_dp_split.vhd
     tb/vhdl/tb_tb_dp_sync_checker.vhd
     tb/vhdl/tb_tb_dp_sync_insert.vhd
+    tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
     tb/vhdl/tb_tb_mms_dp_gain_arr.vhd
     tb/vhdl/tb_tb_mms_dp_gain_serial_arr.vhd
     
@@ -281,6 +286,7 @@ regression_test_vhdl =
     tb/vhdl/tb_tb_dp_sync_checker.vhd
     tb/vhdl/tb_mms_dp_sync_checker.vhd
     tb/vhdl/tb_tb_dp_sync_insert.vhd
+    tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
     tb/vhdl/tb_tb_mms_dp_gain_arr.vhd
     tb/vhdl/tb_tb_mms_dp_gain_serial_arr.vhd
     
diff --git a/libraries/base/dp/src/vhdl/dp_force_data.vhd b/libraries/base/dp/src/vhdl/dp_force_data.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..87c0511d8b79a0e7a5331cdbc1df4cdf883445f4
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_force_data.vhd
@@ -0,0 +1,133 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, 7 apr 2017
+-- Purpose:
+--   Pass the sosi data fields or force them to zero. All other sosi fields
+--   are passed on unchanged.
+-- Description:
+--   Default the force value is constant, but using the generics it can be 
+--   made to automatically increment for every valid and restart at sync or
+--   sop.
+-- Usage:
+-- . DSP tests: Constant (zero) data is useful for DSP tests to be able to
+--   recognize a particular data stream in an array of streams.
+-- . Data move test: Incrementing data or a combination of constant re and
+--   incrementing im is useful for data move test when the data gets
+--   reordered.
+-- Remarks:
+-- . Ready latency = 1
+-- . When force_en='0' then this dp_force_data is equivalent to dp_pipeline.
+
+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;
+
+ENTITY dp_force_data IS
+  GENERIC (
+    g_dat_w             : NATURAL := 32;    -- must be <= 32 to fit INTEGER range
+    g_increment_data    : INTEGER := 0;
+    g_increment_re      : INTEGER := 0;
+    g_increment_im      : INTEGER := 0;
+    g_restart_on_sync   : BOOLEAN := FALSE;
+    g_restart_on_sop    : BOOLEAN := FALSE
+  );
+  PORT (
+    rst           : IN  STD_LOGIC;
+    clk           : IN  STD_LOGIC;
+    -- MM control
+    force_en      : IN  STD_LOGIC := '0';
+    force_data    : IN  INTEGER := 0;       -- used for sosi.data
+    force_re      : IN  INTEGER := 0;       -- used for sosi.re
+    force_im      : IN  INTEGER := 0;       -- used for sosi.im
+    -- ST sink
+    snk_out       : OUT t_dp_siso;
+    snk_in        : IN  t_dp_sosi;
+    -- ST source
+    src_in        : IN  t_dp_siso := c_dp_siso_rdy;
+    src_out       : OUT t_dp_sosi
+  );
+END dp_force_data;
+
+
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.all;
+USE work.dp_stream_pkg.ALL;
+
+ARCHITECTURE str OF dp_force_data IS
+
+  SIGNAL data_in          : t_dp_sosi;
+  SIGNAL data_out         : t_dp_sosi;
+  
+BEGIN
+
+  p_comb : PROCESS(snk_in, force_data, force_re, force_im, data_out)
+  BEGIN
+    data_in <= snk_in;
+    IF force_en='1' THEN
+      -- default force value
+      data_in.data <= TO_DP_SDATA(force_data);
+      data_in.re   <= TO_DP_DSP_DATA(force_re);
+      data_in.im   <= TO_DP_DSP_DATA(force_im);
+      -- optional increment
+      IF g_increment_data/=0 THEN
+        data_in.data <= RESIZE_DP_SDATA(STD_LOGIC_VECTOR(SIGNED(data_out.data(g_dat_w-1 DOWNTO 0)) + g_increment_data));
+      END IF;
+      IF g_increment_re/=0 THEN
+        data_in.re   <= RESIZE_DP_DSP_DATA(STD_LOGIC_VECTOR(SIGNED(data_out.re(g_dat_w-1 DOWNTO 0)) + g_increment_re));
+      END IF;
+      IF g_increment_im/=0 THEN
+        data_in.im   <= RESIZE_DP_DSP_DATA(STD_LOGIC_VECTOR(SIGNED(data_out.im(g_dat_w-1 DOWNTO 0)) + g_increment_im));
+      END IF;
+      -- optional restart increment
+      IF g_restart_on_sync=TRUE AND snk_in.sync='1' THEN
+        data_in.data <= TO_DP_SDATA(force_data);
+        data_in.re   <= TO_DP_DSP_DATA(force_re);
+        data_in.im   <= TO_DP_DSP_DATA(force_im);
+      END IF;
+      IF g_restart_on_sop=TRUE AND snk_in.sop='1' THEN
+        data_in.data <= TO_DP_SDATA(force_data);
+        data_in.re   <= TO_DP_DSP_DATA(force_re);
+        data_in.im   <= TO_DP_DSP_DATA(force_im);
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  u_dp_pipeline : ENTITY work.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 1
+  )
+  PORT MAP (
+    rst          => rst,
+    clk          => clk,
+    -- ST sink
+    snk_out      => snk_out,
+    snk_in       => data_in,
+    -- ST source
+    src_in       => src_in,
+    src_out      => data_out
+  );
+    
+  src_out <= data_out;
+END str;
diff --git a/libraries/base/dp/src/vhdl/mms_dp_force_data.vhd b/libraries/base/dp/src/vhdl/mms_dp_force_data.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..e38dffcb8dc5ce378c6a61b45cfdb0b5e71b2f27
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/mms_dp_force_data.vhd
@@ -0,0 +1,151 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+--
+-- Author : E. Kooistra, 7 apr 2017
+-- Purpose : Control force data per stream via MM
+-- Description:
+--   Address   Data  Access  Description
+--     0        [0]     R/W  force enable or default disable for data pass on
+--     1     [31:0]     R/W  force sosi data
+--     2     [31:0]     R/W  force sosi re
+--     3     [31:0]     R/W  force sosi im
+--
+--   The actual sosi data, re and im width integer is constrained by g_dat_w.
+--   Synthesis will optimize away unused bits from the full integer 32b range.
+--
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+
+
+ENTITY mms_dp_force_data IS
+  GENERIC (
+    g_dat_w             : NATURAL := 32;    -- must be <= 32 to fit INTEGER range
+    g_increment_data    : INTEGER := 0;
+    g_increment_re      : INTEGER := 0;
+    g_increment_im      : INTEGER := 0;
+    g_restart_on_sync   : BOOLEAN := FALSE;
+    g_restart_on_sop    : BOOLEAN := FALSE
+  );
+  PORT (
+    -- Clocks and reset
+    mm_rst              : IN  STD_LOGIC;
+    mm_clk              : IN  STD_LOGIC;
+    dp_rst              : IN  STD_LOGIC;
+    dp_clk              : IN  STD_LOGIC;
+    -- MM control
+    reg_force_data_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
+    reg_force_data_miso : OUT t_mem_miso;
+    -- ST sink
+    snk_out             : OUT t_dp_siso;
+    snk_in              : IN  t_dp_sosi;
+    -- ST source
+    src_in              : IN  t_dp_siso := c_dp_siso_rdy;
+    src_out             : OUT t_dp_sosi
+  );
+END mms_dp_force_data;
+
+ARCHITECTURE str OF mms_dp_force_data IS
+
+  -- TYPE t_c_mem IS RECORD
+  --   latency   : NATURAL;    -- read latency
+  --   adr_w     : NATURAL;
+  --   dat_w     : NATURAL;
+  --   nof_dat   : NATURAL;    -- optional, nof dat words <= 2**adr_w
+  --   init_sl   : STD_LOGIC;  -- optional, init all dat words to std_logic '0', '1' or 'X'
+  CONSTANT c_mm_reg         : t_c_mem := (1, 2, g_dat_w, 4, 'X');
+
+  CONSTANT c_mm_reg_init    : STD_LOGIC_VECTOR(c_mem_reg_init_w-1 DOWNTO 0) := (OTHERS=>'0');
+
+  SIGNAL reg_force_data_wr  : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0);
+  SIGNAL reg_force_data_rd  : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0');
+
+  SIGNAL force_en           : STD_LOGIC := '0';
+  SIGNAL force_data         : INTEGER := 0;       -- used for sosi.data
+  SIGNAL force_re           : INTEGER := 0;       -- used for sosi.re
+  SIGNAL force_im           : INTEGER := 0;       -- used for sosi.im
+
+BEGIN
+
+  -- wires
+  force_en             <= reg_force_data_wr(0);
+  reg_force_data_rd(0) <= reg_force_data_wr(0);  -- other bits are not used and will read '0'
+  force_data                                                    <= TO_SINT(reg_force_data_wr(2*c_mm_reg.dat_w-1 DOWNTO   c_mm_reg.dat_w));
+  reg_force_data_rd(2*c_mm_reg.dat_w-1 DOWNTO   c_mm_reg.dat_w) <=         reg_force_data_wr(2*c_mm_reg.dat_w-1 DOWNTO   c_mm_reg.dat_w);
+  force_re                                                      <= TO_SINT(reg_force_data_wr(3*c_mm_reg.dat_w-1 DOWNTO 2*c_mm_reg.dat_w));
+  reg_force_data_rd(3*c_mm_reg.dat_w-1 DOWNTO 2*c_mm_reg.dat_w) <=         reg_force_data_wr(3*c_mm_reg.dat_w-1 DOWNTO 2*c_mm_reg.dat_w);
+  force_im                                                      <= TO_SINT(reg_force_data_wr(4*c_mm_reg.dat_w-1 DOWNTO 3*c_mm_reg.dat_w));
+  reg_force_data_rd(4*c_mm_reg.dat_w-1 DOWNTO 3*c_mm_reg.dat_w) <=         reg_force_data_wr(4*c_mm_reg.dat_w-1 DOWNTO 3*c_mm_reg.dat_w);
+
+  u_common_reg_r_w_dc_re : ENTITY common_lib.common_reg_r_w_dc
+  GENERIC MAP (
+    g_cross_clock_domain => TRUE,
+    g_readback           => FALSE,
+    g_reg                => c_mm_reg,
+    g_init_reg           => c_mm_reg_init
+  )
+  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_force_data_mosi,
+    sla_out        => reg_force_data_miso,
+
+    -- MM registers in st_clk domain
+    reg_wr_arr     => OPEN,
+    reg_rd_arr     => OPEN,
+    out_reg        => reg_force_data_wr,   -- readback via ST clock domain
+    in_reg         => reg_force_data_rd
+  );
+
+  u_dp_force_data : ENTITY work.dp_force_data
+  GENERIC MAP (
+    g_dat_w             => g_dat_w,
+    g_increment_data    => g_increment_data,
+    g_increment_re      => g_increment_re,
+    g_increment_im      => g_increment_im,
+    g_restart_on_sync   => g_restart_on_sync,
+    g_restart_on_sop    => g_restart_on_sop
+  )
+  PORT MAP (
+    rst           => dp_rst,
+    clk           => dp_clk,
+    -- MM control
+    force_en      => force_en,
+    force_data    => force_data,
+    force_re      => force_re,
+    force_im      => force_im,
+    -- ST sink
+    snk_out       => snk_out,
+    snk_in        => snk_in,
+    -- ST source
+    src_in        => src_in,
+    src_out       => src_out
+  );
+END str;
+
diff --git a/libraries/base/dp/src/vhdl/mms_dp_force_data_arr.vhd b/libraries/base/dp/src/vhdl/mms_dp_force_data_arr.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..2fa99c5c96e9a5c7090cb7860df0941698cd33e9
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/mms_dp_force_data_arr.vhd
@@ -0,0 +1,116 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+--
+-- Author : E. Kooistra, 7 apr 2017
+-- Purpose : Control force data per stream via MM
+-- Description:
+--   Stream Address   Data  Access  Description
+--      0      0        [0]     R/W  force enable or default disable for data pass on
+--      0      1     [31:0]     R/W  force sosi data, re
+--      0      2     [31:0]     R/W  force sosi im
+--      0      3         -      R/W  not used, reads 0
+--      1     4:7    idem
+--      2     8:11   idem
+--      etc.
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+
+
+ENTITY mms_dp_force_data_arr IS
+  GENERIC (
+    g_nof_streams       : NATURAL := 1;
+    g_dat_w             : NATURAL := 32;    -- must be <= 32 to fit INTEGER range
+    g_increment_data    : INTEGER := 0;
+    g_increment_re      : INTEGER := 0;
+    g_increment_im      : INTEGER := 0;
+    g_restart_on_sync   : BOOLEAN := FALSE;
+    g_restart_on_sop    : BOOLEAN := FALSE
+  );
+  PORT (
+    -- Clocks and reset
+    mm_rst              : IN  STD_LOGIC;
+    mm_clk              : IN  STD_LOGIC;
+    dp_rst              : IN  STD_LOGIC;
+    dp_clk              : IN  STD_LOGIC;
+    -- MM control
+    reg_force_data_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
+    reg_force_data_miso : OUT t_mem_miso;
+    -- 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);
+    -- 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)
+  );
+END mms_dp_force_data_arr;
+
+
+ARCHITECTURE str OF mms_dp_force_data_arr IS
+
+  SIGNAL reg_force_data_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0) := (OTHERS=>c_mem_mosi_rst);
+  SIGNAL reg_force_data_miso_arr : t_mem_miso_arr(g_nof_streams-1 DOWNTO 0);
+  
+BEGIN
+
+  u_mem_mux : ENTITY common_lib.common_mem_mux
+  GENERIC MAP (    
+    g_nof_mosi    => g_nof_streams,
+    g_mult_addr_w => 2
+  )
+  PORT MAP (
+    mosi     => reg_force_data_mosi,
+    miso     => reg_force_data_miso,
+    mosi_arr => reg_force_data_mosi_arr,
+    miso_arr => reg_force_data_miso_arr
+  );
+
+  gen_nof_streams : FOR I IN 0 TO g_nof_streams-1 GENERATE
+    u_mms_dp_force_data : ENTITY work.mms_dp_force_data
+    GENERIC MAP (
+      g_dat_w             => g_dat_w,
+      g_increment_data    => g_increment_data,
+      g_increment_re      => g_increment_re,
+      g_increment_im      => g_increment_im,
+      g_restart_on_sync   => g_restart_on_sync,
+      g_restart_on_sop    => g_restart_on_sop
+    )
+    PORT MAP (
+      mm_rst              => mm_rst,
+      mm_clk              => mm_clk,
+      dp_rst              => dp_rst,
+      dp_clk              => dp_clk,
+      -- MM control
+      reg_force_data_mosi => reg_force_data_mosi_arr(I),
+      reg_force_data_miso => reg_force_data_miso_arr(I),
+      -- ST sink
+      snk_out             => snk_out_arr(I),
+      snk_in              => snk_in_arr(I),
+      -- ST source
+      src_in              => src_in_arr(I),
+      src_out             => src_out_arr(I)
+    );
+  END GENERATE;
+END str;
+
diff --git a/libraries/base/dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd b/libraries/base/dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..c759470e0f356f5660dfca407661392ea770e6ac
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_mms_dp_force_data_arr.vhd
@@ -0,0 +1,349 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+-- Author: E. Kooistra, 10 Apr 2017
+-- Purpose: Verify mms_dp_force_data_arr and mms_dp_force_data
+-- Description:
+-- Usage:
+-- > as 10
+-- > run -all
+-- In wave window view sosi.data,re,im in radix decimal
+-- The tb is self stopping and self checking.
+
+  
+LIBRARY IEEE, common_lib, technology_lib;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_lfsr_sequences_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.tb_common_mem_pkg.ALL; 
+USE work.dp_stream_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+
+
+ENTITY tb_mms_dp_force_data_arr IS
+  GENERIC (
+    g_flow_control_stimuli   : t_dp_flow_control_enum := e_active;   -- always active or random stimuli valid flow control
+    g_flow_control_verify    : t_dp_flow_control_enum := e_active;   -- always active or random verify  ready flow control
+    g_nof_streams            : NATURAL := 1;     -- >= 1
+    g_dat_w                  : NATURAL := 5;    -- must be <= 32 to fit INTEGER range
+    g_force_stream           : INTEGER := 0;     -- must be < g_nof_streams, force data on this stream
+    g_force_data             : INTEGER := -1;
+    g_force_re               : INTEGER := 2;
+    g_force_im               : INTEGER := -3;
+    g_increment_data         : INTEGER := 1;
+    g_increment_re           : INTEGER := -5;
+    g_increment_im           : INTEGER := 5;
+    g_restart_on_sync        : BOOLEAN := FALSE;
+    g_restart_on_sop         : BOOLEAN := FALSE
+  );
+END tb_mms_dp_force_data_arr;
+
+
+ARCHITECTURE tb OF tb_mms_dp_force_data_arr IS
+
+  CONSTANT c_mm_clk_period              : TIME := 20 ns;
+  CONSTANT c_dp_clk_period              : TIME := 10 ns;
+  CONSTANT c_cross_clock_domain_latency : NATURAL := 20;
+  
+  CONSTANT c_init_data                  : INTEGER := 0;
+  CONSTANT c_init_channel               : INTEGER := 11;  -- use recognizable value, will not change
+  CONSTANT c_init_error                 : INTEGER := 12;  -- use recognizable value, will not change
+  CONSTANT c_nof_data_per_block         : INTEGER := 17;
+  CONSTANT c_nof_block_per_sync         : INTEGER := 10;
+  CONSTANT c_nof_blocks_per_test        : INTEGER := c_nof_block_per_sync*3;
+  
+  CONSTANT c_mm_reg_nof_dat             : NATURAL := 4;
+  CONSTANT c_force_en                   : NATURAL := 1;
+  CONSTANT c_force_dis                  : NATURAL := 0;
+  
+  SIGNAL tb_end                : STD_LOGIC := '0';
+  SIGNAL mm_clk                : STD_LOGIC := '1';
+  SIGNAL mm_rst                : STD_LOGIC := '1';
+  SIGNAL dp_clk                : STD_LOGIC := '1';
+  SIGNAL dp_rst                : STD_LOGIC := '1';
+
+  SIGNAL random_valid          : STD_LOGIC_VECTOR(15 DOWNTO 0) := (OTHERS=>'0');  -- use different lengths to have different random sequences
+  SIGNAL random_ready          : STD_LOGIC_VECTOR(16 DOWNTO 0) := (OTHERS=>'0');  -- use different lengths to have different random sequences
+  SIGNAL stimuli_en            : STD_LOGIC := '0';
+  SIGNAL verify_en             : STD_LOGIC := '0';
+  SIGNAL force_en              : STD_LOGIC := '0';
+  
+  SIGNAL snk_out               : t_dp_siso;
+  SIGNAL snk_in                : t_dp_sosi;
+  SIGNAL snk_in_dly            : t_dp_sosi;
+  SIGNAL snk_out_arr           : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL snk_in_arr            : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL src_in_arr            : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL src_out_arr           : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL prev_src_out_arr      : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+  SIGNAL src_in                : t_dp_siso;
+  
+  SIGNAL reg_force_data_mosi   : t_mem_mosi := c_mem_mosi_rst;
+  SIGNAL reg_force_data_miso   : t_mem_miso;
+    
+BEGIN
+
+  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;
+  dp_rst <= '1', '0' AFTER c_dp_clk_period*7;    
+  mm_rst <= '1', '0' AFTER c_mm_clk_period*7;
+  
+  random_valid <= func_common_random(random_valid) WHEN rising_edge(dp_clk);
+  random_ready <= func_common_random(random_ready) WHEN rising_edge(dp_clk);
+  
+  stimuli_en   <= random_valid(random_valid'HIGH) WHEN g_flow_control_stimuli=e_random ELSE '1';
+  src_in.ready <= random_ready(random_ready'HIGH) WHEN g_flow_control_verify =e_random ELSE '1';
+  src_in.xon   <= '1';
+  
+  src_in_arr <= (OTHERS=>src_in);
+  
+  ------------------------------------------------------------------------------
+  -- DATA GENERATION
+  ------------------------------------------------------------------------------
+  p_stimuli_st : PROCESS
+    VARIABLE v_sosi : t_dp_sosi := c_dp_sosi_rst;
+  BEGIN
+    -- Initialisations
+    v_sosi.bsn     := TO_DP_BSN(0);
+    v_sosi.data    := TO_DP_SDATA(0);
+    
+    snk_in <= c_dp_sosi_rst;
+    proc_common_wait_until_low(dp_clk, mm_rst);
+    proc_common_wait_until_low(dp_clk, dp_rst);
+    proc_common_wait_some_cycles(dp_clk, 5);
+
+    -- Generate packets
+    WHILE tb_end='0' LOOP
+      v_sosi.sync    := sel_a_b((UNSIGNED(v_sosi.bsn) MOD c_nof_block_per_sync) = 0, '1', '0');  -- insert sync starting at BSN=0 and with period g_sync_period
+      v_sosi.data    := RESIZE_DP_DATA(v_sosi.data(g_dat_w-1 DOWNTO 0));  -- wrap when >= 2**g_dat_w      
+      -- Send block
+      proc_dp_gen_block_data(g_dat_w, c_init_data, c_nof_data_per_block, c_init_channel, c_init_error, v_sosi.sync, v_sosi.bsn, dp_clk, stimuli_en, snk_out, snk_in);
+      -- Prepare for next block
+      v_sosi.bsn     := INCR_UVEC(v_sosi.bsn, 1);
+      v_sosi.data    := INCR_UVEC(v_sosi.data, c_nof_data_per_block);
+    END LOOP;
+    
+    WAIT;
+  END PROCESS;
+
+  u_snk_in_dly : ENTITY work.dp_pipeline
+  GENERIC MAP (
+    g_pipeline   => 1   -- latency of DUT
+  )
+  PORT MAP (
+    rst      => dp_rst,
+    clk      => dp_clk,
+    snk_out  => OPEN,
+    snk_in   => snk_in,
+    src_in   => src_in_arr(0),
+    src_out  => snk_in_dly
+  );
+  
+  snk_out    <= snk_out_arr(0);    -- use stream 0 for flow control, all tb streams have same flow control
+  snk_in_arr <= (OTHERS=>snk_in);  -- apply same default tb data to all streams
+
+  p_stimuli_mm : PROCESS
+    VARIABLE v_force_data : INTEGER := g_force_data;
+  BEGIN              
+    proc_common_wait_until_low(dp_clk, mm_rst);
+    proc_common_wait_until_low(dp_clk, dp_rst);
+    proc_common_wait_some_cycles(mm_clk, 5);
+
+    -- Test default pass on the data unchanged
+    verify_en <= '1';
+    FOR I IN 0 TO c_nof_blocks_per_test-1 LOOP
+      proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+    END LOOP;
+    verify_en <= '0';
+    
+    -- Test force data on stream g_force_stream
+    force_en <= '1';
+    proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 0, c_force_en,   mm_clk, reg_force_data_miso, reg_force_data_mosi);
+    proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 1, g_force_data, mm_clk, reg_force_data_miso, reg_force_data_mosi);
+    proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 2, g_force_re,   mm_clk, reg_force_data_miso, reg_force_data_mosi);
+    proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 3, g_force_im,   mm_clk, reg_force_data_miso, reg_force_data_mosi);
+    proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
+    proc_common_wait_some_cycles(dp_clk, c_cross_clock_domain_latency);    
+    
+    proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+    verify_en <= '1';
+    FOR I IN 0 TO c_nof_blocks_per_test-1 LOOP
+      proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+    END LOOP;
+    verify_en <= '0';
+    
+    -- Test default pass on the data unchanged
+    force_en <= '0';
+    proc_mem_mm_bus_wr(g_force_stream*c_mm_reg_nof_dat + 0, c_force_dis,   mm_clk, reg_force_data_miso, reg_force_data_mosi);
+    proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency);
+    proc_common_wait_some_cycles(dp_clk, c_cross_clock_domain_latency); 
+    
+    verify_en <= '1';
+    FOR I IN 0 TO c_nof_blocks_per_test-1 LOOP
+      proc_common_wait_until_hi_lo(dp_clk, snk_in.eop);
+    END LOOP;
+    verify_en <= '0';
+    
+    tb_end <= '1';
+    WAIT;
+  END PROCESS;  
+
+  -- capture previous valid src_out_arr to verify increments
+  prev_src_out_arr <= src_out_arr WHEN rising_edge(dp_clk) AND snk_in_dly.valid='1';
+  
+  p_verify : PROCESS(dp_clk)
+    VARIABLE v_exp_data : INTEGER;
+    VARIABLE v_exp_re   : INTEGER;
+    VARIABLE v_exp_im   : INTEGER;
+  BEGIN
+    IF rising_edge(dp_clk) THEN
+      IF verify_en='1' AND snk_in_dly.valid='1' THEN
+        FOR I IN 0 TO g_nof_streams-1 LOOP
+          -- verify unchanged sosi fields (= pipeline)
+          ASSERT        src_out_arr(I).sync    =       snk_in_dly.sync     REPORT "Unexpected sync"    SEVERITY ERROR;
+          ASSERT        src_out_arr(I).sop     =       snk_in_dly.sop      REPORT "Unexpected sop"     SEVERITY ERROR;
+          ASSERT        src_out_arr(I).eop     =       snk_in_dly.eop      REPORT "Unexpected eop"     SEVERITY ERROR;
+          ASSERT        src_out_arr(I).valid   =       snk_in_dly.valid    REPORT "Unexpected valid"   SEVERITY ERROR;
+          ASSERT SIGNED(src_out_arr(I).bsn)    =SIGNED(snk_in_dly.bsn)     REPORT "Unexpected bsn"     SEVERITY ERROR;
+          ASSERT SIGNED(src_out_arr(I).channel)=SIGNED(snk_in_dly.channel) REPORT "Unexpected channel" SEVERITY ERROR;
+          ASSERT SIGNED(src_out_arr(I).err)    =SIGNED(snk_in_dly.err)     REPORT "Unexpected err"     SEVERITY ERROR;
+          
+          IF force_en='0' OR I/=g_force_stream THEN
+            -- verify default data pass on (= pipeline)
+            ASSERT SIGNED(src_out_arr(I).data) =SIGNED(snk_in_dly.data) REPORT "Unexpected data"    SEVERITY ERROR;
+            ASSERT SIGNED(src_out_arr(I).re)   =SIGNED(snk_in_dly.re)   REPORT "Unexpected real"    SEVERITY ERROR;
+            ASSERT SIGNED(src_out_arr(I).im)   =SIGNED(snk_in_dly.im)   REPORT "Unexpected imag"    SEVERITY ERROR;
+          ELSE
+            -- verify default force data on stream I=g_force_stream
+            v_exp_data := TO_SINT(INCR_DP_SDATA(   prev_src_out_arr(I).data, g_increment_data, g_dat_w));
+            v_exp_re   := TO_SINT(INCR_DP_DSP_DATA(prev_src_out_arr(I).re,   g_increment_re,   g_dat_w));
+            v_exp_im   := TO_SINT(INCR_DP_DSP_DATA(prev_src_out_arr(I).im,   g_increment_im,   g_dat_w));
+            
+            -- .data
+            IF g_increment_data=0 THEN
+              ASSERT TO_SINT(src_out_arr(I).data)=g_force_data REPORT "Unexpected force data" SEVERITY ERROR;
+            ELSE
+              IF g_restart_on_sync=TRUE AND snk_in_dly.sync='1' THEN
+                ASSERT TO_SINT(src_out_arr(I).data)=g_force_data REPORT "Unexpected restart force data at sync" SEVERITY ERROR;
+              ELSIF g_restart_on_sop=TRUE AND snk_in_dly.sop='1' THEN
+                ASSERT TO_SINT(src_out_arr(I).data)=g_force_data REPORT "Unexpected restart force data at sop" SEVERITY ERROR;
+              ELSE
+                ASSERT TO_SINT(src_out_arr(I).data)=v_exp_data REPORT "Unexpected increment data" SEVERITY ERROR;
+              END IF;
+            END IF;
+            
+            -- .re
+            IF g_increment_re=0 THEN
+              ASSERT TO_SINT(src_out_arr(I).re)=g_force_re REPORT "Unexpected force re" SEVERITY ERROR;
+            ELSE
+              IF g_restart_on_sync=TRUE AND snk_in_dly.sync='1' THEN
+                ASSERT TO_SINT(src_out_arr(I).re)=g_force_re REPORT "Unexpected restart force re at sync" SEVERITY ERROR;
+              ELSIF g_restart_on_sop=TRUE AND snk_in_dly.sop='1' THEN
+                ASSERT TO_SINT(src_out_arr(I).re)=g_force_re REPORT "Unexpected restart force re at sop" SEVERITY ERROR;
+              ELSE
+                ASSERT TO_SINT(src_out_arr(I).re)=v_exp_re REPORT "Unexpected increment re" SEVERITY ERROR;
+              END IF;
+            END IF;
+            
+            -- .im
+            IF g_increment_im=0 THEN
+              ASSERT TO_SINT(src_out_arr(I).im)=g_force_im REPORT "Unexpected force im" SEVERITY ERROR;
+            ELSE
+              IF g_restart_on_sync=TRUE AND snk_in_dly.sync='1' THEN
+                ASSERT TO_SINT(src_out_arr(I).im)=g_force_im REPORT "Unexpected restart force im at sync" SEVERITY ERROR;
+              ELSIF g_restart_on_sop=TRUE AND snk_in_dly.sop='1' THEN
+                ASSERT TO_SINT(src_out_arr(I).im)=g_force_im REPORT "Unexpected restart force im at sop" SEVERITY ERROR;
+              ELSE
+                ASSERT TO_SINT(src_out_arr(I).im)=v_exp_im REPORT "Unexpected increment im" SEVERITY ERROR;
+              END IF;
+            END IF;
+          END IF;
+        END LOOP;
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  ------------------------------------------------------------------------------
+  -- DUT 
+  ------------------------------------------------------------------------------
+  
+  gen_one : IF g_nof_streams=1 GENERATE
+    u_dut_one : ENTITY work.mms_dp_force_data
+    GENERIC MAP (
+      g_dat_w             => g_dat_w,
+      g_increment_data    => g_increment_data,
+      g_increment_re      => g_increment_re,
+      g_increment_im      => g_increment_im,
+      g_restart_on_sync   => g_restart_on_sync,
+      g_restart_on_sop    => g_restart_on_sop
+    )
+    PORT MAP (
+      -- Clocks and reset
+      mm_rst              => mm_rst,
+      mm_clk              => mm_clk,
+      dp_rst              => dp_rst,
+      dp_clk              => dp_clk,
+      -- MM control
+      reg_force_data_mosi => reg_force_data_mosi,
+      reg_force_data_miso => reg_force_data_miso,
+      -- ST sink
+      snk_out             => snk_out_arr(0),
+      snk_in              => snk_in_arr(0),
+      -- ST source
+      src_in              => src_in_arr(0),
+      src_out             => src_out_arr(0)
+    );
+  END GENERATE;  
+  
+  gen_arr : IF g_nof_streams>1 GENERATE
+    u_dut_arr : ENTITY work.mms_dp_force_data_arr
+    GENERIC MAP (
+      g_nof_streams       => g_nof_streams,
+      g_dat_w             => g_dat_w,
+      g_increment_data    => g_increment_data,
+      g_increment_re      => g_increment_re,
+      g_increment_im      => g_increment_im,
+      g_restart_on_sync   => g_restart_on_sync,
+      g_restart_on_sop    => g_restart_on_sop
+    )
+    PORT MAP (
+      -- Clocks and reset
+      mm_rst              => mm_rst,
+      mm_clk              => mm_clk,
+      dp_rst              => dp_rst,
+      dp_clk              => dp_clk,
+      -- MM control
+      reg_force_data_mosi => reg_force_data_mosi,
+      reg_force_data_miso => reg_force_data_miso,
+      -- ST sink
+      snk_out_arr         => snk_out_arr,
+      snk_in_arr          => snk_in_arr,
+      -- ST source
+      src_in_arr          => src_in_arr,
+      src_out_arr         => src_out_arr
+    );
+  END GENERATE;
+  
+END tb;
diff --git a/libraries/base/dp/tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd b/libraries/base/dp/tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..833d348534192dbeb068ff2c7ed175c5ae59cd00
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_tb_mms_dp_force_data_arr.vhd
@@ -0,0 +1,63 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2017
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+--------------------------------------------------------------------------------
+
+-- Author: E. Kooistra, 10 Apr 2017
+-- Purpose: Multi-testbench for mms_dp_force_data_arr
+-- Description:
+--   Verify mms_dp_force_data_arr
+-- Usage:
+--   > as 4
+--   > run -all
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE work.tb_dp_pkg.ALL;
+
+ENTITY tb_tb_mms_dp_force_data_arr IS
+END tb_tb_mms_dp_force_data_arr;
+
+ARCHITECTURE tb OF tb_tb_mms_dp_force_data_arr IS
+  
+  SIGNAL tb_end : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
+  
+BEGIN
+
+-- g_flow_control_stimuli   : t_dp_flow_control_enum := e_active;   -- always active or random stimuli valid flow control
+-- g_flow_control_verify    : t_dp_flow_control_enum := e_active;   -- always active or random verify  ready flow control
+-- g_nof_streams            : NATURAL := 1;     -- >= 1
+-- g_dat_w                  : NATURAL := 32;    -- must be <= 32 to fit INTEGER range
+-- g_force_stream           : INTEGER := 0;     -- must be < g_nof_streams, force data on this stream
+-- g_force_data             : INTEGER := -1;
+-- g_force_re               : INTEGER := 2;
+-- g_force_im               : INTEGER := -3;
+-- g_increment_data         : INTEGER := 0;
+-- g_increment_re           : INTEGER := 0;
+-- g_increment_im           : INTEGER := 0;
+-- g_restart_on_sync        : BOOLEAN := FALSE;
+-- g_restart_on_sop         : BOOLEAN := FALSE
+
+  u_act_force_data_1           : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_active, e_active, 1, 16, 0,  -1, 2, -3,  0, 0, 0,  FALSE, FALSE);
+  u_rnd_force_data_3           : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0,  -1, 2, -3,  0, 0, 0,  FALSE, FALSE);
+  u_rnd_force_data_incr_3      : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0,  -1, 2, -3,  1, 1, 1,  FALSE, FALSE);
+  u_rnd_force_data_incr_sync_3 : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0,  -1, 2, -3,  1, 1, 1,   TRUE, FALSE);
+  u_rnd_force_data_incr_sop_3  : ENTITY work.tb_mms_dp_force_data_arr GENERIC MAP (e_random, e_random, 3, 16, 0,  -1, 2, -3,  1, 1, 1,  FALSE,  TRUE);
+  
+END tb;