diff --git a/hardware/signal_processing/fft.vhd b/hardware/signal_processing/fft.vhd index 4f8287d..5155676 100644 --- a/hardware/signal_processing/fft.vhd +++ b/hardware/signal_processing/fft.vhd @@ -50,85 +50,84 @@ signal next_task_state : work.task.State; signal index : integer range 0 to work.task.STREAM_LEN; - component fftmain is - port( - clock: in std_logic; -- Master Clock - reset: in std_logic; -- Active High Asynchronous Reset - di_en: in std_logic; -- Input Data Enable - di_re: in std_logic_vector(input_data_width-1 downto 0); -- Input Data (Real) - di_im: in std_logic_vector(input_data_width-1 downto 0); -- Input Data (Imag) - do_en: out std_logic; -- Output Data Enable - do_re: out std_logic_vector(output_data_width-1 downto 0); -- Output Data (Real) - do_im: out std_logic_vector(output_data_width-1 downto 0) -- Output Data (Imag) - ); - end component; - --Initialisierung der weiteren Ablaufstruktur - type FFTState is ( - FFTIdle, - FFTRead, - FFTWait, - MAGRead, - MAGStore - ); + 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 + ); - --Signale fuer die Zustandsmaschine - signal current_fft_state : FFTState; - signal next_fft_state : FFTState; - --signal fifo_in : unsigned(31 downto 0); - constant B : signed(7 downto 0) := "00000100"; - --signal C : unsigned(31 downto 0); - --signal D : unsigned(31 downto 0); - --signal E : unsigned(31 downto 0); - --signal F : unsigned(31 downto 0); - signal read_index : integer range 0 to work.task.STREAM_LEN +100; - signal fft_index : integer range 0 to work.task.STREAM_LEN; - signal result : std_logic_vector ( 31 downto 0 ); - signal input_valid : std_logic; - signal input_re : std_logic_vector( 31 downto 0 ); -- in Fixpoint - signal input_im : std_logic_vector( 31 downto 0 ); -- in Fixpoint - signal output_valid : std_logic; - signal output_magnitude : std_logic_vector( 31 downto 0 ); - signal cnt : integer range 0 to work.task.STREAM_LEN; - signal di_en : std_logic; -- Input Data Enable - signal di_re : std_logic_vector(31 downto 0); -- Input Data (Real) - signal di_im : std_logic_vector(31 downto 0); -- Input Data (Imag) - signal do_en : std_logic; -- Output Data Enable - signal do_re : std_logic_vector(31 downto 0); -- Output Data (Real) - signal do_im : std_logic_vector(31 downto 0); -- Output Data (Imag) + 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 + ); - --Port Zuweisung - c_float_fft: entity work.fft_magnitude_calc - PORT MAP ( - clk => clk, - reset => reset, - - input_valid => input_valid, - input_re => input_re, -- in Fixpoint - input_im => input_im, -- in Fixpoint - - output_valid => output_valid, - output_magnitude => output_magnitude - ); - u_fft : fftmain - port map ( - clock => clk, - reset => reset, - - di_en => di_en, - di_re => di_re, - di_im => di_im, - - do_en => do_en, - do_re => do_re, - do_im => do_im - ); - - - - + 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 @@ -136,10 +135,10 @@ case current_task_state is when work.task.TASK_IDLE => if ( task_start = '1' ) then - next_task_state <= work.task.TASK_RUNNING; + next_task_state <= work.task.TASK_RUNNING; end if; when work.task.TASK_RUNNING => - if ( index = (work.task.STREAM_LEN - 1) ) then + if ( index = work.task.STREAM_LEN - 1 ) then next_task_state <= work.task.TASK_DONE; end if; when work.task.TASK_DONE => @@ -149,70 +148,11 @@ end case; end process task_state_transitions; - ---------------------------------------------------------------------- - --FFT Statemachine - fft_state_transitions : process ( all ) is - begin - next_fft_state <= current_fft_state; - case current_fft_state is - when FFTIdle => - if ( current_task_state = work.task.TASK_RUNNING ) then -- Weiterschaltbedingung - next_fft_state <= FFTRead; - end if; - - when FFTRead => - if ( fft_index = work.task.STREAM_LEN ) then - next_fft_state <= FFTWait; - end if; - - when FFTWait => - if ( do_en = '1') then - next_fft_state <= MAGRead; - end if; - - when MAGRead => - if ( output_valid = '1' ) then -- Weiterschaltbedingung - next_fft_state <= MAGStore; - end if; - - when MAGStore => - if ( cnt = (work.task.STREAM_LEN - 1)) then - next_fft_state <= FFTIdle; - end if; - - - end case; - end process fft_state_transitions; - ---------------------------------------------------------------------- - - sync : process ( clk, reset ) is - variable fifo_in : signed(31 downto 0); - variable fifo_in2 : signed(31 downto 0); - variable mag_out : signed(31 downto 0); begin if ( reset = '1' ) then current_task_state <= work.task.TASK_IDLE; index <= 0; - read_index <= 0; - fft_index <= 0; - cnt <= 0; - signal_write <= '0'; - signal_read <= '0'; - input_valid <= '0'; - fifo_in := (others => '0'); - fifo_in2 := (others => '0'); - mag_out := (others => '0'); - -- C <= (others => '0'); - -- D <= (others => '0'); - -- E <= (others => '0'); - --F <= (others => '0'); - input_re <= (others => '0'); - input_im <= (others => '0'); - signal_writedata <= (others => '0'); - di_en <= '0'; - di_re <= (others => '0'); - di_im <= (others => '0'); elsif ( rising_edge( clk ) ) then current_task_state <= next_task_state; case next_task_state is @@ -220,77 +160,93 @@ index <= 0; signal_write <= '0'; when work.task.TASK_RUNNING => - -- index <= index + 1; --Index wird hier hochgezählt, muss in FFT State gemacht werden - -- signal_write <= '1'; - -- signal_writedata <= ( others => '0' ); + index <= index + 1; + signal_write <= '1'; + signal_writedata <= ( others => '0' ); when work.task.TASK_DONE => index <= 0; signal_write <= '0'; end case; - - ---------------------------------------------------------------------- - --Output Statemachine - - current_fft_state <= next_fft_state; - signal_write <= '0'; - signal_read <= '0'; - input_valid <= '0'; - di_en <= '0'; - case next_fft_state is - when FFTIdle => - - when FFTRead => - di_en <= '1'; - signal_read <= '1'; - --fifo_in <= signal_readdata(31 downto 0); - if(signal_readdata(30 downto 23) /= "00000000") then - fifo_in(31) := signal_readdata(31); - fifo_in(30 downto 23) := signed(signal_readdata(30 downto 23)) - 4; - fifo_in(22 downto 0) := signed(signal_readdata(22 downto 0)); - --fifo_in2 := (fifo_in(31) & (signed(fifo_in(30 downto 23)) - 4) & (signed(fifo_in(22 downto 0)))); - - end if; - - di_re <= to_fixed(std_logic_vector(fifo_in)); - di_im <= (others => '0'); - fft_index <= fft_index +1; - when FFTWait => - fft_index <= 0; - when MAGRead => - --D <= do_im(31) & ( unsigned(do_im(30 downto 23)) - B ) & unsigned(do_im(22 downto 0)); - input_valid <= '1'; - input_re <= do_re; - input_im <= do_im; - read_index <= read_index + 1; - when MAGStore => - --read - if(read_index <= work.task.STREAM_LEN) then - --A <= do_re(31) & ( unsigned(do_re(30 downto 23)) - B ) & unsigned(do_re(22 downto 0)); - - --D <= do_im(31) & ( unsigned(do_im(30 downto 23)) - B ) & unsigned(do_im(22 downto 0)); - - signal_read <= '1'; - input_valid <= '1'; - input_re <= do_re; - input_im <= do_im; - read_index <= read_index + 1; - - end if; - --store - signal_write <= '1'; - mag_out(31) := output_magnitude(31) ; - mag_out(30 downto 23) := signed(output_magnitude(30 downto 23)) + 4; - mag_out(22 downto 0) := signed(output_magnitude(22 downto 0)); - signal_writedata <= to_float(std_logic_vector(mag_out)); - index <= index + 1; - cnt <= cnt + 1; - 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; diff --git a/software/signal_processing/fft.c b/software/signal_processing/fft.c index 0fd9581..1036e2a 100644 --- a/software/signal_processing/fft.c +++ b/software/signal_processing/fft.c @@ -26,8 +26,6 @@ void cooley_tukey(float complex *X, const uint32_t N) { } } - - int task_fft_run( void * task ) { fft_config * config = (fft_config*)task; diff --git a/tests/hardware/task_fft/Makefile b/tests/hardware/task_fft/Makefile index c2938fe..d5b0e2a 100644 --- a/tests/hardware/task_fft/Makefile +++ b/tests/hardware/task_fft/Makefile @@ -11,6 +11,8 @@ verilog_srcs = \ vhdl_srcs = \ ../../../hardware/system/reg32.vhd \ ../../../hardware/system/avalon_slave.vhd \ + ../test_utility.vhd \ + ../test_avalon_slave.vhd \ ../../hardware/test_data_channel.vhd \ ../../../hardware/system/avalon_slave_transitions.vhd \ ../../../hardware/system/task.vhd \ @@ -34,3 +36,4 @@ expected_data = ../../data/fft.py include ../data_tests.mk + diff --git a/tests/hardware/task_fft/vsim.wave b/tests/hardware/task_fft/vsim.wave index d2f8057..b8308cd 100644 --- a/tests/hardware/task_fft/vsim.wave +++ b/tests/hardware/task_fft/vsim.wave @@ -1 +1,2 @@ -add wave -position end sim:/test_task_fft/dut/* +add wave -position end sim:/test_task_fft/dut/u_fft/* +