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

Subversion Repositories yac

[/] [yac/] [trunk/] [c_octave/] [cordic_iterative.c] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 feddischso
/***************************************************************************
2
*                                                                          *
3
*  File           : cordic_iterative.c                                     *
4
*  Project        : YAC (Yet Another CORDIC Core)                          *
5
*  Creation       : Feb. 2014                                              *
6
*  Limitations    :                                                        *
7
*  Platform       : Linux, Mac, Windows                                    *
8
*  Target         : Octave, Matlab, Standalone-Application                 *
9
*                                                                          *
10
*  Author(s):     : Christian Haettich                                     *
11
*  Email          : feddischson@opencores.org                              *
12
*                                                                          *
13
*                                                                          *
14
**                                                                        **
15
*                                                                          *
16
*  Description                                                             *
17
*     C-implementation of an interative cordic.                            *
18
*     General information about the CORDIC algorithm can be found          *
19
*     here: - http://en.wikipedia.org/wiki/CORDIC                          *
20
*           - http://en.wikibooks.org/wiki/Digital_Circuits/CORDIC         *
21
*                                                                          *
22
*                                                                          *
23
**                                                                        **
24
*                                                                          *
25
*  TODO                                                                    *
26
*        Some documentation and function description                       *
27
*                                                                          *
28
*                                                                          *
29
*                                                                          *
30
*                                                                          *
31
****************************************************************************
32
*                                                                          *
33
*                     Copyright Notice                                     *
34
*                                                                          *
35
*    This file is part of YAC - Yet Another CORDIC Core                    *
36
*    Copyright (c) 2014, Author(s), All rights reserved.                   *
37
*                                                                          *
38
*    YAC is free software; you can redistribute it and/or                  *
39
*    modify it under the terms of the GNU Lesser General Public            *
40
*    License as published by the Free Software Foundation; either          *
41
*    version 3.0 of the License, or (at your option) any later version.    *
42
*                                                                          *
43
*    YAC is distributed in the hope that it will be useful,                *
44
*    but WITHOUT ANY WARRANTY; without even the implied warranty of        *
45
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
46
*    Lesser General Public License for more details.                       *
47
*                                                                          *
48
*    You should have received a copy of the GNU Lesser General Public      *
49
*    License along with this library. If not, download it from             *
50
*    http://www.gnu.org/licenses/lgpl                                      *
51
*                                                                          *
52
***************************************************************************/
53
 
54
 
55
 
56
#include <stdio.h>
57
#include <stdlib.h>
58
#include <math.h>
59
#include "mex.h"
60
 
61
/* enable debug output */
62 3 feddischso
<<<<<<< HEAD
63 2 feddischso
#define PRINT_DEBUG        0
64 3 feddischso
=======
65
#define PRINT_DEBUG  0
66
>>>>>>> initial commit
67 2 feddischso
 
68
 
69
/* #define CORDIC_ROUNDING    0.5 */
70
#define CORDIC_ROUNDING    0.0
71
 
72
 
73
/* the supported modes */
74
#define C_FLAG_VEC_ROT     0x08
75
#define C_FLAG_ATAN_3      0x04
76
#define C_MODE_MSK         0x03
77
#define C_MODE_CIR         0x00
78
#define C_MODE_LIN         0x01
79
#define C_MODE_HYP         0x02
80
 
81
 
82
 
83
#define PRINT  mexPrintf
84
 
85
 
86
 
87 3 feddischso
<<<<<<< HEAD
88
=======
89
 
90
long long int ov_check( long long int * value, long long int length )
91
{
92
   long long int mask = (1<<length)-1;
93
   long long int result = 0;
94
   long long int min = -((long long int)1<<length);
95
   long long int max =  ((long long int)1<<length);
96
   if( *value > max || *value < min )
97
       result = *value;
98
   /* *value &= mask; */
99
   return result;
100
}
101
 
102
 
103
 
104
>>>>>>> initial commit
105 2 feddischso
void cordic_int( long long int   x_i,
106
                 long long int   y_i,
107
                 long long int   a_i,
108
                 long long int * x_o,
109
                 long long int * y_o,
110
                 long long int * a_o,
111
                 int           * it_o,
112
                 int        mode,
113
                 int        XY_WIDTH,
114
                 int        A_WIDTH,
115
                 int        GUARD_BITS,
116
                 int        RM_GAIN );
117
int            cordic_int_dbg    ( long long int x,
118
                                   long long int y,
119
                                   long long int a,
120
                                   int           mode,
121
                                   int           it,
122
                                   char*         msg );
123
int            cordic_int_init   ( long long int *x,
124
                                   long long int *y,
125
                                   long long int *a,
126
                                   int           mode,
127 3 feddischso
<<<<<<< HEAD
128 2 feddischso
                                   int           A_WIDTH,
129
                                   int           XY_WIDTH );
130 3 feddischso
=======
131
                                   int           A_WIDTH );
132
>>>>>>> initial commit
133 2 feddischso
void           cordic_int_rm_gain( long long int *x,
134
                                   long long int *y,
135
                                   int           mode,
136
                                   int           rm_gain );
137
int            cordic_int_rotate(  long long int * x,
138
                                   long long int * y,
139
                                   long long int * a,
140
                                   int             mode,
141
                                   int             A_WIDTH );
142
long long int  cordic_int_lut    ( int             mode,
143
                                   int             it,
144
                                   int             A_WIDTH );
145
 
146
 
147
 
148
 
149
 
150
 
151
void mexFunction(int nlhs, mxArray *plhs[],
152
                 int nrhs, const mxArray *prhs[])
153
{
154
   double *inx,*iny,*inz,*outx,*outy,*outz,*outi;
155
   double mode;
156
   double xy_width;
157
   double a_width;
158
   double guard_bits;
159
   double rm_gain;
160
 
161
   int mrowsx,ncolsx,mrowsy,ncolsy,mrowsz,ncolsz;
162
   int i;
163
   int it;
164
   if(nrhs!=8 )
165
      mexErrMsgTxt("8 input arguments required");
166
   if(nlhs!=4)
167
      mexErrMsgTxt("4 output arguments required");
168
 
169
   if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]))
170
      mexErrMsgTxt("Input x must be double and non-complex");
171
 
172
   if (!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]))
173
      mexErrMsgTxt("Input y must be double and non-complex");
174
 
175
   if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]))
176
      mexErrMsgTxt("Input a must be double and non-complex");
177
 
178
   mrowsx = mxGetM(prhs[0]);
179
   ncolsx = mxGetN(prhs[0]);
180
   mrowsy = mxGetM(prhs[1]);
181
   ncolsy = mxGetN(prhs[1]);
182
   mrowsz = mxGetM(prhs[2]);
183
   ncolsz = mxGetN(prhs[2]);
184
 
185
 
186
 
187
   if (mrowsx > 1 || mrowsy >1 || mrowsz > 1)
188
       mexErrMsgTxt("Input vector must have the size Nx1.");
189
 
190
   /* printf("%d %d %d\n", ncolsx, ncolsy, ncolsa); */
191
 
192
   if (ncolsx!=ncolsy || ncolsx!=ncolsz || ncolsy!=ncolsz)
193
       mexErrMsgTxt("Input vectors don't have the same length!");
194
 
195
 
196
   plhs[0] = mxCreateDoubleMatrix(mrowsx,ncolsx,mxREAL);
197
   plhs[1] = mxCreateDoubleMatrix(mrowsy,ncolsy,mxREAL);
198
   plhs[2] = mxCreateDoubleMatrix(mrowsz,ncolsz,mxREAL);
199
   plhs[3] = mxCreateDoubleMatrix(mrowsz,ncolsz,mxREAL);
200
 
201
   inx         = mxGetPr(prhs[0]);
202
   iny         = mxGetPr(prhs[1]);
203
   inz         = mxGetPr(prhs[2]);
204
   mode        = mxGetScalar(prhs[3]);
205
   xy_width    = mxGetScalar(prhs[4]);
206
   a_width     = mxGetScalar(prhs[5]);
207
   guard_bits  = mxGetScalar(prhs[6]);
208
   rm_gain     = mxGetScalar(prhs[7]);
209
 
210
   outx= mxGetPr(plhs[0]);
211
   outy= mxGetPr(plhs[1]);
212
   outz= mxGetPr(plhs[2]);
213
   outi= mxGetPr(plhs[3]);
214
 
215
   for( i = 0; i < ncolsx; i++ )
216
   {
217
        long long int inx_i = inx[ i ];
218
        long long int iny_i = iny[ i ];
219
        long long int inz_i = inz[ i ];
220
        long long int outx_i = 0;
221
        long long int outy_i = 0;
222
        long long int outz_i = 0;
223
/*        PRINT("x: %lld, y: %lld, a: %lld\n", inx_i, iny_i, inz_i ); */
224
 
225
        cordic_int(   inx_i,    iny_i,   inz_i,
226
                        &outx_i, &outy_i, &outz_i,
227
                         &it, mode,
228
                         xy_width, a_width, guard_bits, rm_gain );
229
        outx[i] = outx_i;
230
        outy[i] = outy_i;
231
        outz[i] = outz_i;
232
        outi[i] = it;
233
 
234
 
235
   }
236
}
237
 
238
 
239
 
240
 
241
 
242
 
243
void cordic_int( long long int   x_i,
244
                 long long int   y_i,
245
                 long long int   a_i,
246
                 long long int * x_o,
247
                 long long int * y_o,
248
                 long long int * a_o,
249
                 int           * it_o,
250
                 int        mode,
251
                 int        XY_WIDTH,
252
                 int        A_WIDTH,
253
                 int        GUARD_BITS,
254
                 int        RM_GAIN )
255
{
256
   long long int x;
257
   long long int y;
258
   long long int a;
259
   long long int s;
260
   int ov;
261 3 feddischso
<<<<<<< HEAD
262 2 feddischso
   int it = 0;
263 3 feddischso
=======
264
   int it;
265
>>>>>>> initial commit
266 2 feddischso
 
267
 
268
 
269
 
270
   /* total with, including guard bits */
271
   int XY_WIDTH_G = XY_WIDTH + GUARD_BITS;
272
 
273
   cordic_int_dbg( x_i, y_i, a_i, mode, 0, "input" );
274
 
275 3 feddischso
<<<<<<< HEAD
276 2 feddischso
   if( !cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH, XY_WIDTH ) )
277
   {
278
 
279
      it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
280
 
281
      cordic_int_rm_gain( &x_i, &y_i, mode, RM_GAIN );
282
   }
283 3 feddischso
=======
284
   cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH );
285 2 feddischso
 
286 3 feddischso
   it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
287
 
288
   cordic_int_rm_gain( &x_i, &y_i, mode, RM_GAIN );
289
 
290
>>>>>>> initial commit
291
 
292 2 feddischso
   *x_o  = x_i;
293
   *y_o  = y_i;
294
   *a_o  = a_i;
295
   *it_o = it;
296
 
297
}
298
 
299
 
300
 
301
 
302
 
303
 
304
 
305
int cordic_int_init( long long int *x,
306
                     long long int *y,
307
                     long long int *a,
308
                     int           mode,
309 3 feddischso
<<<<<<< HEAD
310 2 feddischso
                     int           A_WIDTH,
311
                     int           XY_WIDTH )
312 3 feddischso
=======
313
                     int           A_WIDTH )
314
>>>>>>> initial commit
315 2 feddischso
{
316
   int already_done = 0;
317
 
318
 
319
   long long int PI   = ( long long int )( M_PI * pow( 2, A_WIDTH-1 ) + 0.5 );
320
   long long int PI_H = (long long int)(  M_PI * pow( 2, A_WIDTH-2 ) + 0.5  );
321 3 feddischso
<<<<<<< HEAD
322 2 feddischso
 
323
   long long int XY_MAX = pow( 2, XY_WIDTH-1 )-1;
324
 
325
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
326
 
327
 
328 3 feddischso
=======
329
 
330
 
331
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
332
>>>>>>> initial commit
333 2 feddischso
   /* Circular rotation mode */
334
   if( 0          == ( mode &  C_FLAG_VEC_ROT )    &&
335
       C_MODE_CIR == ( mode &  C_MODE_MSK     )  )
336
   {
337
      /* move from third quadrant to first
338
         quadrant if necessary */
339
      if( *a <  - PI_H )
340
      {
341
          if( ! (mode & C_FLAG_ATAN_3) )
342
             *a += PI;
343
          *x  = -*x;
344
          *y  = -*y;
345
          #if PRINT_DEBUG > 0
346
          PRINT("move from third quadrand");
347
          #endif
348
      }
349
      /* move from second quadrant to fourth
350
         quadrant if necessary */
351
      else if( *a > PI_H )
352
      {
353
          if( ! (mode & C_FLAG_ATAN_3) )
354
             *a -= PI;
355
          *x  = -*x;
356
          *y  = -*y;
357
          #if PRINT_DEBUG > 0
358
          PRINT("move from second quadrand\n" );
359
          #endif
360
      }
361
   }
362
 
363
   /* circular vector mode */
364
   else if ( 0          != ( mode &  C_FLAG_VEC_ROT )    &&
365
             C_MODE_CIR == ( mode &  C_MODE_MSK     )  )
366
   {
367 3 feddischso
<<<<<<< HEAD
368 2 feddischso
 
369
      if( *x == 0 && *y == 0 )
370
      {
371
         already_done = 1;
372
         *a = 0;
373
         #if PRINT_DEBUG > 0
374
         PRINT( "Zero input, skipping rotations \n" );
375
         #endif
376
      }
377
      else if( *x == XY_MAX && *y == XY_MAX )
378
      {
379
         #if PRINT_DEBUG > 0
380
         PRINT( "All max, skipping rotations 1\n" );
381
         #endif
382
         *a = cordic_int_lut( mode, 0, A_WIDTH );
383
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 );
384
         already_done = 1;
385
      }
386
      else if( *x == -XY_MAX && *y == -XY_MAX )
387
      {
388
         #if PRINT_DEBUG > 0
389
         PRINT( "All max, skipping rotations 2\n" );
390
         #endif
391
         *a = cordic_int_lut( mode, 0, A_WIDTH ) - PI;
392
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 );
393
         already_done = 1;
394
      }
395
      else if( *x ==  XY_MAX && *y == -XY_MAX )
396
      {
397
         #if PRINT_DEBUG > 0
398
         PRINT( "All max, skipping rotations 3\n" );
399
         #endif
400
         *a = -cordic_int_lut( mode, 0, A_WIDTH );
401
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 );
402
         already_done = 1;
403
      }
404
      else if( *x == -XY_MAX && *y ==  XY_MAX )
405
      {
406
         #if PRINT_DEBUG > 0
407
         PRINT( "All max, skipping rotations 4\n" );
408
         #endif
409
         *a = PI - cordic_int_lut( mode, 0, A_WIDTH );
410
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 );
411
         already_done = 1;
412
      }
413
 
414
 
415
 
416
      else if( *x == 0 && *y > 0 )
417
      {
418
         *a = PI_H;
419
         *x = *y;
420
         already_done = 1;
421
         #if PRINT_DEBUG > 0
422
         PRINT( "Fixed value of pi/2, skipping rotations" );
423
         #endif
424
         *y = 0;
425
      }
426
      else if( *x == 0 && *y < 0 )
427
      {
428
         *a = -PI_H;
429
         *x = -*y;
430
         *y = 0;
431
         already_done = 1;
432
         #if PRINT_DEBUG > 0
433
         PRINT( "Fixed value of -pi/2, skipping rotations" );
434
         #endif
435
      }
436
      else if( *x < 0  && *y >= 0 )
437 3 feddischso
=======
438
      if( *x < 0 && *y > 0 )
439
>>>>>>> initial commit
440 2 feddischso
      {
441
         *x = -*x;
442
         *y = -*y;
443
         *a =  PI;
444
          #if PRINT_DEBUG > 0
445 3 feddischso
<<<<<<< HEAD
446 2 feddischso
          PRINT("pre-rotation from second to the fourth quadrant\n" );
447
          #endif
448
      }
449
      else if( *x < 0 && *y <  0 )
450 3 feddischso
=======
451
          PRINT("align from second quadrand\n" );
452
          #endif
453
      }
454
      else if( *x < 0 && *y < 0 )
455
>>>>>>> initial commit
456 2 feddischso
      {
457
         *x = -*x;
458
         *y = -*y;
459
         *a = -PI;
460
          #if PRINT_DEBUG > 0
461 3 feddischso
<<<<<<< HEAD
462 2 feddischso
          PRINT("pre-rotation from third to first quadrand\n" );
463
          #endif
464
      }
465 3 feddischso
=======
466
          PRINT("align from third quadrand\n" );
467
          #endif
468
      }
469
      else if( *x < 0 && *y == 0 )
470
      {
471
         *a           = PI;
472
         already_done = 1;
473
      }
474
>>>>>>> initial commit
475 2 feddischso
      else
476
         *a = 0;
477
   }
478
   /* linear vector mode */
479
   else if ( 0          != ( mode &  C_FLAG_VEC_ROT )    &&
480
             C_MODE_LIN == ( mode &  C_MODE_MSK     )  )
481
   {
482
      if( *x < 0 )
483
      {
484
         *x = -*x;
485
         *y = -*y;
486
      }
487
      *a = 0;
488
   }
489
 
490
   cordic_int_dbg( *x, *y, *a, mode, 0, "after init" );
491 3 feddischso
<<<<<<< HEAD
492 2 feddischso
   return already_done;
493 3 feddischso
=======
494
 
495
>>>>>>> initial commit
496 2 feddischso
}
497
 
498
 
499
 
500
int cordic_int_dbg(  long long int x,
501
                     long long int y,
502
                     long long int a,
503
                     int           mode,
504
                     int           it,
505
                     char*         msg )
506
{
507
   #if PRINT_DEBUG > 0
508
   PRINT( "%20s: mode = %d, iteration %d, x = % 10.lld, y = %10.lld, a = %10.lld \n",
509
           msg,mode,it,x,y,a );
510
   #endif
511
}
512
 
513
int cordic_int_repeat( iteration, mode )
514
{
515
   int i = 4;
516
 
517
   if( C_MODE_HYP != ( mode & C_MODE_MSK ) )
518
      return 0;
519
 
520
 
521
   while( 1 )
522
   {
523
      if( i == iteration )
524
          return 1;
525
      else if( i > iteration )
526
          return 0;
527
      i = i * 3 + 1;
528
   }
529
}
530
 
531
 
532
 
533
 
534
int cordic_int_rotate( long long int * x,
535
                       long long int * y,
536
                       long long int * a,
537
                       int             mode,
538
                       int             A_WIDTH )
539
{
540
   int it = 0;
541
   long long int xsh, ysh;
542
   long long int ylst, alst;
543
   int sign;
544
   int repeat = 0;
545
 
546
   while( 1 )
547
   {
548
      /* get the sign */
549
      if( 0 == ( mode & C_FLAG_VEC_ROT ) )
550
          sign =  ( *a >= 0 );
551
      else
552
          sign = !( *y >= 0 );
553
 
554
      /* shift operation: hyperbolic case*/
555
      if( C_MODE_HYP == ( mode & C_MODE_MSK ) )
556
      {
557
         xsh = *x >> (it+1);
558
         ysh = *y >> (it+1);
559
      }
560
      /* shift operation: circular and linear case*/
561
      else
562
      {
563
         xsh = *x >> it;
564
         ysh = *y >> it;
565
      }
566
 
567
      if( sign == 1 )
568
      {
569
         *a -= cordic_int_lut( mode, it, A_WIDTH );
570
 
571
         if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
572
         {
573
            *x = *x - ysh;
574
            *y = *y + xsh;
575
         }
576
         else
577
         if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
578
         {
579
            *x = *x;
580
            *y = *y + xsh;
581
         }
582
         else
583
         {
584
            *x = *x + ysh;
585
            *y = *y + xsh;
586
         }
587
      }
588
      else
589
      {
590
         *a += cordic_int_lut( mode, it, A_WIDTH );
591
         if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
592
         {
593
            *x = *x + ysh;
594
            *y = *y - xsh;
595
         }
596
         else
597
         if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
598
         {
599
            *x = *x;
600
            *y = *y - xsh;
601
         }
602
         else
603
         {
604
            *x = *x - ysh;
605
            *y = *y - xsh;
606
         }
607
      }
608
      cordic_int_dbg( *x, *y, *a, mode, it, "after rotation" );
609
 
610
      /* abort condition */
611
      if( ( mode & C_FLAG_VEC_ROT  ) == 0 &&
612 3 feddischso
<<<<<<< HEAD
613 2 feddischso
          ( *a == 0 /* || *a == -1 */ ) )
614 3 feddischso
=======
615
          ( *a == 0 || *a == -1 ) )
616
>>>>>>> initial commit
617 2 feddischso
          break;
618
      if( ( mode & C_FLAG_VEC_ROT  ) == 0 &&
619
          ( *a == alst ) )
620
          break;
621
 
622
      if( ( mode & C_FLAG_VEC_ROT  ) != 0 &&
623 3 feddischso
<<<<<<< HEAD
624 2 feddischso
          ( *y == 0 /*|| *y == -1 */ ) )
625 3 feddischso
=======
626
          ( *y == 0 || *y == -1 ) )
627
>>>>>>> initial commit
628 2 feddischso
          break;
629
      if( ( mode & C_FLAG_VEC_ROT  ) != 0 &&
630
          ( *y == ylst ) )
631
          break;
632
 
633
      else if( it > 40 )
634
      {
635
         PRINT( "ERROR: abort %lld %lld %lld %lld - %d - %d!\n", *a, alst, *y, ylst, mode, *y == ylst );
636
         it = -1;
637
          break;
638
      }
639
 
640
 
641
      ylst = *y;
642
      alst = *a;
643
      if( repeat == 0 && cordic_int_repeat( it, mode ) )
644
      {
645
         repeat = 1;
646
         #if PRINT_DEBUG
647
         mexPrintf( "repeat it %d\n" , it );
648
         #endif
649
      }
650
      else
651
      {
652
         repeat = 0;
653
         it++;
654
      }
655
   }
656
   return it;
657
}
658
 
659
 
660
 
661
#define SCALE_VAL( _W_ )(  (double)( (long long int) 1 << (long long int)( _W_ -1 ) ) ) 
662
 
663
long long int cordic_int_lut( int mode, int it, int A_WIDTH )
664
{
665
   long long int lut_val;
666
   if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
667
   {
668
      if( it <= 10 )
669
         lut_val = (long long int)(   atan(  pow( 2, -it ) ) * pow( 2, A_WIDTH-1 ) );
670
      else
671
         lut_val = pow( 2, A_WIDTH-1-it ); /* (long long int)( SCALE_VAL( A_WIDTH-it ) ); */
672
   }
673
   else
674
   if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
675
   {
676
      lut_val =  (long long int)( 1.0 / (double)( ( long long int )1 << (long long int)it )
677
                                *  SCALE_VAL( A_WIDTH ) -1 );
678
   }
679
   else
680
   {
681
      lut_val = (long long int)( atanh( 1.0 / (double)( (long long int)1 << ( long long int )(it+1)  ) )
682
                                *  SCALE_VAL( A_WIDTH ) );
683
   }
684
   return lut_val;
685
}
686
 
687
 
688
 
689
 
690
/**
691
 *
692
 * Cordic gain:
693
 *
694
 *
695
 *
696
 */
697
void cordic_int_rm_gain( long long int *x,
698
                         long long int *y,
699
                         int mode,
700
                         int rm_gain )
701
{
702
   /* for the non-linear case: remove cordic gain if RM_GAIN > 0 */
703
   if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
704
   {
705
 
706
 
707
      switch( rm_gain )
708
      {
709
         case 1: *x = + ( *x >> 1 ) ; break; /* error: 0.1072529350 */
710
         case 2: *x = + ( *x >> 1 ) - ( *x >> 4 ) ; break; /* error: 0.1697529350 */
711
         case 3: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 5 ) ; break; /* error: 0.0135029350 */
712
         case 4: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 8 ) ; break; /* error: 0.0017841850 */
713
         case 5: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 12 ) ; break; /* error: 0.0000752006 */
714
         case 6: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) ; break; /* error: 0.0000141655 */
715
         case 7: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) - ( *x >> 17 ) ; break; /* error: 0.0000217949 */
716
         case 8: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) + ( *x >> 16 ) - ( *x >> 19 ) ; break; /* error: 0.0000008140 */
717
         case 9: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) + ( *x >> 16 ) - ( *x >> 20 ) - ( *x >> 22 ) ; break; /* error: 0.0000000988 */
718
         case 10: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) + ( *x >> 16 ) - ( *x >> 20 ) - ( *x >> 23 ) - ( *x >> 25 ) ; break; /* error: 0.0000000094 */
719
         case 11: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) + ( *x >> 16 ) - ( *x >> 20 ) - ( *x >> 23 ) - ( *x >> 26 ) - ( *x >> 27 ) ; break; /* error: 0.0000000019 */
720
         case 12: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) + ( *x >> 16 ) - ( *x >> 20 ) - ( *x >> 23 ) - ( *x >> 26 ) - ( *x >> 28 ) - ( *x >> 29 ) ; break; /* error: 0.0000000001 */
721
         default: *x = *x; break;
722
      }
723
      switch( rm_gain )
724
      {
725
         case 1: *y = + ( *y >> 1 ) ; break; /* error: 0.1072529350 */
726
         case 2: *y = + ( *y >> 1 ) - ( *y >> 4 ) ; break; /* error: 0.1697529350 */
727
         case 3: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 5 ) ; break; /* error: 0.0135029350 */
728
         case 4: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 8 ) ; break; /* error: 0.0017841850 */
729
         case 5: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 12 ) ; break; /* error: 0.0000752006 */
730
         case 6: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) ; break; /* error: 0.0000141655 */
731
         case 7: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) - ( *y >> 17 ) ; break; /* error: 0.0000217949 */
732
         case 8: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) + ( *y >> 16 ) - ( *y >> 19 ) ; break; /* error: 0.0000008140 */
733
         case 9: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) + ( *y >> 16 ) - ( *y >> 20 ) - ( *y >> 22 ) ; break; /* error: 0.0000000988 */
734
         case 10: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) + ( *y >> 16 ) - ( *y >> 20 ) - ( *y >> 23 ) - ( *y >> 25 ) ; break; /* error: 0.0000000094 */
735
         case 11: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) + ( *y >> 16 ) - ( *y >> 20 ) - ( *y >> 23 ) - ( *y >> 26 ) - ( *y >> 27 ) ; break; /* error: 0.0000000019 */
736
         case 12: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) + ( *y >> 16 ) - ( *y >> 20 ) - ( *y >> 23 ) - ( *y >> 26 ) - ( *y >> 28 ) - ( *y >> 29 ) ; break; /* error: 0.0000000001 */
737
         default: *x = *y; break;
738
      }
739
 
740
   }
741
   else
742
   if( C_MODE_HYP == ( mode & C_MODE_MSK ) )
743
   {
744
      switch( rm_gain )
745
      {
746
         case 1: *x = *x - ( *x >> 3 ) ; break; /* error: 0.3324970678 */
747
         case 2: *x = *x + ( *x >> 2 ) - ( *x >> 4 ) ; break; /* error: 0.0199970678 */
748
         case 3: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 6 ) ; break; /* error: 0.0043720678 */
749
         case 4: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) ; break; /* error: 0.0004658178 */
750
         case 5: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) - ( *x >> 12 ) ; break; /* error: 0.0007099584 */
751
         case 6: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 15 ) ; break; /* error: 0.0000080541 */
752
         case 7: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) ; break; /* error: 0.0000004247 */
753
         case 8: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) - ( *x >> 22 ) ; break; /* error: 0.0000006631 */
754
         case 9: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) + ( *x >> 21 ) - ( *x >> 24 ) ; break; /* error: 0.0000000075 */
755
         case 10: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) + ( *x >> 21 ) - ( *x >> 24 ) + ( *x >> 27 ) ; break; /* error: 0.0000000000 */
756
         case 11: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) + ( *x >> 21 ) - ( *x >> 24 ) + ( *x >> 27 ) - ( *x >> 37 ) ; break; /* error: 0.0000000000 */
757
         case 12: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) + ( *x >> 21 ) - ( *x >> 24 ) + ( *x >> 27 ) + ( *x >> 36 ) - ( *x >> 39 ) ; break; /* error: 0.0000000000 */
758
      }
759
      switch( rm_gain )
760
      {
761
         case 1: *y = *y - ( *y >> 3 ) ; break; /* error: 0.3324970678 */
762
         case 2: *y = *y + ( *y >> 2 ) - ( *y >> 4 ) ; break; /* error: 0.0199970678 */
763
         case 3: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 6 ) ; break; /* error: 0.0043720678 */
764
         case 4: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) ; break; /* error: 0.0004658178 */
765
         case 5: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) - ( *y >> 12 ) ; break; /* error: 0.0007099584 */
766
         case 6: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 15 ) ; break; /* error: 0.0000080541 */
767
         case 7: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) ; break; /* error: 0.0000004247 */
768
         case 8: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) - ( *y >> 22 ) ; break; /* error: 0.0000006631 */
769
         case 9: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) + ( *y >> 21 ) - ( *y >> 24 ) ; break; /* error: 0.0000000075 */
770
         case 10: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) + ( *y >> 21 ) - ( *y >> 24 ) + ( *y >> 27 ) ; break; /* error: 0.0000000000 */
771
         case 11: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) + ( *y >> 21 ) - ( *y >> 24 ) + ( *y >> 27 ) - ( *y >> 37 ) ; break; /* error: 0.0000000000 */
772
         case 12: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) + ( *y >> 21 ) - ( *y >> 24 ) + ( *y >> 27 ) + ( *y >> 36 ) - ( *y >> 39 ) ; break; /* error: 0.0000000000 */
773
      }
774
   }
775
}
776
 

powered by: WebSVN 2.1.0

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