IFFT_Library.bsv
上传用户:aoptech
上传日期:2014-09-22
资源大小:784k
文件大小:12k
源码类别:

3G开发

开发平台:

Others

  1. // The MIT License
  2. //
  3. // Copyright (c) 2006 Nirav Dave (ndave@csail.mit.edu)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. import ComplexF::*;
  23. import DataTypes::*;
  24. import LibraryFunctions::*;
  25. import Vector::*;
  26. //This function just serves as a short hand for grabbing 4 consecutive indices in
  27. //a vector
  28. function Vector#(4, a) take4(Vector#(n, a) sv, alpha idx)
  29.   provisos (Add#(4,k,n), Log#(n,logn),
  30.             Eq#(alpha), Literal#(alpha), Arith#(alpha), Ord#(alpha),
  31.     PrimIndex#(alpha, beta)
  32.             );
  33.   Vector#(4,a) retval = newVector();  
  34.   
  35.   for(alpha i = 0; i < 4; i = i + 1)
  36.      retval[i] = sv[idx+i];
  37.   return retval;
  38. endfunction
  39. // The Radix function. Note that it is noinlined, because 
  40. // there's no point in doing a per-instance optimizations
  41. (* noinline *)
  42. function Radix4Data radix4(OmegaData omegas,
  43.                            Radix4Data xs);
  44.    Radix4Data retval = newVector();
  45.    ComplexF#(16) alpha = xs[0];
  46.    ComplexF#(16) beta = omegas[0] * xs[1];
  47.    ComplexF#(16) gamma = omegas[1] * xs[2];
  48.    ComplexF#(16) delta = omegas[2] * xs[3];
  49.    ComplexF#(16) tao_0 = alpha + gamma;
  50.    ComplexF#(16) tao_1 = alpha - gamma;
  51.    ComplexF#(16) tao_2 = beta + delta;
  52.    ComplexF#(16) tao_3 = beta - delta;
  53.    // rotate tao_3 by 90 degrees
  54.    ComplexF#(16) tao_3_rot90;
  55.    tao_3_rot90.i = -tao_3.q;
  56.    tao_3_rot90.q = tao_3.i;
  57.    retval[0] = tao_0 + tao_2;
  58.    retval[1] = tao_1 - tao_3_rot90;
  59.    retval[2] = tao_0 - tao_2;
  60.    retval[3] = tao_1 + tao_3_rot90;
  61.    return retval;
  62. endfunction
  63. //This describes a permutation such that
  64. //If the ith value in this is j, then the
  65. //ith value of the output will be the jth
  66. // input value.
  67. // This permutation is used on the values directly into the IFFT
  68. function Vector#(64, Integer) reorder();
  69.    Vector#(64, Integer) retval = replicate(?);
  70.    retval[ 0] =  0;
  71.    retval[ 1] = 16;
  72.    retval[ 2] = 32;
  73.    retval[ 3] = 48;
  74.    retval[ 4] =  4;
  75.    retval[ 5] = 20;
  76.    retval[ 6] = 36;
  77.    retval[ 7] = 52;
  78.    retval[ 8] =  8;
  79.    retval[ 9] = 24;
  80.    retval[10] = 40;
  81.    retval[11] = 56;
  82.    retval[12] = 12;
  83.    retval[13] = 28;
  84.    retval[14] = 44;
  85.    retval[15] = 60;
  86.    
  87.    retval[16] =  1;
  88.    retval[17] = 17;
  89.    retval[18] = 33;
  90.    retval[19] = 49;
  91.    retval[20] =  5;
  92.    retval[21] = 21;
  93.    retval[22] = 37;
  94.    retval[23] = 53;
  95.    retval[24] =  9;
  96.    retval[25] = 25;
  97.    retval[26] = 41;
  98.    retval[27] = 57;
  99.    retval[28] = 13;
  100.    retval[29] = 29;
  101.    retval[30] = 45;
  102.    retval[31] = 61;
  103.    
  104.    retval[32] =  2;
  105.    retval[33] = 18;
  106.    retval[34] = 34;
  107.    retval[35] = 50;
  108.    retval[36] =  6;
  109.    retval[37] = 22;
  110.    retval[38] = 38;
  111.    retval[39] = 54;
  112.    retval[40] = 10;
  113.    retval[41] = 26;
  114.    retval[42] = 42;
  115.    retval[43] = 58;
  116.    retval[44] = 14;
  117.    retval[45] = 30;
  118.    retval[46] = 46;
  119.    retval[47] = 62;
  120.    
  121.    retval[48] =  3;
  122.    retval[49] = 19;
  123.    retval[50] = 35;
  124.    retval[51] = 51;
  125.    retval[52] =  7;
  126.    retval[53] = 23;
  127.    retval[54] = 39;
  128.    retval[55] = 55;
  129.    retval[56] = 11;
  130.    retval[57] = 27;
  131.    retval[58] = 43;
  132.    retval[59] = 59;
  133.    retval[60] = 15;
  134.    retval[61] = 31;
  135.    retval[62] = 47;
  136.    retval[63] = 63;
  137.    return retval;
  138. endfunction
  139. // Similiar to the reorder ipermuation. However, this is used after each set of 16 radices
  140. function Vector#(64, Integer) permute();
  141.    Vector#(64, Integer) retval = replicate(?);
  142.   
  143.    retval[ 0] =  0;
  144.    retval[ 1] =  4;
  145.    retval[ 2] =  8;
  146.    retval[ 3] = 12;
  147.    retval[ 4] = 16;
  148.    retval[ 5] = 20;
  149.    retval[ 6] = 24;
  150.    retval[ 7] = 28;
  151.    retval[ 8] = 32;
  152.    retval[ 9] = 36;
  153.    retval[10] = 40;
  154.    retval[11] = 44;
  155.    retval[12] = 48;
  156.    retval[13] = 52;
  157.    retval[14] = 56;
  158.    retval[15] = 60;
  159.    
  160.    retval[16] =  1;
  161.    retval[17] =  5;
  162.    retval[18] =  9;
  163.    retval[19] = 13;
  164.    retval[20] = 17;
  165.    retval[21] = 21;
  166.    retval[22] = 25;
  167.    retval[23] = 29;
  168.    retval[24] = 33;
  169.    retval[25] = 37;
  170.    retval[26] = 41;
  171.    retval[27] = 45;
  172.    retval[28] = 49;
  173.    retval[29] = 53;
  174.    retval[30] = 57;
  175.    retval[31] = 61;
  176.    
  177.    retval[32] =  2;
  178.    retval[33] =  6;
  179.    retval[34] = 10;
  180.    retval[35] = 14;
  181.    retval[36] = 18;
  182.    retval[37] = 22;
  183.    retval[38] = 26;
  184.    retval[39] = 30;
  185.    retval[40] = 34;
  186.    retval[41] = 38;
  187.    retval[42] = 42;
  188.    retval[43] = 46;
  189.    retval[44] = 50;
  190.    retval[45] = 54;
  191.    retval[46] = 58;
  192.    retval[47] = 62;
  193.    
  194.    retval[48] =  3;
  195.    retval[49] =  7;
  196.    retval[50] = 11;
  197.    retval[51] = 15;
  198.    retval[52] = 19;
  199.    retval[53] = 23;
  200.    retval[54] = 27;
  201.    retval[55] = 31;
  202.    retval[56] = 35;
  203.    retval[57] = 39;
  204.    retval[58] = 43;
  205.    retval[59] = 47;
  206.    retval[60] = 51;
  207.    retval[61] = 55;
  208.    retval[62] = 59;
  209.    retval[63] = 63;
  210.    return retval;
  211. endfunction
  212. // Calculate the correct omegas. This gets sent into the
  213. // radix4 block
  214. function Vector#(3, ComplexF#(16)) omega(Bit#(2) stage, Bit#(4) index);
  215.   Vector#(3, ComplexF#(16)) retval = replicate(?);
  216.   case(stage)
  217.    // stage 1
  218.    0:
  219.     begin
  220.       retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
  221.       retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
  222.       retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
  223.     end
  224.    // stage 2
  225.    1:
  226.     case(index >> 2)
  227.       0: begin
  228.            retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
  229.            retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
  230.            retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
  231.          end
  232.       1: begin
  233.            retval[0].i = 16'h7640;   retval[0].q = 16'hcf05;
  234.            retval[1].i = 16'h5a81;   retval[1].q = 16'ha57f;
  235.            retval[2].i = 16'h30fb;   retval[2].q = 16'h89c0;
  236.          end
  237.       2: begin
  238.            retval[0].i = 16'h5a81;   retval[0].q = 16'ha57f;
  239.            retval[1].i = 16'h0000;   retval[1].q = 16'h8000;
  240.            retval[2].i = 16'ha57f;   retval[2].q = 16'ha57f;
  241.          end
  242.       3: begin
  243.            retval[0].i = 16'h30fb;   retval[0].q = 16'h89c0;
  244.            retval[1].i = 16'ha57f;   retval[1].q = 16'ha57f;
  245.            retval[2].i = 16'h89c0;   retval[2].q = 16'h30fb;
  246.          end
  247.     endcase
  248.    // stage 3
  249.    2:
  250.     case(index)
  251.       0: begin
  252.            retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
  253.            retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
  254.            retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
  255.          end
  256.       1: begin
  257.            retval[0].i = 16'h7f61;   retval[0].q = 16'hf375;
  258.            retval[1].i = 16'h7d89;   retval[1].q = 16'he708;
  259.            retval[2].i = 16'h7a7c;   retval[2].q = 16'hdad9;
  260.          end
  261.       2: begin
  262.            retval[0].i = 16'h7d89;   retval[0].q = 16'he708;
  263.            retval[1].i = 16'h7640;   retval[1].q = 16'hcf05;
  264.            retval[2].i = 16'h6a6c;   retval[2].q = 16'hb8e4;
  265.          end
  266.       3: begin
  267.            retval[0].i = 16'h7a7c;   retval[0].q = 16'hdad9;
  268.            retval[1].i = 16'h6a6c;   retval[1].q = 16'hb8e4;
  269.            retval[2].i = 16'h5133;   retval[2].q = 16'h9d0f;
  270.          end
  271.       4: begin
  272.            retval[0].i = 16'h7640;   retval[0].q = 16'hcf05;
  273.            retval[1].i = 16'h5a81;   retval[1].q = 16'ha57f;
  274.            retval[2].i = 16'h30fb;   retval[2].q = 16'h89c0;
  275.          end
  276.       5: begin
  277.            retval[0].i = 16'h70e1;   retval[0].q = 16'hc3aa;
  278.            retval[1].i = 16'h471c;   retval[1].q = 16'h9594;
  279.            retval[2].i = 16'h0c8b;   retval[2].q = 16'h809f;
  280.          end
  281.       6: begin
  282.            retval[0].i = 16'h6a6c;   retval[0].q = 16'hb8e4;
  283.            retval[1].i = 16'h30fb;   retval[1].q = 16'h89c0;
  284.            retval[2].i = 16'he708;   retval[2].q = 16'h8277;
  285.          end
  286.       7: begin
  287.            retval[0].i = 16'h62f1;   retval[0].q = 16'haecd;
  288.            retval[1].i = 16'h18f8;   retval[1].q = 16'h8277;
  289.            retval[2].i = 16'hc3aa;   retval[2].q = 16'h8f1f;
  290.          end
  291.       8: begin
  292.            retval[0].i = 16'h5a81;   retval[0].q = 16'ha57f;
  293.            retval[1].i = 16'h0000;   retval[1].q = 16'h8000;
  294.            retval[2].i = 16'ha57f;   retval[2].q = 16'ha57f;
  295.          end
  296.       9: begin
  297.            retval[0].i = 16'h5133;   retval[0].q = 16'h9d0f;
  298.            retval[1].i = 16'he708;   retval[1].q = 16'h8277;
  299.            retval[2].i = 16'h8f1f;   retval[2].q = 16'hc3aa;
  300.         end
  301.       10: begin
  302.             retval[0].i = 16'h471c;   retval[0].q = 16'h9594;
  303.             retval[1].i = 16'hcf05;   retval[1].q = 16'h89c0;
  304.             retval[2].i = 16'h8277;   retval[2].q = 16'he708;
  305.           end
  306.       11: begin
  307.             retval[0].i = 16'h3c56;   retval[0].q = 16'h8f1f;
  308.             retval[1].i = 16'hb8e4;   retval[1].q = 16'h9594;
  309.             retval[2].i = 16'h809f;   retval[2].q = 16'h0c8b;
  310.           end
  311.       12: begin
  312.             retval[0].i = 16'h30fb;   retval[0].q = 16'h89c0;
  313.             retval[1].i = 16'ha57f;   retval[1].q = 16'ha57f;
  314.             retval[2].i = 16'h89c0;   retval[2].q = 16'h30fb;
  315.           end
  316.       13: begin
  317.             retval[0].i = 16'h2527;   retval[0].q = 16'h8584;
  318.             retval[1].i = 16'h9594;   retval[1].q = 16'hb8e4;
  319.             retval[2].i = 16'h9d0f;   retval[2].q = 16'h5133;
  320.           end
  321.       14: begin
  322.             retval[0].i = 16'h18f8;   retval[0].q = 16'h8277;
  323.             retval[1].i = 16'h89c0;   retval[1].q = 16'hcf05;
  324.             retval[2].i = 16'hb8e4;   retval[2].q = 16'h6a6c;
  325.           end
  326.       15: begin
  327.             retval[0].i = 16'h0c8b;   retval[0].q = 16'h809f;
  328.             retval[1].i = 16'h8277;   retval[1].q = 16'he708;
  329.             retval[2].i = 16'hdad9;   retval[2].q = 16'h7a7c;
  330.           end
  331.     endcase
  332.   endcase
  333.    
  334.   return retval;
  335. endfunction
  336. // This is the stage function which does the IFFT in 3 stages
  337. (* noinline *)
  338. function IFFTData stagefunction(Bit#(2) stage, IFFTData s_in);
  339.   
  340.    IFFTData s_mid = newVector();
  341.    for(Integer i = 0; i < 16; i = i + 1)
  342.      begin
  343.        Nat four_i = fromInteger(4*i);
  344.        Radix4Data temp = radix4(omega(stage, fromInteger(i)),
  345.                                 take4(s_in, four_i));
  346.        for(Integer j = 0; j < 4; j = j + 1)
  347.          s_mid[4*i+j]  = temp[j];
  348.      end
  349.      // permute
  350.      IFFTData s_out = newVector();
  351.      for(Integer i = 0; i < 64; i = i + 1)
  352.        s_out[i] = s_mid[permute[i]];
  353.    
  354.   return (s_out);
  355. endfunction
  356. //These two functions are little hacks which prevent the compiler
  357. //from optimizing past these function boundaries.
  358. (* noinline *)
  359. function IFFTData stopOpt64(IFFTData s_in);
  360.   return s_in;
  361. endfunction  
  362.  
  363. function Vector#(4, ComplexF#(16)) stopOpt4(Vector#(4, ComplexF#(16)) s_in);
  364.   return s_in;
  365. endfunction  
  366. // This is a stage function which does the IFFT in 48 stages, doing 
  367. // 1 radix4 each stage and permuting the values every 16 cycles.
  368. (* noinline *)
  369. function IFFTData stagefunction2(Bit#(6) stage, IFFTData s_in);
  370.   
  371.    IFFTData s_mid = stopOpt64(s_in);
  372.    Bit#(4) step  = stage[3:0]; 
  373.    Bit#(6) step4 = {step,2'b00};  
  374.   
  375.    Radix4Data temp = radix4(omega(stage[5:4],step),
  376.                             take4(s_in, step4));
  377.    for(Bit#(6) j = 0; j < 4; j = j + 1)
  378.       s_mid = update(s_mid, step4+j,temp[j]);
  379.    // permute
  380.    IFFTData s_mid2 = stopOpt64(s_mid);
  381.    IFFTData s_out  = newVector();
  382.   
  383.    for(Integer i = 0; i < 64; i = i + 1)
  384.      s_out[i] = s_mid2[permute[i]];
  385.    
  386.   return ((step == 15) ? s_out : s_mid2);
  387. endfunction