diff --git a/libraries/dsp/filter/src/vhdl/fil_pkg.vhd b/libraries/dsp/filter/src/vhdl/fil_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..ff20ddc66866d096ae79f3d09a9e59fdb0bda71f
--- /dev/null
+++ b/libraries/dsp/filter/src/vhdl/fil_pkg.vhd
@@ -0,0 +1,67 @@
+-------------------------------------------------------------------------------
+-- Author: Harm Jan Pepping : pepping at astron.nl: 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/>.
+--
+-------------------------------------------------------------------------------
+
+library ieee, common_lib;
+use IEEE.std_logic_1164.all;
+use common_lib.common_pkg.all;
+
+package fil_pkg is
+
+  -- Parameters for the (wideband) poly phase filter. 
+  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; -- = 1024, the number of subbands is N (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; -- = 16, number of output bits per stream
+    coef_dat_w     : natural; -- = 16, data width of the FIR coefficients
+  end record;
+  
+  constant c_fil_ppf : t_fil_ppf := (1, 0, 1024, 16, 1, 8, 16, 16);
+  
+  -- Definitions for fil slv array (an array can not have unconstraint elements, so choose sufficiently wide 32 bit slv elements)
+  subtype  t_fil_slv_arr is t_slv_32_arr;    -- use subtype to ease interfacing to existing types and to have central definition for filter components
+  constant c_fil_data_w  : natural := 32;    -- match slv width of t_fil_slv_arr
+  
+  -- Record with the pipeline settings for the filter units. 
+  type t_fil_ppf_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
+    -- generics for the requantizer in the filter unit
+    requant_remove_lsb : natural;  -- = 1
+    requant_remove_msb : natural;  -- = 0
+  end record;
+  
+  constant c_fil_ppf_pipeline : t_fil_ppf_pipeline := (1, 1, 1, 1, 1, 1, 0);
+  
+end package fil_pkg;
+
+package body fil_pkg is
+end fil_pkg;
+
diff --git a/libraries/dsp/filter/src/vhdl/fil_ppf_ctrl.vhd b/libraries/dsp/filter/src/vhdl/fil_ppf_ctrl.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..7e5e83f6fa2a193e6a4dea6059c34514f893122e
--- /dev/null
+++ b/libraries/dsp/filter/src/vhdl/fil_ppf_ctrl.vhd
@@ -0,0 +1,142 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2009
+-- 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: Controlling the data streams for the filter units
+-- 
+-- Description: This unit prepairs the data streams for the ppf_filter 
+--              unit. Incoming data (in_dat) is combined with stored 
+--              data (taps_in_vec) to generate a new vector that is 
+--              offered to the filter unit: taps_out_vec. 
+--             
+--              It also delays the in_val signal in order to generate 
+--              the out_val that is proper alligned with the output data
+--              that is coming from the filter unit. 
+--              
+
+library IEEE, common_lib;
+use IEEE.std_logic_1164.ALL;
+use IEEE.numeric_std.ALL;
+use common_lib.common_pkg.ALL; 
+use work.fil_pkg.ALL;
+
+entity fil_ppf_ctrl is
+  generic (
+    g_fil_ppf          : t_fil_ppf; 
+    g_fil_ppf_pipeline : t_fil_ppf_pipeline
+  );
+  port (       
+    rst         : in  std_logic := '0';  
+    clk         : in  std_logic;         
+    in_dat      : in  std_logic_vector;
+    in_val      : in  std_logic;         
+    taps_in_vec : in  std_logic_vector;
+    taps_rdaddr : out std_logic_vector;
+    taps_wraddr : out std_logic_vector;
+    taps_wren   : out std_logic;         
+    taps_out_vec: out std_logic_vector;
+    out_val     : out std_logic
+  );
+end fil_ppf_ctrl;
+
+architecture rtl of fil_ppf_ctrl is
+  
+  type     t_in_dat_delay is array (g_fil_ppf_pipeline.mem_delay downto 0) of std_logic_vector(g_fil_ppf.in_dat_w*g_fil_ppf.nof_streams-1 downto 0);
+  
+  constant c_addr_w             : natural := ceil_log2(g_fil_ppf.nof_bands * (2**g_fil_ppf.nof_chan));
+  constant c_ctrl_latency       : natural := 1;                               -- due to taps_out_vec register
+  constant c_mult_latency       : natural := g_fil_ppf_pipeline.mult_input + g_fil_ppf_pipeline.mult_product + g_fil_ppf_pipeline.mult_output;
+  constant c_adder_latency      : natural := ceil_log2(g_fil_ppf.nof_taps) * g_fil_ppf_pipeline.adder_stage;
+
+  constant c_filter_zdly        : natural := g_fil_ppf.nof_bands * (2**g_fil_ppf.nof_chan); 
+  constant c_tot_latency        : natural := g_fil_ppf_pipeline.mem_delay + c_ctrl_latency + c_mult_latency + 
+                                             c_adder_latency + c_filter_zdly + g_fil_ppf_pipeline.requant_remove_lsb + 
+                                             g_fil_ppf_pipeline.requant_remove_msb;
+  constant c_single_taps_vec_w  : natural := g_fil_ppf.in_dat_w*g_fil_ppf.nof_taps;                                             
+  constant c_taps_vec_w         : natural := c_single_taps_vec_w*g_fil_ppf.nof_streams;
+  
+  type reg_type is record
+    in_dat_arr   : t_in_dat_delay;                             -- Input register for the data
+    val_dly      : std_logic_vector(c_tot_latency-1 downto 0); -- Delay register for the valid signal 
+    rd_addr      : std_logic_vector(c_addr_w-1 downto 0);      -- The read address
+    wr_addr      : std_logic_vector(c_addr_w-1 downto 0);      -- The write address
+    wr_en        : std_logic;                                  -- Write enable signal for the taps memory
+    taps_out_vec : std_logic_vector(c_taps_vec_w-1 downto 0);  -- Output register containing the next taps data
+  end record;
+  
+  signal r, rin : reg_type; 
+  
+begin
+  
+  comb : process(r, rst, in_val, in_dat, taps_in_vec)
+    variable v : reg_type;
+  begin
+
+    v := r;  
+    v.wr_en  := '0';  
+    
+    -- Perform the shifting for the shiftregister for the valid signal and the input data: 
+    v.val_dly(0) := in_val; 
+    v.val_dly(c_tot_latency-1 downto 1) := r.val_dly(c_tot_latency-2 downto 0);
+    v.in_dat_arr(0) := RESIZE_SVEC(in_dat, r.in_dat_arr(0)'LENGTH);           
+    v.in_dat_arr(g_fil_ppf_pipeline.mem_delay downto 1) := r.in_dat_arr(g_fil_ppf_pipeline.mem_delay-1 downto 0);
+    
+    if(r.val_dly(0) = '1') then                                 -- Wait for incoming data
+      v.rd_addr := INCR_UVEC(r.rd_addr, 1);
+    end if;                                     
+    
+    if(r.val_dly(g_fil_ppf_pipeline.mem_delay+1) = '1') then 
+      v.wr_addr := INCR_UVEC(r.wr_addr, 1);
+    end if; 
+
+    if(r.val_dly(g_fil_ppf_pipeline.mem_delay) = '1') then 
+      for I in 0 to g_fil_ppf.nof_streams-1 loop
+        v.taps_out_vec((I+1)*c_single_taps_vec_w-1 downto I*c_single_taps_vec_w) := taps_in_vec((I+1)*c_single_taps_vec_w - g_fil_ppf.in_dat_w -1 downto I*c_single_taps_vec_w) & r.in_dat_arr(g_fil_ppf_pipeline.mem_delay)((I+1)*g_fil_ppf.in_dat_w-1 downto I*g_fil_ppf.in_dat_w);
+      end loop;
+      --v.taps_out_vec := taps_in_vec(taps_in_vec'HIGH - g_fil_ppf.in_dat_w downto 0) & r.in_dat_arr(g_fil_ppf_pipeline.mem_delay);
+      v.wr_en        := '1';  
+    end if; 
+      
+    if(rst = '1') then
+      v.in_dat_arr   := (others => (others => '0'));
+      v.val_dly      := (others => '0');
+      v.rd_addr      := (others => '0');
+      v.wr_addr      := (others => '0');
+      v.wr_en        := '0';  
+      v.taps_out_vec := (others => '0');
+    end if;
+    
+    rin <= v;  
+    
+  end process comb;
+  
+  regs : process(clk)
+  begin 
+    if rising_edge(clk) then 
+      r <= rin; 
+    end if; 
+  end process; 
+  
+  taps_rdaddr  <= r.rd_addr;
+  taps_wraddr  <= r.wr_addr;
+  taps_wren    <= r.wr_en;
+  taps_out_vec <= r.taps_out_vec; 
+  out_val      <= r.val_dly(c_tot_latency-1);
+  
+end rtl;
diff --git a/libraries/dsp/filter/src/vhdl/fil_ppf_filter.vhd b/libraries/dsp/filter/src/vhdl/fil_ppf_filter.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..db3de4152c20e73091b04717d0f0371ff8c68ad4
--- /dev/null
+++ b/libraries/dsp/filter/src/vhdl/fil_ppf_filter.vhd
@@ -0,0 +1,136 @@
+-------------------------------------------------------------------------------
+--
+-- 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: A FIR filter implementation. 
+--
+-- Description: This unit instantiates a multiplier for every tap. 
+--              All output of the mutipliers are added using an 
+--              adder-tree structure. 
+--              
+-- Remarks:    .
+--              
+
+library IEEE, common_lib;
+use IEEE.std_logic_1164.ALL;
+use IEEE.numeric_std.ALL;
+use common_lib.common_pkg.ALL; 
+use work.fil_pkg.ALL;
+
+entity fil_ppf_filter is
+  generic (
+    g_fil_ppf          : t_fil_ppf; 
+    g_fil_ppf_pipeline : t_fil_ppf_pipeline
+  );
+  port (
+    clk        : in  std_logic;
+    rst        : in  std_logic;
+    taps       : in  std_logic_vector;   
+    coefs      : in  std_logic_vector;
+    result     : out std_logic_vector
+  ); 
+end fil_ppf_filter;
+
+architecture rtl of fil_ppf_filter is 
+
+  constant c_prod_w         : natural := g_fil_ppf.in_dat_w + g_fil_ppf.coef_dat_w - c_sign_w;    -- skip double sign bit
+  constant c_gain_w         : natural := 0;   -- no need for adder bit growth so fixed 0, because filter coefficients should have DC gain <= 1.
+                                              -- The adder tree bit growth depends on DC gain of FIR coefficients, not on ceil_log2(g_fil_ppf.nof_taps).
+  constant c_sum_w          : natural := c_prod_w + c_gain_w;
+  constant c_ppf_lsb_w      : natural := c_sum_w - g_fil_ppf.out_dat_w;
+  
+  signal prod_vec     : std_logic_vector(g_fil_ppf.nof_taps*c_prod_w-1 downto 0);
+  signal adder_out    : std_logic_vector(c_sum_w-1 downto 0) := (others => '0');
+  signal requant_out  : std_logic_vector(g_fil_ppf.out_dat_w-1 downto 0); 
+  
+  signal in_taps      : std_logic_vector(g_fil_ppf.in_dat_w*g_fil_ppf.nof_taps-1 downto 0); 
+
+begin 
+    
+  in_taps <= taps;  -- Use this help signal to create a 'HIGH downto 0 vector again.   
+  ---------------------------------------------------------------
+  -- GENERATE THE MUTIPLIERS
+  ---------------------------------------------------------------
+  -- For every tap a unique multiplier is instantiated that 
+  -- multiplies the data tap with the corresponding filter coefficient
+  gen_multipliers : for I in 0 to g_fil_ppf.nof_taps-1 generate                                                                            
+    u_multiplier : entity common_lib.common_mult(stratix4)
+    generic map (
+      g_in_a_w           => g_fil_ppf.in_dat_w,   
+      g_in_b_w           => g_fil_ppf.coef_dat_w, 
+      g_out_p_w          => c_prod_w,           
+      g_nof_mult         => 1,                    
+      g_pipeline_input   => g_fil_ppf_pipeline.mult_input,
+      g_pipeline_product => g_fil_ppf_pipeline.mult_product,  
+      g_pipeline_output  => g_fil_ppf_pipeline.mult_output, 
+      g_representation   => "SIGNED"            
+    )
+    port map (
+      rst      => rst,
+      clk      => clk,
+      clken    => '1',
+      in_a     => in_taps((I+1)*g_fil_ppf.in_dat_w-1 downto I*g_fil_ppf.in_dat_w),
+      in_b     => coefs((I+1)*g_fil_ppf.coef_dat_w-1 downto I*g_fil_ppf.coef_dat_w),
+      out_p    => prod_vec((I+1)*c_prod_w-1 downto I*c_prod_w)
+    );
+  end generate; 
+
+  ---------------------------------------------------------------
+  -- ADDER TREE
+  ---------------------------------------------------------------  
+  -- The adder tree summarizes the outputs of all multipliers.
+  u_adder_tree : entity common_lib.common_adder_tree(str) 
+  generic map (
+    g_representation => "SIGNED",
+    g_pipeline       => g_fil_ppf_pipeline.adder_stage,          
+    g_nof_inputs     => g_fil_ppf.nof_taps,
+    g_dat_w          => c_prod_w,
+    g_sum_w          => c_sum_w 
+  )
+  port map (
+    clk    => clk,
+    in_dat => prod_vec,
+    sum    => adder_out
+  );
+  
+  u_requantize_addeer_output : entity common_lib.common_requantize
+  generic map (
+    g_representation      => "SIGNED",      
+    g_lsb_w               => c_ppf_lsb_w,  
+    g_lsb_round           => TRUE,           
+    g_lsb_round_clip      => FALSE,      
+    g_msb_clip            => FALSE,            
+    g_msb_clip_symmetric  => FALSE,  
+    g_pipeline_remove_lsb => g_fil_ppf_pipeline.requant_remove_lsb, 
+    g_pipeline_remove_msb => g_fil_ppf_pipeline.requant_remove_msb, 
+    g_in_dat_w            => c_sum_w,            
+    g_out_dat_w           => g_fil_ppf.out_dat_w
+  )
+  port map (
+    clk        => clk,
+    clken      => '1',
+    in_dat     => adder_out,
+    out_dat    => requant_out, 
+    out_ovr    => open
+  );                  
+  
+  result <= RESIZE_SVEC(requant_out, result'LENGTH); 
+
+end rtl; 
+
diff --git a/libraries/dsp/filter/src/vhdl/fil_ppf_wide.vhd b/libraries/dsp/filter/src/vhdl/fil_ppf_wide.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..e547e97cd40912f6eb95b196c360e578ce335a02
--- /dev/null
+++ b/libraries/dsp/filter/src/vhdl/fil_ppf_wide.vhd
@@ -0,0 +1,187 @@
+-------------------------------------------------------------------------------
+--
+-- 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:   Performing a poly phase prefilter function on (multiple) wideband data stream.
+--
+--
+-- Description: The poly phase prefilter function is applied on multiple inputs.
+--              The incoming data must be divided over the inputs as shown in 
+--              the following example where the wideband factor is 4 (4 inputs).
+--
+--              Stream input 0 : t0, t4,  t8, t12, t16...
+--              Stream input 1 : t1, t5,  t9, t13, t17...
+--              Stream input 2 : t2, t6, t10, t14, t18...
+--              Stream input 3 : t3, t7, t11, t15, t19...
+--              
+--              Every input stream will be filtered by a single channel poly
+--              phase prefilter unit. 
+--              It is also possible to offer multiple wideband input streams. Those
+--              input streams will share the filtercoefficients. For a
+--              system with wb_factor=4 and nof_streams=2 the following stream 
+--              inputs should be offered (s0t0 means stream 0, timestamp 0):
+--
+--              Stream input 0 : s0t0, s0t4, s0t8 , s0t12, s0t16...
+--              Stream input 1 : s1t0, s1t4, s1t8 , s1t12, s1t16...
+--              Stream input 2 : s0t1, s0t5, s0t9 , s0t13, s0t17...
+--              Stream input 3 : s1t1, s1t5, s1t9 , s1t13, s1t17...
+--              Stream input 4 : s0t2, s0t6, s0t10, s0t14, s0t18...
+--              Stream input 5 : s1t2, s1t6, s1t10, s1t14, s1t18...
+--              Stream input 6 : s0t3, s0t7, s0t11, s0t15, s0t19...
+--              Stream input 7 : s1t3, s1t7, s1t11, s1t15, s1t19...
+
+--
+-- Remarks:    .
+--              
+
+library IEEE, common_lib;
+use IEEE.std_logic_1164.ALL;
+use IEEE.numeric_std.ALL;
+use common_lib.common_pkg.ALL; 
+use common_lib.common_mem_pkg.ALL;  
+use work.fil_pkg.ALL;
+
+entity fil_ppf_wide is
+  generic (
+    g_fil_ppf           : t_fil_ppf          := c_fil_ppf;    
+    g_fil_ppf_pipeline  : t_fil_ppf_pipeline := c_fil_ppf_pipeline; 
+    g_file_index_arr    : t_nat_natural_arr  := array_init(0, 128, 1);  -- default use the instance index as file index 0, 1, 2, 3, 4 ...
+    g_coefs_file_prefix : string             := "../../data/coef"       -- Relative path to the mif files that contain the initial data for the coefficients memories 
+  );                                                                    -- The sequence number and ".mif"-extension are added within the entity.
+  port (
+    dp_clk         : in  std_logic;
+    dp_rst         : in  std_logic;
+    mm_clk         : in  std_logic;
+    mm_rst         : in  std_logic;
+    ram_coefs_mosi : in  t_mem_mosi;               
+    ram_coefs_miso : out t_mem_miso := c_mem_miso_rst;
+    in_dat_arr     : in  t_fil_slv_arr(g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 downto 0);
+    in_val         : in  std_logic;  
+    out_dat_arr    : out t_fil_slv_arr(g_fil_ppf.nof_streams*g_fil_ppf.wb_factor-1 downto 0);
+    out_val        : out std_logic
+  ); 
+end fil_ppf_wide;
+
+architecture rtl of fil_ppf_wide is   
+
+  type t_fil_ppf_arr      is array(integer range <> ) of t_fil_ppf;                       -- An array of t_fil_ppf's generics.                                                                              
+  type t_nat_natural_arr2 is array(integer range <> ) of t_nat_natural_arr(127 downto 0); -- An array of arrays, used to point to the right .mif files for the coefficients
+  type t_out_arr          is array(integer range <> ) of std_logic_vector(g_fil_ppf.nof_streams*g_fil_ppf.out_dat_w -1 downto 0);
+  type t_in_arr           is array(integer range <> ) of std_logic_vector(g_fil_ppf.nof_streams*g_fil_ppf.in_dat_w  -1 downto 0);
+  
+  ----------------------------------------------------------
+  -- This function creates an array of t_fil_ppf generics 
+  -- for the single channel poly phase filters that are 
+  -- used to compose the multichannel(wideband) poly phase
+  -- filter. The array is based on the content of the g_fil_ppf
+  -- generic that belongs to the fil_ppf_w entity. 
+  -- Only the nof_bands is modified. 
+  ----------------------------------------------------------
+  function func_create_generics_for_ppfs(input: t_fil_ppf) return t_fil_ppf_arr is
+    variable v_nof_bands : natural := input.nof_bands/input.wb_factor;                     -- The nof_bands for the single channel poly phase filters
+    variable v_return    : t_fil_ppf_arr(input.wb_factor-1 downto 0) := (others => input); -- Variable that holds the return values
+  begin
+    for I in 0 to input.wb_factor-1 loop
+      v_return(I).nof_bands := v_nof_bands;     -- The new number of bands
+    end loop;                               
+    return v_return; 
+  end;
+  
+  ----------------------------------------------------------
+  -- Function that divids the input file index array into 
+  -- "wb_factor" new file index arrays. 
+  ----------------------------------------------------------
+  function func_create_file_index_array(input: t_nat_natural_arr; wb_factor: natural; nof_taps: natural) return t_nat_natural_arr2 is
+    variable v_return : t_nat_natural_arr2(wb_factor-1 downto 0) := (others => input);    -- Variable that holds the return values
+  begin
+    for I in 0 to wb_factor-1 loop
+      for J in 0 to nof_taps-1 loop
+        v_return(I)(J) := input(I*nof_taps+J);
+      end loop;
+    end loop;                               
+    return v_return; 
+  end;
+  
+  constant c_fil_ppf_arr     : t_fil_ppf_arr(g_fil_ppf.wb_factor-1      downto 0) := func_create_generics_for_ppfs(g_fil_ppf);  
+  constant c_file_index_arr2 : t_nat_natural_arr2(g_fil_ppf.wb_factor-1 downto 0) := func_create_file_index_array(g_file_index_arr, g_fil_ppf.wb_factor, g_fil_ppf.nof_taps);
+  
+  constant c_mem_addr_w      : natural := ceil_log2(g_fil_ppf.nof_bands * g_fil_ppf.nof_taps / g_fil_ppf.wb_factor); 
+
+  signal ram_coefs_mosi_arr  : t_mem_mosi_arr(g_fil_ppf.wb_factor-1   downto 0);                               
+  signal ram_coefs_miso_arr  : t_mem_miso_arr(g_fil_ppf.wb_factor-1   downto 0) := (others => c_mem_miso_rst); 
+  signal out_val_i           : std_logic_vector(g_fil_ppf.wb_factor-1 downto 0);
+  signal out_arr_i           : t_out_arr(g_fil_ppf.wb_factor-1        downto 0);
+  signal in_dat_vect_arr     : t_in_arr(g_fil_ppf.wb_factor-1         downto 0);
+  
+begin
+  ---------------------------------------------------------------
+  -- COMBINE MEMORY MAPPED INTERFACES
+  ---------------------------------------------------------------
+  -- Combine the internal array of mm interfaces for the coefficents 
+  -- memory to one array that is connected to the port of the fil_ppf_w
+  u_mem_mux_coef : entity common_lib.common_mem_mux
+  generic map (    
+    g_nof_mosi    => g_fil_ppf.wb_factor,
+    g_mult_addr_w => c_mem_addr_w
+  )
+  port map (
+    mosi     => ram_coefs_mosi,
+    miso     => ram_coefs_miso,
+    mosi_arr => ram_coefs_mosi_arr,
+    miso_arr => ram_coefs_miso_arr
+  );
+
+  gen_in_vect_wb : for I in 0 to g_fil_ppf.wb_factor-1 generate
+    gen_in_vect_streams : for J in 0 to g_fil_ppf.nof_streams-1 generate
+       --in_dat_vect_arr(I)((J+1)*g_fil_ppf.in_dat_w-1 downto J*g_fil_ppf.in_dat_w) <= in_dat_arr(J*g_fil_ppf.wb_factor+I)(g_fil_ppf.in_dat_w-1 downto 0);
+       in_dat_vect_arr(I)((J+1)*g_fil_ppf.in_dat_w-1 downto J*g_fil_ppf.in_dat_w) <= in_dat_arr(I*g_fil_ppf.nof_streams+J)(g_fil_ppf.in_dat_w-1 downto 0);
+    end generate;
+  end generate;
+
+  ---------------------------------------------------------------
+  -- INSTANTIATE MULTIPLE SINGLE CHANNEL POLY PHASE FILTERS
+  ---------------------------------------------------------------
+  gen_ppf_singles : for I in 0 to g_fil_ppf.wb_factor-1 generate
+    u_single_filter : entity work.fil_ppf_single 
+    generic map (
+      g_fil_ppf           => c_fil_ppf_arr(I),
+      g_fil_ppf_pipeline  => g_fil_ppf_pipeline,
+      g_file_index_arr    => c_file_index_arr2(I),
+      g_coefs_file_prefix => g_coefs_file_prefix 
+    )
+    port map (
+      dp_clk         => dp_clk,
+      dp_rst         => dp_rst,
+      mm_clk         => mm_clk,
+      mm_rst         => mm_rst,
+      ram_coefs_mosi => ram_coefs_mosi_arr(I), 
+      ram_coefs_miso => ram_coefs_miso_arr(I), 
+      in_dat         => in_dat_vect_arr(I),
+      in_val         => in_val,
+      out_dat        => out_arr_i(I),
+      out_val        => out_val_i(I)
+    ); 
+    gen_in_vect_streams : for J in 0 to g_fil_ppf.nof_streams-1 generate   
+      out_dat_arr(I*g_fil_ppf.nof_streams+J) <= RESIZE_SVEC(out_arr_i(I)((J+1)*g_fil_ppf.out_dat_w-1 downto J*g_fil_ppf.out_dat_w), out_dat_arr(I)'LENGTH);
+    end generate;
+  end generate;  
+  
+  out_val <= out_val_i(0);                             
+  
+end rtl;