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

Added example for wideband subband filterbank out_sosi_arr output format.

parent c0936191
Branches
No related tags found
No related merge requests found
...@@ -20,41 +20,145 @@ ...@@ -20,41 +20,145 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>. -- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- --
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Purpose: Wideband FFT with Subband Statistics and streaming interfaces. -- Purpose: Wideband polyphase filterbank with subband statistics and streaming interfaces.
-- --
-- Description: This unit connects an incoming array of streaming interfaces -- Description:
-- to the wideband 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
-- output streams(sop,eop,sync,bsn,err).
-- --
-- The wpfb unit can handle a wideband factor > 1 (g_wpfb.wb_factor) or -- This WPFB unit connects an incoming array of streaming interfaces to the
-- a narrowband factor > 1 (g_wpfb.nof_chan). Both factors can NOT be -- wideband pft + fft.
-- used (> 1) at the same time. -- The output of the wideband fft is connected to a set of subband statistics
-- . For wb_factor = 1 the wpfb_unit uses fft_r2_pipe and supports nof_chan >= 0 -- units. The statistics can be read via the memory mapped interface.
-- . For wb_factor > 1 the wpfb_unit uses fft_r2_wide -- A control unit takes care of the correct composition of the control of the
-- . For wb_factor = 1 the wpfb_unit supports nof_chan >= 0 -- output streams regarding sop, eop, sync, bsn, err.
-- . For wb_factor > 1 the wpfb_unit only supports nof_chan = 0, because the
-- concept of channels is void when wb_factor > 0.
-- . 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.
-- --
-- Remarks: . The unit can handle only one sync at a time. Therfor the -- The wpfb unit can handle a wideband factor > 1 (g_wpfb.wb_factor) or
-- sync interval should be larger than the total pipeline -- a narrowband factor > 1 (g_wpfb.nof_chan). Both factors can NOT be
-- stages of the wideband fft. -- used (> 1) at the same time.
-- . For wb_factor = 1 the wpfb_unit uses fft_r2_pipe and supports nof_chan >= 0
-- . For wb_factor > 1 the wpfb_unit uses fft_r2_wide
-- . For wb_factor = 1 the wpfb_unit supports nof_chan >= 0
-- . For wb_factor > 1 the wpfb_unit only supports nof_chan = 0, because the
-- concept of channels is void when wb_factor > 0.
-- . 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.
--
-- 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.
--
-- 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
-- out_sosi_arr [nof_streams][wb_factor] [bin] cint
--
-- 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
-- | | | 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 example for wideband subband filterbank:
-- . nof_streams = 2
-- . wb_factor = 4
-- . nof_points = 32
-- . use_reorder = true
-- . use_separate = true
-- - input A via in_dat_re
-- - input B via in_dat_im
--
-- out_sosi_arr:
-- I S P bin frequency order
-- 7 1 3 12 12 13 13 14 14 15 15
-- 6 1 2 8 8 9 9 10 10 11 11
-- 5 1 1 4 4 5 5 6 6 7 7
-- 4 1 0 0 0 1 1 2 2 3 3
-- 3 0 3 12 12 13 13 14 14 15 15
-- 2 0 2 8 8 9 9 10 10 11 11
-- 1 0 1 4 4 5 5 6 6 7 7
-- 0 0 0 0 0 1 1 2 2 3 3
-- ^ ^ ^ ^ ^ ^ ^ ^
-- A B A B A B A B
--
-- 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 in the filter and
-- little-endian in the FFT. Hence the WPFB input is big-endian in
-- time. The WPFB output is little-endian, so with frequency bins in
-- incrementing order. However the precise frequency bin order depends
-- on the reorder generics.
-- 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.
-- --
-- . The g_coefs_file_prefix points to the location where the files
-- with the initial content for the coefficients memories are located.
-- These files can be created using the python script: create_mifs.py
-- create_mifs.py is located in $UNB/Firmware/dsp/filter/src/python/
-- It is possible to create the mif files based on every possible
-- configuration of the filterbank in terms of:
-- * wb_factor
-- * nof points
-- * nof_taps
library ieee, common_lib, dp_lib, rTwoSDF_lib, st_lib, filter_lib, fft_lib, diag_lib; library ieee, common_lib, dp_lib, rTwoSDF_lib, st_lib, filter_lib, fft_lib, diag_lib;
use IEEE.std_logic_1164.all; use IEEE.std_logic_1164.all;
...@@ -128,6 +232,8 @@ architecture str of wpfb_unit_dev is ...@@ -128,6 +232,8 @@ architecture str of wpfb_unit_dev is
g_wpfb.stat_data_w, g_wpfb.stat_data_w,
g_wpfb.stat_data_sz); 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_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, 4, 1); constant c_bg_data_file_index_arr : t_nat_natural_arr := array_init(0, 4, 1);
constant c_bg_data_file_prefix : string := "UNUSED"; constant c_bg_data_file_prefix : string := "UNUSED";
...@@ -170,11 +276,6 @@ architecture str of wpfb_unit_dev is ...@@ -170,11 +276,6 @@ architecture str of wpfb_unit_dev is
begin begin
---------------------------------------------------------------
-- CHECK IF PROVIDED GENERICS ARE ALLOWED.
---------------------------------------------------------------
assert not(g_wpfb.nof_chan /= 0 and g_wpfb.wb_factor /= 1 and rising_edge(dp_clk)) report "nof_chan must be 0 when wb_factor > 1" severity FAILURE;
-- The complete input sosi arry is registered. -- The complete input sosi arry is registered.
comb : process(r, in_sosi_arr) comb : process(r, in_sosi_arr)
variable v : reg_type; variable v : reg_type;
...@@ -213,47 +314,7 @@ begin ...@@ -213,47 +314,7 @@ begin
--------------------------------------------------------------- ---------------------------------------------------------------
-- REWIRE THE DATA FOR WIDEBAND POLY PHASE FILTER -- REWIRE THE DATA FOR WIDEBAND POLY PHASE FILTER
--------------------------------------------------------------- ---------------------------------------------------------------
-- 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.
--
-- When wb_factor = 4 and nof_wb_streams = 2 the mapping is as
-- follows (i = array index, S = wb stream index, 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
--
-- 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
-- | | | out_sosi_arr
-- | | |
-- i S P t | i P S | i S P t | i S P
-- 0 0 0 3 | 0 0 0 RE | 0 0 0 0 | 0 0 0
-- 1 0 1 2 | 1 0 0 IM | 1 0 1 1 | 1 0 1
-- 2 0 2 1 | 2 0 1 RE | 2 0 2 2 | 2 0 2
-- 3 0 3 0 | 3 0 1 IM | 3 0 3 3 | 3 0 3
-- 4 1 0 3 | 4 1 0 RE | 4 1 0 0 | 4 1 0
-- 5 1 1 2 | 5 1 0 IM | 5 1 1 1 | 5 1 1
-- 6 1 2 1 | 6 1 1 RE | 6 1 2 2 | 6 1 2
-- 7 1 3 0 | 7 1 1 IM | 7 1 3 3 | 7 1 3
-- | 8 2 0 RE | |
-- ^ | 9 2 0 IM | ^ |
-- big | 10 2 1 RE | little |
-- endian | 11 2 1 IM | endian |
-- | 12 3 0 RE | |
-- | 13 3 0 IM | |
-- | 14 3 1 RE | |
-- | 15 3 1 IM | |
--
-- Note that wideband time index t is big-endian in the filter and
-- little-endian in the FFT
-- Wire in_sosi_arr --> fil_in_arr -- 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_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 wire_fil_in_streams: for S in 0 to g_wpfb.nof_wb_streams-1 generate
...@@ -272,6 +333,15 @@ begin ...@@ -272,6 +333,15 @@ begin
end generate; end generate;
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
-- 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
fft_in_re_arr(S*g_wpfb.wb_factor + g_wpfb.wb_factor-1-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 + g_wpfb.wb_factor-1-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 -- THE POLY PHASE FILTER
--------------------------------------------------------------- ---------------------------------------------------------------
...@@ -305,14 +375,6 @@ begin ...@@ -305,14 +375,6 @@ begin
fft_in_val <= fil_out_val; fft_in_val <= fil_out_val;
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
-- 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
fft_in_re_arr(S*g_wpfb.wb_factor + g_wpfb.wb_factor-1-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 + g_wpfb.wb_factor-1-P) <= fil_out_arr(P*g_wpfb.nof_wb_streams*c_nof_complex+S*c_nof_complex+1);
end generate;
end generate;
--------------------------------------------------------------- ---------------------------------------------------------------
-- THE WIDEBAND FFT -- THE WIDEBAND FFT
--------------------------------------------------------------- ---------------------------------------------------------------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment