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

Added pfb2 library, see readme_lofar1.txt.

parent 29d1a089
No related branches found
No related tags found
1 merge request!100Removed text for XSub that is now written in Confluence Subband correlator...
hdl_lib_name = pfb2
hdl_library_clause_name = pfb2_lib
hdl_lib_uses_synth = common dp pfs pft2 st
hdl_lib_uses_sim =
hdl_lib_technology =
synth_files =
src/vhdl/pfb2.vhd
src/vhdl/pfb2_unit.vhd
test_bench_files =
regression_test_vhdl =
[modelsim_project_file]
[ise_project_file]
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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
-- Purpose: Combine LOFAR1 pfs + pft2 into pfb2 with statistics and streaming
-- interfaces, similar as wpfb_unit_dev
-- Description:
--
-- Remark:
-- . Convert between LOFAR1 sync timing 1 clk before sop and streaming data path
-- (DP) sync timing at sop.
-- . g_switch_en = '1' decorrelates rounding crosstalk between the X and Y output
-- that can occur due to PFT_MODE_REAL2.
LIBRARY IEEE, common_lib, dp_lib, pfs_lib, pft2_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE pft2_lib.pft_pkg.ALL;
ENTITY pfb2 IS
GENERIC (
g_nof_points : NATURAL := 1024;
-- pfs
g_pfs_nof_taps : NATURAL := 16;
g_pfs_in_dat_w : NATURAL := 12;
g_pfs_out_dat_w : NATURAL := 18;
g_pfs_coef_dat_w : NATURAL := 16;
-- pft2
g_pft_mode : PFT_MODE_TYPE := PFT_MODE_REAL2;
g_pft_switch_en : STD_LOGIC := '1';
g_pft_out_dat_w : NATURAL := 18
);
PORT (
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
in_sosi : IN t_dp_sosi;
fil_sosi : OUT t_dp_sosi;
out_sosi : OUT t_dp_sosi
);
END pfb2;
ARCHITECTURE str OF pfb2 IS
CONSTANT c_nof_coeffs : NATURAL := g_pfs_nof_taps*g_nof_points;
SIGNAL pfs_in_dat_x : STD_LOGIC_VECTOR(g_pfs_in_dat_w-1 DOWNTO 0);
SIGNAL pfs_in_dat_y : STD_LOGIC_VECTOR(g_pfs_in_dat_w-1 DOWNTO 0);
SIGNAL pfs_in_val : STD_LOGIC;
SIGNAL pfs_in_sync : STD_LOGIC;
SIGNAL fil_out_dat_x : STD_LOGIC_VECTOR(g_pfs_out_dat_w-1 DOWNTO 0);
SIGNAL fil_out_dat_y : STD_LOGIC_VECTOR(g_pfs_out_dat_w-1 DOWNTO 0);
SIGNAL fil_out_val : STD_LOGIC;
SIGNAL fil_out_sync : STD_LOGIC;
SIGNAL pft_out_dat_re : STD_LOGIC_VECTOR(g_pft_out_dat_w-1 DOWNTO 0);
SIGNAL pft_out_dat_im : STD_LOGIC_VECTOR(g_pft_out_dat_w-1 DOWNTO 0);
SIGNAL pft_out_val : STD_LOGIC;
SIGNAL pft_out_sync : STD_LOGIC;
BEGIN
-- Delay in_sosi data with respect to sync to fit LOFAR1 sync timing
pfs_in_dat_x <= in_sosi.re(g_pfs_in_dat_w-1 DOWNTO 0) WHEN rising_edge(dp_clk);
pfs_in_dat_y <= in_sosi.im(g_pfs_in_dat_w-1 DOWNTO 0) WHEN rising_edge(dp_clk);
pfs_in_val <= in_sosi.valid WHEN rising_edge(dp_clk);
pfs_in_sync <= in_sosi.sync;
pfs : ENTITY pfs_lib.pfs
GENERIC MAP (
g_nof_bands => g_nof_points,
g_nof_taps => c_nof_coeffs,
g_in_dat_w => g_pfs_in_dat_w,
g_out_dat_w => g_pfs_out_dat_w,
g_coef_dat_w => g_pfs_coef_dat_w
)
PORT MAP (
in_dat_x => pfs_in_dat_x,
in_dat_y => pfs_in_dat_y,
in_val => pfs_in_val,
in_sync => pfs_in_sync,
out_dat_x => fil_out_dat_x,
out_dat_y => fil_out_dat_y,
out_val => fil_out_val,
out_sync => fil_out_sync,
clk => dp_clk,
rst => dp_rst,
restart => '0'
);
fil_sosi.re <= RESIZE_DP_DSP_DATA(fil_out_dat_x);
fil_sosi.im <= RESIZE_DP_DSP_DATA(fil_out_dat_y);
fil_sosi.valid <= fil_out_val;
fil_sosi.sync <= fil_out_sync;
pft : ENTITY pft2_lib.pft
GENERIC MAP (
g_fft_size_w => ceil_log2(g_nof_points),
g_in_dat_w => g_pfs_out_dat_w,
g_out_dat_w => g_pft_out_dat_w,
g_mode => PFT_MODE_REAL2
)
PORT MAP (
in_re => fil_out_dat_x,
in_im => fil_out_dat_y,
in_val => fil_out_val,
in_sync => fil_out_sync,
switch_en => g_pft_switch_en,
out_re => pft_out_dat_re,
out_im => pft_out_dat_im,
out_val => pft_out_val,
out_sync => pft_out_sync,
clk => dp_clk,
rst => dp_rst
);
-- Delay pft sync with respect pft data to fit DP sync timing
out_sosi.re <= RESIZE_DP_DSP_DATA(pft_out_dat_re);
out_sosi.im <= RESIZE_DP_DSP_DATA(pft_out_dat_im);
out_sosi.valid <= pft_out_val;
out_sosi.sync <= pft_out_sync WHEN rising_edge(dp_clk);
END str;
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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
-- Purpose: Combine LOFAR1 pfb2 with subband statistics (SST), similar as wpfb_unit_dev
-- Description:
-- . support multiple complex input streams via g_nof_streams
-- . 1 complex pfb2 per stream
-- . 1 complex pfb2 can process two real inputs with PFT_MODE_REAL2
-- . pass on in_sosi.bsn
--
-- Remark:
LIBRARY IEEE, common_lib, dp_lib, pfs_lib, pft2_lib, st_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE pft2_lib.pft_pkg.ALL;
ENTITY pfb2_unit IS
GENERIC (
g_nof_streams : NATURAL := 1; -- number of pfb2 instances, 1 pfb2 per stream
g_nof_points : NATURAL := 1024;
-- pfs
g_pfs_nof_taps : NATURAL := 16;
g_pfs_in_dat_w : NATURAL := 12;
g_pfs_out_dat_w : NATURAL := 18;
g_pfs_coef_dat_w : NATURAL := 16;
-- pft2
g_pft_mode : PFT_MODE_TYPE := PFT_MODE_REAL2;
g_pft_switch_en : STD_LOGIC := '1';
g_pft_out_dat_w : NATURAL := 18;
-- sst
g_sst_data_w : NATURAL := 64; -- nof bits for the SST power values
g_sst_data_sz : NATURAL := 2 -- nof MM 32b words to fit g_sst_data_w
);
PORT (
dp_rst : IN STD_LOGIC;
dp_clk : IN STD_LOGIC;
mm_rst : IN STD_LOGIC;
mm_clk : IN STD_LOGIC;
ram_st_sst_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- Subband statistics registers
ram_st_sst_miso : OUT t_mem_miso;
in_sosi_arr : IN t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
fil_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0)
);
END pfb2_unit;
ARCHITECTURE str OF pfb2_unit IS
CONSTANT c_nof_stats : NATURAL := g_nof_points; -- SST X and SST Y are interleaved for PFT_MODE_REAL2
SIGNAL ram_st_sst_mosi_arr : t_mem_mosi_arr(g_nof_streams-1 downto 0);
SIGNAL ram_st_sst_miso_arr : t_mem_miso_arr(g_nof_streams-1 downto 0) := (OTHERS => c_mem_miso_rst);
SIGNAL pft_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
BEGIN
---------------------------------------------------------------
-- Polyphase Filterbanks
---------------------------------------------------------------
gen_pfb2: FOR I IN 0 TO g_nof_streams-1 GENERATE
u_pfb2 : ENTITY work.pfb2
GENERIC MAP (
g_nof_points => g_nof_points,
-- pfs
g_pfs_nof_taps => g_pfs_nof_taps,
g_pfs_in_dat_w => g_pfs_in_dat_w,
g_pfs_out_dat_w => g_pfs_out_dat_w,
g_pfs_coef_dat_w => g_pfs_coef_dat_w,
-- pft2
g_pft_mode => g_pft_mode,
g_pft_switch_en => g_pft_switch_en,
g_pft_out_dat_w => g_pft_out_dat_w
)
PORT MAP (
dp_rst => dp_rst,
dp_clk => dp_clk,
in_sosi => in_sosi_arr(I),
fil_sosi => fil_sosi_arr(I),
out_sosi => pft_sosi_arr(I)
);
END GENERATE;
---------------------------------------------------------------
-- Subband Statistics (SST)
---------------------------------------------------------------
-- MM mux for SST
u_mem_mux_sst : ENTITY common_lib.common_mem_mux
GENERIC MAP (
g_nof_mosi => g_nof_streams,
g_mult_addr_w => ceil_log2(g_sst_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_sst: FOR I IN 0 TO g_nof_streams-1 GENERATE
u_sst : ENTITY st_lib.st_sst
GENERIC MAP (
g_nof_stat => c_nof_stats,
g_in_data_w => g_pft_out_dat_w,
g_stat_data_w => g_sst_data_w,
g_stat_data_sz => g_sst_data_sz
)
PORT MAP (
mm_rst => mm_rst,
mm_clk => mm_clk,
dp_rst => dp_rst,
dp_clk => dp_clk,
in_complex => pft_sosi_arr(I),
ram_st_sst_mosi => ram_st_sst_mosi_arr(I),
ram_st_sst_miso => ram_st_sst_miso_arr(I)
);
END GENERATE;
out_sosi_arr <= pft_sosi_arr;
end str;
--------------------------------------------------------------------------------
-- 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;
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- 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
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/RSP was ported to git for LOFAR2
Contents Contents
1) Comparison of LOFAR1 and APERTIF polyphase filterbank (PFB) 1) Comparison of LOFAR1 and APERTIF polyphase filterbank (PFB)
2) Porting LOFAR1 PFB code to LOFAR2.0 2) Porting LOFAR1 PFB code to LOFAR2.0
a) pfs
b) pft2
c) Simulating tb/vhdl/tb_pft2.vhd
3) Create pfb2_unit.vhd that can replace wpfb_unit_dev.vhd
References: References:
[1] LOFAR1 RSP firmware SVN repository https://svn.astron.nl/Station/trunk/RSP/ [1] LOFAR1 RSP firmware SVN repository https://svn.astron.nl/Station/trunk/RSP/
...@@ -11,6 +38,8 @@ References: ...@@ -11,6 +38,8 @@ References:
[4] APERTIF DSP firmware (rTwoSDF, filter, fft, wpfb) in LOFAR2.0 GIT repository https://git.astron.nl/desp/hdl/-/tree/master/libraries/dsp [4] APERTIF DSP firmware (rTwoSDF, filter, fft, wpfb) in LOFAR2.0 GIT repository https://git.astron.nl/desp/hdl/-/tree/master/libraries/dsp
[5] APERTIF PFB MATLAB code in APERTIF firmware SVN repository https://svn.astron.nl/UniBoard_FP7/RadioHDL/trunk/applications/apertif/matlab/apertif_matlab_readme.txt [5] APERTIF PFB MATLAB code in APERTIF firmware SVN repository https://svn.astron.nl/UniBoard_FP7/RadioHDL/trunk/applications/apertif/matlab/apertif_matlab_readme.txt
1) Comparison of LOFAR1 and APERTIF polyphase filterbank (PFB) 1) Comparison of LOFAR1 and APERTIF polyphase filterbank (PFB)
- Advantages of LOFAR1 PFB (= pfs + pft2) are: - Advantages of LOFAR1 PFB (= pfs + pft2) are:
. used in LOFAR1 . used in LOFAR1
...@@ -21,9 +50,11 @@ References: ...@@ -21,9 +50,11 @@ References:
. already available in LOFAR2.0 SDP . already available in LOFAR2.0 SDP
2) Porting LOFAR1 PFB code to LOFAR2.0 2) Porting LOFAR1 PFB code to LOFAR2.0
- Porting from [1] to [3] - Porting from [1] to [3]
a) pfs/
a) pfs
* hdllib.cfg : copy simulation files to data/ * hdllib.cfg : copy simulation files to data/
* src/vhdl/ * src/vhdl/
- pfs_coefsbuf(str).vhd : - pfs_coefsbuf(str).vhd :
...@@ -32,7 +63,8 @@ a) pfs/ ...@@ -32,7 +63,8 @@ a) pfs/
- pfs_filter(rtl).vhd : use ported common_mult_add.vhd from common_mult_lib - pfs_filter(rtl).vhd : use ported common_mult_add.vhd from common_mult_lib
* tb/vhdl/tb_pfs.vhd : ==> simulates OK * tb/vhdl/tb_pfs.vhd : ==> simulates OK
. added usage comment . added usage comment
b) pft2/ at
b) pft2
* hdllib.cfg : copy simulation files to data/ * hdllib.cfg : copy simulation files to data/
* src/vhdl/ * src/vhdl/
- pft_bf(rtl).vhd : - pft_bf(rtl).vhd :
...@@ -60,6 +92,12 @@ c) Simulating tb/vhdl/tb_pft2.vhd ...@@ -60,6 +92,12 @@ c) Simulating tb/vhdl/tb_pft2.vhd
* Added multi tb_tb_pft2.vhd to verify ptf2 with all available *sig files. * Added multi tb_tb_pft2.vhd to verify ptf2 with all available *sig files.
==> tb_tb_pft2.vhd simulates OK using c_diff_max = 20 like in data/tc.tcl ==> tb_tb_pft2.vhd simulates OK using c_diff_max = 20 like in data/tc.tcl
d) Creating pfb2.vhd that can replace wpfb_unit_dev.vhd
3) Create pfb2_unit.vhd that can replace wpfb_unit_dev.vhd
* pfb2.vhd = pfs + pft2
* pfb2_unit.vhd = multiple instances of pfb2 + sst, similar as wpfb_unit_dev.vhd for wideband factor wb = 1.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment