------------------------------------------------------------------------ -- 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; type fft_state_dec is ( FFT_STATE_IDLE, FFT_STATE_READ, FFT_STATE_SCALE, FFT_STATE_FFT, FFT_STATE_MAGNITUDE, FFT_STATE_REVERSE_ORDER, FFT_STATE_WRITE, FFT_STATE_DONE ); component FFTMAIN port ( clock : in std_logic; reset : in std_logic; di_en : in std_logic; di_re : in std_logic_vector(31 downto 0); di_im : in std_logic_vector(31 downto 0); do_en : out std_logic; do_re : out std_logic_vector(31 downto 0); do_im : out std_logic_vector(31 downto 0) ); end component; component fft_magnitude_calc port ( clk : in std_logic; reset : in std_logic; input_valid: in std_logic; input_re : in std_logic_vector( 31 downto 0 ); -- in Fixpoint input_im : in std_logic_vector( 31 downto 0 ); -- in Fixpoint output_valid : out std_logic; output_magnitude : out std_logic_vector( 31 downto 0 ) ); end component fft_magnitude_calc; -- Eigene Steuersignale. signal value_data_in_ready : std_logic; signal value_data_in_real : std_logic_vector(31 downto 0); signal value_data_in_real_scaled : std_logic_vector(31 downto 0); signal value_data_in_imag : std_logic_vector(31 downto 0); signal value_data_out_ready : std_logic; signal value_data_out_real : std_logic_vector(31 downto 0); signal value_data_out_imag : std_logic_vector(31 downto 0); signal value_data_out_mag : std_logic_vector(31 downto 0); signal value_mag_in_ready: std_logic; signal value_mag_out_ready: std_logic; signal fft_state : fft_state_dec := FFT_STATE_IDLE; signal flag_index : bit; begin fft_calc : FFTMAIN port map ( clock => clk, reset => reset, di_en => value_data_in_ready, di_re => value_data_in_real_scaled, di_im => value_data_in_imag, do_en => value_data_out_ready, do_re => value_data_out_real, do_im => value_data_out_imag ); fft_mag: fft_magnitude_calc port map ( clk => clk, reset => reset, input_valid => value_mag_in_ready, input_re => value_data_out_real, input_im => value_data_out_imag, output_valid => value_mag_out_ready, output_magnitude => value_data_out_mag ); 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; sync : process ( clk, reset ) is begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; index <= 0; elsif ( rising_edge( clk ) ) then current_task_state <= next_task_state; case next_task_state is when work.task.TASK_IDLE => index <= 0; signal_write <= '0'; when work.task.TASK_RUNNING => index <= index + 1; signal_write <= '1'; signal_writedata <= ( others => '0' ); when work.task.TASK_DONE => index <= 0; signal_write <= '0'; end case; end if; end process sync; fft : process (clk, reset) is begin -- Bei Reset alle Signale zurücksetzen if ( reset = '1' ) then value_data_in_ready <= '0'; value_data_in_real <= ( others => '0'); value_data_in_imag <= ( others => '0'); value_data_out_ready <= '0'; value_data_out_real <= ( others => '0'); value_data_out_imag <= ( others => '0'); -- Für jeden Takt add_state Zustandsmaschine aufrufen. elsif ( rising_edge( clk ) ) then case fft_state is when FFT_STATE_IDLE => if ( current_task_state = work.task.TASK_RUNNING ) then fft_state <= FFT_STATE_READ; end if; when FFT_STATE_READ => signal_read <= '1'; value_data_in_real <= signal_readdata; signal_read <= '0'; fft_state <= FFT_STATE_SCALE; when FFT_STATE_SCALE => if value_data_in_real(30 downto 23) = "00000000" then value_data_in_real_scaled <= value_data_in_real; else value_data_in_real_scaled(30 downto 23) <= std_logic_vector(signed(value_data_in_real(30 downto 23)) - 4); end if; fft_state <= FFT_STATE_FFT; when FFT_STATE_FFT => value_data_in_ready <= '1'; if ( value_data_out_ready = '1' ) then fft_state <= FFT_STATE_MAGNITUDE; end if; when FFT_STATE_MAGNITUDE => value_mag_in_ready <= '1'; if (value_mag_out_ready = '1') then fft_state <= FFT_STATE_WRITE; end if; when FFT_STATE_REVERSE_ORDER => when FFT_STATE_WRITE => signal_write <= '1'; signal_writedata <= value_data_out_mag; fft_state <= FFT_STATE_DONE; when FFT_STATE_DONE => signal_read <= '0'; signal_write <= '0'; value_data_in_ready <= '0'; value_data_out_ready <= '0'; value_mag_in_ready <= '0'; value_mag_out_ready <= '0'; fft_state <= FFT_STATE_IDLE; end case; end if; end process fft; task_state <= current_task_state; end architecture rtl;