Files of a 5*2^n VHDL entity using Winograd5 and radix2 implementations
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

260 lignes
14KB

  1. LIBRARY ieee;
  2. USE ieee.std_logic_1164.ALL;
  3. USE ieee.std_logic_signed.ALL;
  4. USE ieee.numeric_std.ALL;
  5. USE work.FIVEn_DFT_PKG.ALL;
  6. USE work.coeff.ALL;
  7. ENTITY FFT_tree IS
  8. PORT(
  9. i_clk : IN std_logic;
  10. i_data_re : IN vect_dft_input;
  11. i_data_im : IN vect_dft_input;
  12. o_data_re : OUT vect_dft_output;
  13. o_data_im : OUT vect_dft_output
  14. );
  15. END FFT_tree;
  16. ARCHITECTURE instanciating_cells OF FFT_tree IS
  17. SIGNAL cos_k_pi_over_5 : vect_cos_sin_k_pi_over_5_32b := ("01000000000000000000000000000000", "00110011110001101110111100110111", "00010011110001101110111100110111", "11101100001110010001000011001001", "11001100001110010001000011001001"); -- coeffs multiplied by 2^30
  18. SIGNAL sin_k_pi_over_5 : vect_cos_sin_k_pi_over_5_32b := ("00000000000000000000000000000000", "11011010011000011011100111110111", "11000011001000011110001111011001", "11000011001000011110001111011001", "11011010011000011011100111110111"); -- coeffs multiplied by 2^30
  19. -- purpose: give the proper arrangement for the winograd5 blks
  20. -- the right order: even numbers then odd numbers. The even numbers are the
  21. -- result of others even_odd order multiplied by 2, the odd numbers are the
  22. -- result of others even_odd order multiplied by 2+1.
  23. -- input: the nth winograd5 instance when sort
  24. -- output: the corresponding winograd5 instance number when sort
  25. FUNCTION rearrange (
  26. i : IN natural)
  27. RETURN natural IS
  28. TYPE vect_rearrange IS ARRAY (0 TO cst_nb_samples_in_5ndft) OF natural;
  29. TYPE matrix_rearrange IS ARRAY (0 TO cst_log2_nb_parallel_winograd5) OF vect_rearrange;
  30. VARIABLE matrix_affect_rearrange : matrix_rearrange := (OTHERS => (OTHERS => 0));
  31. BEGIN -- FUNCTION rearrange
  32. IF cst_log2_nb_parallel_winograd5 > 0 THEN
  33. matrix_affect_rearrange(1)(1) := 1;
  34. FOR stage IN 2 TO cst_log2_nb_parallel_winograd5 LOOP
  35. FOR i IN 0 TO 2**(stage-1)-1 LOOP
  36. matrix_affect_rearrange(stage)(i) := matrix_affect_rearrange(stage-1)(i)*2;
  37. matrix_affect_rearrange(stage)(i+2**(stage-1)) := matrix_affect_rearrange(stage-1)(i)*2+1;
  38. END LOOP; -- i
  39. END LOOP; -- stage
  40. RETURN matrix_affect_rearrange(cst_log2_nb_parallel_winograd5)(i);
  41. ELSE
  42. RETURN 0;
  43. END IF;
  44. END FUNCTION rearrange;
  45. TYPE matrix_input_winograd5_5ndft IS ARRAY (0 TO cst_nb_parallel_winograd5-1) OF vect_input_winograd5_5ndft;
  46. TYPE matrix_output_winograd5_5ndft IS ARRAY (0 TO cst_nb_parallel_winograd5-1) OF vect_output_winograd5_5ndft;
  47. SIGNAL cos_k_pi_over_5_wb : vect_cos_sin_k_pi_over_5_wb := (OTHERS => (OTHERS => '0'));
  48. SIGNAL sin_k_pi_over_5_wb : vect_cos_sin_k_pi_over_5_wb := (OTHERS => (OTHERS => '0'));
  49. SIGNAL data_out_winograd5_re : vect_total_output_winograd5_cells := (OTHERS => (OTHERS => '0'));
  50. SIGNAL data_out_winograd5_im : vect_total_output_winograd5_cells := (OTHERS => (OTHERS => '0'));
  51. SIGNAL winograd_rearranged_input_re : vect_dft_input := (OTHERS => (OTHERS => '0'));
  52. SIGNAL winograd_rearranged_input_im : vect_dft_input := (OTHERS => (OTHERS => '0'));
  53. SIGNAL matrix_inputs_outputs_radix2_cells_re : matrix_fft_stages := (OTHERS => (OTHERS => (OTHERS => '0')));
  54. SIGNAL matrix_inputs_outputs_radix2_cells_im : matrix_fft_stages := (OTHERS => (OTHERS => (OTHERS => '0')));
  55. SIGNAL vect_input_1_cell_winograd5_re : matrix_input_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0')));
  56. SIGNAL vect_input_1_cell_winograd5_im : matrix_input_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0')));
  57. SIGNAL vect_output_1_cell_winograd5_re : matrix_output_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0')));
  58. SIGNAL vect_output_1_cell_winograd5_im : matrix_output_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0')));
  59. BEGIN -- ARCHITECTURE instanciating_cells
  60. -- coeffs cut
  61. -- purpose: Rounds the data in 32bits into cst_w_precision_radix2_coeffs_5ndft bits (round for
  62. -- MSBs). Should run and cut before simulation and bitstream
  63. -- inputs : the coeffs to be cut sin_k_pi_over_5, cos_k_pi_over_5, sin_k_pi_over_80, cos_k_pi_over_80
  64. -- outputs: the cut coeffs cos_k_pi_over_5_wb, sin_k_pi_over_5_wb, sin_k_pi_over_80_wb, cos_k_pi_over_80_wb
  65. mult_coeffs_cut : PROCESS(sin_k_pi_over_5, cos_k_pi_over_5)
  66. BEGIN
  67. FOR i IN 0 TO 4 LOOP
  68. cos_k_pi_over_5_wb(i) <= cos_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft);
  69. sin_k_pi_over_5_wb(i) <= sin_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft);
  70. IF(cos_k_pi_over_5(i)(32-cst_w_precision_radix2_coeffs_5ndft-1) = '1') THEN
  71. cos_k_pi_over_5_wb(i) <= std_logic_vector(unsigned(signed(cos_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft))+1));
  72. END IF;
  73. IF(sin_k_pi_over_5(i)(32-cst_w_precision_radix2_coeffs_5ndft-1) = '1') THEN
  74. sin_k_pi_over_5_wb(i) <= std_logic_vector(unsigned(signed(sin_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft))+1));
  75. END IF;
  76. END LOOP; -- i
  77. END PROCESS mult_coeffs_cut;
  78. -- inputs rearranging
  79. -- purpose: affects inputs on their right way (cf. schema and explanations)
  80. -- using the rearrange(i) function, which creates the right winograd
  81. -- instances numbers order. Rearranging inputs order is equivalent to rearranging
  82. -- winograd5 order.
  83. -- inputs: i_data_re, i_data_im
  84. -- outputs: winograd_rearranged_input_re, winograd_rearranged_input_im
  85. rearrange_winograd_input : FOR i IN 0 TO cst_nb_parallel_winograd5-1 GENERATE
  86. five_inputs : FOR j IN 0 TO 4 GENERATE
  87. winograd_rearranged_input_re(rearrange(i => i)*5+j) <= i_data_re(j*cst_nb_parallel_winograd5+i);
  88. winograd_rearranged_input_im(rearrange(i => i)*5+j) <= i_data_im(j*cst_nb_parallel_winograd5+i);
  89. END GENERATE five_inputs;
  90. END GENERATE rearrange_winograd_input;
  91. -- winograd instanciating
  92. -- purpose: wiring; instanciates the parallel winograd stage with their correct inputs and outputs
  93. -- inputs: winograd_rearranged_input_im, winograd_rearranged_input_re (length
  94. -- cst_nb_samples_in_5ndft each, cut then into subvectors of 5 inputs)
  95. -- instances: WINOGRAD5(Behavioral)
  96. -- outputs: vect_output_1_cell_winograd5_im, vect_output_1_cell_winograd5_re
  97. -- (length cst_nb_samples_in_5ndft each, cut then into subvectors of 5 inputs)
  98. winograd5_instances : FOR i IN 0 TO cst_nb_parallel_winograd5-1 GENERATE
  99. fill_for : FOR j IN 0 TO 4 GENERATE
  100. vect_input_1_cell_winograd5_im(i)(j) <= winograd_rearranged_input_im(j+5*i);
  101. vect_input_1_cell_winograd5_re(i)(j) <= winograd_rearranged_input_re(j+5*i);
  102. data_out_winograd5_im(j+5*i) <= vect_output_1_cell_winograd5_im(i)(j);
  103. data_out_winograd5_re(j+5*i) <= vect_output_1_cell_winograd5_re(i)(j);
  104. END GENERATE fill_for;
  105. winograd5_inst : ENTITY work.WINOGRAD5(Behavioral)
  106. PORT MAP(
  107. i_clk => i_clk,
  108. i_data_im => vect_input_1_cell_winograd5_im(i),
  109. i_data_re => vect_input_1_cell_winograd5_re(i),
  110. o_data_im => vect_output_1_cell_winograd5_im(i),
  111. o_data_re => vect_output_1_cell_winograd5_re(i)
  112. );
  113. END GENERATE winograd5_instances;
  114. -- winograd results
  115. -- purpose: fill the 0th stage (input stage) of the matrix instanciating the
  116. -- butterfly (radix2) cells only.
  117. -- inputs: data_out_winograd5_re, data_out_winograd5_im
  118. -- outputs: matrix_inputs_outputs_radix2_cells_re(x)(0), matrix_inputs_outputs_radix2_cells_im(x)(0)
  119. fill_radix2_cells_input_matrix : FOR i IN 0 TO cst_nb_samples_in_5ndft-1 GENERATE
  120. matrix_inputs_outputs_radix2_cells_re(i)(0)(cst_winograd5_w_out_5ndft-1 DOWNTO 0) <= data_out_winograd5_re(i);
  121. matrix_inputs_outputs_radix2_cells_im(i)(0)(cst_winograd5_w_out_5ndft-1 DOWNTO 0) <= data_out_winograd5_im(i);
  122. END GENERATE fill_radix2_cells_input_matrix;
  123. -- purpose: instanciates the first butterfly cells stage (after the winograd
  124. -- results). If there is only 1 parallel winograd5 cell, couple_winograd5_nb
  125. -- will not be use between 0 and -1, so the FOR loop will no execute
  126. -- inputs: matrix_inputs_outputs_radix2_cells_re(x)(0), matrix_inputs_outputs_radix2_cells_im(x)(0)
  127. -- instances: radix_2_cell_winograd(radix2)
  128. -- outputs: matrix_inputs_outputs_radix2_cells_re(x)(1), matrix_inputs_outputs_radix2_cells_im(x)(1)
  129. radix2_cells_stage1 : FOR couple_winograd5_nb IN 0 TO cst_nb_parallel_winograd5/2-1 GENERATE
  130. radix2_winograd_out : FOR i IN 0 TO 4 GENERATE
  131. radix_2_out_winograd_inst : ENTITY work.radix_2_cell_winograd(radix2)
  132. GENERIC MAP(
  133. w_in => cst_winograd5_w_out_5ndft
  134. )
  135. PORT MAP(
  136. i_clk => i_clk,
  137. i_cos => cos_k_pi_over_5_wb(i MOD 5),
  138. i_sin => sin_k_pi_over_5_wb(i MOD 5),
  139. i_data1_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i)(0),
  140. i_data1_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i)(0),
  141. i_data2_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i+5)(0),
  142. i_data2_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i+5)(0),
  143. o_data1_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i)(1),
  144. o_data1_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i)(1),
  145. o_data2_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i+5)(1),
  146. o_data2_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i+5)(1)
  147. );
  148. END GENERATE radix2_winograd_out;
  149. END GENERATE radix2_cells_stage1;
  150. -- radix2 cells instanciation
  151. -- purpose: instanciates all the butterfly stages (except stage 1). The
  152. -- stages are filled decrementing the stage number
  153. -- inputs: matrix_inputs_outputs_radix2_cells_re(x)(1), matrix_inputs_outputs_radix2_cells_im(x)(1)
  154. -- instances: radix_2_cell_winograd(radix2)
  155. -- outputs: matrix_inputs_outputs_radix2_cells_re(x)(cst_log2_nb_parallel_winograd5), matrix_inputs_outputs_radix2_cells_im(x)(cst_log2_nb_parallel_winograd5)
  156. stages_generation : FOR stage IN 1 TO cst_log2_nb_parallel_winograd5-1 GENERATE
  157. k10_blocks : FOR cell_10_nb IN 1 TO 2**(stage-1) GENERATE
  158. parallel_cells : FOR cell_nb IN (cst_nb_samples_in_5ndft/(2**stage))*(cell_10_nb-1) TO (cst_nb_samples_in_5ndft/(2**stage))*(cell_10_nb)-1 GENERATE
  159. radix_2_generic_inst : ENTITY work.radix_2_cell_winograd(radix2)
  160. GENERIC MAP(
  161. w_in => cst_winograd5_w_out_5ndft+(cst_log2_nb_parallel_winograd5-stage)*cst_w_radix2_added
  162. )
  163. PORT MAP(
  164. i_clk => i_clk,
  165. i_cos => cos_k_pi_over_n_wb((cst_nb_wn_coeffs/10/(2**(cst_log2_nb_parallel_winograd5-stage-1))*cell_nb) MOD cst_nb_wn_coeffs),
  166. i_sin => sin_k_pi_over_n_wb((cst_nb_wn_coeffs/10/(2**(cst_log2_nb_parallel_winograd5-stage-1))*cell_nb) MOD cst_nb_wn_coeffs),
  167. i_data1_re => matrix_inputs_outputs_radix2_cells_re(cell_nb)(cst_log2_nb_parallel_winograd5-stage),
  168. i_data1_im => matrix_inputs_outputs_radix2_cells_im(cell_nb)(cst_log2_nb_parallel_winograd5-stage),
  169. i_data2_re => matrix_inputs_outputs_radix2_cells_re(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage),
  170. i_data2_im => matrix_inputs_outputs_radix2_cells_im(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage),
  171. o_data1_re => matrix_inputs_outputs_radix2_cells_re(cell_nb)(cst_log2_nb_parallel_winograd5-stage+1),
  172. o_data1_im => matrix_inputs_outputs_radix2_cells_im(cell_nb)(cst_log2_nb_parallel_winograd5-stage+1),
  173. o_data2_re => matrix_inputs_outputs_radix2_cells_re(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage+1),
  174. o_data2_im => matrix_inputs_outputs_radix2_cells_im(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage+1)
  175. );
  176. END GENERATE parallel_cells;
  177. END GENERATE k10_blocks;
  178. END GENERATE stages_generation;
  179. -- output results
  180. -- purpose: rounds the outputs to have cst_w_out_5ndft bits. Does not round
  181. -- if cst_w_out_5ndft = cst_dft_w_out_5ndft
  182. -- type : sequential
  183. -- inputs : i_clk, matrix_inputs_outputs_radix2_cells_re, matrix_inputs_outputs_radix2_cells_im
  184. -- outputs: o_data_re, i_data_im
  185. output_rounding : PROCESS (i_clk) IS
  186. BEGIN -- PROCESS output_rounding
  187. IF rising_edge(i_clk) THEN -- rising clock edge
  188. FOR i IN 0 TO cst_nb_samples_in_5ndft-1 LOOP
  189. IF(matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24-cst_w_out_5ndft) = '1' AND cst_w_out_5ndft < cst_dft_w_out_5ndft) THEN
  190. o_data_re(i) <= std_logic_vector(unsigned(signed(matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft))+1));
  191. ELSE
  192. o_data_re(i) <= matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft);
  193. END IF;
  194. IF(matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24-cst_w_out_5ndft) = '1' AND cst_w_out_5ndft < cst_dft_w_out_5ndft) THEN
  195. o_data_im(i) <= std_logic_vector(unsigned(signed(matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft))+1));
  196. ELSE
  197. o_data_im(i) <= matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft);
  198. END IF;
  199. END LOOP; -- i
  200. END IF;
  201. END PROCESS output_rounding;
  202. -- if you prefer the whole result, uncomment this section and comment the
  203. -- output_rounding process above. You should also change smpl_out_5ndft from
  204. -- cst_w_out_5ndft to cst_dft_w_out_5ndft (line 32 in FIVEn_dft_pkg).
  205. --fill_outputs : FOR i IN 0 TO cst_nb_samples_in_5ndft-1 GENERATE
  206. -- o_data_re(i) <= matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5);
  207. -- o_data_im(i) <= matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5);
  208. --END GENERATE fill_outputs;
  209. END ARCHITECTURE instanciating_cells;