Skip to content
Snippets Groups Projects
Commit bc9c708c authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Clarified flipped order of FIR coefficients in PFB.

parent dd8ed85d
No related branches found
No related tags found
1 merge request!1Clarified flipped order of FIR coefficients in PFB.
......@@ -83,6 +83,50 @@
% 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
% (tb.nof_subbands).
%
% * Flipped order of FIR coefficients:
% The FIR coefficients 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;
close all;
fig=0;
......@@ -205,7 +249,7 @@ if strcmp(tb.model_filterbank, 'LOFAR')
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.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 = hfir_subband_coeff/max(hfir_subband_coeff);
hfir_subband_coeff = hfir_subband_coeff'; % Use column vector, same format as by pfir_coeff()
......
......@@ -236,6 +236,7 @@ x = fliplr(x);
% Flip ctrl_pfir_subband.coeff per poly phase, because that is the order
% in which the pfir() model and HDL expect the FIR coefficients
% See one_pfb.m for more detailed clarification.
ctrl_pfir_subband.coeff = reshape(hfir_subband_coeff, ctrl_pfir_subband.nof_polyphases, ctrl_pfir_subband.nof_taps);
ctrl_pfir_subband.coeff = flipud(ctrl_pfir_subband.coeff);
ctrl_pfir_subband.Zdelays = zeros(ctrl_pfir_subband.nof_polyphases, ctrl_pfir_subband.nof_taps-1);
......
......@@ -203,7 +203,7 @@ hfir_channel_coeff = pfir_coeff(ctrl_pfir_channel.nof_polyphases, ...
ctrl_pfir_channel.coeff_w, ...
ctrl_pfir_channel.config);
ctrl_pfir_channel.coeff = reshape(hfir_channel_coeff, ctrl_pfir_channel.nof_polyphases, ctrl_pfir_channel.nof_taps);
ctrl_pfir_channel.coeff = flipud(ctrl_pfir_channel.coeff);
ctrl_pfir_channel.coeff = flipud(ctrl_pfir_channel.coeff); % See one_pfb.m for more detailed clarification.
ctrl_pfir_channel.Zdelays = zeros(ctrl_pfir_channel.nof_polyphases, ctrl_pfir_channel.nof_taps-1);
ctrl_pfir_channel.gain = 1; % no gain adjustment in PFIR, just apply the coefficients to the input data
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment