OpenCores
URL https://opencores.org/ocsvn/bluespec-80211atransmitter/bluespec-80211atransmitter/trunk

Subversion Repositories bluespec-80211atransmitter

[/] [bluespec-80211atransmitter/] [trunk/] [IFFT_Library.bsv] - Diff between revs 2 and 3

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 3
?rev1line?
?rev2line?
 
// The MIT License
 
//
 
// Copyright (c) 2006 Nirav Dave (ndave@csail.mit.edu)
 
//
 
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
// of this software and associated documentation files (the "Software"), to deal
 
// in the Software without restriction, including without limitation the rights
 
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
// copies of the Software, and to permit persons to whom the Software is
 
// furnished to do so, subject to the following conditions:
 
//
 
// The above copyright notice and this permission notice shall be included in
 
// all copies or substantial portions of the Software.
 
//
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
// THE SOFTWARE.
 
 
 
 
 
 
 
 
 
import ComplexF::*;
 
import DataTypes::*;
 
 
 
import LibraryFunctions::*;
 
import Vector::*;
 
 
 
 
 
//This function just serves as a short hand for grabbing 4 consecutive indices in
 
//a vector
 
function Vector#(4, a) take4(Vector#(n, a) sv, alpha idx)
 
  provisos (Add#(4,k,n), Log#(n,logn),
 
            Eq#(alpha), Literal#(alpha), Arith#(alpha), Ord#(alpha),
 
            PrimIndex#(alpha, beta)
 
            );
 
  Vector#(4,a) retval = newVector();
 
 
 
  for(alpha i = 0; i < 4; i = i + 1)
 
     retval[i] = sv[idx+i];
 
  return retval;
 
endfunction
 
 
 
 
 
// The Radix function. Note that it is noinlined, because
 
// there's no point in doing a per-instance optimizations
 
(* noinline *)
 
function Radix4Data radix4(OmegaData omegas,
 
                           Radix4Data xs);
 
 
 
   Radix4Data retval = newVector();
 
 
 
   ComplexF#(16) alpha = xs[0];
 
   ComplexF#(16) beta = omegas[0] * xs[1];
 
   ComplexF#(16) gamma = omegas[1] * xs[2];
 
   ComplexF#(16) delta = omegas[2] * xs[3];
 
 
 
   ComplexF#(16) tao_0 = alpha + gamma;
 
   ComplexF#(16) tao_1 = alpha - gamma;
 
   ComplexF#(16) tao_2 = beta + delta;
 
   ComplexF#(16) tao_3 = beta - delta;
 
 
 
   // rotate tao_3 by 90 degrees
 
   ComplexF#(16) tao_3_rot90;
 
   tao_3_rot90.i = -tao_3.q;
 
   tao_3_rot90.q = tao_3.i;
 
 
 
   retval[0] = tao_0 + tao_2;
 
   retval[1] = tao_1 - tao_3_rot90;
 
   retval[2] = tao_0 - tao_2;
 
   retval[3] = tao_1 + tao_3_rot90;
 
 
 
   return retval;
 
endfunction
 
 
 
 
 
 
 
//This describes a permutation such that
 
//If the ith value in this is j, then the
 
//ith value of the output will be the jth
 
// input value.
 
 
 
// This permutation is used on the values directly into the IFFT
 
 
 
function Vector#(64, Integer) reorder();
 
   Vector#(64, Integer) retval = replicate(?);
 
 
 
   retval[ 0] =  0;
 
   retval[ 1] = 16;
 
   retval[ 2] = 32;
 
   retval[ 3] = 48;
 
   retval[ 4] =  4;
 
   retval[ 5] = 20;
 
   retval[ 6] = 36;
 
   retval[ 7] = 52;
 
   retval[ 8] =  8;
 
   retval[ 9] = 24;
 
   retval[10] = 40;
 
   retval[11] = 56;
 
   retval[12] = 12;
 
   retval[13] = 28;
 
   retval[14] = 44;
 
   retval[15] = 60;
 
 
 
   retval[16] =  1;
 
   retval[17] = 17;
 
   retval[18] = 33;
 
   retval[19] = 49;
 
   retval[20] =  5;
 
   retval[21] = 21;
 
   retval[22] = 37;
 
   retval[23] = 53;
 
   retval[24] =  9;
 
   retval[25] = 25;
 
   retval[26] = 41;
 
   retval[27] = 57;
 
   retval[28] = 13;
 
   retval[29] = 29;
 
   retval[30] = 45;
 
   retval[31] = 61;
 
 
 
   retval[32] =  2;
 
   retval[33] = 18;
 
   retval[34] = 34;
 
   retval[35] = 50;
 
   retval[36] =  6;
 
   retval[37] = 22;
 
   retval[38] = 38;
 
   retval[39] = 54;
 
   retval[40] = 10;
 
   retval[41] = 26;
 
   retval[42] = 42;
 
   retval[43] = 58;
 
   retval[44] = 14;
 
   retval[45] = 30;
 
   retval[46] = 46;
 
   retval[47] = 62;
 
 
 
   retval[48] =  3;
 
   retval[49] = 19;
 
   retval[50] = 35;
 
   retval[51] = 51;
 
   retval[52] =  7;
 
   retval[53] = 23;
 
   retval[54] = 39;
 
   retval[55] = 55;
 
   retval[56] = 11;
 
   retval[57] = 27;
 
   retval[58] = 43;
 
   retval[59] = 59;
 
   retval[60] = 15;
 
   retval[61] = 31;
 
   retval[62] = 47;
 
   retval[63] = 63;
 
 
 
   return retval;
 
endfunction
 
 
 
// Similiar to the reorder ipermuation. However, this is used after each set of 16 radices
 
function Vector#(64, Integer) permute();
 
   Vector#(64, Integer) retval = replicate(?);
 
 
 
   retval[ 0] =  0;
 
   retval[ 1] =  4;
 
   retval[ 2] =  8;
 
   retval[ 3] = 12;
 
   retval[ 4] = 16;
 
   retval[ 5] = 20;
 
   retval[ 6] = 24;
 
   retval[ 7] = 28;
 
   retval[ 8] = 32;
 
   retval[ 9] = 36;
 
   retval[10] = 40;
 
   retval[11] = 44;
 
   retval[12] = 48;
 
   retval[13] = 52;
 
   retval[14] = 56;
 
   retval[15] = 60;
 
 
 
   retval[16] =  1;
 
   retval[17] =  5;
 
   retval[18] =  9;
 
   retval[19] = 13;
 
   retval[20] = 17;
 
   retval[21] = 21;
 
   retval[22] = 25;
 
   retval[23] = 29;
 
   retval[24] = 33;
 
   retval[25] = 37;
 
   retval[26] = 41;
 
   retval[27] = 45;
 
   retval[28] = 49;
 
   retval[29] = 53;
 
   retval[30] = 57;
 
   retval[31] = 61;
 
 
 
   retval[32] =  2;
 
   retval[33] =  6;
 
   retval[34] = 10;
 
   retval[35] = 14;
 
   retval[36] = 18;
 
   retval[37] = 22;
 
   retval[38] = 26;
 
   retval[39] = 30;
 
   retval[40] = 34;
 
   retval[41] = 38;
 
   retval[42] = 42;
 
   retval[43] = 46;
 
   retval[44] = 50;
 
   retval[45] = 54;
 
   retval[46] = 58;
 
   retval[47] = 62;
 
 
 
   retval[48] =  3;
 
   retval[49] =  7;
 
   retval[50] = 11;
 
   retval[51] = 15;
 
   retval[52] = 19;
 
   retval[53] = 23;
 
   retval[54] = 27;
 
   retval[55] = 31;
 
   retval[56] = 35;
 
   retval[57] = 39;
 
   retval[58] = 43;
 
   retval[59] = 47;
 
   retval[60] = 51;
 
   retval[61] = 55;
 
   retval[62] = 59;
 
   retval[63] = 63;
 
 
 
   return retval;
 
endfunction
 
 
 
// Calculate the correct omegas. This gets sent into the
 
// radix4 block
 
function Vector#(3, ComplexF#(16)) omega(Bit#(2) stage, Bit#(4) index);
 
 
 
  Vector#(3, ComplexF#(16)) retval = replicate(?);
 
 
 
  case(stage)
 
   // stage 1
 
   0:
 
    begin
 
      retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
 
      retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
 
      retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
 
    end
 
   // stage 2
 
   1:
 
    case(index >> 2)
 
      0: begin
 
           retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
 
           retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
 
           retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
 
         end
 
      1: begin
 
           retval[0].i = 16'h7640;   retval[0].q = 16'hcf05;
 
           retval[1].i = 16'h5a81;   retval[1].q = 16'ha57f;
 
           retval[2].i = 16'h30fb;   retval[2].q = 16'h89c0;
 
         end
 
      2: begin
 
           retval[0].i = 16'h5a81;   retval[0].q = 16'ha57f;
 
           retval[1].i = 16'h0000;   retval[1].q = 16'h8000;
 
           retval[2].i = 16'ha57f;   retval[2].q = 16'ha57f;
 
         end
 
      3: begin
 
           retval[0].i = 16'h30fb;   retval[0].q = 16'h89c0;
 
           retval[1].i = 16'ha57f;   retval[1].q = 16'ha57f;
 
           retval[2].i = 16'h89c0;   retval[2].q = 16'h30fb;
 
         end
 
    endcase
 
   // stage 3
 
   2:
 
    case(index)
 
      0: begin
 
           retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
 
           retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
 
           retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
 
         end
 
      1: begin
 
           retval[0].i = 16'h7f61;   retval[0].q = 16'hf375;
 
           retval[1].i = 16'h7d89;   retval[1].q = 16'he708;
 
           retval[2].i = 16'h7a7c;   retval[2].q = 16'hdad9;
 
         end
 
      2: begin
 
           retval[0].i = 16'h7d89;   retval[0].q = 16'he708;
 
           retval[1].i = 16'h7640;   retval[1].q = 16'hcf05;
 
           retval[2].i = 16'h6a6c;   retval[2].q = 16'hb8e4;
 
         end
 
      3: begin
 
           retval[0].i = 16'h7a7c;   retval[0].q = 16'hdad9;
 
           retval[1].i = 16'h6a6c;   retval[1].q = 16'hb8e4;
 
           retval[2].i = 16'h5133;   retval[2].q = 16'h9d0f;
 
         end
 
      4: begin
 
           retval[0].i = 16'h7640;   retval[0].q = 16'hcf05;
 
           retval[1].i = 16'h5a81;   retval[1].q = 16'ha57f;
 
           retval[2].i = 16'h30fb;   retval[2].q = 16'h89c0;
 
         end
 
      5: begin
 
           retval[0].i = 16'h70e1;   retval[0].q = 16'hc3aa;
 
           retval[1].i = 16'h471c;   retval[1].q = 16'h9594;
 
           retval[2].i = 16'h0c8b;   retval[2].q = 16'h809f;
 
         end
 
      6: begin
 
           retval[0].i = 16'h6a6c;   retval[0].q = 16'hb8e4;
 
           retval[1].i = 16'h30fb;   retval[1].q = 16'h89c0;
 
           retval[2].i = 16'he708;   retval[2].q = 16'h8277;
 
         end
 
      7: begin
 
           retval[0].i = 16'h62f1;   retval[0].q = 16'haecd;
 
           retval[1].i = 16'h18f8;   retval[1].q = 16'h8277;
 
           retval[2].i = 16'hc3aa;   retval[2].q = 16'h8f1f;
 
         end
 
      8: begin
 
           retval[0].i = 16'h5a81;   retval[0].q = 16'ha57f;
 
           retval[1].i = 16'h0000;   retval[1].q = 16'h8000;
 
           retval[2].i = 16'ha57f;   retval[2].q = 16'ha57f;
 
         end
 
      9: begin
 
           retval[0].i = 16'h5133;   retval[0].q = 16'h9d0f;
 
           retval[1].i = 16'he708;   retval[1].q = 16'h8277;
 
           retval[2].i = 16'h8f1f;   retval[2].q = 16'hc3aa;
 
        end
 
      10: begin
 
            retval[0].i = 16'h471c;   retval[0].q = 16'h9594;
 
            retval[1].i = 16'hcf05;   retval[1].q = 16'h89c0;
 
            retval[2].i = 16'h8277;   retval[2].q = 16'he708;
 
          end
 
      11: begin
 
            retval[0].i = 16'h3c56;   retval[0].q = 16'h8f1f;
 
            retval[1].i = 16'hb8e4;   retval[1].q = 16'h9594;
 
            retval[2].i = 16'h809f;   retval[2].q = 16'h0c8b;
 
          end
 
      12: begin
 
            retval[0].i = 16'h30fb;   retval[0].q = 16'h89c0;
 
            retval[1].i = 16'ha57f;   retval[1].q = 16'ha57f;
 
            retval[2].i = 16'h89c0;   retval[2].q = 16'h30fb;
 
          end
 
      13: begin
 
            retval[0].i = 16'h2527;   retval[0].q = 16'h8584;
 
            retval[1].i = 16'h9594;   retval[1].q = 16'hb8e4;
 
            retval[2].i = 16'h9d0f;   retval[2].q = 16'h5133;
 
          end
 
      14: begin
 
            retval[0].i = 16'h18f8;   retval[0].q = 16'h8277;
 
            retval[1].i = 16'h89c0;   retval[1].q = 16'hcf05;
 
            retval[2].i = 16'hb8e4;   retval[2].q = 16'h6a6c;
 
          end
 
      15: begin
 
            retval[0].i = 16'h0c8b;   retval[0].q = 16'h809f;
 
            retval[1].i = 16'h8277;   retval[1].q = 16'he708;
 
            retval[2].i = 16'hdad9;   retval[2].q = 16'h7a7c;
 
          end
 
    endcase
 
  endcase
 
 
 
  return retval;
 
endfunction
 
 
 
 
 
// This is the stage function which does the IFFT in 3 stages
 
(* noinline *)
 
function IFFTData stagefunction(Bit#(2) stage, IFFTData s_in);
 
 
 
   IFFTData s_mid = newVector();
 
   for(Integer i = 0; i < 16; i = i + 1)
 
     begin
 
       Nat four_i = fromInteger(4*i);
 
       Radix4Data temp = radix4(omega(stage, fromInteger(i)),
 
                                take4(s_in, four_i));
 
       for(Integer j = 0; j < 4; j = j + 1)
 
         s_mid[4*i+j]  = temp[j];
 
     end
 
 
 
     // permute
 
     IFFTData s_out = newVector();
 
     for(Integer i = 0; i < 64; i = i + 1)
 
       s_out[i] = s_mid[permute[i]];
 
 
 
  return (s_out);
 
 
 
endfunction
 
 
 
//These two functions are little hacks which prevent the compiler
 
//from optimizing past these function boundaries.
 
(* noinline *)
 
function IFFTData stopOpt64(IFFTData s_in);
 
  return s_in;
 
endfunction
 
 
 
function Vector#(4, ComplexF#(16)) stopOpt4(Vector#(4, ComplexF#(16)) s_in);
 
  return s_in;
 
endfunction
 
 
 
// This is a stage function which does the IFFT in 48 stages, doing
 
// 1 radix4 each stage and permuting the values every 16 cycles.
 
 
 
(* noinline *)
 
function IFFTData stagefunction2(Bit#(6) stage, IFFTData s_in);
 
 
 
   IFFTData s_mid = stopOpt64(s_in);
 
   Bit#(4) step  = stage[3:0];
 
   Bit#(6) step4 = {step,2'b00};
 
 
 
   Radix4Data temp = radix4(omega(stage[5:4],step),
 
                            take4(s_in, step4));
 
 
 
   for(Bit#(6) j = 0; j < 4; j = j + 1)
 
      s_mid = update(s_mid, step4+j,temp[j]);
 
 
 
   // permute
 
   IFFTData s_mid2 = stopOpt64(s_mid);
 
   IFFTData s_out  = newVector();
 
 
 
   for(Integer i = 0; i < 64; i = i + 1)
 
     s_out[i] = s_mid2[permute[i]];
 
 
 
  return ((step == 15) ? s_out : s_mid2);
 
 
 
endfunction

powered by: WebSVN 2.1.0

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