From 017d5ce67f9324b661ceffde1d8465928c05a8bb Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Thu, 3 Feb 2022 15:19:52 +0100
Subject: [PATCH] Added manual verification of g_subband_phase in wave window
 via pfb_sosi_arr and fsub_sosi_arr.

---
 .../tb_lofar2_unb2b_sdp_station_fsub.vhd      | 94 ++++++++++++++++---
 1 file changed, 83 insertions(+), 11 deletions(-)

diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd
index 49fb425c86..b55c9c6142 100644
--- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd
+++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd
@@ -33,11 +33,20 @@
 --   2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg 
 --      to trigger start of WG at BSN.
 --     
---   3) Read subband statistics (SST) via ram_st_sst and verify with 
---      c_exp_subband_power at g_subband.
---      View sp_subband_power in Wave window
---   
+--   3) Read subband statistics (SST) via MM and verify with c_exp_subband_power at g_subband.
+--      . use weighted subbands (default selected by MM)
 --
+--   4) View in wave window
+--      . in_sosi.sop and in_data in u_si_arr(g_sp) to check that:
+--        - WG starts with zero phase sine when c_subband_phase = 0.0 degrees
+--        - WG amplitude = 8191 (is full scale - 1) when wg_ampl = 1.0
+--      . pfb_sosi_arr(c_pfb_index).im/re and fsub_sosi_arr(c_pfb_index).im/re
+--        in u_fsub in decimal radix and analog format to check that subband
+--        phase is g_subband_phase phase as set by the subband weight.
+--        - Raw: pfb_sosi_arr = atan2(-65195 / 0) = -90 degrees
+--        - Weighted: fsub_sosi_arr = atan2(-56457 / 32598) = -60 degrees
+--          --> rotated expected g_subband_phase = -60 - -90 = +30 degrees.
+--   
 -- Usage:
 --   > as 7    # default
 --   > as 12   # for detailed debugging
@@ -62,8 +71,11 @@ USE unb2b_board_lib.unb2b_board_pkg.ALL;
 
 ENTITY tb_lofar2_unb2b_sdp_station_fsub IS
   GENERIC (
-    g_sp           : NATURAL := 3;    -- signal path index in range(S_pn = 12)
-    g_subband      : NATURAL := 102   -- select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
+    g_sp                : NATURAL := 3;    -- signal path index in range(S_pn = 12)
+    g_wg_ampl           : REAL := 1.0;     -- WG normalized amplitude
+    g_subband           : NATURAL := 102;  -- select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
+    g_subband_gain      : REAL := 1.0;     -- subband weight normalized gain
+    g_subband_phase     : REAL := 30.0     -- subband weight phase rotation in degrees
   );
 END tb_lofar2_unb2b_sdp_station_fsub;
 
@@ -99,14 +111,19 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
   -- .ampl
   CONSTANT c_wg_ampl_full_scale   : NATURAL := 2**(c_sdp_W_adc-1);  -- full scale (FS) of WG, will just cause clipping of +FS to +FS-1
   CONSTANT c_wg_ampl_lsb          : REAL := c_diag_wg_ampl_unit / REAL(c_wg_ampl_full_scale);  -- amplitude in number of LSbit resolution steps
-  CONSTANT c_wg_ampl              : NATURAL := c_wg_ampl_full_scale / 1;  -- in number of lsb
+  CONSTANT c_wg_ampl              : NATURAL := NATURAL(g_wg_ampl * REAL(c_wg_ampl_full_scale));  -- in number of lsb
   CONSTANT c_exp_wg_power_sp      : REAL := REAL(c_wg_ampl**2)/2.0 * REAL(c_nof_clk_per_sync);
-   -- . phase
-  CONSTANT c_wg_phase             : REAL := 0.0;  -- phase offset in degrees
+  -- . phase
+  CONSTANT c_subband_phase        : REAL := 0.0;  -- wanted subband phase in degrees = WG phase at sop
+  CONSTANT c_subband_freq         : REAL := REAL(g_subband) / REAL(c_sdp_N_fft);                   -- normalized by fs = f_adc = 200 MHz is dp_clk
+  CONSTANT c_wg_latency           : INTEGER := c_diag_wg_latency - 0;  -- -0 to account for BSN scheduler start trigger latency
+  CONSTANT c_wg_phase_offset      : REAL := 360.0 * REAL(c_wg_latency) * c_subband_freq;  -- c_diag_wg_latency is in dp_clk cycles
+  CONSTANT c_wg_phase             : REAL := c_subband_phase + c_wg_phase_offset;  -- WG phase in degrees
   -- . freq
   CONSTANT c_wg_subband_freq_unit : REAL := c_diag_wg_freq_unit/REAL(c_sdp_N_fft);  -- subband freq = Fs/1024 = 200 MSps/1024 = 195312.5 Hz sinus
 
-  -- WPFB
+  -- FSUB
+  -- . WPFB
   CONSTANT c_pol_index                      : NATURAL := g_sp MOD c_sdp_Q_fft;
   CONSTANT c_pfb_index                      : NATURAL := g_sp / c_sdp_Q_fft;  -- only read used WPFB unit out of range(c_sdp_P_pfb = 6)
   CONSTANT c_exp_subband_sp_power_ratio     : REAL := 1.0/8.0;   -- subband power / SP power, depends on internal WPFB quantization and FIR coefficients
@@ -115,6 +132,15 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
   TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL; 
   TyPE t_slv_64_subbands_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_sub-1);
 
+  -- . Subband weights for selected g_sp
+  CONSTANT c_subband_weight_re   : INTEGER := INTEGER(g_subband_gain * REAL(c_sdp_unit_sub_weight) * COS(g_subband_phase * MATH_2_PI / 360.0));
+  CONSTANT c_subband_weight_im   : INTEGER := INTEGER(g_subband_gain * REAL(c_sdp_unit_sub_weight) * SIN(g_subband_phase * MATH_2_PI / 360.0));
+
+  SIGNAL sp_subband_weight_re    : INTEGER := 0;
+  SIGNAL sp_subband_weight_im    : INTEGER := 0;
+  SIGNAL sp_subband_weight_gain  : REAL := 0.0;
+  SIGNAL sp_subband_weight_phase : REAL := 0.0;
+
   -- MM  
   -- . Address widths of a single MM instance
   CONSTANT c_addr_w_reg_diag_wg           : NATURAL := 2;
@@ -124,6 +150,8 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
   CONSTANT c_mm_file_reg_bsn_source_v2    : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
   CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER";
   CONSTANT c_mm_file_reg_diag_wg          : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG";
+  CONSTANT c_mm_file_ram_equalizer_gains  : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_EQUALIZER_GAINS";
+  CONSTANT c_mm_file_reg_dp_selector      : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_SELECTOR";
   CONSTANT c_mm_file_ram_st_sst           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST";
 
   -- Tb
@@ -138,7 +166,8 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
   -- WG
   SIGNAL current_bsn_wg      : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
 
-  -- WPFB
+  -- FSUB
+  -- . WPFB
   SIGNAL sp_subband_powers_arr2            : t_slv_64_subbands_arr(c_sdp_N_pol-1 DOWNTO 0);   -- [pol][sub]
   SIGNAL sp_subband_power_sum_arr          : t_real_arr(c_sdp_N_pol-1 DOWNTO 0) := (OTHERS => 0.0);
   SIGNAL sp_subband_power                  : REAL := 0.0;
@@ -151,6 +180,9 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
   CONSTANT c_exp_subband_power_leakage_snr_dB   : REAL := 75.0;  -- < 76.372
   CONSTANT c_exp_subband_power_crosstalk_snr_dB : REAL := 95.0;  -- < 96.284
 
+  -- . Selector
+  SIGNAL sst_offload_weighted_subbands     : STD_LOGIC;
+
   -- DUT
   SIGNAL ext_clk             : STD_LOGIC := '0';
   SIGNAL ext_pps             : STD_LOGIC := '0';
@@ -262,6 +294,7 @@ BEGIN
     VARIABLE v_stat_data                  : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0);
     VARIABLE v_len, v_span, v_offset, v_A : NATURAL;  -- address ranges, indices
     VARIABLE v_W, v_P, v_U, v_S, v_B      : NATURAL;  -- array indicies
+    VARIABLE v_re, v_im, v_int            : INTEGER;
     VARIABLE v_power                      : REAL;
   BEGIN
     -- Wait for DUT power up after reset
@@ -279,6 +312,10 @@ BEGIN
     WAIT FOR 1 us;
     pps_rst <= '0';
 
+    mmf_mm_bus_rd(c_mm_file_reg_dp_selector, 0, rd_data, tb_clk);
+    proc_common_wait_some_cycles(tb_clk, 1);
+    sst_offload_weighted_subbands <= NOT rd_data(0);
+
     ----------------------------------------------------------------------------
     -- Enable and start WG
     ----------------------------------------------------------------------------
@@ -304,6 +341,33 @@ BEGIN
     mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, c_bsn_start_wg, tb_clk);  -- first write low then high part
     mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1,              0, tb_clk);  -- assume v_bsn < 2**31-1
 
+    ----------------------------------------------------------------------------
+    -- Write subband weight for selected g_sp and g_subband
+    ----------------------------------------------------------------------------
+    -- . MM format: (cint16)subband_weights[S_pn/Q_fft]_[Q_fft][N_sub] = [S_pn][N_sub]
+    v_A := g_sp * c_sdp_N_sub + g_subband;
+    -- . read
+    mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains, v_A, rd_data, tb_clk);
+    proc_common_wait_some_cycles(tb_clk, 1);
+    v_re := unpack_complex_re(rd_data, c_sdp_W_bf_weight);
+    v_im := unpack_complex_im(rd_data, c_sdp_W_bf_weight);
+    sp_subband_weight_re <= v_re;
+    sp_subband_weight_im <= v_im;
+    sp_subband_weight_gain  <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_sub_weight);
+    sp_subband_weight_phase <= ARCTAN(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI;
+    -- . write
+    v_int := pack_complex(c_subband_weight_re, c_subband_weight_im, c_sdp_W_bf_weight);  -- c_sdp_W_bf_weight = 16 bit
+    mmf_mm_bus_wr(c_mm_file_ram_equalizer_gains, v_A, v_int, tb_clk);
+    -- . read back
+    mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains, v_A, rd_data, tb_clk);
+    proc_common_wait_some_cycles(tb_clk, 1);
+    v_re := unpack_complex_re(rd_data, c_sdp_W_bf_weight);
+    v_im := unpack_complex_im(rd_data, c_sdp_W_bf_weight);
+    sp_subband_weight_re <= v_re;
+    sp_subband_weight_im <= v_im;
+    sp_subband_weight_gain  <= SQRT(REAL(v_re)**2.0 + REAL(v_im)**2.0) / REAL(c_sdp_unit_sub_weight);
+    sp_subband_weight_phase <= ARCTAN(Y => REAL(v_im), X => REAL(v_re)) * 360.0 / MATH_2_PI;
+
     ----------------------------------------------------------------------------
     -- Wait for enough WG data and start of sync interval
     ----------------------------------------------------------------------------
@@ -382,6 +446,14 @@ BEGIN
     ---------------------------------------------------------------------------
     -- Print subband statistics
     ---------------------------------------------------------------------------
+    -- Selector
+    print_str("sst_offload_weighted_subbands      = " & sl_to_str(sst_offload_weighted_subbands));
+
+    -- Subband weight
+    print_str("sp_subband_weight_gain             = " & real_to_str(sp_subband_weight_gain, 20, 6));
+    print_str("sp_subband_weight_phase            = " & real_to_str(sp_subband_weight_phase, 20, 6));
+
+    -- SST
     print_str("sp_subband_power                   = " & real_to_str(sp_subband_power, 20, 0));
 
     -- WPFB details are allready verified in tb of wpfb_unit_dev.vhd, so here
-- 
GitLab