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

Subversion Repositories bluespec-80211atransmitter

[/] [bluespec-80211atransmitter/] [trunk/] [IFFT_Library.bsv] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ndave
// 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
 
23
 
24
 
25
 
26
import ComplexF::*;
27
import DataTypes::*;
28
 
29
import LibraryFunctions::*;
30
import Vector::*;
31
 
32
 
33
//This function just serves as a short hand for grabbing 4 consecutive indices in
34
//a vector
35
function Vector#(4, a) take4(Vector#(n, a) sv, alpha idx)
36
  provisos (Add#(4,k,n), Log#(n,logn),
37
            Eq#(alpha), Literal#(alpha), Arith#(alpha), Ord#(alpha),
38
            PrimIndex#(alpha, beta)
39
            );
40
  Vector#(4,a) retval = newVector();
41
 
42
  for(alpha i = 0; i < 4; i = i + 1)
43
     retval[i] = sv[idx+i];
44
  return retval;
45
endfunction
46
 
47
 
48
// The Radix function. Note that it is noinlined, because
49
// there's no point in doing a per-instance optimizations
50
(* noinline *)
51
function Radix4Data radix4(OmegaData omegas,
52
                           Radix4Data xs);
53
 
54
   Radix4Data retval = newVector();
55
 
56
   ComplexF#(16) alpha = xs[0];
57
   ComplexF#(16) beta = omegas[0] * xs[1];
58
   ComplexF#(16) gamma = omegas[1] * xs[2];
59
   ComplexF#(16) delta = omegas[2] * xs[3];
60
 
61
   ComplexF#(16) tao_0 = alpha + gamma;
62
   ComplexF#(16) tao_1 = alpha - gamma;
63
   ComplexF#(16) tao_2 = beta + delta;
64
   ComplexF#(16) tao_3 = beta - delta;
65
 
66
   // rotate tao_3 by 90 degrees
67
   ComplexF#(16) tao_3_rot90;
68
   tao_3_rot90.i = -tao_3.q;
69
   tao_3_rot90.q = tao_3.i;
70
 
71
   retval[0] = tao_0 + tao_2;
72
   retval[1] = tao_1 - tao_3_rot90;
73
   retval[2] = tao_0 - tao_2;
74
   retval[3] = tao_1 + tao_3_rot90;
75
 
76
   return retval;
77
endfunction
78
 
79
 
80
 
81
//This describes a permutation such that
82
//If the ith value in this is j, then the
83
//ith value of the output will be the jth
84
// input value.
85
 
86
// This permutation is used on the values directly into the IFFT
87
 
88
function Vector#(64, Integer) reorder();
89
   Vector#(64, Integer) retval = replicate(?);
90
 
91
   retval[ 0] =  0;
92
   retval[ 1] = 16;
93
   retval[ 2] = 32;
94
   retval[ 3] = 48;
95
   retval[ 4] =  4;
96
   retval[ 5] = 20;
97
   retval[ 6] = 36;
98
   retval[ 7] = 52;
99
   retval[ 8] =  8;
100
   retval[ 9] = 24;
101
   retval[10] = 40;
102
   retval[11] = 56;
103
   retval[12] = 12;
104
   retval[13] = 28;
105
   retval[14] = 44;
106
   retval[15] = 60;
107
 
108
   retval[16] =  1;
109
   retval[17] = 17;
110
   retval[18] = 33;
111
   retval[19] = 49;
112
   retval[20] =  5;
113
   retval[21] = 21;
114
   retval[22] = 37;
115
   retval[23] = 53;
116
   retval[24] =  9;
117
   retval[25] = 25;
118
   retval[26] = 41;
119
   retval[27] = 57;
120
   retval[28] = 13;
121
   retval[29] = 29;
122
   retval[30] = 45;
123
   retval[31] = 61;
124
 
125
   retval[32] =  2;
126
   retval[33] = 18;
127
   retval[34] = 34;
128
   retval[35] = 50;
129
   retval[36] =  6;
130
   retval[37] = 22;
131
   retval[38] = 38;
132
   retval[39] = 54;
133
   retval[40] = 10;
134
   retval[41] = 26;
135
   retval[42] = 42;
136
   retval[43] = 58;
137
   retval[44] = 14;
138
   retval[45] = 30;
139
   retval[46] = 46;
140
   retval[47] = 62;
141
 
142
   retval[48] =  3;
143
   retval[49] = 19;
144
   retval[50] = 35;
145
   retval[51] = 51;
146
   retval[52] =  7;
147
   retval[53] = 23;
148
   retval[54] = 39;
149
   retval[55] = 55;
150
   retval[56] = 11;
151
   retval[57] = 27;
152
   retval[58] = 43;
153
   retval[59] = 59;
154
   retval[60] = 15;
155
   retval[61] = 31;
156
   retval[62] = 47;
157
   retval[63] = 63;
158
 
159
   return retval;
160
endfunction
161
 
162
// Similiar to the reorder ipermuation. However, this is used after each set of 16 radices
163
function Vector#(64, Integer) permute();
164
   Vector#(64, Integer) retval = replicate(?);
165
 
166
   retval[ 0] =  0;
167
   retval[ 1] =  4;
168
   retval[ 2] =  8;
169
   retval[ 3] = 12;
170
   retval[ 4] = 16;
171
   retval[ 5] = 20;
172
   retval[ 6] = 24;
173
   retval[ 7] = 28;
174
   retval[ 8] = 32;
175
   retval[ 9] = 36;
176
   retval[10] = 40;
177
   retval[11] = 44;
178
   retval[12] = 48;
179
   retval[13] = 52;
180
   retval[14] = 56;
181
   retval[15] = 60;
182
 
183
   retval[16] =  1;
184
   retval[17] =  5;
185
   retval[18] =  9;
186
   retval[19] = 13;
187
   retval[20] = 17;
188
   retval[21] = 21;
189
   retval[22] = 25;
190
   retval[23] = 29;
191
   retval[24] = 33;
192
   retval[25] = 37;
193
   retval[26] = 41;
194
   retval[27] = 45;
195
   retval[28] = 49;
196
   retval[29] = 53;
197
   retval[30] = 57;
198
   retval[31] = 61;
199
 
200
   retval[32] =  2;
201
   retval[33] =  6;
202
   retval[34] = 10;
203
   retval[35] = 14;
204
   retval[36] = 18;
205
   retval[37] = 22;
206
   retval[38] = 26;
207
   retval[39] = 30;
208
   retval[40] = 34;
209
   retval[41] = 38;
210
   retval[42] = 42;
211
   retval[43] = 46;
212
   retval[44] = 50;
213
   retval[45] = 54;
214
   retval[46] = 58;
215
   retval[47] = 62;
216
 
217
   retval[48] =  3;
218
   retval[49] =  7;
219
   retval[50] = 11;
220
   retval[51] = 15;
221
   retval[52] = 19;
222
   retval[53] = 23;
223
   retval[54] = 27;
224
   retval[55] = 31;
225
   retval[56] = 35;
226
   retval[57] = 39;
227
   retval[58] = 43;
228
   retval[59] = 47;
229
   retval[60] = 51;
230
   retval[61] = 55;
231
   retval[62] = 59;
232
   retval[63] = 63;
233
 
234
   return retval;
235
endfunction
236
 
237
// Calculate the correct omegas. This gets sent into the
238
// radix4 block
239
function Vector#(3, ComplexF#(16)) omega(Bit#(2) stage, Bit#(4) index);
240
 
241
  Vector#(3, ComplexF#(16)) retval = replicate(?);
242
 
243
  case(stage)
244
   // stage 1
245
   0:
246
    begin
247
      retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
248
      retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
249
      retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
250
    end
251
   // stage 2
252
   1:
253
    case(index >> 2)
254
      0: begin
255
           retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
256
           retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
257
           retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
258
         end
259
      1: begin
260
           retval[0].i = 16'h7640;   retval[0].q = 16'hcf05;
261
           retval[1].i = 16'h5a81;   retval[1].q = 16'ha57f;
262
           retval[2].i = 16'h30fb;   retval[2].q = 16'h89c0;
263
         end
264
      2: begin
265
           retval[0].i = 16'h5a81;   retval[0].q = 16'ha57f;
266
           retval[1].i = 16'h0000;   retval[1].q = 16'h8000;
267
           retval[2].i = 16'ha57f;   retval[2].q = 16'ha57f;
268
         end
269
      3: begin
270
           retval[0].i = 16'h30fb;   retval[0].q = 16'h89c0;
271
           retval[1].i = 16'ha57f;   retval[1].q = 16'ha57f;
272
           retval[2].i = 16'h89c0;   retval[2].q = 16'h30fb;
273
         end
274
    endcase
275
   // stage 3
276
   2:
277
    case(index)
278
      0: begin
279
           retval[0].i = 16'h7fff;   retval[0].q = 16'h0000;
280
           retval[1].i = 16'h7fff;   retval[1].q = 16'h0000;
281
           retval[2].i = 16'h7fff;   retval[2].q = 16'h0000;
282
         end
283
      1: begin
284
           retval[0].i = 16'h7f61;   retval[0].q = 16'hf375;
285
           retval[1].i = 16'h7d89;   retval[1].q = 16'he708;
286
           retval[2].i = 16'h7a7c;   retval[2].q = 16'hdad9;
287
         end
288
      2: begin
289
           retval[0].i = 16'h7d89;   retval[0].q = 16'he708;
290
           retval[1].i = 16'h7640;   retval[1].q = 16'hcf05;
291
           retval[2].i = 16'h6a6c;   retval[2].q = 16'hb8e4;
292
         end
293
      3: begin
294
           retval[0].i = 16'h7a7c;   retval[0].q = 16'hdad9;
295
           retval[1].i = 16'h6a6c;   retval[1].q = 16'hb8e4;
296
           retval[2].i = 16'h5133;   retval[2].q = 16'h9d0f;
297
         end
298
      4: begin
299
           retval[0].i = 16'h7640;   retval[0].q = 16'hcf05;
300
           retval[1].i = 16'h5a81;   retval[1].q = 16'ha57f;
301
           retval[2].i = 16'h30fb;   retval[2].q = 16'h89c0;
302
         end
303
      5: begin
304
           retval[0].i = 16'h70e1;   retval[0].q = 16'hc3aa;
305
           retval[1].i = 16'h471c;   retval[1].q = 16'h9594;
306
           retval[2].i = 16'h0c8b;   retval[2].q = 16'h809f;
307
         end
308
      6: begin
309
           retval[0].i = 16'h6a6c;   retval[0].q = 16'hb8e4;
310
           retval[1].i = 16'h30fb;   retval[1].q = 16'h89c0;
311
           retval[2].i = 16'he708;   retval[2].q = 16'h8277;
312
         end
313
      7: begin
314
           retval[0].i = 16'h62f1;   retval[0].q = 16'haecd;
315
           retval[1].i = 16'h18f8;   retval[1].q = 16'h8277;
316
           retval[2].i = 16'hc3aa;   retval[2].q = 16'h8f1f;
317
         end
318
      8: begin
319
           retval[0].i = 16'h5a81;   retval[0].q = 16'ha57f;
320
           retval[1].i = 16'h0000;   retval[1].q = 16'h8000;
321
           retval[2].i = 16'ha57f;   retval[2].q = 16'ha57f;
322
         end
323
      9: begin
324
           retval[0].i = 16'h5133;   retval[0].q = 16'h9d0f;
325
           retval[1].i = 16'he708;   retval[1].q = 16'h8277;
326
           retval[2].i = 16'h8f1f;   retval[2].q = 16'hc3aa;
327
        end
328
      10: begin
329
            retval[0].i = 16'h471c;   retval[0].q = 16'h9594;
330
            retval[1].i = 16'hcf05;   retval[1].q = 16'h89c0;
331
            retval[2].i = 16'h8277;   retval[2].q = 16'he708;
332
          end
333
      11: begin
334
            retval[0].i = 16'h3c56;   retval[0].q = 16'h8f1f;
335
            retval[1].i = 16'hb8e4;   retval[1].q = 16'h9594;
336
            retval[2].i = 16'h809f;   retval[2].q = 16'h0c8b;
337
          end
338
      12: begin
339
            retval[0].i = 16'h30fb;   retval[0].q = 16'h89c0;
340
            retval[1].i = 16'ha57f;   retval[1].q = 16'ha57f;
341
            retval[2].i = 16'h89c0;   retval[2].q = 16'h30fb;
342
          end
343
      13: begin
344
            retval[0].i = 16'h2527;   retval[0].q = 16'h8584;
345
            retval[1].i = 16'h9594;   retval[1].q = 16'hb8e4;
346
            retval[2].i = 16'h9d0f;   retval[2].q = 16'h5133;
347
          end
348
      14: begin
349
            retval[0].i = 16'h18f8;   retval[0].q = 16'h8277;
350
            retval[1].i = 16'h89c0;   retval[1].q = 16'hcf05;
351
            retval[2].i = 16'hb8e4;   retval[2].q = 16'h6a6c;
352
          end
353
      15: begin
354
            retval[0].i = 16'h0c8b;   retval[0].q = 16'h809f;
355
            retval[1].i = 16'h8277;   retval[1].q = 16'he708;
356
            retval[2].i = 16'hdad9;   retval[2].q = 16'h7a7c;
357
          end
358
    endcase
359
  endcase
360
 
361
  return retval;
362
endfunction
363
 
364
 
365
// This is the stage function which does the IFFT in 3 stages
366
(* noinline *)
367
function IFFTData stagefunction(Bit#(2) stage, IFFTData s_in);
368
 
369
   IFFTData s_mid = newVector();
370
   for(Integer i = 0; i < 16; i = i + 1)
371
     begin
372
       Nat four_i = fromInteger(4*i);
373
       Radix4Data temp = radix4(omega(stage, fromInteger(i)),
374
                                take4(s_in, four_i));
375
       for(Integer j = 0; j < 4; j = j + 1)
376
         s_mid[4*i+j]  = temp[j];
377
     end
378
 
379
     // permute
380
     IFFTData s_out = newVector();
381
     for(Integer i = 0; i < 64; i = i + 1)
382
       s_out[i] = s_mid[permute[i]];
383
 
384
  return (s_out);
385
 
386
endfunction
387
 
388
//These two functions are little hacks which prevent the compiler
389
//from optimizing past these function boundaries.
390
(* noinline *)
391
function IFFTData stopOpt64(IFFTData s_in);
392
  return s_in;
393
endfunction
394
 
395
function Vector#(4, ComplexF#(16)) stopOpt4(Vector#(4, ComplexF#(16)) s_in);
396
  return s_in;
397
endfunction
398
 
399
// This is a stage function which does the IFFT in 48 stages, doing
400
// 1 radix4 each stage and permuting the values every 16 cycles.
401
 
402
(* noinline *)
403
function IFFTData stagefunction2(Bit#(6) stage, IFFTData s_in);
404
 
405
   IFFTData s_mid = stopOpt64(s_in);
406
   Bit#(4) step  = stage[3:0];
407
   Bit#(6) step4 = {step,2'b00};
408
 
409
   Radix4Data temp = radix4(omega(stage[5:4],step),
410
                            take4(s_in, step4));
411
 
412
   for(Bit#(6) j = 0; j < 4; j = j + 1)
413
      s_mid = update(s_mid, step4+j,temp[j]);
414
 
415
   // permute
416
   IFFTData s_mid2 = stopOpt64(s_mid);
417
   IFFTData s_out  = newVector();
418
 
419
   for(Integer i = 0; i < 64; i = i + 1)
420
     s_out[i] = s_mid2[permute[i]];
421
 
422
  return ((step == 15) ? s_out : s_mid2);
423
 
424
endfunction

powered by: WebSVN 2.1.0

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