VHDL implementation of a polyphase filter bank with polyphase filter and 5ndft
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.

307 lines
16KB

  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. ENTITY WINOGRAD5 IS
  7. PORT(
  8. i_clk : IN std_logic;
  9. i_data_im : IN vect_input_winograd5_5ndft;
  10. i_data_re : IN vect_input_winograd5_5ndft;
  11. o_data_im : OUT vect_output_winograd5_5ndft := (OTHERS => (OTHERS => '0'));
  12. o_data_re : OUT vect_output_winograd5_5ndft := (OTHERS => (OTHERS => '0'))
  13. );
  14. END WINOGRAD5;
  15. ARCHITECTURE Behavioral OF WINOGRAD5 IS
  16. SIGNAL mult_factors : vect_mult_factors_32b := ("10110000000000000000000000000000", "00100011110001101110111100110111", "00010111001111111101011000011110", "01100010011111000110001000101111", "00100101100111100100011000001001");
  17. -- multipliers multiplied by 2^30
  18. SIGNAL mult_factor_w_multipliers : vect_mult_factor_w_multipliers := (OTHERS => (OTHERS => '0'));
  19. --SIGNAL matrix_stages_signed_im : matrix_winograd5_generic_signed_stages := (OTHERS => (OTHERS => (OTHERS => '0')));
  20. --SIGNAL matrix_stages_signed_re : matrix_winograd5_generic_signed_stages := (OTHERS => (OTHERS => (OTHERS => '0')));
  21. SIGNAL matrix_stages_im : matrix_winograd5_generic_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); --matrix(x)(y) = matrix(stage)(layer) form
  22. SIGNAL matrix_stages_re : matrix_winograd5_generic_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); -- matrix(x)(y) = matrix(stage)(layer) form
  23. SIGNAL multiply_by_2_power_cst_w_precision : std_logic_vector(cst_w_precision_winograd5_coeffs_5ndft-3 DOWNTO 0) := (OTHERS => '0');
  24. --SIGNAL in1, in2 : smpl_out_winograd5_5ndft;
  25. --SIGNAL isigned : smpl_out_winograd5_signed_5ndft;
  26. FUNCTION add_sub (
  27. w_smpl : IN natural;
  28. sub : IN boolean;
  29. in1, in2 : IN smpl_out_winograd5_5ndft)
  30. RETURN smpl_out_winograd5_5ndft IS
  31. VARIABLE smpl_stages_out : smpl_out_winograd5_5ndft := (OTHERS => '0');
  32. BEGIN
  33. IF sub THEN
  34. smpl_stages_out(w_smpl DOWNTO 0) := std_logic_vector(unsigned(signed(in1(w_smpl-1)&in1(w_smpl-1 DOWNTO 0))-signed(in2(w_smpl-1)&in2(w_smpl-1 DOWNTO 0))));
  35. ELSE
  36. smpl_stages_out(w_smpl DOWNTO 0) := std_logic_vector(unsigned(signed(in1(w_smpl-1)&in1(w_smpl-1 DOWNTO 0))+signed(in2(w_smpl-1)&in2(w_smpl-1 DOWNTO 0))));
  37. END IF;
  38. RETURN smpl_stages_out;
  39. END FUNCTION;
  40. FUNCTION mult (
  41. w_smpl : IN natural;
  42. cmplx : IN boolean;
  43. w_coeff : IN natural;
  44. input : IN smpl_out_winograd5_5ndft;
  45. coeff : IN smpl_mult_factor_w_multipliers
  46. )
  47. RETURN std_logic_vector IS
  48. VARIABLE smpl_signed : smpl_out_winograd5_signed_5ndft := (OTHERS => '0');
  49. VARIABLE smpl_out : smpl_out_winograd5_5ndft;
  50. BEGIN -- FUNCTION mult
  51. IF(cmplx) THEN
  52. smpl_signed(w_smpl+w_coeff-1 DOWNTO 0) := signed(input(w_smpl-1 DOWNTO 0)) * (-signed(coeff));
  53. ELSE
  54. smpl_signed(w_smpl+w_coeff-1 DOWNTO 0) := signed(input(w_smpl-1 DOWNTO 0)) * signed(coeff);
  55. END IF;
  56. smpl_out := std_logic_vector(unsigned(smpl_signed));
  57. RETURN smpl_out;
  58. END FUNCTION mult;
  59. FUNCTION smpl_copy (
  60. w_smpl : natural;
  61. smpl_in : smpl_out_winograd5_5ndft)
  62. RETURN std_logic_vector IS
  63. VARIABLE smpl_out : smpl_out_winograd5_5ndft := (OTHERS => '0');
  64. BEGIN -- FUNCTION copy
  65. smpl_out(w_smpl DOWNTO 0) := smpl_in(w_smpl-1)&smpl_in(w_smpl-1 DOWNTO 0);
  66. RETURN smpl_out; --smpl_in(cst_winograd5_w_out_5ndft-1 DOWNTO w_smpl+1)&smpl_in(w_smpl-1)&smpl_in(w_smpl-1 DOWNTO 0);--smpl_out;
  67. END FUNCTION smpl_copy;
  68. BEGIN
  69. fill_input_output_matrix_for : FOR i IN 0 TO 4 GENERATE
  70. matrix_stages_im(0)(i)(cst_w_in_5ndft-1 DOWNTO 0) <= i_data_im(i)(cst_w_in_5ndft-1 DOWNTO 0);
  71. matrix_stages_re(0)(i)(cst_w_in_5ndft-1 DOWNTO 0) <= i_data_re(i)(cst_w_in_5ndft-1 DOWNTO 0);
  72. o_data_im(i) <= matrix_stages_im(7)(i);
  73. o_data_re(i) <= matrix_stages_re(7)(i);
  74. END GENERATE fill_input_output_matrix_for;
  75. -- purpose: Rounds the data in 32bits into cst_w_precision_winograd5_coeffs_5ndft bits (round for
  76. -- MSBs). Should run and cut before simulation and bitstream
  77. -- inputs : the coeffs to be cut mult_factors
  78. -- outputs: the cut coeffs mult_factor_w_multipliers
  79. mult_coeffs_cut : PROCESS(mult_factors)
  80. BEGIN
  81. FOR i IN 1 TO 5 LOOP
  82. mult_factor_w_multipliers(i) <= mult_factors(i)(31 DOWNTO 32-cst_w_precision_winograd5_coeffs_5ndft);
  83. IF(mult_factors(i)(31-cst_w_precision_winograd5_coeffs_5ndft) = '1') THEN
  84. mult_factor_w_multipliers(i) <= std_logic_vector(unsigned(signed(mult_factors(i)(31 DOWNTO 32-cst_w_precision_winograd5_coeffs_5ndft)) +1));
  85. END IF;
  86. END LOOP; -- i
  87. END PROCESS mult_coeffs_cut;
  88. -- purpose: calculates each stage following the winograd5 schema
  89. -- inputs: matrix_stages_im(0)
  90. -- outputs: matrix_stages_im(7)
  91. calculations_process : PROCESS(i_clk)
  92. VARIABLE w_smpl : natural;
  93. BEGIN
  94. IF(rising_edge(i_clk)) THEN
  95. -- stage 1
  96. -- w_smpl :=== cst_w_in_5ndft+1;
  97. --data0
  98. matrix_stages_im(1)(0) <= smpl_copy(w_smpl => cst_w_in_5ndft, smpl_in => matrix_stages_im(0)(0));
  99. matrix_stages_re(1)(0) <= smpl_copy(w_smpl => cst_w_in_5ndft, smpl_in => matrix_stages_re(0)(0));
  100. -- data1
  101. matrix_stages_im(1)(1) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_im(0)(3), in2 => matrix_stages_im(0)(2));
  102. matrix_stages_re(1)(1) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_re(0)(3), in2 => matrix_stages_re(0)(2));
  103. --data2
  104. matrix_stages_im(1)(2) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_im(0)(4), in2 => matrix_stages_im(0)(1));
  105. matrix_stages_re(1)(2) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_re(0)(4), in2 => matrix_stages_re(0)(1));
  106. --data3
  107. matrix_stages_im(1)(3) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_im(0)(3), in2 => matrix_stages_im(0)(2));
  108. matrix_stages_re(1)(3) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_re(0)(3), in2 => matrix_stages_re(0)(2));
  109. --data4
  110. matrix_stages_im(1)(4) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_im(0)(1), in2 => matrix_stages_im(0)(4));
  111. matrix_stages_re(1)(4) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_re(0)(1), in2 => matrix_stages_re(0)(4));
  112. -- stage 2
  113. w_smpl := cst_w_in_5ndft+1;
  114. -- data0,3,4
  115. matrix_stages_im(2)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(1)(0));
  116. matrix_stages_re(2)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(1)(0));
  117. matrix_stages_im(2)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(1)(3));
  118. matrix_stages_re(2)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(1)(3));
  119. matrix_stages_im(2)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(1)(4));
  120. matrix_stages_re(2)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(1)(4));
  121. --data1
  122. matrix_stages_im(2)(1) <= add_sub (w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(1)(1), in2 => matrix_stages_im(1)(2));
  123. matrix_stages_re(2)(1) <= add_sub (w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(1)(1), in2 => matrix_stages_re(1)(2));
  124. --data2
  125. matrix_stages_re(2)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(1)(2), in2 => matrix_stages_re(1)(1));
  126. matrix_stages_im(2)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(1)(2), in2 => matrix_stages_im(1)(1));
  127. --data5
  128. matrix_stages_re(2)(5) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(1)(3), in2 => matrix_stages_re(1)(4));
  129. matrix_stages_im(2)(5) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(1)(3), in2 => matrix_stages_im(1)(4));
  130. -- stage 3
  131. w_smpl := cst_w_in_5ndft+2;
  132. --data1,2,3,4,5
  133. matrix_stages_im(3)(1) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(1));
  134. matrix_stages_re(3)(1) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(1));
  135. matrix_stages_im(3)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(2));
  136. matrix_stages_re(3)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(2));
  137. matrix_stages_im(3)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(3));
  138. matrix_stages_re(3)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(3));
  139. matrix_stages_im(3)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(4));
  140. matrix_stages_re(3)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(4));
  141. matrix_stages_im(3)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(5));
  142. matrix_stages_re(3)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(5));
  143. --data0
  144. matrix_stages_im(3)(0) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(2)(1), in2 => matrix_stages_im(2)(0));
  145. matrix_stages_re(3)(0) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(2)(1), in2 => matrix_stages_re(2)(0));
  146. -- stage 4, multiply
  147. w_smpl := cst_w_in_5ndft+3;
  148. --data0, multiply by 1 = copy
  149. matrix_stages_im(4)(0)(w_smpl+cst_w_precision_winograd5_coeffs_5ndft-1 DOWNTO 0) <= matrix_stages_im(3)(0)(w_smpl-1)&matrix_stages_im(3)(0)(w_smpl-1)&matrix_stages_im(3)(0)(w_smpl-1 DOWNTO 0)&multiply_by_2_power_cst_w_precision;
  150. matrix_stages_re(4)(0)(w_smpl+cst_w_precision_winograd5_coeffs_5ndft-1 DOWNTO 0) <= matrix_stages_re(3)(0)(w_smpl-1)&matrix_stages_re(3)(0)(w_smpl-1)&matrix_stages_re(3)(0)(w_smpl-1 DOWNTO 0)&multiply_by_2_power_cst_w_precision;
  151. --data1
  152. matrix_stages_im(4)(1) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(1), coeff => mult_factor_w_multipliers(1));
  153. matrix_stages_re(4)(1) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(1), coeff => mult_factor_w_multipliers(1));
  154. --data2
  155. matrix_stages_im(4)(2) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(2), coeff => mult_factor_w_multipliers(2));
  156. matrix_stages_re(4)(2) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(2), coeff => mult_factor_w_multipliers(2));
  157. --data3
  158. matrix_stages_re(4)(3) <= mult (w_smpl => w_smpl, cmplx => true, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(3), coeff => mult_factor_w_multipliers(3));
  159. matrix_stages_im(4)(3) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(3), coeff => mult_factor_w_multipliers(3));
  160. --data4
  161. matrix_stages_re(4)(4) <= mult (w_smpl => w_smpl, cmplx => true, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(4), coeff => mult_factor_w_multipliers(4));
  162. matrix_stages_im(4)(4) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(4), coeff => mult_factor_w_multipliers(4));
  163. --data5
  164. matrix_stages_re(4)(5) <= mult (w_smpl => w_smpl, cmplx => true, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(5), coeff => mult_factor_w_multipliers(5));
  165. matrix_stages_im(4)(5) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(5), coeff => mult_factor_w_multipliers(5));
  166. -- stage 5
  167. w_smpl := cst_w_in_5ndft+3+cst_w_precision_winograd5_coeffs_5ndft;
  168. --data0, 2, 3, 4, 5
  169. matrix_stages_im(5)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(0));
  170. matrix_stages_re(5)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(0));
  171. matrix_stages_im(5)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(2));
  172. matrix_stages_re(5)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(2));
  173. matrix_stages_im(5)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(3));
  174. matrix_stages_re(5)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(3));
  175. matrix_stages_im(5)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(4));
  176. matrix_stages_re(5)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(4));
  177. matrix_stages_im(5)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(5));
  178. matrix_stages_re(5)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(5));
  179. --data1
  180. matrix_stages_re(5)(1) <= add_sub(w_smpl => w_smpl, sub => false, IN1 => matrix_stages_re(4)(1), in2 => matrix_stages_re(4)(0));
  181. matrix_stages_im(5)(1) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(4)(1), in2 => matrix_stages_im(4)(0));
  182. -- stage 6
  183. w_smpl := cst_w_in_5ndft+3+cst_w_precision_winograd5_coeffs_5ndft+1;
  184. --data0
  185. matrix_stages_im(6)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(5)(0));
  186. matrix_stages_re(6)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(5)(0));
  187. --data1
  188. matrix_stages_re(6)(1) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(5)(1), in2 => matrix_stages_re(5)(2));
  189. matrix_stages_im(6)(1) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(5)(1), in2 => matrix_stages_im(5)(2));
  190. --data2
  191. matrix_stages_re(6)(2) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(5)(1), in2 => matrix_stages_re(5)(2));
  192. matrix_stages_im(6)(2) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(5)(1), in2 => matrix_stages_im(5)(2));
  193. --data3
  194. matrix_stages_re(6)(3) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(5)(5), in2 => matrix_stages_re(5)(3));
  195. matrix_stages_im(6)(3) <= add_sub(w_smpl => w_smpl, sub => false, IN1 => matrix_stages_im(5)(5), in2 => matrix_stages_im(5)(3));
  196. --data4
  197. matrix_stages_re(6)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(5)(5), in2 => matrix_stages_re(5)(4));
  198. matrix_stages_im(6)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(5)(5), in2 => matrix_stages_im(5)(4));
  199. -- stage 7
  200. w_smpl := cst_w_in_5ndft+3+cst_w_precision_winograd5_coeffs_5ndft+2;
  201. --data0
  202. matrix_stages_im(7)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(6)(0));
  203. matrix_stages_re(7)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(6)(0));
  204. --data1
  205. matrix_stages_re(7)(1) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(6)(2), in2 => matrix_stages_re(6)(4));
  206. matrix_stages_im(7)(1) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(6)(2), in2 => matrix_stages_im(6)(4));
  207. --data2
  208. matrix_stages_re(7)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(6)(1), in2 => matrix_stages_re(6)(3));
  209. matrix_stages_im(7)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(6)(1), in2 => matrix_stages_im(6)(3));
  210. --data3
  211. matrix_stages_re(7)(3) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(6)(1), in2 => matrix_stages_re(6)(3));
  212. matrix_stages_im(7)(3) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(6)(1), in2 => matrix_stages_im(6)(3));
  213. --data4
  214. matrix_stages_re(7)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(6)(2), in2 => matrix_stages_re(6)(4));
  215. matrix_stages_im(7)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(6)(2), in2 => matrix_stages_im(6)(4));
  216. END IF;
  217. END PROCESS calculations_process;
  218. END Behavioral;