From 1e86f270fc5e294dea7791237d6f22d57b9c598d Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Tue, 19 Apr 2022 16:22:42 +0200
Subject: [PATCH] Verify c_exp_subband_xst using almost_equal() and
 almost_zero().

---
 .../tb_lofar2_unb2c_sdp_station_xsub_one.vhd  | 57 +++++++++++--------
 1 file changed, 32 insertions(+), 25 deletions(-)

diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one.vhd
index 4a77882eef..2774f8ae02 100644
--- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one.vhd
+++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_xsub_one/tb_lofar2_unb2c_sdp_station_xsub_one.vhd
@@ -34,15 +34,16 @@
 --      to trigger start of WG at BSN.
 --     
 --   3) Read crosslets statistics (XST) via ram_st_xsq and verify that the values
---      are as expected. This is done by comparing the values in the outgoing square
---      correlation matrix.
---         
+--      are as expected. This is done by:
+--      . comparing the values in the outgoing square correlation matrix, they
+--        should all be almost equal because all signal inputs use same WG
+--      . comparing with expected XST value c_exp_subband_xst
 --
 -- Usage:
 --   > as 7    # default
 --   > as 12   # for detailed debugging
 --   > run -a  
---   Takes about 40 m
+--   Takes about 45 m
 --
 -------------------------------------------------------------------------------
 LIBRARY IEEE, common_lib, unb2c_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, lofar2_unb2c_sdp_station_lib;
@@ -78,32 +79,28 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_xsub_one IS
 
   CONSTANT c_tb_clk_period       : TIME := 100 ps; -- use fast tb_clk to speed up M&C
 
-  CONSTANT c_nof_block_per_sync  : NATURAL := 24;
+  CONSTANT c_nof_block_per_sync  : NATURAL := 20;
   CONSTANT c_nof_clk_per_sync    : NATURAL := c_nof_block_per_sync*c_sdp_N_fft; 
   CONSTANT c_pps_period          : NATURAL := c_nof_clk_per_sync;
   CONSTANT c_wpfb_sim            : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync);
   CONSTANT c_ctrl_interval_size  : NATURAL := c_nof_clk_per_sync;
 
-  CONSTANT c_percentage          : REAL := 0.05;  -- percentage that actual value may differ from expected value
-  CONSTANT c_lo_factor           : REAL := 1.0 - c_percentage;  -- lower boundary  
-  CONSTANT c_hi_factor           : REAL := 1.0 + c_percentage;  -- higher boundary
+  CONSTANT c_max_ratio           : REAL := 0.0001;  -- ratio that actual value may differ from expected value
 
   -- WG
   CONSTANT c_bsn_start_wg         : NATURAL := 2;  -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values
-  CONSTANT c_ampl_sp_0            : NATURAL := c_sdp_FS_adc/2;  -- = 0.5 * FS, so in number of lsb
+  CONSTANT c_sp_ampl              : REAL := 0.5;   -- WG normalized amplitude, 1.0 = FS (full scale), use <= 0.5 to avoid XST overflow
+  CONSTANT c_wg_ampl              : NATURAL := NATURAL(c_sp_ampl * REAL(c_sdp_FS_adc));  -- in number of lsb
   CONSTANT c_wg_freq_offset       : REAL := 0.0/11.0; -- in freq_unit
-  CONSTANT c_subband_sp_0         : REAL := 102.0;  -- Select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
-  CONSTANT c_exp_wg_power_sp_0    : REAL := REAL(c_ampl_sp_0**2)/2.0 * REAL(c_nof_clk_per_sync);
+  CONSTANT c_subband_sp           : REAL := 102.0;  -- Select subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz
 
   -- WPFB
-  CONSTANT c_exp_subband_ampl_raw           : REAL := REAL(c_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio;
-  CONSTANT c_exp_subband_ampl_weighted      : REAL := c_exp_subband_ampl_raw * g_subband_weight_gain;
-  CONSTANT c_exp_subband_power_raw          : REAL := c_exp_subband_ampl_raw**2.0;  -- complex, so no divide by 2
-  CONSTANT c_exp_subband_power_weighted     : REAL := c_exp_subband_ampl_weighted**2.0;  -- complex, so no divide by 2
-  CONSTANT c_exp_subband_sst_raw            : REAL := c_exp_subband_power_raw * REAL(c_nof_block_per_sync);
-  CONSTANT c_exp_subband_sst_weighted       : REAL := c_exp_subband_power_weighted * REAL(c_nof_block_per_sync);
+  CONSTANT c_exp_subband_ampl     : REAL := REAL(c_wg_ampl) * c_sdp_wpfb_subband_sp_ampl_ratio;
+  CONSTANT c_exp_subband_power    : REAL := c_exp_subband_ampl**2.0;  -- complex, so no divide by 2
+  CONSTANT c_exp_subband_sst      : REAL := c_exp_subband_power * REAL(c_nof_block_per_sync);
+  CONSTANT c_exp_subband_xst      : REAL := c_exp_subband_sst;  -- all signal inputs use same WG, and auto correlation XST = SST
 
-  TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL; 
+  TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL;
 
   -- MM  
   CONSTANT c_mm_file_reg_bsn_source_v2           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2";
@@ -180,7 +177,7 @@ BEGIN
     g_sim_node_nr            => c_node_nr,
     g_wpfb                   => c_wpfb_sim,
     g_bsn_nof_clk_per_sync   => c_nof_clk_per_sync,
-    g_scope_selected_subband => NATURAL(c_subband_sp_0)
+    g_scope_selected_subband => NATURAL(c_subband_sp)
   )
   PORT MAP (
     -- GENERAL
@@ -240,8 +237,8 @@ BEGIN
     ----------------------------------------------------------------------------
     -- Crosslets Info
     ----------------------------------------------------------------------------  
-    mmf_mm_bus_wr(c_mm_file_reg_crosslets_info, 0,  INTEGER(c_subband_sp_0), tb_clk); -- offset
-    mmf_mm_bus_wr(c_mm_file_reg_crosslets_info, 15, 0                      , tb_clk); -- stepsize
+    mmf_mm_bus_wr(c_mm_file_reg_crosslets_info, 0,  INTEGER(c_subband_sp), tb_clk); -- offset
+    mmf_mm_bus_wr(c_mm_file_reg_crosslets_info, 15, 0                    , tb_clk); -- stepsize
 
     ----------------------------------------------------------------------------
     -- Enable WG
@@ -254,8 +251,8 @@ BEGIN
     FOR I IN 0 TO c_sdp_S_pn-1 LOOP
       mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 0, 1024*2**16 + 1, tb_clk);  -- nof_samples, mode calc
       mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 1, INTEGER(0.0 * c_diag_wg_phase_unit), tb_clk);  -- phase offset in degrees
-      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 2, INTEGER((c_subband_sp_0 + c_wg_freq_offset) * c_sdp_wg_subband_freq_unit), tb_clk);  -- freq
-      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 3, INTEGER(REAL(c_ampl_sp_0) * c_sdp_wg_ampl_lsb), tb_clk);  -- ampl
+      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 2, INTEGER((c_subband_sp + c_wg_freq_offset) * c_sdp_wg_subband_freq_unit), tb_clk);  -- freq
+      mmf_mm_bus_wr(c_mm_file_reg_diag_wg, I*4 + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk);  -- ampl
     END LOOP;
 
     -- Read current BSN
@@ -277,7 +274,7 @@ BEGIN
 
     -- Wait for enough WG data and start of sync interval
     mmf_mm_wait_until_value(c_mm_file_reg_bsn_scheduler_wg, 0,                    -- read BSN low
-                            "UNSIGNED", rd_data, ">=", c_nof_block_per_sync * 2,  -- this is the wait until condition
+                            "UNSIGNED", rd_data, ">=", c_nof_block_per_sync * 3,  -- this is the wait until condition
                             c_sdp_T_sub, tb_clk);
 
     ---------------------------------------------------------------------------
@@ -341,7 +338,17 @@ BEGIN
 
       -- Check if values are > 0
       IF v_C=0 THEN ASSERT (SIGNED(xsub_stats_arr(I)) > TO_SIGNED(0, c_longword_w)) REPORT "correlation is 0 which is unexpected! at I = " & int_to_str(I) SEVERITY ERROR; END IF;
-    END LOOP; 
+
+      -- All XST values (almost) equal, because they use the same WG setting.
+      -- therefore also verify the expected XST value for all XST.
+      IF I MOD c_nof_complex = 0 THEN
+        -- real part
+        ASSERT almost_equal(TO_SREAL(xsub_stats_arr(I)) / c_exp_subband_xst, 1.0, c_max_ratio) REPORT "Wrong XST real value at I = " & int_to_str(I) SEVERITY ERROR;
+      ELSE
+        -- imag part
+        ASSERT almost_zero(TO_SREAL(xsub_stats_arr(I)) / c_exp_subband_xst, c_max_ratio) REPORT "Wrong XST imag value at I = " & int_to_str(I) SEVERITY ERROR;
+      END IF;
+    END LOOP;
  
     ---------------------------------------------------------------------------
     -- End Simulation 
-- 
GitLab