Lösung des Praktikums Systementwurf
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.

SdfUnit.v 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. //----------------------------------------------------------------------
  2. // SdfUnit: Radix-2^2 Single-Path Delay Feedback Unit for N-Point FFT
  3. //----------------------------------------------------------------------
  4. module SdfUnit #(
  5. parameter N = 64, // Number of FFT Point
  6. parameter M = 64, // Twiddle Resolution
  7. parameter WIDTH = 16 // Data Bit Length
  8. )(
  9. input clock, // Master Clock
  10. input reset, // Active High Asynchronous Reset
  11. input di_en, // Input Data Enable
  12. input [WIDTH-1:0] di_re, // Input Data (Real)
  13. input [WIDTH-1:0] di_im, // Input Data (Imag)
  14. output do_en, // Output Data Enable
  15. output [WIDTH-1:0] do_re, // Output Data (Real)
  16. output [WIDTH-1:0] do_im // Output Data (Imag)
  17. );
  18. // log2 constant function
  19. function integer log2;
  20. input integer x;
  21. integer value;
  22. begin
  23. value = x-1;
  24. for (log2=0; value>0; log2=log2+1)
  25. value = value>>1;
  26. end
  27. endfunction
  28. localparam LOG_N = log2(N); // Bit Length of N
  29. localparam LOG_M = log2(M); // Bit Length of M
  30. //----------------------------------------------------------------------
  31. // Internal Regs and Nets
  32. //----------------------------------------------------------------------
  33. // 1st Butterfly
  34. reg [LOG_N-1:0] di_count; // Input Data Count
  35. wire bf1_bf; // Butterfly Add/Sub Enable
  36. wire[WIDTH-1:0] bf1_x0_re; // Data #0 to Butterfly (Real)
  37. wire[WIDTH-1:0] bf1_x0_im; // Data #0 to Butterfly (Imag)
  38. wire[WIDTH-1:0] bf1_x1_re; // Data #1 to Butterfly (Real)
  39. wire[WIDTH-1:0] bf1_x1_im; // Data #1 to Butterfly (Imag)
  40. wire[WIDTH-1:0] bf1_y0_re; // Data #0 from Butterfly (Real)
  41. wire[WIDTH-1:0] bf1_y0_im; // Data #0 from Butterfly (Imag)
  42. wire[WIDTH-1:0] bf1_y1_re; // Data #1 from Butterfly (Real)
  43. wire[WIDTH-1:0] bf1_y1_im; // Data #1 from Butterfly (Imag)
  44. wire[WIDTH-1:0] db1_di_re; // Data to DelayBuffer (Real)
  45. wire[WIDTH-1:0] db1_di_im; // Data to DelayBuffer (Imag)
  46. wire[WIDTH-1:0] db1_do_re; // Data from DelayBuffer (Real)
  47. wire[WIDTH-1:0] db1_do_im; // Data from DelayBuffer (Imag)
  48. wire[WIDTH-1:0] bf1_sp_re; // Single-Path Data Output (Real)
  49. wire[WIDTH-1:0] bf1_sp_im; // Single-Path Data Output (Imag)
  50. reg bf1_sp_en; // Single-Path Data Enable
  51. reg [LOG_N-1:0] bf1_count; // Single-Path Data Count
  52. wire bf1_start; // Single-Path Output Trigger
  53. wire bf1_end; // End of Single-Path Data
  54. wire bf1_mj; // Twiddle (-j) Enable
  55. reg [WIDTH-1:0] bf1_do_re; // 1st Butterfly Output Data (Real)
  56. reg [WIDTH-1:0] bf1_do_im; // 1st Butterfly Output Data (Imag)
  57. // 2nd Butterfly
  58. reg bf2_bf; // Butterfly Add/Sub Enable
  59. wire[WIDTH-1:0] bf2_x0_re; // Data #0 to Butterfly (Real)
  60. wire[WIDTH-1:0] bf2_x0_im; // Data #0 to Butterfly (Imag)
  61. wire[WIDTH-1:0] bf2_x1_re; // Data #1 to Butterfly (Real)
  62. wire[WIDTH-1:0] bf2_x1_im; // Data #1 to Butterfly (Imag)
  63. wire[WIDTH-1:0] bf2_y0_re; // Data #0 from Butterfly (Real)
  64. wire[WIDTH-1:0] bf2_y0_im; // Data #0 from Butterfly (Imag)
  65. wire[WIDTH-1:0] bf2_y1_re; // Data #1 from Butterfly (Real)
  66. wire[WIDTH-1:0] bf2_y1_im; // Data #1 from Butterfly (Imag)
  67. wire[WIDTH-1:0] db2_di_re; // Data to DelayBuffer (Real)
  68. wire[WIDTH-1:0] db2_di_im; // Data to DelayBuffer (Imag)
  69. wire[WIDTH-1:0] db2_do_re; // Data from DelayBuffer (Real)
  70. wire[WIDTH-1:0] db2_do_im; // Data from DelayBuffer (Imag)
  71. wire[WIDTH-1:0] bf2_sp_re; // Single-Path Data Output (Real)
  72. wire[WIDTH-1:0] bf2_sp_im; // Single-Path Data Output (Imag)
  73. reg bf2_sp_en; // Single-Path Data Enable
  74. reg [LOG_N-1:0] bf2_count; // Single-Path Data Count
  75. reg bf2_start; // Single-Path Output Trigger
  76. wire bf2_end; // End of Single-Path Data
  77. reg [WIDTH-1:0] bf2_do_re; // 2nd Butterfly Output Data (Real)
  78. reg [WIDTH-1:0] bf2_do_im; // 2nd Butterfly Output Data (Imag)
  79. reg bf2_do_en; // 2nd Butterfly Output Data Enable
  80. // Multiplication
  81. wire[1:0] tw_sel; // Twiddle Select (2n/n/3n)
  82. wire[LOG_N-3:0] tw_num; // Twiddle Number (n)
  83. wire[LOG_N-1:0] tw_addr; // Twiddle Table Address
  84. wire[WIDTH-1:0] tw_re; // Twiddle Factor (Real)
  85. wire[WIDTH-1:0] tw_im; // Twiddle Factor (Imag)
  86. reg mu_en; // Multiplication Enable
  87. wire[WIDTH-1:0] mu_a_re; // Multiplier Input (Real)
  88. wire[WIDTH-1:0] mu_a_im; // Multiplier Input (Imag)
  89. wire[WIDTH-1:0] mu_m_re; // Multiplier Output (Real)
  90. wire[WIDTH-1:0] mu_m_im; // Multiplier Output (Imag)
  91. reg [WIDTH-1:0] mu_do_re; // Multiplication Output Data (Real)
  92. reg [WIDTH-1:0] mu_do_im; // Multiplication Output Data (Imag)
  93. reg mu_do_en; // Multiplication Output Data Enable
  94. //----------------------------------------------------------------------
  95. // 1st Butterfly
  96. //----------------------------------------------------------------------
  97. always @(posedge clock or posedge reset) begin
  98. if (reset) begin
  99. di_count <= {LOG_N{1'b0}};
  100. end else begin
  101. di_count <= di_en ? (di_count + 1'b1) : {LOG_N{1'b0}};
  102. end
  103. end
  104. assign bf1_bf = di_count[LOG_M-1];
  105. // Set unknown value x for verification
  106. assign bf1_x0_re = bf1_bf ? db1_do_re : {WIDTH{1'bx}};
  107. assign bf1_x0_im = bf1_bf ? db1_do_im : {WIDTH{1'bx}};
  108. assign bf1_x1_re = bf1_bf ? di_re : {WIDTH{1'bx}};
  109. assign bf1_x1_im = bf1_bf ? di_im : {WIDTH{1'bx}};
  110. Butterfly #(.WIDTH(WIDTH),.RH(0)) BF1 (
  111. .x0_re (bf1_x0_re ), // i
  112. .x0_im (bf1_x0_im ), // i
  113. .x1_re (bf1_x1_re ), // i
  114. .x1_im (bf1_x1_im ), // i
  115. .y0_re (bf1_y0_re ), // o
  116. .y0_im (bf1_y0_im ), // o
  117. .y1_re (bf1_y1_re ), // o
  118. .y1_im (bf1_y1_im ) // o
  119. );
  120. DelayBuffer #(.DEPTH(2**(LOG_M-1)),.WIDTH(WIDTH)) DB1 (
  121. .clock (clock ), // i
  122. .di_re (db1_di_re ), // i
  123. .di_im (db1_di_im ), // i
  124. .do_re (db1_do_re ), // o
  125. .do_im (db1_do_im ) // o
  126. );
  127. assign db1_di_re = bf1_bf ? bf1_y1_re : di_re;
  128. assign db1_di_im = bf1_bf ? bf1_y1_im : di_im;
  129. assign bf1_sp_re = bf1_bf ? bf1_y0_re : bf1_mj ? db1_do_im : db1_do_re;
  130. assign bf1_sp_im = bf1_bf ? bf1_y0_im : bf1_mj ? -db1_do_re : db1_do_im;
  131. always @(posedge clock or posedge reset) begin
  132. if (reset) begin
  133. bf1_sp_en <= 1'b0;
  134. bf1_count <= {LOG_N{1'b0}};
  135. end else begin
  136. bf1_sp_en <= bf1_start ? 1'b1 : bf1_end ? 1'b0 : bf1_sp_en;
  137. bf1_count <= bf1_sp_en ? (bf1_count + 1'b1) : {LOG_N{1'b0}};
  138. end
  139. end
  140. assign bf1_start = (di_count == (2**(LOG_M-1)-1));
  141. assign bf1_end = (bf1_count == (2**LOG_N-1));
  142. assign bf1_mj = (bf1_count[LOG_M-1:LOG_M-2] == 2'd3);
  143. always @(posedge clock) begin
  144. bf1_do_re <= bf1_sp_re;
  145. bf1_do_im <= bf1_sp_im;
  146. end
  147. //----------------------------------------------------------------------
  148. // 2nd Butterfly
  149. //----------------------------------------------------------------------
  150. always @(posedge clock) begin
  151. bf2_bf <= bf1_count[LOG_M-2];
  152. end
  153. // Set unknown value x for verification
  154. assign bf2_x0_re = bf2_bf ? db2_do_re : {WIDTH{1'bx}};
  155. assign bf2_x0_im = bf2_bf ? db2_do_im : {WIDTH{1'bx}};
  156. assign bf2_x1_re = bf2_bf ? bf1_do_re : {WIDTH{1'bx}};
  157. assign bf2_x1_im = bf2_bf ? bf1_do_im : {WIDTH{1'bx}};
  158. // Negative bias occurs when RH=0 and positive bias occurs when RH=1.
  159. // Using both alternately reduces the overall rounding error.
  160. Butterfly #(.WIDTH(WIDTH),.RH(1)) BF2 (
  161. .x0_re (bf2_x0_re ), // i
  162. .x0_im (bf2_x0_im ), // i
  163. .x1_re (bf2_x1_re ), // i
  164. .x1_im (bf2_x1_im ), // i
  165. .y0_re (bf2_y0_re ), // o
  166. .y0_im (bf2_y0_im ), // o
  167. .y1_re (bf2_y1_re ), // o
  168. .y1_im (bf2_y1_im ) // o
  169. );
  170. DelayBuffer #(.DEPTH(2**(LOG_M-2)),.WIDTH(WIDTH)) DB2 (
  171. .clock (clock ), // i
  172. .di_re (db2_di_re ), // i
  173. .di_im (db2_di_im ), // i
  174. .do_re (db2_do_re ), // o
  175. .do_im (db2_do_im ) // o
  176. );
  177. assign db2_di_re = bf2_bf ? bf2_y1_re : bf1_do_re;
  178. assign db2_di_im = bf2_bf ? bf2_y1_im : bf1_do_im;
  179. assign bf2_sp_re = bf2_bf ? bf2_y0_re : db2_do_re;
  180. assign bf2_sp_im = bf2_bf ? bf2_y0_im : db2_do_im;
  181. always @(posedge clock or posedge reset) begin
  182. if (reset) begin
  183. bf2_sp_en <= 1'b0;
  184. bf2_count <= {LOG_N{1'b0}};
  185. end else begin
  186. bf2_sp_en <= bf2_start ? 1'b1 : bf2_end ? 1'b0 : bf2_sp_en;
  187. bf2_count <= bf2_sp_en ? (bf2_count + 1'b1) : {LOG_N{1'b0}};
  188. end
  189. end
  190. always @(posedge clock) begin
  191. bf2_start <= (bf1_count == (2**(LOG_M-2)-1)) & bf1_sp_en;
  192. end
  193. assign bf2_end = (bf2_count == (2**LOG_N-1));
  194. always @(posedge clock) begin
  195. bf2_do_re <= bf2_sp_re;
  196. bf2_do_im <= bf2_sp_im;
  197. end
  198. always @(posedge clock or posedge reset) begin
  199. if (reset) begin
  200. bf2_do_en <= 1'b0;
  201. end else begin
  202. bf2_do_en <= bf2_sp_en;
  203. end
  204. end
  205. //----------------------------------------------------------------------
  206. // Multiplication
  207. //----------------------------------------------------------------------
  208. assign tw_sel[1] = bf2_count[LOG_M-2];
  209. assign tw_sel[0] = bf2_count[LOG_M-1];
  210. assign tw_num = bf2_count << (LOG_N-LOG_M);
  211. assign tw_addr = tw_num * tw_sel;
  212. Twiddle TW (
  213. .clock (clock ), // i
  214. .addr (tw_addr), // i
  215. .tw_re (tw_re ), // o
  216. .tw_im (tw_im ) // o
  217. );
  218. // Multiplication is bypassed when twiddle address is 0.
  219. always @(posedge clock) begin
  220. mu_en <= (tw_addr != {LOG_N{1'b0}});
  221. end
  222. // Set unknown value x for verification
  223. assign mu_a_re = mu_en ? bf2_do_re : {WIDTH{1'bx}};
  224. assign mu_a_im = mu_en ? bf2_do_im : {WIDTH{1'bx}};
  225. Multiply #(.WIDTH(WIDTH)) MU (
  226. .a_re (mu_a_re), // i
  227. .a_im (mu_a_im), // i
  228. .b_re (tw_re ), // i
  229. .b_im (tw_im ), // i
  230. .m_re (mu_m_re), // o
  231. .m_im (mu_m_im) // o
  232. );
  233. always @(posedge clock) begin
  234. mu_do_re <= mu_en ? mu_m_re : bf2_do_re;
  235. mu_do_im <= mu_en ? mu_m_im : bf2_do_im;
  236. end
  237. always @(posedge clock or posedge reset) begin
  238. if (reset) begin
  239. mu_do_en <= 1'b0;
  240. end else begin
  241. mu_do_en <= bf2_do_en;
  242. end
  243. end
  244. // No multiplication required at final stage
  245. assign do_en = (LOG_M == 2) ? bf2_do_en : mu_do_en;
  246. assign do_re = (LOG_M == 2) ? bf2_do_re : mu_do_re;
  247. assign do_im = (LOG_M == 2) ? bf2_do_im : mu_do_im;
  248. endmodule