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

Subversion Repositories yac

[/] [yac/] [trunk/] [c_octave/] [cordic_iterative.c] - Rev 12

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

/***************************************************************************
*                                                                          *
*  File           : cordic_iterative.c                                     *
*  Project        : YAC (Yet Another CORDIC Core)                          *
*  Creation       : Feb. 2014                                              *
*  Limitations    :                                                        *
*  Platform       : Linux, Mac, Windows                                    *
*  Target         : Octave, Matlab, Standalone-Application                 *
*                                                                          *
*  Author(s):     : Christian Haettich                                     *
*  Email          : feddischson@opencores.org                              *
*                                                                          *
*                                                                          *
**                                                                        **
*                                                                          *
*  Description                                                             *
*     C-implementation of an interative cordic.                            *
*     General information about the CORDIC algorithm can be found          *
*     here: - http://en.wikipedia.org/wiki/CORDIC                          *
*           - http://en.wikibooks.org/wiki/Digital_Circuits/CORDIC         *
*                                                                          *
*                                                                          *
**                                                                        **
*                                                                          *
*  TODO                                                                    *
*        Some documentation and function description                       *
*                                                                          *
*                                                                          *
*                                                                          *
*                                                                          *
****************************************************************************
*                                                                          *
*                     Copyright Notice                                     *
*                                                                          *
*    This file is part of YAC - Yet Another CORDIC Core                    *
*    Copyright (c) 2014, Author(s), All rights reserved.                   *
*                                                                          *
*    YAC is free software; you can redistribute it and/or                  *
*    modify it under the terms of the GNU Lesser General Public            *
*    License as published by the Free Software Foundation; either          *
*    version 3.0 of the License, or (at your option) any later version.    *
*                                                                          *
*    YAC is distributed in the hope that it will be useful,                *
*    but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
*    Lesser General Public License for more details.                       *
*                                                                          *
*    You should have received a copy of the GNU Lesser General Public      *
*    License along with this library. If not, download it from             *
*    http://www.gnu.org/licenses/lgpl                                      *
*                                                                          *
***************************************************************************/
 
 
 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
#ifndef OR32_TARGET
 #include "mex.h"
#endif 
 
/* enable debug output */
<<<<<<< HEAD
<<<<<<< HEAD
#define PRINT_DEBUG        0
=======
#define PRINT_DEBUG  0
>>>>>>> initial commit
=======
#define PRINT_DEBUG        0
>>>>>>> Updated C and RTL model as well as the documentation
 
/* #define CORDIC_ROUNDING    0.5 */
#define CORDIC_ROUNDING    0.0
 
 
/* the supported modes */
#define C_FLAG_VEC_ROT     0x08
#define C_FLAG_ATAN_3      0x04
#define C_MODE_MSK         0x03
#define C_MODE_CIR         0x00
#define C_MODE_LIN         0x01
#define C_MODE_HYP         0x02
 
 
#ifndef OR32_TARGET
 #define PRINT  mexPrintf
#endif
 
 
<<<<<<< HEAD
<<<<<<< HEAD
=======
 
long long int ov_check( long long int * value, long long int length )
{
   long long int mask = (1<<length)-1;
   long long int result = 0;
   long long int min = -((long long int)1<<length);
   long long int max =  ((long long int)1<<length);
   if( *value > max || *value < min )
       result = *value;
   /* *value &= mask; */
   return result;
}
 
 
 
>>>>>>> initial commit
=======
>>>>>>> Updated C and RTL model as well as the documentation
void cordic_int( long long int   x_i, 
                 long long int   y_i,
                 long long int   a_i,
                 long long int * x_o,
                 long long int * y_o,
                 long long int * a_o,
                 int           * it_o,
                 int        mode,
                 int        XY_WIDTH,
                 int        A_WIDTH,
                 int        GUARD_BITS,
                 int        RM_GAIN );
void           cordic_int_dbg    ( long long int x,
                                   long long int y,
                                   long long int a,
                                   int           mode,
                                   int           it,
                                   char*         msg );
int            cordic_int_init   ( long long int *x,
                                   long long int *y,
                                   long long int *a,
                                   int           mode, 
<<<<<<< HEAD
<<<<<<< HEAD
                                   int           A_WIDTH, 
                                   int           XY_WIDTH );
=======
                                   int           A_WIDTH );
>>>>>>> initial commit
=======
                                   int           A_WIDTH, 
                                   int           XY_WIDTH );
>>>>>>> Updated C and RTL model as well as the documentation
void           cordic_int_rm_gain( long long int *x, 
                                   long long int *y,
                                   int           mode,
                                   int           rm_gain );
int            cordic_int_rotate(  long long int * x, 
                                   long long int * y, 
                                   long long int * a, 
                                   int             mode,
                                   int             A_WIDTH );
long long int  cordic_int_lut    ( int             mode, 
                                   int             it,
                                   int             A_WIDTH );
 
 
 
#ifndef OR32_TARGET
 
 
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
   double *inx,*iny,*inz,*outx,*outy,*outz,*outi;
   double mode;
   double xy_width;
   double a_width;
   double guard_bits;
   double rm_gain;
 
   int mrowsx,ncolsx,mrowsy,ncolsy,mrowsz,ncolsz;
   int i;
   int it;
   if(nrhs!=8 )
      mexErrMsgTxt("8 input arguments required");
   if(nlhs!=4)
      mexErrMsgTxt("4 output arguments required");
 
   if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]))
      mexErrMsgTxt("Input x must be double and non-complex");
 
   if (!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]))
      mexErrMsgTxt("Input y must be double and non-complex");
 
   if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]))
      mexErrMsgTxt("Input a must be double and non-complex");
 
   mrowsx = mxGetM(prhs[0]);
   ncolsx = mxGetN(prhs[0]);
   mrowsy = mxGetM(prhs[1]);
   ncolsy = mxGetN(prhs[1]);
   mrowsz = mxGetM(prhs[2]);
   ncolsz = mxGetN(prhs[2]);
 
 
 
   if (mrowsx > 1 || mrowsy >1 || mrowsz > 1)
       mexErrMsgTxt("Input vector must have the size Nx1.");
 
   /* printf("%d %d %d\n", ncolsx, ncolsy, ncolsa); */
 
   if (ncolsx!=ncolsy || ncolsx!=ncolsz || ncolsy!=ncolsz)
       mexErrMsgTxt("Input vectors don't have the same length!");
 
 
   plhs[0] = mxCreateDoubleMatrix(mrowsx,ncolsx,mxREAL);
   plhs[1] = mxCreateDoubleMatrix(mrowsy,ncolsy,mxREAL);
   plhs[2] = mxCreateDoubleMatrix(mrowsz,ncolsz,mxREAL);
   plhs[3] = mxCreateDoubleMatrix(mrowsz,ncolsz,mxREAL);
 
   inx         = mxGetPr(prhs[0]);
   iny         = mxGetPr(prhs[1]);
   inz         = mxGetPr(prhs[2]);
   mode        = mxGetScalar(prhs[3]);
   xy_width    = mxGetScalar(prhs[4]);
   a_width     = mxGetScalar(prhs[5]);
   guard_bits  = mxGetScalar(prhs[6]);
   rm_gain     = mxGetScalar(prhs[7]);
 
   outx= mxGetPr(plhs[0]);
   outy= mxGetPr(plhs[1]); 
   outz= mxGetPr(plhs[2]);
   outi= mxGetPr(plhs[3]);
 
   for( i = 0; i < ncolsx; i++ )
   {
        long long int inx_i = inx[ i ];
        long long int iny_i = iny[ i ];
        long long int inz_i = inz[ i ];
        long long int outx_i = 0;
        long long int outy_i = 0;
        long long int outz_i = 0;
/*        PRINT("x: %lld, y: %lld, a: %lld\n", inx_i, iny_i, inz_i ); */
 
        cordic_int(   inx_i,    iny_i,   inz_i,  
                        &outx_i, &outy_i, &outz_i,
                         &it, mode, 
                         xy_width, a_width, guard_bits, rm_gain );
        outx[i] = outx_i;
        outy[i] = outy_i;
        outz[i] = outz_i;
        outi[i] = it;
 
 
   }
}
 
#endif
 
 
 
 
void cordic_int( long long int   x_i, 
                 long long int   y_i,
                 long long int   a_i,
                 long long int * x_o,
                 long long int * y_o,
                 long long int * a_o,
                 int           * it_o,
                 int        mode,
                 int        XY_WIDTH,
                 int        A_WIDTH,
                 int        GUARD_BITS,
                 int        RM_GAIN )
{
   long long int x;
   long long int y;
   long long int a;
   long long int s;
   int ov;
<<<<<<< HEAD
<<<<<<< HEAD
   int it = 0;
=======
   int it;
>>>>>>> initial commit
=======
   int it = 0;
>>>>>>> Updated C and RTL model as well as the documentation
 
 
 
 
   /* total with, including guard bits */
   int XY_WIDTH_G = XY_WIDTH + GUARD_BITS;
 
   cordic_int_dbg( x_i, y_i, a_i, mode, 0, "input" );
 
<<<<<<< HEAD
<<<<<<< HEAD
   if( !cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH, XY_WIDTH ) )
   {
 
      it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
 
      cordic_int_rm_gain( &x_i, &y_i, mode, RM_GAIN );
   }
=======
   cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH );
 
   it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
=======
   if( !cordic_int_init( &x_i, &y_i, &a_i, mode, A_WIDTH, XY_WIDTH ) )
   {
>>>>>>> Updated C and RTL model as well as the documentation
 
      it = cordic_int_rotate( &x_i, &y_i, &a_i, mode, A_WIDTH );
 
<<<<<<< HEAD
>>>>>>> initial commit
=======
      cordic_int_rm_gain( &x_i, &y_i, mode, RM_GAIN );
   }
>>>>>>> Updated C and RTL model as well as the documentation
 
   *x_o  = x_i;
   *y_o  = y_i;
   *a_o  = a_i;
   *it_o = it;
 
}
 
 
 
 
 
 
 
int cordic_int_init( long long int *x,
                     long long int *y,
                     long long int *a,
                     int           mode,
<<<<<<< HEAD
<<<<<<< HEAD
                     int           A_WIDTH,
                     int           XY_WIDTH )
=======
                     int           A_WIDTH )
>>>>>>> initial commit
=======
                     int           A_WIDTH,
                     int           XY_WIDTH )
>>>>>>> Updated C and RTL model as well as the documentation
{
   int already_done = 0;
 
 
   long long int PI   = ( long long int )( M_PI * pow( 2, A_WIDTH-1 ) + 0.5 );
   long long int PI_H = (long long int)(  M_PI * pow( 2, A_WIDTH-2 ) + 0.5  );
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
 
   long long int XY_MAX = pow( 2, XY_WIDTH-1 )-1;
 
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
 
 
=======
 
 
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
>>>>>>> initial commit
=======
 
=======
 
>>>>>>> Removed some bugs regarding pre-rotation and negative numbers in the wb wrapper
   long long int XY_MAX = pow( 2, XY_WIDTH-1 )-1;
 
   cordic_int_dbg( *x, *y, *a, mode, 0, "before init" );
 
 
<<<<<<< HEAD
>>>>>>> Updated C and RTL model as well as the documentation
=======
   if( 0 != ( mode &  C_FLAG_VEC_ROT ) && *y == 0 )
   {
       already_done = 1;
       *a = 0;
       #if PRINT_DEBUG > 0
       PRINT( "Zero input, skipping rotations \n" );
       #endif
   }
   else if( 0 == ( mode &  C_FLAG_VEC_ROT )  && *a == 0 )
   {
       #if PRINT_DEBUG > 0
       PRINT("zero angular input\n" );
       #endif
       already_done = 1;
   }
 
>>>>>>> Removed some bugs regarding pre-rotation and negative numbers in the wb wrapper
   /* Circular rotation mode */
   else if( 0          == ( mode &  C_FLAG_VEC_ROT )    &&
       C_MODE_CIR == ( mode &  C_MODE_MSK     )  )
   {
 
 
      /* move from third quadrant to first 
         quadrant if necessary */
      if( *a <  - PI_H )
      {
          if( ! (mode & C_FLAG_ATAN_3) )
             *a += PI;
          *x  = -*x;
          *y  = -*y;
          #if PRINT_DEBUG > 0
          PRINT("move from third quadrand"); 
          #endif
      }
      /* move from second quadrant to fourth 
         quadrant if necessary */
      else if( *a > PI_H )
      {
          if( ! (mode & C_FLAG_ATAN_3) )
             *a -= PI;
          *x  = -*x;
          *y  = -*y;
          #if PRINT_DEBUG > 0
          PRINT("move from second quadrand\n" );
          #endif
      }
   }
 
   /* circular vector mode */
   else if ( 0          != ( mode &  C_FLAG_VEC_ROT )    &&
             C_MODE_CIR == ( mode &  C_MODE_MSK     )  )
   {
<<<<<<< HEAD
<<<<<<< HEAD
=======
>>>>>>> Updated C and RTL model as well as the documentation
 
      if( *x == XY_MAX && *y == XY_MAX )
      {
         #if PRINT_DEBUG > 0
         PRINT( "All max, skipping rotations 1\n" );
         #endif
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
         *y = 0;
         *a = cordic_int_lut( mode, 0, A_WIDTH );
         already_done = 1;
      }
      else if( *x == -XY_MAX && *y == -XY_MAX )
      {
         #if PRINT_DEBUG > 0
         PRINT( "All max, skipping rotations 2\n" );
         #endif
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
         *y = 0;
         *a = cordic_int_lut( mode, 0, A_WIDTH ) - PI;
         already_done = 1;
      }
      else if( *x ==  XY_MAX && *y == -XY_MAX )
      {
         #if PRINT_DEBUG > 0
         PRINT( "All max, skipping rotations 3\n" );
         #endif
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
         *y = 0;
         *a = -cordic_int_lut( mode, 0, A_WIDTH );
         already_done = 1;
      }
      else if( *x == -XY_MAX && *y ==  XY_MAX )
      {
         #if PRINT_DEBUG > 0
         PRINT( "All max, skipping rotations 4\n" );
         #endif
         *x = sqrt( 2 ) * pow( 2, XY_WIDTH-1 ) + 0.5;
         *y = 0;
         *a = PI - cordic_int_lut( mode, 0, A_WIDTH );
         already_done = 1;
      }
 
 
 
      else if( *x == 0 && *y > 0 ) 
      {
         *a = PI_H;
         *x = *y;
         already_done = 1;
         #if PRINT_DEBUG > 0
         PRINT( "Fixed value of pi/2, skipping rotations\n" );
         #endif
         *y = 0;
      }
      else if( *x == 0 && *y < 0 ) 
      {
         *a = -PI_H;
         *x = -*y;
         *y = 0;
         already_done = 1;
         #if PRINT_DEBUG > 0
         PRINT( "Fixed value of -pi/2, skipping rotations\n" );
         #endif
      }
      else if( *x < 0  && *y >= 0 )
<<<<<<< HEAD
=======
      if( *x < 0 && *y > 0 )
>>>>>>> initial commit
=======
>>>>>>> Updated C and RTL model as well as the documentation
      {
         *x = -*x;
         *y = -*y;
         *a =  PI;
          #if PRINT_DEBUG > 0
<<<<<<< HEAD
<<<<<<< HEAD
          PRINT("pre-rotation from second to the fourth quadrant\n" );
          #endif
      }
      else if( *x < 0 && *y <  0 )
=======
          PRINT("align from second quadrand\n" );
          #endif
      }
      else if( *x < 0 && *y < 0 )
>>>>>>> initial commit
=======
          PRINT("pre-rotation from second to the fourth quadrant\n" );
          #endif
      }
      else if( *x < 0 && *y <  0 )
>>>>>>> Updated C and RTL model as well as the documentation
      {
         *x = -*x;
         *y = -*y;
         *a = -PI;
          #if PRINT_DEBUG > 0
<<<<<<< HEAD
<<<<<<< HEAD
          PRINT("pre-rotation from third to first quadrand\n" );
          #endif
      }
=======
          PRINT("align from third quadrand\n" );
          #endif
      }
      else if( *x < 0 && *y == 0 )
      {
         *a           = PI;
         already_done = 1;
      }
>>>>>>> initial commit
=======
          PRINT("pre-rotation from third to first quadrand\n" );
          #endif
      }
>>>>>>> Updated C and RTL model as well as the documentation
      else
         *a = 0;
   }
   /* linear vector mode */
   else if ( 0          != ( mode &  C_FLAG_VEC_ROT )    &&
             C_MODE_LIN == ( mode &  C_MODE_MSK     )  )
   {
      if( *x < 0 )
      {
         *x = -*x;
         *y = -*y;
      }
      *a = 0;
   }
   cordic_int_dbg( *x, *y, *a, mode, 0, "after init" );
<<<<<<< HEAD
<<<<<<< HEAD
   return already_done; 
=======
 
>>>>>>> initial commit
=======
   return already_done; 
>>>>>>> Updated C and RTL model as well as the documentation
}
 
 
 
void cordic_int_dbg(  long long int x,
                     long long int y,
                     long long int a,
                     int           mode,
                     int           it,
                     char*         msg )
{
   #if PRINT_DEBUG > 0
   PRINT( "%20s: mode = %d, iteration %d, x = % 10.lld, y = %10.lld, a = %10.lld \n",
           msg,mode,it,x,y,a );
   #endif
}
 
int cordic_int_repeat( iteration, mode )
{
   int i = 4;
 
   if( C_MODE_HYP != ( mode & C_MODE_MSK ) )
      return 0;
 
 
   while( 1 )
   {
      if( i == iteration )
          return 1;
      else if( i > iteration )
          return 0;
      i = i * 3 + 1;
   }
}
 
 
 
 
int cordic_int_rotate( long long int * x, 
                       long long int * y, 
                       long long int * a, 
                       int             mode,
                       int             A_WIDTH )
{
   int it = 0;
   long long int xsh, ysh;
   long long int ylst, alst;
   int sign;
   int repeat = 0;
 
   while( 1 )
   {
      /* get the sign */
      if( 0 == ( mode & C_FLAG_VEC_ROT ) )
          sign =  ( *a >= 0 );
      else
          sign = !( *y >= 0 );
 
      /* shift operation: hyperbolic case*/
      if( C_MODE_HYP == ( mode & C_MODE_MSK ) )
      {
         xsh = *x >> (it+1);
         ysh = *y >> (it+1);
      }
      /* shift operation: circular and linear case*/
      else
      {
         xsh = *x >> it;
         ysh = *y >> it;
      }
 
      if( sign == 1 )
      {
         *a -= cordic_int_lut( mode, it, A_WIDTH );
 
         if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
         {
            *x = *x - ysh;
            *y = *y + xsh;
         }
         else
         if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
         {
            *x = *x;
            *y = *y + xsh;
         }
         else
         {
            *x = *x + ysh;
            *y = *y + xsh;
         }
      }
      else
      {
         *a += cordic_int_lut( mode, it, A_WIDTH );
         if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
         {
            *x = *x + ysh;
            *y = *y - xsh;
         }
         else
         if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
         {
            *x = *x;
            *y = *y - xsh;
         }
         else
         {
            *x = *x - ysh;
            *y = *y - xsh;
         }
      }
      cordic_int_dbg( *x, *y, *a, mode, it, "after rotation" );
 
      /* abort condition */
      if( ( mode & C_FLAG_VEC_ROT  ) == 0 && 
<<<<<<< HEAD
<<<<<<< HEAD
          ( *a == 0 /* || *a == -1 */ ) )
=======
          ( *a == 0 || *a == -1 ) )
>>>>>>> initial commit
=======
          ( *a == 0 /* || *a == -1 */ ) )
>>>>>>> Updated C and RTL model as well as the documentation
          break;
      if( ( mode & C_FLAG_VEC_ROT  ) == 0 && 
          ( *a == alst ) )
          break;
 
      if( ( mode & C_FLAG_VEC_ROT  ) != 0 && 
<<<<<<< HEAD
<<<<<<< HEAD
          ( *y == 0 /*|| *y == -1 */ ) )
=======
          ( *y == 0 || *y == -1 ) )
>>>>>>> initial commit
=======
          ( *y == 0 /*|| *y == -1 */ ) )
>>>>>>> Updated C and RTL model as well as the documentation
          break;
      if( ( mode & C_FLAG_VEC_ROT  ) != 0 && 
          ( *y == ylst ) )
          break;
 
      else if( it > 40 )
      {
#if PRINT_DEBUG
         PRINT( "ERROR: abort %lld %lld %lld %lld - %d - %d!\n", *a, alst, *y, ylst, mode, *y == ylst );
#endif
         it = -1;  
          break;
      }
 
 
      ylst = *y;
      alst = *a;
      if( repeat == 0 && cordic_int_repeat( it, mode ) )
      {
         repeat = 1;
         #if PRINT_DEBUG
         mexPrintf( "repeat it %d\n" , it );
         #endif
      }
      else
      {
         repeat = 0;
         it++;
      }
   }
   return it;
}
 
 
 
#define SCALE_VAL( _W_ )(  (double)( (long long int) 1 << (long long int)( _W_ -1 ) ) ) 
 
long long int cordic_int_lut( int mode, int it, int A_WIDTH )
{
   long long int lut_val;
   if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
   {
      if( it <= 10 )
         lut_val = (long long int)(   atan(  pow( 2, -it ) ) * pow( 2, A_WIDTH-1 ) );
      else
         lut_val = pow( 2, A_WIDTH-1-it ); /* (long long int)( SCALE_VAL( A_WIDTH-it ) ); */
   }
   else 
   if( C_MODE_LIN == ( mode & C_MODE_MSK ) )
   {
      lut_val =  (long long int)( 1.0 / (double)( ( long long int )1 << (long long int)it ) 
                                *  SCALE_VAL( A_WIDTH ) -1 );
   }
   else
   {
      lut_val = (long long int)( atanh( 1.0 / (double)( (long long int)1 << ( long long int )(it+1)  ) ) 
                                *  SCALE_VAL( A_WIDTH ) );
   }
   return lut_val;
}
 
 
 
 
/**
 *
 * Cordic gain: 
 *
 *
 *
 */
void cordic_int_rm_gain( long long int *x, 
                         long long int *y,
                         int mode,
                         int rm_gain )
{
   /* for the non-linear case: remove cordic gain if RM_GAIN > 0 */
   if( C_MODE_CIR == ( mode & C_MODE_MSK ) )
   {
 
 
      switch( rm_gain )
      {
         case 1: *x = + ( *x >> 1 ) ; break; /* error: 0.1072529350 */ 
         case 2: *x = + ( *x >> 1 ) - ( *x >> 4 ) ; break; /* error: 0.1697529350 */ 
         case 3: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 5 ) ; break; /* error: 0.0135029350 */ 
         case 4: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 8 ) ; break; /* error: 0.0017841850 */ 
         case 5: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 12 ) ; break; /* error: 0.0000752006 */ 
         case 6: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) ; break; /* error: 0.0000141655 */ 
         case 7: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) - ( *x >> 17 ) ; break; /* error: 0.0000217949 */ 
         case 8: *x = + ( *x >> 1 ) + ( *x >> 3 ) - ( *x >> 6 ) - ( *x >> 9 ) - ( *x >> 13 ) - ( *x >> 14 ) + ( *x >> 16 ) - ( *x >> 19 ) ; break; /* error: 0.0000008140 */ 
         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 */ 
         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 */ 
         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 */ 
         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 */ 
         default: *x = *x; break;
      }
      switch( rm_gain )
      {
         case 1: *y = + ( *y >> 1 ) ; break; /* error: 0.1072529350 */ 
         case 2: *y = + ( *y >> 1 ) - ( *y >> 4 ) ; break; /* error: 0.1697529350 */ 
         case 3: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 5 ) ; break; /* error: 0.0135029350 */ 
         case 4: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 8 ) ; break; /* error: 0.0017841850 */ 
         case 5: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 12 ) ; break; /* error: 0.0000752006 */ 
         case 6: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) ; break; /* error: 0.0000141655 */ 
         case 7: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) - ( *y >> 17 ) ; break; /* error: 0.0000217949 */ 
         case 8: *y = + ( *y >> 1 ) + ( *y >> 3 ) - ( *y >> 6 ) - ( *y >> 9 ) - ( *y >> 13 ) - ( *y >> 14 ) + ( *y >> 16 ) - ( *y >> 19 ) ; break; /* error: 0.0000008140 */ 
         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 */ 
         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 */ 
         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 */ 
         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 */ 
         default: *x = *y; break;
      }
 
   }
   else 
   if( C_MODE_HYP == ( mode & C_MODE_MSK ) )
   {
      switch( rm_gain )
      {
         case 1: *x = *x - ( *x >> 3 ) ; break; /* error: 0.3324970678 */ 
         case 2: *x = *x + ( *x >> 2 ) - ( *x >> 4 ) ; break; /* error: 0.0199970678 */ 
         case 3: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 6 ) ; break; /* error: 0.0043720678 */ 
         case 4: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) ; break; /* error: 0.0004658178 */ 
         case 5: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) - ( *x >> 12 ) ; break; /* error: 0.0007099584 */ 
         case 6: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 15 ) ; break; /* error: 0.0000080541 */ 
         case 7: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) ; break; /* error: 0.0000004247 */ 
         case 8: *x = *x + ( *x >> 2 ) - ( *x >> 5 ) - ( *x >> 7 ) - ( *x >> 8 ) + ( *x >> 11 ) - ( *x >> 16 ) - ( *x >> 17 ) - ( *x >> 22 ) ; break; /* error: 0.0000006631 */ 
         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 */ 
         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 */ 
         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 */ 
         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 */ 
      }
      switch( rm_gain )
      {
         case 1: *y = *y - ( *y >> 3 ) ; break; /* error: 0.3324970678 */ 
         case 2: *y = *y + ( *y >> 2 ) - ( *y >> 4 ) ; break; /* error: 0.0199970678 */ 
         case 3: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 6 ) ; break; /* error: 0.0043720678 */ 
         case 4: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) ; break; /* error: 0.0004658178 */ 
         case 5: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) - ( *y >> 12 ) ; break; /* error: 0.0007099584 */ 
         case 6: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 15 ) ; break; /* error: 0.0000080541 */ 
         case 7: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) ; break; /* error: 0.0000004247 */ 
         case 8: *y = *y + ( *y >> 2 ) - ( *y >> 5 ) - ( *y >> 7 ) - ( *y >> 8 ) + ( *y >> 11 ) - ( *y >> 16 ) - ( *y >> 17 ) - ( *y >> 22 ) ; break; /* error: 0.0000006631 */ 
         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 */ 
         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 */ 
         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 */ 
         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 */ 
      }
   }
}
 
 

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

powered by: WebSVN 2.1.0

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