diff --git a/libraries/dsp/fft/src/vhdl/fft_pkg.vhd b/libraries/dsp/fft/src/vhdl/fft_pkg.vhd index ccf7dab185359bd3c020f34aa520a1c0a544f023..3521770a6625dab607199860a2d3c8e20efb47fa 100644 --- a/libraries/dsp/fft/src/vhdl/fft_pkg.vhd +++ b/libraries/dsp/fft/src/vhdl/fft_pkg.vhd @@ -51,8 +51,6 @@ package fft_pkg is function resize_fft_uvec(vec : std_logic_vector) return std_logic_vector; -- map to c_fft_data_w wide slv function resize_fft_svec(vec : std_logic_vector) return std_logic_vector; -- map to c_fft_data_w wide slv - function fft_index_to_bin_frequency(wb_factor, nof_points, index : natural; use_reorder, use_separate, use_transpose : boolean) return natural; -- map fft output index to bin frequency - end package fft_pkg; package body fft_pkg is @@ -72,78 +70,5 @@ package body fft_pkg is return RESIZE_SVEC(vec, c_fft_data_w); end resize_fft_svec; - function fft_index_to_bin_frequency(wb_factor, nof_points, index : natural; use_reorder, use_separate, use_transpose : boolean) return natural is - -- Purpose: map fft output index to bin frequency - -- Description: - -- The index counts from 0..nof_points-1 and starting with the - -- first sample on stream 0 then the first sample of the other wb_factor - -- streams and then the second sample on stream 0 etc. Hence for - -- use_transpose=false and use_separate=false the bin frequency is equal - -- to the index assuming that the FFT use_reorder is used. - -- - -- Example: - -- wb_factor = 4 - -- nof_points = 32 - -- index = 0..nof_points-1 = 0..31 - -- - -- use_ use_ use_ - -- reorder separate transpose name bin frequency - -- false false false Complex 0 4 2 6 1 5 3 7 <== without use_reorder the use_separate and use_transpose can only be false - -- 16 20 18 22 17 21 19 23 - -- 8 12 10 14 9 13 11 15 - -- 24 28 26 30 25 29 27 31 - -- - -- true false false Complex reordered 0 4 8 12 16 20 24 28 <== bin_frequency = index - -- 1 5 9 13 17 21 25 29 - -- 2 6 10 14 18 22 26 30 - -- 3 7 11 15 19 23 27 31 - -- - -- true false true Complex transposed 0 1 2 3 4 5 6 7 <== this is how it is implemented in fft_wide_unit for complex input - -- 8 9 10 11 12 13 14 15 - -- 16 17 18 19 20 21 22 23 - -- 24 25 26 27 28 29 30 31 - -- - -- true true false Two real reordered 0 0 4 4 8 8 12 12 - -- 1 1 5 5 9 9 13 13 - -- 2 2 6 6 10 10 14 14 - -- 3 3 7 7 11 11 15 15 - -- - -- true true true Two real transposed 0 0 1 1 2 2 3 3 <== this is how it is implemented in fft_wide_unit for two real inputs - -- 4 4 5 5 6 6 7 7 - -- 8 8 9 9 10 10 11 11 - -- 12 12 13 13 14 14 15 15 - constant c_addr_w : natural := ceil_log2(nof_points); - - variable v_addr : std_logic_vector(c_addr_w-1 downto 0); - variable v_index : natural; - variable v_bin : natural; - begin - if use_reorder=false then - if use_separate=false and use_transpose=false then - v_addr := to_uvec(index, c_addr_w); - v_bin := to_uint(flip(v_addr)); - else - report "fft_index_to_bin_frequency : without reorder there can be no separate or transpose" severity failure; - end if; - else - if use_separate=false then - if use_transpose=false then - v_bin := index; - else - v_bin := transpose(index, wb_factor, nof_points/wb_factor); - end if; - else - if use_transpose=false then - v_index := index/wb_factor; -- 0 1 2 3 4 5 6 7 = complex column index - v_index := v_index / 2; -- 0 0 1 1 2 2 3 3 = two real column index - v_bin := index MOD wb_factor + v_index * wb_factor; - else - v_bin := transpose(index, wb_factor, nof_points/wb_factor)/2; - end if; - end if; - end if; - return v_bin; - end fft_index_to_bin_frequency; - end fft_pkg; diff --git a/libraries/dsp/fft/tb/vhdl/tb_fft_functions.vhd b/libraries/dsp/fft/tb/vhdl/tb_fft_functions.vhd index 10eaecc8008931911496c65190b5bb49b2123c14..443c77b25337b326f060df68a21278d9e0c6f1d8 100644 --- a/libraries/dsp/fft/tb/vhdl/tb_fft_functions.vhd +++ b/libraries/dsp/fft/tb/vhdl/tb_fft_functions.vhd @@ -32,7 +32,7 @@ LIBRARY IEEE, common_lib; USE IEEE.STD_LOGIC_1164.ALL; USE common_lib.common_pkg.ALL; -USE work.fft_pkg.ALL; +USE work.tb_fft_pkg.ALL; ENTITY tb_fft_functions IS END tb_fft_functions; diff --git a/libraries/dsp/fft/tb/vhdl/tb_fft_pkg.vhd b/libraries/dsp/fft/tb/vhdl/tb_fft_pkg.vhd index 68e404232aebfdaf407c3af2e073e035ca57a1c6..00eef814d70b4dd876bd13c23b88650779319c6d 100644 --- a/libraries/dsp/fft/tb/vhdl/tb_fft_pkg.vhd +++ b/libraries/dsp/fft/tb/vhdl/tb_fft_pkg.vhd @@ -38,6 +38,24 @@ PACKAGE tb_fft_pkg IS SUBTYPE t_fft_sst_arr IS t_slv_64_arr(c_fft_nof_subbands_max-1 DOWNTO 0); -- use subtype to allow using assignments via t_slv_64_arr as well TYPE t_fft_sst_arr2 IS ARRAY (INTEGER RANGE <>) OF t_fft_sst_arr; -- Private procedures + -- map fft output index to bin frequency + function fft_index_to_bin_frequency(wb_factor, nof_points, index : natural; use_reorder, use_separate, use_transpose : boolean) return natural; + + -- use out_val and out_val_cnt to determine the FFT output bin frequency and channel + procedure proc_fft_out_control(wb_factor : natural; + nof_points : natural; + nof_channels : natural; + use_reorder : boolean; + use_separate : boolean; + use_transpose : boolean; + signal out_val_cnt : in natural; -- count at sclk sample rate + signal out_val : in std_logic; + signal out_val_a : out std_logic; + signal out_val_b : out std_logic; + signal out_channel : out natural; + signal out_bin : out natural; + signal out_bin_cnt : out natural); + PROCEDURE proc_read_input_file(SIGNAL clk : IN STD_LOGIC; SIGNAL in_file_data : OUT t_integer_matrix; SIGNAL in_file_sync : OUT STD_LOGIC_VECTOR; @@ -74,11 +92,124 @@ PACKAGE tb_fft_pkg IS -- VARIABLE im_arr : OUT t_integer_arr; -- file_name : IN STRING); - END tb_fft_pkg; PACKAGE BODY tb_fft_pkg IS + function fft_index_to_bin_frequency(wb_factor, nof_points, index : natural; use_reorder, use_separate, use_transpose : boolean) return natural is + -- Purpose: map fft output index to bin frequency + -- Description: + -- The index counts from 0..nof_points-1 and starting with the + -- first sample on stream 0 then the first sample of the other wb_factor + -- streams and then the second sample on stream 0 etc. Hence for + -- use_transpose=false and use_separate=false the bin frequency is equal + -- to the index assuming that the FFT use_reorder is used. + -- + -- Example: + -- wb_factor = 4 + -- nof_points = 32 + -- index = 0..nof_points-1 = 0..31 + -- + -- use_ use_ use_ + -- reorder separate transpose name bin frequency + -- false false false Complex 0 4 2 6 1 5 3 7 <== without use_reorder the use_separate and use_transpose can only be false + -- 16 20 18 22 17 21 19 23 + -- 8 12 10 14 9 13 11 15 + -- 24 28 26 30 25 29 27 31 + -- + -- true false false Complex reordered 0 4 8 12 16 20 24 28 <== bin_frequency = index + -- 1 5 9 13 17 21 25 29 + -- 2 6 10 14 18 22 26 30 + -- 3 7 11 15 19 23 27 31 + -- + -- true false true Complex transposed 0 1 2 3 4 5 6 7 <== this is how it is implemented in fft_wide_unit for complex input + -- 8 9 10 11 12 13 14 15 + -- 16 17 18 19 20 21 22 23 + -- 24 25 26 27 28 29 30 31 + -- + -- true true false Two real reordered 0 0 4 4 8 8 12 12 + -- 1 1 5 5 9 9 13 13 + -- 2 2 6 6 10 10 14 14 + -- 3 3 7 7 11 11 15 15 + -- + -- true true true Two real transposed 0 0 1 1 2 2 3 3 <== this is how it is implemented in fft_wide_unit for two real inputs + -- 4 4 5 5 6 6 7 7 + -- 8 8 9 9 10 10 11 11 + -- 12 12 13 13 14 14 15 15 + constant c_addr_w : natural := ceil_log2(nof_points); + + variable v_addr : std_logic_vector(c_addr_w-1 downto 0); + variable v_index : natural; + variable v_bin : natural; + begin + if use_reorder=false then + if use_separate=false and use_transpose=false then + v_addr := to_uvec(index, c_addr_w); + v_bin := to_uint(flip(v_addr)); + else + report "fft_index_to_bin_frequency : without reorder there can be no separate or transpose" severity failure; + end if; + else + if use_separate=false then + if use_transpose=false then + v_bin := index; + else + v_bin := transpose(index, wb_factor, nof_points/wb_factor); + end if; + else + if use_transpose=false then + v_index := index/wb_factor; -- 0 1 2 3 4 5 6 7 = complex column index + v_index := v_index / 2; -- 0 0 1 1 2 2 3 3 = two real column index + v_bin := index MOD wb_factor + v_index * wb_factor; + else + v_bin := transpose(index, wb_factor, nof_points/wb_factor)/2; + end if; + end if; + end if; + return v_bin; + end fft_index_to_bin_frequency; + + procedure proc_fft_out_control(wb_factor : natural; + nof_points : natural; + nof_channels : natural; + use_reorder : boolean; + use_separate : boolean; + use_transpose : boolean; + signal out_val_cnt : in natural; -- count at sclk sample rate + signal out_val : in std_logic; + signal out_val_a : out std_logic; + signal out_val_b : out std_logic; + signal out_channel : out natural; + signal out_bin : out natural; + signal out_bin_cnt : out natural) is + variable v_blk_cnt : natural; + variable v_blk_val_cnt : natural; + variable v_bin : natural; + begin + out_val_a <= '0'; + out_val_b <= '0'; + if use_separate=true then + if out_val_cnt mod c_nof_complex = 0 then + out_val_a <= out_val; + else + out_val_b <= out_val; + end if; + end if; + + v_blk_cnt := out_val_cnt / nof_points; + out_channel <= v_blk_cnt mod nof_channels; + + v_blk_val_cnt := out_val_cnt mod nof_points; + v_bin := fft_index_to_bin_frequency(wb_factor, nof_points, v_blk_val_cnt, use_reorder, use_separate, use_transpose); + + out_bin <= v_bin; + if use_separate=true then + out_bin_cnt <= v_bin + v_blk_cnt * nof_points / c_nof_complex; + else + out_bin_cnt <= v_bin + v_blk_cnt * nof_points; + end if; + end proc_fft_out_control; + ------------------------------------------------------------------------------ -- PROCEDURE: Read input file. -- Reads data (re, im, sync and val) from a file and writes values diff --git a/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd b/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd index fe3d649a4a52815c5c343e995c380ec2235b4285..4e034c199bec69b4ebe66d2f13d9ad5f47ad7c14 100644 --- a/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd +++ b/libraries/dsp/fft/tb/vhdl/tb_fft_r2_pipe.vhd @@ -57,6 +57,7 @@ use common_lib.tb_common_pkg.all; use common_lib.tb_common_mem_pkg.ALL; use rTwoSDF_lib.rTwoSDFPkg.all; use work.fft_pkg.all; +use work.tb_fft_pkg.all; entity tb_fft_r2_pipe is generic( @@ -133,47 +134,6 @@ architecture tb of tb_fft_r2_pipe is constant c_gap_factor : natural := sel_a_b(g_enable_in_val_gaps, 3, 1); - procedure proc_fft_out_control(wb_factor : natural; - nof_points : natural; - nof_channels : natural; - use_reorder : boolean; - use_separate : boolean; - use_transpose : boolean; - signal out_val_cnt : in natural; -- count at sclk sample rate - signal out_val : in std_logic; - signal out_val_a : out std_logic; - signal out_val_b : out std_logic; - signal out_channel : out natural; - signal out_bin : out natural; - signal out_bin_cnt : out natural) is - variable v_blk_cnt : natural; - variable v_blk_val_cnt : natural; - variable v_bin : natural; - begin - out_val_a <= '0'; - out_val_b <= '0'; - if use_separate=true then - if out_val_cnt mod c_nof_complex = 0 then - out_val_a <= out_val; - else - out_val_b <= out_val; - end if; - end if; - - v_blk_cnt := out_val_cnt / nof_points; - out_channel <= v_blk_cnt mod nof_channels; - - v_blk_val_cnt := out_val_cnt mod nof_points; - v_bin := fft_index_to_bin_frequency(wb_factor, nof_points, v_blk_val_cnt, use_reorder, use_separate, use_transpose); - - out_bin <= v_bin; - if use_separate=true then - out_bin_cnt <= v_bin + v_blk_cnt * nof_points / c_nof_complex; - else - out_bin_cnt <= v_bin + v_blk_cnt * nof_points; - end if; - end proc_fft_out_control; - -- signal definitions signal tb_end : std_logic := '0'; signal tb_end_almost : std_logic := '0';