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

Remove unintended commit.

parent e6a4427b
No related branches found
No related tags found
1 merge request!100Removed text for XSub that is now written in Confluence Subband correlator...
--------------------------------------------------------------------------------
-- 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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment