------------------------------------------------------------------------ -- fft -- -- calculation of FFT magnitude -- -- Inputs: -- 32-Bit Floating Point number in range +-16 expected (loaded from FIFO) -- -- Outputs -- 32-Bit Floating Point number in range +-16 calculated (stored in FIFO) -- ----------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library work; use work.reg32.all; use work.task.all; use work.float.all; entity fft is generic ( -- input data width of real/img part input_data_width : integer := 32; -- output data width of real/img part output_data_width : integer := 32 ); port ( clk : in std_logic; reset : in std_logic; task_start : in std_logic; task_state : out work.task.State; signal_read : out std_logic; signal_readdata : in std_logic_vector( 31 downto 0 ); signal_write : out std_logic; signal_writedata : out std_logic_vector( 31 downto 0 ) ); end entity fft; architecture rtl of fft is signal current_task_state : work.task.State; signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; component fftmain is -- generic( width : integer := 32 --); port( clock: in std_logic; reset: in std_logic; di_en: in std_logic; di_re: in std_logic_vector(input_data_width-1 downto 0); di_im: in std_logic_vector(input_data_width-1 downto 0); do_en: out std_logic; do_re: out std_logic_vector(output_data_width-1 downto 0); do_im: out std_logic_vector(output_data_width-1 downto 0) ); end component; -- Zustände für die Zustandsmaschine zur Berechnung type SigState is ( SIG_IDLE, SIG_READ, SIG_FFTMAIN, SIG_FFTMAG, SIG_WRITE ); signal current_sig_state : SigState; signal next_sig_state : SigState; signal fftmain_start : std_logic; signal fftmain_done : std_logic; signal fftmag_start : std_logic; signal fftmag_done : std_logic; signal fftmain_out_re : std_logic_vector( 31 downto 0 ); signal fftmain_out_im : std_logic_vector( 31 downto 0 ); signal exp : std_logic_vector( 7 downto 0); signal scaled_exp : std_logic_vector( 7 downto 0); signal scaled_readdata : std_logic_vector( 31 downto 0); signal exp_int : integer; signal scaled_data_fixp : std_logic_vector(31 downto 0); signal exp2 : std_logic_vector( 7 downto 0); signal scaled_exp2 : std_logic_vector( 7 downto 0); signal exp_int2 : integer; signal magnitude_output : std_logic_vector( 31 downto 0 ); signal writedata_float : std_logic_vector( 31 downto 0 ); type std_logic_vector_array is array (0 to 1023) of std_logic_vector(31 downto 0); signal my_array : std_logic_vector_array; begin exp <= signal_readdata( 30 downto 23 ); exp_int <= to_integer(unsigned(exp)); scaled_exp <= std_logic_vector(to_unsigned(exp_int - 4, 8)); scaled_readdata <= signal_readdata( 31 ) & scaled_exp & signal_readdata( 22 downto 0 ); scaled_data_fixp <= to_fixed(scaled_readdata); writedata_float <= to_float(magnitude_output); exp2 <= writedata_float( 30 downto 23 ); exp_int2 <= to_integer(unsigned(exp2)); scaled_exp2 <= std_logic_vector(to_unsigned(exp_int2 + 5, 8)); my_array(1023 - index) <= writedata_float( 31 ) & scaled_exp2 & writedata_float( 22 downto 0 ); signal_writedata <= my_array(index); u_fft : fftmain port map ( clock => clk, reset => reset, di_en => fftmain_start, di_re => scaled_data_fixp, di_im => x"00000000", do_en => fftmain_done, do_re => fftmain_out_re, do_im => fftmain_out_im ); u_fft_mag_calc : entity work.fft_magnitude_calc port map ( clk => clk, reset => reset, input_valid => fftmag_start, input_re => fftmain_out_re, input_im => fftmain_out_im, output_valid => fftmag_done, output_magnitude => magnitude_output ); task_state_transitions : process ( current_task_state, task_start, index ) is begin next_task_state <= current_task_state; case current_task_state is when work.task.TASK_IDLE => if ( task_start = '1' ) then next_task_state <= work.task.TASK_RUNNING; end if; when work.task.TASK_RUNNING => if ( index = work.task.STREAM_LEN - 1 ) then next_task_state <= work.task.TASK_DONE; end if; when work.task.TASK_DONE => if ( task_start = '1' ) then next_task_state <= work.task.TASK_RUNNING; end if; end case; end process task_state_transitions; sig_state_transitions : process (all) is begin next_sig_state <= current_sig_state; case current_sig_state is when SIG_IDLE => if ( current_task_state = work.task.TASK_RUNNING ) then next_sig_state <= SIG_READ; end if; when SIG_READ => next_sig_state <= SIG_FFTMAIN; when SIG_FFTMAIN => if ( fftmain_done = '1') then next_sig_state <= SIG_FFTMAG; end if; when SIG_FFTMAG => if ( fftmain_done = '0') then next_sig_state <= SIG_WRITE; end if; when SIG_WRITE => null; end case; end process sig_state_transitions; sync : process ( clk, reset ) is begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; current_sig_state <= SIG_IDLE; index <= 0; signal_read <= '0'; fftmain_start <= '0'; fftmag_start <= '0'; signal_write <= '0'; elsif ( rising_edge( clk ) ) then current_task_state <= next_task_state; case next_task_state is when work.task.TASK_IDLE => null; when work.task.TASK_RUNNING => null; when work.task.TASK_DONE => null; end case; current_sig_state <= next_sig_state; case next_sig_state is when SIG_IDLE => signal_write <= '0'; when SIG_READ => signal_read <= '1'; when SIG_FFTMAIN => fftmain_start <= '1'; when SIG_FFTMAG => signal_read <= '0'; fftmain_start <= '0'; fftmag_start <= '1'; signal_write <= '0'; index <= index + 1; when SIG_WRITE => fftmag_start <= '0'; signal_write <= '1'; end case; end if; end process sync; task_state <= current_task_state; end architecture rtl;