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

Subversion Repositories kvcordic

[/] [kvcordic/] [trunk/] [sw/] [cordic.c] - Rev 2

Compare with Previous | Blame | View Log

//
// Filename: cordic.c
// Purpose : N-address code (NAC) implementation for a fixed-point universal 
//           CORDIC. The arithmetic representation used is signed fixed-point 
//           (Q2.14S). The implementation has been generated by a modified 
//           version of the simple fixed-point CORDIC tools from:
//           http://www.dcs.gla.ac.uk/~jhw/cordic/
// Author  : Nikolaos Kavvadias (C) 2010
// Date    : 31-Oct-2010
// Revision: 0.3.0 (31/10/10)
//           Initial version.
//           0.3.1 (08/11/10)
//           Description of the universal CORDIC algorithm is finalized.
// 
#include <stdio.h>
#include <math.h>
 
#define ROTATION   0
#define VECTORING  1
#define CIRCULAR   0
#define LINEAR     1
#define HYPERBOLIC 2
 
typedef short int integer;
//typedef integer int;
 
//Cordic in 16 bit signed fixed point math
//Function is valid for arguments in range -pi/2 -- pi/2
//for values pi/2--pi: value = half_pi-(theta-half_pi) and similarly for values -pi---pi/2
//
// 1.0 = 16384
// 1/k = 0.6072529350088812561694
// pi = 3.1415926536897932384626
//Constants
#define MY_PI 3.1415926536897932384626
// Q2.14S
#define cordic_1K 9949
#define cordic_1Kp 19783
#define half_pi 25735
#define MUL 16384.000000
#define CORDIC_NTAB 14
integer cordic_tab[3*CORDIC_NTAB] = {
  65535 /* NOT USED */, 8999, 4184, 2058, 1025, 512, 256, 128, 64, 32, 16, 8, 4, 2, /* HYPERBOLIC */
  16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2,                /* LINEAR */
  12867, 7596, 4013, 2037, 1022, 511, 255, 127, 63, 31, 15, 7, 3, 1                 /* CIRCULAR */
};
// for convergence in hyperbolic mode, steps 4 and 13 must be repeated
integer cordic_hyp_steps[] = {
//	1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
	1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13
};
integer gdirection; // {0: ROTATION, 1: VECTORING}
integer gmode; // {0: CIRCULAR, 1: LINEAR, 2: HYPERBOLIC}
 
void cordicopt(integer direction, integer mode, integer xin, integer yin, integer zin, integer *xout, integer *yout, integer *zout)
{
  integer k, kk, d, x1, x2, y1, y2, z1, z2;
  integer x, y, z;
  integer kstart, kfinal, xbyk, ybyk, tabval;
  integer offset;
 
  x = xin;
  y = yin;
  z = zin;
  offset = ((mode == HYPERBOLIC) ? 0 : ((mode == LINEAR) ? 14 : 28));
  kfinal = ((mode != HYPERBOLIC) ? CORDIC_NTAB : CORDIC_NTAB+1);
  for (k = 0; k < kfinal; k++)
  {
    d = ((direction == ROTATION) ? ((z>=0) ? 0 : 1) : ((y<0) ? 0 : 1));
    kk = ((mode != HYPERBOLIC) ? k : cordic_hyp_steps[k]);
    xbyk = (x>>kk);
    ybyk = ((mode == HYPERBOLIC) ? -(y>>kk) : ((mode == LINEAR) ? 0 : (y>>kk)));
    tabval = cordic_tab[kk+offset];
    x1 = x - ybyk;
    x2 = x + ybyk;
    y1 = y + xbyk;
    y2 = y - xbyk;
    z1 = z - tabval;
    z2 = z + tabval;
    x = ((d == 0) ? x1 : x2);
    y = ((d == 0) ? y1 : y2);
    z = ((d == 0) ? z1 : z2);
  }  
  *xout = x;
  *yout = y;
  *zout = z;
}
 
int main(int argc, char **argv)
{
  double p;
  integer x1, y1, z1, x2, y2, z2, i, temp;   
  integer w1;
 
  // ROTATION, SIN/COS
#ifndef DATAGEN
  printf("SINE, COSINE\n");
#endif
  gdirection = ROTATION; gmode = CIRCULAR;
  x1 = cordic_1K; y1 = 0;
  for (i = 0; i < 50; i++)
  {
    p = (i/50.0)*MY_PI/2;        
    z1 = (integer)(p * MUL);
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
#ifdef DATAGEN    
// Use this to generate the "cordic_test_data.txt" reference vectors.
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", 
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
#else
// Use this to compare floating-point (math.h) against CORDIC fixed-point
// results.
    printf("%f : cos=%f (%f), sin=%f (%f)\n", p, x2/MUL, cos(p), y2/MUL, sin(p));
#endif    
  }       
 
  // VECTORING, ATAN
#ifndef DATAGEN
  printf("\nARCTAN\n");
#endif
  gdirection = VECTORING; gmode = CIRCULAR;
  z1 = 0;
  for (x1 = 0; x1 <= 7000; x1+=500)
  {
    for (y1 = 0; y1 <= 7000; y1+=500)
    { 
      cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
#ifdef DATAGEN    
// Use this to generate the "cordic_test_data.txt" reference vectors.
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", 
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
#else
// Use this to compare floating-point (math.h) against CORDIC fixed-point
// results.
      printf("%d/%d: atan=%f (%f), y2 = %d\n", y1, x1, z2/MUL, atan((double)y1/x1), y2);
#endif
    }
  }       
 
  // HYPERBOLIC, VECTORING, SQUARE ROOT
#ifndef DATAGEN
  printf("\nSQUARE ROOT\n");
#endif
  gdirection = VECTORING; gmode = HYPERBOLIC;
  z1 = 0;
  for (w1 = 100; w1 <= 7000; w1+=100)
  {
     x1 = w1+(1<<12);
     y1 = w1-(1<<12);
     cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
#ifdef DATAGEN    
// Use this to generate the "cordic_test_data.txt" reference vectors.
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", 
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
#else
// Use this to compare floating-point (math.h) against CORDIC fixed-point
// results.
    printf("%d: sqrt=%f (%f)\n", w1, (cordic_1Kp/MUL)*x2/MUL, sqrt((double)w1/MUL));
#endif
  } 
 
  // LINEAR, VECTORING, RECIPROCAL
#ifndef DATAGEN
  printf("\nRECIPROCAL\n");
#endif
  gdirection = VECTORING; gmode = LINEAR;
  z1 = 0;
  y1 = (1<<14);
  for (x1 = 32000; x1 > 8000; x1-=250)
  {
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
#ifdef DATAGEN    
// Use this to generate the "cordic_test_data.txt" reference vectors.
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", 
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
#else
// Use this to compare floating-point (math.h) against CORDIC fixed-point
// results.
    printf("%d: 1/x=%f (%f)\n", x1, z2/MUL, (double)y1/x1);
#endif
  } 
 
  // HYPERBOLIC, VECTORING, SQUARE ROOT + LINEAR, VECTORING, RECIPROCAL
#ifndef DATAGEN
  printf("\nINVERSE SQUARE ROOT\n");
#endif
  for (w1 = 4000; w1 <= 28600; w1+=200)
  {
    gdirection = VECTORING; gmode = HYPERBOLIC; 
    z1 = 0;
    x1 = w1+(1<<12);
    y1 = w1-(1<<12);
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
#ifdef DATAGEN    
// Use this to generate the "cordic_test_data.txt" reference vectors.
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", 
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
#else
// Use this to compare floating-point (math.h) against CORDIC fixed-point
// results.
    printf("%d: sqrt=%f (%f)\n", w1, (cordic_1Kp/MUL)*x2/MUL, sqrt((double)w1/MUL));
#endif
    gdirection = VECTORING; gmode = LINEAR; 
    z1 = 0; 
    y1 = (1<<14); 
    x1 = (cordic_1Kp/MUL)*x2;
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
#ifdef DATAGEN    
// Use this to generate the "cordic_test_data.txt" reference vectors.
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", 
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
#else
// Use this to compare floating-point (math.h) against CORDIC fixed-point
// results.
    printf("%d: 1/sqrt(x)=%f (%f)\n", w1, z2/MUL, sqrt((double)MUL/w1));
#endif
  } 
  return (0);
}
 

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.