Studentenversion des ESY6/A Praktikums "signal_processing".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fft.vhd 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. ------------------------------------------------------------------------
  2. -- fft
  3. --
  4. -- calculation of FFT magnitude
  5. --
  6. -- Inputs:
  7. -- 32-Bit Floating Point number in range +-16 expected (loaded from FIFO)
  8. --
  9. -- Outputs
  10. -- 32-Bit Floating Point number in range +-16 calculated (stored in FIFO)
  11. --
  12. -----------------------------------------------------------------------
  13. library ieee;
  14. use ieee.std_logic_1164.all;
  15. use ieee.numeric_std.all;
  16. library work;
  17. use work.reg32.all;
  18. use work.task.all;
  19. use work.float.all;
  20. entity fft is
  21. generic (
  22. -- input data width of real/img part
  23. input_data_width : integer := 32;
  24. -- output data width of real/img part
  25. output_data_width : integer := 32
  26. );
  27. port (
  28. clk : in std_logic;
  29. reset : in std_logic;
  30. task_start : in std_logic;
  31. task_state : out work.task.State;
  32. signal_read : out std_logic;
  33. signal_readdata : in std_logic_vector( 31 downto 0 );
  34. signal_write : out std_logic;
  35. signal_writedata : out std_logic_vector( 31 downto 0 )
  36. );
  37. end entity fft;
  38. architecture rtl of fft is
  39. signal current_task_state : work.task.State;
  40. signal next_task_state : work.task.State;
  41. signal index : integer range 0 to work.task.STREAM_LEN;
  42. component fftmain is
  43. -- generic( width : integer := 32
  44. --);
  45. port(
  46. clock: in std_logic;
  47. reset: in std_logic;
  48. di_en: in std_logic;
  49. di_re: in std_logic_vector(input_data_width-1 downto 0);
  50. di_im: in std_logic_vector(input_data_width-1 downto 0);
  51. do_en: out std_logic;
  52. do_re: out std_logic_vector(output_data_width-1 downto 0);
  53. do_im: out std_logic_vector(output_data_width-1 downto 0)
  54. );
  55. end component;
  56. -- Zustände für die Zustandsmaschine zur Berechnung
  57. type SigState is (
  58. SIG_IDLE,
  59. SIG_READ,
  60. SIG_FFTMAIN,
  61. SIG_FFTMAG,
  62. SIG_WRITE
  63. );
  64. signal current_sig_state : SigState;
  65. signal next_sig_state : SigState;
  66. signal fftmain_start : std_logic;
  67. signal fftmain_done : std_logic;
  68. signal fftmag_start : std_logic;
  69. signal fftmag_done : std_logic;
  70. signal fftmain_out_re : std_logic_vector( 31 downto 0 );
  71. signal fftmain_out_im : std_logic_vector( 31 downto 0 );
  72. signal exp : std_logic_vector( 7 downto 0);
  73. signal scaled_exp : std_logic_vector( 7 downto 0);
  74. signal scaled_readdata : std_logic_vector( 31 downto 0);
  75. signal exp_int : integer;
  76. signal scaled_data_fixp : std_logic_vector(31 downto 0);
  77. signal exp2 : std_logic_vector( 7 downto 0);
  78. signal scaled_exp2 : std_logic_vector( 7 downto 0);
  79. signal exp_int2 : integer;
  80. signal magnitude_output : std_logic_vector( 31 downto 0 );
  81. signal writedata_float : std_logic_vector( 31 downto 0 );
  82. type std_logic_vector_array is array (0 to 1023) of std_logic_vector(31 downto 0);
  83. signal my_array : std_logic_vector_array;
  84. begin
  85. exp <= signal_readdata( 30 downto 23 );
  86. exp_int <= to_integer(unsigned(exp));
  87. scaled_exp <= std_logic_vector(to_unsigned(exp_int - 4, 8));
  88. scaled_readdata <= signal_readdata( 31 ) & scaled_exp & signal_readdata( 22 downto 0 );
  89. scaled_data_fixp <= to_fixed(scaled_readdata);
  90. writedata_float <= to_float(magnitude_output);
  91. exp2 <= writedata_float( 30 downto 23 );
  92. exp_int2 <= to_integer(unsigned(exp2));
  93. scaled_exp2 <= std_logic_vector(to_unsigned(exp_int2 + 5, 8));
  94. my_array(1023 - index) <= writedata_float( 31 ) & scaled_exp2 & writedata_float( 22 downto 0 );
  95. signal_writedata <= my_array(index);
  96. u_fft : fftmain
  97. port map (
  98. clock => clk,
  99. reset => reset,
  100. di_en => fftmain_start,
  101. di_re => scaled_data_fixp,
  102. di_im => x"00000000",
  103. do_en => fftmain_done,
  104. do_re => fftmain_out_re,
  105. do_im => fftmain_out_im
  106. );
  107. u_fft_mag_calc : entity work.fft_magnitude_calc
  108. port map (
  109. clk => clk,
  110. reset => reset,
  111. input_valid => fftmag_start,
  112. input_re => fftmain_out_re,
  113. input_im => fftmain_out_im,
  114. output_valid => fftmag_done,
  115. output_magnitude => magnitude_output
  116. );
  117. task_state_transitions : process ( current_task_state, task_start, index ) is
  118. begin
  119. next_task_state <= current_task_state;
  120. case current_task_state is
  121. when work.task.TASK_IDLE =>
  122. if ( task_start = '1' ) then
  123. next_task_state <= work.task.TASK_RUNNING;
  124. end if;
  125. when work.task.TASK_RUNNING =>
  126. if ( index = work.task.STREAM_LEN - 1 ) then
  127. next_task_state <= work.task.TASK_DONE;
  128. end if;
  129. when work.task.TASK_DONE =>
  130. if ( task_start = '1' ) then
  131. next_task_state <= work.task.TASK_RUNNING;
  132. end if;
  133. end case;
  134. end process task_state_transitions;
  135. sig_state_transitions : process (all) is
  136. begin
  137. next_sig_state <= current_sig_state;
  138. case current_sig_state is
  139. when SIG_IDLE =>
  140. if ( current_task_state = work.task.TASK_RUNNING ) then
  141. next_sig_state <= SIG_READ;
  142. end if;
  143. when SIG_READ =>
  144. next_sig_state <= SIG_FFTMAIN;
  145. when SIG_FFTMAIN =>
  146. if ( fftmain_done = '1') then
  147. next_sig_state <= SIG_FFTMAG;
  148. end if;
  149. when SIG_FFTMAG =>
  150. if ( fftmain_done = '0') then
  151. next_sig_state <= SIG_WRITE;
  152. end if;
  153. when SIG_WRITE =>
  154. null;
  155. end case;
  156. end process sig_state_transitions;
  157. sync : process ( clk, reset ) is
  158. begin
  159. if ( reset = '1' ) then
  160. current_task_state <= work.task.TASK_IDLE;
  161. current_sig_state <= SIG_IDLE;
  162. index <= 0;
  163. signal_read <= '0';
  164. fftmain_start <= '0';
  165. fftmag_start <= '0';
  166. signal_write <= '0';
  167. elsif ( rising_edge( clk ) ) then
  168. current_task_state <= next_task_state;
  169. case next_task_state is
  170. when work.task.TASK_IDLE =>
  171. null;
  172. when work.task.TASK_RUNNING =>
  173. null;
  174. when work.task.TASK_DONE =>
  175. null;
  176. end case;
  177. current_sig_state <= next_sig_state;
  178. case next_sig_state is
  179. when SIG_IDLE =>
  180. signal_write <= '0';
  181. when SIG_READ =>
  182. signal_read <= '1';
  183. when SIG_FFTMAIN =>
  184. fftmain_start <= '1';
  185. when SIG_FFTMAG =>
  186. signal_read <= '0';
  187. fftmain_start <= '0';
  188. fftmag_start <= '1';
  189. signal_write <= '0';
  190. index <= index + 1;
  191. when SIG_WRITE =>
  192. fftmag_start <= '0';
  193. signal_write <= '1';
  194. end case;
  195. end if;
  196. end process sync;
  197. task_state <= current_task_state;
  198. end architecture rtl;