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

# Subversion Repositorieskvcordic

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

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
}