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

Subversion Repositories yac

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

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
 
60 7 feddischso
#ifndef OR32_TARGET
61
 #include "mex.h"
62
#endif 
63
 
64 2 feddischso
/* enable debug output */
65 3 feddischso
<<<<<<< HEAD
66 4 feddischso
<<<<<<< HEAD
67 2 feddischso
#define PRINT_DEBUG        0
68 3 feddischso
=======
69
#define PRINT_DEBUG  0
70
>>>>>>> initial commit
71 4 feddischso
=======
72
#define PRINT_DEBUG        0
73
>>>>>>> Updated C and RTL model as well as the documentation
74 2 feddischso
 
75
/* #define CORDIC_ROUNDING    0.5 */
76
#define CORDIC_ROUNDING    0.0
77
 
78
 
79
/* the supported modes */
80
#define C_FLAG_VEC_ROT     0x08
81
#define C_FLAG_ATAN_3      0x04
82
#define C_MODE_MSK         0x03
83
#define C_MODE_CIR         0x00
84
#define C_MODE_LIN         0x01
85
#define C_MODE_HYP         0x02
86
 
87
 
88 7 feddischso
#ifndef OR32_TARGET
89
 #define PRINT  mexPrintf
90
#endif
91 2 feddischso
 
92
 
93 3 feddischso
<<<<<<< HEAD
94 4 feddischso
<<<<<<< HEAD
95 3 feddischso
=======
96
 
97
long long int ov_check( long long int * value, long long int length )
98
{
99
   long long int mask = (1<<length)-1;
100
   long long int result = 0;
101
   long long int min = -((long long int)1<<length);
102
   long long int max =  ((long long int)1<<length);
103
   if( *value > max || *value < min )
104
       result = *value;
105
   /* *value &= mask; */
106
   return result;
107
}
108
 
109
 
110
 
111
>>>>>>> initial commit
112 4 feddischso
=======
113
>>>>>>> Updated C and RTL model as well as the documentation
114 2 feddischso
void cordic_int( long long int   x_i,
115
                 long long int   y_i,
116
                 long long int   a_i,
117
                 long long int * x_o,
118
                 long long int * y_o,
119
                 long long int * a_o,
120
                 int           * it_o,
121
                 int        mode,
122
                 int        XY_WIDTH,
123
                 int        A_WIDTH,
124
                 int        GUARD_BITS,
125
                 int        RM_GAIN );
126
int            cordic_int_dbg    ( long long int x,
127
                                   long long int y,
128
                                   long long int a,
129
                                   int           mode,
130
                                   int           it,
131
                                   char*         msg );
132
int            cordic_int_init   ( long long int *x,
133
                                   long long int *y,
134
                                   long long int *a,
135
                                   int           mode,
136 3 feddischso
<<<<<<< HEAD
137 4 feddischso
<<<<<<< HEAD
138 2 feddischso
                                   int           A_WIDTH,
139
                                   int           XY_WIDTH );
140 3 feddischso
=======
141
                                   int           A_WIDTH );
142
>>>>>>> initial commit
143 4 feddischso
=======
144
                                   int           A_WIDTH,
145
                                   int           XY_WIDTH );
146
>>>>>>> Updated C and RTL model as well as the documentation
147 2 feddischso
void           cordic_int_rm_gain( long long int *x,
148
                                   long long int *y,
149
                                   int           mode,
150
                                   int           rm_gain );
151
int            cordic_int_rotate(  long long int * x,
152
                                   long long int * y,
153
                                   long long int * a,
154
                                   int             mode,
155
                                   int             A_WIDTH );
156
long long int  cordic_int_lut    ( int             mode,
157
                                   int             it,
158
                                   int             A_WIDTH );
159
 
160
 
161
 
162 7 feddischso
#ifndef OR32_TARGET
163 2 feddischso
 
164
 
165
void mexFunction(int nlhs, mxArray *plhs[],
166
                 int nrhs, const mxArray *prhs[])
167
{
168
   double *inx,*iny,*inz,*outx,*outy,*outz,*outi;
169
   double mode;
170
   double xy_width;
171
   double a_width;
172
   double guard_bits;
173
   double rm_gain;
174
 
175
   int mrowsx,ncolsx,mrowsy,ncolsy,mrowsz,ncolsz;
176
   int i;
177
   int it;
178
   if(nrhs!=8 )
179
      mexErrMsgTxt("8 input arguments required");
180
   if(nlhs!=4)
181
      mexErrMsgTxt("4 output arguments required");
182 7 feddischso
 
183 2 feddischso
   if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]))
184
      mexErrMsgTxt("Input x must be double and non-complex");
185 7 feddischso
 
186 2 feddischso
   if (!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]))
187
      mexErrMsgTxt("Input y must be double and non-complex");
188 7 feddischso
 
189 2 feddischso
   if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]))
190
      mexErrMsgTxt("Input a must be double and non-complex");
191 7 feddischso
 
192 2 feddischso
   mrowsx = mxGetM(prhs[0]);
193
   ncolsx = mxGetN(prhs[0]);
194
   mrowsy = mxGetM(prhs[1]);
195
   ncolsy = mxGetN(prhs[1]);
196
   mrowsz = mxGetM(prhs[2]);
197
   ncolsz = mxGetN(prhs[2]);
198
 
199 7 feddischso
 
200
 
201 2 feddischso
   if (mrowsx > 1 || mrowsy >1 || mrowsz > 1)
202
       mexErrMsgTxt("Input vector must have the size Nx1.");
203
 
204
   /* printf("%d %d %d\n", ncolsx, ncolsy, ncolsa); */
205 7 feddischso
 
206 2 feddischso
   if (ncolsx!=ncolsy || ncolsx!=ncolsz || ncolsy!=ncolsz)
207
       mexErrMsgTxt("Input vectors don't have the same length!");
208 7 feddischso
 
209
 
210 2 feddischso
   plhs[0] = mxCreateDoubleMatrix(mrowsx,ncolsx,mxREAL);
211
   plhs[1] = mxCreateDoubleMatrix(mrowsy,ncolsy,mxREAL);
212
   plhs[2] = mxCreateDoubleMatrix(mrowsz,ncolsz,mxREAL);
213
   plhs[3] = mxCreateDoubleMatrix(mrowsz,ncolsz,mxREAL);
214 7 feddischso
 
215 2 feddischso
   inx         = mxGetPr(prhs[0]);
216
   iny         = mxGetPr(prhs[1]);
217
   inz         = mxGetPr(prhs[2]);
218
   mode        = mxGetScalar(prhs[3]);
219
   xy_width    = mxGetScalar(prhs[4]);
220
   a_width     = mxGetScalar(prhs[5]);
221
   guard_bits  = mxGetScalar(prhs[6]);
222
   rm_gain     = mxGetScalar(prhs[7]);
223
 
224
   outx= mxGetPr(plhs[0]);
225
   outy= mxGetPr(plhs[1]);
226
   outz= mxGetPr(plhs[2]);
227
   outi= mxGetPr(plhs[3]);
228
 
229
   for( i = 0; i < ncolsx; i++ )
230
   {
231
        long long int inx_i = inx[ i ];
232
        long long int iny_i = iny[ i ];
233
        long long int inz_i = inz[ i ];
234
        long long int outx_i = 0;
235
        long long int outy_i = 0;
236
        long long int outz_i = 0;
237
/*        PRINT("x: %lld, y: %lld, a: %lld\n", inx_i, iny_i, inz_i ); */
238
 
239
        cordic_int(   inx_i,    iny_i,   inz_i,
240
                        &outx_i, &outy_i, &outz_i,
241
                         &it, mode,
242
                         xy_width, a_width, guard_bits, rm_gain );
243
        outx[i] = outx_i;
244
        outy[i] = outy_i;
245
        outz[i] = outz_i;
246
        outi[i] = it;
247
 
248 7 feddischso
 
249 2 feddischso
   }
250
}
251
 
252 7 feddischso
#endif
253 2 feddischso
 
254
 
255
 
256
 
257
void cordic_int( long long int   x_i,
258
                 long long int   y_i,
259
                 long long int   a_i,
260
                 long long int * x_o,
261
                 long long int * y_o,
262
                 long long int * a_o,
263
                 int           * it_o,
264
                 int        mode,
265
                 int        XY_WIDTH,
266
                 int        A_WIDTH,
267
                 int        GUARD_BITS,
268
                 int        RM_GAIN )
269
{
270
   long long int x;
271
   long long int y;
272
   long long int a;
273
   long long int s;
274
   int ov;
275 3 feddischso
<<<<<<< HEAD
276 4 feddischso
<<<<<<< HEAD
277 2 feddischso
   int it = 0;
278 3 feddischso
=======
279
   int it;
280
>>>>>>> initial commit
281 4 feddischso
=======
282
   int it = 0;
283
>>>>>>> Updated C and RTL model as well as the documentation
284 2 feddischso
 
285
 
286
 
287 7 feddischso
 
288 2 feddischso
   /* total with, including guard bits */
289
   int XY_WIDTH_G = XY_WIDTH + GUARD_BITS;
290 7 feddischso
 
291 2 feddischso
   cordic_int_dbg( x_i, y_i, a_i, mode, 0, "input" );
292
 
293 3 feddischso
<<<<<<< HEAD
294 4 feddischso
<<<<<<< HEAD
295 2 feddischso
   if( !cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH, XY_WIDTH ) )
296
   {
297
 
298
      it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
299
 
300
      cordic_int_rm_gain( &x_i, &y_i, mode, RM_GAIN );
301
   }
302 3 feddischso
=======
303
   cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH );
304 2 feddischso
 
305 3 feddischso
   it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
306 4 feddischso
=======
307
   if( !cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH, XY_WIDTH ) )
308
   {
309
>>>>>>> Updated C and RTL model as well as the documentation
310 3 feddischso
 
311 4 feddischso
      it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
312 3 feddischso
 
313 4 feddischso
<<<<<<< HEAD
314 3 feddischso
>>>>>>> initial commit
315 4 feddischso
=======
316
      cordic_int_rm_gain( &x_i, &y_i, mode, RM_GAIN );
317
   }
318
>>>>>>> Updated C and RTL model as well as the documentation
319 3 feddischso
 
320 2 feddischso
   *x_o  = x_i;
321
   *y_o  = y_i;
322
   *a_o  = a_i;
323
   *it_o = it;
324
 
325
}
326
 
327
 
328
 
329
 
330
 
331
 
332
 
333
int cordic_int_init( long long int *x,
334
                     long long int *y,
335
                     long long int *a,
336
                     int           mode,
337 3 feddischso
<<<<<<< HEAD
338 4 feddischso
<<<<<<< HEAD
339 2 feddischso
                     int           A_WIDTH,
340
                     int           XY_WIDTH )
341 3 feddischso
=======
342
                     int           A_WIDTH )
343
>>>>>>> initial commit
344 4 feddischso
=======
345
                     int           A_WIDTH,
346
                     int           XY_WIDTH )
347
>>>>>>> Updated C and RTL model as well as the documentation
348 2 feddischso
{
349
   int already_done = 0;
350
 
351
 
352
   long long int PI   = ( long long int )( M_PI * pow( 2, A_WIDTH-1 ) + 0.5 );
353
   long long int PI_H = (long long int)(  M_PI * pow( 2, A_WIDTH-2 ) + 0.5  );
354 3 feddischso
<<<<<<< HEAD
355 4 feddischso
<<<<<<< HEAD
356 7 feddischso
<<<<<<< HEAD
357 2 feddischso
 
358
   long long int XY_MAX = pow( 2, XY_WIDTH-1 )-1;
359
 
360
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
361
 
362
 
363 3 feddischso
=======
364
 
365
 
366
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
367
>>>>>>> initial commit
368 4 feddischso
=======
369
 
370 7 feddischso
=======
371
 
372
>>>>>>> Removed some bugs regarding pre-rotation and negative numbers in the wb wrapper
373 4 feddischso
   long long int XY_MAX = pow( 2, XY_WIDTH-1 )-1;
374 7 feddischso
 
375 4 feddischso
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
376
 
377
 
378 7 feddischso
<<<<<<< HEAD
379 4 feddischso
>>>>>>> Updated C and RTL model as well as the documentation
380 7 feddischso
=======
381
   if( 0 != ( mode &  C_FLAG_VEC_ROT ) && *y == 0 )
382
   {
383
       already_done = 1;
384
       *a = 0;
385
       #if PRINT_DEBUG > 0
386
       PRINT( "Zero input, skipping rotations \n" );
387
       #endif
388
   }
389
   else if( 0 == ( mode &  C_FLAG_VEC_ROT )  && *a == 0 )
390
   {
391
       #if PRINT_DEBUG > 0
392
       PRINT("zero angular input\n" );
393
       #endif
394
       already_done = 1;
395
   }
396
 
397
>>>>>>> Removed some bugs regarding pre-rotation and negative numbers in the wb wrapper
398 2 feddischso
   /* Circular rotation mode */
399 7 feddischso
   else if( 0          == ( mode &  C_FLAG_VEC_ROT )    &&
400 2 feddischso
       C_MODE_CIR == ( mode &  C_MODE_MSK     )  )
401
   {
402 7 feddischso
 
403
 
404 2 feddischso
      /* move from third quadrant to first
405
         quadrant if necessary */
406
      if( *a <  - PI_H )
407
      {
408
          if( ! (mode & C_FLAG_ATAN_3) )
409
             *a += PI;
410
          *x  = -*x;
411
          *y  = -*y;
412
          #if PRINT_DEBUG > 0
413
          PRINT("move from third quadrand");
414
          #endif
415
      }
416
      /* move from second quadrant to fourth
417
         quadrant if necessary */
418
      else if( *a > PI_H )
419
      {
420
          if( ! (mode & C_FLAG_ATAN_3) )
421
             *a -= PI;
422
          *x  = -*x;
423
          *y  = -*y;
424
          #if PRINT_DEBUG > 0
425
          PRINT("move from second quadrand\n" );
426
          #endif
427
      }
428
   }
429
 
430
   /* circular vector mode */
431
   else if ( 0          != ( mode &  C_FLAG_VEC_ROT )    &&
432
             C_MODE_CIR == ( mode &  C_MODE_MSK     )  )
433
   {
434 3 feddischso
<<<<<<< HEAD
435 4 feddischso
<<<<<<< HEAD
436
=======
437
>>>>>>> Updated C and RTL model as well as the documentation
438 2 feddischso
 
439 7 feddischso
      if( *x == XY_MAX && *y == XY_MAX )
440 2 feddischso
      {
441
         #if PRINT_DEBUG > 0
442
         PRINT( "All max, skipping rotations 1\n" );
443
         #endif
444 7 feddischso
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
445
         *y = 0;
446 2 feddischso
         *a = cordic_int_lut( mode, 0, A_WIDTH );
447
         already_done = 1;
448
      }
449
      else if( *x == -XY_MAX && *y == -XY_MAX )
450
      {
451
         #if PRINT_DEBUG > 0
452
         PRINT( "All max, skipping rotations 2\n" );
453
         #endif
454 7 feddischso
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
455
         *y = 0;
456 2 feddischso
         *a = cordic_int_lut( mode, 0, A_WIDTH ) - PI;
457
         already_done = 1;
458
      }
459
      else if( *x ==  XY_MAX && *y == -XY_MAX )
460
      {
461
         #if PRINT_DEBUG > 0
462
         PRINT( "All max, skipping rotations 3\n" );
463
         #endif
464 7 feddischso
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
465
         *y = 0;
466 2 feddischso
         *a = -cordic_int_lut( mode, 0, A_WIDTH );
467
         already_done = 1;
468
      }
469
      else if( *x == -XY_MAX && *y ==  XY_MAX )
470
      {
471
         #if PRINT_DEBUG > 0
472
         PRINT( "All max, skipping rotations 4\n" );
473
         #endif
474 7 feddischso
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
475
         *y = 0;
476 2 feddischso
         *a = PI - cordic_int_lut( mode, 0, A_WIDTH );
477
         already_done = 1;
478
      }
479
 
480
 
481
 
482
      else if( *x == 0 && *y > 0 )
483
      {
484
         *a = PI_H;
485
         *x = *y;
486
         already_done = 1;
487
         #if PRINT_DEBUG > 0
488 7 feddischso
         PRINT( "Fixed value of pi/2, skipping rotations\n" );
489 2 feddischso
         #endif
490
         *y = 0;
491
      }
492
      else if( *x == 0 && *y < 0 )
493
      {
494
         *a = -PI_H;
495
         *x = -*y;
496
         *y = 0;
497
         already_done = 1;
498
         #if PRINT_DEBUG > 0
499 7 feddischso
         PRINT( "Fixed value of -pi/2, skipping rotations\n" );
500 2 feddischso
         #endif
501
      }
502
      else if( *x < 0  && *y >= 0 )
503 4 feddischso
<<<<<<< HEAD
504 3 feddischso
=======
505
      if( *x < 0 && *y > 0 )
506
>>>>>>> initial commit
507 4 feddischso
=======
508
>>>>>>> Updated C and RTL model as well as the documentation
509 2 feddischso
      {
510
         *x = -*x;
511
         *y = -*y;
512
         *a =  PI;
513
          #if PRINT_DEBUG > 0
514 3 feddischso
<<<<<<< HEAD
515 4 feddischso
<<<<<<< HEAD
516 2 feddischso
          PRINT("pre-rotation from second to the fourth quadrant\n" );
517
          #endif
518
      }
519
      else if( *x < 0 && *y <  0 )
520 3 feddischso
=======
521
          PRINT("align from second quadrand\n" );
522
          #endif
523
      }
524
      else if( *x < 0 && *y < 0 )
525
>>>>>>> initial commit
526 4 feddischso
=======
527
          PRINT("pre-rotation from second to the fourth quadrant\n" );
528
          #endif
529
      }
530
      else if( *x < 0 && *y <  0 )
531
>>>>>>> Updated C and RTL model as well as the documentation
532 2 feddischso
      {
533
         *x = -*x;
534
         *y = -*y;
535
         *a = -PI;
536
          #if PRINT_DEBUG > 0
537 3 feddischso
<<<<<<< HEAD
538 4 feddischso
<<<<<<< HEAD
539 2 feddischso
          PRINT("pre-rotation from third to first quadrand\n" );
540
          #endif
541
      }
542 3 feddischso
=======
543
          PRINT("align from third quadrand\n" );
544
          #endif
545
      }
546
      else if( *x < 0 && *y == 0 )
547
      {
548
         *a           = PI;
549
         already_done = 1;
550
      }
551
>>>>>>> initial commit
552 4 feddischso
=======
553
          PRINT("pre-rotation from third to first quadrand\n" );
554
          #endif
555
      }
556
>>>>>>> Updated C and RTL model as well as the documentation
557 2 feddischso
      else
558
         *a = 0;
559
   }
560
   /* linear vector mode */
561
   else if ( 0          != ( mode &  C_FLAG_VEC_ROT )    &&
562
             C_MODE_LIN == ( mode &  C_MODE_MSK     )  )
563
   {
564
      if( *x < 0 )
565
      {
566
         *x = -*x;
567
         *y = -*y;
568
      }
569
      *a = 0;
570
   }
571
   cordic_int_dbg( *x, *y, *a, mode, 0, "after init" );
572 3 feddischso
<<<<<<< HEAD
573 4 feddischso
<<<<<<< HEAD
574 2 feddischso
   return already_done;
575 3 feddischso
=======
576
 
577
>>>>>>> initial commit
578 4 feddischso
=======
579
   return already_done;
580
>>>>>>> Updated C and RTL model as well as the documentation
581 2 feddischso
}
582
 
583
 
584
 
585
int cordic_int_dbg(  long long int x,
586
                     long long int y,
587
                     long long int a,
588
                     int           mode,
589
                     int           it,
590
                     char*         msg )
591
{
592
   #if PRINT_DEBUG > 0
593
   PRINT( "%20s: mode = %d, iteration %d, x = % 10.lld, y = %10.lld, a = %10.lld \n",
594
           msg,mode,it,x,y,a );
595
   #endif
596
}
597
 
598
int cordic_int_repeat( iteration, mode )
599
{
600
   int i = 4;
601 7 feddischso
 
602 2 feddischso
   if( C_MODE_HYP != ( mode & C_MODE_MSK ) )
603
      return 0;
604 7 feddischso
 
605
 
606 2 feddischso
   while( 1 )
607
   {
608
      if( i == iteration )
609
          return 1;
610
      else if( i > iteration )
611
          return 0;
612
      i = i * 3 + 1;
613
   }
614
}
615
 
616
 
617
 
618
 
619
int cordic_int_rotate( long long int * x,
620
                       long long int * y,
621
                       long long int * a,
622
                       int             mode,
623
                       int             A_WIDTH )
624
{
625
   int it = 0;
626
   long long int xsh, ysh;
627
   long long int ylst, alst;
628
   int sign;
629
   int repeat = 0;
630
 
631
   while( 1 )
632
   {
633
      /* get the sign */
634
      if( 0 == ( mode & C_FLAG_VEC_ROT ) )
635
          sign =  ( *a >= 0 );
636
      else
637
          sign = !( *y >= 0 );
638
 
639
      /* shift operation: hyperbolic case*/
640
      if( C_MODE_HYP == ( mode & C_MODE_MSK ) )
641
      {
642
         xsh = *x >> (it+1);
643
         ysh = *y >> (it+1);
644
      }
645
      /* shift operation: circular and linear case*/
646
      else
647
      {
648
         xsh = *x >> it;
649
         ysh = *y >> it;
650
      }
651
 
652
      if( sign == 1 )
653
      {
654
         *a -= cordic_int_lut( mode, it, A_WIDTH );
655
 
656
         if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
657
         {
658
            *x = *x - ysh;
659
            *y = *y + xsh;
660
         }
661
         else
662
         if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
663
         {
664
            *x = *x;
665
            *y = *y + xsh;
666
         }
667
         else
668
         {
669
            *x = *x + ysh;
670
            *y = *y + xsh;
671
         }
672
      }
673
      else
674
      {
675
         *a += cordic_int_lut( mode, it, A_WIDTH );
676
         if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
677
         {
678
            *x = *x + ysh;
679
            *y = *y - xsh;
680
         }
681
         else
682
         if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
683
         {
684
            *x = *x;
685
            *y = *y - xsh;
686
         }
687
         else
688
         {
689
            *x = *x - ysh;
690
            *y = *y - xsh;
691
         }
692
      }
693
      cordic_int_dbg( *x, *y, *a, mode, it, "after rotation" );
694 7 feddischso
 
695 2 feddischso
      /* abort condition */
696
      if( ( mode & C_FLAG_VEC_ROT  ) == 0 &&
697 3 feddischso
<<<<<<< HEAD
698 4 feddischso
<<<<<<< HEAD
699 2 feddischso
          ( *a == 0 /* || *a == -1 */ ) )
700 3 feddischso
=======
701
          ( *a == 0 || *a == -1 ) )
702
>>>>>>> initial commit
703 4 feddischso
=======
704
          ( *a == 0 /* || *a == -1 */ ) )
705
>>>>>>> Updated C and RTL model as well as the documentation
706 2 feddischso
          break;
707
      if( ( mode & C_FLAG_VEC_ROT  ) == 0 &&
708
          ( *a == alst ) )
709
          break;
710 7 feddischso
 
711 2 feddischso
      if( ( mode & C_FLAG_VEC_ROT  ) != 0 &&
712 3 feddischso
<<<<<<< HEAD
713 4 feddischso
<<<<<<< HEAD
714 2 feddischso
          ( *y == 0 /*|| *y == -1 */ ) )
715 3 feddischso
=======
716
          ( *y == 0 || *y == -1 ) )
717
>>>>>>> initial commit
718 4 feddischso
=======
719
          ( *y == 0 /*|| *y == -1 */ ) )
720
>>>>>>> Updated C and RTL model as well as the documentation
721 2 feddischso
          break;
722
      if( ( mode & C_FLAG_VEC_ROT  ) != 0 &&
723
          ( *y == ylst ) )
724
          break;
725
 
726
      else if( it > 40 )
727
      {
728 7 feddischso
#if PRINT_DEBUG
729 2 feddischso
         PRINT( "ERROR: abort %lld %lld %lld %lld - %d - %d!\n", *a, alst, *y, ylst, mode, *y == ylst );
730 7 feddischso
#endif
731 2 feddischso
         it = -1;
732
          break;
733
      }
734
 
735
 
736
      ylst = *y;
737
      alst = *a;
738
      if( repeat == 0 && cordic_int_repeat( it, mode ) )
739
      {
740
         repeat = 1;
741
         #if PRINT_DEBUG
742
         mexPrintf( "repeat it %d\n" , it );
743
         #endif
744
      }
745
      else
746
      {
747
         repeat = 0;
748
         it++;
749
      }
750
   }
751
   return it;
752
}
753
 
754
 
755
 
756
#define SCALE_VAL( _W_ )(  (double)( (long long int) 1 << (long long int)( _W_ -1 ) ) ) 
757
 
758
long long int cordic_int_lut( int mode, int it, int A_WIDTH )
759
{
760
   long long int lut_val;
761
   if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
762
   {
763
      if( it <= 10 )
764
         lut_val = (long long int)(   atan(  pow( 2, -it ) ) * pow( 2, A_WIDTH-1 ) );
765
      else
766
         lut_val = pow( 2, A_WIDTH-1-it ); /* (long long int)( SCALE_VAL( A_WIDTH-it ) ); */
767
   }
768
   else
769
   if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
770
   {
771
      lut_val =  (long long int)( 1.0 / (double)( ( long long int )1 << (long long int)it )
772
                                *  SCALE_VAL( A_WIDTH ) -1 );
773
   }
774
   else
775
   {
776
      lut_val = (long long int)( atanh( 1.0 / (double)( (long long int)1 << ( long long int )(it+1)  ) )
777
                                *  SCALE_VAL( A_WIDTH ) );
778
   }
779
   return lut_val;
780
}
781
 
782
 
783
 
784
 
785
/**
786
 *
787
 * Cordic gain:
788
 *
789
 *
790
 *
791
 */
792
void cordic_int_rm_gain( long long int *x,
793
                         long long int *y,
794
                         int mode,
795
                         int rm_gain )
796
{
797
   /* for the non-linear case: remove cordic gain if RM_GAIN > 0 */
798
   if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
799
   {
800
 
801
 
802
      switch( rm_gain )
803
      {
804
         case 1: *x = + ( *x >> 1 ) ; break; /* error: 0.1072529350 */
805
         case 2: *x = + ( *x >> 1 ) - ( *x >> 4 ) ; break; /* error: 0.1697529350 */
806
         case 3: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 5 ) ; break; /* error: 0.0135029350 */
807
         case 4: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 8 ) ; break; /* error: 0.0017841850 */
808
         case 5: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 12 ) ; break; /* error: 0.0000752006 */
809
         case 6: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) ; break; /* error: 0.0000141655 */
810
         case 7: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) - ( *x >> 17 ) ; break; /* error: 0.0000217949 */
811
         case 8: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) + ( *x >> 16 ) - ( *x >> 19 ) ; break; /* error: 0.0000008140 */
812
         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 */
813
         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 */
814
         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 */
815
         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 */
816
         default: *x = *x; break;
817
      }
818
      switch( rm_gain )
819
      {
820
         case 1: *y = + ( *y >> 1 ) ; break; /* error: 0.1072529350 */
821
         case 2: *y = + ( *y >> 1 ) - ( *y >> 4 ) ; break; /* error: 0.1697529350 */
822
         case 3: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 5 ) ; break; /* error: 0.0135029350 */
823
         case 4: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 8 ) ; break; /* error: 0.0017841850 */
824
         case 5: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 12 ) ; break; /* error: 0.0000752006 */
825
         case 6: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) ; break; /* error: 0.0000141655 */
826
         case 7: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) - ( *y >> 17 ) ; break; /* error: 0.0000217949 */
827
         case 8: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) + ( *y >> 16 ) - ( *y >> 19 ) ; break; /* error: 0.0000008140 */
828
         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 */
829
         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 */
830
         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 */
831
         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 */
832
         default: *x = *y; break;
833
      }
834
 
835
   }
836
   else
837
   if( C_MODE_HYP == ( mode & C_MODE_MSK ) )
838
   {
839
      switch( rm_gain )
840
      {
841
         case 1: *x = *x - ( *x >> 3 ) ; break; /* error: 0.3324970678 */
842
         case 2: *x = *x + ( *x >> 2 ) - ( *x >> 4 ) ; break; /* error: 0.0199970678 */
843
         case 3: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 6 ) ; break; /* error: 0.0043720678 */
844
         case 4: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) ; break; /* error: 0.0004658178 */
845
         case 5: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) - ( *x >> 12 ) ; break; /* error: 0.0007099584 */
846
         case 6: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 15 ) ; break; /* error: 0.0000080541 */
847
         case 7: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) ; break; /* error: 0.0000004247 */
848
         case 8: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) - ( *x >> 22 ) ; break; /* error: 0.0000006631 */
849
         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 */
850
         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 */
851
         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 */
852
         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 */
853
      }
854
      switch( rm_gain )
855
      {
856
         case 1: *y = *y - ( *y >> 3 ) ; break; /* error: 0.3324970678 */
857
         case 2: *y = *y + ( *y >> 2 ) - ( *y >> 4 ) ; break; /* error: 0.0199970678 */
858
         case 3: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 6 ) ; break; /* error: 0.0043720678 */
859
         case 4: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) ; break; /* error: 0.0004658178 */
860
         case 5: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) - ( *y >> 12 ) ; break; /* error: 0.0007099584 */
861
         case 6: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 15 ) ; break; /* error: 0.0000080541 */
862
         case 7: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) ; break; /* error: 0.0000004247 */
863
         case 8: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) - ( *y >> 22 ) ; break; /* error: 0.0000006631 */
864
         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 */
865
         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 */
866
         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 */
867
         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 */
868
      }
869
   }
870
}
871
 

powered by: WebSVN 2.1.0

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