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

Subversion Repositories kvcordic

[/] [kvcordic/] [trunk/] [sw/] [cordic.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 kavi
//
2
// Filename: cordic.c
3
// Purpose : N-address code (NAC) implementation for a fixed-point universal 
4
//           CORDIC. The arithmetic representation used is signed fixed-point 
5
//           (Q2.14S). The implementation has been generated by a modified 
6
//           version of the simple fixed-point CORDIC tools from:
7
//           http://www.dcs.gla.ac.uk/~jhw/cordic/
8
// Author  : Nikolaos Kavvadias (C) 2010
9
// Date    : 31-Oct-2010
10
// Revision: 0.3.0 (31/10/10)
11
//           Initial version.
12
//           0.3.1 (08/11/10)
13
//           Description of the universal CORDIC algorithm is finalized.
14
// 
15
#include <stdio.h>
16
#include <math.h>
17
 
18
#define ROTATION   0
19
#define VECTORING  1
20
#define CIRCULAR   0
21
#define LINEAR     1
22
#define HYPERBOLIC 2
23
 
24
typedef short int integer;
25
//typedef integer int;
26
 
27
//Cordic in 16 bit signed fixed point math
28
//Function is valid for arguments in range -pi/2 -- pi/2
29
//for values pi/2--pi: value = half_pi-(theta-half_pi) and similarly for values -pi---pi/2
30
//
31
// 1.0 = 16384
32
// 1/k = 0.6072529350088812561694
33
// pi = 3.1415926536897932384626
34
//Constants
35
#define MY_PI 3.1415926536897932384626
36
// Q2.14S
37
#define cordic_1K 9949
38
#define cordic_1Kp 19783
39
#define half_pi 25735
40
#define MUL 16384.000000
41
#define CORDIC_NTAB 14
42
integer cordic_tab[3*CORDIC_NTAB] = {
43
  65535 /* NOT USED */, 8999, 4184, 2058, 1025, 512, 256, 128, 64, 32, 16, 8, 4, 2, /* HYPERBOLIC */
44
  16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2,                /* LINEAR */
45
  12867, 7596, 4013, 2037, 1022, 511, 255, 127, 63, 31, 15, 7, 3, 1                 /* CIRCULAR */
46
};
47
// for convergence in hyperbolic mode, steps 4 and 13 must be repeated
48
integer cordic_hyp_steps[] = {
49
//      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
50
        1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13
51
};
52
integer gdirection; // {0: ROTATION, 1: VECTORING}
53
integer gmode; // {0: CIRCULAR, 1: LINEAR, 2: HYPERBOLIC}
54
 
55
void cordicopt(integer direction, integer mode, integer xin, integer yin, integer zin, integer *xout, integer *yout, integer *zout)
56
{
57
  integer k, kk, d, x1, x2, y1, y2, z1, z2;
58
  integer x, y, z;
59
  integer kstart, kfinal, xbyk, ybyk, tabval;
60
  integer offset;
61
 
62
  x = xin;
63
  y = yin;
64
  z = zin;
65
  offset = ((mode == HYPERBOLIC) ? 0 : ((mode == LINEAR) ? 14 : 28));
66
  kfinal = ((mode != HYPERBOLIC) ? CORDIC_NTAB : CORDIC_NTAB+1);
67
  for (k = 0; k < kfinal; k++)
68
  {
69
    d = ((direction == ROTATION) ? ((z>=0) ? 0 : 1) : ((y<0) ? 0 : 1));
70
    kk = ((mode != HYPERBOLIC) ? k : cordic_hyp_steps[k]);
71
    xbyk = (x>>kk);
72
    ybyk = ((mode == HYPERBOLIC) ? -(y>>kk) : ((mode == LINEAR) ? 0 : (y>>kk)));
73
    tabval = cordic_tab[kk+offset];
74
    x1 = x - ybyk;
75
    x2 = x + ybyk;
76
    y1 = y + xbyk;
77
    y2 = y - xbyk;
78
    z1 = z - tabval;
79
    z2 = z + tabval;
80
    x = ((d == 0) ? x1 : x2);
81
    y = ((d == 0) ? y1 : y2);
82
    z = ((d == 0) ? z1 : z2);
83
  }
84
  *xout = x;
85
  *yout = y;
86
  *zout = z;
87
}
88
 
89
int main(int argc, char **argv)
90
{
91
  double p;
92
  integer x1, y1, z1, x2, y2, z2, i, temp;
93
  integer w1;
94
 
95
  // ROTATION, SIN/COS
96
#ifndef DATAGEN
97
  printf("SINE, COSINE\n");
98
#endif
99
  gdirection = ROTATION; gmode = CIRCULAR;
100
  x1 = cordic_1K; y1 = 0;
101
  for (i = 0; i < 50; i++)
102
  {
103
    p = (i/50.0)*MY_PI/2;
104
    z1 = (integer)(p * MUL);
105
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
106
#ifdef DATAGEN    
107
// Use this to generate the "cordic_test_data.txt" reference vectors.
108
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
109
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
110
#else
111
// Use this to compare floating-point (math.h) against CORDIC fixed-point
112
// results.
113
    printf("%f : cos=%f (%f), sin=%f (%f)\n", p, x2/MUL, cos(p), y2/MUL, sin(p));
114
#endif    
115
  }
116
 
117
  // VECTORING, ATAN
118
#ifndef DATAGEN
119
  printf("\nARCTAN\n");
120
#endif
121
  gdirection = VECTORING; gmode = CIRCULAR;
122
  z1 = 0;
123
  for (x1 = 0; x1 <= 7000; x1+=500)
124
  {
125
    for (y1 = 0; y1 <= 7000; y1+=500)
126
    {
127
      cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
128
#ifdef DATAGEN    
129
// Use this to generate the "cordic_test_data.txt" reference vectors.
130
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
131
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
132
#else
133
// Use this to compare floating-point (math.h) against CORDIC fixed-point
134
// results.
135
      printf("%d/%d: atan=%f (%f), y2 = %d\n", y1, x1, z2/MUL, atan((double)y1/x1), y2);
136
#endif
137
    }
138
  }
139
 
140
  // HYPERBOLIC, VECTORING, SQUARE ROOT
141
#ifndef DATAGEN
142
  printf("\nSQUARE ROOT\n");
143
#endif
144
  gdirection = VECTORING; gmode = HYPERBOLIC;
145
  z1 = 0;
146
  for (w1 = 100; w1 <= 7000; w1+=100)
147
  {
148
     x1 = w1+(1<<12);
149
     y1 = w1-(1<<12);
150
     cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
151
#ifdef DATAGEN    
152
// Use this to generate the "cordic_test_data.txt" reference vectors.
153
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
154
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
155
#else
156
// Use this to compare floating-point (math.h) against CORDIC fixed-point
157
// results.
158
    printf("%d: sqrt=%f (%f)\n", w1, (cordic_1Kp/MUL)*x2/MUL, sqrt((double)w1/MUL));
159
#endif
160
  }
161
 
162
  // LINEAR, VECTORING, RECIPROCAL
163
#ifndef DATAGEN
164
  printf("\nRECIPROCAL\n");
165
#endif
166
  gdirection = VECTORING; gmode = LINEAR;
167
  z1 = 0;
168
  y1 = (1<<14);
169
  for (x1 = 32000; x1 > 8000; x1-=250)
170
  {
171
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
172
#ifdef DATAGEN    
173
// Use this to generate the "cordic_test_data.txt" reference vectors.
174
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
175
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
176
#else
177
// Use this to compare floating-point (math.h) against CORDIC fixed-point
178
// results.
179
    printf("%d: 1/x=%f (%f)\n", x1, z2/MUL, (double)y1/x1);
180
#endif
181
  }
182
 
183
  // HYPERBOLIC, VECTORING, SQUARE ROOT + LINEAR, VECTORING, RECIPROCAL
184
#ifndef DATAGEN
185
  printf("\nINVERSE SQUARE ROOT\n");
186
#endif
187
  for (w1 = 4000; w1 <= 28600; w1+=200)
188
  {
189
    gdirection = VECTORING; gmode = HYPERBOLIC;
190
    z1 = 0;
191
    x1 = w1+(1<<12);
192
    y1 = w1-(1<<12);
193
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
194
#ifdef DATAGEN    
195
// Use this to generate the "cordic_test_data.txt" reference vectors.
196
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
197
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
198
#else
199
// Use this to compare floating-point (math.h) against CORDIC fixed-point
200
// results.
201
    printf("%d: sqrt=%f (%f)\n", w1, (cordic_1Kp/MUL)*x2/MUL, sqrt((double)w1/MUL));
202
#endif
203
    gdirection = VECTORING; gmode = LINEAR;
204
    z1 = 0;
205
    y1 = (1<<14);
206
    x1 = (cordic_1Kp/MUL)*x2;
207
    cordic(gdirection, gmode, x1, y1, z1, &x2, &y2, &z2);
208
#ifdef DATAGEN    
209
// Use this to generate the "cordic_test_data.txt" reference vectors.
210
    printf("%04x %04x %04x %04x %04x %04x %04x %04x\n",
211
      gdirection, gmode, x1&0xffff, y1&0xffff, z1&0xffff, x2&0xffff, y2&0xffff, z2&0xffff);
212
#else
213
// Use this to compare floating-point (math.h) against CORDIC fixed-point
214
// results.
215
    printf("%d: 1/sqrt(x)=%f (%f)\n", w1, z2/MUL, sqrt((double)MUL/w1));
216
#endif
217
  }
218
  return (0);
219
}

powered by: WebSVN 2.1.0

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