Skip to content
Snippets Groups Projects

Clarified flipped order of FIR coefficients in PFB.

Files

+ 48
1
@@ -83,6 +83,53 @@
@@ -83,6 +83,53 @@
% filterbank is defined by the FFT size (tb.subband_fft_size). The block
% filterbank is defined by the FFT size (tb.subband_fft_size). The block
% size after the subband filterbank is defined by the number of subbands
% size after the subband filterbank is defined by the number of subbands
% (tb.nof_subbands).
% (tb.nof_subbands).
 
%
 
% * Flipped order of FIR coefficients:
 
% The FIR filter in the PFB is defined by a prototype filter h[] with N_fft
 
% * N_taps = 1024 *16 = 16384 coefficients. The impulse response of this
 
% prototype filter will show the coefficients in h[0:16383] order. The
 
% FIR coefficients of h[] in the PFB are flipped per column of N_fft = 1024
 
% coefficients, for all N_taps = 16 columns. In VHDL simulation this shows
 
% with tb_verify_pfb_response.vhd and in the Matlab model this flip is also
 
% done by ctrl_pfir_subband.coeff = flipud(ctrl_pfir_subband.coeff).
 
% With the flip the one_pfb.m yields SNR subband / spurious max = 64.305310
 
% dB in subband 64 for an input WG at 64.015625. Without the flip the SNR
 
% subband / spurious max = 29.857938 dB, so much worse. Hence flipping the
 
% FIR coefficients is needed, and not due to an implementation detail in
 
% the VHDL. The run_pfb.m is equivalent to one_pfb.m and is used to create
 
% reference input and expected output data for the wpfb implementation in
 
% VHDL by wpfb_unit_wide.vhd. The tb_tb_wpfb_unit_wide.vhd verifies multiple
 
% sets of reference data including sinus, chirp, noise and real input or
 
% complex input and wideband (f_sample > f_clk) or same rate (f_sample =
 
% f_clk). This tb guarantees that the VHDL agrees with the Matlab model.
 
% In the Matlab model the data blocks and data time are defined as:
 
%
 
% WG FIR with four taps FFT
 
% index t t
 
% 0 -1023 1023 2047 3071 4095 --> + --> -1023
 
% . . . . .
 
% . . . . .
 
% -2 2 . . . -2
 
% -1 1 . . . -1
 
% 1023 0 0 1024 2048 3072 --> + --> 0
 
% d h h h h d
 
%
 
% The waveform generator (WG) generates a block of 1024 samples with index
 
% 0:1023, where sample at index 1023 is the newest and sample at index 0 is
 
% the oldest. In a filter the newest sample needs to be multiplied with h[0]
 
% and the older samples are multiplied by the subsequent coefficients,
 
% because it is a convolution. Therefore the FIR coefficients need to be
 
% flipped up/down per column, to allow doing the filter as a d .* h vector
 
% multiply in pfir.m. The FFT operates on blocks of data with same index and
 
% time range as the WG. The data output of the FIR filter fits this input
 
% range of the FFT. Therefore no data flipping is needed.
 
%
 
% In the tb_verify_pfb_response.vhd the input stimuli is a block of N_fft =
 
% 1024 ones followed by N_taps-1 blocks with zeros. In time the oldest data
 
% will appear first in the simulator Wave Window, so therefore the
 
% fil_re_scope signal in the tb_verify_pfb_response.vhd will show the FIR
 
% coefficients h[] in order 1023:0, 2047:1024, ..., so flipped per block.
 
%
clear all;
clear all;
close all;
close all;
fig=0;
fig=0;
@@ -205,7 +252,7 @@ if strcmp(tb.model_filterbank, 'LOFAR')
@@ -205,7 +252,7 @@ if strcmp(tb.model_filterbank, 'LOFAR')
ctrl_pfir_subband.nof_taps = 16; % Number of taps
ctrl_pfir_subband.nof_taps = 16; % Number of taps
ctrl_pfir_subband.nof_coefficients = ctrl_pfir_subband.nof_polyphases*ctrl_pfir_subband.nof_taps; % Number of filter coefficients (taps)
ctrl_pfir_subband.nof_coefficients = ctrl_pfir_subband.nof_polyphases*ctrl_pfir_subband.nof_taps; % Number of filter coefficients (taps)
ctrl_pfir_subband.data_w = 16;
ctrl_pfir_subband.data_w = 16;
ctrl_pfir_subband.config.design = 'lofar file';
ctrl_pfir_subband.config.design = 'lofar_file';
hfir_subband_coeff = load('data/Coeffs16384Kaiser-quant.dat');
hfir_subband_coeff = load('data/Coeffs16384Kaiser-quant.dat');
hfir_subband_coeff = hfir_subband_coeff/max(hfir_subband_coeff);
hfir_subband_coeff = hfir_subband_coeff/max(hfir_subband_coeff);
hfir_subband_coeff = hfir_subband_coeff'; % Use column vector, same format as by pfir_coeff()
hfir_subband_coeff = hfir_subband_coeff'; % Use column vector, same format as by pfir_coeff()
Loading