diff --git a/libraries/base/dp/src/vhdl/dp_deinterleave.vhd b/libraries/base/dp/src/vhdl/dp_deinterleave.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..69a04573ae32d7082f447b7e71d03fe5abee040b
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_deinterleave.vhd
@@ -0,0 +1,265 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- 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/>.
+--
+--------------------------------------------------------------------------------
+
+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;
+
+-- Purpose: 
+-- . Deinterleave the input into g_nof_out outputs, outputting g_block_size words before switching to next output.
+-- Description: 
+-- . DP wrapper for common_deinterleave
+-- Remark:
+-- . Usage is straightforward, but when g_use_ctrl is TRUE, do make sure the input blocks can be evenly
+--   distributed over the chosen number of outputs at the chosen deinterleaver block size (g_block_size).
+
+ENTITY dp_deinterleave IS
+  GENERIC (
+    g_dat_w          : NATURAL;
+    g_nof_out        : NATURAL;
+    g_block_size     : NATURAL;         -- Deinterleaver block size; output g_block_size words before witching to next output
+    g_use_ctrl       : BOOLEAN := TRUE; -- Requires: [input block size (sop:eop)] / [g_nof_out]/ [g_block_size] = integer number!
+    g_use_complex    : BOOLEAN;
+    g_align_out      : BOOLEAN := FALSE 
+  );
+  PORT (
+    rst         : IN  STD_LOGIC;
+    clk         : IN  STD_LOGIC;
+
+    snk_in      : IN  t_dp_sosi;
+    src_out_arr : OUT t_dp_sosi_arr(g_nof_out-1 DOWNTO 0)
+  );
+END dp_deinterleave;
+
+
+ARCHITECTURE wrap OF dp_deinterleave IS
+
+  CONSTANT c_complex_w  : NATURAL := g_dat_w/2;
+
+  -- Arrays flattened into SLVs
+  SIGNAL out_dat        : STD_LOGIC_VECTOR(g_nof_out*g_dat_w-1 DOWNTO 0);
+  SIGNAL out_val        : STD_LOGIC_VECTOR(g_nof_out-1 DOWNTO 0);
+
+  SIGNAL piped_snk_in   : t_dp_sosi;
+
+  -- Either SOSI data or SOSI Im&Re is forwarded to the deinterleaver
+  SIGNAL in_dat         : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
+  SIGNAL piped_in_dat   : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
+
+BEGIN
+
+  gen_sosi_dat_in: IF g_use_complex = FALSE GENERATE
+    -----------------------------------------------------------------------------
+    -- Forward SOSI data field
+    -----------------------------------------------------------------------------
+    in_dat <= snk_in.data(g_dat_w-1 DOWNTO 0);
+  END GENERATE;
+
+  gen_sosi_compl_in: IF g_use_complex = TRUE GENERATE
+    -----------------------------------------------------------------------------
+    -- Forward concatenated im & re fields
+    -----------------------------------------------------------------------------
+    in_dat <= snk_in.im(c_complex_w-1 DOWNTO 0) & snk_in.re(c_complex_w-1 DOWNTO 0);
+  END GENERATE;
+
+  u_deinterleave : ENTITY common_lib.common_deinterleave
+  GENERIC MAP (
+    g_nof_out    => g_nof_out,
+    g_block_size => g_block_size,
+    g_dat_w      => g_dat_w,
+    g_align_out  => g_align_out
+  )
+  PORT MAP (
+    rst        => rst,
+    clk        => clk,
+    
+    in_dat     => piped_in_dat,
+    in_val     => piped_snk_in.valid, 
+    
+    out_dat    => out_dat,
+    out_val    => out_val
+  );
+
+  -----------------------------------------------------------------------------
+  -- Map output SLV to sosi_arr
+  -----------------------------------------------------------------------------
+  gen_wires_out : FOR i IN 0 TO g_nof_out-1 GENERATE
+    gen_sosi_dat_out: IF g_use_complex = FALSE GENERATE
+      -----------------------------------------------------------------------------
+      -- Forward SOSI data field
+      -----------------------------------------------------------------------------
+      src_out_arr(i).data(g_dat_w-1 DOWNTO 0) <= out_dat( i*g_dat_w+g_dat_w -1 DOWNTO i*g_dat_w);
+    END GENERATE;
+    
+    gen_sosi_compl_out: IF g_use_complex = TRUE GENERATE
+      -----------------------------------------------------------------------------
+      -- Forward concatenated im & re fields
+      -----------------------------------------------------------------------------
+      src_out_arr(i).im <= RESIZE_DP_DSP_DATA(out_dat( i*g_dat_w + g_dat_w     -1 DOWNTO i*g_dat_w + c_complex_w));
+      src_out_arr(i).re <= RESIZE_DP_DSP_DATA(out_dat( i*g_dat_w + c_complex_w -1 DOWNTO i*g_dat_w));
+    END GENERATE;
+
+    src_out_arr(i).valid <= out_val(i);
+  END GENERATE;
+
+  -----------------------------------------------------------------------------
+  -- The input data and valid are delayed for g_block_size cycles before they
+  -- enter common_deinterleave, so the snk_in.eop will be aligned with 
+  -- src_out(0).eop.
+  -----------------------------------------------------------------------------
+  u_pipe_dat : ENTITY common_lib.common_pipeline
+  GENERIC MAP (
+    g_pipeline  => g_block_size,
+    g_in_dat_w  => g_dat_w,
+    g_out_dat_w => g_dat_w
+  )
+  PORT MAP (
+    rst     => rst,
+    clk     => clk,
+    in_dat  => in_dat,
+    out_dat => piped_in_dat 
+  );
+
+  u_pipe_val : ENTITY common_lib.common_pipeline
+  GENERIC MAP (
+    g_pipeline  => g_block_size,
+    g_in_dat_w  => 1,
+    g_out_dat_w => 1
+  )
+  PORT MAP (
+    rst     => rst,
+    clk     => clk,
+    in_dat  => slv(snk_in.valid),
+    sl(out_dat) => piped_snk_in.valid 
+  );        
+  
+  -----------------------------------------------------------------------------
+  -- Forward and align the input Sync, BSN, SOP and EOP with the outputs
+  -----------------------------------------------------------------------------
+  gen_ctrl : if g_use_ctrl=TRUE GENERATE
+    gen_out_pipes: FOR i IN 0 TO g_nof_out-1 GENERATE
+      -----------------------------------------------------------------------------
+      -- Before forwarding the remaining (ctrl) signals to the outputs, they also 
+      -- need the base delay of g_block_size*, plus additional incremental delays 
+      -- (i*g_block_size) to align them with the data and valid (that already have
+      -- those delays because of the sequential deinterleaving) of the 
+      -- corresponding output (i).
+      --
+      -- *this excludes eop as that was the reason for delaying the other inputs
+      --  by g_block_size cycles in the first place.
+      -----------------------------------------------------------------------------
+      u_pipe_sync : ENTITY common_lib.common_pipeline
+      GENERIC MAP (
+        g_pipeline  => g_block_size + i*g_block_size,
+        g_in_dat_w  => 1,
+        g_out_dat_w => 1
+      )
+      PORT MAP (
+        rst     => rst,
+        clk     => clk,
+        in_dat  => slv(snk_in.sync),
+        sl(out_dat) => src_out_arr(i).sync
+      );
+
+      u_pipe_bsn : ENTITY common_lib.common_pipeline
+      GENERIC MAP (
+        g_pipeline  => g_block_size + i*g_block_size,
+        g_in_dat_w  => c_dp_stream_bsn_w,
+        g_out_dat_w => c_dp_stream_bsn_w
+      )
+      PORT MAP (
+        rst     => rst,
+        clk     => clk,
+        in_dat  => snk_in.bsn,
+        out_dat => src_out_arr(i).bsn
+      );
+
+      u_pipe_sop : ENTITY common_lib.common_pipeline
+      GENERIC MAP (
+        g_pipeline  => g_block_size + i*g_block_size,
+        g_in_dat_w  => 1,
+        g_out_dat_w => 1
+      )
+      PORT MAP (
+        rst     => rst,
+        clk     => clk,
+        in_dat  => slv(snk_in.sop),
+        sl(out_dat) => src_out_arr(i).sop
+      );
+
+      u_pipe_eop : ENTITY common_lib.common_pipeline
+      GENERIC MAP (
+        g_pipeline  => i*g_block_size,
+        g_in_dat_w  => 1,
+        g_out_dat_w => 1
+      )
+      PORT MAP (
+        rst     => rst,
+        clk     => clk,
+        in_dat  => slv(snk_in.eop),
+        sl(out_dat) => src_out_arr(i).eop
+      );
+
+      u_pipe_err : ENTITY common_lib.common_pipeline
+      GENERIC MAP (
+        g_pipeline  => g_block_size + i*g_block_size,
+        g_in_dat_w  => c_dp_stream_error_w,
+        g_out_dat_w => c_dp_stream_error_w
+      )
+      PORT MAP (
+        rst     => rst,
+        clk     => clk,
+        in_dat  => snk_in.err,
+        out_dat => src_out_arr(i).err
+      );
+
+      u_pipe_empty : ENTITY common_lib.common_pipeline
+      GENERIC MAP (
+        g_pipeline  => g_block_size + i*g_block_size,
+        g_in_dat_w  => c_dp_stream_empty_w,
+        g_out_dat_w => c_dp_stream_empty_w
+      )
+      PORT MAP (
+        rst     => rst,
+        clk     => clk,
+        in_dat  => snk_in.empty,
+        out_dat => src_out_arr(i).empty
+      );
+
+      u_pipe_channel : ENTITY common_lib.common_pipeline
+      GENERIC MAP (
+        g_pipeline  => g_block_size + i*g_block_size,
+        g_in_dat_w  => c_dp_stream_channel_w,
+        g_out_dat_w => c_dp_stream_channel_w
+      )
+      PORT MAP (
+        rst     => rst,
+        clk     => clk,
+        in_dat  => snk_in.channel,
+        out_dat => src_out_arr(i).channel
+      );
+
+    END GENERATE;
+  END GENERATE;
+
+END wrap;
diff --git a/libraries/base/dp/src/vhdl/dp_reinterleave.vhd b/libraries/base/dp/src/vhdl/dp_reinterleave.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f4389a0c568e6ced7a58b6b6fce7a9495b8b6827
--- /dev/null
+++ b/libraries/base/dp/src/vhdl/dp_reinterleave.vhd
@@ -0,0 +1,211 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- 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/>.
+--
+--------------------------------------------------------------------------------
+
+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;
+
+-- Purpose: DP wrapper for common_reinterleave
+-- Description:
+-- Remarks:
+-- . Requirements: 
+--   * All input streams must be synchronous;
+--   * g_inter_block_size >= g_deint_block_size;
+--   * Correct forwarding of SOP, EOP and Sync (g_use_ctrl=TRUE) requires that:
+--    . g_nof_in = g_nof_out;
+--    . No gaps between SOP and EOP;
+--    . g_deint_block_size = g_block_size out
+--    . Input block length (!= g_deint_block_size) / nof_out / g_block_size_x = integer. 
+--      If it is not an integer number, the input blocks cannot be evenly distributed over
+--      the outputs with the chosen block_size_x.
+
+ENTITY dp_reinterleave IS
+  GENERIC (
+    g_dat_w          : NATURAL;
+    g_nof_in         : NATURAL;
+    g_deint_block_size  : NATURAL; -- Inputs streams will be de-interleaved using this block size. Should match block_size_out when g_use_ctrl=TRUE
+    g_nof_out        : NATURAL;
+    g_inter_block_size : NATURAL; -- Outputs streams will be interleaved using this block size. Should match block_size_in when g_use_ctrl=TRUE
+    g_use_ctrl       : BOOLEAN := TRUE;
+    g_use_complex    : BOOLEAN;
+    g_align_out  : BOOLEAN := FALSE
+  );
+  PORT (
+    rst         : IN  STD_LOGIC;
+    clk         : IN  STD_LOGIC;
+
+    snk_in_arr  : IN  t_dp_sosi_arr(g_nof_in-1 DOWNTO 0);
+    src_out_arr : OUT t_dp_sosi_arr(g_nof_out-1 DOWNTO 0)
+  );
+END dp_reinterleave;
+
+
+ARCHITECTURE wrap OF dp_reinterleave IS
+
+  CONSTANT c_complex_w : NATURAL := g_dat_w/2;
+
+  -- common_interleave latency: multiplexer input register stage
+  CONSTANT c_inter_mux_latency : NATURAL := 1;
+
+  -- common_interleave latency: common_blockreg latencies: see common_blockreg.vhd for details
+  CONSTANT c_common_blockreg_latency       : NATURAL := 1;
+  CONSTANT c_common_blockreg_valid_latency : NATURAL := g_inter_block_size*g_nof_out - (g_deint_block_size*g_nof_out - g_deint_block_size);
+
+  -- Arrays flattened into SLVs
+  SIGNAL in_dat        : STD_LOGIC_VECTOR(g_nof_in*g_dat_w-1 DOWNTO 0);
+
+  SIGNAL out_dat       : STD_LOGIC_VECTOR(g_nof_out*g_dat_w-1 DOWNTO 0);
+  SIGNAL out_val       : STD_LOGIC_VECTOR(g_nof_out-1 DOWNTO 0);
+
+BEGIN
+
+  -----------------------------------------------------------------------------
+  -- Map input sosi_arr to SLV
+  -----------------------------------------------------------------------------
+  gen_wires_in : FOR i IN 0 TO g_nof_in-1 GENERATE 
+    gen_sosi_dat_in: IF g_use_complex = FALSE GENERATE
+      -----------------------------------------------------------------------------
+      -- Forward SOSI data field
+      -----------------------------------------------------------------------------
+      in_dat( i*g_dat_w+g_dat_w -1 DOWNTO i*g_dat_w) <= snk_in_arr(i).data(g_dat_w-1 DOWNTO 0);
+    END GENERATE;
+
+    gen_sosi_compl_in: IF g_use_complex = TRUE GENERATE
+      -----------------------------------------------------------------------------
+      -- Forward concatenated im & re fields
+      -----------------------------------------------------------------------------
+      in_dat( i*g_dat_w+g_dat_w -1 DOWNTO i*g_dat_w) <= snk_in_arr(i).im(c_complex_w-1 DOWNTO 0) & snk_in_arr(i).re(c_complex_w-1 DOWNTO 0);
+    END GENERATE;
+  END GENERATE;
+
+  u_reinterleave : ENTITY common_lib.common_reinterleave
+  GENERIC MAP (
+    g_nof_in         => g_nof_in,
+    g_deint_block_size  => g_deint_block_size,
+    g_nof_out        => g_nof_out,
+    g_inter_block_size => g_inter_block_size,
+    g_dat_w          => g_dat_w,
+    g_align_out => g_align_out
+  )
+  PORT MAP (
+    rst        => rst,
+    clk        => clk,
+    
+    in_dat     => in_dat,
+    in_val     => snk_in_arr(0).valid, -- All input streams should be synchronous
+    
+    out_dat    => out_dat,
+    out_val    => out_val
+  );
+
+  -----------------------------------------------------------------------------
+  -- Map output SLV to sosi_arr
+  -----------------------------------------------------------------------------
+  gen_wires_out : FOR i IN 0 TO g_nof_out-1 GENERATE
+    gen_sosi_dat_out: IF g_use_complex = FALSE GENERATE
+      -----------------------------------------------------------------------------
+      -- Forward SOSI data field
+      -----------------------------------------------------------------------------
+      src_out_arr(i).data(g_dat_w-1 DOWNTO 0) <= out_dat( i*g_dat_w+g_dat_w -1 DOWNTO i*g_dat_w);
+    END GENERATE;
+    
+    gen_sosi_compl_out: IF g_use_complex = TRUE GENERATE
+      -----------------------------------------------------------------------------
+      -- Forward concatenated im & re fields
+      -----------------------------------------------------------------------------
+      src_out_arr(i).im <= RESIZE_DP_DSP_DATA(out_dat( i*g_dat_w + g_dat_w     -1 DOWNTO i*g_dat_w + c_complex_w));
+      src_out_arr(i).re <= RESIZE_DP_DSP_DATA(out_dat( i*g_dat_w + c_complex_w -1 DOWNTO i*g_dat_w));
+    END GENERATE;
+
+    src_out_arr(i).valid <= out_val(i);
+  END GENERATE;
+
+  -----------------------------------------------------------------------------
+  -- Forward SOP, EOP and Sync of snk_in(0) to all outputs, with the correct 
+  -- delays. Don't compensate for asynchronous deinterleaver output streams
+  -- when g_align_out is true.
+  -----------------------------------------------------------------------------
+  gen_ctrl : if g_use_ctrl=TRUE GENERATE
+    gen_pipe_sop: FOR i IN 0 TO g_nof_out-1 GENERATE 
+      u_shiftreg_sop : ENTITY common_lib.common_shiftreg
+      GENERIC MAP (
+        g_pipeline  => c_common_blockreg_latency + c_inter_mux_latency,
+        g_nof_dat   => 1 + c_common_blockreg_valid_latency + sel_a_b(g_align_out, (g_nof_out-1)*g_deint_block_size, (i*g_deint_block_size)),
+        g_dat_w     => 1 
+      )
+      PORT MAP (
+        rst          => rst,
+        clk          => clk,
+        
+        in_dat       => slv(snk_in_arr(0).sop),        
+        sl(out_dat)  => src_out_arr(i).sop
+      );
+ 
+      u_shiftreg_eop : ENTITY common_lib.common_shiftreg
+      GENERIC MAP (
+        g_pipeline  => c_common_blockreg_latency + c_inter_mux_latency,
+        g_nof_dat   => 1 + c_common_blockreg_valid_latency + sel_a_b(g_align_out, (g_nof_out-1)*g_deint_block_size, (i*g_deint_block_size)),
+        g_dat_w     => 1,
+        g_flush_en  => TRUE -- Flush out the EOP immediately
+      )
+      PORT MAP (
+        rst          => rst,
+        clk          => clk,
+        
+        in_dat       => slv(snk_in_arr(0).eop),
+        in_eop       => snk_in_arr(0).eop, 
+        sl(out_dat)  => src_out_arr(i).eop  
+       );
+ 
+      u_shiftreg_sync : ENTITY common_lib.common_shiftreg
+      GENERIC MAP (
+        g_pipeline  => c_common_blockreg_latency + c_inter_mux_latency,
+        g_nof_dat   => 1 + c_common_blockreg_valid_latency + sel_a_b(g_align_out, (g_nof_out-1)*g_deint_block_size, (i*g_deint_block_size)), 
+        g_dat_w     => 1 
+      )
+      PORT MAP (
+        rst          => rst,
+        clk          => clk,
+        
+        in_dat       => slv(snk_in_arr(0).sync),       
+        sl(out_dat)  => src_out_arr(i).sync
+      );
+
+      u_shiftreg_bsn : ENTITY common_lib.common_shiftreg
+      GENERIC MAP (
+        g_pipeline  => c_common_blockreg_latency + c_inter_mux_latency,
+        g_nof_dat   => 1 + c_common_blockreg_valid_latency + sel_a_b(g_align_out, (g_nof_out-1)*g_deint_block_size, (i*g_deint_block_size)), 
+        g_dat_w     => c_dp_stream_bsn_w
+      )
+      PORT MAP (
+        rst          => rst,
+        clk          => clk,
+        
+        in_dat       => snk_in_arr(0).bsn,       
+        out_dat      => src_out_arr(i).bsn
+      );
+  
+    END GENERATE;
+  END GENERATE;
+
+END wrap;
diff --git a/libraries/base/dp/tb/vhdl/tb_dp_reinterleave.vhd b/libraries/base/dp/tb/vhdl/tb_dp_reinterleave.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f03a80372c76bd7312140479d410a10369f355c2
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_dp_reinterleave.vhd
@@ -0,0 +1,150 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- 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/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE work.dp_stream_pkg.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+
+-- Purpose: Test bench to check deinterleave function on DP level
+-- Usage:
+--   > as 6
+--   > run -all
+-- Remark: 
+--   This TB is only used to visually inspect the wave window to see
+--   if all functions well on DP level. The actual deinterleaving itself
+--   is verified more thoroughly in tb_common_reinterleave.
+
+ENTITY tb_dp_deinterleave IS
+  GENERIC (
+    g_dat_w       : NATURAL := 16;
+    g_nof_out     : NATURAL := 2;
+    g_block_size  : NATURAL := 3;
+    g_use_complex : BOOLEAN := TRUE
+ );
+END;
+
+ARCHITECTURE tb OF tb_dp_deinterleave IS
+
+  TYPE t_dsp_data_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_dat_w/2-1 DOWNTO 0);
+  TYPE t_data_arr     IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
+  TYPE t_val_arr      IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC;
+
+  -----------------------------------------------------------------------------
+  -- Standard TB clocking, RST and control
+  -----------------------------------------------------------------------------
+  CONSTANT c_clk_period : TIME := 10 ns;
+
+  SIGNAL clk            : STD_LOGIC := '1';
+  SIGNAL rst            : STD_LOGIC;
+  SIGNAL tb_end         : STD_LOGIC := '0';
+
+  SIGNAL cnt_ena        : STD_LOGIC;
+
+  -----------------------------------------------------------------------------
+  --I/O streams
+  -----------------------------------------------------------------------------
+  CONSTANT c_input_val   : NATURAL := 192;
+  CONSTANT c_input_inval : NATURAL := 64;
+
+  SIGNAL snk_in  : t_dp_sosi;
+  SIGNAL snk_out : t_dp_siso;
+
+  SIGNAL src_out_arr : t_dp_sosi_arr(g_nof_out-1 DOWNTO 0);
+  
+  -----------------------------------------------------------------------------
+  --Monitor signals for wave window
+  -----------------------------------------------------------------------------
+  SIGNAL in_data      :  STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
+  SIGNAL in_re        :  STD_LOGIC_VECTOR(g_dat_w/2-1 DOWNTO 0);
+  SIGNAL in_im        :  STD_LOGIC_VECTOR(g_dat_w/2-1 DOWNTO 0);
+  SIGNAL in_val       :  STD_LOGIC;
+  SIGNAL out_data_arr :  t_data_arr(g_nof_out-1 DOWNTO 0);
+  SIGNAL out_re_arr   :  t_dsp_data_arr(g_nof_out-1 DOWNTO 0);
+  SIGNAL out_im_arr   :  t_dsp_data_arr(g_nof_out-1 DOWNTO 0);
+  SIGNAL out_val_arr  :  t_val_arr(g_nof_out-1 DOWNTO 0);
+  
+BEGIN
+
+  -----------------------------------------------------------------------------
+  -- Standard TB clocking, RST and control
+  -----------------------------------------------------------------------------
+  clk    <= NOT clk OR tb_end AFTER c_clk_period/2;
+  rst    <= '1', '0' AFTER 3*c_clk_period;
+
+  tb_end <= '0', '1' AFTER 2 us;
+  
+  -----------------------------------------------------------------------------
+  -- Generate test data stream with counter data
+  -----------------------------------------------------------------------------
+  cnt_ena <= '0', '1' AFTER 20*c_clk_period;
+
+  snk_out.ready <= '1';
+  snk_out.xon <= '1';
+
+  p_stimuli : PROCESS
+    VARIABLE v_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');
+  BEGIN
+    WHILE TRUE LOOP
+      WAIT UNTIL rising_edge(clk);
+      proc_dp_gen_block_data(1, sel_a_b(g_use_complex, FALSE, TRUE), g_dat_w, g_dat_w, 0, 0, 0, c_input_val, 0, 0, '1', v_bsn, clk, cnt_ena, snk_out, snk_in);
+      proc_common_wait_some_cycles(clk, c_input_inval);
+      v_bsn := INCR_UVEC(v_bsn, 1);
+    END LOOP;
+   END PROCESS;
+
+  -----------------------------------------------------------------------------
+  -- DUT
+  -----------------------------------------------------------------------------
+  u_deinterleave : ENTITY work.dp_deinterleave
+  GENERIC MAP (
+    g_nof_out      => g_nof_out,
+    g_block_size   => g_block_size,
+    g_dat_w        => g_dat_w,
+    g_use_complex  => g_use_complex
+  )
+  PORT MAP (
+    rst        => rst,
+    clk        => clk,
+    
+    snk_in      => snk_in, 
+    src_out_arr => src_out_arr
+  );
+
+  
+  -----------------------------------------------------------------------------
+  -- Wave window monitor
+  -----------------------------------------------------------------------------
+  in_data <= snk_in.data(g_dat_w-1 DOWNTO 0);
+  in_re   <= snk_in.re(g_dat_w/2-1 DOWNTO 0);
+  in_im   <= snk_in.im(g_dat_w/2-1 DOWNTO 0);
+  in_val  <= snk_in.valid;
+
+  gen_out : FOR I IN g_nof_out-1 DOWNTO 0 GENERATE
+    out_data_arr(I)<= src_out_arr(I).data(g_dat_w-1 DOWNTO 0);
+    out_re_arr(I)  <= src_out_arr(I).re(g_dat_w/2-1 DOWNTO 0);
+    out_im_arr(I)  <= src_out_arr(I).im(g_dat_w/2-1 DOWNTO 0);
+    out_val_arr(I) <= src_out_arr(I).valid;
+  END GENERATE;
+  
+END tb;