diff --git a/libraries/dsp/fft/hdllib.cfg b/libraries/dsp/fft/hdllib.cfg index f58dabe76ba5055641afc38ac4f2174482425bdf..dc054d8a66804073a951df9d113fbfe6e8300ef7 100644 --- a/libraries/dsp/fft/hdllib.cfg +++ b/libraries/dsp/fft/hdllib.cfg @@ -29,9 +29,13 @@ test_bench_files = tb/vhdl/tb_mmf_fft_r2.vhd tb/vhdl/tb_mmf_fft_wide_unit.vhd tb/vhdl/tb_tb_fft_r2_pipe.vhd + tb/vhdl/tb_tb_fft_r2_par.vhd + tb/vhdl/tb_tb_fft_r2_wide.vhd regression_test_vhdl = - tb/vhdl/tb_tb_fft_r2_pipe.vhd + tb/vhdl/tb_tb_fft_r2_pipe.vhd + tb/vhdl/tb_tb_fft_r2_par.vhd + tb/vhdl/tb_tb_fft_r2_wide.vhd [modelsim_project_file] diff --git a/libraries/dsp/fft/tb/vhdl/tb_tb_fft_r2_wide.vhd b/libraries/dsp/fft/tb/vhdl/tb_tb_fft_r2_wide.vhd new file mode 100644 index 0000000000000000000000000000000000000000..7ad981dc05fb5dc64a5174d23026bfb557d6f43d --- /dev/null +++ b/libraries/dsp/fft/tb/vhdl/tb_tb_fft_r2_wide.vhd @@ -0,0 +1,155 @@ +-------------------------------------------------------------------------------- +-- +-- Copyright (C) 2016 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +-------------------------------------------------------------------------------- + +-- Purpose: Multi-testbench for fft_r2_wide using file data +-- Description: +-- Verify fft_r2_wide using and data generated by Matlab scripts: +-- +-- - $RADIOHDL/applications/apertif/matlab/run_pfft.m +-- - $RADIOHDL/applications/apertif/matlab/run_pfft_complex.m +-- +-- Usage: +-- > as 4 +-- > run -all + +LIBRARY IEEE, common_lib, rTwoSDF_lib; +USE IEEE.std_logic_1164.ALL; +USE common_lib.common_pkg.all; +USE rTwoSDF_lib.rTwoSDFPkg.all; +USE work.fft_pkg.all; + +ENTITY tb_tb_fft_r2_wide IS +END tb_tb_fft_r2_wide; + +ARCHITECTURE tb OF tb_tb_fft_r2_wide IS + + CONSTANT c_pipeline : t_fft_pipeline := (1, 1, 3, 1, 1, 0, 0, 1); + + CONSTANT c_fft_two_real : t_fft := ( true, true, 0, 4, 0, 128, 8, 16, c_dsp_mult_w, 2, true, 56, 2); + CONSTANT c_fft_complex : t_fft := ( true, false, 0, 4, 0, 64, 8, 16, c_dsp_mult_w, 2, true, 56, 2); + CONSTANT c_fft_complex_flipped : t_fft := (false, false, 0, 4, 0, 64, 8, 16, c_dsp_mult_w, 2, true, 56, 2); + + CONSTANT c_diff_margin : natural := 2; + + -- Real input + CONSTANT c_impulse_chirp : string := "data/run_pfft_m_impulse_chirp_8b_128points_16b.dat"; -- 25600 lines + CONSTANT c_sinusoid_chirp : string := "data/run_pfft_m_sinusoid_chirp_8b_128points_16b.dat"; -- 25600 lines + CONSTANT c_noise : string := "data/run_pfft_m_noise_8b_128points_16b.dat"; -- 1280 lines + CONSTANT c_dc_agwn : string := "data/run_pfft_m_dc_agwn_8b_128points_16b.dat"; -- 1280 lines + -- Complex input + CONSTANT c_phasor_chirp : string := "data/run_pfft_complex_m_phasor_chirp_8b_64points_16b.dat"; -- 12800 lines + CONSTANT c_phasor : string := "data/run_pfft_complex_m_phasor_8b_64points_16b.dat"; -- 320 lines + CONSTANT c_noise_complex : string := "data/run_pfft_complex_m_noise_complex_8b_64points_16b.dat"; -- 620 lines + -- Zero input + CONSTANT c_zero : string := "UNUSED"; + CONSTANT c_unused : string := "UNUSED"; + + SIGNAL tb_end : STD_LOGIC := '0'; -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end' + +BEGIN + +-- -- DUT generics +-- g_pipeline : t_fft_pipeline := (1, 1, 3, 1, 1, 0, 0, 1); +-- -- type t_rtwo_sdf_stage_pipeline is record +-- -- -- generics for rTwoSDFStage +-- -- stage_lat : natural; -- = 1 +-- -- weight_lat : natural; -- = 1 +-- -- mul_lat : natural; -- = 3 +-- -- -- generics for rTwoBFStage +-- -- bf_lat : natural; -- = 1 +-- -- -- generics for rTwoBF +-- -- bf_use_zdly : natural; -- = 1 +-- -- bf_in_a_zdly : natural; -- = 0 +-- -- bf_out_d_zdly : natural; -- = 0 +-- -- sep_lat : natural; -- = 1 +-- -- end record; +-- --g_fft : t_fft := (true, true, 0, 4, 0, 128, 8, 16, c_dsp_mult_w, 2, true, 56, 2); -- two real inputs A and B +-- g_fft : t_fft := (true, true, 0, 4, 0, 32, 8, 16, c_dsp_mult_w, 2, true, 56, 2); -- two real inputs A and B +-- --g_fft : t_fft := ( true, false, 0, 4, 0, 32, 8, 16, c_dsp_mult_w, 2, true, 56, 2); -- complex input reordered +-- --g_fft : t_fft := (false, false, 0, 4, 0, 32, 8, 16, c_dsp_mult_w, 2, true, 56, 2); -- complex input flipped +-- -- type t_rtwo_fft is record +-- -- use_reorder : boolean; -- = false for bit-reversed output, true for normal output +-- -- use_separate : boolean; -- = false for complex input, true for two real inputs +-- -- nof_chan : natural; -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan +-- -- wb_factor : natural; -- = default 1, wideband factor +-- -- twiddle_offset : natural; -- = default 0, twiddle offset for PFT sections in a wideband FFT +-- -- nof_points : natural; -- = 1024, N point FFT +-- -- in_dat_w : natural; -- = 8, number of input bits +-- -- out_dat_w : natural; -- = 13, number of output bits, bit growth: in_dat_w + natural((ceil_log2(nof_points))/2 + 2) +-- -- stage_dat_w : natural; -- = 18, data width used between the stages(= DSP multiplier-width) +-- -- guard_w : natural; -- = 2, Guard used to avoid overflow in FFT stage. +-- -- guard_enable : boolean; -- = true when input needs guarding, false when input requires no guarding but scaling must be skipped at the last stage(s) (used in wb fft) +-- -- stat_data_w : positive; -- = 56 (= 18b+18b)+log2(781250) +-- -- stat_data_sz : positive; -- = 2 (complex re and im) +-- -- end record; +-- -- +-- -- TB generics +-- g_diff_margin : integer := 2; -- maximum difference between HDL output and expected output (> 0 to allow minor rounding differences) +-- +-- -- Two real input data files A and B used when g_fft.use_separate = true +-- -- * 128 points = 64 subbands +-- --g_data_file_a : string := "data/run_pfft_m_sinusoid_chirp_8b_128points_16b.dat"; +-- --g_data_file_a_nof_lines : natural := 25600; +-- --g_data_file_b : string := "UNUSED"; +-- --g_data_file_b_nof_lines : natural := 0; +-- +-- -- * 32 points = 16 subbands +-- g_data_file_a : string := "data/run_pfft_m_sinusoid_chirp_8b_32points_16b.dat"; +-- g_data_file_a_nof_lines : natural := 6400; +-- --g_data_file_a : string := "data/run_pfft_m_sinusoid_8b_32points_16b.dat"; +-- --g_data_file_a_nof_lines : natural := 160; +-- +-- --g_data_file_b : string := "data/run_pfft_m_impulse_chirp_8b_32points_16b.dat"; +-- --g_data_file_b_nof_lines : natural := 6400; +-- g_data_file_b : string := "UNUSED"; +-- g_data_file_b_nof_lines : natural := 0; +-- +-- -- One complex input data file C used when g_fft.use_separate = false +-- -- * 64 points = 64 channels +-- --g_data_file_c : string := "data/run_pfft_complex_m_phasor_chirp_8b_64points_16b.dat"; +-- --g_data_file_c_nof_lines : natural := 12800; +-- --g_data_file_c : string := "data/run_pfft_complex_m_phasor_8b_64points_16b.dat"; +-- --g_data_file_c_nof_lines : natural := 320; +-- --g_data_file_c : string := "data/run_pfft_complex_m_noise_8b_64points_16b.dat"; +-- --g_data_file_c_nof_lines : natural := 640; +-- +-- -- * 32 points = 32 channels +-- g_data_file_c : string := "data/run_pfft_complex_m_phasor_chirp_8b_32points_16b.dat"; +-- g_data_file_c_nof_lines : natural := 6400; +-- --g_data_file_c : string := "data/run_pfft_complex_m_phasor_8b_32points_16b.dat"; +-- --g_data_file_c_nof_lines : natural := 160; +-- --g_data_file_c : string := "data/run_pfft_complex_m_noise_8b_32points_16b.dat"; +-- --g_data_file_c_nof_lines : natural := 320; +-- +-- g_data_file_nof_lines : natural := 6400; -- actual number of lines with input data to simulate from the data files, must be <= g_data_file_*_nof_lines +-- g_enable_in_val_gaps : boolean := TRUE -- when false then in_val flow control active continuously, else with random inactive gaps + + -- Two real input data A and B + u_act_two_real_chirp : ENTITY work.tb_fft_r2_wide GENERIC MAP (c_pipeline, c_fft_two_real, c_diff_margin, c_sinusoid_chirp, 25600, c_impulse_chirp, 25600, c_unused, 0, 25600, FALSE); + u_act_two_real_a0 : ENTITY work.tb_fft_r2_wide GENERIC MAP (c_pipeline, c_fft_two_real, c_diff_margin, c_zero, 25600, c_impulse_chirp, 25600, c_unused, 0, 5120, FALSE); + u_act_two_real_b0 : ENTITY work.tb_fft_r2_wide GENERIC MAP (c_pipeline, c_fft_two_real, c_diff_margin, c_sinusoid_chirp, 25600, c_zero, 25600, c_unused, 0, 5120, FALSE); + u_rnd_two_real_noise : ENTITY work.tb_fft_r2_wide GENERIC MAP (c_pipeline, c_fft_two_real, c_diff_margin, c_noise, 1280, c_dc_agwn, 1280, c_unused, 0, 1280, TRUE); + + -- Complex input data + u_act_complex_chirp : ENTITY work.tb_fft_r2_wide GENERIC MAP (c_pipeline, c_fft_complex, c_diff_margin, c_unused, 0, c_unused, 0, c_phasor_chirp, 12800, 12800, FALSE); + u_act_flipped_complex : ENTITY work.tb_fft_r2_wide GENERIC MAP (c_pipeline, c_fft_complex_flipped, c_diff_margin, c_unused, 0, c_unused, 0, c_phasor_chirp, 12800, 1280, FALSE); + u_rnd_complex_noise : ENTITY work.tb_fft_r2_wide GENERIC MAP (c_pipeline, c_fft_complex, c_diff_margin, c_unused, 0, c_unused, 0, c_noise_complex, 640, 640, TRUE); +END tb;