------------------------------------------------------------------------ -- 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_FILL_IP_CORE, FFT_STATE_GET_IP_CORE, FFT_STATE_SORT, 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_real_scaled_fixed : 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_data_out_mag_float : std_logic_vector(31 downto 0); signal value_data_out_mag_float_scaled : std_logic_vector(31 downto 0); type memory_array is array (0 to work.task.STREAM_LEN - 1) of std_logic_vector(31 downto 0); signal memory : memory_array := (others => (others => '0')); signal sorted_memory : memory_array := (others => (others => '0')); signal bitsort_index : integer range 0 to work.task.STREAM_LEN; signal bitsort_index_temp: integer range 0 to work.task.STREAM_LEN; signal bitsort_index_out : integer range 0 to work.task.STREAM_LEN; signal input_vector : std_logic_vector(work.task.STREAM_LEN-1 downto 0); signal reversed_bits : std_logic_vector(work.task.STREAM_LEN-1 downto 0); signal a_vec : std_logic_vector(9 downto 0); -- Vector for 1024 range signal b_vec : std_logic_vector(9 downto 0); -- Reversed vector signal a : integer range 0 to 1023 := 100; -- Example input integer signal b : integer range 0 to 1023; -- Reversed integer output 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; signal write_done_flag : bit; --signal memory_scale : work.reg.32.RegArray(0 to 1023); begin fft_calc : FFTMAIN port map ( clock => clk, reset => reset, di_en => value_data_in_ready, di_re => value_data_in_real_scaled_fixed, 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 ); -- current_task_state, task_start, index 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 => --index = work.task.STREAM_LEN if ( write_done_flag = '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_writedata <= ( others => '0' ); if ( flag_index = '1' ) then index <= index + 1; end if; when work.task.TASK_DONE => index <= 0; --signal_write <= '0'; end case; end if; end process sync; fft : process (clk, reset) is variable fifo_in : signed(31 downto 0); variable fifo_out : signed(31 downto 0); 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_mag_in_ready <= '0'; write_done_flag <= '0'; signal_write <= '0'; signal_read <= '0'; flag_index <= '0'; a_vec <= (others => '0'); b_vec <= (others => '0'); b <= 0; a <= 0; -- Für jeden Takt fft_state Zustandsmaschine aufrufen. elsif ( rising_edge( clk ) ) then case fft_state is when FFT_STATE_IDLE => flag_index <= '0'; if ( current_task_state = work.task.TASK_RUNNING ) then fft_state <= FFT_STATE_FILL_IP_CORE; end if; when FFT_STATE_FILL_IP_CORE => value_data_in_ready <= '1'; signal_read <= '1'; value_data_in_real <= signal_readdata; if value_data_in_real(30 downto 23) = "00000000" then value_data_in_real_scaled_fixed <= to_fixed(value_data_in_real); else fifo_in(31) := value_data_in_real(31); fifo_in(30 downto 23) := signed(value_data_in_real(30 downto 23)) - 4; fifo_in(22 downto 0) := signed(value_data_in_real(22 downto 0)); value_data_in_real_scaled_fixed <= to_fixed(std_logic_vector(fifo_in)); end if; if (value_data_out_ready = '1') then fft_state <= FFT_STATE_GET_IP_CORE; end if; when FFT_STATE_GET_IP_CORE => signal_read <= '0'; value_mag_in_ready <= '1'; value_data_out_mag_float <= to_float(value_data_out_mag); value_data_out_mag_float_scaled(31) <= value_data_out_mag_float(31); value_data_out_mag_float_scaled(22 downto 0) <= std_logic_vector(signed(value_data_out_mag_float(22 downto 0))); if value_data_out_mag_float(30 downto 23) = "00000000" then value_data_out_mag_float_scaled(30 downto 23) <= std_logic_vector(signed(value_data_out_mag_float(30 downto 23)) + 4); else value_data_out_mag_float_scaled(30 downto 23) <= std_logic_vector(signed(value_data_out_mag_float(30 downto 23)) + 5); end if; memory(index) <= value_data_out_mag_float_scaled; if (value_mag_out_ready = '1') then flag_index <= '1'; end if; if ( index = work.task.STREAM_LEN - 1 ) then --value_data_in_ready <= '0'; flag_index <= '0'; bitsort_index <= 0; bitsort_index_temp <= 0; bitsort_index_out <= 0; fft_state <= FFT_STATE_SORT; end if; when FFT_STATE_SORT => a_vec <= std_logic_vector(to_unsigned(bitsort_index, a_vec'length)); for i in 0 to 9 loop b_vec(i) <= a_vec(9 - i); end loop; b <= to_integer(unsigned(b_vec)); sorted_memory(b) <= memory(bitsort_index); bitsort_index <= bitsort_index + 1; if (bitsort_index = work.task.STREAM_LEN - 1) then bitsort_index <= 0; fft_state <= FFT_STATE_WRITE; end if; when FFT_STATE_WRITE => signal_write <= '1'; signal_writedata <= sorted_memory(bitsort_index); bitsort_index <= bitsort_index + 1; if (bitsort_index = work.task.STREAM_LEN - 1) then fft_state <= FFT_STATE_DONE; write_done_flag <= '1'; end if; when FFT_STATE_DONE => signal_write <= '0'; flag_index <= '0'; signal_read <= '0'; value_data_in_ready <= '0'; value_mag_in_ready <= '0'; end case; end if; end process fft; task_state <= current_task_state; end architecture rtl;