OpenCores
URL https://opencores.org/ocsvn/fft2_size/fft2_size/trunk

Subversion Repositories fft2_size

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /fft2_size
    from Rev 6 to Rev 7
    Reverse comparison

Rev 6 → Rev 7

/fft_int_size/Quartus/fft_int_size.qar Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
fft_int_size/Quartus/fft_int_size.qar Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: fft_int_size/IntToBit32.m =================================================================== --- fft_int_size/IntToBit32.m (nonexistent) +++ fft_int_size/IntToBit32.m (revision 7) @@ -0,0 +1,4 @@ +function y = IntToBit32(x) +% double to bit32 + y = typecast(int32(round(x)), 'uint32'); +end \ No newline at end of file Index: fft_int_size/W.m =================================================================== --- fft_int_size/W.m (nonexistent) +++ fft_int_size/W.m (revision 7) @@ -0,0 +1,8 @@ +function c = W(k, N) +% if mod(k, N) == 0 return 1; + arg = -2 * pi * k / N; + Re = cos(arg); + Im = sin(arg); + c = complex(Re, Im); +end + Index: fft_int_size/W_int32.sv =================================================================== --- fft_int_size/W_int32.sv (nonexistent) +++ fft_int_size/W_int32.sv (revision 7) @@ -0,0 +1,451 @@ +`ifndef _fft_w_ +`define _fft_w_ +`include "round32.sv" + +module W_int32 #(parameter POW = 10, W_WIDTH = 32)(clk, k, W_Re, W_Im); +// N = 2**POW, Max POW = 10, Max W_WIDTH = 32 +// File contains the rotate coefficients +// W(k, N) = exp(-2i * pi * k / N) +// in the scale W * 2^30 + input wire clk; + input wire [POW-2:0] k; + output wire signed [W_WIDTH-1:0] W_Re, W_Im; + +// assert(POW >= 2 && POW <= 10) $info("POW OK"); else $error("POW failed"); + + generate + if (POW == 1) + begin + localparam bit signed [31:0] W_Re_table = 32'sh40000000; + localparam bit signed [31:0] W_Im_table = 32'sh00000000; + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_table, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_table, W_Im); + end + else if (POW == 2) + begin + reg signed [31:0] W_Re_table[2] = '{ + 32'sh40000000, 32'sh00000000 + }; + + reg signed [31:0] W_Im_table[2] = '{ + 32'sh00000000, 32'shc0000000 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 3) + begin + reg signed [31:0] W_Re_table[4] = '{ + 32'sh40000000, 32'sh2d413ccd, 32'sh00000000, 32'shd2bec333 + }; + + reg signed [31:0] W_Im_table[4] = '{ + 32'sh00000000, 32'shd2bec333, 32'shc0000000, 32'shd2bec333 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 4) + begin + reg signed [31:0] W_Re_table[8] = '{ + 32'sh40000000, 32'sh3b20d79e, 32'sh2d413ccd, 32'sh187de2a7, 32'sh00000000, 32'she7821d59, 32'shd2bec333, 32'shc4df2862 + }; + + reg signed [31:0] W_Im_table[8] = '{ + 32'sh00000000, 32'she7821d59, 32'shd2bec333, 32'shc4df2862, 32'shc0000000, 32'shc4df2862, 32'shd2bec333, 32'she7821d59 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 5) + begin + + + reg signed [31:0] W_Re_table[16] = '{ + 32'sh40000000, 32'sh3ec52fa0, 32'sh3b20d79e, 32'sh3536cc52, 32'sh2d413ccd, 32'sh238e7673, 32'sh187de2a7, 32'sh0c7c5c1e, + 32'sh00000000, 32'shf383a3e2, 32'she7821d59, 32'shdc71898d, 32'shd2bec333, 32'shcac933ae, 32'shc4df2862, 32'shc13ad060 + }; + + reg signed [31:0] W_Im_table[16] = '{ + 32'sh00000000, 32'shf383a3e2, 32'she7821d59, 32'shdc71898d, 32'shd2bec333, 32'shcac933ae, 32'shc4df2862, 32'shc13ad060, + 32'shc0000000, 32'shc13ad060, 32'shc4df2862, 32'shcac933ae, 32'shd2bec333, 32'shdc71898d, 32'she7821d59, 32'shf383a3e2 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 6) + begin + + reg signed [31:0] W_Re_table[32] = '{ + 32'sh40000000, 32'sh3fb11b48, 32'sh3ec52fa0, 32'sh3d3e82ae, 32'sh3b20d79e, 32'sh387165e3, 32'sh3536cc52, 32'sh317900d6, + 32'sh2d413ccd, 32'sh2899e64a, 32'sh238e7673, 32'sh1e2b5d38, 32'sh187de2a7, 32'sh1294062f, 32'sh0c7c5c1e, 32'sh0645e9af, + 32'sh00000000, 32'shf9ba1651, 32'shf383a3e2, 32'shed6bf9d1, 32'she7821d59, 32'she1d4a2c8, 32'shdc71898d, 32'shd76619b6, + 32'shd2bec333, 32'shce86ff2a, 32'shcac933ae, 32'shc78e9a1d, 32'shc4df2862, 32'shc2c17d52, 32'shc13ad060, 32'shc04ee4b8 + }; + + reg signed [31:0] W_Im_table[32] = '{ + 32'sh00000000, 32'shf9ba1651, 32'shf383a3e2, 32'shed6bf9d1, 32'she7821d59, 32'she1d4a2c8, 32'shdc71898d, 32'shd76619b6, + 32'shd2bec333, 32'shce86ff2a, 32'shcac933ae, 32'shc78e9a1d, 32'shc4df2862, 32'shc2c17d52, 32'shc13ad060, 32'shc04ee4b8, + 32'shc0000000, 32'shc04ee4b8, 32'shc13ad060, 32'shc2c17d52, 32'shc4df2862, 32'shc78e9a1d, 32'shcac933ae, 32'shce86ff2a, + 32'shd2bec333, 32'shd76619b6, 32'shdc71898d, 32'she1d4a2c8, 32'she7821d59, 32'shed6bf9d1, 32'shf383a3e2, 32'shf9ba1651 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 7) + begin + + reg signed [31:0] W_Re_table[64] = '{ + 32'sh40000000, 32'sh3fec43c7, 32'sh3fb11b48, 32'sh3f4eaafe, 32'sh3ec52fa0, 32'sh3e14fdf7, 32'sh3d3e82ae, 32'sh3c42420a, + 32'sh3b20d79e, 32'sh39daf5e8, 32'sh387165e3, 32'sh36e5068a, 32'sh3536cc52, 32'sh3367c090, 32'sh317900d6, 32'sh2f6bbe45, + 32'sh2d413ccd, 32'sh2afad269, 32'sh2899e64a, 32'sh261feffa, 32'sh238e7673, 32'sh20e70f32, 32'sh1e2b5d38, 32'sh1b5d100a, + 32'sh187de2a7, 32'sh158f9a76, 32'sh1294062f, 32'sh0f8cfcbe, 32'sh0c7c5c1e, 32'sh09640837, 32'sh0645e9af, 32'sh0323ecbe, + 32'sh00000000, 32'shfcdc1342, 32'shf9ba1651, 32'shf69bf7c9, 32'shf383a3e2, 32'shf0730342, 32'shed6bf9d1, 32'shea70658a, + 32'she7821d59, 32'she4a2eff6, 32'she1d4a2c8, 32'shdf18f0ce, 32'shdc71898d, 32'shd9e01006, 32'shd76619b6, 32'shd5052d97, + 32'shd2bec333, 32'shd09441bb, 32'shce86ff2a, 32'shcc983f70, 32'shcac933ae, 32'shc91af976, 32'shc78e9a1d, 32'shc6250a18, + 32'shc4df2862, 32'shc3bdbdf6, 32'shc2c17d52, 32'shc1eb0209, 32'shc13ad060, 32'shc0b15502, 32'shc04ee4b8, 32'shc013bc39 + }; + + reg signed [31:0] W_Im_table[64] = '{ + 32'sh00000000, 32'shfcdc1342, 32'shf9ba1651, 32'shf69bf7c9, 32'shf383a3e2, 32'shf0730342, 32'shed6bf9d1, 32'shea70658a, + 32'she7821d59, 32'she4a2eff6, 32'she1d4a2c8, 32'shdf18f0ce, 32'shdc71898d, 32'shd9e01006, 32'shd76619b6, 32'shd5052d97, + 32'shd2bec333, 32'shd09441bb, 32'shce86ff2a, 32'shcc983f70, 32'shcac933ae, 32'shc91af976, 32'shc78e9a1d, 32'shc6250a18, + 32'shc4df2862, 32'shc3bdbdf6, 32'shc2c17d52, 32'shc1eb0209, 32'shc13ad060, 32'shc0b15502, 32'shc04ee4b8, 32'shc013bc39, + 32'shc0000000, 32'shc013bc39, 32'shc04ee4b8, 32'shc0b15502, 32'shc13ad060, 32'shc1eb0209, 32'shc2c17d52, 32'shc3bdbdf6, + 32'shc4df2862, 32'shc6250a18, 32'shc78e9a1d, 32'shc91af976, 32'shcac933ae, 32'shcc983f70, 32'shce86ff2a, 32'shd09441bb, + 32'shd2bec333, 32'shd5052d97, 32'shd76619b6, 32'shd9e01006, 32'shdc71898d, 32'shdf18f0ce, 32'she1d4a2c8, 32'she4a2eff6, + 32'she7821d59, 32'shea70658a, 32'shed6bf9d1, 32'shf0730342, 32'shf383a3e2, 32'shf69bf7c9, 32'shf9ba1651, 32'shfcdc1342 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 8) + begin + + reg signed [31:0] W_Re_table[128] = '{ + 32'sh40000000, 32'sh3ffb10c1, 32'sh3fec43c7, 32'sh3fd39b5a, 32'sh3fb11b48, 32'sh3f84c8e2, 32'sh3f4eaafe, 32'sh3f0ec9f5, + 32'sh3ec52fa0, 32'sh3e71e759, 32'sh3e14fdf7, 32'sh3dae81cf, 32'sh3d3e82ae, 32'sh3cc511d9, 32'sh3c42420a, 32'sh3bb6276e, + 32'sh3b20d79e, 32'sh3a8269a3, 32'sh39daf5e8, 32'sh392a9642, 32'sh387165e3, 32'sh37af8159, 32'sh36e5068a, 32'sh361214b0, + 32'sh3536cc52, 32'sh34534f41, 32'sh3367c090, 32'sh32744493, 32'sh317900d6, 32'sh30761c18, 32'sh2f6bbe45, 32'sh2e5a1070, + 32'sh2d413ccd, 32'sh2c216eaa, 32'sh2afad269, 32'sh29cd9578, 32'sh2899e64a, 32'sh275ff452, 32'sh261feffa, 32'sh24da0a9a, + 32'sh238e7673, 32'sh223d66a8, 32'sh20e70f32, 32'sh1f8ba4dc, 32'sh1e2b5d38, 32'sh1cc66e99, 32'sh1b5d100a, 32'sh19ef7944, + 32'sh187de2a7, 32'sh17088531, 32'sh158f9a76, 32'sh14135c94, 32'sh1294062f, 32'sh1111d263, 32'sh0f8cfcbe, 32'sh0e05c135, + 32'sh0c7c5c1e, 32'sh0af10a22, 32'sh09640837, 32'sh07d59396, 32'sh0645e9af, 32'sh04b54825, 32'sh0323ecbe, 32'sh0192155f, + 32'sh00000000, 32'shfe6deaa1, 32'shfcdc1342, 32'shfb4ab7db, 32'shf9ba1651, 32'shf82a6c6a, 32'shf69bf7c9, 32'shf50ef5de, + 32'shf383a3e2, 32'shf1fa3ecb, 32'shf0730342, 32'sheeee2d9d, 32'shed6bf9d1, 32'shebeca36c, 32'shea70658a, 32'she8f77acf, + 32'she7821d59, 32'she61086bc, 32'she4a2eff6, 32'she3399167, 32'she1d4a2c8, 32'she0745b24, 32'shdf18f0ce, 32'shddc29958, + 32'shdc71898d, 32'shdb25f566, 32'shd9e01006, 32'shd8a00bae, 32'shd76619b6, 32'shd6326a88, 32'shd5052d97, 32'shd3de9156, + 32'shd2bec333, 32'shd1a5ef90, 32'shd09441bb, 32'shcf89e3e8, 32'shce86ff2a, 32'shcd8bbb6d, 32'shcc983f70, 32'shcbacb0bf, + 32'shcac933ae, 32'shc9edeb50, 32'shc91af976, 32'shc8507ea7, 32'shc78e9a1d, 32'shc6d569be, 32'shc6250a18, 32'shc57d965d, + 32'shc4df2862, 32'shc449d892, 32'shc3bdbdf6, 32'shc33aee27, 32'shc2c17d52, 32'shc2517e31, 32'shc1eb0209, 32'shc18e18a7, + 32'shc13ad060, 32'shc0f1360b, 32'shc0b15502, 32'shc07b371e, 32'shc04ee4b8, 32'shc02c64a6, 32'shc013bc39, 32'shc004ef3f + }; + + reg signed [31:0] W_Im_table[128] = '{ + 32'sh00000000, 32'shfe6deaa1, 32'shfcdc1342, 32'shfb4ab7db, 32'shf9ba1651, 32'shf82a6c6a, 32'shf69bf7c9, 32'shf50ef5de, + 32'shf383a3e2, 32'shf1fa3ecb, 32'shf0730342, 32'sheeee2d9d, 32'shed6bf9d1, 32'shebeca36c, 32'shea70658a, 32'she8f77acf, + 32'she7821d59, 32'she61086bc, 32'she4a2eff6, 32'she3399167, 32'she1d4a2c8, 32'she0745b24, 32'shdf18f0ce, 32'shddc29958, + 32'shdc71898d, 32'shdb25f566, 32'shd9e01006, 32'shd8a00bae, 32'shd76619b6, 32'shd6326a88, 32'shd5052d97, 32'shd3de9156, + 32'shd2bec333, 32'shd1a5ef90, 32'shd09441bb, 32'shcf89e3e8, 32'shce86ff2a, 32'shcd8bbb6d, 32'shcc983f70, 32'shcbacb0bf, + 32'shcac933ae, 32'shc9edeb50, 32'shc91af976, 32'shc8507ea7, 32'shc78e9a1d, 32'shc6d569be, 32'shc6250a18, 32'shc57d965d, + 32'shc4df2862, 32'shc449d892, 32'shc3bdbdf6, 32'shc33aee27, 32'shc2c17d52, 32'shc2517e31, 32'shc1eb0209, 32'shc18e18a7, + 32'shc13ad060, 32'shc0f1360b, 32'shc0b15502, 32'shc07b371e, 32'shc04ee4b8, 32'shc02c64a6, 32'shc013bc39, 32'shc004ef3f, + 32'shc0000000, 32'shc004ef3f, 32'shc013bc39, 32'shc02c64a6, 32'shc04ee4b8, 32'shc07b371e, 32'shc0b15502, 32'shc0f1360b, + 32'shc13ad060, 32'shc18e18a7, 32'shc1eb0209, 32'shc2517e31, 32'shc2c17d52, 32'shc33aee27, 32'shc3bdbdf6, 32'shc449d892, + 32'shc4df2862, 32'shc57d965d, 32'shc6250a18, 32'shc6d569be, 32'shc78e9a1d, 32'shc8507ea7, 32'shc91af976, 32'shc9edeb50, + 32'shcac933ae, 32'shcbacb0bf, 32'shcc983f70, 32'shcd8bbb6d, 32'shce86ff2a, 32'shcf89e3e8, 32'shd09441bb, 32'shd1a5ef90, + 32'shd2bec333, 32'shd3de9156, 32'shd5052d97, 32'shd6326a88, 32'shd76619b6, 32'shd8a00bae, 32'shd9e01006, 32'shdb25f566, + 32'shdc71898d, 32'shddc29958, 32'shdf18f0ce, 32'she0745b24, 32'she1d4a2c8, 32'she3399167, 32'she4a2eff6, 32'she61086bc, + 32'she7821d59, 32'she8f77acf, 32'shea70658a, 32'shebeca36c, 32'shed6bf9d1, 32'sheeee2d9d, 32'shf0730342, 32'shf1fa3ecb, + 32'shf383a3e2, 32'shf50ef5de, 32'shf69bf7c9, 32'shf82a6c6a, 32'shf9ba1651, 32'shfb4ab7db, 32'shfcdc1342, 32'shfe6deaa1 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 9) + begin + + reg signed [31:0] W_Re_table[256] = '{ + 32'sh40000000, 32'sh3ffec42d, 32'sh3ffb10c1, 32'sh3ff4e5e0, 32'sh3fec43c7, 32'sh3fe12acb, 32'sh3fd39b5a, 32'sh3fc395f9, + 32'sh3fb11b48, 32'sh3f9c2bfb, 32'sh3f84c8e2, 32'sh3f6af2e3, 32'sh3f4eaafe, 32'sh3f2ff24a, 32'sh3f0ec9f5, 32'sh3eeb3347, + 32'sh3ec52fa0, 32'sh3e9cc076, 32'sh3e71e759, 32'sh3e44a5ef, 32'sh3e14fdf7, 32'sh3de2f148, 32'sh3dae81cf, 32'sh3d77b192, + 32'sh3d3e82ae, 32'sh3d02f757, 32'sh3cc511d9, 32'sh3c84d496, 32'sh3c42420a, 32'sh3bfd5cc4, 32'sh3bb6276e, 32'sh3b6ca4c4, + 32'sh3b20d79e, 32'sh3ad2c2e8, 32'sh3a8269a3, 32'sh3a2fcee8, 32'sh39daf5e8, 32'sh3983e1e8, 32'sh392a9642, 32'sh38cf1669, + 32'sh387165e3, 32'sh3811884d, 32'sh37af8159, 32'sh374b54ce, 32'sh36e5068a, 32'sh367c9a7e, 32'sh361214b0, 32'sh35a5793c, + 32'sh3536cc52, 32'sh34c61236, 32'sh34534f41, 32'sh33de87de, 32'sh3367c090, 32'sh32eefdea, 32'sh32744493, 32'sh31f79948, + 32'sh317900d6, 32'sh30f8801f, 32'sh30761c18, 32'sh2ff1d9c7, 32'sh2f6bbe45, 32'sh2ee3cebe, 32'sh2e5a1070, 32'sh2dce88aa, + 32'sh2d413ccd, 32'sh2cb2324c, 32'sh2c216eaa, 32'sh2b8ef77d, 32'sh2afad269, 32'sh2a650525, 32'sh29cd9578, 32'sh29348937, + 32'sh2899e64a, 32'sh27fdb2a7, 32'sh275ff452, 32'sh26c0b162, 32'sh261feffa, 32'sh257db64c, 32'sh24da0a9a, 32'sh2434f332, + 32'sh238e7673, 32'sh22e69ac8, 32'sh223d66a8, 32'sh2192e09b, 32'sh20e70f32, 32'sh2039f90f, 32'sh1f8ba4dc, 32'sh1edc1953, + 32'sh1e2b5d38, 32'sh1d79775c, 32'sh1cc66e99, 32'sh1c1249d8, 32'sh1b5d100a, 32'sh1aa6c82b, 32'sh19ef7944, 32'sh19372a64, + 32'sh187de2a7, 32'sh17c3a931, 32'sh17088531, 32'sh164c7ddd, 32'sh158f9a76, 32'sh14d1e242, 32'sh14135c94, 32'sh135410c3, + 32'sh1294062f, 32'sh11d3443f, 32'sh1111d263, 32'sh104fb80e, 32'sh0f8cfcbe, 32'sh0ec9a7f3, 32'sh0e05c135, 32'sh0d415013, + 32'sh0c7c5c1e, 32'sh0bb6ecef, 32'sh0af10a22, 32'sh0a2abb59, 32'sh09640837, 32'sh089cf867, 32'sh07d59396, 32'sh070de172, + 32'sh0645e9af, 32'sh057db403, 32'sh04b54825, 32'sh03ecadcf, 32'sh0323ecbe, 32'sh025b0caf, 32'sh0192155f, 32'sh00c90e90, + 32'sh00000000, 32'shff36f170, 32'shfe6deaa1, 32'shfda4f351, 32'shfcdc1342, 32'shfc135231, 32'shfb4ab7db, 32'shfa824bfd, + 32'shf9ba1651, 32'shf8f21e8e, 32'shf82a6c6a, 32'shf7630799, 32'shf69bf7c9, 32'shf5d544a7, 32'shf50ef5de, 32'shf4491311, + 32'shf383a3e2, 32'shf2beafed, 32'shf1fa3ecb, 32'shf136580d, 32'shf0730342, 32'shefb047f2, 32'sheeee2d9d, 32'shee2cbbc1, + 32'shed6bf9d1, 32'shecabef3d, 32'shebeca36c, 32'sheb2e1dbe, 32'shea70658a, 32'she9b38223, 32'she8f77acf, 32'she83c56cf, + 32'she7821d59, 32'she6c8d59c, 32'she61086bc, 32'she55937d5, 32'she4a2eff6, 32'she3edb628, 32'she3399167, 32'she28688a4, + 32'she1d4a2c8, 32'she123e6ad, 32'she0745b24, 32'shdfc606f1, 32'shdf18f0ce, 32'shde6d1f65, 32'shddc29958, 32'shdd196538, + 32'shdc71898d, 32'shdbcb0cce, 32'shdb25f566, 32'shda8249b4, 32'shd9e01006, 32'shd93f4e9e, 32'shd8a00bae, 32'shd8024d59, + 32'shd76619b6, 32'shd6cb76c9, 32'shd6326a88, 32'shd59afadb, 32'shd5052d97, 32'shd4710883, 32'shd3de9156, 32'shd34dcdb4, + 32'shd2bec333, 32'shd2317756, 32'shd1a5ef90, 32'shd11c3142, 32'shd09441bb, 32'shd00e2639, 32'shcf89e3e8, 32'shcf077fe1, + 32'shce86ff2a, 32'shce0866b8, 32'shcd8bbb6d, 32'shcd110216, 32'shcc983f70, 32'shcc217822, 32'shcbacb0bf, 32'shcb39edca, + 32'shcac933ae, 32'shca5a86c4, 32'shc9edeb50, 32'shc9836582, 32'shc91af976, 32'shc8b4ab32, 32'shc8507ea7, 32'shc7ee77b3, + 32'shc78e9a1d, 32'shc730e997, 32'shc6d569be, 32'shc67c1e18, 32'shc6250a18, 32'shc5d03118, 32'shc57d965d, 32'shc52d3d18, + 32'shc4df2862, 32'shc4935b3c, 32'shc449d892, 32'shc402a33c, 32'shc3bdbdf6, 32'shc37b2b6a, 32'shc33aee27, 32'shc2fd08a9, + 32'shc2c17d52, 32'shc2884e6e, 32'shc2517e31, 32'shc21d0eb8, 32'shc1eb0209, 32'shc1bb5a11, 32'shc18e18a7, 32'shc1633f8a, + 32'shc13ad060, 32'shc114ccb9, 32'shc0f1360b, 32'shc0d00db6, 32'shc0b15502, 32'shc0950d1d, 32'shc07b371e, 32'shc063d405, + 32'shc04ee4b8, 32'shc03c6a07, 32'shc02c64a6, 32'shc01ed535, 32'shc013bc39, 32'shc00b1a20, 32'shc004ef3f, 32'shc0013bd3 + }; + + reg signed [31:0] W_Im_table[256] = '{ + 32'sh00000000, 32'shff36f170, 32'shfe6deaa1, 32'shfda4f351, 32'shfcdc1342, 32'shfc135231, 32'shfb4ab7db, 32'shfa824bfd, + 32'shf9ba1651, 32'shf8f21e8e, 32'shf82a6c6a, 32'shf7630799, 32'shf69bf7c9, 32'shf5d544a7, 32'shf50ef5de, 32'shf4491311, + 32'shf383a3e2, 32'shf2beafed, 32'shf1fa3ecb, 32'shf136580d, 32'shf0730342, 32'shefb047f2, 32'sheeee2d9d, 32'shee2cbbc1, + 32'shed6bf9d1, 32'shecabef3d, 32'shebeca36c, 32'sheb2e1dbe, 32'shea70658a, 32'she9b38223, 32'she8f77acf, 32'she83c56cf, + 32'she7821d59, 32'she6c8d59c, 32'she61086bc, 32'she55937d5, 32'she4a2eff6, 32'she3edb628, 32'she3399167, 32'she28688a4, + 32'she1d4a2c8, 32'she123e6ad, 32'she0745b24, 32'shdfc606f1, 32'shdf18f0ce, 32'shde6d1f65, 32'shddc29958, 32'shdd196538, + 32'shdc71898d, 32'shdbcb0cce, 32'shdb25f566, 32'shda8249b4, 32'shd9e01006, 32'shd93f4e9e, 32'shd8a00bae, 32'shd8024d59, + 32'shd76619b6, 32'shd6cb76c9, 32'shd6326a88, 32'shd59afadb, 32'shd5052d97, 32'shd4710883, 32'shd3de9156, 32'shd34dcdb4, + 32'shd2bec333, 32'shd2317756, 32'shd1a5ef90, 32'shd11c3142, 32'shd09441bb, 32'shd00e2639, 32'shcf89e3e8, 32'shcf077fe1, + 32'shce86ff2a, 32'shce0866b8, 32'shcd8bbb6d, 32'shcd110216, 32'shcc983f70, 32'shcc217822, 32'shcbacb0bf, 32'shcb39edca, + 32'shcac933ae, 32'shca5a86c4, 32'shc9edeb50, 32'shc9836582, 32'shc91af976, 32'shc8b4ab32, 32'shc8507ea7, 32'shc7ee77b3, + 32'shc78e9a1d, 32'shc730e997, 32'shc6d569be, 32'shc67c1e18, 32'shc6250a18, 32'shc5d03118, 32'shc57d965d, 32'shc52d3d18, + 32'shc4df2862, 32'shc4935b3c, 32'shc449d892, 32'shc402a33c, 32'shc3bdbdf6, 32'shc37b2b6a, 32'shc33aee27, 32'shc2fd08a9, + 32'shc2c17d52, 32'shc2884e6e, 32'shc2517e31, 32'shc21d0eb8, 32'shc1eb0209, 32'shc1bb5a11, 32'shc18e18a7, 32'shc1633f8a, + 32'shc13ad060, 32'shc114ccb9, 32'shc0f1360b, 32'shc0d00db6, 32'shc0b15502, 32'shc0950d1d, 32'shc07b371e, 32'shc063d405, + 32'shc04ee4b8, 32'shc03c6a07, 32'shc02c64a6, 32'shc01ed535, 32'shc013bc39, 32'shc00b1a20, 32'shc004ef3f, 32'shc0013bd3, + 32'shc0000000, 32'shc0013bd3, 32'shc004ef3f, 32'shc00b1a20, 32'shc013bc39, 32'shc01ed535, 32'shc02c64a6, 32'shc03c6a07, + 32'shc04ee4b8, 32'shc063d405, 32'shc07b371e, 32'shc0950d1d, 32'shc0b15502, 32'shc0d00db6, 32'shc0f1360b, 32'shc114ccb9, + 32'shc13ad060, 32'shc1633f8a, 32'shc18e18a7, 32'shc1bb5a11, 32'shc1eb0209, 32'shc21d0eb8, 32'shc2517e31, 32'shc2884e6e, + 32'shc2c17d52, 32'shc2fd08a9, 32'shc33aee27, 32'shc37b2b6a, 32'shc3bdbdf6, 32'shc402a33c, 32'shc449d892, 32'shc4935b3c, + 32'shc4df2862, 32'shc52d3d18, 32'shc57d965d, 32'shc5d03118, 32'shc6250a18, 32'shc67c1e18, 32'shc6d569be, 32'shc730e997, + 32'shc78e9a1d, 32'shc7ee77b3, 32'shc8507ea7, 32'shc8b4ab32, 32'shc91af976, 32'shc9836582, 32'shc9edeb50, 32'shca5a86c4, + 32'shcac933ae, 32'shcb39edca, 32'shcbacb0bf, 32'shcc217822, 32'shcc983f70, 32'shcd110216, 32'shcd8bbb6d, 32'shce0866b8, + 32'shce86ff2a, 32'shcf077fe1, 32'shcf89e3e8, 32'shd00e2639, 32'shd09441bb, 32'shd11c3142, 32'shd1a5ef90, 32'shd2317756, + 32'shd2bec333, 32'shd34dcdb4, 32'shd3de9156, 32'shd4710883, 32'shd5052d97, 32'shd59afadb, 32'shd6326a88, 32'shd6cb76c9, + 32'shd76619b6, 32'shd8024d59, 32'shd8a00bae, 32'shd93f4e9e, 32'shd9e01006, 32'shda8249b4, 32'shdb25f566, 32'shdbcb0cce, + 32'shdc71898d, 32'shdd196538, 32'shddc29958, 32'shde6d1f65, 32'shdf18f0ce, 32'shdfc606f1, 32'she0745b24, 32'she123e6ad, + 32'she1d4a2c8, 32'she28688a4, 32'she3399167, 32'she3edb628, 32'she4a2eff6, 32'she55937d5, 32'she61086bc, 32'she6c8d59c, + 32'she7821d59, 32'she83c56cf, 32'she8f77acf, 32'she9b38223, 32'shea70658a, 32'sheb2e1dbe, 32'shebeca36c, 32'shecabef3d, + 32'shed6bf9d1, 32'shee2cbbc1, 32'sheeee2d9d, 32'shefb047f2, 32'shf0730342, 32'shf136580d, 32'shf1fa3ecb, 32'shf2beafed, + 32'shf383a3e2, 32'shf4491311, 32'shf50ef5de, 32'shf5d544a7, 32'shf69bf7c9, 32'shf7630799, 32'shf82a6c6a, 32'shf8f21e8e, + 32'shf9ba1651, 32'shfa824bfd, 32'shfb4ab7db, 32'shfc135231, 32'shfcdc1342, 32'shfda4f351, 32'shfe6deaa1, 32'shff36f170 + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else if (POW == 10) + begin + + reg signed [31:0] W_Re_table[512] = '{ + 32'sh40000000, 32'sh3fffb10b, 32'sh3ffec42d, 32'sh3ffd3969, 32'sh3ffb10c1, 32'sh3ff84a3c, 32'sh3ff4e5e0, 32'sh3ff0e3b6, + 32'sh3fec43c7, 32'sh3fe7061f, 32'sh3fe12acb, 32'sh3fdab1d9, 32'sh3fd39b5a, 32'sh3fcbe75e, 32'sh3fc395f9, 32'sh3fbaa740, + 32'sh3fb11b48, 32'sh3fa6f228, 32'sh3f9c2bfb, 32'sh3f90c8da, 32'sh3f84c8e2, 32'sh3f782c30, 32'sh3f6af2e3, 32'sh3f5d1d1d, + 32'sh3f4eaafe, 32'sh3f3f9cab, 32'sh3f2ff24a, 32'sh3f1fabff, 32'sh3f0ec9f5, 32'sh3efd4c54, 32'sh3eeb3347, 32'sh3ed87efc, + 32'sh3ec52fa0, 32'sh3eb14563, 32'sh3e9cc076, 32'sh3e87a10c, 32'sh3e71e759, 32'sh3e5b9392, 32'sh3e44a5ef, 32'sh3e2d1ea8, + 32'sh3e14fdf7, 32'sh3dfc4418, 32'sh3de2f148, 32'sh3dc905c5, 32'sh3dae81cf, 32'sh3d9365a8, 32'sh3d77b192, 32'sh3d5b65d2, + 32'sh3d3e82ae, 32'sh3d21086c, 32'sh3d02f757, 32'sh3ce44fb7, 32'sh3cc511d9, 32'sh3ca53e09, 32'sh3c84d496, 32'sh3c63d5d1, + 32'sh3c42420a, 32'sh3c201994, 32'sh3bfd5cc4, 32'sh3bda0bf0, 32'sh3bb6276e, 32'sh3b91af97, 32'sh3b6ca4c4, 32'sh3b470753, + 32'sh3b20d79e, 32'sh3afa1605, 32'sh3ad2c2e8, 32'sh3aaadea6, 32'sh3a8269a3, 32'sh3a596442, 32'sh3a2fcee8, 32'sh3a05a9fd, + 32'sh39daf5e8, 32'sh39afb313, 32'sh3983e1e8, 32'sh395782d3, 32'sh392a9642, 32'sh38fd1ca4, 32'sh38cf1669, 32'sh38a08402, + 32'sh387165e3, 32'sh3841bc7f, 32'sh3811884d, 32'sh37e0c9c3, 32'sh37af8159, 32'sh377daf89, 32'sh374b54ce, 32'sh371871a5, + 32'sh36e5068a, 32'sh36b113fd, 32'sh367c9a7e, 32'sh36479a8e, 32'sh361214b0, 32'sh35dc0968, 32'sh35a5793c, 32'sh356e64b2, + 32'sh3536cc52, 32'sh34feb0a5, 32'sh34c61236, 32'sh348cf190, 32'sh34534f41, 32'sh34192bd5, 32'sh33de87de, 32'sh33a363ec, + 32'sh3367c090, 32'sh332b9e5e, 32'sh32eefdea, 32'sh32b1dfc9, 32'sh32744493, 32'sh32362ce0, 32'sh31f79948, 32'sh31b88a66, + 32'sh317900d6, 32'sh3138fd35, 32'sh30f8801f, 32'sh30b78a36, 32'sh30761c18, 32'sh30343667, 32'sh2ff1d9c7, 32'sh2faf06da, + 32'sh2f6bbe45, 32'sh2f2800af, 32'sh2ee3cebe, 32'sh2e9f291b, 32'sh2e5a1070, 32'sh2e148566, 32'sh2dce88aa, 32'sh2d881ae8, + 32'sh2d413ccd, 32'sh2cf9ef09, 32'sh2cb2324c, 32'sh2c6a0746, 32'sh2c216eaa, 32'sh2bd8692b, 32'sh2b8ef77d, 32'sh2b451a55, + 32'sh2afad269, 32'sh2ab02071, 32'sh2a650525, 32'sh2a19813f, 32'sh29cd9578, 32'sh2981428c, 32'sh29348937, 32'sh28e76a37, + 32'sh2899e64a, 32'sh284bfe2f, 32'sh27fdb2a7, 32'sh27af0472, 32'sh275ff452, 32'sh2710830c, 32'sh26c0b162, 32'sh2670801a, + 32'sh261feffa, 32'sh25cf01c8, 32'sh257db64c, 32'sh252c0e4f, 32'sh24da0a9a, 32'sh2487abf7, 32'sh2434f332, 32'sh23e1e117, + 32'sh238e7673, 32'sh233ab414, 32'sh22e69ac8, 32'sh22922b5e, 32'sh223d66a8, 32'sh21e84d76, 32'sh2192e09b, 32'sh213d20e8, + 32'sh20e70f32, 32'sh2090ac4d, 32'sh2039f90f, 32'sh1fe2f64c, 32'sh1f8ba4dc, 32'sh1f340596, 32'sh1edc1953, 32'sh1e83e0eb, + 32'sh1e2b5d38, 32'sh1dd28f15, 32'sh1d79775c, 32'sh1d2016e9, 32'sh1cc66e99, 32'sh1c6c7f4a, 32'sh1c1249d8, 32'sh1bb7cf23, + 32'sh1b5d100a, 32'sh1b020d6c, 32'sh1aa6c82b, 32'sh1a4b4128, 32'sh19ef7944, 32'sh19937161, 32'sh19372a64, 32'sh18daa52f, + 32'sh187de2a7, 32'sh1820e3b0, 32'sh17c3a931, 32'sh1766340f, 32'sh17088531, 32'sh16aa9d7e, 32'sh164c7ddd, 32'sh15ee2738, + 32'sh158f9a76, 32'sh1530d881, 32'sh14d1e242, 32'sh1472b8a5, 32'sh14135c94, 32'sh13b3cefa, 32'sh135410c3, 32'sh12f422db, + 32'sh1294062f, 32'sh1233bbac, 32'sh11d3443f, 32'sh1172a0d7, 32'sh1111d263, 32'sh10b0d9d0, 32'sh104fb80e, 32'sh0fee6e0d, + 32'sh0f8cfcbe, 32'sh0f2b650f, 32'sh0ec9a7f3, 32'sh0e67c65a, 32'sh0e05c135, 32'sh0da39978, 32'sh0d415013, 32'sh0cdee5f9, + 32'sh0c7c5c1e, 32'sh0c19b374, 32'sh0bb6ecef, 32'sh0b540982, 32'sh0af10a22, 32'sh0a8defc3, 32'sh0a2abb59, 32'sh09c76dd8, + 32'sh09640837, 32'sh09008b6a, 32'sh089cf867, 32'sh08395024, 32'sh07d59396, 32'sh0771c3b3, 32'sh070de172, 32'sh06a9edc9, + 32'sh0645e9af, 32'sh05e1d61b, 32'sh057db403, 32'sh0519845e, 32'sh04b54825, 32'sh0451004d, 32'sh03ecadcf, 32'sh038851a2, + 32'sh0323ecbe, 32'sh02bf801a, 32'sh025b0caf, 32'sh01f69373, 32'sh0192155f, 32'sh012d936c, 32'sh00c90e90, 32'sh006487c4, + 32'sh00000000, 32'shff9b783c, 32'shff36f170, 32'shfed26c94, 32'shfe6deaa1, 32'shfe096c8d, 32'shfda4f351, 32'shfd407fe6, + 32'shfcdc1342, 32'shfc77ae5e, 32'shfc135231, 32'shfbaeffb3, 32'shfb4ab7db, 32'shfae67ba2, 32'shfa824bfd, 32'shfa1e29e5, + 32'shf9ba1651, 32'shf9561237, 32'shf8f21e8e, 32'shf88e3c4d, 32'shf82a6c6a, 32'shf7c6afdc, 32'shf7630799, 32'shf6ff7496, + 32'shf69bf7c9, 32'shf6389228, 32'shf5d544a7, 32'shf572103d, 32'shf50ef5de, 32'shf4abf67e, 32'shf4491311, 32'shf3e64c8c, + 32'shf383a3e2, 32'shf3211a07, 32'shf2beafed, 32'shf25c6688, 32'shf1fa3ecb, 32'shf19839a6, 32'shf136580d, 32'shf0d49af1, + 32'shf0730342, 32'shf01191f3, 32'shefb047f2, 32'shef4f2630, 32'sheeee2d9d, 32'shee8d5f29, 32'shee2cbbc1, 32'shedcc4454, + 32'shed6bf9d1, 32'shed0bdd25, 32'shecabef3d, 32'shec4c3106, 32'shebeca36c, 32'sheb8d475b, 32'sheb2e1dbe, 32'sheacf277f, + 32'shea70658a, 32'shea11d8c8, 32'she9b38223, 32'she9556282, 32'she8f77acf, 32'she899cbf1, 32'she83c56cf, 32'she7df1c50, + 32'she7821d59, 32'she7255ad1, 32'she6c8d59c, 32'she66c8e9f, 32'she61086bc, 32'she5b4bed8, 32'she55937d5, 32'she4fdf294, + 32'she4a2eff6, 32'she44830dd, 32'she3edb628, 32'she39380b6, 32'she3399167, 32'she2dfe917, 32'she28688a4, 32'she22d70eb, + 32'she1d4a2c8, 32'she17c1f15, 32'she123e6ad, 32'she0cbfa6a, 32'she0745b24, 32'she01d09b4, 32'shdfc606f1, 32'shdf6f53b3, + 32'shdf18f0ce, 32'shdec2df18, 32'shde6d1f65, 32'shde17b28a, 32'shddc29958, 32'shdd6dd4a2, 32'shdd196538, 32'shdcc54bec, + 32'shdc71898d, 32'shdc1e1ee9, 32'shdbcb0cce, 32'shdb785409, 32'shdb25f566, 32'shdad3f1b1, 32'shda8249b4, 32'shda30fe38, + 32'shd9e01006, 32'shd98f7fe6, 32'shd93f4e9e, 32'shd8ef7cf4, 32'shd8a00bae, 32'shd850fb8e, 32'shd8024d59, 32'shd7b401d1, + 32'shd76619b6, 32'shd71895c9, 32'shd6cb76c9, 32'shd67ebd74, 32'shd6326a88, 32'shd5e67ec1, 32'shd59afadb, 32'shd54fdf8f, + 32'shd5052d97, 32'shd4bae5ab, 32'shd4710883, 32'shd42796d5, 32'shd3de9156, 32'shd395f8ba, 32'shd34dcdb4, 32'shd30610f7, + 32'shd2bec333, 32'shd277e518, 32'shd2317756, 32'shd1eb7a9a, 32'shd1a5ef90, 32'shd160d6e5, 32'shd11c3142, 32'shd0d7ff51, + 32'shd09441bb, 32'shd050f926, 32'shd00e2639, 32'shcfcbc999, 32'shcf89e3e8, 32'shcf4875ca, 32'shcf077fe1, 32'shcec702cb, + 32'shce86ff2a, 32'shce47759a, 32'shce0866b8, 32'shcdc9d320, 32'shcd8bbb6d, 32'shcd4e2037, 32'shcd110216, 32'shccd461a2, + 32'shcc983f70, 32'shcc5c9c14, 32'shcc217822, 32'shcbe6d42b, 32'shcbacb0bf, 32'shcb730e70, 32'shcb39edca, 32'shcb014f5b, + 32'shcac933ae, 32'shca919b4e, 32'shca5a86c4, 32'shca23f698, 32'shc9edeb50, 32'shc9b86572, 32'shc9836582, 32'shc94eec03, + 32'shc91af976, 32'shc8e78e5b, 32'shc8b4ab32, 32'shc8825077, 32'shc8507ea7, 32'shc81f363d, 32'shc7ee77b3, 32'shc7be4381, + 32'shc78e9a1d, 32'shc75f7bfe, 32'shc730e997, 32'shc702e35c, 32'shc6d569be, 32'shc6a87d2d, 32'shc67c1e18, 32'shc6504ced, + 32'shc6250a18, 32'shc5fa5603, 32'shc5d03118, 32'shc5a69bbe, 32'shc57d965d, 32'shc555215a, 32'shc52d3d18, 32'shc505e9fb, + 32'shc4df2862, 32'shc4b8f8ad, 32'shc4935b3c, 32'shc46e5069, 32'shc449d892, 32'shc425f410, 32'shc402a33c, 32'shc3dfe66c, + 32'shc3bdbdf6, 32'shc39c2a2f, 32'shc37b2b6a, 32'shc35ac1f7, 32'shc33aee27, 32'shc31bb049, 32'shc2fd08a9, 32'shc2def794, + 32'shc2c17d52, 32'shc2a49a2e, 32'shc2884e6e, 32'shc26c9a58, 32'shc2517e31, 32'shc236fa3b, 32'shc21d0eb8, 32'shc203bbe8, + 32'shc1eb0209, 32'shc1d2e158, 32'shc1bb5a11, 32'shc1a46c6e, 32'shc18e18a7, 32'shc1785ef4, 32'shc1633f8a, 32'shc14eba9d, + 32'shc13ad060, 32'shc1278104, 32'shc114ccb9, 32'shc102b3ac, 32'shc0f1360b, 32'shc0e05401, 32'shc0d00db6, 32'shc0c06355, + 32'shc0b15502, 32'shc0a2e2e3, 32'shc0950d1d, 32'shc087d3d0, 32'shc07b371e, 32'shc06f3726, 32'shc063d405, 32'shc0590dd8, + 32'shc04ee4b8, 32'shc04558c0, 32'shc03c6a07, 32'shc03418a2, 32'shc02c64a6, 32'shc0254e27, 32'shc01ed535, 32'shc018f9e1, + 32'shc013bc39, 32'shc00f1c4a, 32'shc00b1a20, 32'shc007b5c4, 32'shc004ef3f, 32'shc002c697, 32'shc0013bd3, 32'shc0004ef5 + }; + + reg signed [31:0] W_Im_table[512] = '{ + 32'sh00000000, 32'shff9b783c, 32'shff36f170, 32'shfed26c94, 32'shfe6deaa1, 32'shfe096c8d, 32'shfda4f351, 32'shfd407fe6, + 32'shfcdc1342, 32'shfc77ae5e, 32'shfc135231, 32'shfbaeffb3, 32'shfb4ab7db, 32'shfae67ba2, 32'shfa824bfd, 32'shfa1e29e5, + 32'shf9ba1651, 32'shf9561237, 32'shf8f21e8e, 32'shf88e3c4d, 32'shf82a6c6a, 32'shf7c6afdc, 32'shf7630799, 32'shf6ff7496, + 32'shf69bf7c9, 32'shf6389228, 32'shf5d544a7, 32'shf572103d, 32'shf50ef5de, 32'shf4abf67e, 32'shf4491311, 32'shf3e64c8c, + 32'shf383a3e2, 32'shf3211a07, 32'shf2beafed, 32'shf25c6688, 32'shf1fa3ecb, 32'shf19839a6, 32'shf136580d, 32'shf0d49af1, + 32'shf0730342, 32'shf01191f3, 32'shefb047f2, 32'shef4f2630, 32'sheeee2d9d, 32'shee8d5f29, 32'shee2cbbc1, 32'shedcc4454, + 32'shed6bf9d1, 32'shed0bdd25, 32'shecabef3d, 32'shec4c3106, 32'shebeca36c, 32'sheb8d475b, 32'sheb2e1dbe, 32'sheacf277f, + 32'shea70658a, 32'shea11d8c8, 32'she9b38223, 32'she9556282, 32'she8f77acf, 32'she899cbf1, 32'she83c56cf, 32'she7df1c50, + 32'she7821d59, 32'she7255ad1, 32'she6c8d59c, 32'she66c8e9f, 32'she61086bc, 32'she5b4bed8, 32'she55937d5, 32'she4fdf294, + 32'she4a2eff6, 32'she44830dd, 32'she3edb628, 32'she39380b6, 32'she3399167, 32'she2dfe917, 32'she28688a4, 32'she22d70eb, + 32'she1d4a2c8, 32'she17c1f15, 32'she123e6ad, 32'she0cbfa6a, 32'she0745b24, 32'she01d09b4, 32'shdfc606f1, 32'shdf6f53b3, + 32'shdf18f0ce, 32'shdec2df18, 32'shde6d1f65, 32'shde17b28a, 32'shddc29958, 32'shdd6dd4a2, 32'shdd196538, 32'shdcc54bec, + 32'shdc71898d, 32'shdc1e1ee9, 32'shdbcb0cce, 32'shdb785409, 32'shdb25f566, 32'shdad3f1b1, 32'shda8249b4, 32'shda30fe38, + 32'shd9e01006, 32'shd98f7fe6, 32'shd93f4e9e, 32'shd8ef7cf4, 32'shd8a00bae, 32'shd850fb8e, 32'shd8024d59, 32'shd7b401d1, + 32'shd76619b6, 32'shd71895c9, 32'shd6cb76c9, 32'shd67ebd74, 32'shd6326a88, 32'shd5e67ec1, 32'shd59afadb, 32'shd54fdf8f, + 32'shd5052d97, 32'shd4bae5ab, 32'shd4710883, 32'shd42796d5, 32'shd3de9156, 32'shd395f8ba, 32'shd34dcdb4, 32'shd30610f7, + 32'shd2bec333, 32'shd277e518, 32'shd2317756, 32'shd1eb7a9a, 32'shd1a5ef90, 32'shd160d6e5, 32'shd11c3142, 32'shd0d7ff51, + 32'shd09441bb, 32'shd050f926, 32'shd00e2639, 32'shcfcbc999, 32'shcf89e3e8, 32'shcf4875ca, 32'shcf077fe1, 32'shcec702cb, + 32'shce86ff2a, 32'shce47759a, 32'shce0866b8, 32'shcdc9d320, 32'shcd8bbb6d, 32'shcd4e2037, 32'shcd110216, 32'shccd461a2, + 32'shcc983f70, 32'shcc5c9c14, 32'shcc217822, 32'shcbe6d42b, 32'shcbacb0bf, 32'shcb730e70, 32'shcb39edca, 32'shcb014f5b, + 32'shcac933ae, 32'shca919b4e, 32'shca5a86c4, 32'shca23f698, 32'shc9edeb50, 32'shc9b86572, 32'shc9836582, 32'shc94eec03, + 32'shc91af976, 32'shc8e78e5b, 32'shc8b4ab32, 32'shc8825077, 32'shc8507ea7, 32'shc81f363d, 32'shc7ee77b3, 32'shc7be4381, + 32'shc78e9a1d, 32'shc75f7bfe, 32'shc730e997, 32'shc702e35c, 32'shc6d569be, 32'shc6a87d2d, 32'shc67c1e18, 32'shc6504ced, + 32'shc6250a18, 32'shc5fa5603, 32'shc5d03118, 32'shc5a69bbe, 32'shc57d965d, 32'shc555215a, 32'shc52d3d18, 32'shc505e9fb, + 32'shc4df2862, 32'shc4b8f8ad, 32'shc4935b3c, 32'shc46e5069, 32'shc449d892, 32'shc425f410, 32'shc402a33c, 32'shc3dfe66c, + 32'shc3bdbdf6, 32'shc39c2a2f, 32'shc37b2b6a, 32'shc35ac1f7, 32'shc33aee27, 32'shc31bb049, 32'shc2fd08a9, 32'shc2def794, + 32'shc2c17d52, 32'shc2a49a2e, 32'shc2884e6e, 32'shc26c9a58, 32'shc2517e31, 32'shc236fa3b, 32'shc21d0eb8, 32'shc203bbe8, + 32'shc1eb0209, 32'shc1d2e158, 32'shc1bb5a11, 32'shc1a46c6e, 32'shc18e18a7, 32'shc1785ef4, 32'shc1633f8a, 32'shc14eba9d, + 32'shc13ad060, 32'shc1278104, 32'shc114ccb9, 32'shc102b3ac, 32'shc0f1360b, 32'shc0e05401, 32'shc0d00db6, 32'shc0c06355, + 32'shc0b15502, 32'shc0a2e2e3, 32'shc0950d1d, 32'shc087d3d0, 32'shc07b371e, 32'shc06f3726, 32'shc063d405, 32'shc0590dd8, + 32'shc04ee4b8, 32'shc04558c0, 32'shc03c6a07, 32'shc03418a2, 32'shc02c64a6, 32'shc0254e27, 32'shc01ed535, 32'shc018f9e1, + 32'shc013bc39, 32'shc00f1c4a, 32'shc00b1a20, 32'shc007b5c4, 32'shc004ef3f, 32'shc002c697, 32'shc0013bd3, 32'shc0004ef5, + 32'shc0000000, 32'shc0004ef5, 32'shc0013bd3, 32'shc002c697, 32'shc004ef3f, 32'shc007b5c4, 32'shc00b1a20, 32'shc00f1c4a, + 32'shc013bc39, 32'shc018f9e1, 32'shc01ed535, 32'shc0254e27, 32'shc02c64a6, 32'shc03418a2, 32'shc03c6a07, 32'shc04558c0, + 32'shc04ee4b8, 32'shc0590dd8, 32'shc063d405, 32'shc06f3726, 32'shc07b371e, 32'shc087d3d0, 32'shc0950d1d, 32'shc0a2e2e3, + 32'shc0b15502, 32'shc0c06355, 32'shc0d00db6, 32'shc0e05401, 32'shc0f1360b, 32'shc102b3ac, 32'shc114ccb9, 32'shc1278104, + 32'shc13ad060, 32'shc14eba9d, 32'shc1633f8a, 32'shc1785ef4, 32'shc18e18a7, 32'shc1a46c6e, 32'shc1bb5a11, 32'shc1d2e158, + 32'shc1eb0209, 32'shc203bbe8, 32'shc21d0eb8, 32'shc236fa3b, 32'shc2517e31, 32'shc26c9a58, 32'shc2884e6e, 32'shc2a49a2e, + 32'shc2c17d52, 32'shc2def794, 32'shc2fd08a9, 32'shc31bb049, 32'shc33aee27, 32'shc35ac1f7, 32'shc37b2b6a, 32'shc39c2a2f, + 32'shc3bdbdf6, 32'shc3dfe66c, 32'shc402a33c, 32'shc425f410, 32'shc449d892, 32'shc46e5069, 32'shc4935b3c, 32'shc4b8f8ad, + 32'shc4df2862, 32'shc505e9fb, 32'shc52d3d18, 32'shc555215a, 32'shc57d965d, 32'shc5a69bbe, 32'shc5d03118, 32'shc5fa5603, + 32'shc6250a18, 32'shc6504ced, 32'shc67c1e18, 32'shc6a87d2d, 32'shc6d569be, 32'shc702e35c, 32'shc730e997, 32'shc75f7bfe, + 32'shc78e9a1d, 32'shc7be4381, 32'shc7ee77b3, 32'shc81f363d, 32'shc8507ea7, 32'shc8825077, 32'shc8b4ab32, 32'shc8e78e5b, + 32'shc91af976, 32'shc94eec03, 32'shc9836582, 32'shc9b86572, 32'shc9edeb50, 32'shca23f698, 32'shca5a86c4, 32'shca919b4e, + 32'shcac933ae, 32'shcb014f5b, 32'shcb39edca, 32'shcb730e70, 32'shcbacb0bf, 32'shcbe6d42b, 32'shcc217822, 32'shcc5c9c14, + 32'shcc983f70, 32'shccd461a2, 32'shcd110216, 32'shcd4e2037, 32'shcd8bbb6d, 32'shcdc9d320, 32'shce0866b8, 32'shce47759a, + 32'shce86ff2a, 32'shcec702cb, 32'shcf077fe1, 32'shcf4875ca, 32'shcf89e3e8, 32'shcfcbc999, 32'shd00e2639, 32'shd050f926, + 32'shd09441bb, 32'shd0d7ff51, 32'shd11c3142, 32'shd160d6e5, 32'shd1a5ef90, 32'shd1eb7a9a, 32'shd2317756, 32'shd277e518, + 32'shd2bec333, 32'shd30610f7, 32'shd34dcdb4, 32'shd395f8ba, 32'shd3de9156, 32'shd42796d5, 32'shd4710883, 32'shd4bae5ab, + 32'shd5052d97, 32'shd54fdf8f, 32'shd59afadb, 32'shd5e67ec1, 32'shd6326a88, 32'shd67ebd74, 32'shd6cb76c9, 32'shd71895c9, + 32'shd76619b6, 32'shd7b401d1, 32'shd8024d59, 32'shd850fb8e, 32'shd8a00bae, 32'shd8ef7cf4, 32'shd93f4e9e, 32'shd98f7fe6, + 32'shd9e01006, 32'shda30fe38, 32'shda8249b4, 32'shdad3f1b1, 32'shdb25f566, 32'shdb785409, 32'shdbcb0cce, 32'shdc1e1ee9, + 32'shdc71898d, 32'shdcc54bec, 32'shdd196538, 32'shdd6dd4a2, 32'shddc29958, 32'shde17b28a, 32'shde6d1f65, 32'shdec2df18, + 32'shdf18f0ce, 32'shdf6f53b3, 32'shdfc606f1, 32'she01d09b4, 32'she0745b24, 32'she0cbfa6a, 32'she123e6ad, 32'she17c1f15, + 32'she1d4a2c8, 32'she22d70eb, 32'she28688a4, 32'she2dfe917, 32'she3399167, 32'she39380b6, 32'she3edb628, 32'she44830dd, + 32'she4a2eff6, 32'she4fdf294, 32'she55937d5, 32'she5b4bed8, 32'she61086bc, 32'she66c8e9f, 32'she6c8d59c, 32'she7255ad1, + 32'she7821d59, 32'she7df1c50, 32'she83c56cf, 32'she899cbf1, 32'she8f77acf, 32'she9556282, 32'she9b38223, 32'shea11d8c8, + 32'shea70658a, 32'sheacf277f, 32'sheb2e1dbe, 32'sheb8d475b, 32'shebeca36c, 32'shec4c3106, 32'shecabef3d, 32'shed0bdd25, + 32'shed6bf9d1, 32'shedcc4454, 32'shee2cbbc1, 32'shee8d5f29, 32'sheeee2d9d, 32'shef4f2630, 32'shefb047f2, 32'shf01191f3, + 32'shf0730342, 32'shf0d49af1, 32'shf136580d, 32'shf19839a6, 32'shf1fa3ecb, 32'shf25c6688, 32'shf2beafed, 32'shf3211a07, + 32'shf383a3e2, 32'shf3e64c8c, 32'shf4491311, 32'shf4abf67e, 32'shf50ef5de, 32'shf572103d, 32'shf5d544a7, 32'shf6389228, + 32'shf69bf7c9, 32'shf6ff7496, 32'shf7630799, 32'shf7c6afdc, 32'shf82a6c6a, 32'shf88e3c4d, 32'shf8f21e8e, 32'shf9561237, + 32'shf9ba1651, 32'shfa1e29e5, 32'shfa824bfd, 32'shfae67ba2, 32'shfb4ab7db, 32'shfbaeffb3, 32'shfc135231, 32'shfc77ae5e, + 32'shfcdc1342, 32'shfd407fe6, 32'shfda4f351, 32'shfe096c8d, 32'shfe6deaa1, 32'shfed26c94, 32'shff36f170, 32'shff9b783c + }; + + reg signed [31:0] W_Re_reg, W_Im_reg; + always_ff @(posedge clk) begin + W_Re_reg <= W_Re_table[k]; + W_Im_reg <= W_Im_table[k]; + end + + round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re); + round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im); + end + else + begin :illegal +// assign W_Re = '0, W_Im = '0; +// $fatal("Error"); + end + endgenerate +endmodule :W_int32 + +`endif Index: fft_int_size/W_int32_gen.m =================================================================== --- fft_int_size/W_int32_gen.m (nonexistent) +++ fft_int_size/W_int32_gen.m (revision 7) @@ -0,0 +1,91 @@ +clc +clear +close all + +POW_MAX = 16; + +fid = fopen('W_int32.sv', 'w'); + +fprintf(fid, '`ifndef _fft_w_\n'); +fprintf(fid, '`define _fft_w_\n'); +fprintf(fid, '`include "round32.sv"\n\n'); + +fprintf(fid, 'module W_int32 #(parameter POW, W_WIDTH)(clk, k, W_Re, W_Im);\n'); +fprintf(fid, '// N = 2**POW, Max POW = 10, Max W_WIDTH = 32\n'); +fprintf(fid, '// File contains the rotate coefficients\n'); +fprintf(fid, '// W(k, N) = exp(-2i * pi * k / N)\n'); +fprintf(fid, '// in the scale W * 2^30\n\n'); +fprintf(fid, ' input wire clk;\n'); +fprintf(fid, ' input wire [POW-2:0] k;\n'); +fprintf(fid, ' output wire signed [W_WIDTH-1:0] W_Re, W_Im;\n\n'); + +fprintf(fid, ' generate\n'); +fprintf(fid, ' if (POW == 1)\n'); +fprintf(fid, ' begin\n'); +w = W(0, 2) * 2^30; +bit32 = IntToBit32(real(w)); +fprintf(fid, ' localparam bit signed [31:0] W_Re_table = 32''sh%08x;\n', bit32); + +bit32 = IntToBit32(imag(w)); +fprintf(fid, ' localparam bit signed [31:0] W_Im_table = 32''sh%08x;\n\n', bit32); + +fprintf(fid, ' round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_table, W_Re);\n'); +fprintf(fid, ' round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_table, W_Im);\n'); +fprintf(fid, ' end\n'); + +for POW = 2:POW_MAX + fprintf(fid, ' else if (POW == %d)\n', POW); + fprintf(fid, ' begin\n'); + fprintf(fid, ' reg signed [31:0] W_Re_table[%d] = ''{\n', 2^(POW-1)); + fprintf(fid, ' '); + for i=1:2^(POW-1) + w = W(i-1, 2^POW) * 2^30; + bit32 = IntToBit32(real(w)); + if i ~= 2^(POW-1) + fprintf(fid, '32''sh%08x, ', bit32); + if mod(i, 8) == 0 + fprintf(fid, '\n'); + fprintf(fid, ' '); + end + else + fprintf(fid, '32''sh%08x\n', bit32); + fprintf(fid, ' };\n\n'); + end + end + + fprintf(fid, ' reg signed [31:0] W_Im_table[%d] = ''{\n', 2^(POW-1)); + fprintf(fid, ' '); + for i=1:2^(POW-1) + w = W(i-1, 2^POW) * 2^30; + bit32 = IntToBit32(imag(w)); + if i ~= 2^(POW-1) + fprintf(fid, '32''sh%08x, ', bit32); + if mod(i, 8) == 0 + fprintf(fid, '\n'); + fprintf(fid, ' '); + end + else + fprintf(fid, '32''sh%08x\n', bit32); + fprintf(fid, ' };\n\n'); + end + end + + fprintf(fid, ' reg signed [31:0] W_Re_reg, W_Im_reg;\n'); + fprintf(fid, ' always_ff @(posedge clk) begin\n'); + fprintf(fid, ' W_Re_reg <= W_Re_table[k];\n'); + fprintf(fid, ' W_Im_reg <= W_Im_table[k];\n'); + fprintf(fid, ' end\n\n'); + + fprintf(fid, ' round32 #(.WIDTH(W_WIDTH)) round_re(W_Re_reg, W_Re);\n'); + fprintf(fid, ' round32 #(.WIDTH(W_WIDTH)) round_im(W_Im_reg, W_Im);\n'); + + fprintf(fid, ' end\n'); +end + +fprintf(fid, ' endgenerate\n'); + +fprintf(fid, 'endmodule :W_int32\n\n'); + +fprintf(fid, '`endif\n'); + +fclose(fid); Index: fft_int_size/bitrev.sv =================================================================== --- fft_int_size/bitrev.sv (nonexistent) +++ fft_int_size/bitrev.sv (revision 7) @@ -0,0 +1,33 @@ +/* +Bit-reversal permutation module +Delay 1 clock +*/ + +`ifndef _bitrev_ +`define _bitrev_ + +module bitrev #( + parameter WIDTH = 14, // max data width + parameter BIT_WIDTH = (2**$clog2(WIDTH) > WIDTH - 1) ? $clog2(WIDTH) : $clog2(WIDTH) + 1 +)( + input clk, + input [BIT_WIDTH-1:0] width, // current data width + input [WIDTH-1:0] x, // input data + output [WIDTH-1:0] y // result +); + + wire [WIDTH-1:0] yy; + + genvar i; + generate for (i = 0; i < WIDTH; i++) + begin :gen + assign yy[WIDTH-1-i] = x[i]; + end + endgenerate + + always_ff @(posedge clk) + y <= yy >> (WIDTH - width); + +endmodule :bitrev + +`endif Index: fft_int_size/bitrev_cnt.sv =================================================================== --- fft_int_size/bitrev_cnt.sv (nonexistent) +++ fft_int_size/bitrev_cnt.sv (revision 7) @@ -0,0 +1,48 @@ +`ifndef _bitrev_cnt_ +`define _bitrev_cnt_ + +module bitrev_cnt #( + parameter WIDTH = 7, + parameter WIDTH_WIDTH = (2**$clog2(WIDTH) > WIDTH - 1) ? $clog2(WIDTH) : $clog2(WIDTH) + 1 +)( + input clk, aclr, + input clk_ena, sclr, + input [WIDTH_WIDTH-1:0] width, + input [WIDTH-1:0] cnt_max, + output reg [WIDTH-1:0] cnt, cnt_rev +); + wire [WIDTH-1:0] _cnt_rev; + + always_ff @(posedge clk, posedge aclr) + if (aclr) + cnt <= '0; + else if (clk_ena) + if (sclr || cnt == cnt_max) + cnt <= '0; + else + cnt <= cnt + 1'b1; + + bitrev #(.WIDTH(WIDTH)) bitrev_inst(.x(cnt + 1'b1), .y(_cnt_rev)); + + always_ff @(posedge clk, posedge aclr) + if (aclr) + cnt_rev <= '0; + else if (clk_ena) + if (sclr || cnt == cnt_max) + cnt_rev <= '0; + else + cnt_rev <= _cnt_rev >> (WIDTH - width); + +endmodule :bitrev_cnt + +// Fix width bit reversial. It dont need any logic +module bitrev #(parameter WIDTH)(input [WIDTH-1:0] x, output [WIDTH-1:0] y); + genvar i; + generate for (i = 0; i < WIDTH; i++) + begin :gen + assign y[WIDTH-1-i] = x[i]; + end + endgenerate +endmodule :bitrev + +`endif Index: fft_int_size/butterfly.sv =================================================================== --- fft_int_size/butterfly.sv (nonexistent) +++ fft_int_size/butterfly.sv (revision 7) @@ -0,0 +1,146 @@ +`ifndef _butterfly_ +`define _butterfly_ +`include "W_int32.sv" + +// Delay 3, 4 +module butterfly #(parameter DATA_WIDTH = 32, W_WIDTH = 32, POW = 3)( + input clk, + input sync, // y + input signed [DATA_WIDTH-1:0] sink_Re, sink_Im, + output reg signed [DATA_WIDTH:0] source_Re, source_Im +); + reg [POW-1:0] cnt; + + always_ff @(posedge clk) + if (sync) + cnt <= '0; + else + cnt <= cnt + 1'b1; + + generate + if (POW == 1) // delay 3 + begin :gen1 + wire x_yn; + reg signed [DATA_WIDTH-1:0] Re_reg[2], Im_reg[2]; + reg signed [DATA_WIDTH:0] new_x_Re, new_x_Im; + + assign x_yn = cnt[0]; + + // W = 1 + always_ff @(posedge clk) begin + Re_reg[0] <= sink_Re; + Im_reg[0] <= sink_Im; + Re_reg[1] <= Re_reg[0]; + Im_reg[1] <= Im_reg[0]; + end + + always_ff @(posedge clk) + if (x_yn == 1'b1) + begin + new_x_Re <= Re_reg[0] + Re_reg[1]; // x + y + new_x_Im <= Im_reg[0] + Im_reg[1]; + source_Re <= Re_reg[0] - Re_reg[1]; // x - y + source_Im <= Im_reg[0] - Im_reg[1]; + end + else + begin + source_Re <= new_x_Re; + source_Im <= new_x_Im; + end + end + else if (POW == 2) // delay 3 + begin :gen2 + wire x_yn, k; + reg signed [DATA_WIDTH-1:0] Re_reg, Im_reg; + reg signed [DATA_WIDTH-1:0] wy_Re, wy_Im; + reg signed [DATA_WIDTH:0] new_x_Re, new_x_Im; + + assign x_yn = cnt[0]; + assign k = cnt[1]; + + always_ff @(posedge clk) begin + Re_reg <= sink_Re; + Im_reg <= sink_Im; + end + + always_ff @(posedge clk) + if (x_yn == 1'b0) + case (k) + 1'b0: // 1 + begin + wy_Re <= Re_reg; + wy_Im <= Im_reg; + end + 1'b1: // -j: -j * (a + j*b) = b - j*a + begin + wy_Re <= Im_reg; + wy_Im <= DATA_WIDTH'('sh0) - Re_reg; + end + endcase + + always_ff @(posedge clk) + if (x_yn == 1'b1) + begin + new_x_Re <= Re_reg + wy_Re; // x + w*y + new_x_Im <= Im_reg + wy_Im; + source_Re <= Re_reg - wy_Re; // x - w*y + source_Im <= Im_reg - wy_Im; + end + else + begin + source_Re <= new_x_Re; + source_Im <= new_x_Im; + end + end + else // delay 4 + begin :gen3 + reg x_yn; + wire [POW-2:0] k; + reg signed [DATA_WIDTH-1:0] Re_reg[2], Im_reg[2]; + wire signed [W_WIDTH-1:0] W_Re, W_Im; + reg signed [W_WIDTH + DATA_WIDTH:0] wy_Re, wy_Im; + wire signed [DATA_WIDTH-1:0] wy_Re_tr, wy_Im_tr; + reg signed [DATA_WIDTH:0] new_x_Re, new_x_Im; + + always_ff @(posedge clk) + begin + Re_reg[0] <= sink_Re; + Im_reg[0] <= sink_Im; + Re_reg[1] <= Re_reg[0]; + Im_reg[1] <= Im_reg[0]; + x_yn <= cnt[0]; + end + + assign k = cnt[POW-1:1]; + + W_int32 #(.POW(POW), .W_WIDTH(W_WIDTH)) W_inst(.clk, .k, .W_Re, .W_Im); + + // w * y = (wr + wi * j) * (yr + yi * j) = wr * yr - wi * yi + j * (wi * yr + wr * yi) + always_ff @(posedge clk) + if (x_yn == 1'b0) + begin + wy_Re <= W_Re * Re_reg[1] - W_Im * Im_reg[1]; + wy_Im <= W_Re * Im_reg[1] + W_Im * Re_reg[1]; + end + + assign wy_Re_tr = wy_Re[(W_WIDTH-2)+:DATA_WIDTH]; + assign wy_Im_tr = wy_Im[(W_WIDTH-2)+:DATA_WIDTH]; + + always_ff @(posedge clk) + if (x_yn == 1'b1) + begin + new_x_Re <= Re_reg[1] + wy_Re_tr; // x + new_x_Im <= Im_reg[1] + wy_Im_tr; + source_Re <= Re_reg[1] - wy_Re_tr; // y + source_Im <= Im_reg[1] - wy_Im_tr; + end + else + begin + source_Re <= new_x_Re; + source_Im <= new_x_Im; + end + end + endgenerate +endmodule :butterfly + +`endif Index: fft_int_size/cascade_0.sv =================================================================== --- fft_int_size/cascade_0.sv (nonexistent) +++ fft_int_size/cascade_0.sv (revision 7) @@ -0,0 +1,93 @@ +/* +Pre-processing cascade +It make bit-reversal permutation +First FFT cascade reads data from it +*/ + + +`ifndef _cascade_0_ +`define _cascade_0_ +`include "bitrev_cnt.sv" + +module cascade_0 #(parameter + ADDR_WIDTH = 9, + DATA_WIDTH = 32, + POW_WIDTH = (2**$clog2(ADDR_WIDTH) > ADDR_WIDTH - 1) ? $clog2(ADDR_WIDTH) : $clog2(ADDR_WIDTH) + 1 +)( + input clk, aclr, + + // input data stream + input sink_sop, sink_eop, sink_valid, // valid must be solid + input signed [DATA_WIDTH-1:0] sink_Re, sink_Im, + + // current pow and last addr + input [POW_WIDTH-1:0] pow, + input [ADDR_WIDTH-1:0] addr_max, + + // access to output buffer + input [ADDR_WIDTH-1:0] rdaddr, // read address + output reg signed [DATA_WIDTH-1:0] q_Re, q_Im, // read data + output reg ready, // buffer ready + input rdack, // read data acknowledge + + output reg error // input stream error +); + reg wr_buf = 1'b0, rd_buf = 1'b0; + reg signed [DATA_WIDTH-1:0] mem_Re[2][2**ADDR_WIDTH]; + reg signed [DATA_WIDTH-1:0] mem_Im[2][2**ADDR_WIDTH]; + + wire [ADDR_WIDTH-1:0] wraddr, wraddr_rev; + reg valid_reg = 1'b0, eop_reg = 1'b0; + reg signed [DATA_WIDTH-1:0] Re_reg, Im_reg; + + bitrev_cnt #(.WIDTH(ADDR_WIDTH)) cnt_inst( + .clk, .aclr, + .clk_ena(sink_valid), .sclr(sink_sop), + .width(pow), .cnt_max(addr_max), + .cnt(wraddr), .cnt_rev(wraddr_rev) + ); + + always_ff @(posedge clk, posedge aclr) + valid_reg <= (aclr) ? 1'b0 : sink_valid; + + always_ff @(posedge clk) begin + Re_reg <= sink_Re; + Im_reg <= sink_Im; + eop_reg <= sink_eop; + + if (valid_reg) begin + mem_Re[wr_buf][wraddr_rev] <= Re_reg; + mem_Im[wr_buf][wraddr_rev] <= Im_reg; + end + end + + always_ff @(posedge clk) begin + q_Re <= mem_Re[rd_buf][rdaddr]; + q_Im <= mem_Im[rd_buf][rdaddr]; + end + + always_ff @(posedge clk, posedge aclr) + if (aclr) + ready <= 1'b0; + else if (valid_reg && eop_reg && wraddr == addr_max) + ready <= 1'b1; + else if (rdack) + ready <= 1'b0; + + always_ff @(posedge clk, posedge aclr) + if (aclr) + wr_buf <= 1'b0; + else if (valid_reg && eop_reg && wraddr == addr_max) + wr_buf <= !wr_buf; + + always_ff @(posedge clk, posedge aclr) + if (aclr) + rd_buf <= 1'b0; + else if (rdack) + rd_buf <= !rd_buf; + + always_ff @(posedge clk, posedge aclr) + error <= (aclr) ? 1'b0 : (sink_sop || sink_eop) && !sink_valid || sink_eop && wraddr != addr_max - 1'b1; +endmodule :cascade_0 + +`endif Index: fft_int_size/cascade_n.sv =================================================================== --- fft_int_size/cascade_n.sv (nonexistent) +++ fft_int_size/cascade_n.sv (revision 7) @@ -0,0 +1,122 @@ +`ifndef _cascade_n_ +`define _cascade_n_ +`include "butterfly.sv" +`include "yx_addr.sv" +`include "delay_line.sv" + +module cascade_n #(parameter + ADDR_WIDTH = 9, + DATA_WIDTH = 32, +// RES_WIDTH = DATA_WIDTH + 1, + POW = 3, // 1...ADDR_WIDTH/2 + POW_WIDTH = (2**$clog2(ADDR_WIDTH) > ADDR_WIDTH - 1) ? $clog2(ADDR_WIDTH) : $clog2(ADDR_WIDTH) + 1 +)( + input aclr, clk, sink_ready, + output [ADDR_WIDTH-1:0] sink_rdaddr, + input signed [DATA_WIDTH-1:0] sink_Re, sink_Im, + output reg sink_rdack, + input [POW_WIDTH-1:0] pow, // 4..ADDR_WIDTH + input [ADDR_WIDTH-1:0] addr_max, + + input [ADDR_WIDTH-1:0] source_rdaddr, + input source_rdack, + output reg signed [DATA_WIDTH:0] source_Re, source_Im, + output reg source_ready +); + localparam DELAY = (POW == 1 || POW == 2) ? 3 : 4; + + reg wr_buf = 1'b0, rd_buf = 1'b0; + reg signed [DATA_WIDTH:0] mem_Re[2][2**ADDR_WIDTH]; + reg signed [DATA_WIDTH:0] mem_Im[2][2**ADDR_WIDTH]; + + reg [ADDR_WIDTH-1:0] cnt, cnt_dly; + reg sop = 1'b0; + wire [ADDR_WIDTH-1:0] wraddr; + wire wrvalid; + wire [DATA_WIDTH:0] bf_Re, bf_Im; + + always @(posedge clk, posedge aclr) + if (aclr) + cnt <= '0; + else if (!sink_ready || sink_rdack || cnt == addr_max) + cnt <= '0; + else + cnt <= cnt + 1'b1; + + yx_addr #(.WIDTH(ADDR_WIDTH), .POW(POW)) yx0(.cnt, .yx_cnt(sink_rdaddr)); + + always_ff @(posedge clk) begin + sink_rdack <= cnt == addr_max - 1'b1; // at last addr + sop <= cnt == 'h0; + end + + butterfly #(.DATA_WIDTH(DATA_WIDTH), .POW(POW)) bf( // 3,4 clocks delay + .clk, .sync(sop), .sink_Re, .sink_Im, // y, x + .source_Re(bf_Re), .source_Im(bf_Im) // y, x + ); + + // Delay line. Butterfly (3 or 4) + memory read (1) + delay_lines_reg #(.DELAY(DELAY + 1), .WIDTH(ADDR_WIDTH)) dly0( + .aclr(1'b0), .sclr(1'b0), .clock(clk), .clock_ena(1'b1), + .sig_in(cnt), .sig_out(cnt_dly) + ); + + delay_line_reg #(.DELAY(DELAY + 1)) dly1( + .aclr, .sclr(1'b0), .clock(clk), .clock_ena(1'b1), + .sig_in(sink_ready), .sig_out(wrvalid) + ); + + yx_addr #(.WIDTH(ADDR_WIDTH), .POW(POW)) yx1(.cnt(cnt_dly), .yx_cnt(wraddr)); + + always_ff @(posedge clk) + if (wrvalid) + begin + mem_Re[wr_buf][wraddr] <= bf_Re; + mem_Im[wr_buf][wraddr] <= bf_Im; + end + + always_ff @(posedge clk) begin + source_Re <= mem_Re[rd_buf][source_rdaddr]; + source_Im <= mem_Im[rd_buf][source_rdaddr]; + end + + generate + if (POW == ADDR_WIDTH) + begin + always_ff @(posedge clk, posedge aclr) + if (aclr) + source_ready <= 1'b0; + else if (wrvalid && cnt_dly == 2**(POW-1)) // last cascade, ready to line read + source_ready <= 1'b1; + else if (source_rdack) // end + source_ready <= 1'b0; + end + else + begin + always_ff @(posedge clk, posedge aclr) + if (aclr) + source_ready <= 1'b0; + else if (pow == POW && wrvalid && cnt_dly == 2**(POW-1)) // last cascade, ready to line read + source_ready <= 1'b1; + else if (wrvalid && wraddr == 2**POW) + source_ready <= 1'b1; + else if (source_rdack) // end + source_ready <= 1'b0; + end + endgenerate + + always_ff @(posedge clk, posedge aclr) + if (aclr) + wr_buf <= 1'b0; + else if (wrvalid && cnt_dly == addr_max) + wr_buf <= !wr_buf; + + always_ff @(posedge clk, posedge aclr) + if (aclr) + rd_buf <= 1'b0; + else if (source_ready && source_rdack) + rd_buf <= !rd_buf; + +endmodule :cascade_n + +`endif Index: fft_int_size/delay_line.sv =================================================================== --- fft_int_size/delay_line.sv (nonexistent) +++ fft_int_size/delay_line.sv (revision 7) @@ -0,0 +1,50 @@ +`ifndef _delay_line_ +`define _delay_line_ + +module delay_lines_reg #(parameter DELAY = 300, WIDTH = 3)( + input aclr, sclr, clock, clock_ena, + input [WIDTH-1:0] sig_in, + output [WIDTH-1:0] sig_out +); + +genvar i; +generate for (i = 0; i < WIDTH; i++) + begin :line + delay_line_reg #(.DELAY(DELAY)) delay_line_inst(.aclr, .sclr, .clock, .clock_ena, .sig_in(sig_in[i]), .sig_out(sig_out[i])); + end +endgenerate + +endmodule :delay_lines_reg + +module delay_line_reg #(parameter DELAY = 300)(input aclr, sclr, clock, clock_ena, sig_in, output sig_out); + +generate + if (DELAY == 0) + assign sig_out = !aclr && !sclr && sig_in; + else if (DELAY == 1) + begin + reg sig_reg = 1'b0; + + always_ff @(posedge clock, posedge aclr) + if (aclr) sig_reg <= 1'b0; + else if (sclr) sig_reg <= 1'b0; + else if (clock_ena) sig_reg <= sig_in; + + assign sig_out = sig_reg; + end + else + begin + reg [DELAY-1:0] sig_reg = '0; + + always_ff @(posedge clock, posedge aclr) + if (aclr) sig_reg <= '0; + else if (sclr) sig_reg <= '0; + else if (clock_ena) sig_reg <= {sig_reg[DELAY-2:0], sig_in}; + + assign sig_out = sig_reg[DELAY-1]; + end +endgenerate + +endmodule :delay_line_reg + +`endif Index: fft_int_size/fft_int_size.sv =================================================================== --- fft_int_size/fft_int_size.sv (nonexistent) +++ fft_int_size/fft_int_size.sv (revision 7) @@ -0,0 +1,185 @@ +/* +Streaming FFT module with resizable FFT length +*/ + +`ifndef _fft_int_size_ +`define _fft_int_size_ +`include "size_ctrl.sv" +`include "cascade_0.sv" +`include "cascade_n.sv" + +// Integer resizable streaming FFT +module fft_int_size #(parameter + POW = 9, // max fft size 2**POW + DATA_WIDTH = 32, + POW_WIDTH = (2**$clog2(POW) > POW - 1) ? $clog2(POW) : $clog2(POW) + 1, + RES_WIDTH = DATA_WIDTH + POW +)( + input clk, aclr, + + // input data stream + input sink_sop, sink_eop, sink_valid, // valid signal must be solid between sop and eop + input signed [DATA_WIDTH-1:0] sink_Re, sink_Im, + + // FFT length 2**pow + input [POW_WIDTH-1:0] pow, // 4..POW + output pow_ready, // pow ready to change + + // Result data stream + output reg source_sop, source_eop, source_valid, + output reg signed [RES_WIDTH-1:0] source_Re, source_Im, + + output error +); + wire [POW-1:0][POW-1:0] fft_rdaddr; + wire [POW-1:0] fft_rdack; + wire [POW:0] ready; + + logic [POW:0][POW-1:0] rdaddr; + logic [POW:0] rdack; + + genvar k; + generate for (k = 0; k <= POW; k++) + begin :res + wire signed [DATA_WIDTH + k - 1:0] re, im; + end + endgenerate + + wire [POW_WIDTH-1:0] pow_reg; + wire [POW-1:0] addr_max; + wire [1:0] err; + + wire sop_reg, eop_reg, valid_reg; + wire signed [DATA_WIDTH-1:0] re_reg, im_reg; + + size_ctrl #(.POW(POW), .DATA_WIDTH(DATA_WIDTH)) size_inst( + .clk, .aclr, .pow, .source_eop, + .pow_reg, .addr_max, .pow_ready, .error(err[0]), + + .sink_sop, .sink_eop, .sink_valid, .sink_Re, .sink_Im, + .sop_reg, .eop_reg, .valid_reg, .re_reg, .im_reg + ); + + // input controller + cascade_0 #(.ADDR_WIDTH(POW), .DATA_WIDTH(DATA_WIDTH)) c0( + .clk, .aclr, + .sink_sop(sop_reg), .sink_eop(eop_reg), .sink_valid(valid_reg), .sink_Re(re_reg), .sink_Im(im_reg), + .pow(pow_reg), .addr_max, + + .rdaddr(rdaddr[0]), + .q_Re(res[0].re), .q_Im(res[0].im), + .ready(ready[0]), + .rdack(rdack[0]), + .error(err[1]) + ); + + always_comb begin + rdaddr[0] = fft_rdaddr[0]; + rdack[0] = fft_rdack[0]; + end + + reg [POW-1:0] cnt = '0; + genvar i; + generate + for (i = 1; i <= POW; i++) + begin :gen + cascade_n #(.ADDR_WIDTH(POW), .DATA_WIDTH(DATA_WIDTH + i - 1), .POW(i)) cn( + .clk, .aclr, .sink_ready(ready[i-1] && pow_reg >= i), + .sink_rdaddr(fft_rdaddr[i-1]), + .sink_Re(res[i-1].re), .sink_Im(res[i-1].im), + .sink_rdack(fft_rdack[i-1]), + .pow(pow_reg), .addr_max, + + .source_rdaddr(rdaddr[i]), + .source_rdack(rdack[i]), + .source_Re(res[i].re), .source_Im(res[i].im), + .source_ready(ready[i]) + ); + + if (i < 4) + begin + always_comb + begin + rdaddr[i] = fft_rdaddr[i]; + rdack[i] = fft_rdack[i]; + end + end + else if (i == POW) + begin + always_comb begin + rdaddr[POW] = cnt; + rdack[POW] = cnt == '1; + end + end + else + begin + always_comb + if (pow_reg > i) + begin // todo: use 2 ports memory to read data + rdaddr[i] = fft_rdaddr[i]; + rdack[i] = fft_rdack[i]; + end + else + begin + rdaddr[i] = cnt; + rdack[i] = cnt == addr_max; + end + end + end + endgenerate + + // Read data from last cascade + always_ff @(posedge clk, posedge aclr) + if (aclr) + cnt <= '0; + else if (!ready[pow_reg] || cnt == addr_max) + cnt <= '0; + else + cnt <= cnt + 1'b1; + + reg res_sop, res_eop, res_valid = 1'b0; + + always_ff @(posedge clk) begin + res_sop <= ready[pow_reg] && cnt == '0; + res_eop <= cnt == addr_max; + end + + always_ff @(posedge clk, posedge aclr) + res_valid <= (aclr) ? 1'b0 : ready[pow_reg] || rdack[pow_reg]; + + // form result + // todo: 2 regs + wire signed [RES_WIDTH - 1:0] res_re[2**POW_WIDTH], res_im[2**POW_WIDTH]; + + genvar m; + generate for (m = 0; m < 2**POW_WIDTH; m++) + begin :gen_res + if (m >= 4 && m <= POW) + begin + assign res_re[m] = RES_WIDTH'('sh0) + signed'(res[m].re); + assign res_im[m] = RES_WIDTH'('sh0) + signed'(res[m].im); + end + else + begin + assign res_re[m] = 'sh0; + assign res_im[m] = 'sh0; + end + end + endgenerate + + always_ff @(posedge clk) begin + source_sop <= res_sop; + source_eop <= res_eop; + + source_Re <= res_re[pow_reg]; + source_Im <= res_im[pow_reg]; + end + + always_ff @(posedge clk, posedge aclr) + source_valid <= (aclr) ? 1'b0 : res_valid; + + assign error = |err; + +endmodule :fft_int_size + +`endif Index: fft_int_size/fft_int_size_tb.sv =================================================================== --- fft_int_size/fft_int_size_tb.sv (nonexistent) +++ fft_int_size/fft_int_size_tb.sv (revision 7) @@ -0,0 +1,154 @@ +timeunit 1ns; +timeprecision 1ns; + +module fft_int_size_tb; + localparam POW = 9; + localparam DATA_WIDTH = 32; + localparam POW_WIDTH = (2**$clog2(POW) > POW - 1) ? $clog2(POW) : $clog2(POW) + 1; + localparam RES_WIDTH = DATA_WIDTH + POW; + + bit clk = 0, aclr = 1; + bit sink_sop = 0, sink_eop = 0, sink_valid = 0; + bit signed [DATA_WIDTH-1:0] sink_Re = 0, sink_Im = 0; + + bit [POW_WIDTH-1:0] pow = 7; // 4..POW + wire pow_ready; + + wire source_sop, source_eop, source_valid; + wire signed [RES_WIDTH-1:0] source_Re, source_Im; + wire error; + + localparam time period = 20ns; + always #(period/2) clk++; + + initial begin + repeat(10) @(posedge clk); + aclr = 0; + repeat(10) @(posedge clk); + + wait(pow_ready); + pow = 6; + @(posedge clk); + Test(2**pow, 1<<1); + Test(2**pow, 1<<2); + Test(2**pow, 5<<1); + + wait(pow_ready); + pow = 9; + @(posedge clk); + Test(2**pow, 1<<1); + Test(2**pow, 1<<2); + Test(2**pow, 5<<1); + +// TestLine(2**pow); +// TestConst(2**pow); + + wait (pow_ready || error); + if (error) $warning("ERROR"); + + repeat(2**pow * 3 + 400) @(posedge clk); + $stop(2); + end + + always #(period * 2**POW * 10) begin + $warning("Timeout"); + $stop(2); + end + + fft_int_size #(.POW(POW), .DATA_WIDTH(DATA_WIDTH)) dut(.*); + + localparam IFFT_WIDTH = RES_WIDTH + POW; + + wire ifft_pow_ready; + wire signed [IFFT_WIDTH-1:0] ifft_source_Re, ifft_source_Im; + wire signed [IFFT_WIDTH-POW-1:0] ifft_Re, ifft_Im; + wire ifft_sop, ifft_eop, ifft_valid; + wire ifft_err; + + fft_int_size #(.POW(POW), .DATA_WIDTH(RES_WIDTH)) ifft( + .clk, .aclr, + .sink_sop(source_sop), .sink_eop(source_eop), .sink_valid(source_valid), + .sink_Re(source_Im), .sink_Im(source_Re), + .pow(pow), .pow_ready(ifft_pow_ready), + .source_sop(ifft_sop), .source_eop(ifft_eop), .source_valid(ifft_valid), + .source_Re(ifft_source_Im), .source_Im(ifft_source_Re), + .error(ifft_err) + ); + + assign ifft_Re = ifft_source_Re / 2**pow; + assign ifft_Im = ifft_source_Im / 2**pow; + + task Test(int len, int bin_msk = 2); + int ar[]; + ar = new[len]; + + for (int i = 0; i < len; i++) + if ((bin_msk & 1< POW - 1) ? $clog2(POW) : $clog2(POW) + 1 +)( + input clk, aclr, + input [POW_WIDTH-1:0] pow, // 4..POW - FFT size is 2**pow + input source_eop, // end of FFT + output reg [POW_WIDTH-1:0] pow_reg, // current FFT pow + output reg [POW-1:0] addr_max, // current last FFT data number + output reg pow_ready, // pow ready to change + output reg error, // error of parameter pow + + // input data stream + input sink_sop, sink_eop, sink_valid, + input signed [DATA_WIDTH-1:0] sink_Re, sink_Im, + // output data stream + output reg sop_reg, eop_reg, valid_reg, + output reg signed [DATA_WIDTH-1:0] re_reg, im_reg +); + reg [1:0] tsk_cnt = '0; // fft tasks counter + + always_ff @(posedge clk, posedge aclr) + if (aclr) + begin + pow_reg <= POW_WIDTH'(POW); + addr_max <= {POW{1'b1}}; + end + else if (pow > POW) + begin + pow_reg <= POW_WIDTH'(POW); + addr_max <= {POW{1'b1}}; + end + else if (pow_ready && sink_sop && sink_valid) + begin + pow_reg <= pow; + addr_max <= {POW{1'b1}}>>(POW - pow); + end + + always_ff @(posedge clk, posedge aclr) + if (aclr) + tsk_cnt <= '0; + else if (sink_sop && sink_valid && source_eop) + ; + else if (sink_sop && sink_valid) + tsk_cnt <= tsk_cnt + 1'b1; + else if (source_eop) + tsk_cnt <= tsk_cnt - 1'b1; + + always_ff @(posedge clk, posedge aclr) + if (aclr) + pow_ready <= 1'b0; + else if (sink_sop && sink_valid) + pow_ready <= 1'b0; + else if (source_eop && tsk_cnt == 'd1) + pow_ready <= 1'b1; + else + pow_ready <= tsk_cnt == '0; + + always_ff @(posedge clk, posedge aclr) + if (aclr) + error <= 1'b0; + else if (sink_sop && sink_valid && (pow != pow_reg && !pow_ready || pow < 4 || pow > POW)) + error <= 1'b1; + + always_ff @(posedge clk, posedge aclr) + valid_reg <= (aclr) ? 1'b0 : sink_valid; + + always_ff @(posedge clk) begin + sop_reg <= sink_sop; + eop_reg <= sink_eop; + re_reg <= sink_Re; + im_reg <= sink_Im; + end + +endmodule :size_ctrl + +`endif Index: fft_int_size/yx_addr.sv =================================================================== --- fft_int_size/yx_addr.sv (nonexistent) +++ fft_int_size/yx_addr.sv (revision 7) @@ -0,0 +1,30 @@ +`ifndef _yx_addr_ +`define _yx_addr_ + +module yx_addr #(WIDTH = 9, POW = 2)( + input [WIDTH-1:0] cnt, + output [WIDTH-1:0] yx_cnt +); + +generate + if (POW < 1) + begin + assign yx_cnt = cnt; + end + else if (POW == 1) + begin + assign yx_cnt = {cnt[WIDTH-1:POW], !cnt[0]}; + end + else if (POW == WIDTH) + begin + assign yx_cnt = {!cnt[0], cnt[POW-1:1]}; + end + else + begin + assign yx_cnt = {cnt[WIDTH-1:POW], !cnt[0], cnt[POW-1:1]}; + end +endgenerate + +endmodule :yx_addr + +`endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.