diff --git a/applications/lofar1/pfb2/src/vhdl/wpfb_unit_dev.vhd b/applications/lofar1/pfb2/src/vhdl/wpfb_unit_dev.vhd
deleted file mode 100644
index 8ce1683177a1d182ac838b7688556aefcd3723ff..0000000000000000000000000000000000000000
--- a/applications/lofar1/pfb2/src/vhdl/wpfb_unit_dev.vhd
+++ /dev/null
@@ -1,718 +0,0 @@
---------------------------------------------------------------------------------
--- 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: Wideband polyphase filterbank with subband statistics and streaming interfaces.
---
--- Description:
---
--- This WPFB unit connects an incoming array of streaming interfaces to the
--- wideband pft + fft.
--- The output of the wideband fft is connected to a set of subband statistics
--- units. The statistics can be read via the memory mapped interface.
--- A control unit takes care of the correct composition of the control of the 
--- output streams regarding sop, eop, sync, bsn, err.
---
--- The wpfb unit can handle a wideband factor >= 1 (g_wpfb.wb_factor) or
--- a narrowband factor >= 1 (2**g_wpfb.nof_chan).
--- . For wb_factor = 1 the wpfb_unit uses fft_r2_pipe
--- . For wb_factor > 1 the wpfb_unit uses fft_r2_wide
--- . For wb_factor >= 1 the wpfb_unit supports nof_chan >= 0, even though the
---   concept of channels is typically not useful when wb_factor > 1.
--- . The wpfb_unit does support use_reorder.
--- . The wpfb_unit does support use_separate.
--- . The wpfb_unit does support input flow control with invalid gaps in the
---   input.
---
--- . g_coefs_file_prefix:
---   The g_coefs_file_prefix points to the location where the files
---   with the initial content for the coefficients memories are located and
---   is described in fil_ppf_wide.vhd.
---
--- . fft_out_gain_w
---   For two real input typically fft_out_gain_w = 1 is used to compensate for
---   the divide by 2 in the separate function that is done because real input
---   frequency bins have norm 0.5. For complex input typically fft_out_gain_w
---   = 0, because the complex bins have norm 1.
---
--- . g_dont_flip_channels:
---   True preserves channel interleaving, set by g_wpfb.nof_chan>0, of the FFT
---   output when g_bit_flip=true to reorder the FFT output.
---   The g_dont_flip_channels applies for both complex input and two_real
---   input FFT. The g_dont_flip_channels is only implemented for the pipelined
---   fft_r2_pipe, because for g_wpfb.wb_factor=1 using g_wpfb.nof_chan>0 makes
---   sense, while for the fft_r2_wide with g_wpfb.wb_factor>1 using input
---   multiplexing via g_wpfb.nof_chan>0 makes less sense.
---
--- The reordering to the fil_ppf_wide is done such that the FIR filter
--- coefficients are reused. The same filter coefficients are used for all
--- streams. The filter has real coefficients, because the filterbank
--- channels are symmetrical in frequency. The real part and the imaginary
--- part are filtered independently and also use the same real FIR
--- coefficients.
---
--- Note that:
--- . The same P of all streams are grouped the in filter and all P per
---   stream are grouped in the FFT. Hence the WPFB input is grouped per
---   P for all wideband streams to allow FIR coefficients reuse per P
---   for all wideband streams. The WPFB output is grouped per wideband
---   stream to have all P together.
---
--- . The wideband time index t is big-endian inside the prefilter and
---   little-endian inside the FFT. 
---   When g_big_endian_wb_in=true then the WPFB input must be in big-endian
---   format, else in little-endian format.
---   For little-endian time index t increments in the same direction as the
---   wideband factor index P, so P = 0, 1, 2, 3 --> t0, t1, t2, t3.
---   For big-endian the time index t increments in the opposite direction of
---   the wideband factor index P, so P = 3, 2, 1, 0 --> t0, t1, t2, t3.
---   The WPFB output is fixed little-endian, so with frequency bins in
---   incrementing order. However the precise frequency bin order depends
---   on the reorder generics.
---
--- When wb_factor = 4 and nof_wb_streams = 2 the mapping is as follows using 
--- the array notation:
---
---   . I = array index
---   . S = stream index of a wideband stream
---   . P = wideband factor index
---   . t = time index
---
---                    parallel                           serial   type
---   in_sosi_arr      [nof_streams][wb_factor]           [t]      cint
---                                               
---   fil_in_arr       [wb_factor][nof_streams][complex]  [t]       int
---   fil_out_arr      [wb_factor][nof_streams][complex]  [t]       int
---                                               
---   fil_sosi_arr     [nof_streams][wb_factor]           [t]      cint
---   fft_in_re_arr    [nof_streams][wb_factor]           [t]       int
---   fft_in_im_arr    [nof_streams][wb_factor]           [t]       int
---   fft_out_re_arr   [nof_streams][wb_factor]           [bin]     int
---   fft_out_im_arr   [nof_streams][wb_factor]           [bin]     int
---   fft_out_sosi_arr [nof_streams][wb_factor]           [bin]    cint
---   pfb_out_sosi_arr [nof_streams][wb_factor]           [bin]    cint with sync, BSN, sop, eop
---   out_sosi_arr     [nof_streams][wb_factor]           [bin]    cint with sync, BSN, sop, eop
--- 
---   in_sosi_arr  | fil_in_arr  | fft_in_re_arr | fft_out_re_arr  
---   fil_sosi_arr | fil_out_arr | fft_in_im_arr | fft_out_im_arr  
---                |             |               | fft_out_sosi_arr
---                |             |               | pfb_out_sosi_arr
---                |             |               |     out_sosi_arr
---                |             |               |
---    I  S P t    |   I  P S    | I  S P t      | I  S P          
---    7  1 3 0    |  15  3 1 IM | 7  1 3 3      | 7  1 3          
---    6  1 2 1    |  14  3 1 RE | 6  1 2 2      | 6  1 2          
---    5  1 1 2    |  13  3 0 IM | 5  1 1 1      | 5  1 1          
---    4  1 0 3    |  12  3 0 RE | 4  1 0 0      | 4  1 0          
---    3  0 3 0    |  11  2 1 IM | 3  0 3 3      | 3  0 3          
---    2  0 2 1    |  10  2 1 RE | 2  0 2 2      | 2  0 2          
---    1  0 1 2    |   9  2 0 IM | 1  0 1 1      | 1  0 1          
---    0  0 0 3    |   8  2 0 RE | 0  0 0 0      | 0  0 0          
---                |   7  1 1 IM |               |                 
---           ^    |   6  1 1 RE |        ^      |                 
---         big    |   5  1 0 IM |      little   |                 
---         endian |   4  1 0 RE |      endian   |                 
---                |   3  0 1 IM |               |                 
---                |   2  0 1 RE |               |                 
---                |   1  0 0 IM |               |                 
---                |   0  0 0 RE |               |                 
---
--- The WPFB output are the frequency bins per transformed block:
---   . subbands, in case ot two real input or
---   . channels, in case of complex input
---
--- The order of the WPFB output depends on the g_fft fields:
---   . wb_factor
---   . use_reorder
---   . use_fft_shift
---   . use_separate
--- 
--- The frequency bin order at the output is obtained with reg_out_bin
--- in the test bench tb_wpfb_unit_dev.vhd.
---
--- Output examples:
---
--- Frequency bins:
---     fs = sample frequency
---     Bb = fs/nof_points = bin bandwidth
---
---     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
---     ^                                           ^  ^  ^                                          ^
---     <--------- negative bin frequencies ---------> 0 <---------- positive bin frequencies ------->
---     -fs/2                                      -Bb 0 +Bb                                        +fs/2-Bb
---
--- I) Wideband wb_factor = 4
--- 1) Two real inputs:
--- 
---   out_sosi_arr:
---     I  S P    bin frequency order         . nof_streams   = 2            
---     7  1 3    12 12 13 13 14 14 15 15     . wb_factor     = 4                 
---     6  1 2     8  8  9  9 10 10 11 11     . nof_points    = 32               
---     5  1 1     4  4  5  5  6  6  7  7     . use_reorder   = true            
---     4  1 0     0  0  1  1  2  2  3  3     . use_fft_shift = false         
---     3  0 3    12 12 13 13 14 14 15 15     . use_separate  = true           
---     2  0 2     8  8  9  9 10 10 11 11       - input A via in_sosi_arr().re
---     1  0 1     4  4  5  5  6  6  7  7       - input B via in_sosi_arr().im
---     0  0 0     0  0  1  1  2  2  3  3
---      input     A  B  A  B  A  B  A  B
---
---   when nof_chan=1 then:
---     I  S P    bin frequency order    
---     7  1 3    12 12 13 13 14 14 15 15 12 12 13 13 14 14 15 15
---     6  1 2     8  8  9  9 10 10 11 11  8  8  9  9 10 10 11 11
---     5  1 1     4  4  5  5  6  6  7  7  4  4  5  5  6  6  7  7
---     4  1 0     0  0  1  1  2  2  3  3  0  0  1  1  2  2  3  3
---     3  0 3    12 12 13 13 14 14 15 15 12 12 13 13 14 14 15 15
---     2  0 2     8  8  9  9 10 10 11 11  8  8  9  9 10 10 11 11
---     1  0 1     4  4  5  5  6  6  7  7  4  4  5  5  6  6  7  7
---     0  0 0     0  0  1  1  2  2  3  3  0  0  1  1  2  2  3  3
---      input     A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B
---    channel     0....................0  1....................1
---
--- 2a) Complex input with fft_shift:
--- 
---   out_sosi_arr:
---     I  S P    bin frequency order         . nof_streams   = 2                    
---     7  1 3    24 25 26 27 28 29 30 31     . wb_factor     = 4                 
---     6  1 2    16 17 18 19 20 21 22 23     . nof_points    = 32               
---     5  1 1     8  9 10 11 12 13 14 15     . use_reorder   = true                         
---     4  1 0     0  1  2  3  4  5  6  7     . use_fft_shift = true 
---     3  0 3    24 25 26 27 28 29 30 31     . use_separate  = false                       
---     2  0 2    16 17 18 19 20 21 22 23       - complex input via in_sosi_arr().re and im
---     1  0 1     8  9 10 11 12 13 14 15
---     0  0 0     0  1  2  3  4  5  6  7
---
---   when nof_chan=1 then:
---     I  S P    bin frequency order    
---     7  1 3    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31
---     6  1 2    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
---     5  1 1     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15 
---     4  1 0     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
---     3  0 3    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31
---     2  0 2    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
---     1  0 1     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15
---     0  0 0     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
---    channel     0....................0  1....................1
---
--- 2b) Complex input with reorder, but no fft_shift:
--- 
---   out_sosi_arr:
---     I  S P    bin frequency order         . nof_streams   = 2                    
---     7  1 3     8  9 10 11 12 13 14 15     . wb_factor     = 4                 
---     6  1 2     0  1  2  3  4  5  6  7     . nof_points    = 32               
---     5  1 1    24 25 26 27 28 29 30 31     . use_reorder   = true                         
---     4  1 0    16 17 18 19 20 21 22 23     . use_fft_shift = false                      
---     3  0 3     8  9 10 11 12 13 14 15     . use_separate  = false                       
---     2  0 2     0  1  2  3  4  5  6  7       - complex input via in_sosi_arr().re and im
---     1  0 1    24 25 26 27 28 29 30 31
---     0  0 0    16 17 18 19 20 21 22 23
--- 
---   when nof_chan=1 then:
---     I  S P    bin frequency order
---     7  1 3     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15
---     6  1 2     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
---     5  1 1    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31  
---     4  1 0    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
---     3  0 3     8  9 10 11 12 13 14 15  8  9 10 11 12 13 14 15 
---     2  0 2     0  1  2  3  4  5  6  7  0  1  2  3  4  5  6  7
---     1  0 1    24 25 26 27 28 29 30 31 24 25 26 27 28 29 30 31
---     0  0 0    16 17 18 19 20 21 22 23 16 17 18 19 20 21 22 23
---    channel     0....................0  1....................1
---
--- 2c) Complex input without reorder (so bit flipped):
--- 
---   out_sosi_arr:
---     I  S P    bin frequency order         . nof_streams   = 2                
---     7  1 3     8 12 10 14  9 13 11 15     . wb_factor     = 4                
---     6  1 2    24 28 26 30 25 29 27 31     . nof_points    = 32               
---     5  1 1     0  4  2  6  1  5  3  7     . use_reorder   = false                        
---     4  1 0    16 20 18 22 17 21 19 23     . use_fft_shift = false                      
---     3  0 3     8 12 10 14  9 13 11 15     . use_separate  = false                       
---     2  0 2    24 28 26 30 25 29 27 31       - complex input via in_sosi_arr().re and im
---     1  0 1     0  4  2  6  1  5  3  7
---     0  0 0    16 20 18 22 17 21 19 23
---
---   when nof_chan=1 then:
---     I  S P    bin frequency order    
---     7  1 3     8  8 12 12 10 10 14 14  9  9 13 13 11 11 15 15
---     6  1 2    24 24 28 28 26 26 30 30 25 25 29 29 27 27 31 31
---     5  1 1     0  0  4  4  2  2  6  6  1  1  5  5  3  3  7  7  
---     4  1 0    16 16 20 20 18 18 22 22 17 17 21 21 19 19 23 23
---     3  0 3     8  8 12 12 10 10 14 14  9  9 13 13 11 11 15 15 
---     2  0 2    24 24 28 28 26 26 30 30 25 25 29 29 27 27 31 31
---     1  0 1     0  0  4  4  2  2  6  6  1  1  5  5  3  3  7  7
---     0  0 0    16 16 20 20 18 18 22 22 17 17 21 21 19 19 23 23
---    channel     0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1
---
--- II) Narrowband wb_factor = 1
---
--- 1) Two real inputs:
--- 
---   . nof_streams   = 2
---   . nof_chan      = 0
---   . wb_factor     = 1
---   . nof_points    = 32
---   . use_reorder   = true
---   . use_fft_shift = false
---   . use_separate  = true
---     - input A via in_sosi_arr().re
---     - input B via in_sosi_arr().im
---
---   out_sosi_arr:
---     I  S P    bin frequency order
---     1  1 0     0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15
---     0  0 0     0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15
---      input     A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B
---
---   when nof_chan=1 then:
---     I  S P    bin frequency order
---     1  1 0     0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15  0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15
---     0  0 0     0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15  0  0  1  1  2  2  3  3  4  4  5  5  6  6  7  7  8  8  9  9 10 10 11 11 12 12 13 13 14 14 15 15
---      input     A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B  A  B
---     channel:   0............................................................................................0  1............................................................................................1
---
--- 2) Complex input
---   . nof_streams = 2
---   . nof_chan = 0
---   . wb_factor = 1
---   . nof_points = 32
---   . use_separate = false
---     - complex input via in_sosi_arr().re and im
-
--- 2a) Complex input with fft_shift (so use_reorder = true, use_fft_shift = true)
--- 
---   out_sosi_arr:
---     I  S P    bin frequency order
---     1  1 0     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
---     0  0 0     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
---
---   when nof_chan=1 then:
---     I  S P    bin frequency order
---     1  1 0     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
---     0  0 0     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
---     channel:   0............................................................................................0  1............................................................................................1
---
--- 2b) Complex input with reorder but no fft_shift (so use_reorder = true, use_fft_shift = false)
--- 
---   out_sosi_arr:
---     I  S P    bin frequency order
---     1  1 0    16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
---     0  0 0    16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
---
---   when nof_chan=1 then:
---     I  S P    bin frequency order
---     1  1 0    16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
---     0  0 0    16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
---     channel:   0............................................................................................0  1............................................................................................1
---
--- 2c) Complex input without reorder (so use_reorder = false, use_fft_shift = false)
--- 
---   out_sosi_arr:
---     I  S P    bin frequency order
---     1  1 0    16  0 24  8 20  4 28 12 18  2 26 10 22  6 30 14 17  1 25  9 21  5 29 13 19  3 27 11 23  7 31 15
---     0  0 0    16  0 24  8 20  4 28 12 18  2 26 10 22  6 30 14 17  1 25  9 21  5 29 13 19  3 27 11 23  7 31 15
---
---   when nof_chan=1 then:
---     I  S P    bin frequency order
---     1  1 0    16 16  0  0 24 24  8  8 20 20  4  4 28 28 12 12 18 18  2  2 26 26 10 10 22 22  6  6 30 30 14 14 17 17  1  1 25 25  9  9 21 21  5  5 29 29 13 13 19 19  3  3 27 27 11 11 23 23  7  7 31 31 15 15
---     0  0 0    16 16  0  0 24 24  8  8 20 20  4  4 28 28 12 12 18 18  2  2 26 26 10 10 22 22  6  6 30 30 14 14 17 17  1  1 25 25  9  9 21 21  5  5 29 29 13 13 19 19  3  3 27 27 11 11 23 23  7  7 31 31 15 15
---     channel:   0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1
---
--- Remarks:
--- . The unit can handle only one sync at a time. Therfor the
---   sync interval should be larger than the total pipeline
---   stages of the wideband fft.
---
-
-library ieee, common_lib, dp_lib, rTwoSDF_lib, st_lib, filter_lib, fft_lib, diag_lib;
-use IEEE.std_logic_1164.all;
-use STD.textio.all;
-use common_lib.common_pkg.all;
-use common_lib.common_mem_pkg.all;
-use dp_lib.dp_stream_pkg.ALL;
-use rTwoSDF_lib.rTwoSDFPkg.all;
-use st_lib.all;
-use filter_lib.all;
-use filter_lib.fil_pkg.all;
-use fft_lib.all;
-use fft_lib.fft_pkg.all;
-use work.wpfb_pkg.all;
-
-entity wpfb_unit_dev is
-  generic (
-    g_big_endian_wb_in  : boolean           := true;
-    g_wpfb              : t_wpfb;
-    g_dont_flip_channels: boolean           := false;   -- True preserves channel interleaving for pipelined FFT
-    g_use_prefilter     : boolean           := TRUE;
-    g_stats_ena         : boolean           := TRUE;    -- Enables the statistics unit
-    g_use_bg            : boolean           := FALSE;
-    g_coefs_file_prefix : string            := "data/coefs_wide" -- File prefix for the coefficients files.
-   );
-  port (
-    dp_rst             : in  std_logic := '0';
-    dp_clk             : in  std_logic;
-    mm_rst             : in  std_logic;
-    mm_clk             : in  std_logic;
-    ram_fil_coefs_mosi : in  t_mem_mosi := c_mem_mosi_rst;
-    ram_fil_coefs_miso : out t_mem_miso;
-    ram_st_sst_mosi    : in  t_mem_mosi := c_mem_mosi_rst;  -- Subband statistics registers
-    ram_st_sst_miso    : out t_mem_miso;
-    reg_bg_ctrl_mosi   : in  t_mem_mosi := c_mem_mosi_rst;
-    reg_bg_ctrl_miso   : out t_mem_miso;
-    ram_bg_data_mosi   : in  t_mem_mosi := c_mem_mosi_rst;
-    ram_bg_data_miso   : out t_mem_miso;
-    in_sosi_arr        : in  t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-    fil_sosi_arr       : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-    out_sosi_arr       : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0)
-  );
-end entity wpfb_unit_dev;
-
-architecture str of wpfb_unit_dev is
-
-  constant c_nof_channels          : natural := 2**g_wpfb.nof_chan;
-  
-  constant c_nof_data_per_block    : natural := c_nof_channels * g_wpfb.nof_points;
-  constant c_nof_valid_per_block   : natural := c_nof_data_per_block / g_wpfb.wb_factor;
-  
-  constant c_nof_stats             : natural := c_nof_valid_per_block;
-  
-  constant c_fil_ppf         : t_fil_ppf := (g_wpfb.wb_factor,
-                                             g_wpfb.nof_chan,
-                                             g_wpfb.nof_points,
-                                             g_wpfb.nof_taps,
-                                             c_nof_complex*g_wpfb.nof_wb_streams,  -- Complex FFT always requires 2 filter streams: real and imaginary
-                                             g_wpfb.fil_backoff_w,
-                                             g_wpfb.fil_in_dat_w,
-                                             g_wpfb.fil_out_dat_w,
-                                             g_wpfb.coef_dat_w);
-
-  constant c_fft             : t_fft     := (g_wpfb.use_reorder,
-                                             g_wpfb.use_fft_shift,
-                                             g_wpfb.use_separate,
-                                             g_wpfb.nof_chan,
-                                             g_wpfb.wb_factor,
-                                             0,
-                                             g_wpfb.nof_points,
-                                             g_wpfb.fft_in_dat_w,
-                                             g_wpfb.fft_out_dat_w,
-                                             g_wpfb.fft_out_gain_w,
-                                             g_wpfb.stage_dat_w,
-                                             g_wpfb.guard_w,
-                                             g_wpfb.guard_enable,
-                                             g_wpfb.stat_data_w,
-                                             g_wpfb.stat_data_sz);
-
-  constant c_fft_r2_check           : boolean := fft_r2_parameter_asserts(c_fft);
-  
-  constant c_bg_buf_adr_w           : natural := ceil_log2(g_wpfb.nof_points/g_wpfb.wb_factor);
-  constant c_bg_data_file_index_arr : t_nat_natural_arr := array_init(0, g_wpfb.nof_wb_streams*g_wpfb.wb_factor, 1);
-  constant c_bg_data_file_prefix    : string  := "UNUSED";
-
-  signal ram_st_sst_mosi_arr : t_mem_mosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal ram_st_sst_miso_arr : t_mem_miso_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_mem_miso_rst);
-
-  signal fil_in_arr          : t_fil_slv_arr(c_nof_complex*g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fil_in_val          : std_logic;
-  signal fil_out_arr         : t_fil_slv_arr(c_nof_complex*g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fil_out_val         : std_logic;
-  
-  signal fft_in_re_arr       : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_in_im_arr       : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_in_val          : std_logic;
-
-  signal fft_out_re_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_out_im_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_out_re_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_out_im_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_out_re_arr_pipe : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_out_im_arr_pipe : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  signal fft_out_val_arr     : std_logic_vector(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-
-  signal fft_out_sosi        : t_dp_sosi;
-  signal fft_out_sosi_arr    : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst);
-  
-  signal pfb_out_sosi_arr    : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst);
-  
-  type reg_type is record
-    in_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
-  end record;
-
-  signal r, rin : reg_type;
-
-begin
-
-  -- The complete input sosi arry is registered.
-  comb : process(r, in_sosi_arr)
-    variable v : reg_type;
-  begin
-    v             := r;
-    v.in_sosi_arr := in_sosi_arr;
-    rin           <= v;
-  end process comb;
-
-  regs : process(dp_clk)
-  begin
-    if rising_edge(dp_clk) then
-      r <= rin;
-    end if;
-  end process;
-
-  ---------------------------------------------------------------
-  -- COMBINE MEMORY MAPPED INTERFACES
-  ---------------------------------------------------------------
-  -- Combine the internal array of mm interfaces for the subband
-  -- statistics to one array that is connected to the port of the
-  -- fft_wide_unit.
-  u_mem_mux_sst : entity common_lib.common_mem_mux
-  generic map (
-    g_nof_mosi    => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
-    g_mult_addr_w => ceil_log2(g_wpfb.stat_data_sz*c_nof_stats)
-  )
-  port map (
-    mosi     => ram_st_sst_mosi,
-    miso     => ram_st_sst_miso,
-    mosi_arr => ram_st_sst_mosi_arr,
-    miso_arr => ram_st_sst_miso_arr
-  );
-
-  gen_pfb : if g_use_bg = FALSE generate
-    ---------------------------------------------------------------
-    -- REWIRE THE DATA FOR WIDEBAND POLY PHASE FILTER
-    ---------------------------------------------------------------
-
-    -- Wire in_sosi_arr --> fil_in_arr
-    wire_fil_in_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
-      wire_fil_in_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
-        fil_in_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex)   <= RESIZE_SVEC_32(r.in_sosi_arr(S*g_wpfb.wb_factor+P).re(g_wpfb.fil_in_dat_w-1 downto 0));
-        fil_in_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex+1) <= RESIZE_SVEC_32(r.in_sosi_arr(S*g_wpfb.wb_factor+P).im(g_wpfb.fil_in_dat_w-1 downto 0));
-      end generate;
-    end generate;
-    fil_in_val <= r.in_sosi_arr(0).valid;
-
-    -- Wire fil_out_arr --> fil_sosi_arr
-    wire_fil_sosi_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
-      wire_fil_sosi_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
-        fil_sosi_arr(S*g_wpfb.wb_factor+P).valid <= fil_out_val;
-        fil_sosi_arr(S*g_wpfb.wb_factor+P).re    <= RESIZE_DP_DSP_DATA(fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex  ));
-        fil_sosi_arr(S*g_wpfb.wb_factor+P).im    <= RESIZE_DP_DSP_DATA(fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex+1));
-      end generate;
-    end generate; 
-    
-    -- Wire fil_out_arr --> fft_in_re_arr, fft_in_im_arr
-    wire_fft_in_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
-      wire_fft_in_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
-        fft_in_re_arr(S*g_wpfb.wb_factor + P) <= fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex);
-        fft_in_im_arr(S*g_wpfb.wb_factor + P) <= fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex+1);
-      end generate;
-    end generate;
-
-    ---------------------------------------------------------------
-    -- THE POLY PHASE FILTER
-    ---------------------------------------------------------------
-    gen_prefilter : IF g_use_prefilter = TRUE generate
-      u_filter : entity filter_lib.fil_ppf_wide
-      generic map (
-        g_big_endian_wb_in  => g_big_endian_wb_in,
-        g_big_endian_wb_out => false,  -- reverse wideband order from big-endian [3:0] = [t0,t1,t2,t3] in fil_ppf_wide to little-endian [3:0] = [t3,t2,t1,t0] in fft_r2_wide
-        g_fil_ppf           => c_fil_ppf,
-        g_fil_ppf_pipeline  => g_wpfb.fil_pipeline,
-        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_fil_coefs_mosi,
-        ram_coefs_miso => ram_fil_coefs_miso,
-        in_dat_arr     => fil_in_arr,
-        in_val         => fil_in_val,
-        out_dat_arr    => fil_out_arr,
-        out_val        => fil_out_val
-      );
-    end generate;
-
-    -- Bypass filter
-    no_prefilter : if g_use_prefilter = FALSE generate
-      fil_out_arr <= fil_in_arr;
-      fil_out_val <= fil_in_val;
-    end generate;
-
-    fft_in_val <= fil_out_val;
-
-    ---------------------------------------------------------------
-    -- THE WIDEBAND FFT
-    ---------------------------------------------------------------
-    gen_wideband_fft: if g_wpfb.wb_factor > 1  generate
-      gen_fft_r2_wide_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
-        u_fft_r2_wide : entity fft_lib.fft_r2_wide
-        generic map(
-          g_fft          => c_fft,         -- generics for the WFFT
-          g_pft_pipeline => g_wpfb.pft_pipeline,
-          g_fft_pipeline => g_wpfb.fft_pipeline
-        )
-        port map(
-          clk        => dp_clk,
-          rst        => dp_rst,
-          in_re_arr  => fft_in_re_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
-          in_im_arr  => fft_in_im_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
-          in_val     => fft_in_val,
-          out_re_arr => fft_out_re_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
-          out_im_arr => fft_out_im_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
-          out_val    => fft_out_val_arr(S)
-        );
-      end generate;
-    end generate;
-
-    ---------------------------------------------------------------
-    -- THE PIPELINED FFT
-    ---------------------------------------------------------------
-    gen_pipeline_fft: if g_wpfb.wb_factor = 1  generate
-      gen_fft_r2_pipe_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
-        u_fft_r2_pipe : entity fft_lib.fft_r2_pipe
-        generic map(
-          g_fft      => c_fft,
-          g_dont_flip_channels => g_dont_flip_channels,
-          g_pipeline => g_wpfb.fft_pipeline
-        )
-        port map(
-          clk       => dp_clk,
-          rst       => dp_rst,
-          in_re     => fft_in_re_arr(S)(c_fft.in_dat_w-1 downto 0),
-          in_im     => fft_in_im_arr(S)(c_fft.in_dat_w-1 downto 0),
-          in_val    => fft_in_val,
-          out_re    => fft_out_re_arr_i(S)(c_fft.out_dat_w-1 downto 0),
-          out_im    => fft_out_im_arr_i(S)(c_fft.out_dat_w-1 downto 0),
-          out_val   => fft_out_val_arr(S)
-        );
-        
-        fft_out_re_arr(S) <= RESIZE_SVEC_32(fft_out_re_arr_i(S)(c_fft.out_dat_w-1 downto 0));
-        fft_out_im_arr(S) <= RESIZE_SVEC_32(fft_out_im_arr_i(S)(c_fft.out_dat_w-1 downto 0));
-      end generate;
-    end generate;
-
-    ---------------------------------------------------------------
-    -- FFT CONTROL UNIT
-    ---------------------------------------------------------------
-    
-    -- Capture input BSN at input sync and pass the captured input BSN it on to PFB output sync.
-    -- The FFT output valid defines PFB output sync, sop, eop.
-
-    fft_out_sosi.sync  <= r.in_sosi_arr(0).sync;  
-    fft_out_sosi.bsn   <= r.in_sosi_arr(0).bsn;   
-    fft_out_sosi.valid <= fft_out_val_arr(0);     
-    
-    wire_fft_out_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate
-      fft_out_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(fft_out_re_arr(I));
-      fft_out_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(fft_out_im_arr(I));
-      fft_out_sosi_arr(I).valid <=                    fft_out_val_arr(I);
-    end generate;
-    
-    u_dp_block_gen_valid_arr : ENTITY dp_lib.dp_block_gen_valid_arr
-    GENERIC MAP (
-      g_nof_streams         => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
-      g_nof_data_per_block  => c_nof_valid_per_block,
-      g_nof_blk_per_sync    => g_wpfb.nof_blk_per_sync,
-      g_check_input_sync    => false,
-      g_nof_pages_bsn       => 1,
-      g_restore_global_bsn  => true
-    )
-    PORT MAP (
-      rst         => dp_rst,
-      clk         => dp_clk,
-      -- Streaming sink
-      snk_in      => fft_out_sosi,
-      snk_in_arr  => fft_out_sosi_arr,
-      -- Streaming source
-      src_out_arr => pfb_out_sosi_arr,
-      -- Control
-      enable      => '1'
-    );
-  end generate;
-
-  ----------------------------------------------------------------------------
-  -- Source: block generator
-  ----------------------------------------------------------------------------
-  gen_bg : if g_use_bg = TRUE generate
-    u_bg : entity diag_lib.mms_diag_block_gen
-    generic map(
-      g_nof_streams      => g_wpfb.nof_wb_streams*g_wpfb.wb_factor,
-      g_buf_dat_w        => c_nof_complex*g_wpfb.fft_out_dat_w,
-      g_buf_addr_w       => c_bg_buf_adr_w,               -- Waveform buffer size 2**g_buf_addr_w nof samples
-      g_file_index_arr   => c_bg_data_file_index_arr,
-      g_file_name_prefix => c_bg_data_file_prefix
-    )
-    port map(
-      -- System
-      mm_rst           => mm_rst,
-      mm_clk           => mm_clk,
-      dp_rst           => dp_rst,
-      dp_clk           => dp_clk,
-      en_sync          => '0',
-      -- MM interface
-      reg_bg_ctrl_mosi => reg_bg_ctrl_mosi,
-      reg_bg_ctrl_miso => reg_bg_ctrl_miso,
-      ram_bg_data_mosi => ram_bg_data_mosi,
-      ram_bg_data_miso => ram_bg_data_miso,
-      -- ST interface
-      out_sosi_arr     => pfb_out_sosi_arr
-    );
-  end generate;
-
- ---------------------------------------------------------------
-  -- SUBBAND STATISTICS
-  ---------------------------------------------------------------
-  -- For all "wb_factor"x"nof_wb_streams" output streams of the
-  -- wideband FFT a subband statistics unit is placed if the
-  -- g_stats_ena is TRUE.
-  -- Since the subband statistics module uses embedded DSP blocks
-  -- for multiplication, the incoming data cannot be wider
-  -- than 18 bit.
-  gen_stats : if g_stats_ena = TRUE generate
-    gen_stats_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
-      gen_stats_wideband: for P in 0 to g_wpfb.wb_factor-1 generate
-        u_subband_stats : entity st_lib.st_sst
-        generic map(
-          g_nof_stat      => c_nof_stats,
-          g_in_data_w     => g_wpfb.fft_out_dat_w,
-          g_stat_data_w   => g_wpfb.stat_data_w,
-          g_stat_data_sz  => g_wpfb.stat_data_sz
-        )
-        port map (
-          mm_rst          => mm_rst,
-          mm_clk          => mm_clk,
-          dp_rst          => dp_rst,
-          dp_clk          => dp_clk,
-          in_complex      => pfb_out_sosi_arr(S*g_wpfb.wb_factor+P),
-          ram_st_sst_mosi => ram_st_sst_mosi_arr(S*g_wpfb.wb_factor+P),
-          ram_st_sst_miso => ram_st_sst_miso_arr(S*g_wpfb.wb_factor+P)
-        );
-      end generate;
-    end generate;
-  end generate;
-
-  -- Connect to the outside world
-  out_sosi_arr <= pfb_out_sosi_arr;
-
-end str;
-
-
-
diff --git a/applications/lofar1/pfs/hdllib.cfg b/applications/lofar1/pfs/hdllib.cfg
index 106f0dc0d5e45e9eb0e8462270d04e540f94b86c..1b731b60a2f4c964f65abf55b6f26644635bcf42 100644
--- a/applications/lofar1/pfs/hdllib.cfg
+++ b/applications/lofar1/pfs/hdllib.cfg
@@ -6,17 +6,10 @@ hdl_lib_technology =
 
 synth_files =
     src/vhdl/pfs_ctrl.vhd
-    src/vhdl/pfs_ctrl(rtl).vhd
     src/vhdl/pfs_tapsbuf.vhd
     src/vhdl/pfs_coefsbuf.vhd
     src/vhdl/pfs_filter.vhd
-    src/vhdl/pfs_tapsbuf(rtl).vhd
-    src/vhdl/pfs_coefsbuf(str).vhd
-    src/vhdl/pfs_filter(rtl).vhd
     src/vhdl/pfs.vhd
-    src/vhdl/pfs(str).vhd
-    src/vhdl/pfs_top.vhd
-    src/vhdl/pfs_top(str).vhd
     
 test_bench_files = 
     tb/vhdl/tb_pfs.vhd
diff --git a/applications/lofar1/pfs/src/vhdl/pfs.vhd b/applications/lofar1/pfs/src/vhdl/pfs.vhd
index 67afceb7ab28e5d64326658cf4e7a0855a7ee186..f0efbc4dacba22bfb2395b670b4f99d42e222a63 100644
--- a/applications/lofar1/pfs/src/vhdl/pfs.vhd
+++ b/applications/lofar1/pfs/src/vhdl/pfs.vhd
@@ -1,6 +1,31 @@
-LIBRARY IEEE;
-USE IEEE.STD_LOGIC_1164.ALL;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
 
+LIBRARY IEEE, common_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
 
 ENTITY pfs IS
   GENERIC (
@@ -25,3 +50,127 @@ ENTITY pfs IS
   );
 END pfs;
 
+
+ARCHITECTURE str OF pfs IS
+
+  CONSTANT c_nof_bands_w    : NATURAL := ceil_log2(g_nof_bands);
+  CONSTANT c_nof_fir_taps   : NATURAL := g_nof_taps / g_nof_bands;
+  CONSTANT c_nof_fir_taps_w : NATURAL := ceil_log2(c_nof_fir_taps);
+
+  SIGNAL taps_rdaddr        : STD_LOGIC_VECTOR(c_nof_bands_w-1 DOWNTO 0);
+  SIGNAL taps_wraddr        : STD_LOGIC_VECTOR(c_nof_bands_w-1 DOWNTO 0);
+  SIGNAL taps_wren          : STD_LOGIC;
+  SIGNAL taps_in_x          : STD_LOGIC_VECTOR(g_in_dat_w*c_nof_fir_taps-1 DOWNTO 0);
+  SIGNAL taps_in_y          : STD_LOGIC_VECTOR(g_in_dat_w*c_nof_fir_taps-1 DOWNTO 0);
+  SIGNAL taps_out_x         : STD_LOGIC_VECTOR(g_in_dat_w*c_nof_fir_taps-1 DOWNTO 0);
+  SIGNAL taps_out_y         : STD_LOGIC_VECTOR(g_in_dat_w*c_nof_fir_taps-1 DOWNTO 0);
+  SIGNAL coefs              : STD_LOGIC_VECTOR(g_coef_dat_w*c_nof_fir_taps-1 DOWNTO 0);
+
+BEGIN
+
+  ctrl : ENTITY work.pfs_ctrl
+  GENERIC MAP (
+    g_nof_bands_w     => c_nof_bands_w,
+    g_nof_taps        => c_nof_fir_taps,
+    g_nof_taps_w      => c_nof_fir_taps_w,
+    g_taps_w          => g_in_dat_w
+  )
+  PORT MAP (
+    clk               => clk,
+    rst               => rst,
+    restart           => restart,
+    in_x              => in_dat_x,
+    in_y              => in_dat_y,
+    in_val            => in_val,
+    in_sync           => in_sync,
+    taps_rdaddr       => taps_rdaddr,
+    taps_wraddr       => taps_wraddr,
+    taps_wren         => taps_wren,
+    taps_in_x         => taps_in_x,
+    taps_in_y         => taps_in_y,
+    taps_out_x        => taps_out_x,
+    taps_out_y        => taps_out_y,
+    out_val           => out_val,
+    out_sync          => out_sync
+  );
+
+
+  firx : ENTITY work.pfs_filter
+  GENERIC MAP (
+    g_coef_w          => g_coef_dat_w,
+    g_out_w           => g_out_dat_w,
+    g_taps_w          => g_in_dat_w,
+    g_nof_taps        => c_nof_fir_taps
+  )
+  PORT MAP(
+    clk               => clk,
+    taps              => taps_out_x,
+    coefs             => coefs,
+    result            => out_dat_x
+  );
+
+
+  firy : ENTITY work.pfs_filter
+  GENERIC MAP (
+    g_coef_w          => g_coef_dat_w,
+    g_out_w           => g_out_dat_w,
+    g_taps_w          => g_in_dat_w,
+    g_nof_taps        => c_nof_fir_taps
+  )
+  PORT MAP (
+    clk               => clk,
+    taps              => taps_out_y,
+    coefs             => coefs,
+    result            => out_dat_y
+  );
+
+
+  tapsbufx : ENTITY work.pfs_tapsbuf
+  GENERIC MAP (
+    g_data_w          => g_in_dat_w * c_nof_fir_taps,
+    g_nof_words       => g_nof_bands,
+    g_addr_w          => c_nof_bands_w
+  )
+  PORT MAP (
+    wrdata            => taps_out_x,
+    wren              => taps_wren,
+    wraddr            => taps_wraddr,
+    rdaddr            => taps_rdaddr,
+    rddata            => taps_in_x,
+    clk               => clk,
+    rst               => rst
+  );
+
+
+  tapsbufy : ENTITY work.pfs_tapsbuf
+  GENERIC MAP (
+    g_data_w          => g_in_dat_w * c_nof_fir_taps,
+    g_nof_words       => g_nof_bands,
+    g_addr_w          => c_nof_bands_w
+  )
+  PORT MAP (
+    wrdata            => taps_out_y,
+    wren              => taps_wren,
+    wraddr            => taps_wraddr,
+    rdaddr            => taps_rdaddr,
+    rddata            => taps_in_y,
+    clk               => clk,
+    rst               => rst
+  );
+
+
+  coefsbuf : ENTITY work.pfs_coefsbuf
+  GENERIC MAP (
+    g_data_w          => g_coef_dat_w * c_nof_fir_taps,
+    g_nof_coefs       => g_nof_bands,
+    g_addr_w          => c_nof_bands_w
+  )
+  PORT MAP (
+    addr              => taps_rdaddr,
+    data              => coefs,
+    clk               => clk,
+    rst               => rst
+  );
+
+END str;
+
diff --git a/applications/lofar1/pfs/src/vhdl/pfs_coefsbuf.vhd b/applications/lofar1/pfs/src/vhdl/pfs_coefsbuf.vhd
index 70d2d539561d54ae1ce09373a0b4a2665a6f274b..913cc1d5c07f6371e46d53a36910022267c365af 100644
--- a/applications/lofar1/pfs/src/vhdl/pfs_coefsbuf.vhd
+++ b/applications/lofar1/pfs/src/vhdl/pfs_coefsbuf.vhd
@@ -1,6 +1,33 @@
-LIBRARY IEEE;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
+LIBRARY IEEE, common_lib;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
+USE common_lib.common_mem_pkg.ALL;
+
 
 ENTITY pfs_coefsbuf IS
   GENERIC (
@@ -17,3 +44,27 @@ ENTITY pfs_coefsbuf IS
 END pfs_coefsbuf;
 
 
+ARCHITECTURE str OF pfs_coefsbuf IS
+
+  CONSTANT c_coefs_rom   : t_c_mem := (latency  => 2,
+                                       adr_w    => g_addr_w,
+                                       dat_w    => g_data_w,
+                                       nof_dat  => g_nof_coefs,  -- <= 2**g_addr_w
+                                       init_sl  => '0');
+
+BEGIN
+
+  rom : ENTITY common_lib.common_rom
+  GENERIC MAP (
+    g_ram             => c_coefs_rom,
+    g_init_file       => "data/pfs_coefsbuf_1024.hex"  -- Quartus .hex extension, replaced by .bin in common_rom works for XST
+    --g_init_file       => "data/pfs_coefsbuf_1024.bin"  -- Synplify fails on file extension change to .bin in common_rom and requires extra ../
+  )
+  PORT MAP (
+    rst               => rst,
+    clk               => clk,
+    rd_adr            => addr,
+    rd_dat            => data
+  );
+
+END str;
diff --git a/applications/lofar1/pfs/src/vhdl/pfs_ctrl.vhd b/applications/lofar1/pfs/src/vhdl/pfs_ctrl.vhd
index c047c852a42657b366c98efe019075a7b6107183..1ea585a951b1facbb03557c0eefcf172dd715cfb 100644
--- a/applications/lofar1/pfs/src/vhdl/pfs_ctrl.vhd
+++ b/applications/lofar1/pfs/src/vhdl/pfs_ctrl.vhd
@@ -1,5 +1,31 @@
-LIBRARY ieee;
-USE ieee.std_logic_1164.ALL;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
 
 
 ENTITY pfs_ctrl IS
@@ -29,3 +55,98 @@ ENTITY pfs_ctrl IS
   );
 END pfs_ctrl;
 
+
+ARCHITECTURE rtl OF pfs_ctrl IS
+
+  -- The number of cycles that should be waited until the result that comes out
+  -- of the MAC block is the valid result. The ctrl block will generate a valid
+  -- pulse.
+  CONSTANT c_mem_delay   : INTEGER := 2;
+  CONSTANT c_fir_delay   : INTEGER := 8;
+
+  TYPE delay_reg IS ARRAY (0 TO c_mem_delay) OF STD_LOGIC_VECTOR(g_taps_w-1 DOWNTO 0);
+
+  SIGNAL in_val_reg      : STD_LOGIC;
+  SIGNAL in_x_reg        : delay_reg;
+  SIGNAL in_y_reg        : delay_reg;
+  SIGNAL i_taps_rdaddr   : STD_LOGIC_VECTOR(taps_rdaddr'RANGE);
+  SIGNAL nxt_taps_rdaddr : STD_LOGIC_VECTOR(taps_rdaddr'RANGE);
+  SIGNAL rdval           : STD_LOGIC_VECTOR(c_fir_delay-1 DOWNTO 0);
+  SIGNAL sync_reg        : STD_LOGIC_VECTOR(c_fir_delay DOWNTO 0);
+  SIGNAL nxt_rdval       : STD_LOGIC_VECTOR(rdval'RANGE);
+  SIGNAL i_taps_wraddr   : STD_LOGIC_VECTOR(taps_wraddr'RANGE);
+  SIGNAL nxt_taps_wraddr : STD_LOGIC_VECTOR(taps_wraddr'RANGE);
+
+BEGIN
+
+  -- Output signals.
+  taps_rdaddr <= i_taps_rdaddr;
+  taps_wraddr <= i_taps_wraddr;
+  out_val <= rdval(c_fir_delay-1);
+  out_sync <= sync_reg(c_fir_delay);
+
+  registers_proc : PROCESS (clk, rst)
+  BEGIN
+    IF rst = '1' THEN
+      -- Input registers.
+      in_val_reg    <= '0';
+      in_x_reg      <= (OTHERS => (OTHERS => '0'));
+      in_y_reg      <= (OTHERS => (OTHERS => '0'));
+      -- Output registers.
+      -- Internal registers.
+      rdval         <= (OTHERS => '0');
+      sync_reg      <= (OTHERS => '0');
+      i_taps_rdaddr <= (OTHERS => '0');
+      i_taps_wraddr <= (OTHERS => '0');
+    ELSIF rising_edge(clk) THEN
+      -- Input registers.
+      in_val_reg    <= in_val;
+      in_x_reg      <= in_x & in_x_reg(0 TO in_x_reg'HIGH-1);
+      in_y_reg      <= in_y & in_y_reg(0 TO in_y_reg'HIGH-1);
+      -- Output registers.
+      -- Internal registers.
+      rdval         <= nxt_rdval;
+      sync_reg      <= sync_reg(sync_reg'HIGH-1 DOWNTO 0) & in_sync;
+      i_taps_rdaddr <= nxt_taps_rdaddr;
+      i_taps_wraddr <= nxt_taps_wraddr;
+    END IF;
+  END PROCESS;
+
+
+  read_address_gen : PROCESS (restart, i_taps_rdaddr, in_val_reg, rdval)
+  BEGIN
+    nxt_taps_rdaddr <= STD_LOGIC_VECTOR(UNSIGNED(i_taps_rdaddr)+1);
+    IF restart = '1' THEN
+      nxt_taps_rdaddr <= (OTHERS => '0');
+    ELSIF in_val_reg = '0' THEN
+      nxt_taps_rdaddr <= i_taps_rdaddr;
+    END IF;
+    
+    nxt_rdval <= rdval(rdval'HIGH-1 DOWNTO 0) & '0';
+    IF in_val_reg = '1' THEN
+      nxt_rdval <= rdval(rdval'HIGH-1 DOWNTO 0) & '1';
+    END IF;
+  END PROCESS;
+
+
+  write_control : PROCESS (restart, i_taps_wraddr, taps_in_x, taps_in_y, in_x_reg, rdval,
+      in_y_reg)
+  BEGIN
+    nxt_taps_wraddr <= STD_LOGIC_VECTOR(UNSIGNED(i_taps_wraddr)+1);
+    IF restart = '1' THEN
+      nxt_taps_wraddr <= (OTHERS => '0');
+    ELSIF rdval(c_mem_delay-1) = '0' THEN
+      nxt_taps_wraddr <= i_taps_wraddr;
+    END IF;
+    
+    taps_out_x <= (OTHERS => '0');
+    taps_out_y <= (OTHERS => '0');
+    taps_wren <= '0';
+    IF rdval(c_mem_delay-1) = '1' THEN
+      taps_out_x <= taps_in_x(taps_in_x'HIGH-g_taps_w DOWNTO 0) & in_x_reg(c_mem_delay);
+      taps_out_y <= taps_in_y(taps_in_y'HIGH-g_taps_w DOWNTO 0) & in_y_reg(c_mem_delay);
+      taps_wren <= '1';
+    END IF;
+  END PROCESS;
+
+END rtl;
diff --git a/applications/lofar1/pfs/src/vhdl/pfs_filter.vhd b/applications/lofar1/pfs/src/vhdl/pfs_filter.vhd
index b6044a6682359855e4be68ddab3c91b48861a4aa..8378497351fc288f31c5b0685c7a6f138e0d011a 100644
--- a/applications/lofar1/pfs/src/vhdl/pfs_filter.vhd
+++ b/applications/lofar1/pfs/src/vhdl/pfs_filter.vhd
@@ -1,6 +1,32 @@
-LIBRARY IEEE;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
+LIBRARY IEEE, common_lib, common_mult_lib;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
+USE common_lib.common_pkg.ALL;
 
 
 ENTITY pfs_filter IS
@@ -18,3 +44,64 @@ ENTITY pfs_filter IS
   );
 END pfs_filter;
 
+
+ARCHITECTURE rtl OF pfs_filter IS
+
+  type type_res is array (0 to 7) of std_logic_vector(g_coef_w+g_taps_w+1-1 DOWNTO 0);
+  
+  SIGNAL res      : type_res;
+  SIGNAL res_0    : STD_LOGIC_VECTOR(g_coef_w+g_taps_w+2-1 DOWNTO 0);
+  SIGNAL res_1    : STD_LOGIC_VECTOR(g_coef_w+g_taps_w+2-1 DOWNTO 0);
+  SIGNAL res_2    : STD_LOGIC_VECTOR(g_coef_w+g_taps_w+2-1 DOWNTO 0);
+  SIGNAL res_3    : STD_LOGIC_VECTOR(g_coef_w+g_taps_w+2-1 DOWNTO 0);
+  SIGNAL add_a    : STD_LOGIC_VECTOR(g_coef_w+g_taps_w+3-1 DOWNTO 0);
+  SIGNAL add_b    : STD_LOGIC_VECTOR(g_coef_w+g_taps_w+3-1 DOWNTO 0);
+  SIGNAL add_c    : STD_LOGIC_VECTOR(g_coef_w+g_taps_w+4-1 DOWNTO 0);
+
+BEGIN
+
+  registers : PROCESS (clk)
+  BEGIN
+    IF rising_edge(clk) THEN
+      result <= add_c(add_c'HIGH DOWNTO add_c'LENGTH - result'LENGTH);
+      add_a  <= STD_LOGIC_VECTOR(RESIZE(SIGNED(res_0),add_a'LENGTH) + SIGNED(res_1));
+      add_b  <= STD_LOGIC_VECTOR(RESIZE(SIGNED(res_2),add_b'LENGTH) + SIGNED(res_3));
+    END IF;
+  END PROCESS;
+
+
+  add_c <= STD_LOGIC_VECTOR(SHIFT_LEFT((RESIZE(SIGNED(add_a),add_c'LENGTH) + SIGNED(add_b)),4));
+--  nxt_result <= STD_LOGIC_VECTOR(RESIZE(SIGNED(add_c),
+
+  gen : FOR i IN 0 TO 7 GENERATE
+    --MULT_ADD : ENTITY common_lib.common_mult_add(rtl)
+    --MULT_ADD : ENTITY common_lib.common_mult_add(virtex)
+    MULT_ADD : ENTITY common_mult_lib.common_mult_add   -- rtl
+    GENERIC MAP (
+      g_in_a_w     => g_taps_w,
+      g_in_b_w     => g_coef_w,
+      g_out_dat_w  => g_coef_w+g_taps_w+1,
+      g_add_sub    => "ADD",
+      g_pipeline   => 3
+    )
+    PORT MAP (
+      clk     => clk,
+      in_a0   => taps (g_taps_w*(2*i+1)-1 DOWNTO g_taps_w*2*i),
+      in_b0   => coefs(g_coef_w*(2*i+1)-1 DOWNTO g_coef_w*2*i),
+      in_a1   => taps (g_taps_w*(2*i+2)-1 DOWNTO g_taps_w*(2*i+1)),
+      in_b1   => coefs(g_coef_w*(2*i+2)-1 DOWNTO g_coef_w*(2*i+1)),
+      out_dat => res(i)
+    );
+  END GENERATE;
+
+  pipe : PROCESS (clk)
+  BEGIN
+    IF rising_edge(clk) THEN     
+      res_0 <= STD_LOGIC_VECTOR(RESIZE(SIGNED(res(0)),res_0'LENGTH) + RESIZE(SIGNED(res(1)),res_0'LENGTH));
+      res_1 <= STD_LOGIC_VECTOR(RESIZE(SIGNED(res(2)),res_0'LENGTH) + RESIZE(SIGNED(res(3)),res_0'LENGTH));      
+      res_2 <= STD_LOGIC_VECTOR(RESIZE(SIGNED(res(4)),res_0'LENGTH) + RESIZE(SIGNED(res(5)),res_0'LENGTH));
+      res_3 <= STD_LOGIC_VECTOR(RESIZE(SIGNED(res(6)),res_0'LENGTH) + RESIZE(SIGNED(res(7)),res_0'LENGTH));
+    END IF;
+  END PROCESS;
+ 
+END rtl;
diff --git a/applications/lofar1/pfs/src/vhdl/pfs_tapsbuf.vhd b/applications/lofar1/pfs/src/vhdl/pfs_tapsbuf.vhd
index f2af2d1a056c5427f78c33a7b09d995c57c2e3c2..0ddf24038f6a1c34a918079316f4a97e8e3084e3 100644
--- a/applications/lofar1/pfs/src/vhdl/pfs_tapsbuf.vhd
+++ b/applications/lofar1/pfs/src/vhdl/pfs_tapsbuf.vhd
@@ -1,6 +1,33 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
 LIBRARY IEEE;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_unsigned.ALL;
+
 
 ENTITY pfs_tapsbuf IS
   GENERIC (
@@ -20,3 +47,26 @@ ENTITY pfs_tapsbuf IS
 END pfs_tapsbuf;
 
 
+ARCHITECTURE rtl OF pfs_tapsbuf IS
+
+  type RamType is array(0 to 2**g_addr_w) of std_logic_vector(g_data_w-1 downto 0);
+
+  -- pfs_tapsbuf_1024.hex is empty (all zeros)
+  signal RAM : RamType := (OTHERS => (OTHERS => '0'));
+
+  signal read_addrb : std_logic_vector(g_addr_w-1 downto 0);
+
+BEGIN
+
+  process (clk)
+  begin
+    if rising_edge(clk) then
+      if (wren = '1') then
+        RAM (conv_integer(wraddr)) <= wrdata;
+      end if;
+      read_addrb <= rdaddr;
+      rddata <= RAM(conv_integer(read_addrb));
+    end if;
+  end process;
+
+END rtl;
diff --git a/applications/lofar1/pft2/hdllib.cfg b/applications/lofar1/pft2/hdllib.cfg
index 73ad9896125c41cc3b3066ff43671c1be870d409..b26cec4dbdd7005fdf6591d415d3ab0dc9ced680 100644
--- a/applications/lofar1/pft2/hdllib.cfg
+++ b/applications/lofar1/pft2/hdllib.cfg
@@ -8,28 +8,15 @@ synth_files =
     src/vhdl/pft_lfsr.vhd
     src/vhdl/pft_switch.vhd
     src/vhdl/pft_unswitch.vhd
-    src/vhdl/pft_switch(rtl).vhd
-    src/vhdl/pft_unswitch(rtl).vhd
-    src/vhdl/pft_lfsr(rtl).vhd
-    src/vhdl/pft(pkg).vhd
+    src/vhdl/pft_pkg.vhd
     src/vhdl/pft_bf.vhd
-    src/vhdl/pft_bf(rtl).vhd
     src/vhdl/pft_bf_fw.vhd
-    src/vhdl/pft_bf_fw(rtl).vhd
     src/vhdl/pft_tmult.vhd
-    src/vhdl/pft_tmult(rtl).vhd
     src/vhdl/pft_stage.vhd
-    src/vhdl/pft_stage(str).vhd
     src/vhdl/pft_buffer.vhd
-    src/vhdl/pft_buffer(rtl).vhd
     src/vhdl/pft_reverse.vhd
-    src/vhdl/pft_reverse(rtl).vhd
     src/vhdl/pft_separate.vhd
-    src/vhdl/pft_separate(rtl).vhd
     src/vhdl/pft.vhd
-    src/vhdl/pft(str).vhd
-    src/vhdl/pft_top.vhd
-    src/vhdl/pft_top(str).vhd
     
 test_bench_files = 
     tb/vhdl/tb_pft2.vhd
diff --git a/applications/lofar1/pft2/src/vhdl/pft.vhd b/applications/lofar1/pft2/src/vhdl/pft.vhd
index f0ff2003d3520867b19fe59fdda89b71fb854672..0f85ddfef1f7acc3e854c6585539e5a73a730f1d 100644
--- a/applications/lofar1/pft2/src/vhdl/pft.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft.vhd
@@ -1,3 +1,28 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
 LIBRARY IEEE;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
@@ -5,6 +30,7 @@ USE IEEE.numeric_std.ALL;
 LIBRARY pft2_lib;
 USE pft2_lib.pft_pkg.ALL;
 
+
 ENTITY pft IS
   GENERIC (
     g_fft_size_w   : NATURAL := 10;
@@ -27,3 +53,337 @@ ENTITY pft IS
   );
 END pft;
 
+
+ARCHITECTURE str OF pft IS
+
+  FUNCTION pft_dat_w ( output_w : IN NATURAL; mode : IN PFT_MODE_TYPE) RETURN NATURAL IS
+    VARIABLE dat_w : NATURAL;
+  BEGIN
+    IF mode = PFT_MODE_REAL2  THEN
+      dat_w := output_w;
+    ELSE
+      dat_w := output_w;
+    END IF;
+    RETURN dat_w;
+  END;
+
+  CONSTANT c_nof_stages      : NATURAL := g_fft_size_w/2;
+  CONSTANT c_stage_dat_w     : NATURAL := c_pft_stage_dat_w;
+  CONSTANT c_pft_dat_w       : NATURAL := pft_dat_w(g_out_dat_w, g_mode);
+
+  TYPE stage_rec IS RECORD
+    re   : STD_LOGIC_VECTOR(c_stage_dat_w-1 DOWNTO 0);
+    im   : STD_LOGIC_VECTOR(c_stage_dat_w-1 DOWNTO 0);
+    val  : STD_LOGIC;
+    sync : STD_LOGIC;
+  END RECORD;
+
+  TYPE stage_arr IS ARRAY(c_nof_stages-2 DOWNTO 0) OF stage_rec;
+
+  SIGNAL switch_re        : STD_LOGIC_VECTOR(in_re'RANGE);
+  SIGNAL switch_im        : STD_LOGIC_VECTOR(in_im'RANGE);
+  SIGNAL switch_val       : STD_LOGIC;
+  SIGNAL switch_sync      : STD_LOGIC;
+  
+  SIGNAL stage            : stage_arr;
+
+  SIGNAL pft_re           : STD_LOGIC_VECTOR(c_pft_dat_w-1 DOWNTO 0);
+  SIGNAL pft_im           : STD_LOGIC_VECTOR(c_pft_dat_w-1 DOWNTO 0);
+  SIGNAL pft_val          : STD_LOGIC;
+  SIGNAL pft_sync         : STD_LOGIC;
+
+  SIGNAL buf_re           : STD_LOGIC_VECTOR(c_pft_dat_w-1 DOWNTO 0);
+  SIGNAL buf_im           : STD_LOGIC_VECTOR(c_pft_dat_w-1 DOWNTO 0);
+  SIGNAL buf_en           : STD_LOGIC;
+  SIGNAL buf_val          : STD_LOGIC;
+  SIGNAL buf_adr          : STD_LOGIC_VECTOR(g_fft_size_w-1 DOWNTO 0);
+  SIGNAL buf_sync         : STD_LOGIC;
+  SIGNAL buf_rdy          : STD_LOGIC;
+
+  SIGNAL sep_re           : STD_LOGIC_VECTOR(out_re'RANGE);
+  SIGNAL sep_im           : STD_LOGIC_VECTOR(out_im'RANGE);
+  SIGNAL sep_val          : STD_LOGIC;
+  SIGNAL sep_sync         : STD_LOGIC;
+  
+  SIGNAL unswitch_re      : STD_LOGIC_VECTOR(out_re'RANGE);
+  SIGNAL unswitch_im      : STD_LOGIC_VECTOR(out_im'RANGE);
+  SIGNAL unswitch_val     : STD_LOGIC;
+  SIGNAL unswitch_sync    : STD_LOGIC;
+
+
+  -- synthesis translate_off
+  SIGNAL bin       : STD_LOGIC_VECTOR(g_fft_size_w-1 DOWNTO 0):= (OTHERS => '0');
+  SIGNAL band      : STD_LOGIC_VECTOR(g_fft_size_w-2 DOWNTO 0);
+  SIGNAL fft_x_re  : STD_LOGIC_VECTOR(out_re'RANGE);
+  SIGNAL fft_x_im  : STD_LOGIC_VECTOR(out_im'RANGE);
+  SIGNAL fft_y_re  : STD_LOGIC_VECTOR(out_re'RANGE);
+  SIGNAL fft_y_im  : STD_LOGIC_VECTOR(out_im'RANGE);
+  SIGNAL power     : STD_LOGIC_VECTOR(2*g_out_dat_w-1 DOWNTO 0);
+  SIGNAL power_x   : STD_LOGIC_VECTOR(2*g_out_dat_w-1 DOWNTO 0);
+  SIGNAL power_y   : STD_LOGIC_VECTOR(2*g_out_dat_w-1 DOWNTO 0);
+  -- synthesis translate_on
+
+BEGIN
+
+  -- The pipelined fft is composed of a number of consecutive stages.
+  -- The output of each stage is used as input for the next stage.
+  -- NB. The first stage has index c_nof_stages-1, the last stage has index 0.
+  
+  
+  switch: ENTITY pft2_lib.pft_switch
+  GENERIC MAP (
+    g_dat_w    => g_in_dat_w,
+    g_fft_sz_w => g_fft_size_w
+  )
+  PORT MAP (
+    rst          => rst,
+    clk          => clk,
+    in_val       => in_val,
+    in_sync      => in_sync,    
+    in_re        => in_re,
+    in_im        => in_im,
+    switch_en    => switch_en,
+    out_re       => switch_re,
+    out_im       => switch_im,
+    out_val      => switch_val,
+    out_sync     => switch_sync
+  );
+
+  first_gen : IF (c_nof_stages>1) GENERATE
+    first_stage : ENTITY pft2_lib.pft_stage
+      GENERIC MAP (
+        g_index          => c_nof_stages-1,
+        g_in_dat_w       => g_in_dat_w,
+        g_out_dat_w      => c_stage_dat_w
+      )
+      PORT MAP (
+        in_re            => switch_re,
+        in_im            => switch_im,
+        in_val           => switch_val,
+        in_sync          => switch_sync,
+        out_re           => stage(c_nof_stages-2).re,
+        out_im           => stage(c_nof_stages-2).im,
+        out_val          => stage(c_nof_stages-2).val,
+        out_sync         => stage(c_nof_stages-2).sync,
+        clk              => clk,
+        rst              => rst
+      );
+  END GENERATE;
+
+
+  middle_gen : FOR i IN c_nof_stages-2 DOWNTO 1 GENERATE
+    middle_stage : ENTITY pft2_lib.pft_stage
+      GENERIC MAP (
+        g_index          => i,
+        g_in_dat_w       => c_stage_dat_w,
+        g_out_dat_w      => c_stage_dat_w
+      )
+      PORT MAP (
+        in_re            => stage(i).re,
+        in_im            => stage(i).im,
+        in_val           => stage(i).val,
+        in_sync          => stage(i).sync,
+        out_re           => stage(i-1).re,
+        out_im           => stage(i-1).im,
+        out_val          => stage(i-1).val,
+        out_sync         => stage(i-1).sync,
+        clk              => clk,
+        rst              => rst
+      );
+  END GENERATE;
+
+  last_gen : IF c_nof_stages>1 GENERATE
+    last_stage : ENTITY pft2_lib.pft_stage
+      GENERIC MAP (
+        g_index          => 0,
+        g_in_dat_w       => c_stage_dat_w,
+        g_out_dat_w      => c_pft_dat_w
+      )
+      PORT MAP (
+        in_re            => stage(0).re,
+        in_im            => stage(0).im,
+        in_val           => stage(0).val,
+        in_sync          => stage(0).sync,
+        out_re           => pft_re,
+        out_im           => pft_im,
+        out_val          => pft_val,
+        out_sync         => pft_sync,
+        clk              => clk,
+        rst              => rst
+      );
+  END GENERATE;
+
+  only_gen : IF c_nof_stages=1 GENERATE
+    only_stage : ENTITY pft2_lib.pft_stage
+        GENERIC MAP (
+          g_index          => 0,
+          g_in_dat_w       => g_in_dat_w,
+          g_out_dat_w      => c_pft_dat_w
+        )
+        PORT MAP (
+          in_re            => in_re,
+          in_im            => in_im,
+          in_val           => in_val,
+          in_sync          => in_sync,
+          out_re           => pft_re,
+          out_im           => pft_im,
+          out_val          => pft_val,
+          out_sync         => pft_sync,
+          clk              => clk,
+          rst              => rst
+        );
+  END GENERATE;
+
+  -- In "BITREV" mode, fft output is in bit reversed order.
+  none_gen : IF g_mode = PFT_MODE_BITREV GENERATE
+    sep_re   <= pft_re;
+    sep_im   <= pft_im;
+    sep_val  <= pft_val;
+    sep_sync <= pft_sync;
+  END GENERATE;
+
+  buf_gen : IF g_mode /= PFT_MODE_BITREV GENERATE
+
+    buf : ENTITY pft2_lib.pft_buffer
+      GENERIC MAP (
+        g_fft_size_w      => g_fft_size_w,
+        g_dat_w           => c_pft_dat_w
+      )
+      PORT MAP (
+        wr_re             => pft_re,
+        wr_im             => pft_im,
+        wr_val            => pft_val,
+        wr_sync           => pft_sync,
+        rd_re             => buf_re,
+        rd_im             => buf_im,
+        rd_adr            => buf_adr,
+        rd_en             => buf_en,
+        rd_val            => buf_val,
+        rd_sync           => buf_sync,
+        rd_rdy            => buf_rdy,
+        clk               => clk,
+        rst               => rst
+      );
+  END GENERATE;
+
+
+   reverse_gen : IF g_mode = PFT_MODE_COMPLEX GENERATE
+    reverse : ENTITY pft2_lib.pft_reverse
+      GENERIC MAP (
+        g_fft_sz          => 2**g_fft_size_w,
+        g_fft_sz_w        => g_fft_size_w,
+        g_data_w          => c_pft_dat_w
+      )
+      PORT MAP (
+        rddata_re         => buf_re,
+        rddata_im         => buf_im,
+        rdaddr            => buf_adr,
+        rden              => buf_en,
+        rdval             => buf_val,
+        rdsync            => buf_sync,
+        page_rdy          => buf_rdy,
+        out_dat_re        => sep_re,
+        out_dat_im        => sep_im,
+        out_val           => sep_val,
+        out_sync          => sep_sync,
+        clk               => clk,
+        rst               => rst
+      );     
+
+  END GENERATE;
+
+
+  separate_gen : IF g_mode = PFT_MODE_REAL2 GENERATE
+    separate : ENTITY pft2_lib.pft_separate
+      GENERIC MAP (
+        g_fft_sz          => 2**g_fft_size_w,
+        g_fft_sz_w        => g_fft_size_w,
+        g_rd_dat_w        => c_pft_dat_w,
+        g_out_dat_w       => g_out_dat_w
+      )
+      PORT MAP (
+        rddata_re         => buf_re,
+        rddata_im         => buf_im,
+        rdaddr            => buf_adr,
+        rden              => buf_en,
+        rdval             => buf_val,
+        rdsync            => buf_sync,
+        page_rdy          => buf_rdy,
+        out_dat_re        => sep_re,
+        out_dat_im        => sep_im,
+        out_val           => sep_val,
+        out_sync          => sep_sync,
+        clk               => clk,
+        rst               => rst
+      );
+  END GENERATE;
+
+  unswitch: ENTITY pft2_lib.pft_unswitch
+  GENERIC MAP (
+    g_dat_w    => g_out_dat_w,
+    g_fft_sz_w => g_fft_size_w
+  )
+  PORT MAP (
+    rst          => rst,
+    clk          => clk,
+    in_val       => sep_val,
+    in_sync      => sep_sync,    
+    in_re        => sep_re,
+    in_im        => sep_im,
+    switch_en    => switch_en,
+    out_re       => unswitch_re,
+    out_im       => unswitch_im,
+    out_val      => unswitch_val,
+    out_sync     => unswitch_sync
+  );
+
+
+  -- calculate the power. This is intended to be used in simulations only.
+  
+  -- synthesis translate_off    
+    determine_bin : PROCESS (clk)
+    BEGIN
+      IF rising_edge(clk) THEN
+        IF unswitch_val= '1' THEN
+          bin <= STD_LOGIC_VECTOR(UNSIGNED(bin)+1);
+        END IF;
+      END IF;
+    END PROCESS;
+    
+    band  <= bin(bin'HIGH DOWNTO 1);
+
+    power <= STD_LOGIC_VECTOR(   SIGNED(unswitch_re) * SIGNED(unswitch_re)
+                               + SIGNED(unswitch_im) * SIGNED(unswitch_im)
+                              ) WHEN unswitch_val='1' ELSE (OTHERS => '0');
+
+    -- Wave window: View fft_re, fft_im in analogue format
+    -- Wave window: View power in binary format to get a spectrum diagram
+    
+    -- power_x <= power WHEN bin(0) = '0' ELSE power_x;
+    -- power_y <= power WHEN bin(0) = '1' ELSE power_y;
+    
+    -- Use clk to avoid limit cycle pulses in power_x and power_y
+    demux_power : PROCESS(clk)
+    BEGIN
+      IF falling_edge(clk) THEN
+        IF unswitch_val= '1' THEN
+          IF bin(0) = '0' THEN
+            fft_x_re <= unswitch_re;
+            fft_x_im <= unswitch_im;
+            power_x  <= power;
+          ELSE
+            fft_y_re <= unswitch_re;
+            fft_y_im <= unswitch_im;
+            power_y  <= power;
+          END IF;
+        END IF;
+      END IF;
+    END PROCESS;  
+  -- synthesis translate_on
+  
+  out_re   <= unswitch_re;
+  out_im   <= unswitch_im;
+  out_val  <= unswitch_val;
+  out_sync <= unswitch_sync;
+
+END str;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_bf.vhd b/applications/lofar1/pft2/src/vhdl/pft_bf.vhd
index 4396f98f1315015b788791f4411077c6504f92bc..0fb8742918d9c84b5f4d8a61f4a1a29f73d50ca7 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_bf.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_bf.vhd
@@ -1,5 +1,33 @@
-LIBRARY ieee;
-USE IEEE.std_logic_1164.ALL;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+
+LIBRARY common_lib;
 
 
 ENTITY pft_bf IS
@@ -25,3 +53,360 @@ ENTITY pft_bf IS
   );
 END pft_bf;
 
+
+ARCHITECTURE rtl OF pft_bf IS
+
+  CONSTANT c_read_pipeline  : NATURAL := 1;
+  CONSTANT c_add_pipeline   : NATURAL := 2;
+  CONSTANT c_write_pipeline : NATURAL := 1;
+  CONSTANT c_pipeline       : NATURAL := c_read_pipeline+c_add_pipeline+c_write_pipeline;
+  CONSTANT c_cnt_w          : NATURAL := g_index+2;
+  CONSTANT c_regbank_size_w : NATURAL := g_index;
+  CONSTANT c_regbank_size   : NATURAL := 2**c_regbank_size_w;
+  CONSTANT c_dat_w          : NATURAL := g_in_dat_w+1;
+
+  TYPE sig_rec IS RECORD
+    val     : STD_LOGIC;
+    sync    : STD_LOGIC;
+    s0      : STD_LOGIC;
+    s1      : STD_LOGIC;
+    wr_req  : STD_LOGIC;
+  END RECORD;
+
+  TYPE sig_array IS ARRAY (c_pipeline-1 DOWNTO 0) OF sig_rec;
+
+  SUBTYPE fifo_type IS STD_LOGIC_VECTOR(2*c_dat_w-1 DOWNTO 0);
+  TYPE fifo_arr IS ARRAY(c_regbank_size-c_pipeline DOWNTO 0) OF fifo_type;
+
+  SIGNAL fifo_dat     : fifo_arr;
+  SIGNAL nxt_fifo_dat : fifo_arr;
+
+  SIGNAL sig : sig_array;
+  SIGNAL nxt_sig : sig_array;
+
+  SIGNAL init         : STD_LOGIC;
+  SIGNAL nxt_init     : STD_LOGIC;
+
+  SIGNAL cnt          : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0);
+  SIGNAL nxt_cnt      : STD_LOGIC_VECTOR(cnt'RANGE);
+
+  SIGNAL s0           : STD_LOGIC;
+  SIGNAL s1           : STD_LOGIC;
+  SIGNAL sync         : STD_LOGIC;
+  SIGNAl nxt_sync     : STD_LOGIC;
+
+  SIGNAL add_ar       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL add_ai       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL add_br       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL add_bi       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL add_cr       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL add_ci       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+
+  SIGNAL sub_ar       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL sub_ai       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL sub_br       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL sub_bi       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL sub_cr       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL sub_ci       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+
+  SIGNAL nxt_out_re   : STD_LOGIC_VECTOR(out_re'RANGE);
+  SIGNAL nxt_out_im   : STD_LOGIC_VECTOR(out_re'RANGE);
+
+  SIGNAL reg_re       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL nxt_reg_re   : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+
+  SIGNAL reg_im       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL nxt_reg_im   : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+
+  SIGNAL rd_re        : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL rd_im        : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL rd_req       : STD_LOGIC;
+
+  SIGNAL nxt_wr_re    : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL nxt_wr_im    : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+
+  SIGNAL wr_req       : STD_LOGIC;
+
+  SIGNAL wr_dat       : STD_LOGIC_VECTOR(2*c_dat_w -1 DOWNTO 0);
+  SIGNAL nxt_wr_dat   : STD_LOGIC_VECTOR(2*c_dat_w -1 DOWNTO 0);
+  SIGNAL rd_dat       : STD_LOGIC_VECTOR(2*c_dat_w -1 DOWNTO 0);
+
+BEGIN
+
+  out_val      <= sig(0).val;
+  out_sync     <= sig(0).sync;
+  wr_req       <= sig(0).wr_req;
+
+  nxt_wr_dat   <= nxt_wr_re & nxt_wr_im;
+  --wr_re        <= wr_dat(wr_dat'HIGH DOWNTO wr_im'LENGTH);
+  --wr_im        <= wr_dat(wr_im'RANGE);
+
+  s0  <= cnt(cnt'HIGH-1);
+  s1  <= cnt(cnt'HIGH  ) WHEN g_bf_name="bf2" ELSE '0';
+
+  registers : PROCESS (clk, rst)
+  BEGIN
+    IF rst = '1' THEN
+      init     <= '0';
+      cnt      <= (OTHERS => '0');
+      sig      <= (OTHERS => (OTHERS => '0'));
+      sync     <= '0';
+      out_re   <= (OTHERS => '0');
+      out_im   <= (OTHERS => '0');
+      wr_dat   <= (OTHERS => '0');
+      reg_re   <= (OTHERS => '0');
+      reg_im   <= (OTHERS => '0');
+    ELSIF RISING_EDGE(clk) THEN
+      init     <= nxt_init;
+      cnt      <= nxt_cnt;
+      sig      <= nxt_sig;
+      sync     <= nxt_sync;
+      out_re   <= nxt_out_re;
+      out_im   <= nxt_out_im;
+      wr_dat   <= nxt_wr_dat;
+      reg_re   <= nxt_reg_re;
+      reg_im   <= nxt_reg_im;
+    END IF;
+  END PROCESS;
+
+  sync_proc : PROCESS(cnt, in_sync, sync)
+  BEGIN
+    nxt_sync               <= sync;
+    nxt_sig(sig'HIGH).sync <= '0';
+    IF in_sync = '1' OR UNSIGNED(cnt)=c_regbank_size-1 THEN
+      nxt_sync               <= in_sync;
+      nxt_sig(sig'HIGH).sync <= sync;
+    END IF;
+  END PROCESS;
+
+  cnt_proc : PROCESS (cnt, in_val, in_sync)
+  BEGIN
+    nxt_cnt <= cnt;
+    IF in_sync = '1' OR SIGNED(cnt)=-1 THEN
+      nxt_cnt  <= (OTHERS => '0');
+    ELSIF in_val = '1' THEN
+      nxt_cnt <= STD_LOGIC_VECTOR(UNSIGNED(cnt) + 1);
+    END IF;
+  END PROCESS;
+
+  init_proc : PROCESS(cnt,init,in_val)
+  BEGIN
+    nxt_init <= init;
+    IF UNSIGNED(cnt)=c_regbank_size-1 AND in_val='1' THEN
+      nxt_init <= '1';
+    END IF;
+  END PROCESS;
+
+  rd_proc : PROCESS(rd_dat,sig)
+  BEGIN
+    rd_re <= rd_dat(rd_dat'HIGH DOWNTO rd_im'LENGTH);
+    rd_im <= rd_dat(rd_im'RANGE);
+    --synthesis translate off
+    IF sig(sig'HIGH).val='0' THEN
+      rd_re <= (OTHERS => '0');
+      rd_im <= (OTHERS => '0');
+    END IF;
+    --synthesis translate on
+  END PROCESS;
+
+  rd_req       <= in_val AND init;
+
+  nxt_reg_re <= STD_LOGIC_VECTOR(RESIZE(SIGNED(in_re),c_dat_w));
+  nxt_reg_im <= STD_LOGIC_VECTOR(RESIZE(SIGNED(in_im),c_dat_w));
+
+  nxt_sig(sig'HIGH).val    <= rd_req;
+  nxt_sig(sig'HIGH).s0     <= s0;
+  nxt_sig(sig'HIGH).s1     <= s1;
+  nxt_sig(sig'HIGH).wr_req <= in_val;
+
+  nxt_sig(c_pipeline-2 DOWNTO 0) <= sig(c_pipeline-1 DOWNTO 1);
+
+  in_proc : PROCESS (sig, reg_re, reg_im, rd_re, rd_im)
+  BEGIN
+    add_ar <= rd_re;
+    add_ai <= rd_im;
+    sub_ar <= reg_re;
+    sub_ai <= reg_im;
+    add_br <= (OTHERS => '0');
+    add_bi <= (OTHERS => '0');
+    sub_br <= (OTHERS => '0');
+    sub_bi <= (OTHERS => '0');
+    IF sig(sig'HIGH).s0='1' THEN
+      sub_ar <= rd_re;
+      sub_ai <= rd_im;
+      add_br <= reg_re;
+      add_bi <= reg_im;
+      sub_br <= reg_re;
+      sub_bi <= reg_im;
+      IF sig(sig'HIGH).s1='1' THEN
+        add_br <= reg_im;
+        add_bi <= reg_re;
+        sub_br <= reg_im;
+        sub_bi <= reg_re;
+      END IF;
+    END IF;
+  END PROCESS;
+
+
+  out_proc : PROCESS (sig, add_cr,add_ci,sub_cr,sub_ci)
+  BEGIN
+    nxt_out_re  <= STD_LOGIC_VECTOR(RESIZE(SIGNED(add_cr),g_out_dat_w));
+    nxt_out_im  <= STD_LOGIC_VECTOR(RESIZE(SIGNED(add_ci),g_out_dat_w));
+    nxt_wr_re   <= sub_cr;
+    nxt_wr_im   <= sub_ci;
+    IF sig(1).s0 = '1' AND sig(1).s1 = '1' THEN
+      nxt_out_re  <= STD_LOGIC_VECTOR(RESIZE(SIGNED(add_cr),g_out_dat_w));
+      nxt_out_im  <= STD_LOGIC_VECTOR(RESIZE(SIGNED(sub_ci),g_out_dat_w));
+      nxt_wr_re   <= sub_cr;
+      nxt_wr_im   <= add_ci;
+    END IF;
+  END PROCESS;
+
+
+-- Adds/ Subs ------------------------------------------------------------------
+
+--  Intel Altera lmp_add_sub carry in:
+--  ADD: out = a + b + cin      => cin = '0' to have out = a + b
+--  SUB: out = a - b + cin - 1  => cin = '1' to have out = a - b
+
+  --cadd : ENTITY common_lib.common_caddsub
+  --GENERIC MAP (
+  --  g_in_a_w   => c_dat_w,
+  --  g_in_b_w   => c_dat_w,
+  --  g_out_c_w  => c_dat_w,
+  --  g_pipeline => c_add_pipeline,
+  --  g_add_sub  => "ADD"
+  --)
+  --PORT MAP (
+  --  in_ar  => add_ar,
+  --  in_ai  => add_ai,
+  --  in_br  => add_br,
+  --  in_bi  => add_bi,
+  --  in_cr  => '0',
+  --  in_ci  => '0',
+  --  out_cr => add_cr,
+  --  out_ci => add_ci,
+  --  clk    => clk,
+  --  rst    => rst
+  --);
+  
+  cadd : ENTITY common_lib.common_complex_add_sub
+  GENERIC MAP (
+    g_direction       => "ADD",
+    g_representation  => "SIGNED",
+    g_pipeline_input  => 0,               -- 0 or 1
+    g_pipeline_output => c_add_pipeline,  -- >= 0
+    g_in_dat_w        => c_dat_w,
+    g_out_dat_w       => c_dat_w          -- only support g_out_dat_w=g_in_dat_w and g_out_dat_w=g_in_dat_w+1
+  )
+  PORT MAP (
+    clk      => clk,
+    in_ar    => add_ar,
+    in_ai    => add_ai,
+    in_br    => add_br,
+    in_bi    => add_bi,
+    out_re   => add_cr,
+    out_im   => add_ci
+  );
+  
+--  csub : ENTITY common_lib.common_caddsub
+--  GENERIC MAP (
+--    g_in_a_w   => c_dat_w,
+--    g_in_b_w   => c_dat_w,
+--    g_out_c_w  => c_dat_w,
+--    g_pipeline => c_add_pipeline,
+--    g_add_sub  => "SUB"
+--  )
+--  PORT MAP (
+--    in_ar  => sub_ar,
+--    in_ai  => sub_ai,
+--    in_br  => sub_br,
+--    in_bi  => sub_bi,
+--    in_cr  => '1',
+--    in_ci  => '1',
+--    out_cr => sub_cr,
+--    out_ci => sub_ci,
+--    clk    => clk,
+--    rst    => rst
+--  );
+
+  csub : ENTITY common_lib.common_complex_add_sub
+  GENERIC MAP (
+    g_direction       => "SUB",
+    g_representation  => "SIGNED",
+    g_pipeline_input  => 0,               -- 0 or 1
+    g_pipeline_output => c_add_pipeline,  -- >= 0
+    g_in_dat_w        => c_dat_w,
+    g_out_dat_w       => c_dat_w          -- only support g_out_dat_w=g_in_dat_w and g_out_dat_w=g_in_dat_w+1
+  )
+  PORT MAP (
+    clk      => clk,
+    in_ar    => sub_ar,
+    in_ai    => sub_ai,
+    in_br    => sub_br,
+    in_bi    => sub_bi,
+    out_re   => sub_cr,
+    out_im   => sub_ci
+  );
+  
+-- regbank --------------------------------------------------------------------------
+  fifo_gen: IF c_regbank_size>8 GENERATE
+  fifo : ENTITY common_lib.common_fifo_sc
+  GENERIC MAP (
+    g_dat_w     => wr_dat'LENGTH,
+    g_nof_words => c_regbank_size
+  )
+  PORT MAP (
+    wr_dat => wr_dat,
+    wr_req => wr_req,
+    rd_dat => rd_dat,
+    rd_req => rd_req,
+    clk    => clk,
+    rst    => rst
+  );
+  END GENERATE fifo_gen;
+
+  
+  fifo2_gen : IF c_regbank_size>c_pipeline AND c_regbank_size<=8 GENERATE
+  fifo2_reg : PROCESS (clk, rst)
+  BEGIN
+    IF rst = '1' THEN
+      fifo_dat <= (OTHERS => (OTHERS => '0'));
+    ELSIF RISING_EDGE(clk) THEN
+      fifo_dat <= nxt_fifo_dat;
+    END IF;
+  END PROCESS;
+  
+  fifo2_proc : PROCESS(fifo_dat,wr_req,wr_dat)
+  BEGIN
+    nxt_fifo_dat <= fifo_dat;
+    IF wr_req='1' THEN
+      nxt_fifo_dat <= wr_dat & fifo_dat(fifo_dat'HIGH DOWNTO 1);
+    END IF;
+    rd_dat <= fifo_dat(0);
+  END PROCESS;
+  END GENERATE;
+
+  fifo3_gen : IF c_regbank_size=c_pipeline GENERATE
+  fifo3_reg : PROCESS (clk, rst)
+  BEGIN
+    IF rst = '1' THEN
+      fifo_dat <= (OTHERS => (OTHERS => '0'));
+    ELSIF RISING_EDGE(clk) THEN
+      fifo_dat <= nxt_fifo_dat;
+    END IF;
+  END PROCESS;
+  
+  fifo3_proc : PROCESS(fifo_dat, wr_req, wr_dat)
+  BEGIN
+    nxt_fifo_dat <= fifo_dat;
+    IF wr_req='1' THEN
+      nxt_fifo_dat(0) <= wr_dat;
+    END IF;
+    rd_dat <= fifo_dat(0);
+  END PROCESS;
+  END GENERATE;
+
+  ASSERT c_regbank_size>=c_pipeline SEVERITY FAILURE;
+
+END rtl;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_bf_fw.vhd b/applications/lofar1/pft2/src/vhdl/pft_bf_fw.vhd
index 72b79634029d9adf395405f716ad8054afdc3ed6..b3920c53f36ac381fcfa4792845463a2e76d6a2a 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_bf_fw.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_bf_fw.vhd
@@ -1,6 +1,33 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
 
-LIBRARY ieee;
-USE IEEE.std_logic_1164.ALL;
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+
+LIBRARY common_lib;
 
 
 ENTITY pft_bf_fw IS
@@ -26,3 +53,239 @@ ENTITY pft_bf_fw IS
   );
 END pft_bf_fw;
 
+
+ARCHITECTURE rtl OF pft_bf_fw IS
+
+  CONSTANT c_add_pipeline  : NATURAL := 2;
+  CONSTANT c_dist          : NATURAL := 2**g_index;  
+  CONSTANT c_pipeline      : NATURAL := c_add_pipeline + c_dist + 2;
+  CONSTANT c_cnt_w         : NATURAL := g_index + 2;  
+    
+  TYPE reg_arr IS ARRAY (c_dist DOWNTO -c_dist) OF STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
+  TYPE val_arr IS ARRAY (c_dist DOWNTO -c_dist) OF STD_LOGIC;  
+      
+  SIGNAL xr                : reg_arr;
+  SIGNAL nxt_xr            : reg_arr;  
+  
+  SIGNAL xi                : reg_arr;
+  SIGNAL nxt_xi            : reg_arr;  
+  
+  
+  SIGNAL pipe_val          : STD_LOGIC_VECTOR(c_pipeline-1 DOWNTO 0);
+  SIGNAL nxt_pipe_val      : STD_LOGIC_VECTOR(pipe_val'RANGE);  
+  SIGNAL pipe_sync         : STD_LOGIC_VECTOR(c_pipeline-1 DOWNTO 0);
+  SIGNAL nxt_pipe_sync     : STD_LOGIC_VECTOR(pipe_sync'RANGE);  
+  
+  SIGNAL cnt               : STD_LOGIC_VECTOR(c_cnt_w-1 DOWNTO 0);
+  SIGNAL nxt_cnt           : STD_LOGIC_VECTOR(cnt'RANGE);    
+  SIGNAL s0                : STD_LOGIC;
+  SIGNAL s1                : STD_LOGIC;
+
+  SIGNAL yr_a              : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);    
+  SIGNAL yr_b              : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);  
+  SIGNAL yi_a              : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);  
+  SIGNAL yi_b              : STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);  
+  SIGNAL yr_add            : STD_LOGIC;
+  SIGNAL yi_add            : STD_LOGIC;
+  SIGNAL yr_cry            : STD_LOGIC;
+  SIGNAL yi_cry            : STD_LOGIC;
+
+
+  SIGNAL nxt_yr_a          : STD_LOGIC_VECTOR(yr_a'RANGE);
+  SIGNAL nxt_yr_b          : STD_LOGIC_VECTOR(yr_b'RANGE);
+  SIGNAL nxt_yi_a          : STD_LOGIC_VECTOR(yi_a'RANGE);
+  SIGNAL nxt_yi_b          : STD_LOGIC_VECTOR(yi_b'RANGE);
+  SIGNAL nxt_yr_add        : STD_LOGIC;
+  SIGNAL nxt_yi_add        : STD_LOGIC;
+
+
+BEGIN
+
+  nxt_xr  <= in_re  & xr (xr 'HIGH DOWNTO xr 'LOW+1);
+  nxt_xi  <= in_im  & xi (xi 'HIGH DOWNTO xi 'LOW+1);
+  
+  nxt_pipe_val  <= in_val  & pipe_val (pipe_val 'HIGH DOWNTO 1);
+  nxt_pipe_sync <= in_sync & pipe_sync(pipe_sync'HIGH DOWNTO 1);
+  
+  s0  <= cnt(cnt'HIGH-1);      
+  s1  <= cnt(cnt'HIGH  ) WHEN g_bf_name="bf2" ELSE '0';
+  
+  out_val  <= pipe_val(0);
+  out_sync <= pipe_sync(0);  
+    
+  registers : PROCESS (clk, rst)
+  BEGIN
+    IF rst = '1' THEN
+      xr          <= (OTHERS => (OTHERS => '0'));
+      xi          <= (OTHERS => (OTHERS => '0'));
+      pipe_val    <= (OTHERS => '0');
+      pipe_sync   <= (OTHERS => '0');      
+      cnt         <= (OTHERS => '0');
+      yr_a        <= (OTHERS => '0');
+      yr_b        <= (OTHERS => '0');
+      yi_a        <= (OTHERS => '0');
+      yi_b        <= (OTHERS => '0');
+      yr_add      <= '0';
+      yi_add      <= '0';            
+    ELSIF RISING_EDGE(clk) THEN
+      xr          <= nxt_xr;      
+      xi          <= nxt_xi;     
+      pipe_val    <= nxt_pipe_val;
+      pipe_sync   <= nxt_pipe_sync;
+      cnt         <= nxt_cnt;
+      yr_a        <= nxt_yr_a;
+      yr_b        <= nxt_yr_b;
+      yi_a        <= nxt_yi_a;
+      yi_b        <= nxt_yi_b;
+      yr_add      <= nxt_yr_add;
+      yi_add      <= nxt_yi_add;
+    END IF;
+  END PROCESS;
+
+
+  counter : PROCESS (cnt, pipe_val, pipe_sync)
+  BEGIN
+    nxt_cnt <= cnt;
+    IF pipe_sync(pipe_sync'HIGH-c_dist) = '1' THEN
+      nxt_cnt <= (OTHERS => '0');
+    ELSIF pipe_val(pipe_val'HIGH-c_dist) = '1' THEN
+      nxt_cnt <= STD_LOGIC_VECTOR(UNSIGNED(cnt) + 1);
+    END IF;
+  END PROCESS;
+
+
+  PROCESS(s0,s1,xr,xi)  
+    VARIABLE state : STD_LOGIC_VECTOR (1 DOWNTO 0);      
+  BEGIN
+    state := s1 & s0;    
+    CASE state IS
+    
+      WHEN "00" =>
+        -- y  <= x(n+k) + x(n)
+        
+        -- yr <= xr(n+k) + xr(n)
+        nxt_yr_add <= '1';
+        nxt_yr_a   <= xr(0);
+        nxt_yr_b   <= xr(c_dist);
+        -- yi <= xi(n+k) + xi(n);     
+        nxt_yi_add <= '1';
+        nxt_yi_a   <= xi(0);
+        nxt_yi_b   <= xi(c_dist);
+        
+      WHEN "01" =>
+        -- y  <= x(n-k) - x(n)
+        
+        -- yr <= xr(n-k) - xr(n)
+        nxt_yr_add <= '0';
+        nxt_yr_a   <= xr(-c_dist);
+        nxt_yr_b   <= xr(0);
+        -- yi <= xi(n-k) - xi(n)
+        nxt_yi_add <= '0';
+        nxt_yi_a   <= xi(-c_dist);
+        nxt_yi_b   <= xi(0);      
+        
+      WHEN "10" =>
+        -- y <= x(n) - i*x(n+k)
+      
+        -- yr <= xr(n)   + xi(n+k)
+        nxt_yr_add <= '1';
+        nxt_yr_a   <= xr(0);
+        nxt_yr_b   <= xi(c_dist);
+        -- yi <= xi(n)   - xr(n+k)
+        nxt_yi_add <= '0';
+        nxt_yi_a   <= xi(0);
+        nxt_yi_b   <= xr(c_dist);
+  
+      WHEN OTHERS =>
+        -- y <= x(n-k) + i*x(n)        
+        -- yr(n) <= xr(n-k) - xi(n);       
+        nxt_yr_add <= '0';
+        nxt_yr_a   <= xr(-c_dist);
+        nxt_yr_b   <= xi(0);
+        -- yi(n) <= xi(n-k) + xr(n);        
+        nxt_yi_add <= '1';
+        nxt_yi_a   <= xi(-c_dist);
+        nxt_yi_b   <= xr(0);
+                
+    END CASE;  
+  END PROCESS;
+
+  -- Adds/ Subs ----------------------------------------------------------------
+
+--  Intel Altera lmp_add_sub carry in:
+--  ADD: out = a + b + cin      => cin = '0' to have out = a + b
+--  SUB: out = a - b + cin - 1  => cin = '1' to have out = a - b
+
+--  yr_cry <= NOT yr_add;
+  
+--  yr : ENTITY common_lib.common_addsub  
+--  GENERIC MAP (
+--    g_in_a_w    => g_in_dat_w,
+--    g_in_b_w    => g_in_dat_w,
+--    g_out_c_w   => g_out_dat_w,    
+--    g_pipeline  => c_add_pipeline,
+--    g_add_sub   => "BOTH"
+--  )
+--  PORT MAP (
+--    in_a        => yr_a,
+--    in_b        => yr_b,
+--    in_cry      => yr_cry,
+--    add_sub     => yr_add,
+--    clk         => clk,
+--    out_c       => out_re
+--  );
+
+  yr : ENTITY common_lib.common_add_sub
+  GENERIC MAP (
+    g_direction       => "BOTH",
+    g_representation  => "SIGNED",
+    g_pipeline_input  => 0,               -- 0 or 1
+    g_pipeline_output => c_add_pipeline,  -- >= 0
+    g_in_dat_w        => g_in_dat_w,
+    g_out_dat_w       => g_out_dat_w          -- only support g_out_dat_w=g_in_dat_w and g_out_dat_w=g_in_dat_w+1
+  )
+  PORT MAP (
+    clk      => clk,
+    sel_add  => yr_add,
+    in_a     => yr_a,
+    in_b     => yr_b,
+    result   => out_re
+  );
+  
+--  yi_cry <= NOT yi_add;
+--  
+--  yi : ENTITY common_lib.common_addsub  
+--  GENERIC MAP (
+--    g_in_a_w    => g_in_dat_w,
+--    g_in_b_w    => g_in_dat_w,
+--    g_out_c_w   => g_out_dat_w,    
+--    g_pipeline  => c_add_pipeline,
+--    g_add_sub   => "BOTH"
+--  )
+--  PORT MAP (
+--    in_a        => yi_a,
+--    in_b        => yi_b,
+--    in_cry      => yi_cry,
+--    add_sub     => yi_add,
+--    clk         => clk,
+--    out_c       => out_im
+--  );
+
+  yi : ENTITY common_lib.common_add_sub
+  GENERIC MAP (
+    g_direction       => "BOTH",
+    g_representation  => "SIGNED",
+    g_pipeline_input  => 0,               -- 0 or 1
+    g_pipeline_output => c_add_pipeline,  -- >= 0
+    g_in_dat_w        => g_in_dat_w,
+    g_out_dat_w       => g_out_dat_w          -- only support g_out_dat_w=g_in_dat_w and g_out_dat_w=g_in_dat_w+1
+  )
+  PORT MAP (
+    clk      => clk,
+    sel_add  => yi_add,
+    in_a     => yi_a,
+    in_b     => yi_b,
+    result   => out_im
+  );
+  
+END rtl;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_buffer.vhd b/applications/lofar1/pft2/src/vhdl/pft_buffer.vhd
index 754cc0270e5e556e2893132beed1aad2ee18a256..d2112956ad7baa03567862da3426757ed982e9a9 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_buffer.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_buffer.vhd
@@ -1,6 +1,35 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
 LIBRARY IEEE;
 USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
 
+LIBRARY common_lib;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
 
 ENTITY pft_buffer IS
   GENERIC (
@@ -23,3 +52,137 @@ ENTITY pft_buffer IS
     rst               : IN  STD_LOGIC
   );
 END pft_buffer;
+
+
+ARCHITECTURE rtl OF pft_buffer IS
+
+  CONSTANT c_latency       : NATURAL := 2;
+  CONSTANT c_adr_w         : NATURAL := g_fft_size_w+1;  
+  CONSTANT c_nof_words     : NATURAL := 2**c_adr_w; 
+  
+  CONSTANT c_ram   : t_c_mem := (latency  => c_latency,
+                                 adr_w    => c_adr_w,
+                                 dat_w    => 2*g_dat_w,
+                                 nof_dat  => c_nof_words,  -- <= 2**g_addr_w
+                                 init_sl  => '0');
+
+  SIGNAL rd_dat            : STD_LOGIC_VECTOR(2*g_dat_w-1 DOWNTO 0);
+  SIGNAL wr_dat            : STD_LOGIC_VECTOR(rd_dat'RANGE);  
+  SIGNAL rd_adr_paged      : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);
+  SIGNAL wr_adr_paged      : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);
+  SIGNAL wr_adr            : STD_LOGIC_VECTOR(g_fft_size_w-1 DOWNTO 0);
+  SIGNAL nxt_wr_adr        : STD_LOGIC_VECTOR(wr_adr'RANGE);  
+  SIGNAL wr_page           : STD_LOGIC;
+  SIGNAL nxt_wr_page       : STD_LOGIC;
+  SIGNAL rd_page           : STD_LOGIC;
+  SIGNAL nxt_rd_page       : STD_LOGIC;
+  SIGNAL wr_en             : STD_LOGIC;
+  
+    
+  SIGNAL pipe_val          : STD_LOGIC_VECTOR(c_latency-1 DOWNTO 0);  
+  SIGNAL nxt_pipe_val      : STD_LOGIC_VECTOR(pipe_val'RANGE);
+  
+  FUNCTION bit_rev(adr : IN STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+    VARIABLE result: STD_LOGIC_VECTOR(adr'RANGE);    
+  BEGIN
+    FOR i IN adr'HIGH DOWNTO 0 LOOP
+      result(i) := adr(adr'HIGH-i);
+    END LOOP;
+    RETURN result;
+  END FUNCTION;
+  
+BEGIN
+
+  nxt_rd_page <= NOT nxt_wr_page;
+  rd_adr_paged <= rd_page & rd_adr;      
+  
+  registers : PROCESS (rst, clk)
+  BEGIN
+    IF rst = '1' THEN
+      pipe_val   <= (OTHERS => '0');
+      wr_adr     <= (OTHERS => '0');
+      wr_page    <= '0';
+      rd_page    <= '1';
+    ELSIF rising_edge(clk) THEN
+      pipe_val   <= nxt_pipe_val;
+      wr_adr     <= nxt_wr_adr;      
+      wr_page    <= nxt_wr_page;
+      rd_page    <= nxt_rd_page;
+    END IF;
+  END PROCESS;
+  
+  pipe_proc: PROCESS(pipe_val,rd_en) 
+  BEGIN
+    nxt_pipe_val  <= rd_en & pipe_val (pipe_val 'HIGH DOWNTO 1);  
+    rd_val  <= pipe_val(0);
+  END PROCESS;
+  
+  wr_adr_proc : PROCESS (wr_adr, wr_en, wr_page, wr_sync)
+  BEGIN
+    nxt_wr_adr  <= wr_adr;    
+    nxt_wr_page <= wr_page;
+    rd_rdy      <= '0';
+    rd_sync     <= '0';   
+    IF wr_en='1' THEN
+      IF SIGNED(wr_adr) = -1 OR wr_sync='1' THEN
+        rd_rdy      <= '1';
+        rd_sync     <= wr_sync;
+        nxt_wr_page <= NOT wr_page;      
+        nxt_wr_adr  <= (OTHERS => '0');
+      ELSE
+        nxt_wr_adr <= STD_LOGIC_VECTOR(UNSIGNED(wr_adr) + 1);    
+      END IF;
+    END IF;
+    wr_adr_paged <= wr_page & bit_rev(wr_adr);
+  END PROCESS;
+  
+  -- combine real and imaginary to a single data word  
+  rd_proc : PROCESS (rd_dat, pipe_val) 
+  BEGIN
+    rd_re  <= rd_dat(rd_dat'HIGH DOWNTO rd_im'LENGTH);
+    rd_im  <= rd_dat(rd_im'RANGE);  
+    -- synthesis translate off    
+    IF pipe_val(0)='0' THEN
+      rd_re <= (OTHERS => '0');
+      rd_im <= (OTHERS => '0');
+    END IF;    
+    --synthesis translate on    
+  END PROCESS;   
+    
+  wr_dat <= wr_re & wr_im;
+  wr_en  <= wr_val;
+
+--  -- ram module
+--  ram : ENTITY common_lib.common_dpram
+--  GENERIC MAP (
+--    g_dat_w                => 2*g_dat_w,
+--    g_adr_w                => c_adr_w,
+--    g_nof_words            => c_nof_words    
+--  )
+--  PORT MAP (
+--    rd_dat                 => rd_dat,
+--    rd_adr                 => rd_adr_paged,
+--    rd_en                  => rd_en,
+--    wr_dat                 => wr_dat,
+--    wr_adr                 => wr_adr_paged,
+--    wr_en                  => wr_en,
+--    clk                    => clk,
+--    rst                    => rst
+--  );
+
+  ram : ENTITY common_lib.common_ram_r_w
+  GENERIC MAP (
+    g_ram        => c_ram
+  )
+  PORT MAP (
+    rst       => rst,
+    clk       => clk,
+    wr_en     => wr_en,
+    wr_adr    => wr_adr_paged,
+    wr_dat    => wr_dat,
+    rd_en     => rd_en,
+    rd_adr    => rd_adr_paged,
+    rd_dat    => rd_dat
+  );
+  
+END rtl;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_lfsr.vhd b/applications/lofar1/pft2/src/vhdl/pft_lfsr.vhd
index 63783fd6fb93b2b933f550f28313c4bc8dc19467..afcb2c4b9c54ed883ce8cb5c32aea6078ddeda49 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_lfsr.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_lfsr.vhd
@@ -1,3 +1,28 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
 LIBRARY IEEE;
 USE IEEE.std_logic_1164.ALL;
 
@@ -11,3 +36,57 @@ ENTITY pft_lfsr IS
   );
 END pft_lfsr;
 
+
+ARCHITECTURE rtl OF pft_lfsr IS
+  
+  -- uses preferred pair of pritive trinomials
+  -- x^41 + x^20 + 1  and x^41 + x^3 + 1  
+  -- see XAPP217
+  
+  CONSTANT c_max : NATURAL := 41;
+  CONSTANT c1    : NATURAL := 20;
+  CONSTANT c2    : NATURAL := 3;  
+    
+  SIGNAL s1      : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0);
+  SIGNAL nxt_s1  : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0);
+  
+  SIGNAL s2      : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0);
+  SIGNAL nxt_s2  : STD_LOGIC_VECTOR(c_max-1 DOWNTO 0);
+  
+  
+BEGIN
+  regs: PROCESS(rst,clk)
+  BEGIN
+    IF rst='1' THEN
+      s1 <= "01000101011101110101001011111000101100001";
+      s2 <= "11011001000101001011011001110101100101100";
+    ELSIF rising_edge(clk) THEN
+      s1 <= nxt_s1;      
+      s2 <= nxt_s2;      
+    END IF;
+  END PROCESS;
+  
+  out_bit1 <= s1(s1'HIGH); 
+  out_bit2 <= s2(s2'HIGH);      
+  
+  seed_proc: PROCESS(in_en,s1,s2)
+  BEGIN
+    nxt_s1 <= s1;    
+    nxt_s2 <= s2;    
+    IF in_en='1' THEN
+      -- shift      
+      nxt_s1(c_max-1 DOWNTO 1) <= s1(c_max-2 DOWNTO 0);      
+      nxt_s2(c_max-1 DOWNTO 1) <= s2(c_max-2 DOWNTO 0);      
+      
+      -- feedback 1
+      nxt_s1(0) <= s1(c_max-1);
+      nxt_s2(0) <= s2(c_max-1);
+      
+      -- feedback 2
+      nxt_s1(c1) <= s1(c_max-1) xor s1(c1-1);
+      nxt_s2(c2) <= s2(c_max-1) xor s2(c2-1);
+    END IF;
+  END PROCESS;
+
+end rtl;
+
diff --git a/applications/lofar1/pft2/src/vhdl/pft_pkg.vhd b/applications/lofar1/pft2/src/vhdl/pft_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..d6d92acaa5ee83e7eae38fa60e4369a7f88d56a2
--- /dev/null
+++ b/applications/lofar1/pft2/src/vhdl/pft_pkg.vhd
@@ -0,0 +1,50 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Copy of pft(pkg).vhd to avoid () in file name.
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+
+PACKAGE pft_pkg IS
+  CONSTANT c_pft_stage_dat_w : NATURAL := 20;
+
+  TYPE pft_mode_type IS (
+    PFT_MODE_BITREV,
+    PFT_MODE_COMPLEX,
+    PFT_MODE_REAL2
+  );
+  
+  TYPE pft_bf_type IS (
+    PFT_BF1,
+    PFT_BF2
+  );
+
+END pft_pkg;
+
+
+PACKAGE BODY pft_pkg IS
+END pft_pkg;
+
+
diff --git a/applications/lofar1/pft2/src/vhdl/pft_reverse.vhd b/applications/lofar1/pft2/src/vhdl/pft_reverse.vhd
index 5f42d6600a389dde3a1c90c63ca4177f89cd6d7b..43c1cc8348c149c76387265ee04af7770190a684 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_reverse.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_reverse.vhd
@@ -1,6 +1,31 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
 LIBRARY IEEE;
 USE IEEE.STD_LOGIC_1164.ALL;
-
+USE IEEE.NUMERIC_STD.ALL;
 
 ENTITY pft_reverse IS
   GENERIC (
@@ -26,3 +51,65 @@ ENTITY pft_reverse IS
     rst               : IN  STD_LOGIC
   );
 END pft_reverse;
+
+
+ARCHITECTURE rtl OF pft_reverse IS
+
+  SIGNAL i_rdaddr   : STD_LOGIC_VECTOR(rdaddr'RANGE);
+  SIGNAL nxt_rdaddr : STD_LOGIC_VECTOR(rdaddr'RANGE);
+  SIGNAL i_rden     : STD_LOGIC;
+  SIGNAL nxt_rden   : STD_LOGIC;
+  SIGNAL rdrdy      : STD_LOGIC;
+
+
+BEGIN
+
+  rdaddr    <= i_rdaddr;
+  rden      <= i_rden;
+  page_done <= rdrdy;
+
+  registers : PROCESS (rst, clk)
+  BEGIN
+    IF rst = '1' THEN
+      -- Output signals.
+      i_rdaddr <= (OTHERS => '0');
+      i_rden   <= '0';
+      -- Internal signals.
+    ELSIF rising_edge(clk) THEN
+      -- Output signals.
+      i_rdaddr <= nxt_rdaddr;
+      i_rden   <= nxt_rden;
+      -- Internal signals.
+    END IF;
+  END PROCESS;
+
+
+  read_enable_control : PROCESS (i_rden, page_rdy, rdrdy)
+  BEGIN
+    nxt_rden <= i_rden;
+    IF page_rdy = '1' THEN
+      nxt_rden <= '1';
+    ELSIF rdrdy = '1' THEN
+      nxt_rden <= '0';
+    END IF;
+  END PROCESS;
+
+
+  read_addr_control : PROCESS (i_rdaddr, i_rden)
+  BEGIN
+    rdrdy      <= '0';
+    nxt_rdaddr <= i_rdaddr;
+    IF UNSIGNED(i_rdaddr) >= g_fft_sz-1 THEN
+      nxt_rdaddr <= (OTHERS => '0');
+      rdrdy      <= '1';
+    ELSIF i_rden = '1' THEN
+      nxt_rdaddr <= STD_LOGIC_VECTOR(UNSIGNED(i_rdaddr) + 1);
+    END IF;
+  END PROCESS;
+
+
+  out_dat_re <= rddata_re WHEN rdval = '1' ELSE (OTHERS => '0');
+  out_dat_im <= rddata_im WHEN rdval = '1' ELSE (OTHERS => '0');
+  out_val    <= '1' WHEN rdval = '1' ELSE '0';
+  out_sync   <= '1' WHEN rdsync = '1' ELSE '0'; 
+END rtl;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_separate.vhd b/applications/lofar1/pft2/src/vhdl/pft_separate.vhd
index c3bd638faa3d6376f5fe0fb4687f110a74c88ec0..f1b6206b2d82a886c7ca0b980ad08d635687f37b 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_separate.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_separate.vhd
@@ -1,6 +1,31 @@
-LIBRARY IEEE;
-USE IEEE.STD_LOGIC_1164.ALL;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
 
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
 
 ENTITY pft_separate IS
   GENERIC (
@@ -26,3 +51,239 @@ ENTITY pft_separate IS
     rst               : IN  STD_LOGIC
   );
 END pft_separate;
+
+
+ARCHITECTURE rtl OF pft_separate IS
+
+  CONSTANT c_reg_delay     : NATURAL := 2;  
+  CONSTANT c_add_delay     : NATURAL := 2;
+  CONSTANT c_tot_delay     : NATURAL := c_reg_delay + c_add_delay;
+ 
+  TYPE data_dly_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(rddata_re'RANGE);
+
+  SIGNAL nxt_rden          : STD_LOGIC;
+  
+  SIGNAL cnt               : STD_LOGIC_VECTOR(rdaddr'HIGH DOWNTO 0);
+  SIGNAL nxt_cnt           : STD_LOGIC_VECTOR(cnt'RANGE);
+
+  SIGNAL rddata_re_dly     : data_dly_arr(0 TO c_reg_delay);
+  SIGNAL rddata_im_dly     : data_dly_arr(0 TO c_reg_delay);
+
+  SIGNAL rd_cnt            : STD_LOGIC_VECTOR(g_fft_sz_w-1 DOWNTO 0);
+  SIGNAL nxt_rd_cnt        : STD_LOGIC_VECTOR(rd_cnt'RANGE);
+  
+  SIGNAL page_rdy_dly      : STD_LOGIC_VECTOR( 0 TO c_tot_delay-1);
+  SIGNAL rdval_dly         : STD_LOGIC_VECTOR( 0 TO c_tot_delay-1);
+  SIGNAL rdsync_dly        : STD_LOGIC_VECTOR( 0 TO c_tot_delay+1);
+  SIGNAL nxt_rdsync_dly    : STD_LOGIC_VECTOR(rdsync_dly'RANGE);
+  SIGNAL rdsync_reg        : STD_LOGIC;
+  SIGNAL nxt_rdsync_reg    : STD_LOGIC;
+  
+  SIGNAL nxt_out_dat_re    : STD_LOGIC_VECTOR(out_dat_re'RANGE);
+  SIGNAL nxt_out_dat_im    : STD_LOGIC_VECTOR(out_dat_im'RANGE);
+  SIGNAL nxt_out_val       : STD_LOGIC;
+  SIGNAL nxt_out_sync      : STD_LOGIC;  
+
+  SIGNAL add_out           : STD_LOGIC_VECTOR(out_dat_re'RANGE);
+  SIGNAL add0              : STD_LOGIC_VECTOR(rddata_re'RANGE);
+  SIGNAL add1              : STD_LOGIC_VECTOR(rddata_re'RANGE);
+  SIGNAL nxt_add0          : STD_LOGIC_VECTOR(rddata_re'RANGE);
+  SIGNAL nxt_add1          : STD_LOGIC_VECTOR(rddata_re'RANGE);
+  SIGNAL sub_out           : STD_LOGIC_VECTOR(out_dat_im'RANGE);
+  SIGNAL sub0              : STD_LOGIC_VECTOR(rddata_re'RANGE);
+  SIGNAL sub1              : STD_LOGIC_VECTOR(rddata_re'RANGE);
+  SIGNAL nxt_sub0          : STD_LOGIC_VECTOR(rddata_re'RANGE);
+  SIGNAL nxt_sub1          : STD_LOGIC_VECTOR(rddata_re'RANGE);
+
+BEGIN
+
+
+  registers : PROCESS (rst, clk)
+  BEGIN
+    IF rst = '1' THEN
+      -- Output signals.
+      out_dat_re    <= (OTHERS => '0');
+      out_dat_im    <= (OTHERS => '0');
+      out_val       <= '0';
+      out_sync      <= '0';      
+      rden          <= '0';
+      -- Internal signals.
+      cnt           <= STD_LOGIC_VECTOR(TO_SIGNED(-2,g_fft_sz_w));
+      rd_cnt        <= (OTHERS => '0');
+      page_rdy_dly  <= (OTHERS => '0');
+      rddata_re_dly <= (OTHERS => (OTHERS => '0'));
+      rddata_im_dly <= (OTHERS => (OTHERS => '0'));
+      rdval_dly     <= (OTHERS => '0');
+      rdsync_dly    <= (OTHERS => '0');      
+      rdsync_reg    <= '0';
+      add0          <= (OTHERS => '0');
+      add1          <= (OTHERS => '0');
+      sub0          <= (OTHERS => '0');
+      sub1          <= (OTHERS => '0');
+    ELSIF rising_edge(clk) THEN
+      -- Output signals.
+      out_dat_re    <= nxt_out_dat_re;
+      out_dat_im    <= nxt_out_dat_im;
+      out_val       <= nxt_out_val;
+      out_sync      <= nxt_out_sync;
+      rden          <= nxt_rden;
+      -- Internal signals.
+      cnt           <= nxt_cnt;
+      rd_cnt        <= nxt_rd_cnt;
+      page_rdy_dly  <= page_rdy & page_rdy_dly(0 TO page_rdy_dly'HIGH -1);
+      rddata_re_dly <= rddata_re & rddata_re_dly(0 TO rddata_re_dly'HIGH-1);
+      rddata_im_dly <= rddata_im & rddata_im_dly(0 TO rddata_im_dly'HIGH-1);
+      rdval_dly     <= rdval  & rdval_dly(0 TO rdval_dly'HIGH-1);
+      rdsync_dly    <= nxt_rdsync_dly;
+      rdsync_reg    <= nxt_rdsync_reg;
+      add0          <= nxt_add0;
+      add1          <= nxt_add1;
+      sub0          <= nxt_sub0;
+      sub1          <= nxt_sub1;
+    END IF;
+  END PROCESS;
+  
+  sync_proc : PROCESS(page_rdy, rdsync, rdsync_dly, rdsync_reg)
+  BEGIN
+    nxt_rdsync_reg <= rdsync_reg;
+    nxt_rdsync_dly <= '0' & rdsync_dly(0 TO rdsync_dly'HIGH -1);
+    IF page_rdy='1' THEN
+      nxt_rdsync_reg <= rdsync;  
+      nxt_rdsync_dly <= ( 0 => rdsync_reg, OTHERS => '0');
+    END IF;
+  END PROCESS;
+
+  cnt_control : PROCESS (cnt, page_rdy)
+  BEGIN
+    nxt_rden <= '0';
+    nxt_cnt <= cnt;
+    IF page_rdy='1' THEN
+      nxt_cnt      <= (OTHERS => '1');
+      nxt_rden <= '1';      
+    ELSIF SIGNED(cnt)/=-2 THEN
+      nxt_cnt <= STD_LOGIC_VECTOR(UNSIGNED(cnt) + 1);
+      nxt_rden <= '1';      
+    END IF;
+  END PROCESS;
+
+
+  addr_gen : PROCESS (cnt)
+  BEGIN
+    rdaddr <= (OTHERS => '0');
+    IF cnt(0) = '0' THEN
+      rdaddr <= '0' & cnt(cnt'HIGH DOWNTO 1);
+    ELSE
+      rdaddr <= '1' & STD_LOGIC_VECTOR(NOT(UNSIGNED(cnt(cnt'HIGH DOWNTO 1))));
+    END IF;
+  END PROCESS;
+
+  rd_counter : PROCESS (rd_cnt, rdval_dly, page_rdy_dly)
+  BEGIN
+    nxt_rd_cnt <= rd_cnt;
+    IF page_rdy_dly(3) = '1' THEN
+      nxt_rd_cnt <= (OTHERS => '0');      
+    ELSIF rdval_dly(1) = '1' THEN
+      nxt_rd_cnt <= STD_LOGIC_VECTOR(UNSIGNED(rd_cnt) + 1);
+    END IF;    
+  END PROCESS;
+
+  adder_inputs : PROCESS (rddata_re_dly, rddata_im_dly, rd_cnt)
+  BEGIN
+    IF UNSIGNED(rd_cnt)=0 THEN
+      nxt_add0 <= rddata_re_dly(0);
+      nxt_add1 <= rddata_re_dly(0);
+      nxt_sub0 <= rddata_re_dly(1);
+      nxt_sub1 <= STD_LOGIC_VECTOR(-SIGNED(rddata_re_dly(1)));
+    ELSIF UNSIGNED(rd_cnt)=1 THEN
+      nxt_add0 <= rddata_im_dly(1);
+      nxt_add1 <= rddata_im_dly(1);
+      nxt_sub0 <= rddata_im_dly(2); 
+      nxt_sub1 <= STD_LOGIC_VECTOR(-SIGNED(rddata_im_dly(2)));
+    ELSIF rd_cnt(0) = '0' THEN    
+      nxt_add0 <= rddata_re_dly(0);
+      nxt_add1 <= rddata_re_dly(1);    
+      nxt_sub0 <= rddata_im_dly(0);
+      nxt_sub1 <= rddata_im_dly(1);
+    ELSE
+      nxt_add0 <= rddata_im_dly(2);
+      nxt_add1 <= rddata_im_dly(1);
+      nxt_sub0 <= rddata_re_dly(2);
+      nxt_sub1 <= rddata_re_dly(1);
+    END IF;
+  END PROCESS;
+
+
+  nxt_out_dat_re <= add_out;
+  nxt_out_dat_im <= sub_out;
+  nxt_out_val    <= rdval_dly(rdval_dly'HIGH);
+  nxt_out_sync   <= rdsync_dly(rdsync_dly'HIGH);  
+
+--  Intel Altera lmp_add_sub carry in:
+--  ADD: out = a + b + cin      => cin = '0' to have out = a + b
+--  SUB: out = a - b + cin - 1  => cin = '1' to have out = a - b
+
+--  add : ENTITY common_lib.common_addsub
+--  GENERIC MAP (
+--    g_in_a_w   => add0'LENGTH,
+--    g_in_b_w   => add1'LENGTH,
+--    g_out_c_w  => add_out'LENGTH,    
+--    g_pipeline => c_add_delay-1,
+--    g_add_sub  => "ADD"
+--  )
+--  PORT MAP (
+--    in_a       => add0,
+--    in_b       => add1,
+--    in_cry     => '0',
+--    out_c      => add_out,
+--    clk        => clk
+--  );
+
+  add : ENTITY common_lib.common_add_sub
+  GENERIC MAP (
+    g_direction       => "ADD",
+    g_representation  => "SIGNED",
+    g_pipeline_input  => 0,               -- 0 or 1
+    g_pipeline_output => c_add_delay-1,  -- >= 0
+    g_in_dat_w        => g_rd_dat_w,
+    g_out_dat_w       => g_out_dat_w          -- only support g_out_dat_w=g_in_dat_w and g_out_dat_w=g_in_dat_w+1
+  )
+  PORT MAP (
+    clk      => clk,
+    in_a     => add0,
+    in_b     => add1,
+    result   => add_out
+  );
+  
+--  sub : ENTITY common_lib.common_addsub
+--  GENERIC MAP (
+--    g_in_a_w   => sub0'LENGTH,
+--    g_in_b_w   => sub1'LENGTH,
+--    g_out_c_w  => sub_out'LENGTH,    
+--    g_pipeline => c_add_delay-1,
+--    g_add_sub  => "SUB"
+--  )
+--  PORT MAP (
+--    in_a       => sub0,
+--    in_b       => sub1,
+--    in_cry     => '1',
+--    out_c      => sub_out,
+--    clk        => clk
+--  );
+
+  sub : ENTITY common_lib.common_add_sub
+  GENERIC MAP (
+    g_direction       => "SUB",
+    g_representation  => "SIGNED",
+    g_pipeline_input  => 0,               -- 0 or 1
+    g_pipeline_output => c_add_delay-1,  -- >= 0
+    g_in_dat_w        => g_rd_dat_w,
+    g_out_dat_w       => g_out_dat_w          -- only support g_out_dat_w=g_in_dat_w and g_out_dat_w=g_in_dat_w+1
+  )
+  PORT MAP (
+    clk      => clk,
+    in_a     => sub0,
+    in_b     => sub1,
+    result   => sub_out
+  );
+
+END rtl;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_stage.vhd b/applications/lofar1/pft2/src/vhdl/pft_stage.vhd
index 558c51bc5ef55eaac5aed20be3389dfd9162d212..14d769a3c4a4169c8b4895478fe2622939328abe 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_stage.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_stage.vhd
@@ -1,6 +1,32 @@
-LIBRARY IEEE;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
+LIBRARY IEEE, common_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
 
+
 ENTITY pft_stage IS
   GENERIC (
     g_index          : NATURAL;
@@ -19,4 +45,172 @@ ENTITY pft_stage IS
     clk              : IN  STD_LOGIC;
     rst              : IN  STD_LOGIC
  );
-END pft_stage;  
\ No newline at end of file
+END pft_stage;  
+
+
+ARCHITECTURE str OF pft_stage IS
+  
+  CONSTANT c_round_pipeline_in  : NATURAL := 1;
+  CONSTANT c_round_pipeline_out : NATURAL := 1;
+  CONSTANT c_round_pipeline     : NATURAL := c_round_pipeline_in + c_round_pipeline_out;
+  
+  CONSTANT c_bf1_out_w   : NATURAL := g_in_dat_w + 1;
+  CONSTANT c_bf2_out_w   : NATURAL := g_in_dat_w + 2;
+    
+  SIGNAL bf1_re    : STD_LOGIC_VECTOR(c_bf1_out_w-1 DOWNTO 0);
+  SIGNAL bf1_im    : STD_LOGIC_VECTOR(c_bf1_out_w-1 DOWNTO 0);
+  SIGNAL bf1_val   : STD_LOGIC;  
+  SIGNAL bf1_sync  : STD_LOGIC;  
+  
+  SIGNAL bf2_re    : STD_LOGIC_VECTOR(c_bf2_out_w-1 DOWNTO 0);
+  SIGNAL bf2_im    : STD_LOGIC_VECTOR(c_bf2_out_w-1 DOWNTO 0);
+  SIGNAL bf2_val   : STD_LOGIC;
+  SIGNAL bf2_sync  : STD_LOGIC;
+  
+BEGIN
+
+  gen_middle: IF g_index>0 GENERATE
+      
+    bf1 : ENTITY work.pft_bf
+    GENERIC MAP (
+      g_index          => 2*g_index+1,
+      g_in_dat_w       => g_in_dat_w,      
+      g_out_dat_w      => c_bf1_out_w,
+      g_bf_name        => "bf1"
+    )
+    PORT MAP (
+      in_re            => in_re,
+      in_im            => in_im,
+      in_val           => in_val,
+      in_sync          => in_sync,      
+      out_re           => bf1_re,
+      out_im           => bf1_im,
+      out_val          => bf1_val,
+      out_sync         => bf1_sync,
+      clk              => clk,
+      rst              => rst
+    );
+  
+    bf2 : ENTITY work.pft_bf
+    GENERIC MAP (
+      g_index          => 2*g_index,
+      g_in_dat_w       => c_bf1_out_w,      
+      g_out_dat_w      => c_bf2_out_w,
+      g_bf_name        => "bf2"
+    )
+    PORT MAP (
+      in_re            => bf1_re,
+      in_im            => bf1_im,
+      in_val           => bf1_val,
+      in_sync          => bf1_sync,
+      out_re           => bf2_re,
+      out_im           => bf2_im,
+      out_val          => bf2_val,
+      out_sync         => bf2_sync,      
+      clk              => clk,
+      rst              => rst
+    );
+    
+    tmult : ENTITY work.pft_tmult
+    GENERIC MAP (
+      g_in_dat_w     => c_bf2_out_w,
+      g_out_dat_w    => g_out_dat_w, 
+      g_index        => g_index
+    )                
+    PORT MAP (       
+      in_re          => bf2_re,
+      in_im          => bf2_im,
+      in_val         => bf2_val,
+      in_sync        => bf2_sync,      
+      out_re         => out_re,
+      out_im         => out_im,
+      out_val        => out_val,
+      out_sync       => out_sync,
+      clk            => clk,
+      rst            => rst
+    );
+  END GENERATE;
+  
+  gen_last: IF g_index=0 GENERATE  
+  
+    SIGNAL reg_val  : STD_LOGIC;
+    SIGNAL reg_sync : STD_LOGIC; 
+
+  BEGIN
+
+    bf1_fw : ENTITY work.pft_bf_fw
+    GENERIC MAP (
+      g_index          => 2*g_index+1,
+      g_in_dat_w       => g_in_dat_w,      
+      g_out_dat_w      => c_bf1_out_w,
+      g_bf_name        => "bf1"
+    )
+    PORT MAP (
+      in_re            => in_re,
+      in_im            => in_im,
+      in_val           => in_val,
+      in_sync          => in_sync,      
+      out_re           => bf1_re,
+      out_im           => bf1_im,
+      out_val          => bf1_val,
+      out_sync         => bf1_sync,
+      clk              => clk,
+      rst              => rst
+    );
+  
+    bf2_fw : ENTITY work.pft_bf_fw
+    GENERIC MAP (
+      g_index          => 2*g_index,
+      g_in_dat_w       => c_bf1_out_w,      
+      g_out_dat_w      => c_bf2_out_w,
+      g_bf_name        => "bf2"
+    )
+    PORT MAP (
+      in_re            => bf1_re,
+      in_im            => bf1_im,
+      in_val           => bf1_val,
+      in_sync          => bf1_sync,
+      out_re           => bf2_re,
+      out_im           => bf2_im,
+      out_val          => bf2_val,
+      out_sync         => bf2_sync,      
+      clk              => clk,
+      rst              => rst
+    );
+  
+    u_rnd : ENTITY common_lib.common_complex_round
+    GENERIC MAP (
+      g_representation  => "SIGNED",
+      g_round           => TRUE,
+      g_round_clip      => FALSE,
+      g_pipeline_input  => c_round_pipeline_in,
+      g_pipeline_output => c_round_pipeline_out,
+      g_in_dat_w        => c_bf2_out_w,
+      g_out_dat_w       => g_out_dat_w
+    )                
+    PORT MAP (       
+      in_re          => bf2_re,
+      in_im          => bf2_im,
+      out_re         => out_re,
+      out_im         => out_im,
+      clk            => clk
+    );
+    
+    p_regs: PROCESS(clk,rst)
+    BEGIN
+      IF rst='1' THEN
+        reg_val  <= '0';
+        reg_sync <= '0';
+        out_val  <= '0';
+        out_sync <= '0';
+      ELSIF rising_edge(clk) THEN
+        out_val  <= reg_val;        
+        out_sync <= reg_sync;        
+        reg_val  <= bf2_val;
+        reg_sync <= bf2_sync;        
+      END IF;
+    END PROCESS;   
+    
+  END GENERATE;
+  
+END str;     
diff --git a/applications/lofar1/pft2/src/vhdl/pft_switch.vhd b/applications/lofar1/pft2/src/vhdl/pft_switch.vhd
index f8be448d483fd5fa341317147413748d742b14c0..ef05f46339693ec4d35fa08c39f3e24eafea95fa 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_switch.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_switch.vhd
@@ -1,5 +1,32 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
+
 LIBRARY IEEE;
-USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
 
 ENTITY pft_switch IS
   GENERIC (
@@ -21,3 +48,86 @@ ENTITY pft_switch IS
     rst               : IN  STD_LOGIC
   );
 END pft_switch;
+
+
+ARCHITECTURE rtl OF pft_switch IS
+
+SIGNAL cnt         : STD_LOGIC_VECTOR(g_fft_sz_w DOWNTO 0);
+SIGNAL nxt_cnt     : STD_LOGIC_VECTOR(cnt'RANGE);
+
+SIGNAL lfsr_bit1   : STD_LOGIC;
+SIGNAL lfsr_bit2   : STD_LOGIC;
+SIGNAL lfsr_en     : STD_LOGIC;
+
+SIGNAL nxt_out_val : STD_LOGIC;
+SIGNAL nxt_out_sync : STD_LOGIC;
+SIGNAL nxt_out_re   : STD_LOGIC_VECTOR(in_re'RANGE);
+SIGNAL nxt_out_im   : STD_LOGIC_VECTOR(in_im'RANGE);
+
+BEGIN
+
+  registers : PROCESS (rst, clk)
+  BEGIN
+    IF rst = '1' THEN
+      cnt      <= (OTHERS => '0');      
+      out_val  <= '0';
+      out_sync <= '0';      
+      out_re   <= (OTHERS => '0');
+      out_im   <= (OTHERS => '0');      
+    ELSIF rising_edge(clk) THEN
+      cnt      <= nxt_cnt;      
+      out_val  <= nxt_out_val;
+      out_re   <= nxt_out_re;
+      out_im   <= nxt_out_im;
+      out_sync <= nxt_out_sync;
+    END IF;
+  END PROCESS;
+
+  counter: PROCESS(cnt, in_val, in_sync)
+  BEGIN
+    nxt_cnt <= cnt;        
+    IF in_sync='1' THEN
+      nxt_cnt <= (OTHERS => '0');
+    ELSIF in_val='1' THEN
+      nxt_cnt <= STD_LOGIC_VECTOR(UNSIGNED(cnt)+1);
+    END IF;
+  END PROCESS;
+  
+  lfsr_ctrl: PROCESS(cnt,in_val)
+  BEGIN
+    if SIGNED(cnt)=-1 AND in_val='1' THEN
+      lfsr_en <= '1';
+    ELSE
+      lfsr_en <= '0';
+    END IF;
+  END PROCESS;
+
+  proc: PROCESS(cnt, lfsr_bit1, lfsr_bit2, in_im, in_re, in_val, in_sync, switch_en)
+  BEGIN
+    nxt_out_val  <= in_val;
+    nxt_out_sync <= in_sync AND in_val;
+    
+    IF lfsr_bit1=cnt(cnt'HIGH) AND switch_en='1' THEN
+      nxt_out_re <= STD_LOGIC_VECTOR(-SIGNED(in_re));
+    ELSE
+      nxt_out_re <= in_re;
+    END IF;
+    
+    IF lfsr_bit2=cnt(cnt'HIGH) AND switch_en='1' THEN
+      nxt_out_im <= STD_LOGIC_VECTOR(-SIGNED(in_im));
+    ELSE
+      nxt_out_im <= in_im;
+    END IF;    
+  END PROCESS;
+    
+  lfsr: ENTITY work.pft_lfsr
+  PORT MAP (
+    clk      => clk,
+    rst      => rst,
+    in_en    => lfsr_en,
+    out_bit1 => lfsr_bit1,
+    out_bit2 => lfsr_bit2
+  ); 
+    
+
+END rtl;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_tmult.vhd b/applications/lofar1/pft2/src/vhdl/pft_tmult.vhd
index dea2aba47e94459a501dbd45a1e6438ff68b088d..313619ba4908798189d8b5618e04dd6764842477 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_tmult.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_tmult.vhd
@@ -1,6 +1,36 @@
-LIBRARY ieee;
-USE IEEE.std_logic_1164.ALL;
-USE IEEE.numeric_std.ALL;
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+
+LIBRARY common_mult_lib;
+LIBRARY common_lib;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
 
 
 ENTITY pft_tmult IS
@@ -24,3 +54,175 @@ ENTITY pft_tmult IS
 END pft_tmult;
 
 
+ARCHITECTURE rtl OF pft_tmult IS
+
+  CONSTANT c_nof_twids      : NATURAL := 16 * 2**(2*(g_index-1));
+  CONSTANT c_adr_w          : NATURAL := 2 + 2*g_index;
+  
+  CONSTANT c_mult_in_w      : NATURAL := 18;
+  CONSTANT c_coeff_w        : NATURAL := 16;
+  CONSTANT c_mult_out_w     : NATURAL := c_mult_in_w + c_coeff_w-1;    
+  
+  CONSTANT c_twid_rom       : t_c_mem := (latency  => 2,
+                                          adr_w    => c_adr_w,
+                                          dat_w    => 2*c_coeff_w,   -- complex
+                                          nof_dat  => 3*c_nof_twids/4,  -- <= 2**g_addr_w
+                                          init_sl  => '0');
+  
+  CONSTANT c_twid_file      : STRING  := 
+    "data/twiddle_" & NATURAL'IMAGE(c_coeff_w) 
+    & "_" & NATURAL'IMAGE(g_index) & ".hex";    -- Quartus .hex extension, replaced by .bin in common_rom works for XST
+  --CONSTANT c_twid_file      : STRING  := 
+  --  "../../../../../pft2/src/data/twiddle_" & NATURAL'IMAGE(c_coeff_w) 
+  --  & "_" & NATURAL'IMAGE(g_index) & ".bin";    -- Synplify fails on file extension change to .bin in common_rom and requires extra ../
+  
+  CONSTANT c_read_pipeline      : NATURAL := 1;
+  CONSTANT c_mult_pipeline_input   : NATURAL := 1;     -- 0 or 1
+  CONSTANT c_mult_pipeline_product : NATURAL := 0;     -- 0 or 1
+  CONSTANT c_mult_pipeline_adder   : NATURAL := 1;     -- 0 or 1
+  CONSTANT c_mult_pipeline_output  : NATURAL := 1;     -- >= 0
+  CONSTANT c_mult_pipeline         : NATURAL := c_mult_pipeline_input + c_mult_pipeline_product + c_mult_pipeline_adder + c_mult_pipeline_output;  -- = 3
+  CONSTANT c_round_pipeline_in  : NATURAL := 1;
+  CONSTANT c_round_pipeline_out : NATURAL := 1;
+  CONSTANT c_round_pipeline     : NATURAL := c_round_pipeline_in + c_round_pipeline_out;
+  CONSTANT c_pipeline           : NATURAL := c_round_pipeline + c_mult_pipeline + c_round_pipeline;  
+  
+  SIGNAL reg_val            : STD_LOGIC_VECTOR(c_pipeline-1 DOWNTO 0);
+  SIGNAL nxt_reg_val        : STD_LOGIC_VECTOR(reg_val'RANGE);  
+  SIGNAL reg_sync           : STD_LOGIC_VECTOR(c_pipeline-1 DOWNTO 0);  
+  
+  SIGNAL nxt_reg_sync       : STD_LOGIC_VECTOR(reg_sync'RANGE); 
+  
+  SIGNAL adr                : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);  
+  SIGNAL nxt_adr            : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);  
+  
+  SIGNAL cnt                : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0);
+  SIGNAL nxt_cnt            : STD_LOGIC_VECTOR(cnt'RANGE);
+
+  SIGNAL mult_in_re         : STD_LOGIC_VECTOR(c_mult_in_w-1 DOWNTO 0);
+  SIGNAL mult_in_im         : STD_LOGIC_VECTOR(c_mult_in_w-1 DOWNTO 0);
+    
+  SIGNAL mult_out_re        : STD_LOGIC_VECTOR(c_mult_out_w-1 DOWNTO 0);
+  SIGNAL mult_out_im        : STD_LOGIC_VECTOR(c_mult_out_w-1 DOWNTO 0);
+  
+  SIGNAL coeff_dat          : STD_LOGIC_VECTOR(2*c_coeff_w-1 DOWNTO 0);
+  SIGNAL coeff_re           : STD_LOGIC_VECTOR(c_coeff_w-1 DOWNTO 0);
+  SIGNAL coeff_im           : STD_LOGIC_VECTOR(c_coeff_w-1 DOWNTO 0);
+  
+BEGIN
+
+  p_regs : PROCESS (clk, rst)
+  BEGIN
+    IF rst = '1' THEN
+      reg_val     <= (OTHERS => '0');
+      reg_sync    <= (OTHERS => '0');      
+      cnt         <= (OTHERS => '0');
+      adr         <= (OTHERS => '0');
+      coeff_re    <= (OTHERS => '0');
+      coeff_im    <= (OTHERS => '0');      
+    ELSIF RISING_EDGE(clk) THEN
+      reg_val     <= nxt_reg_val;
+      reg_sync    <= nxt_reg_sync;
+      cnt         <= nxt_cnt;
+      adr         <= nxt_adr;      
+      coeff_re    <= coeff_dat(coeff_re'RANGE);  
+      coeff_im    <= coeff_dat(coeff_dat'HIGH DOWNTO coeff_re'LENGTH);  
+    END IF;
+  END PROCESS;
+  
+  p_cnt : PROCESS (cnt, in_val, in_sync)
+  BEGIN
+    nxt_cnt <= cnt;
+    IF in_sync = '1' THEN
+      nxt_cnt <= (OTHERS => '0');
+    ELSIF in_val = '1' THEN
+      nxt_cnt <= STD_LOGIC_VECTOR(UNSIGNED(cnt) + 1);
+    END IF;
+  END PROCESS;
+  
+  p_adr : PROCESS (adr, cnt, reg_sync)
+  BEGIN
+    nxt_adr <= adr;
+    IF UNSIGNED(adr)=3*c_nof_twids/4-1 OR reg_sync(reg_sync'HIGH)='1' THEN
+      nxt_adr <= (OTHERS => '0');
+    ELSIF UNSIGNED(adr) > 0 OR UNSIGNED(cnt) = c_nof_twids/4-1 THEN
+      nxt_adr <= STD_LOGIC_VECTOR(UNSIGNED(adr) + 1);
+    END IF;
+  END PROCESS;
+  
+  nxt_reg_val   <= in_val  & reg_val(reg_val'HIGH  DOWNTO 1);  
+  nxt_reg_sync  <= in_sync & reg_sync(reg_sync'HIGH DOWNTO 1);        
+  out_val       <= reg_val(0);    
+  out_sync      <= reg_sync(0);      
+
+  u_coeff : ENTITY common_lib.common_rom  
+  GENERIC MAP (
+    g_ram        => c_twid_rom,
+    g_init_file  => c_twid_file    
+  )
+  PORT MAP (
+    rst          => rst,
+    clk          => clk,
+    rd_adr       => adr,
+    rd_dat       => coeff_dat
+  );
+  
+  u_rnd1 : ENTITY common_lib.common_complex_round
+  GENERIC MAP (
+    g_representation  => "SIGNED",
+    g_round           => TRUE,
+    g_round_clip      => FALSE,
+    g_pipeline_input  => c_round_pipeline_in,
+    g_pipeline_output => c_round_pipeline_out,
+    g_in_dat_w        => g_in_dat_w,
+    g_out_dat_w       => c_mult_in_w
+  )                
+  PORT MAP (       
+    in_re          => in_re,
+    in_im          => in_im,
+    out_re         => mult_in_re,
+    out_im         => mult_in_im,
+    clk            => clk
+  );
+        
+  u_cmult : ENTITY common_mult_lib.common_complex_mult
+  GENERIC MAP (
+    g_variant     => "IP",
+    g_in_a_w      => c_mult_in_w,
+    g_in_b_w      => c_coeff_w,
+    g_out_p_w     => c_mult_out_w, 
+    g_conjugate_b => FALSE,
+    g_pipeline_input   => c_mult_pipeline_input,     -- 0 or 1
+    g_pipeline_product => c_mult_pipeline_product,   -- 0 or 1
+    g_pipeline_adder   => c_mult_pipeline_adder,     -- 0 or 1
+    g_pipeline_output  => c_mult_pipeline_output     -- >= 0
+  )
+  PORT MAP (       
+    in_ar         => mult_in_re,
+    in_ai         => mult_in_im,
+    in_br         => coeff_re,
+    in_bi         => coeff_im,
+    out_pr        => mult_out_re,
+    out_pi        => mult_out_im,
+    clk           => clk
+  );
+  
+  u_rnd2 : ENTITY common_lib.common_complex_round
+  GENERIC MAP (
+    g_representation  => "SIGNED",
+    g_round           => TRUE,
+    g_round_clip      => FALSE,
+    g_pipeline_input  => c_round_pipeline_in,
+    g_pipeline_output => c_round_pipeline_out,
+    g_in_dat_w        => c_mult_out_w,      
+    g_out_dat_w       => g_out_dat_w
+  )                
+  PORT MAP (       
+    in_re          => mult_out_re,
+    in_im          => mult_out_im,
+    out_re         => out_re,
+    out_im         => out_im,
+    clk            => clk
+  );                
+  
+END rtl;
diff --git a/applications/lofar1/pft2/src/vhdl/pft_unswitch.vhd b/applications/lofar1/pft2/src/vhdl/pft_unswitch.vhd
index ded20e91067be5adee421b8d9e665198cbcd2df6..f1aff4542c88de4f86d365eb734a701ac16eea8d 100644
--- a/applications/lofar1/pft2/src/vhdl/pft_unswitch.vhd
+++ b/applications/lofar1/pft2/src/vhdl/pft_unswitch.vhd
@@ -1,5 +1,32 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2021
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+--
+-- Author: E. Kooistra, original 2011 by W. Lubberhuizen / W. Poeisz
+-- Purpose: Polyphase FIR filter
+-- Description: Ported from LOFAR1, see readme_lofar1.txt
+-- Remark: Put entity and architecture in same file without () in file name.
+
 LIBRARY IEEE;
 USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+
 
 ENTITY pft_unswitch IS
   GENERIC (
@@ -21,3 +48,83 @@ ENTITY pft_unswitch IS
     rst               : IN STD_LOGIC   
   );
 END pft_unswitch;
+
+
+ARCHITECTURE rtl OF pft_unswitch IS
+
+SIGNAL cnt          : STD_LOGIC_VECTOR(g_fft_sz_w DOWNTO 0);
+SIGNAL nxt_cnt      : STD_LOGIC_VECTOR(cnt'RANGE);
+
+SIGNAL lfsr_bit1    : STD_LOGIC;
+SIGNAL lfsr_bit2    : STD_LOGIC;
+
+SIGNAL lfsr_en      : STD_LOGIC;
+
+SIGNAL nxt_out_val  : STD_LOGIC;
+SIGNAL nxt_out_sync : STD_LOGIC;
+SIGNAL nxt_out_re   : STD_LOGIC_VECTOR(in_re'RANGE);
+SIGNAL nxt_out_im   : STD_LOGIC_VECTOR(in_im'RANGE);
+
+BEGIN
+
+  registers : PROCESS (rst, clk)
+  BEGIN
+    IF rst = '1' THEN
+      cnt      <= (OTHERS => '0');      
+      out_val  <= '0';
+      out_sync <= '0';      
+      out_re   <= (OTHERS => '0');
+      out_im   <= (OTHERS => '0');      
+    ELSIF rising_edge(clk) THEN
+      cnt      <= nxt_cnt;      
+      out_val  <= nxt_out_val;
+      out_sync <= nxt_out_sync;
+      out_re   <= nxt_out_re;
+      out_im   <= nxt_out_im;
+    END IF;
+  END PROCESS;
+
+  counter: PROCESS(cnt, in_val, in_sync)
+  BEGIN
+    nxt_cnt <= cnt;        
+    IF in_sync='1' THEN
+      nxt_cnt <= (OTHERS => '0');
+    ELSIF in_val='1' THEN
+      nxt_cnt <= STD_LOGIC_VECTOR(UNSIGNED(cnt)+1);
+    END IF;
+  END PROCESS;
+  
+  lfsr_ctrl: PROCESS(cnt,in_val)
+  BEGIN
+    if SIGNED(cnt)=-1 AND in_val='1' THEN
+      lfsr_en <= '1';
+    ELSE
+      lfsr_en <= '0';
+    END IF;
+  END PROCESS;
+
+  proc: PROCESS(in_re, in_im, in_val, in_sync, cnt, lfsr_bit1, lfsr_bit2, switch_en)
+  BEGIN
+    nxt_out_val  <= in_val;
+    nxt_out_sync <= in_sync AND in_val;    
+    nxt_out_re   <= in_re;        
+    nxt_out_im   <= in_im;    
+    IF    ((cnt(0)='0' AND cnt(cnt'HIGH)=lfsr_bit1) 
+       OR (cnt(0)='1' AND cnt(cnt'HIGH)=lfsr_bit2)) AND (switch_en='1') THEN
+        nxt_out_re <= STD_LOGIC_VECTOR(-SIGNED(in_re));
+        nxt_out_im <= STD_LOGIC_VECTOR(-SIGNED(in_im));
+    END IF;
+  END PROCESS;
+    
+  lfsr: ENTITY work.pft_lfsr
+  PORT MAP (
+    clk      => clk,
+    rst      => rst,
+    in_en    => lfsr_en,
+    out_bit1 => lfsr_bit1,
+    out_bit2 => lfsr_bit2
+  ); 
+    
+
+END rtl;
+
diff --git a/applications/lofar1/readme_lofar1.txt b/applications/lofar1/readme_lofar1.txt
index 64324e75cfc400b87c2aa9d802f1f1b52ca35611..31e53f11d8ca8602e072b6868f41c96f94717831 100644
--- a/applications/lofar1/readme_lofar1.txt
+++ b/applications/lofar1/readme_lofar1.txt
@@ -20,7 +20,9 @@
 --
 -- Author: E. Kooistra
 
-This readme describes how the PFB (= pfs + pft2) code of LOFAR1/RSP was ported to git for LOFAR2
+This readme describes how the PFB (= pfs + pft2) code of LOFAR1 on RSP that
+was created in 2011 by W. Lubberhuizen / W. Poiesz, was ported to git for
+LOFAR2/SDP on UniBoard2 in 2021 by E. Kooistra.
 
 Contents
 1) Comparison of LOFAR1 and APERTIF polyphase filterbank (PFB)
@@ -29,6 +31,7 @@ Contents
   b) pft2
   c) Simulating tb/vhdl/tb_pft2.vhd
 3) Create pfb2_unit.vhd that can replace wpfb_unit_dev.vhd
+4) Remove () from filenames
 
 
 References:
@@ -59,7 +62,7 @@ a) pfs
   * src/vhdl/
     - pfs_coefsbuf(str).vhd :
       . use c_coefs_rom : t_c_mem for common_rom from common_lib.
-      . use g_init_file => "data/pfs_coefsbuf_1024.hex"
+      . use g_init_file => "data/pfs_coefsbuf_1024.hex" = Coeffs16384Kaiser-quant.dat
     - pfs_filter(rtl).vhd : use ported common_mult_add.vhd from common_mult_lib
   * tb/vhdl/tb_pfs.vhd : ==> simulates OK
     . added usage comment
@@ -99,5 +102,10 @@ c) Simulating tb/vhdl/tb_pft2.vhd
   * pfb2_unit.vhd = multiple instances of pfb2 + sst, similar as wpfb_unit_dev.vhd for wideband factor wb = 1.
 
 
-
+4) Remove () from filenames
+  * The () in the files names cause the 'mk' command in Modelsim to fail, 'mk compile' can
+    handle () in file names, but 'mk' is also needed for efficient compilation.
+  * Put entity and architecture in same file without () in file name.
+  * Use _pkg instead of (pkg) in package file name to avoid () in file name.
+  * Keep only the actually used files in the hdllib.cfg