From d60e646253ad0d0e430621d31a25bdf31f821df0 Mon Sep 17 00:00:00 2001
From: Reinier van der Walle <walle@astron.nl>
Date: Tue, 8 Dec 2020 09:38:28 +0100
Subject: [PATCH] Processed review comments

---
 .../tb/vhdl/tb_lofar2_unb2b_beamformer.vhd    | 303 +++++++++++-------
 1 file changed, 196 insertions(+), 107 deletions(-)

diff --git a/applications/lofar2/designs/lofar2_unb2b_beamformer/tb/vhdl/tb_lofar2_unb2b_beamformer.vhd b/applications/lofar2/designs/lofar2_unb2b_beamformer/tb/vhdl/tb_lofar2_unb2b_beamformer.vhd
index 0411a85bb6..33d323da64 100644
--- a/applications/lofar2/designs/lofar2_unb2b_beamformer/tb/vhdl/tb_lofar2_unb2b_beamformer.vhd
+++ b/applications/lofar2/designs/lofar2_unb2b_beamformer/tb/vhdl/tb_lofar2_unb2b_beamformer.vhd
@@ -33,15 +33,13 @@
 --   2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg 
 --      to trigger start of WG at BSN.
 --     
---   3) Read WG data via ram_aduh_mon into sp_sample and replay sp_sample for
---      analogue view in Wave window:
+--   3) Read subband statistics (SST)
 --   
---   4) Read ADUH monitor power sum for via reg_aduh_mon and verify with 
---      c_exp_wg_power_sp_0.
---      View sp_power_sum in Wave window
---   5) Read beamlet statistics (BST) via ram_st_bst and verify with 
---      c_exp_subband_power_sp_0 at c_sdp_N_sub-1 - c_subband_sp_0.
---      View sp_subband_power_0  in Wave window
+--   4) Read beamlet statistics (BST) via ram_st_bst and verify with 
+--      c_exp_beamlet_power_sp_0 at c_sdp_N_sub-1 - c_subband_sp_0.
+--      View sp_beamlet_power_0  in Wave window
+--   5) Compare SST with BST.
+--   6) Verify 10GbE output.
 --   
 --
 -- Usage:
@@ -50,7 +48,7 @@
 --   > run -a  
 --
 -------------------------------------------------------------------------------
-LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, tech_pll_lib;
+LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, tech_pll_lib, tr_10GbE_lib;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
 USE IEEE.MATH_REAL.ALL;
@@ -106,9 +104,9 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_beamformer IS
 
   -- WPFB
   CONSTANT c_wb_leakage_bin                 : NATURAL := c_wpfb_sim.nof_points / c_wpfb_sim.wb_factor;   -- = 256, leakage will occur in this bin if FIR wb_factor is reversed 
-  CONSTANT c_exp_sp_subband_power_ratio     : REAL := 1.0/8.0;   -- depends on internal WPFB quantization and FIR coefficients
-  CONSTANT c_exp_sp_subband_power_sum_ratio : REAL := c_exp_sp_subband_power_ratio;   -- because all sinus power is expected in one subband
-  CONSTANT c_exp_subband_power_sp_0         : REAL := c_exp_wg_power_sp_0 * c_exp_sp_subband_power_ratio;
+  CONSTANT c_exp_sp_beamlet_power_ratio     : REAL := 1.0/8.0;   -- depends on internal WPFB quantization and FIR coefficients
+  CONSTANT c_exp_sp_beamlet_power_sum_ratio : REAL := c_exp_sp_beamlet_power_ratio;   -- because all sinus power is expected in one subband
+  CONSTANT c_exp_beamlet_power_sp_0         : REAL := c_exp_wg_power_sp_0 * c_exp_sp_beamlet_power_ratio;
 
   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_S_sub_bf);
@@ -126,7 +124,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_beamformer IS
   CONSTANT c_mm_file_ram_aduh_mon         : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ADUH_MONITOR";
   CONSTANT c_mm_file_ram_st_bst           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_BST";
   CONSTANT c_mm_file_reg_dp_xonoff        : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_XONOFF";
-
+  CONSTANT c_mm_file_ram_st_sst           : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST";
 
   -- Tb
   SIGNAL tb_end              : STD_LOGIC := '0';
@@ -143,18 +141,31 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_beamformer IS
 
   -- WPFB
   SIGNAL sp_subband_powers_arr2         : t_slv_64_subbands_arr(c_sdp_N_beamsets*c_sdp_N_pol-1 DOWNTO 0);   -- [sp][sub]
-  SIGNAL sp_subband_power_0             : REAL;
-  SIGNAL sp_subband_power_sum           : t_real_arr(c_sdp_N_beamsets*c_sdp_N_pol-1 DOWNTO 0) := (OTHERS=>0.0);
-  SIGNAL sp_subband_power_sum_0         : REAL;
-  SIGNAL sp_subband_power_ratio_0       : REAL;
-  SIGNAL sp_subband_power_sum_ratio_0   : REAL;
-  SIGNAL sp_subband_power_leakage_sum_0 : REAL;
-  
+
+  SIGNAL sp_beamlet_powers_arr2         : t_slv_64_subbands_arr(c_sdp_N_beamsets*c_sdp_N_pol-1 DOWNTO 0);   -- [sp][sub]
+  SIGNAL sp_beamlet_power_0             : REAL;
+  SIGNAL sp_beamlet_power_sum           : t_real_arr(c_sdp_N_beamsets*c_sdp_N_pol-1 DOWNTO 0) := (OTHERS=>0.0);
+  SIGNAL sp_beamlet_power_sum_0         : REAL;
+  SIGNAL sp_beamlet_power_ratio_0       : REAL;
+  SIGNAL sp_beamlet_power_sum_ratio_0   : REAL;
+  SIGNAL sp_beamlet_power_leakage_sum_0 : REAL;
+
+  -- 10GbE
+  CONSTANT c_exp_beamlet_index : NATURAL := NATURAL(c_subband_sp_0) * c_sdp_N_pol;
+  CONSTANT c_exp_beamlet : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"7F81"; --Derived from simulation
+
+  SIGNAL beamlet_arr2 : t_slv_16_arr(c_sdp_cep_nof_beamlets_per_block-1 DOWNTO 0);
+
+  SIGNAL tr_10GbE_src_out       : t_dp_sosi;
+  SIGNAL tr_ref_clk_312         : STD_LOGIC := '0';
+  SIGNAL tr_ref_clk_156         : STD_LOGIC := '0';
+  SIGNAL tr_ref_rst_156         : STD_LOGIC := '0';
+
   -- DUT
   SIGNAL ext_clk             : STD_LOGIC := '0';
   SIGNAL pps                 : STD_LOGIC := '0';
   SIGNAL ext_pps             : STD_LOGIC := '0'; 
-  SIGNAL pps_rst             : STD_LOGIC := '0';
+  SIGNAL pps_rst             : STD_LOGIC := '1';
 
   SIGNAL WDI                 : STD_LOGIC;
   SIGNAL INTA                : STD_LOGIC;
@@ -189,6 +200,7 @@ BEGIN
   eth_clk <= NOT eth_clk AFTER c_eth_clk_period/2;  -- Ethernet ref clock (125 MHz)
   JESD204B_REFCLK <= NOT JESD204B_REFCLK AFTER c_bck_ref_clk_period/2;  -- JESD sample clock (200MHz) 
   SA_CLK <= NOT SA_CLK AFTER c_sa_clk_period/2; -- Serial Gigabit IO sa clock (644 MHz)
+  pps_rst <= '0' AFTER c_ext_clk_period*2;
 
   INTA <= 'H';  -- pull up
   INTB <= 'H';  -- pull up
@@ -262,6 +274,45 @@ BEGIN
     JESD204B_SYNC_N => jesd204b_sync_n
   );
 
+    u_unb2_board_clk644_pll : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks
+    PORT MAP (
+      refclk_644 => SA_CLK,
+      rst_in     => pps_rst,
+      clk_156    => tr_ref_clk_156,
+      clk_312    => tr_ref_clk_312,
+      rst_156    => tr_ref_rst_156,
+      rst_312    => OPEN
+    );
+    
+    u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE
+    GENERIC MAP (
+      g_sim           => TRUE,
+      g_sim_level     => 1,
+      g_nof_macs      => 1,
+      g_use_mdio      => FALSE
+    )
+    PORT MAP (
+      -- Transceiver PLL reference clock
+      tr_ref_clk_644      => SA_CLK,
+      tr_ref_clk_312      => tr_ref_clk_312,  -- 312.5      MHz for 10GBASE-R
+      tr_ref_clk_156      => tr_ref_clk_156,  -- 156.25     MHz for 10GBASE-R or for XAUI
+      tr_ref_rst_156      => tr_ref_rst_156,  --                for 10GBASE-R or for XAUI
+    
+      -- MM interface
+      mm_rst              => pps_rst,
+      mm_clk              => tb_clk,
+      
+      -- DP interface
+      dp_rst              => pps_rst,
+      dp_clk              => ext_clk,
+    
+      serial_rx_arr(0)    => si_lpbk_0(0),
+      
+      src_out_arr(0)      => tr_10GbE_src_out
+      
+    );
+
+
   ------------------------------------------------------------------------------
   -- MM slave accesses via file IO
   ------------------------------------------------------------------------------
@@ -269,7 +320,8 @@ BEGIN
   
   p_mm_stimuli : PROCESS
     VARIABLE v_bsn                   : NATURAL;
-    VARIABLE v_sp_power_sum_0          : REAL;
+    VARIABLE v_sp_power_sum_0        : REAL;
+    VARIABLE v_sp_beamlet_power      : REAL;
     VARIABLE v_sp_subband_power      : REAL;
     VARIABLE v_W, v_T, v_U, v_S, v_B : NATURAL;  -- array indicies
   BEGIN
@@ -280,10 +332,10 @@ BEGIN
 
  
     ----------------------------------------------------------------------------
-    -- Enable UDP offload (dp_xonoff) of both beamsets
+    -- Enable UDP offload (dp_xonoff) of beamset 0
     ----------------------------------------------------------------------------
     mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff,0 , 1, tb_clk);
-    mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff,2 , 1, tb_clk);
+    --mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff,2 , 1, tb_clk);
 
     ----------------------------------------------------------------------------
     -- Enable BS
@@ -318,59 +370,40 @@ BEGIN
     mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 0, v_bsn, 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
     
-    -- Wait for ADUH monitor to have filled with WG data
-    WAIT FOR c_sdp_T_sub*c_sdp_N_taps;
-    WAIT FOR c_sdp_T_sub*2;
-
-    ----------------------------------------------------------------------------
-    -- WG data : read ADUH monitor buffer
-    ----------------------------------------------------------------------------
-    -- Wait for 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
-                            c_sdp_T_sub, tb_clk);
-    
-    WAIT FOR c_sdp_T_sub;  -- ensure that one block of samples has filled the ADUH monitor buffer after the sync
-
-    -- Read via MM    
-    FOR I IN 0 TO c_mon_buffer_nof_words-1 LOOP
-      mmf_mm_bus_rd(c_mm_file_ram_aduh_mon, I, rd_data, tb_clk);
-      sp_samples(I) <= TO_SINT(rd_data(15 DOWNTO 0)); 
-    END LOOP;
-    
-    -- Play to have waveform in time to allow viewing as analogue in the Wave Window
-    FOR I IN 0 TO c_mon_buffer_nof_words-1 LOOP
-      proc_common_wait_some_cycles(ext_clk, 1);
-      sp_sample <= sp_samples(I);
-    END LOOP;
- 
-    WAIT FOR c_sdp_T_sub*3;
-
-    ---------------------------------------------------------------------------
-    -- Read ADUH monitor power sum 
-    ---------------------------------------------------------------------------
-    -- Wait for start of sync interval
+    -- 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*3,   -- this is the wait until condition
                             c_sdp_T_sub, tb_clk);
-    
-    -- Read ADUH monitor power sum 
-    mmf_mm_bus_rd(c_mm_file_reg_aduh_mon, 2, rd_data, tb_clk);  -- read low part
-    sp_power_sum(31 DOWNTO 0) <= rd_data;
-    mmf_mm_bus_rd(c_mm_file_reg_aduh_mon, 3, rd_data, tb_clk);  -- read high part
-    sp_power_sum(63 DOWNTO 32) <= rd_data;
-    proc_common_wait_some_cycles(tb_clk, 1);
 
     ---------------------------------------------------------------------------
-    -- Verify sp_power_sum 
-    ---------------------------------------------------------------------------
-
-    -- Convert STD_LOGIC_VECTOR sp_power_sum to REAL
-    v_sp_power_sum_0 := REAL(REAL(TO_UINT(sp_power_sum(61 DOWNTO 30)))*REAL(2**30) + REAL(TO_UINT(sp_power_sum(29 DOWNTO 0)))); 
-
-    ASSERT v_sp_power_sum_0 > c_lo_factor * c_exp_wg_power_sp_0 REPORT "Wrong SP power for SP 0" SEVERITY ERROR;
-    ASSERT v_sp_power_sum_0 < c_hi_factor * c_exp_wg_power_sp_0 REPORT "Wrong SP power for SP 0" SEVERITY ERROR;
-     
+    -- Read subband statistics
+    ---------------------------------------------------------------------------   
+    -- . the subband statistics are c_wpfb_sim.stat_data_sz = 2 word power values.
+    -- . there are c_sdp_N_sub = 512 subbands per signal path
+    -- . one complex WPFB can process two real inputs A, B
+    -- . the subbands are output alternately so A0 B0 A1 B1 ... A511 B511 for input A, B
+    -- . the subband statistics multiple WPFB units appear in order in the ram_st_sst address map
+    -- . the subband statistics are stored first lo word 0 then hi word 1
+    
+    FOR I IN 0 TO c_sdp_N_pol*c_sdp_S_sub_bf*(c_longword_sz/c_word_sz)-1 LOOP
+      v_W := I MOD (c_longword_sz/c_word_sz);
+      v_T := (I / (c_longword_sz/c_word_sz)) MOD c_sdp_N_pol;
+      v_U := I / (c_sdp_N_pol*(c_longword_sz/c_word_sz)*c_sdp_S_sub_bf);
+      v_S := v_T + v_U * c_sdp_N_pol;
+      v_B := (I / (c_sdp_N_pol*(c_longword_sz/c_word_sz))) MOD c_sdp_S_sub_bf;
+      IF v_S=0 THEN
+        IF v_W=0 THEN
+          -- low part
+          mmf_mm_bus_rd(c_mm_file_ram_st_sst, I, rd_data, tb_clk);
+          sp_subband_powers_arr2(v_S)(v_B)(31 DOWNTO 0) <= rd_data;
+        ELSE      
+          -- high part
+          mmf_mm_bus_rd(c_mm_file_ram_st_sst, I, rd_data, tb_clk);
+          sp_subband_powers_arr2(v_S)(v_B)(63 DOWNTO 32) <= rd_data;
+        END IF;
+      END IF;
+    END LOOP;
+ 
     ---------------------------------------------------------------------------
     -- Read beamlet statistics
     ---------------------------------------------------------------------------
@@ -379,61 +412,117 @@ BEGIN
     -- . the subbands are output alternately so A0 B0 A1 B1 ... A5487 B487 for input A, B
     -- . the subband statistics multiple units appear in order in the ram_st_bst address map
     -- . the subband statistics are stored first lo word 0 then hi word 1
-    -- . Only read beamset 0
+    -- . Only read beamset 0, pol 0
     FOR I IN 0 TO c_sdp_N_pol*c_sdp_S_sub_bf*(c_longword_sz/c_word_sz)-1 LOOP
       v_W := I MOD (c_longword_sz/c_word_sz);
       v_T := (I / (c_longword_sz/c_word_sz)) MOD c_sdp_N_pol;
       v_U := I / (c_sdp_N_pol*(c_longword_sz/c_word_sz)*c_sdp_S_sub_bf);
       v_S := v_T + v_U * c_sdp_N_pol;
       v_B := (I / (c_sdp_N_pol*(c_longword_sz/c_word_sz))) MOD c_sdp_S_sub_bf;
-      IF v_W=0 THEN
-        -- low part
-        --mmf_mm_bus_rd(c_mm_file_ram_st_bst, I+(c_sdp_N_pol*c_sdp_N_sub*(c_longword_sz/c_word_sz)), rd_data, tb_clk);
-        mmf_mm_bus_rd(c_mm_file_ram_st_bst, I, rd_data, tb_clk);
-        sp_subband_powers_arr2(v_S)(v_B)(31 DOWNTO 0) <= rd_data;
-      ELSE      
-        -- high part
-        --mmf_mm_bus_rd(c_mm_file_ram_st_bst, I+(c_sdp_N_pol*c_sdp_N_sub*(c_longword_sz/c_word_sz)), rd_data, tb_clk);
-        mmf_mm_bus_rd(c_mm_file_ram_st_bst, I, rd_data, tb_clk);
-        sp_subband_powers_arr2(v_S)(v_B)(63 DOWNTO 32) <= rd_data;
-
-        -- Convert STD_LOGIC_VECTOR to REAL
-        v_sp_subband_power := REAL(TO_UINT(rd_data(29 DOWNTO 0) & 
-            sp_subband_powers_arr2(v_S)(v_B)(31 DOWNTO 30)))*2.0**30 + 
-            REAL(TO_UINT(sp_subband_powers_arr2(v_S)(v_B)(29 DOWNTO 0)));
-        -- sum
-        sp_subband_power_sum(v_S) <= sp_subband_power_sum(v_S) + v_sp_subband_power;
+      IF v_S=0 THEN
+        IF v_W=0 THEN
+          -- low part
+          --mmf_mm_bus_rd(c_mm_file_ram_st_bst, I+(c_sdp_N_pol*c_sdp_N_sub*(c_longword_sz/c_word_sz)), rd_data, tb_clk);
+          mmf_mm_bus_rd(c_mm_file_ram_st_bst, I, rd_data, tb_clk);
+          sp_beamlet_powers_arr2(v_S)(v_B)(31 DOWNTO 0) <= rd_data;
+        ELSE      
+          -- high part
+          --mmf_mm_bus_rd(c_mm_file_ram_st_bst, I+(c_sdp_N_pol*c_sdp_N_sub*(c_longword_sz/c_word_sz)), rd_data, tb_clk);
+          mmf_mm_bus_rd(c_mm_file_ram_st_bst, I, rd_data, tb_clk);
+          sp_beamlet_powers_arr2(v_S)(v_B)(63 DOWNTO 32) <= rd_data;
+  
+          -- Convert STD_LOGIC_VECTOR to REAL
+          v_sp_beamlet_power := REAL(TO_UINT(rd_data(29 DOWNTO 0) & 
+              sp_beamlet_powers_arr2(v_S)(v_B)(31 DOWNTO 30)))*2.0**30 + 
+              REAL(TO_UINT(sp_beamlet_powers_arr2(v_S)(v_B)(29 DOWNTO 0)));
+          -- sum
+          sp_beamlet_power_sum(v_S) <= sp_beamlet_power_sum(v_S) + v_sp_beamlet_power;
+        END IF;
       END IF;
     END LOOP;
 
-    -- sp_subband_power_sum is the sum of all subband powers per SP, this value will be close to sp_subband_power
-    -- because the input is a sinus, so most power will be in 1 subband. The sp_subband_power_leakage_sum shows
+    -- sp_beamlet_power_sum is the sum of all subband powers per SP, this value will be close to sp_beamlet_power
+    -- because the input is a sinus, so most power will be in 1 subband. The sp_beamlet_power_leakage_sum shows
     -- how much power from the input sinus at a specific subband has leaked into the 511 other subbands.
-    -- NOTE peak shows up in 511-c_subband_sp_0
-    sp_subband_power_0 <= REAL(TO_UINT(sp_subband_powers_arr2(0)(INTEGER(ROUND(c_subband_sp_0)))(61 DOWNTO 30)))*2.0**30 + 
-        REAL(TO_UINT(sp_subband_powers_arr2(0)(INTEGER(ROUND(c_subband_sp_0)))(29 DOWNTO 0)));
+    sp_beamlet_power_0 <= REAL(TO_UINT(sp_beamlet_powers_arr2(0)(INTEGER(ROUND(c_subband_sp_0)))(61 DOWNTO 30)))*2.0**30 + 
+        REAL(TO_UINT(sp_beamlet_powers_arr2(0)(INTEGER(ROUND(c_subband_sp_0)))(29 DOWNTO 0)));
 
-    sp_subband_power_sum_0 <= sp_subband_power_sum(0);
+    sp_beamlet_power_sum_0 <= sp_beamlet_power_sum(0);
     
     proc_common_wait_some_cycles(tb_clk, 1);
 
+ 
+    ---------------------------------------------------------------------------
+    -- Read 10GbE Stream
+    ---------------------------------------------------------------------------
+    proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.sop);
+    FOR I IN 0 TO 9 LOOP -- Packet header
+      proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid);
+      proc_common_wait_some_cycles(ext_clk, 1);
+    END LOOP;
+  
+    -- First word contains 3 beamlets + 1 header part
+    beamlet_arr2(0) <= tr_10GbE_src_out.data(15 DOWNTO 0);
+    beamlet_arr2(1) <= tr_10GbE_src_out.data(31 DOWNTO 16);
+    beamlet_arr2(2) <= tr_10GbE_src_out.data(47 DOWNTO 32);
+    proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid);
+    proc_common_wait_some_cycles(ext_clk, 1);
+    FOR I IN 1 TO (c_sdp_cep_nof_beamlets_per_block/4)-1 LOOP
+      beamlet_arr2(I*4 -1) <= tr_10GbE_src_out.data(15 DOWNTO 0);
+      beamlet_arr2(I*4 +0) <= tr_10GbE_src_out.data(31 DOWNTO 16);
+      beamlet_arr2(I*4 +1) <= tr_10GbE_src_out.data(47 DOWNTO 32);
+      beamlet_arr2(I*4 +2) <= tr_10GbE_src_out.data(63 DOWNTO 48);
+      proc_common_wait_until_high(ext_clk, tr_10GbE_src_out.valid);
+      proc_common_wait_some_cycles(ext_clk, 1);
+    END LOOP;
+
+    beamlet_arr2(c_sdp_cep_nof_beamlets_per_block-1) <= tr_10GbE_src_out.data(63 DOWNTO 48);
+
     ---------------------------------------------------------------------------
     -- Verify subband statistics
-    ---------------------------------------------------------------------------  
+    --------------------------------------------------------------------------- 
+    FOR I IN 0 TO c_sdp_N_pol*c_sdp_S_sub_bf-1 LOOP
+      v_T := I  MOD c_sdp_N_pol;
+      v_U := I / (c_sdp_N_pol*c_sdp_S_sub_bf);
+      v_S := v_T + v_U * c_sdp_N_pol;
+      v_B := (I / c_sdp_N_pol) MOD c_sdp_S_sub_bf;
+      IF v_S=0 THEN
+        -- Convert STD_LOGIC_VECTOR to REAL
+        v_sp_beamlet_power := REAL(TO_UINT(rd_data(29 DOWNTO 0) & 
+            sp_beamlet_powers_arr2(v_S)(v_B)(31 DOWNTO 30)))*2.0**30 + 
+            REAL(TO_UINT(sp_beamlet_powers_arr2(v_S)(v_B)(29 DOWNTO 0)));
+  
+        -- Convert STD_LOGIC_VECTOR to REAL
+        v_sp_subband_power := REAL(TO_UINT(rd_data(29 DOWNTO 0) & 
+            sp_subband_powers_arr2(v_S)(v_B)(31 DOWNTO 30)))*2.0**30 + 
+            REAL(TO_UINT(sp_subband_powers_arr2(v_S)(v_B)(29 DOWNTO 0)));
+  
+        -- verify if subband power and beamlet power are the same. This is expected because we only use 1 WG input and the BF weights have unit value.
+        -- the difference should not be larger than 0.5% (+/- 2^13 for low values)
+        ASSERT v_sp_beamlet_power > 0.995 * v_sp_subband_power -2.0**13 REPORT "index ("& integer'image(v_S) &","& integer'image(v_B)  &"): Subband power = "& real'image(v_sp_subband_power) &" and Beamlet power = "& real'image(v_sp_beamlet_power) &" are not equal" SEVERITY ERROR;
+        ASSERT v_sp_beamlet_power < 1.005 * v_sp_subband_power +2.0**13 REPORT "index ("& integer'image(v_S) &","& integer'image(v_B)  &"): Subband power = "& real'image(v_sp_subband_power) &" and Beamlet power = "& real'image(v_sp_beamlet_power) &" are not equal" SEVERITY ERROR;
+      END IF;
+    END LOOP;
+
     -- verify expected subband power based on WG power
-    IF v_sp_power_sum_0>0.0 THEN ASSERT sp_subband_power_0 > c_lo_factor * c_exp_subband_power_sp_0 REPORT "Wrong subband power for SP 0" SEVERITY ERROR; END IF;
-    IF v_sp_power_sum_0>0.0 THEN ASSERT sp_subband_power_0 < c_hi_factor * c_exp_subband_power_sp_0 REPORT "Wrong subband power for SP 0" SEVERITY ERROR; END IF;
+    IF sp_beamlet_power_sum_0>0.0 THEN ASSERT sp_beamlet_power_0 > c_lo_factor * c_exp_beamlet_power_sp_0 REPORT "Wrong beamlet power for SP 0" SEVERITY ERROR; END IF;
+    IF sp_beamlet_power_sum_0>0.0 THEN ASSERT sp_beamlet_power_0 < c_hi_factor * c_exp_beamlet_power_sp_0 REPORT "Wrong beamlet power for SP 0" SEVERITY ERROR; END IF;
     
-    -- view c_exp_sp_subband_power_ratio in Wave window
-    IF v_sp_power_sum_0>0.0 THEN sp_subband_power_ratio_0 <= sp_subband_power_0/v_sp_power_sum_0; END IF;
+    -- view c_exp_sp_beamlet_power_ratio in Wave window
+    IF sp_beamlet_power_sum_0>0.0 THEN sp_beamlet_power_ratio_0 <= sp_beamlet_power_0/v_sp_power_sum_0; END IF;
     
-    -- view c_exp_sp_subband_power_sum_ratio in Wave window
-    -- The sp_subband_power_sum_ratio show similar information as sp_subband_power_leakage_sum, because when
-    -- sp_subband_power_leakage_sum is small then sp_subband_power_sum_ratio ~= sp_subband_power_ratio.
-    IF v_sp_power_sum_0>0.0 THEN sp_subband_power_sum_ratio_0 <= sp_subband_power_sum_0/v_sp_power_sum_0; END IF;
+    -- view c_exp_sp_beamlet_power_sum_ratio in Wave window
+    -- The sp_beamlet_power_sum_ratio show similar information as sp_beamlet_power_leakage_sum, because when
+    -- sp_beamlet_power_leakage_sum is small then sp_beamlet_power_sum_ratio ~= sp_beamlet_power_ratio.
+    IF sp_beamlet_power_sum_0>0.0 THEN sp_beamlet_power_sum_ratio_0 <= sp_beamlet_power_sum_0/v_sp_power_sum_0; END IF;
 
-    -- View sp_subband_power_leakage_sum in Wave window
-    IF v_sp_power_sum_0>0.0 THEN sp_subband_power_leakage_sum_0 <= sp_subband_power_sum_0 - sp_subband_power_0; END IF;
+    -- View sp_beamlet_power_leakage_sum in Wave window
+    IF sp_beamlet_power_sum_0>0.0 THEN sp_beamlet_power_leakage_sum_0 <= sp_beamlet_power_sum_0 - sp_beamlet_power_0; END IF;
+
+    ---------------------------------------------------------------------------
+    -- Verify 10GbE UDP offload
+    --------------------------------------------------------------------------- 
+    ASSERT beamlet_arr2(c_exp_beamlet_index) = c_exp_beamlet REPORT "Wrong 10GbE output" SEVERITY ERROR;
 
     ---------------------------------------------------------------------------
     -- End Simulation 
-- 
GitLab