Skip to content
Snippets Groups Projects
Commit 69c6b237 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Clarified reading one WPFB unit into sp_subband_powers_arr2. Updated comments....

Clarified reading one WPFB unit into sp_subband_powers_arr2. Updated comments. No functional change. Improved release of pps_rst to reduce sim time.
parent fcedac3d
No related branches found
No related tags found
1 merge request!198Clarified reading one WPFB unit into sp_subband_powers_arr2. Updated comments....
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- --
-- Author: R. van der Walle -- Author: R. van der Walle (original), E. Kooistra (updates)
-- Purpose: Self-checking testbench for simulating lofar2_unb2b_sdp_station_fsub using WG data. -- Purpose: Self-checking testbench for simulating lofar2_unb2b_sdp_station_fsub using WG data.
-- --
-- Description: -- Description:
...@@ -34,39 +34,46 @@ ...@@ -34,39 +34,46 @@
-- to trigger start of WG at BSN. -- to trigger start of WG at BSN.
-- --
-- 3) Read subband statistics (SST) via ram_st_sst and verify with -- 3) Read subband statistics (SST) via ram_st_sst and verify with
-- c_exp_subband_power_sp_0 at c_subband_sp_0. -- c_exp_subband_power at g_subband.
-- View sp_subband_power_0 in Wave window -- View sp_subband_power in Wave window
-- --
-- --
-- Usage: -- Usage:
-- > as 7 # default -- > as 7 # default
-- > as 12 # for detailed debugging -- > as 12 # for detailed debugging
-- > run -a -- > run -a
-- # Takes about 40 m
-- --
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, lofar2_unb2b_sdp_station_lib; LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, lofar2_unb2b_sdp_station_lib;
USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL; USE IEEE.numeric_std.ALL;
USE IEEE.MATH_REAL.ALL; USE IEEE.math_real.ALL;
USE common_lib.common_pkg.ALL; USE common_lib.common_pkg.ALL;
USE unb2b_board_lib.unb2b_board_pkg.ALL;
USE common_lib.tb_common_pkg.ALL; USE common_lib.tb_common_pkg.ALL;
USE common_lib.common_str_pkg.ALL; USE common_lib.common_str_pkg.ALL;
USE mm_lib.mm_file_pkg.ALL; USE mm_lib.mm_file_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE mm_lib.mm_file_unb_pkg.ALL; USE mm_lib.mm_file_unb_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE diag_lib.diag_pkg.ALL; USE diag_lib.diag_pkg.ALL;
USE wpfb_lib.wpfb_pkg.ALL; USE wpfb_lib.wpfb_pkg.ALL;
USE lofar2_sdp_lib.sdp_pkg.ALL; USE lofar2_sdp_lib.sdp_pkg.ALL;
USE unb2b_board_lib.unb2b_board_pkg.ALL;
ENTITY tb_lofar2_unb2b_sdp_station_fsub IS 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
);
END tb_lofar2_unb2b_sdp_station_fsub; END tb_lofar2_unb2b_sdp_station_fsub;
ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
CONSTANT c_sim : BOOLEAN := TRUE; CONSTANT c_sim : BOOLEAN := TRUE;
CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0
CONSTANT c_node_nr : NATURAL := 0; CONSTANT c_node_nr : NATURAL := 0;
CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0
CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000";
CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00";
CONSTANT c_fw_version : t_unb2b_board_fw_version := (1, 0); CONSTANT c_fw_version : t_unb2b_board_fw_version := (1, 0);
...@@ -81,32 +88,39 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS ...@@ -81,32 +88,39 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync*c_sdp_N_fft - (c_sdp_N_fft/2); --15.5 block per sync CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync*c_sdp_N_fft - (c_sdp_N_fft/2); --15.5 block per sync
CONSTANT c_pps_period : NATURAL := c_nof_clk_per_sync; 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_wpfb_sim : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync);
CONSTANT c_stat_data_sz : NATURAL := c_wpfb_sim.stat_data_sz; -- = 2
CONSTANT c_percentage : REAL := 0.05; -- percentage that actual value may differ from expected value 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_lo_factor : REAL := 1.0 - c_percentage; -- lower boundary
CONSTANT c_hi_factor : REAL := 1.0 + c_percentage; -- higher boundary CONSTANT c_hi_factor : REAL := 1.0 + c_percentage; -- higher boundary
-- WG -- WG
CONSTANT c_full_scale_ampl : REAL := REAL(2**(14-1)-1); -- = full scale of WG CONSTANT c_bsn_start_wg : NATURAL := c_init_bsn + 2; -- start WG at this BSN to instead of some BSN, to avoid mismatches in exact expected data values
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 -- .ampl
CONSTANT c_ampl_sp_0 : NATURAL := 2**(c_sdp_W_adc-1)/1; -- in number of lsb 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_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
-- . 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 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
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_wg_ampl_lsb : REAL := c_diag_wg_ampl_unit / c_full_scale_ampl; -- amplitude in number of LSbit resolution steps
CONSTANT c_exp_wg_power_sp_0 : REAL := REAL(c_ampl_sp_0**2)/2.0 * REAL(c_nof_clk_per_sync);
-- WPFB -- WPFB
CONSTANT c_nof_pfb : NATURAL := 1; -- Verifying 1 of c_sdp_P_pfb = 6 pfb to speed up simulation. CONSTANT c_pol_index : NATURAL := g_sp MOD c_sdp_Q_fft;
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_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_sp_subband_power_ratio : REAL := 1.0/8.0; -- depends on internal WPFB quantization and FIR coefficients CONSTANT c_exp_subband_sp_power_ratio : REAL := 1.0/8.0; -- subband power / SP power, 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 : REAL := c_exp_wg_power_sp * c_exp_subband_sp_power_ratio;
CONSTANT c_exp_subband_power_sp_0 : REAL := c_exp_wg_power_sp_0 * c_exp_sp_subband_power_ratio;
TYPE t_real_arr IS ARRAY (INTEGER RANGE <>) OF REAL; 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); TyPE t_slv_64_subbands_arr IS ARRAY (INTEGER RANGE <>) OF t_slv_64_arr(0 TO c_sdp_N_sub-1);
-- MM -- MM
-- . Address widths of a single MM instance
CONSTANT c_addr_w_reg_diag_wg : NATURAL := 2;
-- . Address spans of a single MM instance
CONSTANT c_mm_span_reg_diag_wg : NATURAL := 2**c_addr_w_reg_diag_wg;
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_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_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_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG";
...@@ -118,23 +132,28 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS ...@@ -118,23 +132,28 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS
SIGNAL tb_clk : STD_LOGIC := '0'; SIGNAL tb_clk : STD_LOGIC := '0';
SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL pps_rst : STD_LOGIC := '1';
SIGNAL gen_pps : STD_LOGIC := '0';
-- WG -- WG
SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
-- WPFB -- WPFB
SIGNAL sp_subband_powers_arr2 : t_slv_64_subbands_arr(c_nof_pfb*c_nof_complex-1 DOWNTO 0); -- [sp][sub] SIGNAL sp_subband_powers_arr2 : t_slv_64_subbands_arr(c_sdp_N_pol-1 DOWNTO 0); -- [pol][sub]
SIGNAL sp_subband_power_0 : REAL; SIGNAL sp_subband_power_sum_arr : t_real_arr(c_sdp_N_pol-1 DOWNTO 0) := (OTHERS => 0.0);
SIGNAL sp_subband_power_sum : t_real_arr(c_nof_pfb*c_nof_complex-1 DOWNTO 0) := (OTHERS=>0.0); SIGNAL sp_subband_power : REAL := 0.0;
SIGNAL sp_subband_power_sum_0 : REAL; SIGNAL sp_subband_power_leakage : REAL := 0.0;
SIGNAL sp_subband_power_ratio_0 : REAL; SIGNAL sp_subband_power_leakage_snr_dB : REAL := 0.0; -- signal to noise (leakage) ratio
SIGNAL sp_subband_power_sum_ratio_0 : REAL; SIGNAL sp_subband_power_crosstalk : REAL := 0.0;
SIGNAL sp_subband_power_leakage_sum_0 : REAL; SIGNAL sp_subband_power_crosstalk_snr_dB : REAL := 0.0; -- signal to noise (crosstalk) ration
-- . expected limit values, obtained with print_str() for g_subband = 102
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
-- DUT -- DUT
SIGNAL ext_clk : STD_LOGIC := '0'; SIGNAL ext_clk : STD_LOGIC := '0';
SIGNAL pps : STD_LOGIC := '0'; SIGNAL ext_pps : STD_LOGIC := '0';
SIGNAL ext_pps : STD_LOGIC := '0';
SIGNAL pps_rst : STD_LOGIC := '0';
SIGNAL WDI : STD_LOGIC; SIGNAL WDI : STD_LOGIC;
SIGNAL INTA : STD_LOGIC; SIGNAL INTA : STD_LOGIC;
...@@ -176,9 +195,9 @@ BEGIN ...@@ -176,9 +195,9 @@ BEGIN
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- External PPS -- External PPS
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, pps); proc_common_gen_pulse(5, c_pps_period, '1', pps_rst, ext_clk, gen_pps);
jesd204b_sysref <= pps; jesd204b_sysref <= gen_pps;
ext_pps <= pps; ext_pps <= gen_pps;
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- DUT -- DUT
...@@ -192,12 +211,12 @@ BEGIN ...@@ -192,12 +211,12 @@ BEGIN
g_sim_node_nr => c_node_nr, g_sim_node_nr => c_node_nr,
g_wpfb => c_wpfb_sim, g_wpfb => c_wpfb_sim,
g_bsn_nof_clk_per_sync => c_nof_clk_per_sync, g_bsn_nof_clk_per_sync => c_nof_clk_per_sync,
g_scope_selected_subband => NATURAL(c_subband_sp_0) g_scope_selected_subband => g_subband
) )
PORT MAP ( PORT MAP (
-- GENERAL -- GENERAL
CLK => ext_clk, CLK => ext_clk,
PPS => pps, PPS => ext_pps,
WDI => WDI, WDI => WDI,
INTA => INTA, INTA => INTA,
INTB => INTB, INTB => INTB,
...@@ -238,36 +257,41 @@ BEGIN ...@@ -238,36 +257,41 @@ BEGIN
tb_clk <= NOT tb_clk AFTER c_tb_clk_period/2; -- Testbench MM clock tb_clk <= NOT tb_clk AFTER c_tb_clk_period/2; -- Testbench MM clock
p_mm_stimuli : PROCESS p_mm_stimuli : PROCESS
VARIABLE v_bsn : NATURAL; VARIABLE v_bsn : NATURAL;
VARIABLE v_sp_subband_power : REAL; VARIABLE v_data_lo, v_data_hi : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
VARIABLE v_W, v_T, v_U, v_S, v_B : NATURAL; -- array indicies 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_power : REAL;
BEGIN BEGIN
-- Wait for DUT power up after reset -- Wait for DUT power up after reset
WAIT FOR 1 us; WAIT FOR 1 us;
-- wait for pps
proc_common_wait_until_hi_lo(ext_clk, ext_pps);
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
-- Enable BSN -- Enable BSN
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, c_init_bsn, tb_clk); -- Init BSN
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 2, 0, tb_clk); -- Init BSN = 0 mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 3, 0, tb_clk); -- Write high part activates the init BSN
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_sync mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_sync
mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000003#, tb_clk); -- Enable BSN at PPS mmf_mm_bus_wr(c_mm_file_reg_bsn_source_v2, 0, 16#00000003#, tb_clk); -- Enable BSN at PPS
-- Release PPS pulser, to get first PPS now and to start BSN source
WAIT FOR 1 us;
pps_rst <= '0';
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
-- Enable WG -- Enable and start WG
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
-- 0 : mode[7:0] --> off=0, calc=1, repeat=2, single=3) -- 0 : mode[7:0] --> off=0, calc=1, repeat=2, single=3)
-- nof_samples[31:16] --> <= c_ram_wg_size=1024 -- nof_samples[31:16] --> <= c_ram_wg_size=1024
-- 1 : phase[15:0] -- 1 : phase[15:0]
-- 2 : freq[30:0] -- 2 : freq[30:0]
-- 3 : ampl[16:0] -- 3 : ampl[16:0]
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc v_offset := g_sp * c_mm_span_reg_diag_wg;
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 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, v_offset + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 2, INTEGER((c_subband_sp_0+c_wg_freq_offset) * c_wg_subband_freq_unit), tb_clk); -- freq mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 3, INTEGER(REAL(c_ampl_sp_0) * c_wg_ampl_lsb), tb_clk); -- ampl mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 2, INTEGER(REAL(g_subband) * c_wg_subband_freq_unit), tb_clk); -- freq
mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_ampl) * c_wg_ampl_lsb), tb_clk); -- ampl
-- Read current BSN -- Read current BSN
mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk); mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk);
...@@ -278,75 +302,106 @@ BEGIN ...@@ -278,75 +302,106 @@ BEGIN
v_bsn := TO_UINT(current_bsn_wg) + 2; v_bsn := TO_UINT(current_bsn_wg) + 2;
ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR; ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR;
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, 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 mmf_mm_bus_wr(c_mm_file_reg_bsn_scheduler_wg, 1, 0, tb_clk); -- assume v_bsn < 2**31-1
----------------------------------------------------------------------------
-- Wait for enough WG data and 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 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 "UNSIGNED", rd_data, ">=", c_init_bsn + c_nof_block_per_sync * 3, -- this is the wait until condition
c_sdp_T_sub, tb_clk); c_sdp_T_sub, tb_clk);
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- Read subband statistics -- Read subband statistics
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- . the subband statistics are c_wpfb_sim.stat_data_sz = 2 word power values. -- . the subband statistics are c_stat_data_sz = 2 word power values.
-- . there are c_sdp_N_sub = 512 subbands per signal path -- . there are c_sdp_S_pn = 12 signal inputs A, B, C, D, E, F, G, H, I, J, K, L
-- . one complex WPFB can process two real inputs A, B -- . there are c_sdp_N_sub = 512 subbands per signal input (SI, = signal path, SP)
-- . one complex WPFB can process two real inputs A, B, so there are c_sdp_P_pfb = 6 WPFB units,
-- but only read for the 1 WPFB unit of the selected g_sp, to speed up simulation
-- . the outputs for A, B are time multiplexed, c_sdp_Q_fft = 2, assume that they
-- correspond to the c_sdp_N_pol = 2 signal polarizations
-- . the subbands are output alternately so A0 B0 A1 B1 ... A511 B511 for input 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 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 -- . the subband statistics are stored first lo word 0 then hi word 1
v_len := c_sdp_N_sub * c_sdp_N_pol * c_stat_data_sz; -- 2048 = 512 * 2 * 64/32
FOR I IN 0 TO c_nof_pfb*c_nof_complex*c_sdp_N_sub*c_wpfb_sim.stat_data_sz-1 LOOP v_span := true_log_pow2(v_len); -- = 2048
v_W := I MOD c_wpfb_sim.stat_data_sz; FOR I IN 0 TO v_len - 1 LOOP
v_T := (I / c_wpfb_sim.stat_data_sz) MOD c_nof_complex; v_W := I MOD c_stat_data_sz; -- 0, 1 per statistics word, word index
v_U := I / (c_nof_complex*c_wpfb_sim.stat_data_sz*c_sdp_N_sub); v_P := (I / c_stat_data_sz) MOD c_sdp_N_pol; -- 0, 1 per SP pol, polarization index
v_S := v_T + v_U * c_nof_complex; v_B := I / (c_sdp_N_pol * c_stat_data_sz); -- subband index, range(N_sub = 512) per dual pol
v_B := (I / (c_nof_complex*c_wpfb_sim.stat_data_sz)) MOD c_sdp_N_sub; v_A := I + c_pfb_index * v_span; -- MM address for WPFB unit of selected g_sp
IF v_W=0 THEN IF v_W = 0 THEN
-- low part -- low part
mmf_mm_bus_rd(c_mm_file_ram_st_sst, I, rd_data, tb_clk); mmf_mm_bus_rd(c_mm_file_ram_st_sst, v_A, rd_data, tb_clk);
sp_subband_powers_arr2(v_S)(v_B)(31 DOWNTO 0) <= rd_data; v_data_lo := rd_data;
ELSE ELSE
-- high part -- high part
mmf_mm_bus_rd(c_mm_file_ram_st_sst, I, rd_data, tb_clk); mmf_mm_bus_rd(c_mm_file_ram_st_sst, v_A, rd_data, tb_clk);
sp_subband_powers_arr2(v_S)(v_B)(63 DOWNTO 32) <= rd_data; v_data_hi := rd_data;
v_stat_data := v_data_hi & v_data_lo;
-- Convert STD_LOGIC_VECTOR to REAL
v_sp_subband_power := REAL(TO_UINT(rd_data(29 DOWNTO 0) & sp_subband_powers_arr2(v_P)(v_B) <= v_stat_data;
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 of all subband powers per pol
-- sum sp_subband_power_sum_arr(v_P) <= sp_subband_power_sum_arr(v_P) + TO_UREAL(v_stat_data);
sp_subband_power_sum(v_S) <= sp_subband_power_sum(v_S) + v_sp_subband_power;
END IF; END IF;
END LOOP; END LOOP;
-- sp_subband_power_sum is the sum of all subband powers per SP, this value will be close to sp_subband_power -- Subband power of g_subband in g_sp
-- because the input is a sinus, so most power will be in 1 subband. The sp_subband_power_leakage_sum shows -- . For the selected g_subband in g_sp the sp_subband_power will be close
-- how much power from the input sinus at a specific subband has leaked into the 511 other subbands. -- to sp_subband_power_sum_arr(c_pol_index), because the input is a
sp_subband_power_0 <= REAL(TO_UINT(sp_subband_powers_arr2(0)(INTEGER(ROUND(c_subband_sp_0)))(61 DOWNTO 30)))*2.0**30 + -- sinus, so most power will be in 1 subband.
REAL(TO_UINT(sp_subband_powers_arr2(0)(INTEGER(ROUND(c_subband_sp_0)))(29 DOWNTO 0))); sp_subband_power <= TO_UREAL(sp_subband_powers_arr2(c_pol_index)(g_subband));
proc_common_wait_some_cycles(tb_clk, 1);
-- The sp_subband_power_leakage shows how much power from the input sinus at a specific
-- subband has leaked into the N_sub - 1 = 511 other subbands. The power ratio yields an
-- indication of the SNR, although that also depends on the SNR of the WG sinus.
v_power := sp_subband_power_sum_arr(c_pol_index) - sp_subband_power;
sp_subband_power_leakage <= v_power;
IF v_power > 0.0 THEN
sp_subband_power_leakage_snr_dB <= 10.0 * LOG10(sp_subband_power / v_power);
ELSE
REPORT "Wrong, zero leakage is unexpected for SP-" & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
END IF;
-- The sp_subband_power_crosstalk shows how much power from one WPFB input cross talks
-- into the other output, due to quantization cross talk in the complex FFT. The power
-- ration indicates the suppression, provided that the other input was zero.
v_power := sp_subband_power_sum_arr(not_int(c_pol_index));
sp_subband_power_crosstalk <= v_power;
IF v_power > 0.0 THEN
sp_subband_power_crosstalk_snr_dB <= 10.0 * LOG10(sp_subband_power / v_power);
ELSE
REPORT "Wrong, zero crosstalk is unexpected for SP-" & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
END IF;
sp_subband_power_sum_0 <= sp_subband_power_sum(0);
proc_common_wait_some_cycles(tb_clk, 1); proc_common_wait_some_cycles(tb_clk, 1);
---------------------------------------------------------------------------
-- Print subband statistics
---------------------------------------------------------------------------
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
-- quality indicators like leakage and crosstalk are also reported out of
-- interest.
print_str("sp_subband_power_leakage = " & real_to_str(sp_subband_power_leakage, 20, 0));
print_str("sp_subband_power_leakage_snr_dB = " & real_to_str(sp_subband_power_leakage_snr_dB, 20, 3));
print_str("sp_subband_power_crosstalk = " & real_to_str(sp_subband_power_crosstalk, 20, 0));
print_str("sp_subband_power_crosstalk_snr_db = " & real_to_str(sp_subband_power_crosstalk_snr_db, 20, 3));
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- Verify subband statistics -- Verify subband statistics
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- verify expected subband power based on WG power -- verify expected subband power based on WG power
IF sp_subband_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; ASSERT sp_subband_power > c_lo_factor * c_exp_subband_power REPORT "Wrong subband power for SP-" & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
IF sp_subband_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; ASSERT sp_subband_power < c_hi_factor * c_exp_subband_power REPORT "Wrong subband power for SP-" & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
-- view c_exp_sp_subband_power_ratio in Wave window
IF sp_subband_power_sum_0>0.0 THEN sp_subband_power_ratio_0 <= sp_subband_power_0/sp_subband_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 sp_subband_power_sum_0>0.0 THEN sp_subband_power_sum_ratio_0 <= sp_subband_power_sum_0/sp_subband_power_0; END IF;
-- View sp_subband_power_leakage_sum in Wave window -- Verify expected SNR quality measures
IF sp_subband_power_sum_0>0.0 THEN sp_subband_power_leakage_sum_0 <= sp_subband_power_sum_0 - sp_subband_power_0; END IF; ASSERT sp_subband_power_leakage_snr_dB > c_exp_subband_power_leakage_snr_dB REPORT "Wrong to much leakage for SP-" & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
ASSERT sp_subband_power_crosstalk_snr_dB > c_exp_subband_power_crosstalk_snr_dB REPORT "Wrong to much crosstalk for SP-" & NATURAL'IMAGE(g_sp) SEVERITY ERROR;
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- End Simulation -- End Simulation
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment