From 54b53f8a0fe8c51794eaf7a1f3713d74cdaec902 Mon Sep 17 00:00:00 2001 From: Reinier van der Walle <walle@astron.nl> Date: Thu, 17 Sep 2020 09:46:23 +0200 Subject: [PATCH] Initial commit of tb_lofar2_unb2b_filterbank --- .../tb/vhdl/tb_lofar2_unb2b_filterbank.vhd | 196 +++++++++++++----- 1 file changed, 146 insertions(+), 50 deletions(-) diff --git a/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd b/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd index 31b4150fdf..f322629c59 100644 --- a/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_filterbank/tb/vhdl/tb_lofar2_unb2b_filterbank.vhd @@ -27,7 +27,7 @@ -- MM control actions: -- -- 1) Enable calc mode for WG via reg_diag_wg with: --- freq = 20MHz +-- freq = 19.921875MHz -- ampl = 0.5 * 2**13 -- -- 2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg @@ -37,8 +37,12 @@ -- analogue view in Wave window: -- -- 4) Read ADUH monitor power sum for via reg_aduh_mon and verify with --- c_exp_wg_power_sp. +-- c_exp_wg_power_sp_0. -- View sp_power_sum in Wave window +-- 5) Read subband statistics (SST) via ram_st_sst and verify with +-- c_exp_subband_power_sp_0 at c_subband_sp_0. +-- View sp_subband_power_0 in Wave window +-- -- -- Usage: -- > as 7 # default @@ -46,9 +50,10 @@ -- > run -a -- ------------------------------------------------------------------------------- -LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib; +LIBRARY IEEE, common_lib, unb2b_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; +USE IEEE.MATH_REAL.ALL; USE common_lib.common_pkg.ALL; USE unb2b_board_lib.unb2b_board_pkg.ALL; USE common_lib.tb_common_pkg.ALL; @@ -57,6 +62,8 @@ USE mm_lib.mm_file_pkg.ALL; USE dp_lib.dp_stream_pkg.ALL; USE mm_lib.mm_file_unb_pkg.ALL; USE diag_lib.diag_pkg.ALL; +USE wpfb_lib.wpfb_pkg.ALL; +USE lofar2_sdp_lib.sdp_pkg.ALL; ENTITY tb_lofar2_unb2b_filterbank IS END tb_lofar2_unb2b_filterbank; @@ -76,43 +83,53 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_filterbank IS CONSTANT c_pps_period : NATURAL := 1000; CONSTANT c_tb_clk_period : TIME := 100 ps; -- use fast tb_clk to speed up M&C - CONSTANT c_cable_delay : TIME := 12 ns -; + CONSTANT c_cable_delay : TIME := 12 ns; + CONSTANT c_sample_freq : NATURAL := c_unb2b_board_ext_clk_freq_200M/10**6; -- 200 MSps CONSTANT c_sample_period : TIME := (10**6 / c_sample_freq) * 1 ps; - CONSTANT c_nof_sync : NATURAL := 5; CONSTANT c_nof_block_per_sync : NATURAL := 16; - + CONSTANT c_wpfb_sim : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_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_nof_points : NATURAL := 1024; - CONSTANT c_nof_taps : NATURAL := 16; - - CONSTANT c_subband_period : TIME := c_nof_points * c_sample_period; + CONSTANT c_subband_period : TIME := c_sdp_N_fft * c_sample_period; -- WG CONSTANT c_full_scale_ampl : REAL := REAL(2**(18-1)-1); -- = full scale of 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 : NATURAL := 2**(14-1)/2; -- in number of lsb - CONSTANT c_subband_sp : REAL := 51.2; -- Select subband at index 512/10 = 51.2 = 20 MHz - CONSTANT c_wg_subband_freq_unit : REAL := c_diag_wg_freq_unit/512.0; -- subband freq = Fs/512 = 200 MSps/512 = 390625 Hz sinus + CONSTANT c_ampl_sp_0 : NATURAL := 2**(14-1)/2; -- in number of lsb + 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 : REAL := REAL(c_ampl_sp**2)/2.0 * REAL(c_nof_points*c_nof_block_per_sync); - + CONSTANT c_exp_wg_power_sp_0 : REAL := REAL(c_ampl_sp_0**2)/2.0 * REAL(c_sdp_N_fft*c_nof_block_per_sync); + + -- WPFB + CONSTANT c_nof_pfb : NATURAL := 1; -- Verifying 1 of c_sdp_P_pfb = 6 pfb to speed up simulation. + 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_measured_subband_power_sp_0 : REAL := 17016589184.0; -- obtained from Wave window + + 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); + -- ADUH - CONSTANT c_mon_buffer_nof_samples : NATURAL := 1024; --samples per stream - CONSTANT c_mon_buffer_nof_words : NATURAL := c_mon_buffer_nof_samples; + CONSTANT c_mon_buffer_nof_samples : NATURAL := 512; --samples per stream + CONSTANT c_mon_buffer_nof_words : NATURAL := c_mon_buffer_nof_samples; -- MM - CONSTANT c_mm_file_reg_ppsh : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS"; - CONSTANT c_mm_file_reg_bsn_source : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE"; - 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_aduh_mon : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_ADUH_MONITOR"; - 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_reg_ppsh : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS"; + CONSTANT c_mm_file_reg_bsn_source : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE"; + 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_aduh_mon : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_ADUH_MONITOR"; + 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_sst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST"; -- Tb @@ -122,12 +139,21 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_filterbank IS SIGNAL rd_data : STD_LOGIC_VECTOR(c_32-1 DOWNTO 0); -- WG - SIGNAL dbg_c_exp_wg_power_sp : REAL := c_exp_wg_power_sp; - SIGNAL sp_samples : t_integer_arr(0 TO c_mon_buffer_nof_samples-1) := (OTHERS=>0); - SIGNAL sp_sample : INTEGER := 0; - SIGNAL sp_power_sum : UNSIGNED(63 DOWNTO 0); - SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); - + SIGNAL dbg_c_exp_wg_power_sp_0 : REAL := c_exp_wg_power_sp_0; + SIGNAL sp_samples : t_integer_arr(0 TO c_mon_buffer_nof_samples-1) := (OTHERS=>0); + SIGNAL sp_sample : INTEGER := 0; + SIGNAL sp_power_sum : STD_LOGIC_VECTOR(63 DOWNTO 0); + SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); + + -- 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_power_0 : REAL; + SIGNAL sp_subband_power_sum : t_real_arr(c_nof_pfb*c_nof_complex-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; + -- DUT SIGNAL ext_clk : STD_LOGIC := '0'; SIGNAL pps : STD_LOGIC := '0'; @@ -184,11 +210,13 @@ BEGIN ------------------------------------------------------------------------------ u_lofar_unb2b_filterbank : ENTITY work.lofar2_unb2b_filterbank GENERIC MAP ( - g_design_name => "lofar2_unb2b_filterbank_full", - g_design_note => "Lofar2 adc full", - g_sim => c_sim, - g_sim_unb_nr => c_unb_nr, - g_sim_node_nr => c_node_nr + g_design_name => "lofar2_unb2b_filterbank_full", + g_design_note => "Lofar2 adc full", + g_sim => c_sim, + g_sim_unb_nr => c_unb_nr, + g_sim_node_nr => c_node_nr, + g_wpfb => c_wpfb_sim, + g_scope_selected_subband => NATURAL(c_subband_sp_0) ) PORT MAP ( -- GENERAL @@ -220,8 +248,8 @@ BEGIN QSFP_LED => open, -- back transceivers - JESD204B_SERIAL_DATA => JESD204B_SERIAL_DATA, - JESD204B_REFCLK => JESD204B_REFCLK, + JESD204B_SERIAL_DATA => JESD204B_SERIAL_DATA, + JESD204B_REFCLK => JESD204B_REFCLK, -- jesd204b syncronization signals JESD204B_SYSREF => jesd204b_sysref, @@ -235,7 +263,9 @@ BEGIN p_mm_stimuli : PROCESS VARIABLE v_bsn : NATURAL; - VARIABLE v_sp_power_sum : REAL; + VARIABLE v_sp_power_sum_0 : REAL; + VARIABLE v_sp_subband_power : REAL; + VARIABLE v_W, v_T, v_U, v_S, v_B : NATURAL; -- array indicies BEGIN -- Wait for DUT power up after reset WAIT FOR 1 us; @@ -260,9 +290,9 @@ BEGIN -- 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 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, 2, INTEGER(c_subband_sp * c_wg_subband_freq_unit), tb_clk); -- freq - mmf_mm_bus_wr(c_mm_file_reg_diag_wg, 3, INTEGER(REAL(c_ampl_sp) * c_wg_ampl_lsb), tb_clk); -- ampl - + 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, 3, INTEGER(REAL(c_ampl_sp_0) * c_wg_ampl_lsb), tb_clk); -- ampl + -- 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, 1, current_bsn_wg(63 DOWNTO 32), tb_clk); @@ -276,7 +306,7 @@ BEGIN 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_subband_period*c_nof_taps; + WAIT FOR c_subband_period*c_sdp_N_taps; WAIT FOR c_subband_period*2; ---------------------------------------------------------------------------- @@ -313,19 +343,85 @@ BEGIN -- 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) <= UNSIGNED(rd_data); + 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) <= UNSIGNED(rd_data); + sp_power_sum(63 DOWNTO 32) <= rd_data; proc_common_wait_some_cycles(tb_clk, 1); --------------------------------------------------------------------------- - -- Verification + -- 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 --------------------------------------------------------------------------- - -- Convert UNSIGNED sp_power_sum to REAL - v_sp_power_sum := REAL(REAL(TO_INTEGER(sp_power_sum(61 DOWNTO 30)))*REAL(2**30) + REAL(TO_INTEGER(sp_power_sum(29 DOWNTO 0)))); + -- . 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_nof_pfb*c_nof_complex*c_sdp_N_sub*c_wpfb_sim.stat_data_sz-1 LOOP + v_W := I MOD c_wpfb_sim.stat_data_sz; + v_T := (I / c_wpfb_sim.stat_data_sz) MOD c_nof_complex; + v_U := I / (c_nof_complex*c_wpfb_sim.stat_data_sz*c_sdp_N_sub); + v_S := v_T + v_U * c_nof_complex; + v_B := (I / (c_nof_complex*c_wpfb_sim.stat_data_sz)) MOD c_sdp_N_sub; + 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; + + -- 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; + END IF; + END LOOP; - ASSERT v_sp_power_sum > c_lo_factor * c_exp_wg_power_sp REPORT "Wrong SP power for SP 0" SEVERITY ERROR; - ASSERT v_sp_power_sum < c_hi_factor * c_exp_wg_power_sp REPORT "Wrong SP power for SP 0" SEVERITY ERROR; + -- 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 + -- how much power from the input sinus at a specific subband has leaked into the 511 other subbands. + 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_subband_power_sum_0 <= sp_subband_power_sum(0); + + proc_common_wait_some_cycles(tb_clk, 1); + + --------------------------------------------------------------------------- + -- Verify subband statistics + --------------------------------------------------------------------------- + -- 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; + + -- verify expected subband power based on earlier simulation of exactly measurement of subband power + ASSERT sp_subband_power_0 = c_measured_subband_power_sp_0 REPORT "Wrong exact subband power for SP 0" SEVERITY ERROR; + + -- 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_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 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; --------------------------------------------------------------------------- -- End Simulation @@ -335,5 +431,5 @@ BEGIN proc_common_stop_simulation(TRUE, ext_clk, sim_done, tb_end); WAIT; END PROCESS; - + END tb; -- GitLab