From 2abac46da74dbb47a62e258cdcff3655ca96ba67 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Tue, 1 Nov 2022 15:45:22 +0100
Subject: [PATCH] Prepare for using subband fraction bits between WPFB and
 subband equalizer / BF.

---
 .../sdp/src/vhdl/node_sdp_filterbank.vhd      |  16 +-
 .../vhdl/node_sdp_oversampled_filterbank.vhd  |  14 +-
 .../sdp/src/vhdl/sdp_beamformer_local.vhd     |   2 +-
 .../libraries/sdp/src/vhdl/sdp_bf_weights.vhd |   8 +-
 .../lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd |   4 +-
 .../sdp/src/vhdl/sdp_subband_equalizer.vhd    |  10 +-
 libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd    | 137 +++++++++++-------
 libraries/dsp/fft/src/vhdl/fft_r2_wide.vhd    |  32 ++--
 .../fft/src/vhdl/fft_reorder_sepa_pipe.vhd    |  12 +-
 libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd  |  18 +--
 libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2.vhd   |  16 +-
 .../dsp/fft/tb/vhdl/tb_mmf_fft_r2_pipe.vhd    |  16 +-
 .../dsp/verify_pfb/tb_verify_pfb_response.vhd |   4 +-
 libraries/dsp/verify_pfb/tb_verify_pfb_wg.vhd |   4 +-
 libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd     |  16 +-
 libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd | 129 +++++++++--------
 .../dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd     |   3 +-
 .../dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd    |   3 +-
 18 files changed, 262 insertions(+), 182 deletions(-)

diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
index 8f37ffab21..0ca1f59c6d 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd
@@ -119,9 +119,10 @@ ARCHITECTURE str OF node_sdp_filterbank IS
   SIGNAL master_miso_arr     : t_mem_miso_arr(0 TO c_nof_masters-1) := (OTHERS=>c_mem_miso_rst);
 
   SIGNAL si_sosi_arr                    : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)  := (OTHERS => c_dp_sosi_rst);
-  SIGNAL wpfb_unit_out_sosi_arr         : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
-  SIGNAL wpfb_unit_fil_sosi_arr         : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   SIGNAL wpfb_unit_in_sosi_arr          : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL wpfb_unit_fil_sosi_arr         : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL wpfb_unit_out_quant_sosi_arr   : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
+  SIGNAL wpfb_unit_out_raw_sosi_arr     : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   SIGNAL subband_equalizer_out_sosi_arr : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   SIGNAL dp_selector_out_sosi_arr       : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
   SIGNAL scope_sosi_arr                 : t_dp_sosi_integer_arr(c_sdp_S_pn-1 DOWNTO 0);
@@ -199,13 +200,14 @@ BEGIN
 
     in_sosi_arr        => wpfb_unit_in_sosi_arr, 
     fil_sosi_arr       => wpfb_unit_fil_sosi_arr, 
-    out_sosi_arr       => wpfb_unit_out_sosi_arr,
- 
+    out_quant_sosi_arr => wpfb_unit_out_quant_sosi_arr,
+    out_raw_sosi_arr   => wpfb_unit_out_raw_sosi_arr,
+
     dp_bsn_source_restart => dp_bsn_source_restart_pipe
   );
   
   -- Output PFB streams
-  pfb_sosi_arr <= wpfb_unit_out_sosi_arr;
+  pfb_sosi_arr <= wpfb_unit_out_quant_sosi_arr;
 
   ---------------------------------------------------------------
   -- SUBBAND EQUALIZER
@@ -218,7 +220,7 @@ BEGIN
       dp_clk         => dp_clk,
       dp_rst         => dp_rst,
 
-      in_sosi_arr    => wpfb_unit_out_sosi_arr,
+      in_sosi_arr    => wpfb_unit_out_quant_sosi_arr,
       out_sosi_arr   => subband_equalizer_out_sosi_arr,
   
       mm_rst         => mm_rst,
@@ -248,7 +250,7 @@ BEGIN
       reg_selector_mosi => reg_selector_mosi,
       reg_selector_miso => reg_selector_miso,
 
-      pipe_sosi_arr  => wpfb_unit_out_sosi_arr, 
+      pipe_sosi_arr  => wpfb_unit_out_quant_sosi_arr,
       ref_sosi_arr   => subband_equalizer_out_sosi_arr,    
       out_sosi_arr   => dp_selector_out_sosi_arr,
 
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd
index ba01e264bb..83cdf658c9 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd
@@ -154,9 +154,9 @@ ARCHITECTURE str OF node_sdp_oversampled_filterbank IS
 
   SIGNAL complex_mult_src_out_arr       : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
   SIGNAL requantize_src_out_arr         : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
-  SIGNAL wpfb_unit_complex_out_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
-  SIGNAL wpfb_unit_complex_fil_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
   SIGNAL wpfb_unit_complex_in_sosi_arr  : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
+  SIGNAL wpfb_unit_complex_fil_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
+  SIGNAL wpfb_unit_complex_out_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
   SIGNAL wpfb_unit_out_resized_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
   SIGNAL wpfb_fifo_sosi_arr             : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_sosi_rst);
   SIGNAL wpfb_fifo_siso_arr             : t_dp_siso_arr(c_sdp_S_pn-1 DOWNTO 0)   := (OTHERS => c_dp_siso_rst);
@@ -244,8 +244,9 @@ BEGIN
 
     in_sosi_arr        => wpfb_unit_in_sosi_arr, 
     fil_sosi_arr       => wpfb_unit_fil_sosi_arr, 
-    out_sosi_arr       => wpfb_unit_out_sosi_arr,
- 
+    out_quant_sosi_arr => wpfb_unit_out_sosi_arr,
+    out_raw_sosi_arr   => OPEN,
+
     dp_bsn_source_restart => dp_bsn_source_restart_pipe
   );
 
@@ -415,8 +416,9 @@ BEGIN
 
     in_sosi_arr        => wpfb_unit_complex_in_sosi_arr, 
     fil_sosi_arr       => wpfb_unit_complex_fil_sosi_arr, 
-    out_sosi_arr       => wpfb_unit_complex_out_sosi_arr,
- 
+    out_quant_sosi_arr => wpfb_unit_complex_out_sosi_arr,
+    out_raw_sosi_arr   => OPEN,
+
     dp_bsn_source_restart => dp_bsn_source_restart_pipe_complex
   );
  
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd
index 52c400be4b..dd3b98a7ba 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_local.vhd
@@ -217,7 +217,7 @@ BEGIN
   GENERIC MAP (               
     g_complex             => TRUE,  
     g_representation      => "SIGNED",           
-    g_lsb_w               => c_sdp_W_bf_weight_fraction,
+    g_lsb_w               => c_sdp_W_bf_weight_fraction + c_sdp_W_subband_fraction,
     g_lsb_round           => TRUE,       
     g_lsb_round_clip      => FALSE,      
     g_msb_clip            => FALSE,      
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd
index 3dec6eb529..9b83b85016 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_bf_weights.vhd
@@ -61,13 +61,17 @@ END sdp_bf_weights;
 
 ARCHITECTURE str OF sdp_bf_weights IS
 
+  CONSTANT c_in_dat_w : NATURAL := c_sdp_W_subband + c_sdp_W_subband_fraction;
   CONSTANT c_gain_addr_w : NATURAL := ceil_log2(c_sdp_Q_fft * c_sdp_S_sub_bf);
-  CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_bf_weight + c_sdp_W_subband -1;
+  CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_bf_weight + c_in_dat_w - 1;  -- -1 to skip double sign bit in product
   
   SIGNAL cnt : NATURAL RANGE 0 TO c_sdp_Q_fft * c_sdp_S_sub_bf-1;
   SIGNAL gains_rd_address : STD_LOGIC_VECTOR(c_gain_addr_w-1 DOWNTO 0);
 
 BEGIN
+
+  ASSERT c_gain_out_dat_w = c_sdp_W_bf_product REPORT "Wrong beamformer product width." SEVERITY FAILURE;
+
   ---------------------------------------------------------------
   -- Counter 
   ---------------------------------------------------------------
@@ -118,7 +122,7 @@ BEGIN
     g_complex_data    => TRUE,
     g_complex_gain    => TRUE,
     g_gain_w          => c_sdp_W_bf_weight,
-    g_in_dat_w        => c_sdp_W_subband,
+    g_in_dat_w        => c_in_dat_w,
     g_out_dat_w       => c_gain_out_dat_w,
     g_gains_file_name => g_gains_file_name
   )
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
index f881389b64..bd89e862a8 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd
@@ -92,6 +92,7 @@ PACKAGE sdp_pkg is
   CONSTANT c_sdp_W_adc_jesd                : NATURAL := 16;
   CONSTANT c_sdp_W_fir_coef                : NATURAL := 16;
   CONSTANT c_sdp_W_subband                 : NATURAL := 18;
+  CONSTANT c_sdp_W_subband_fraction        : NATURAL := 0;  -- extra bits beteen FSub and subband equalizer / beamformer
   CONSTANT c_sdp_W_crosslet                : NATURAL := 16;
   CONSTANT c_sdp_W_beamlet_sum             : NATURAL := 18;
   CONSTANT c_sdp_W_beamlet                 : NATURAL := 8;
@@ -129,7 +130,8 @@ PACKAGE sdp_pkg is
   CONSTANT c_sdp_P_pfb                   : NATURAL := c_sdp_S_pn / c_sdp_Q_fft;  -- = 6 PFB units, for 6 signal input pairs
   CONSTANT c_sdp_T_adc                   : TIME    := (10**6 / c_sdp_f_adc_MHz) * 1 ps;  -- = 5 ns @ 200MHz
   CONSTANT c_sdp_T_sub                   : TIME    := c_sdp_N_fft * c_sdp_T_adc;  -- = 5.12 us @ 200MHz
-  CONSTANT c_sdp_W_bf_product            : NATURAL := c_sdp_W_subband + c_sdp_W_bf_weight -1;
+  CONSTANT c_sdp_W_equalizer_product     : NATURAL := c_sdp_W_sub_weight + c_sdp_W_subband + c_sdp_W_subband_fraction - 1;  -- -1 to skip double sign bit in product
+  CONSTANT c_sdp_W_bf_product            : NATURAL := c_sdp_W_bf_weight + c_sdp_W_subband + c_sdp_W_subband_fraction - 1;  -- -1 to skip double sign bit in product
   CONSTANT c_sdp_X_sq                    : NATURAL := c_sdp_S_pn * c_sdp_S_pn;  -- = 144
   CONSTANT c_sdp_block_period            : NATURAL := c_sdp_N_fft * 1000 / c_sdp_f_adc_MHz;  -- = 5120 [ns]
   CONSTANT c_sdp_N_beamlets_sdp          : NATURAL := c_sdp_N_beamsets * c_sdp_S_sub_bf;  -- = 976
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd
index f337da198f..7b4db7cbb3 100644
--- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_equalizer.vhd
@@ -61,14 +61,18 @@ END sdp_subband_equalizer;
 
 ARCHITECTURE str OF sdp_subband_equalizer IS
 
+  CONSTANT c_in_dat_w : NATURAL := c_sdp_W_subband + c_sdp_W_subband_fraction;
   CONSTANT c_gain_addr_w : NATURAL := ceil_log2(c_sdp_Q_fft * c_sdp_N_sub);
-  CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_sub_weight + c_sdp_W_subband -1;
+  CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_sub_weight + c_in_dat_w - 1;  -- = c_sdp_W_se_product
   
   SIGNAL cnt : NATURAL RANGE 0 TO c_sdp_Q_fft * c_sdp_N_sub-1;
   SIGNAL gains_rd_address : STD_LOGIC_VECTOR(c_gain_addr_w-1 DOWNTO 0);
   SIGNAL dp_gain_serial_out_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
 
 BEGIN
+
+  ASSERT c_gain_out_dat_w = c_sdp_W_equalizer_product REPORT "Wrong subband equalizer product width." SEVERITY FAILURE;
+
   ---------------------------------------------------------------
   -- Counter 
   ---------------------------------------------------------------
@@ -119,7 +123,7 @@ BEGIN
     g_complex_data    => TRUE,
     g_complex_gain    => TRUE,
     g_gain_w          => c_sdp_W_sub_weight,
-    g_in_dat_w        => c_sdp_W_subband,
+    g_in_dat_w        => c_in_dat_w,
     g_out_dat_w       => c_gain_out_dat_w,
     g_gains_file_name => g_gains_file_name
   )
@@ -149,7 +153,7 @@ BEGIN
     GENERIC MAP (               
       g_complex             => TRUE,  
       g_representation      => "SIGNED",           
-      g_lsb_w               => c_sdp_W_sub_weight_fraction,
+      g_lsb_w               => c_sdp_W_sub_weight_fraction + c_sdp_W_subband_fraction,
       g_lsb_round           => TRUE,       
       g_lsb_round_clip      => FALSE,      
       g_msb_clip            => TRUE,      
diff --git a/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd b/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd
index 696fcdf427..a121630cc5 100644
--- a/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd
+++ b/libraries/dsp/fft/src/vhdl/fft_r2_pipe.vhd
@@ -72,14 +72,17 @@ entity fft_r2_pipe is
     g_dont_flip_channels : boolean := false        -- generic to prevent re-ordering of the channels
   );
   port (
-    clk      : in  std_logic;
-    rst      : in  std_logic := '0';
-    in_re    : in  std_logic_vector(g_fft.in_dat_w-1 downto 0);
-    in_im    : in  std_logic_vector(g_fft.in_dat_w-1 downto 0);
-    in_val   : in  std_logic := '1';
-    out_re   : out std_logic_vector(g_fft.out_dat_w-1 downto 0);
-    out_im   : out std_logic_vector(g_fft.out_dat_w-1 downto 0);
-    out_val  : out std_logic
+    clk            : in  std_logic;
+    rst            : in  std_logic := '0';
+    in_re          : in  std_logic_vector(g_fft.in_dat_w-1 downto 0);
+    in_im          : in  std_logic_vector(g_fft.in_dat_w-1 downto 0);
+    in_val         : in  std_logic := '1';
+    out_quant_re   : out std_logic_vector(g_fft.out_dat_w-1 downto 0);
+    out_quant_im   : out std_logic_vector(g_fft.out_dat_w-1 downto 0);
+    -- use c_32 width as in t_fft_slv_arr, to allow leaving OUT port open, actual width is c_raw_dat_w
+    out_raw_re     : out std_logic_vector(c_32-1 DOWNTO 0);
+    out_raw_im     : out std_logic_vector(c_32-1 DOWNTO 0);
+    out_val        : out std_logic
   );
 end entity fft_r2_pipe;
 
@@ -90,7 +93,6 @@ architecture str of fft_r2_pipe is
   constant c_switch_en          : boolean := g_fft.use_separate;  -- default do apply switch/unswitch per real input to mitigate quantization crosstalk
   constant c_switch_sz_w        : natural := ceil_log2(g_fft.nof_points) + g_fft.nof_chan;
   constant c_switch_dat_w       : natural := g_fft.in_dat_w + 1;  -- add 1 extra bit to fit negation of most negative value per real input switch function
-  constant c_unswitch_dat_w     : natural := g_fft.out_dat_w;  -- no need for extra bit, because most negative value cannot occur in output
   constant c_switch_seed1       : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := fft_switch_new_seed(c_fft_switch_seed1, g_instance_index);
   constant c_switch_seed2       : STD_LOGIC_VECTOR(c_fft_lfsr_len-1 DOWNTO 0) := fft_switch_new_seed(c_fft_switch_seed2, g_instance_index);
   constant c_nof_stages         : natural := ceil_log2(g_fft.nof_points);
@@ -99,6 +101,7 @@ architecture str of fft_r2_pipe is
   constant c_out_scale_w        : integer := g_fft.stage_dat_w - g_fft.out_dat_w - g_fft.out_gain_w;  -- Estimate number of LSBs to throw throw away when > 0 or insert when < 0
   constant c_sepa_growth_w      : natural := sel_a_b(g_fft.use_separate, 1, 0);  -- add one bit for add sub growth in separate
   constant c_raw_dat_w          : natural := g_fft.stage_dat_w + c_sepa_growth_w;
+  constant c_unswitch_dat_w     : natural := c_raw_dat_w;  -- no need for extra bit, because most negative value cannot occur in FFT output
 
   -- number the stage instances from c_nof_stages:1
   -- . the data input for the first stage has index c_nof_stages
@@ -119,13 +122,14 @@ architecture str of fft_r2_pipe is
 
   signal in_cplx      : std_logic_vector(c_nof_complex*g_fft.stage_dat_w-1 downto 0);
   signal out_cplx     : std_logic_vector(c_nof_complex*c_raw_dat_w-1 downto 0);
-  signal raw_out_re   : std_logic_vector(c_raw_dat_w-1 downto 0);
-  signal raw_out_im   : std_logic_vector(c_raw_dat_w-1 downto 0);
-  signal raw_out_val  : std_logic;
 
-  signal quant_re     : std_logic_vector(g_fft.out_dat_w-1 downto 0);
-  signal quant_im     : std_logic_vector(g_fft.out_dat_w-1 downto 0);
-  signal quant_val    : std_logic;
+  signal fft_out_re   : std_logic_vector(c_raw_dat_w-1 downto 0);
+  signal fft_out_im   : std_logic_vector(c_raw_dat_w-1 downto 0);
+  signal fft_out_val  : std_logic;
+
+  signal raw_re       : std_logic_vector(c_raw_dat_w-1 downto 0);
+  signal raw_im       : std_logic_vector(c_raw_dat_w-1 downto 0);
+  signal raw_val      : std_logic;
 
   -- debug signals to view parameters in Wave Window
   signal dbg_g_g_fft          : t_fft := g_fft;
@@ -236,25 +240,48 @@ begin
       in_dat  => in_cplx,      -- c_nof_complex * g_fft.stage_dat_w
       in_val  => data_val(0),
       out_dat => out_cplx,     -- c_nof_complex * c_raw_dat_w
-      out_val => raw_out_val
+      out_val => fft_out_val
     );
 
     -- c_raw_dat_w = g_fft.stage_dat_w     when g_fft.use_separate = false
     -- c_raw_dat_w = g_fft.stage_dat_w + 1 when g_fft.use_separate = true
-    raw_out_re <= out_cplx(  c_raw_dat_w-1 downto 0);
-    raw_out_im <= out_cplx(2*c_raw_dat_w-1 downto c_raw_dat_w);
+    fft_out_re <= out_cplx(  c_raw_dat_w-1 downto 0);
+    fft_out_im <= out_cplx(2*c_raw_dat_w-1 downto c_raw_dat_w);
    
   end generate;
   
   no_reorder_no_seperate : if g_fft.use_separate=false and g_fft.use_reorder=false generate
     -- c_raw_dat_w = g_fft.stage_dat_w because g_fft.use_separate = false
-    raw_out_re  <= data_re(0);
-    raw_out_im  <= data_im(0);
-    raw_out_val <= data_val(0);
+    fft_out_re  <= data_re(0);
+    fft_out_im  <= data_im(0);
+    fft_out_val <= data_val(0);
   end generate;  
-  
+
+  ------------------------------------------------------------------------------
+  -- Undo input random negation of u_switch at FFT output when c_switch_en =
+  -- g_fft.use_separate = TRUE
+  ------------------------------------------------------------------------------
+  u_unswitch : ENTITY work.fft_unswitch
+  GENERIC MAP (
+    g_switch_en => c_switch_en,
+    g_seed1     => c_switch_seed1,
+    g_seed2     => c_switch_seed2,
+    g_fft_sz_w  => c_switch_sz_w,
+    g_dat_w     => c_unswitch_dat_w
+  )
+  PORT MAP (
+    in_re      => fft_out_re,
+    in_im      => fft_out_im,
+    in_val     => fft_out_val,
+    out_re     => raw_re,
+    out_im     => raw_im,
+    out_val    => raw_val,
+    clk        => clk,
+    rst        => rst
+  );
+
   ------------------------------------------------------------------------------
-  -- pipelined FFT output requantization
+  -- Pipelined FFT output requantization
   ------------------------------------------------------------------------------
   u_requantize_re : entity common_lib.common_requantize
   generic map (
@@ -271,8 +298,8 @@ begin
   )
   port map (
     clk        => clk,
-    in_dat     => raw_out_re,
-    out_dat    => quant_re,
+    in_dat     => raw_re,
+    out_dat    => out_quant_re,
     out_ovr    => open
   );       
 
@@ -291,41 +318,53 @@ begin
   )
   port map (
     clk        => clk,
-    in_dat     => raw_out_im,
-    out_dat    => quant_im,
+    in_dat     => raw_im,
+    out_dat    => out_quant_im,
     out_ovr    => open
   );
   
-  -- Valid Output
-  u_out_val : entity common_lib.common_pipeline_sl
+  u_quant_val : entity common_lib.common_pipeline_sl
   generic map (
     g_pipeline => c_pipeline_remove_lsb
   )
   port map (
     rst     => rst,
     clk     => clk,
-    in_dat  => raw_out_val,
-    out_dat => quant_val
+    in_dat  => raw_val,
+    out_dat => out_val
   );
-  
-  -- Undo input random negation of u_switch at output when g_fft.use_separate = TRUE
-  u_unswitch : ENTITY work.fft_unswitch
-  GENERIC MAP (
-    g_switch_en => c_switch_en,
-    g_seed1     => c_switch_seed1,
-    g_seed2     => c_switch_seed2,
-    g_fft_sz_w  => c_switch_sz_w,
-    g_dat_w     => c_unswitch_dat_w
+
+  ------------------------------------------------------------------------------
+  -- Pipelined FFT raw output register
+  -- . Pipeline out_raw_* to align with out_quant_*, so they can share out_val
+  ------------------------------------------------------------------------------
+
+  u_out_raw_re : entity common_lib.common_pipeline
+  generic map (
+    g_representation => "SIGNED",
+    g_pipeline       => c_pipeline_remove_lsb,
+    g_in_dat_w       => c_raw_dat_w,
+    g_out_dat_w      => c_32
   )
-  PORT MAP (
-    in_re      => quant_re,
-    in_im      => quant_im,
-    in_val     => quant_val,
-    out_re     => out_re,
-    out_im     => out_im,
-    out_val    => out_val,
-    clk        => clk,
-    rst        => rst
+  port map (
+    rst     => rst,
+    clk     => clk,
+    in_dat  => raw_re,
+    out_dat => out_raw_re
+  );
+
+  u_out_raw_im : entity common_lib.common_pipeline
+  generic map (
+    g_representation => "SIGNED",
+    g_pipeline       => c_pipeline_remove_lsb,
+    g_in_dat_w       => c_raw_dat_w,
+    g_out_dat_w      => c_32
+  )
+  port map (
+    rst     => rst,
+    clk     => clk,
+    in_dat  => raw_im,
+    out_dat => out_raw_im
   );
 
 end str;
diff --git a/libraries/dsp/fft/src/vhdl/fft_r2_wide.vhd b/libraries/dsp/fft/src/vhdl/fft_r2_wide.vhd
index ecc6a02739..0a2be83321 100644
--- a/libraries/dsp/fft/src/vhdl/fft_r2_wide.vhd
+++ b/libraries/dsp/fft/src/vhdl/fft_r2_wide.vhd
@@ -196,14 +196,14 @@ begin
       g_pipeline       => g_pft_pipeline
     )
     port map (
-      clk        => clk,
-      rst        => rst,
-      in_re      => in_re_arr(0)(g_fft.in_dat_w-1 downto 0),
-      in_im      => in_im_arr(0)(g_fft.in_dat_w-1 downto 0),
-      in_val     => in_val,
-      out_re     => fft_pipe_out_re,
-      out_im     => fft_pipe_out_im,
-      out_val    => out_val
+      clk           => clk,
+      rst           => rst,
+      in_re         => in_re_arr(0)(g_fft.in_dat_w-1 downto 0),
+      in_im         => in_im_arr(0)(g_fft.in_dat_w-1 downto 0),
+      in_val        => in_val,
+      out_quant_re  => fft_pipe_out_re,
+      out_quant_im  => fft_pipe_out_im,
+      out_val       => out_val
     );
     
     out_re_arr(0) <= resize_fft_svec(fft_pipe_out_re);
@@ -251,14 +251,14 @@ begin
         g_pipeline       => g_pft_pipeline          -- pipeline generics for the pipelined FFTs
       )
       port map (
-        clk       => clk,
-        rst       => rst,
-        in_re     => in_fft_pipe_re_arr(I)(c_fft_r2_pipe_arr(I).in_dat_w-1 downto 0),
-        in_im     => in_fft_pipe_im_arr(I)(c_fft_r2_pipe_arr(I).in_dat_w-1 downto 0),
-        in_val    => in_val,
-        out_re    => out_fft_pipe_re_arr(I)(c_fft_r2_pipe_arr(I).out_dat_w-1 downto 0),
-        out_im    => out_fft_pipe_im_arr(I)(c_fft_r2_pipe_arr(I).out_dat_w-1 downto 0),
-        out_val   => out_fft_pipe_val(I)
+        clk           => clk,
+        rst           => rst,
+        in_re         => in_fft_pipe_re_arr(I)(c_fft_r2_pipe_arr(I).in_dat_w-1 downto 0),
+        in_im         => in_fft_pipe_im_arr(I)(c_fft_r2_pipe_arr(I).in_dat_w-1 downto 0),
+        in_val        => in_val,
+        out_quant_re  => out_fft_pipe_re_arr(I)(c_fft_r2_pipe_arr(I).out_dat_w-1 downto 0),
+        out_quant_im  => out_fft_pipe_im_arr(I)(c_fft_r2_pipe_arr(I).out_dat_w-1 downto 0),
+        out_val       => out_fft_pipe_val(I)
       );     
     end generate;       
     
diff --git a/libraries/dsp/fft/src/vhdl/fft_reorder_sepa_pipe.vhd b/libraries/dsp/fft/src/vhdl/fft_reorder_sepa_pipe.vhd
index b363745caf..d0c2a68feb 100644
--- a/libraries/dsp/fft/src/vhdl/fft_reorder_sepa_pipe.vhd
+++ b/libraries/dsp/fft/src/vhdl/fft_reorder_sepa_pipe.vhd
@@ -51,9 +51,9 @@ entity fft_reorder_sepa_pipe is
   port (
     clk     : in  std_logic;
     rst     : in  std_logic;
-    in_dat  : in  std_logic_vector;  -- c_dat_w
+    in_dat  : in  std_logic_vector;  -- c_dat_w (Im & Re)
     in_val  : in  std_logic;
-    out_dat : out std_logic_vector;  -- c_dat_w when g_separate = false, else c_dat_w + 2
+    out_dat : out std_logic_vector;  -- c_dat_w when g_separate = false, else c_dat_w + 2 (Im & Re, with 1 extra bit for both)
     out_val : out std_logic
   );
 end entity fft_reorder_sepa_pipe;
@@ -105,6 +105,14 @@ architecture rtl of fft_reorder_sepa_pipe is
 
   signal r, rin : reg_type;   
 
+  -- debug signals to view parameters in Wave Window
+  signal dbg_c_nof_channels : natural := c_nof_channels;
+  signal dbg_c_dat_w        : natural := c_dat_w;
+  signal dbg_c_page_size    : natural := c_page_size;
+  signal dbg_c_adr_points_w : natural := c_adr_points_w;
+  signal dbg_c_adr_chan_w   : natural := c_adr_chan_w;
+  signal dbg_c_adr_tot_w    : natural := c_adr_tot_w;
+
 begin
 
   out_dat_i <= rd_dat;
diff --git a/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd b/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd
index 35a6684bc3..785430c6b0 100644
--- a/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd
+++ b/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd
@@ -331,14 +331,14 @@ begin
     g_fft      => g_fft
   )
   port map (
-    clk      => clk,
-    rst      => rst,
-    in_re    => in_dat_a,
-    in_im    => in_dat_b,
-    in_val   => in_val,
-    out_re   => out_re,
-    out_im   => out_im,
-    out_val  => out_val
+    clk           => clk,
+    rst           => rst,
+    in_re         => in_dat_a,
+    in_im         => in_dat_b,
+    in_val        => in_val,
+    out_quant_re  => out_re,
+    out_quant_im  => out_im,
+    out_val       => out_val
   );
 
   -- Separate output
@@ -447,4 +447,4 @@ begin
   diff_re_c_scope <= exp_re_c_scope - out_re_c_scope;
   diff_im_c_scope <= exp_im_c_scope - out_im_c_scope;
 
-end tb;
\ No newline at end of file
+end tb;
diff --git a/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2.vhd b/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2.vhd
index 2a0c51f25a..b744daefe0 100644
--- a/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2.vhd
+++ b/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2.vhd
@@ -278,14 +278,14 @@ BEGIN
       g_fft      => c_fft
     )
     port map(
-      clk       => dp_clk,
-      rst       => dp_rst,
-      in_re     => in_re_arr(0)(c_fft.in_dat_w-1 DOWNTO 0),
-      in_im     => in_im_arr(0)(c_fft.in_dat_w-1 DOWNTO 0),
-      in_val    => in_val,
-      out_re    => out_re_arr(0)(c_fft.out_dat_w-1 DOWNTO 0),
-      out_im    => out_im_arr(0)(c_fft.out_dat_w-1 DOWNTO 0),
-      out_val   => out_val
+      clk           => dp_clk,
+      rst           => dp_rst,
+      in_re         => in_re_arr(0)(c_fft.in_dat_w-1 DOWNTO 0),
+      in_im         => in_im_arr(0)(c_fft.in_dat_w-1 DOWNTO 0),
+      in_val        => in_val,
+      out_quant_re  => out_re_arr(0)(c_fft.out_dat_w-1 DOWNTO 0),
+      out_quant_im  => out_im_arr(0)(c_fft.out_dat_w-1 DOWNTO 0),
+      out_val       => out_val
     );
   END GENERATE;  
   
diff --git a/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2_pipe.vhd b/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2_pipe.vhd
index 675d4d6481..549f82b0c4 100644
--- a/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2_pipe.vhd
+++ b/libraries/dsp/fft/tb/vhdl/tb_mmf_fft_r2_pipe.vhd
@@ -219,14 +219,14 @@ BEGIN
     g_fft      => g_fft     -- generics for the FFT
   )
   port map(
-    clk       => dp_clk,
-    rst       => dp_rst,
-    in_re     => in_re,
-    in_im     => in_im,
-    in_val    => in_val,
-    out_re    => out_re,
-    out_im    => out_im,
-    out_val   => out_val
+    clk           => dp_clk,
+    rst           => dp_rst,
+    in_re         => in_re,
+    in_im         => in_im,
+    in_val        => in_val,
+    out_quant_re  => out_re,
+    out_quant_im  => out_im,
+    out_val       => out_val
   );
 
   ss_out_sosi_re_arr(0).data  <= RESIZE_SVEC(out_re, ss_out_sosi_re_arr(0).data'LENGTH);
diff --git a/libraries/dsp/verify_pfb/tb_verify_pfb_response.vhd b/libraries/dsp/verify_pfb/tb_verify_pfb_response.vhd
index 22eeddb4d0..27c61530d0 100644
--- a/libraries/dsp/verify_pfb/tb_verify_pfb_response.vhd
+++ b/libraries/dsp/verify_pfb/tb_verify_pfb_response.vhd
@@ -190,6 +190,7 @@ ARCHITECTURE tb OF tb_verify_pfb_response IS
   SIGNAL fil_blk_cnt            : NATURAL := 0;   -- count blocks per sync interval
   
   -- Output
+  SIGNAL raw_sosi_arr           : t_dp_sosi_arr(0 DOWNTO 0);
   SIGNAL out_sosi_arr           : t_dp_sosi_arr(0 DOWNTO 0);
   SIGNAL out_sosi               : t_dp_sosi;
   SIGNAL out_re                 : INTEGER;
@@ -372,7 +373,8 @@ BEGIN
       ram_fil_coefs_miso => ram_fil_coefs_miso,
       in_sosi_arr        => in_sosi_arr,
       fil_sosi_arr       => fil_sosi_arr,
-      out_sosi_arr       => out_sosi_arr
+      out_quant_sosi_arr => out_sosi_arr,
+      out_raw_sosi_arr   => raw_sosi_arr
     );
   END GENERATE;
   
diff --git a/libraries/dsp/verify_pfb/tb_verify_pfb_wg.vhd b/libraries/dsp/verify_pfb/tb_verify_pfb_wg.vhd
index 326e370deb..ae037d7590 100644
--- a/libraries/dsp/verify_pfb/tb_verify_pfb_wg.vhd
+++ b/libraries/dsp/verify_pfb/tb_verify_pfb_wg.vhd
@@ -486,6 +486,7 @@ ARCHITECTURE tb OF tb_verify_pfb_wg IS
   SIGNAL wpfb_measured_proc_gain_b_dB : REAL := 0.0;
   
   -- Output
+  SIGNAL raw_sosi_arr           : t_dp_sosi_arr(0 DOWNTO 0);
   SIGNAL out_sosi_arr           : t_dp_sosi_arr(0 DOWNTO 0);
   SIGNAL out_sosi               : t_dp_sosi;
   SIGNAL out_re                 : INTEGER;
@@ -1136,7 +1137,8 @@ BEGIN
       ram_st_sst_miso    => ram_st_sst_miso,
       in_sosi_arr        => in_sosi_arr,
       fil_sosi_arr       => fil_sosi_arr,
-      out_sosi_arr       => out_sosi_arr
+      out_quant_sosi_arr => out_sosi_arr,
+      out_raw_sosi_arr   => raw_sosi_arr
     );
   END GENERATE;
   
diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd
index 2bfba7f1b1..65fce12b0a 100644
--- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd
+++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit.vhd
@@ -315,14 +315,14 @@ begin
           g_pipeline => g_wpfb.fft_pipeline
         )
         port map(
-          clk       => dp_clk,
-          rst       => dp_rst,
-          in_re     => fft_in_re_arr(I)(c_fft.in_dat_w-1 downto 0),
-          in_im     => fft_in_im_arr(I)(c_fft.in_dat_w-1 downto 0),
-          in_val    => fft_in_val,
-          out_re    => fft_out_re_arr_i(I)(c_fft.out_dat_w-1 downto 0),
-          out_im    => fft_out_im_arr_i(I)(c_fft.out_dat_w-1 downto 0),
-          out_val   => fft_out_val(I)
+          clk           => dp_clk,
+          rst           => dp_rst,
+          in_re         => fft_in_re_arr(I)(c_fft.in_dat_w-1 downto 0),
+          in_im         => fft_in_im_arr(I)(c_fft.in_dat_w-1 downto 0),
+          in_val        => fft_in_val,
+          out_quant_re  => fft_out_re_arr_i(I)(c_fft.out_dat_w-1 downto 0),
+          out_quant_im  => fft_out_im_arr_i(I)(c_fft.out_dat_w-1 downto 0),
+          out_val       => fft_out_val(I)
         );
         fft_out_re_arr(I) <= RESIZE_SVEC(fft_out_re_arr_i(I)(c_fft.out_dat_w-1 downto 0), fft_out_re_arr(I)'length);
         fft_out_im_arr(I) <= RESIZE_SVEC(fft_out_im_arr_i(I)(c_fft.out_dat_w-1 downto 0), fft_out_im_arr(I)'length);
diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
index 66342d6c93..f859148e0c 100644
--- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
+++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd
@@ -96,26 +96,24 @@
 --   . P = wideband factor index
 --   . t = time index
 --
---                    parallel                           serial   type
---   in_sosi_arr      [nof_streams][wb_factor]           [t]      cint
+--                          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_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
+--   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_quant_re_arr   [nof_streams][wb_factor]           [bin]     int
+--   fft_out_quant_im_arr   [nof_streams][wb_factor]           [bin]     int
+--   pfb_out_quant_sosi_arr [nof_streams][wb_factor]           [bin]    cint with sync, BSN, sop, eop
+--   out_quant_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_quant_re_arr
+--   fil_sosi_arr | fil_out_arr | fft_in_im_arr | fft_out_quant_im_arr
+--                |             |               | pfb_out_quant_sosi_arr
+--                |             |               |     out_quant_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          
@@ -162,7 +160,7 @@
 -- I) Wideband wb_factor = 4
 -- 1) Two real inputs:
 -- 
---   out_sosi_arr:
+--   out_quant_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               
@@ -189,7 +187,7 @@
 --
 -- 2a) Complex input with fft_shift:
 -- 
---   out_sosi_arr:
+--   out_quant_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               
@@ -214,7 +212,7 @@
 --
 -- 2b) Complex input with reorder, but no fft_shift:
 -- 
---   out_sosi_arr:
+--   out_quant_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               
@@ -239,7 +237,7 @@
 --
 -- 2c) Complex input without reorder (so bit flipped):
 -- 
---   out_sosi_arr:
+--   out_quant_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               
@@ -276,7 +274,7 @@
 --     - input A via in_sosi_arr().re
 --     - input B via in_sosi_arr().im
 --
---   out_sosi_arr:
+--   out_quant_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
@@ -299,7 +297,7 @@
 
 -- 2a) Complex input with fft_shift (so use_reorder = true, use_fft_shift = true)
 -- 
---   out_sosi_arr:
+--   out_quant_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
@@ -312,7 +310,7 @@
 --
 -- 2b) Complex input with reorder but no fft_shift (so use_reorder = true, use_fft_shift = false)
 -- 
---   out_sosi_arr:
+--   out_quant_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
@@ -325,7 +323,7 @@
 --
 -- 2c) Complex input without reorder (so use_reorder = false, use_fft_shift = false)
 -- 
---   out_sosi_arr:
+--   out_quant_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
@@ -382,7 +380,8 @@ entity wpfb_unit_dev is
     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);
+    out_quant_sosi_arr    : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
+    out_raw_sosi_arr      : out t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
     dp_bsn_source_restart : in  std_logic := '0'
   );
 end entity wpfb_unit_dev;
@@ -440,15 +439,15 @@ architecture str of wpfb_unit_dev is
   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_quant_re_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
+  signal fft_out_quant_im_arr_i    : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
+  signal fft_out_quant_re_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
+  signal fft_out_quant_im_arr      : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
+  signal fft_out_raw_re_arr        : t_fft_slv_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0);
+  signal fft_out_raw_im_arr        : 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 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);
+  signal pfb_out_quant_sosi_arr    : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst);
   signal ctrl_pfb_out_sosi   : t_dp_sosi := c_dp_sosi_rst;
   
   type reg_type is record
@@ -586,8 +585,8 @@ begin
           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_re_arr => fft_out_quant_re_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
+          out_im_arr => fft_out_quant_im_arr((S+1)*g_wpfb.wb_factor-1 downto S*g_wpfb.wb_factor),
           out_val    => fft_out_val_arr(S)
         );
       end generate;
@@ -606,18 +605,20 @@ begin
           g_dont_flip_channels => g_dont_flip_channels
         )
         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)
+          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_quant_re  => fft_out_quant_re_arr_i(S)(c_fft.out_dat_w-1 downto 0),
+          out_quant_im  => fft_out_quant_im_arr_i(S)(c_fft.out_dat_w-1 downto 0),
+          out_raw_re    => fft_out_raw_re_arr(S),
+          out_raw_im    => fft_out_raw_im_arr(S),
+          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));
+        fft_out_quant_re_arr(S) <= RESIZE_SVEC_32(fft_out_quant_re_arr_i(S)(c_fft.out_dat_w-1 downto 0));
+        fft_out_quant_im_arr(S) <= RESIZE_SVEC_32(fft_out_quant_im_arr_i(S)(c_fft.out_dat_w-1 downto 0));
       end generate;
     end generate;
 
@@ -642,14 +643,26 @@ begin
       out_sosi    => ctrl_pfb_out_sosi
     );
 
-    wire_pfb_out_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate
-      pfb_out_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(fft_out_re_arr(I));
-      pfb_out_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(fft_out_im_arr(I));
-      pfb_out_sosi_arr(I).valid <= ctrl_pfb_out_sosi.valid;
-      pfb_out_sosi_arr(I).sync  <= ctrl_pfb_out_sosi.sync;
-      pfb_out_sosi_arr(I).bsn   <= ctrl_pfb_out_sosi.bsn;
-      pfb_out_sosi_arr(I).sop   <= ctrl_pfb_out_sosi.sop;
-      pfb_out_sosi_arr(I).eop   <= ctrl_pfb_out_sosi.eop;
+    -- wire pfb_out_quant_sosi_arr that is used for SST and 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));
+      pfb_out_quant_sosi_arr(I).valid <= ctrl_pfb_out_sosi.valid;
+      pfb_out_quant_sosi_arr(I).sync  <= ctrl_pfb_out_sosi.sync;
+      pfb_out_quant_sosi_arr(I).bsn   <= ctrl_pfb_out_sosi.bsn;
+      pfb_out_quant_sosi_arr(I).sop   <= ctrl_pfb_out_sosi.sop;
+      pfb_out_quant_sosi_arr(I).eop   <= ctrl_pfb_out_sosi.eop;
+    end generate;
+
+    -- directly wire out_raw_sosi_arr
+    wire_out_raw_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate
+      out_raw_sosi_arr(I).re    <= RESIZE_DP_DSP_DATA(fft_out_raw_re_arr(I));
+      out_raw_sosi_arr(I).im    <= RESIZE_DP_DSP_DATA(fft_out_raw_im_arr(I));
+      out_raw_sosi_arr(I).valid <= ctrl_pfb_out_sosi.valid;
+      out_raw_sosi_arr(I).sync  <= ctrl_pfb_out_sosi.sync;
+      out_raw_sosi_arr(I).bsn   <= ctrl_pfb_out_sosi.bsn;
+      out_raw_sosi_arr(I).sop   <= ctrl_pfb_out_sosi.sop;
+      out_raw_sosi_arr(I).eop   <= ctrl_pfb_out_sosi.eop;
     end generate;
   end generate;
 
@@ -678,7 +691,7 @@ begin
       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
+      out_sosi_arr     => pfb_out_quant_sosi_arr
     );
   end generate;
 
@@ -706,7 +719,7 @@ begin
           mm_clk          => mm_clk,
           dp_rst          => dp_rst,
           dp_clk          => dp_clk,
-          in_complex      => pfb_out_sosi_arr(S*g_wpfb.wb_factor+P),
+          in_complex      => pfb_out_quant_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)
         );
@@ -715,7 +728,7 @@ begin
   end generate;
 
   -- Connect to the outside world
-  out_sosi_arr <= pfb_out_sosi_arr;
+  out_quant_sosi_arr <= pfb_out_quant_sosi_arr;
 
 end str;
 
diff --git a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd
index f789359e1d..07485ee366 100644
--- a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd
+++ b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_dev.vhd
@@ -330,7 +330,8 @@ BEGIN
     ram_bg_data_mosi   => ram_diag_bg_pfb_mosi,
     ram_bg_data_miso   => ram_diag_bg_pfb_miso,
     in_sosi_arr        => bg_sosi_arr,     
-    out_sosi_arr       => out_sosi_arr
+    out_quant_sosi_arr => out_sosi_arr,
+    out_raw_sosi_arr   => open
   ); 
 
   time_map : process is
diff --git a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd
index d385e8f7cf..caa83e1592 100644
--- a/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd
+++ b/libraries/dsp/wpfb/tb/vhdl/tb_wpfb_unit_wide.vhd
@@ -486,7 +486,8 @@ begin
     ram_bg_data_miso   => open,
     in_sosi_arr        => in_sosi_arr,
     fil_sosi_arr       => fil_sosi_arr,
-    out_sosi_arr       => out_sosi_arr
+    out_quant_sosi_arr => out_sosi_arr,
+    out_raw_sosi_arr   => open
   );
   
   p_fil_sosi_arr : process(fil_sosi_arr)
-- 
GitLab