From 45d9ce3b8d55af56752c675a46bfaca173ed2b52 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Wed, 2 Nov 2022 09:54:45 +0100
Subject: [PATCH] Use functions to map g_wpfb to fil and fft records.

---
 libraries/dsp/wpfb/src/vhdl/wpfb_pkg.vhd      | 40 ++++++++++++++
 libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd     | 28 +---------
 libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd | 55 +++++++++----------
 3 files changed, 67 insertions(+), 56 deletions(-)

diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_pkg.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_pkg.vhd
index 71d3145036..62105ae77d 100644
--- a/libraries/dsp/wpfb/src/vhdl/wpfb_pkg.vhd
+++ b/libraries/dsp/wpfb/src/vhdl/wpfb_pkg.vhd
@@ -70,6 +70,12 @@ package wpfb_pkg is
     fil_pipeline      : t_fil_ppf_pipeline; -- Pipeline settings for the filter units     
   end record;
 
+  -----------------------------------------------------------------------------
+  -- Map WPFB parameters to FIL parameter and to FFT parameters
+  -----------------------------------------------------------------------------
+  function func_wpfb_map_wpfb_parameters_to_fil_ppf(g_wpfb : t_wpfb) return t_fil_ppf;
+  function func_wpfb_map_wpfb_parameters_to_fft(g_wpfb : t_wpfb) return t_fft;
+
   -----------------------------------------------------------------------------
   -- LOFAR2 subband filter
   -----------------------------------------------------------------------------
@@ -246,6 +252,40 @@ end package wpfb_pkg;
 
 package body wpfb_pkg is
 
+  function func_wpfb_map_wpfb_parameters_to_fil_ppf(g_wpfb : t_wpfb) return t_fil_ppf is
+    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);
+  begin
+    return c_fil_ppf;
+  end func_wpfb_map_wpfb_parameters_to_fil_ppf;
+
+  function func_wpfb_map_wpfb_parameters_to_fft(g_wpfb : t_wpfb) return t_fft is
+    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);
+  begin
+    return c_fft;
+  end func_wpfb_map_wpfb_parameters_to_fft;
+
   function func_wpfb_subband_scale_w(wpfb : t_wpfb) return natural is
   begin
     return wpfb.fft_out_dat_w + wpfb.fft_out_gain_w - (wpfb.fil_in_dat_w + wpfb.fil_backoff_w);
diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd
index 65fce12b0a..fceeb8f5f2 100644
--- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd
+++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd
@@ -90,32 +90,8 @@ architecture str of wpfb_unit is
 
   constant c_nof_stats       : natural := 2**g_wpfb.nof_chan * g_wpfb.nof_points/g_wpfb.wb_factor;
 
-  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_fil_ppf         : t_fil_ppf := func_wpfb_map_wpfb_parameters_to_fil_ppf(g_wpfb);
+  constant c_fft             : t_fft := func_wpfb_map_wpfb_parameters_to_fft(g_wpfb);
 
   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);
diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
index f859148e0c..0fe902a0f5 100644
--- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
+++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
@@ -69,7 +69,7 @@
 -- part are filtered independently and also use the same real FIR
 -- coefficients.
 --
--- Note that:
+-- Remarks:
 -- . 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
@@ -88,6 +88,19 @@
 --   incrementing order. However the precise frequency bin order depends
 --   on the reorder generics.
 --
+-- . Output subband widths:
+--   - out_quant_sosi_arr : c_fft.out_dat_w bits (within c_32 word)
+--   - out_raw_sosi_arr   : c_raw_dat_w bits (within c_32 word)
+--   The out_quant carries subbands of c_fft.out_dat_w bits, so the
+--   c_raw_fraction_w fraction bits in c_raw_dat_w have been rounded.
+--   The out_raw carries subbands of c_raw_dat_w bits, that still have the
+--   c_raw_fraction_w fraction bits. The out_raw subbands are suitable for
+--   further weighting or alternative rounding.
+--   Note that c_raw_dat_w and c_raw_fraction_w depend on c_fft.use_separate.
+--   For real input data FFT there is one fraction bit more than for complex
+--   input FFT, due to the adder stage in the separate function.
+--   Both out_quant and out_raw use FFT out_val, so they have the same timing.
+--
 -- When wb_factor = 4 and nof_wb_streams = 2 the mapping is as follows using 
 -- the array notation:
 --
@@ -395,34 +408,14 @@ architecture str of wpfb_unit_dev is
   
   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_fil_ppf               : t_fil_ppf := func_wpfb_map_wpfb_parameters_to_fil_ppf(g_wpfb);
+  constant c_fft                   : t_fft := func_wpfb_map_wpfb_parameters_to_fft(g_wpfb);
 
   constant c_fft_r2_check           : boolean := fft_r2_parameter_asserts(c_fft);
   
+  constant c_raw_fraction_w         : natural := func_fft_raw_fraction_w(c_fft);
+  constant c_raw_dat_w              : natural := func_fft_raw_dat_w(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";
@@ -458,9 +451,11 @@ architecture str of wpfb_unit_dev is
   signal r, rin : reg_type;
 
   -- Debug signals to view parameters in Wave Window
-  signal dbg_g_wpfb          : t_wpfb := g_wpfb;
-  signal dbg_c_fil_ppf       : t_fil_ppf := c_fil_ppf;
-  signal dbg_c_fft           : t_fft := c_fft;
+  signal dbg_g_wpfb           : t_wpfb := g_wpfb;
+  signal dbg_c_fil_ppf        : t_fil_ppf := c_fil_ppf;
+  signal dbg_c_fft            : t_fft := c_fft;
+  signal dbg_c_raw_fraction_w : natural := c_raw_fraction_w;
+  signal dbg_c_raw_dat_w      : natural := c_raw_dat_w;
 
 begin
 
@@ -643,7 +638,7 @@ begin
       out_sosi    => ctrl_pfb_out_sosi
     );
 
-    -- wire pfb_out_quant_sosi_arr that is used for SST and out_quant_sosi_arr
+    -- wire pfb_out_quant_sosi_arr that is used for SST and for out_quant_sosi_arr
     wire_pfb_out_quant_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate
       pfb_out_quant_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(fft_out_quant_re_arr(I));
       pfb_out_quant_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(fft_out_quant_im_arr(I));
-- 
GitLab