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

Subversion Repositories yac

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

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

powered by: WebSVN 2.1.0

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