|
|
|
|
|
|
|
|
|
|
|
|
|
|
type fft_state_dec is ( |
|
|
type fft_state_dec is ( |
|
|
FFT_STATE_IDLE, |
|
|
FFT_STATE_IDLE, |
|
|
FFT_STATE_READ, |
|
|
|
|
|
FFT_STATE_SCALE, |
|
|
|
|
|
FFT_STATE_FFT, |
|
|
|
|
|
FFT_STATE_MAGNITUDE, |
|
|
|
|
|
FFT_STATE_REVERSE_ORDER, |
|
|
|
|
|
|
|
|
FFT_STATE_FILL_IP_CORE, |
|
|
|
|
|
FFT_STATE_GET_IP_CORE, |
|
|
|
|
|
FFT_STATE_SORT, |
|
|
FFT_STATE_WRITE, |
|
|
FFT_STATE_WRITE, |
|
|
FFT_STATE_DONE |
|
|
FFT_STATE_DONE |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
signal value_data_in_ready : std_logic; |
|
|
signal value_data_in_ready : std_logic; |
|
|
signal value_data_in_real : std_logic_vector(31 downto 0); |
|
|
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 : 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_in_imag : std_logic_vector(31 downto 0); |
|
|
signal value_data_out_ready : std_logic; |
|
|
signal value_data_out_ready : std_logic; |
|
|
signal value_data_out_real : std_logic_vector(31 downto 0); |
|
|
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_imag : std_logic_vector(31 downto 0); |
|
|
signal value_data_out_mag : 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_in_ready: std_logic; |
|
|
signal value_mag_out_ready: std_logic; |
|
|
signal value_mag_out_ready: std_logic; |
|
|
|
|
|
|
|
|
signal fft_state : fft_state_dec := FFT_STATE_IDLE; |
|
|
signal fft_state : fft_state_dec := FFT_STATE_IDLE; |
|
|
signal flag_index : bit; |
|
|
signal flag_index : bit; |
|
|
|
|
|
signal write_done_flag : bit; |
|
|
|
|
|
|
|
|
|
|
|
--signal memory_scale : work.reg.32.RegArray(0 to 1023); |
|
|
|
|
|
|
|
|
begin |
|
|
begin |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fft_calc : FFTMAIN |
|
|
fft_calc : FFTMAIN |
|
|
port map ( |
|
|
port map ( |
|
|
clock => clk, |
|
|
clock => clk, |
|
|
reset => reset, |
|
|
reset => reset, |
|
|
di_en => value_data_in_ready, |
|
|
di_en => value_data_in_ready, |
|
|
di_re => value_data_in_real_scaled, |
|
|
|
|
|
|
|
|
di_re => value_data_in_real_scaled_fixed, |
|
|
di_im => value_data_in_imag, |
|
|
di_im => value_data_in_imag, |
|
|
do_en => value_data_out_ready, |
|
|
do_en => value_data_out_ready, |
|
|
do_re => value_data_out_real, |
|
|
do_re => value_data_out_real, |
|
|
|
|
|
|
|
|
output_valid => value_mag_out_ready, |
|
|
output_valid => value_mag_out_ready, |
|
|
output_magnitude => value_data_out_mag |
|
|
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; |
|
|
|
|
|
|
|
|
-- 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 |
|
|
fft : process (clk, reset) is |
|
|
|
|
|
variable fifo_in : signed(31 downto 0); |
|
|
|
|
|
variable fifo_out : signed(31 downto 0); |
|
|
begin |
|
|
begin |
|
|
-- Bei Reset alle Signale zurücksetzen |
|
|
-- Bei Reset alle Signale zurücksetzen |
|
|
if ( reset = '1' ) then |
|
|
if ( reset = '1' ) then |
|
|
value_data_in_ready <= '0'; |
|
|
value_data_in_ready <= '0'; |
|
|
value_data_in_real <= ( others => '0'); |
|
|
value_data_in_real <= ( others => '0'); |
|
|
value_data_in_imag <= ( 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. |
|
|
|
|
|
|
|
|
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 |
|
|
elsif ( rising_edge( clk ) ) then |
|
|
case fft_state is |
|
|
case fft_state is |
|
|
when FFT_STATE_IDLE => |
|
|
when FFT_STATE_IDLE => |
|
|
|
|
|
flag_index <= '0'; |
|
|
if ( current_task_state = work.task.TASK_RUNNING ) then |
|
|
if ( current_task_state = work.task.TASK_RUNNING ) then |
|
|
fft_state <= FFT_STATE_READ; |
|
|
|
|
|
|
|
|
fft_state <= FFT_STATE_FILL_IP_CORE; |
|
|
end if; |
|
|
end if; |
|
|
when FFT_STATE_READ => |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
when FFT_STATE_FILL_IP_CORE => |
|
|
|
|
|
|
|
|
|
|
|
value_data_in_ready <= '1'; |
|
|
signal_read <= '1'; |
|
|
signal_read <= '1'; |
|
|
|
|
|
|
|
|
value_data_in_real <= signal_readdata; |
|
|
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 |
|
|
if value_data_in_real(30 downto 23) = "00000000" then |
|
|
value_data_in_real_scaled <= value_data_in_real; |
|
|
|
|
|
|
|
|
value_data_in_real_scaled_fixed <= to_fixed(value_data_in_real); |
|
|
else |
|
|
else |
|
|
value_data_in_real_scaled(30 downto 23) <= std_logic_vector(signed(value_data_in_real(30 downto 23)) - 4); |
|
|
|
|
|
|
|
|
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; |
|
|
end if; |
|
|
|
|
|
|
|
|
fft_state <= FFT_STATE_FFT; |
|
|
|
|
|
|
|
|
|
|
|
when FFT_STATE_FFT => |
|
|
|
|
|
|
|
|
if (value_data_out_ready = '1') then |
|
|
|
|
|
fft_state <= FFT_STATE_GET_IP_CORE; |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
value_data_in_ready <= '1'; |
|
|
|
|
|
|
|
|
when FFT_STATE_GET_IP_CORE => |
|
|
|
|
|
|
|
|
|
|
|
signal_read <= '0'; |
|
|
|
|
|
|
|
|
if ( value_data_out_ready = '1' ) then |
|
|
|
|
|
fft_state <= FFT_STATE_MAGNITUDE; |
|
|
|
|
|
end if; |
|
|
|
|
|
|
|
|
value_mag_in_ready <= '1'; |
|
|
|
|
|
|
|
|
|
|
|
value_data_out_mag_float <= to_float(value_data_out_mag); |
|
|
|
|
|
|
|
|
when FFT_STATE_MAGNITUDE => |
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
value_mag_in_ready <= '1'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memory(index) <= value_data_out_mag_float_scaled; |
|
|
|
|
|
|
|
|
if (value_mag_out_ready = '1') then |
|
|
if (value_mag_out_ready = '1') then |
|
|
fft_state <= FFT_STATE_WRITE; |
|
|
|
|
|
|
|
|
flag_index <= '1'; |
|
|
end if; |
|
|
end if; |
|
|
|
|
|
|
|
|
when FFT_STATE_REVERSE_ORDER => |
|
|
|
|
|
|
|
|
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 => |
|
|
|
|
|
|
|
|
when FFT_STATE_WRITE => |
|
|
|
|
|
|
|
|
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_write <= '1'; |
|
|
signal_writedata <= value_data_out_mag; |
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
fft_state <= FFT_STATE_DONE; |
|
|
|
|
|
|
|
|
|
|
|
when FFT_STATE_DONE => |
|
|
when FFT_STATE_DONE => |
|
|
|
|
|
|
|
|
signal_read <= '0'; |
|
|
|
|
|
|
|
|
|
|
|
signal_write <= '0'; |
|
|
signal_write <= '0'; |
|
|
|
|
|
flag_index <= '0'; |
|
|
|
|
|
signal_read <= '0'; |
|
|
value_data_in_ready <= '0'; |
|
|
value_data_in_ready <= '0'; |
|
|
value_data_out_ready <= '0'; |
|
|
|
|
|
value_mag_in_ready <= '0'; |
|
|
value_mag_in_ready <= '0'; |
|
|
value_mag_out_ready <= '0'; |
|
|
|
|
|
|
|
|
|
|
|
fft_state <= FFT_STATE_IDLE; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end case; |
|
|
end case; |
|
|
end if; |
|
|
end if; |