diff --git a/libraries/dsp/filter/tb/vhdl/tb_fil_ppf_single.vhd b/libraries/dsp/filter/tb/vhdl/tb_fil_ppf_single.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..c0304fe5fb76184b61119d3d6a68524683def62f
--- /dev/null
+++ b/libraries/dsp/filter/tb/vhdl/tb_fil_ppf_single.vhd
@@ -0,0 +1,207 @@
+-- Author: Harm Jan Pepping : HJP at astron.nl: April 2012
+--------------------------------------------------------------------------------
+--
+-- 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/>.
+--
+--------------------------------------------------------------------------------
+
+--
+-- Purpose: Test bench for the single channel Poly Phase Filter unit
+--
+--          The testbech inserts an impulse on every band. The output 
+--          is verified by checking if the output values equal the 
+--          filter coefficients: It verifies the impulse-response. 
+--
+-- Usage:
+--   > run -all
+--   > testbench is selftesting. The first four spectrums are verified. 
+--
+
+library ieee, common_lib, dp_lib, diag_lib;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use IEEE.std_logic_textio.all;
+use STD.textio.all;
+use common_lib.common_pkg.all;
+use common_lib.common_mem_pkg.ALL;
+use common_lib.tb_common_pkg.all;
+use common_lib.tb_common_mem_pkg.ALL;
+use dp_lib.dp_stream_pkg.ALL;
+use work.fil_pkg.all;
+
+entity tb_fil_ppf_single is
+  generic(
+    -- generics for tb
+    g_fil_ppf_pipeline : t_fil_ppf_pipeline := (1, 1, 1, 1, 1, 1, 0);  
+      -- type t_fil_pipeline is record
+      --   -- generic for the taps and coefficients memory
+      --   mem_delay      : natural;  -- = 2
+      --   -- generics for the multiplier in in the filter unit
+      --   mult_input     : natural;  -- = 1
+      --   mult_product   : natural;  -- = 1
+      --   mult_output    : natural;  -- = 1                   
+      --   -- generics for the adder tree in in the filter unit
+      --   adder_stage    : natural;  -- = 1
+      --   -- generics for the requantizer in the filter unit
+      --  requant_remove_lsb : natural;  -- = 1
+      --  requant_remove_msb : natural;  -- = 0
+      -- end record;
+    g_fil_ppf : t_fil_ppf := (1, 2, 512, 16, 4, 8, 23, 16); 
+      -- type t_fil_ppf is record
+      --   wb_factor      : natural; -- = 1, the wideband factor
+      --   nof_chan       : natural; -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan 
+      --   nof_bands      : natural; -- = 512, the number of subbands is N/2 (N=nof_points of the FFT)
+      --   nof_taps       : natural; -- = 16, the number of FIR taps per subband
+      --   nof_streams    : natural; -- = 1, the number of streams that are served by the same coefficients. 
+      --   in_dat_w       : natural; -- = 8, number of input bits per stream
+      --   out_dat_w      : natural; -- = 23, number of output bits (per stream). It is set to 23 to be sure the requantizer does not remove
+      --                                  any of the data in order to be able to verify with the original coefficients values. 
+      --   coef_dat_w     : natural; -- = 16, data width of the FIR coefficients
+      -- end record;
+    g_file_index_arr    : t_nat_natural_arr := array_init(0, 128, 1); 
+    g_coefs_file_prefix : string            := "../../data/coef"      
+  );
+end entity tb_fil_ppf_single;
+
+architecture tb of tb_fil_ppf_single is
+  
+  constant c_clk_period : time    := 10 ns;
+  constant c_nof_coefs  : natural := g_fil_ppf.nof_taps*g_fil_ppf.nof_bands*2**g_fil_ppf.nof_chan;
+
+  -- input/output data width
+
+  constant c_in_dat_w   : natural := g_fil_ppf.in_dat_w;   
+  constant c_out_dat_w  : natural := g_fil_ppf.out_dat_w;
+
+  -- signal definitions
+  signal tb_end         : std_logic := '0';
+  signal clk            : std_logic := '0';
+  signal rst            : std_logic := '0';
+
+  signal ram_coefs_mosi : t_mem_mosi;  
+  signal ram_coefs_miso : t_mem_miso;  
+  
+  signal in_dat         : std_logic_vector(c_in_dat_w*g_fil_ppf.nof_streams-1 downto 0); 
+  signal in_val         : std_logic; 
+
+  signal out_dat        : std_logic_vector(c_out_dat_w*g_fil_ppf.nof_streams-1 downto 0); 
+  signal out_val        : std_logic; 
+  
+  signal ref_dat_arr    : t_integer_arr(c_nof_coefs-1 downto 0);
+  signal ref_arr        : t_integer_arr(g_fil_ppf.nof_bands-1 downto 0); 
+  signal ref_dat        : integer; 
+  signal ref_index      : natural; 
+    
+begin
+
+  clk <= (not clk) or tb_end after c_clk_period/2;
+  rst <= '1', '0' after c_clk_period*7;
+
+  
+  ram_coefs_mosi <= c_mem_mosi_rst;             -- Reset the master out interface
+  ---------------------------------------------------------------
+  -- SEND IMPULSE TO THE DATA INPUT
+  ---------------------------------------------------------------  
+  p_send_impulse : PROCESS                                                     
+  BEGIN
+    tb_end <= '0';                          
+    in_dat <= (OTHERS => '0'); 
+    in_val <= '0';
+    proc_common_wait_until_low(clk, rst);         -- Wait until reset has finished
+    proc_common_wait_some_cycles(clk, 10);        -- Wait an additional amount of cycles
+    FOR I IN 0 TO g_fil_ppf.nof_bands*(2**g_fil_ppf.nof_chan)-1 LOOP        
+      FOR J in 0 To g_fil_ppf.nof_streams-1 LOOP
+        in_dat((J+1)*c_in_dat_w-1 DOWNTO J*c_in_dat_w) <= TO_UVEC(1, c_in_dat_w); 
+      END LOOP;
+      in_val <= '1';                      
+      proc_common_wait_some_cycles(clk, 1);
+    END LOOP;
+    FOR J IN 0 TO g_fil_ppf.nof_taps-2 + 2 LOOP                                                
+      FOR I IN 0 TO g_fil_ppf.nof_bands-1 LOOP        
+        in_dat <= (OTHERS => '0'); 
+        in_val <= '1';
+        proc_common_wait_some_cycles(clk, 1);
+      END LOOP;
+    END LOOP;                            
+    in_dat <= (OTHERS => '0'); 
+    in_val <= '0';
+    proc_common_wait_some_cycles(clk, 10);  
+    tb_end <= '1';                                          
+    WAIT;
+  END PROCESS;
+  
+  ---------------------------------------------------------------  
+  -- CREATE REFERENCE ARRAY
+  ---------------------------------------------------------------  
+  p_create_ref : PROCESS                                                     
+  begin
+    for J in 0 to g_fil_ppf.nof_taps-1 loop
+      proc_common_read_mif_file(g_coefs_file_prefix & "_" & integer'image(J) & ".mif", ref_arr); 
+      wait for 1 ns;  
+      for I in 0 to g_fil_ppf.nof_bands-1 loop   
+        for K in 0 to 2**g_fil_ppf.nof_chan-1 loop
+          ref_dat_arr(J*g_fil_ppf.nof_bands*2**g_fil_ppf.nof_chan + I*2**g_fil_ppf.nof_chan + K) <= TO_SINT(TO_UVEC(ref_arr(I), 16));
+        end loop;
+      end loop;
+    end loop;                            
+  wait;   
+  end process;  
+
+  ---------------------------------------------------------------  
+  -- MAKE THE REFERENCE STREAM
+  ---------------------------------------------------------------  
+  ref_index  <= ref_index + 1 when rising_edge(clk) and out_val='1' and ref_index < c_nof_coefs-1;
+  ref_dat    <= ref_dat_arr(ref_index);
+    
+  ---------------------------------------------------------------  
+  -- DUT = Device Under Test
+  ---------------------------------------------------------------  
+  u_dut : entity work.fil_ppf_single 
+  generic map (
+    g_fil_ppf           => g_fil_ppf,
+    g_fil_ppf_pipeline  => g_fil_ppf_pipeline,
+    g_file_index_arr    => g_file_index_arr,
+    g_coefs_file_prefix => g_coefs_file_prefix 
+  )
+  port map (
+    dp_clk         => clk,
+    dp_rst         => rst,
+    mm_clk         => clk,
+    mm_rst         => rst,
+    ram_coefs_mosi => ram_coefs_mosi, 
+    ram_coefs_miso => ram_coefs_miso, 
+    in_dat         => in_dat,
+    in_val         => in_val,
+    out_dat        => out_dat,
+    out_val        => out_val
+  ); 
+    
+  -- Verify the output of the DUT with the expected output from the reference array
+  p_verify_output : process(clk)
+  begin
+    -- Compare
+    if rising_edge(clk) then
+      if out_val='1' and ref_index < c_nof_coefs-1 then
+        for I in 0 to g_fil_ppf.nof_streams-1 loop
+          assert TO_SINT(out_dat((I+1)*g_fil_ppf.out_dat_w-1 downto I*g_fil_ppf.out_dat_w)) = ref_dat  report "Output data error" severity error;
+        end loop;
+      end if;
+    end if;
+  end process;
+
+end tb;
\ No newline at end of file
diff --git a/libraries/dsp/filter/tb/vhdl/tb_fil_ppf_wide.vhd b/libraries/dsp/filter/tb/vhdl/tb_fil_ppf_wide.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f962f7fd5096c54256b9baa5f60d2f1031658f83
--- /dev/null
+++ b/libraries/dsp/filter/tb/vhdl/tb_fil_ppf_wide.vhd
@@ -0,0 +1,270 @@
+-- Author: Harm Jan Pepping : HJP at astron.nl: April 2012
+--------------------------------------------------------------------------------
+--
+-- 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/>.
+--
+--------------------------------------------------------------------------------
+
+--
+-- Purpose: Test bench for the multi channel Poly Phase PreFilter unit
+--
+--          The testbech inserts an impulse on every band. The output 
+--          is verified by checking if the output values equal the 
+--          filter coefficients: It verifies the impulse-response. 
+--
+--          It is possible to vary wb_factor, nof_chan, nof_bands, nof_taps 
+--          and nof_streams. 
+--          Note that for each specific combination of wb_factor, nof_bands
+--          and nof_taps a new set of mif-files must be created. The mif-files
+--          are used to initially load the coefficients in the rams.
+--          Use the script ../../src/python/create_mifs.py to create the required
+--          mif files. 
+--          For wb_factor = 2, nof_bands = 1024, nof_taps = 8 the script
+--          should be called like this: 
+--
+--          > create_mifs.py -t 8 -b 1024 -w 2  
+--
+--          The generated mif files will be placed in ../../build/data/
+--
+--
+-- Usage:
+--   > run -all
+--   > testbench is selftesting. 
+--
+
+library ieee, common_lib, dp_lib, diag_lib;
+use IEEE.std_logic_1164.all;                                            
+use IEEE.numeric_std.all;
+use IEEE.std_logic_textio.all;
+use STD.textio.all;
+use common_lib.common_pkg.all;
+use common_lib.common_mem_pkg.ALL;
+use common_lib.tb_common_pkg.all;
+use common_lib.tb_common_mem_pkg.ALL;
+use dp_lib.dp_stream_pkg.ALL;
+use work.fil_pkg.all;
+
+entity tb_fil_ppf_wide is
+  generic(
+    -- generics for tb
+    g_fil_ppf_pipeline : t_fil_ppf_pipeline := (1, 1, 1, 1, 1, 1, 0);  
+      -- type t_fil_pipeline is record
+      --   -- generic for the taps and coefficients memory
+      --   mem_delay      : natural;  -- = 1
+      --   -- generics for the multiplier in in the filter unit
+      --   mult_input     : natural;  -- = 1
+      --   mult_product   : natural;  -- = 1
+      --   mult_output    : natural;  -- = 1                   
+      --   -- generics for the adder tree in in the filter unit
+      --   adder_stage    : natural;  -- = 1
+      -- end record;
+      -- type t_fil_pipeline is record
+      --   -- generic for the taps and coefficients memory
+      --   mem_delay      : natural;  -- = 2
+      --   -- generics for the multiplier in in the filter unit
+      --   mult_input     : natural;  -- = 1
+      --   mult_product   : natural;  -- = 1
+      --   mult_output    : natural;  -- = 1                   
+      --   -- generics for the adder tree in in the filter unit
+      --   adder_stage    : natural;  -- = 1
+      --   -- generics for the requantizer in the filter unit
+      --  requant_remove_lsb : natural;  -- = 1
+      --  requant_remove_msb : natural;  -- = 0
+      -- end record;
+    g_fil_ppf : t_fil_ppf := (4, 2, 1024, 16, 2, 8, 23, 16); 
+      -- type t_fil_ppf is record
+      --   wb_factor      : natural; -- = 4, the wideband factor
+      --   nof_chan       : natural; -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan 
+      --   nof_bands      : natural; -- = 1024, the number of subbands is N/2 (N=nof_points of the FFT)
+      --   nof_taps       : natural; -- = 16, the number of FIR taps per subband
+      --   nof_streams    : natural; -- = 1, the number of streams that are served by the same coefficients. 
+      --   in_dat_w       : natural; -- = 8, number of input bits per stream
+      --   out_dat_w      : natural; -- = 23, number of output bits. It is set to 23 to be sure the requantizer does not removes
+      --                                  any of the data in order to be able to verify with the original coefficients values. 
+      --   coef_dat_w     : natural; -- = 16, data width of the FIR coefficients
+      -- end record;
+    g_file_index_arr    : t_nat_natural_arr := array_init(0, 128, 1); 
+    g_coefs_file_prefix : string            := "../../data/coefs_wide"      
+  );
+end entity tb_fil_ppf_wide;
+
+architecture tb of tb_fil_ppf_wide is
+  
+  constant c_clk_period : time    := 10 ns;
+  constant c_nof_coefs  : natural := g_fil_ppf.nof_taps*g_fil_ppf.nof_bands;
+
+  constant c_coefs_file_prefix : string := g_coefs_file_prefix & natural'image(g_fil_ppf.wb_factor) & "_p"& natural'image(g_fil_ppf.nof_bands) & "_t"& natural'image(g_fil_ppf.nof_taps);
+
+  -- input/output data width
+  constant c_in_dat_w             : natural := g_fil_ppf.in_dat_w;   
+  constant c_out_dat_w            : natural := g_fil_ppf.in_dat_w + g_fil_ppf.coef_dat_w + ceil_log2(g_fil_ppf.nof_taps);
+  constant c_nof_bands_per_stream : natural := g_fil_ppf.nof_bands / g_fil_ppf.wb_factor;
+  constant c_nof_chan             : natural := 2**g_fil_ppf.nof_chan;
+
+  type t_integer_arr2 is array(integer range <> ) of t_integer_arr(c_nof_coefs/g_fil_ppf.wb_factor-1 downto 0);
+  
+  -- signal definitions
+  signal tb_end          : std_logic := '0';
+  signal clk             : std_logic := '0';
+  signal rst             : std_logic := '0';
+                         
+  signal ram_coefs_mosi  : t_mem_mosi;  
+  signal ram_coefs_miso  : t_mem_miso;  
+  signal coefs_arr       : t_integer_arr (c_nof_bands_per_stream-1 downto 0); 
+                         
+  signal in_dat_arr      : t_fil_slv_arr(g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 downto 0);
+  signal in_val          : std_logic; 
+                         
+  signal out_dat_arr     : t_fil_slv_arr(g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 downto 0);
+  signal out_val         : std_logic; 
+                         
+  signal ref_dat_arr     : t_integer_arr (g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 downto 0);
+  signal ref_dat_arr2    : t_integer_arr2(g_fil_ppf.wb_factor-1 downto 0);
+  signal ref_arr         : t_integer_arr (c_nof_bands_per_stream-1 downto 0); 
+  signal ref_index       : natural := 0; 
+  signal chn_index       : natural := 0; 
+  signal coefs_mem_write : boolean := FALSE;                             
+    
+begin
+
+  clk <= (not clk) or tb_end after c_clk_period/2;
+  rst <= '1', '0' after c_clk_period*7;
+ 
+  ---------------------------------------------------------------
+  -- WRITE THE COEFFICIENTS TO THE COEFS MEMORY
+  ---------------------------------------------------------------  
+  p_coefs_memory_write : process                                                     
+  begin
+    coefs_mem_write <= FALSE;                           
+    ram_coefs_mosi  <= c_mem_mosi_rst;             -- Reset the master out interface
+    for K in 0 to g_fil_ppf.wb_factor-1 loop
+      for J in 0 to g_fil_ppf.nof_taps-1 loop
+        proc_common_read_mif_file(c_coefs_file_prefix & "_" & integer'image(k*g_fil_ppf.nof_taps+J) & ".mif", coefs_arr); 
+        wait for 1 ns; 
+        for I in 0 to c_nof_bands_per_stream-1 loop 
+          proc_mem_mm_bus_wr(K*c_nof_bands_per_stream*g_fil_ppf.nof_taps + J*c_nof_bands_per_stream + I, coefs_arr(I), clk, ram_coefs_mosi); -- Write the coefficient to the memory       
+        end loop;
+      end loop; 
+    end loop;
+    coefs_mem_write <= TRUE;                           
+    wait;
+  end process;
+
+  ---------------------------------------------------------------
+  -- SEND IMPULSE TO THE DATA INPUT
+  ---------------------------------------------------------------  
+  p_send_impulse : process                                                     
+  begin
+    tb_end <= '0';                            
+    for I in 0 to g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 loop
+      in_dat_arr(I) <= (others => '0'); 
+    end loop;
+    in_val <= '0';
+    proc_common_wait_until_low(clk, rst);         -- Wait until reset has finished
+    proc_common_wait_some_cycles(clk, 10);        -- Wait an additional amount of cycles
+    wait until coefs_mem_write = TRUE; 
+    for J in 0 to c_nof_chan*c_nof_bands_per_stream-1 loop
+      for I in 0 to g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 loop
+        in_dat_arr(I) <= TO_UVEC(1, in_dat_arr(I)'LENGTH); 
+        in_val        <= '1';                      
+      end loop;
+      proc_common_wait_some_cycles(clk, 1);
+    end loop;
+    for K in 0 to g_fil_ppf.nof_taps-2 + 2 loop
+      for J in 0 to c_nof_chan*c_nof_bands_per_stream-1 loop  
+        for I in 0 to g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 loop      
+          in_dat_arr(I) <= (others => '0'); 
+          in_val        <= '1';
+        end loop;
+        proc_common_wait_some_cycles(clk, 1);
+      end loop;
+    end loop;                            
+    for I in 0 to g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 loop      
+      in_dat_arr(I) <= (others => '0'); 
+      in_val        <= '0';
+    end loop;    
+    proc_common_wait_some_cycles(clk, 10);  
+    tb_end <= '1';                                          
+    wait;
+  end process;
+  
+  ---------------------------------------------------------------  
+  -- CREATE REFERENCE ARRAY
+  ---------------------------------------------------------------  
+  p_create_ref : process                                                     
+  begin
+    for K in 0 to g_fil_ppf.wb_factor-1 loop
+      for J in 0 to g_fil_ppf.nof_taps-1 loop
+        proc_common_read_mif_file(c_coefs_file_prefix & "_" & integer'image(k*g_fil_ppf.nof_taps+J) & ".mif", ref_arr); 
+        wait for 1 ns;  
+        for I in 0 to c_nof_bands_per_stream-1 loop        
+          ref_dat_arr2(K)(J*c_nof_bands_per_stream + I) <= TO_SINT(TO_UVEC(ref_arr(I), 16));
+        end loop;
+      end loop; 
+    end loop;                           
+  wait;   
+  end process;  
+
+  ---------------------------------------------------------------  
+  -- MAKE THE REFERENCE STREAM
+  --------------------------------------------------------------- 
+  chn_index <= chn_index + 1 when (falling_edge(clk) and out_val='1') else 0 when (chn_index = c_nof_chan); 
+  ref_index <= ref_index + 1 when rising_edge(clk) and out_val='1' and ref_index < c_nof_coefs/g_fil_ppf.wb_factor-1 and chn_index = 0;
+  assign_ref_dat_arr_wb : for I in 0 to g_fil_ppf.wb_factor-1 generate
+    assign_ref_dat_arr_streams : for J in 0 to g_fil_ppf.nof_streams-1 generate
+      ref_dat_arr(I*g_fil_ppf.nof_streams+J) <= ref_dat_arr2(I)(ref_index);
+    end generate;
+  end generate;
+    
+  ---------------------------------------------------------------  
+  -- DUT = Device Under Test
+  ---------------------------------------------------------------  
+  u_dut : entity work.fil_ppf_wide 
+  generic map (
+    g_fil_ppf           => g_fil_ppf,
+    g_fil_ppf_pipeline  => g_fil_ppf_pipeline,
+    g_file_index_arr    => g_file_index_arr,
+    g_coefs_file_prefix => c_coefs_file_prefix 
+  )
+  port map (
+    dp_clk         => clk,
+    dp_rst         => rst,
+    mm_clk         => clk,
+    mm_rst         => rst,
+    ram_coefs_mosi => ram_coefs_mosi, 
+    ram_coefs_miso => ram_coefs_miso, 
+    in_dat_arr     => in_dat_arr,
+    in_val         => in_val,
+    out_dat_arr    => out_dat_arr,
+    out_val        => out_val
+  ); 
+    
+  -- Verify the output of the DUT with the expected output from the reference array
+  p_verify_output : process(clk)
+  begin
+    -- Compare
+    if rising_edge(clk) then
+      if out_val='1' and ref_index < c_nof_coefs/g_fil_ppf.wb_factor-1 then
+        for I in 0 to g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 loop
+          assert TO_SINT(out_dat_arr(I)(g_fil_ppf.out_dat_w-1 DOWNTO 0)) = ref_dat_arr(I)  report "Output data error" severity error;
+        end loop; 
+      end if;
+    end if;
+  end process;
+
+end tb;
\ No newline at end of file