1 |
6 |
root |
/* file: cordic.v
|
2 |
|
|
author: Dale Drinkard
|
3 |
|
|
release: 08/06/2008
|
4 |
|
|
|
5 |
|
|
brief:
|
6 |
|
|
|
7 |
|
|
First Quadrant CORDIC
|
8 |
|
|
|
9 |
|
|
This is a self contained, configurable CORDIC generator
|
10 |
|
|
The user can modify the `defines below to customize the code generation.
|
11 |
|
|
This code is for the first quadrant, but is easily extended to the full
|
12 |
|
|
circle by first doing a coarse rotation. For example, to compute the
|
13 |
|
|
arctan of -y/x, in the second quadrant, feed the cordic function y/x and
|
14 |
|
|
then add 90 degrees (or pi/2 if using radian mode) to the result. When
|
15 |
|
|
computing sin and cos of an angle, coarse rotate the angle into the first quadrant
|
16 |
|
|
by subtracting the appropriate number of 90 (or pi/2) increments to get the angle in
|
17 |
|
|
the first quadrant, keep track of this value, feed the cordic the angle. Then
|
18 |
|
|
simply change the sign of the results based on this stored number.
|
19 |
|
|
|
20 |
|
|
To use the core comment/uncomment the `defines below. The user can change the number
|
21 |
|
|
of bits that represent the x,y, and theta values. The core can operate in either radian
|
22 |
|
|
or degree mode.
|
23 |
|
|
**NOTE** Even though there are allowances for changeing many parameters of the code, it is
|
24 |
|
|
strongly advised that the user understand the CORDIC algorythm before monkeying with these
|
25 |
|
|
settings. By default, the core uses 16+sign (17 bit) numbers for x,y, and theta, and iterates 16
|
26 |
|
|
times in the algorythm. There are two arctan function tables,one for radian and one for degree
|
27 |
|
|
mode. If more iterations or higher precision calculations are desired then a new arctan table will
|
28 |
|
|
need to be computed.
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
The core will operate in one
|
32 |
|
|
of two modes:
|
33 |
|
|
|
34 |
|
|
|
35 |
|
|
ROTATE: In this mode the user supplies a X and Y cartesian vector and an angle. The
|
36 |
|
|
CORDIC rotator seeks to reduce the angle to zero by rotating the vector.
|
37 |
|
|
|
38 |
|
|
To compute the cos and sin of the angle, set the inputs as follows:
|
39 |
|
|
|
40 |
|
|
y_in = 0;
|
41 |
|
|
x_in = `CORDIC_1
|
42 |
|
|
theta_in = the input angle
|
43 |
|
|
|
44 |
|
|
on completion:
|
45 |
|
|
|
46 |
|
|
y_out = sin
|
47 |
|
|
x_out = cos
|
48 |
|
|
|
49 |
|
|
The `CORDIC_1 above is the inverse of the cordic gain... or ~0.603
|
50 |
|
|
The input angle depends on whether you build in radian or degree mode
|
51 |
|
|
see the description of the `defines below.
|
52 |
|
|
|
53 |
|
|
|
54 |
|
|
VECTOR: In this mode the user supplies the tangent value in x and y and the rotator
|
55 |
|
|
seeks to minimize the y value, thus computing the angle.
|
56 |
|
|
|
57 |
|
|
To compute the arctan set the inputs as follows
|
58 |
|
|
|
59 |
|
|
y_in and x_in such that y/x = the tangent value for which you wish to find the angle
|
60 |
|
|
theta_in = 0;
|
61 |
|
|
|
62 |
|
|
on completion
|
63 |
|
|
|
64 |
|
|
theta_out = the angle
|
65 |
|
|
|
66 |
|
|
|
67 |
|
|
|
68 |
|
|
*/
|
69 |
|
|
|
70 |
|
|
/* data valid flag
|
71 |
|
|
|
72 |
|
|
The iterative CORDIC implementations take a predetermined number of clock cycles to complete
|
73 |
|
|
If the VALID_FLAG is defined the core instantiates a dvalid_in and dvalid_out signal. This
|
74 |
|
|
signal makes no sense in the COMBINATORIAL mode.
|
75 |
|
|
*/
|
76 |
|
|
// `define VALID_FLAG
|
77 |
|
|
|
78 |
|
|
/* Angle mode
|
79 |
|
|
|
80 |
|
|
The CORDIC can work with the angle expressed in radians or degrees
|
81 |
|
|
Uncomment the appropriate `define below.
|
82 |
|
|
RADIAN_16 uses 16 bit values (+ sign bit for 17 bit accuracy). angle information
|
83 |
|
|
is in the format U(1,15) where bit 16 is the sign bit, bit 15 is the whole number part
|
84 |
|
|
and bits [14:0] are the fractional parts.
|
85 |
|
|
DEGREE_8_8 uses U(8,8) + a sign bit where bit 16 = the sign bit, [15:8] = the whole number part
|
86 |
|
|
and [7:0] = the fractional.
|
87 |
|
|
|
88 |
|
|
The user can define other formats by creating a new tanangle function
|
89 |
|
|
*/
|
90 |
|
|
// `define DEGREE_8_8
|
91 |
|
|
`define RADIAN_16
|
92 |
|
|
|
93 |
|
|
/* Bit accuracy for sin and cos
|
94 |
|
|
|
95 |
|
|
The X and Y values are computed using a `XY_BITS + sign bit accuracy. The format is assumed to be U(1,15) + sign bit
|
96 |
|
|
However, the CORDIC algorythm really doesn't care.
|
97 |
|
|
*/
|
98 |
|
|
`define XY_BITS 16
|
99 |
|
|
|
100 |
|
|
/* Bit accuracy for theta
|
101 |
|
|
|
102 |
|
|
The angle can be represented in either degree or radians. This define determines the number of bits used to represent the
|
103 |
|
|
angle. Going to a higher number of bits would allow more iterations thus improving accuracy. 16 bits is enough for
|
104 |
|
|
most applications.
|
105 |
|
|
*/
|
106 |
|
|
`define THETA_BITS 16
|
107 |
|
|
|
108 |
|
|
/* Iteration accuracy
|
109 |
|
|
|
110 |
|
|
This is the number of times the algorithm will iterate. For pipelined options, this is the number of stages.
|
111 |
|
|
This number is <= the number of bits used in the angles
|
112 |
|
|
|
113 |
|
|
*/
|
114 |
|
|
`define ITERATIONS 16
|
115 |
|
|
`define ITERATION_BITS 4 // 2^ITERATION_BITS = ITERATIONS
|
116 |
|
|
|
117 |
|
|
/* Implementation options
|
118 |
|
|
|
119 |
|
|
The CORDIC core can be realized in one of three methods:
|
120 |
|
|
ITERATE: This option builds a single ROTATOR. The user provides the arguments and gives the core ITERATIONS
|
121 |
|
|
clock cycles to get the result. A signal named init is instantiated to load the input values. It uses the
|
122 |
|
|
least amount of LUTs
|
123 |
|
|
PIPELINE: This option can take a new input on every clock and gives results ITERATIONS clock cycles later. It uses the
|
124 |
|
|
most amount of LUTS.
|
125 |
|
|
COMBINATORIAL: This option gives a result in a single clock cycle at the expense of very deep logic levels. The
|
126 |
|
|
combinatorial implementation runs at about 10 mhz while the iterative ones run at about 125 in a
|
127 |
|
|
Lattice ECP2 device.
|
128 |
|
|
*/
|
129 |
|
|
//`define ITERATE
|
130 |
|
|
`define PIPELINE
|
131 |
|
|
//`define COMBINATORIAL
|
132 |
|
|
|
133 |
|
|
/* CORDIC function
|
134 |
|
|
The CORDIC core works in one of two methods: VECTOR and ROTATE.
|
135 |
|
|
VECTOR: This mode seeks to reduce the Y values and is used to compute an angle given a point.
|
136 |
|
|
Enter the sin and cos of the desired angle and the core calculates the angle. This
|
137 |
|
|
mode computes ARCTAN.
|
138 |
|
|
ROTATE: This mode seeks to reduce the angle. It can be used to compute the sin and cos of a given angle
|
139 |
|
|
*/
|
140 |
|
|
//`define VECTOR // computes the arctan and square root
|
141 |
|
|
`define ROTATE // computes sin cos
|
142 |
|
|
|
143 |
|
|
|
144 |
|
|
/* CORDIC GAIN
|
145 |
|
|
The CORDIC algorithm has an associated gain that is:
|
146 |
|
|
|
147 |
|
|
CORDIC_gain = for (i=0;i<n;i++) An = An*SQRT(1+(1/2^2i)
|
148 |
|
|
This quickly converges to ~ 1.647 as i goes to infinity.
|
149 |
|
|
For 16 bit numbers in the U(1,15) the value is 17'd53955
|
150 |
|
|
*** NOTE *** If you change the number representations
|
151 |
|
|
you will have to recompute these values.
|
152 |
|
|
*/
|
153 |
|
|
`define CORDIC_GAIN 17'd53955
|
154 |
|
|
`define CORDIC_1 17'd19896 // CORDIC inverse
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
//==================== DO NOT EDIT BELOW THIS LINE ======================
|
158 |
|
|
|
159 |
|
|
`ifdef PIPELINE
|
160 |
|
|
`define GENERATE_LOOP
|
161 |
|
|
`endif
|
162 |
|
|
`ifdef COMBINATORIAL
|
163 |
|
|
`define GENERATE_LOOP
|
164 |
|
|
`endif
|
165 |
|
|
|
166 |
|
|
|
167 |
|
|
/* Signed shifter
|
168 |
|
|
This module does an arbitrary right shift to implement'
|
169 |
|
|
the 1/2^i function on signed numbers
|
170 |
|
|
*/
|
171 |
|
|
module signed_shifter (
|
172 |
|
|
input wire [`ITERATION_BITS-1:0] i,
|
173 |
|
|
input wire signed [`XY_BITS:0] D,
|
174 |
|
|
output reg signed [`XY_BITS:0] Q );
|
175 |
|
|
integer j;
|
176 |
|
|
always @ * begin
|
177 |
|
|
Q = D;
|
178 |
|
|
for(j=0;j<i;j=j+1) Q = (Q >> 1) | (D[`XY_BITS] << `XY_BITS);
|
179 |
|
|
end
|
180 |
|
|
endmodule
|
181 |
|
|
/* Rotator
|
182 |
|
|
This module is the heart of the CORDIC computer and implements the CORDIC algorithm.
|
183 |
|
|
Input values x_i, y_i, and z_i are micro computed based on the iteration step
|
184 |
|
|
and the arctan of that step. See the description of the CORDIC algorithm for details.
|
185 |
|
|
|
186 |
|
|
*/
|
187 |
|
|
module rotator (
|
188 |
|
|
input wire clk,
|
189 |
|
|
input wire rst,
|
190 |
|
|
`ifdef ITERATE
|
191 |
|
|
input wire init,
|
192 |
|
|
input wire [`ITERATION_BITS:0] iteration,
|
193 |
|
|
input wire signed [`THETA_BITS:0] tangle,
|
194 |
|
|
`endif
|
195 |
|
|
input wire signed [`XY_BITS:0] x_i,
|
196 |
|
|
input wire signed [`XY_BITS:0] y_i,
|
197 |
|
|
input wire signed [`THETA_BITS:0] z_i,
|
198 |
|
|
output wire signed [`XY_BITS:0] x_o,
|
199 |
|
|
output wire signed [`XY_BITS:0] y_o,
|
200 |
|
|
output wire signed [`THETA_BITS:0] z_o
|
201 |
|
|
);
|
202 |
|
|
|
203 |
|
|
`ifdef GENERATE_LOOP
|
204 |
|
|
parameter integer iteration = 0;
|
205 |
|
|
parameter signed [`THETA_BITS:0] tangle = 0;
|
206 |
|
|
`endif
|
207 |
|
|
reg signed [`XY_BITS:0] x_1;
|
208 |
|
|
reg signed [`XY_BITS:0] y_1;
|
209 |
|
|
reg signed [`THETA_BITS:0] z_1;
|
210 |
|
|
wire signed [`XY_BITS:0] x_i_shifted;
|
211 |
|
|
wire signed [`XY_BITS:0] y_i_shifted;
|
212 |
|
|
signed_shifter x_shifter(iteration,x_i,x_i_shifted);
|
213 |
|
|
signed_shifter y_shifter(iteration,y_i,y_i_shifted);
|
214 |
|
|
`ifdef COMBINATORIAL
|
215 |
|
|
always @ *
|
216 |
|
|
`endif
|
217 |
|
|
`ifdef ITERATE
|
218 |
|
|
always @ (posedge clk)
|
219 |
|
|
`endif
|
220 |
|
|
`ifdef PIPELINE
|
221 |
|
|
always @ (posedge clk)
|
222 |
|
|
`endif
|
223 |
|
|
if (rst) begin
|
224 |
|
|
x_1 <= 0;
|
225 |
|
|
y_1 <= 0;
|
226 |
|
|
z_1 <= 0;
|
227 |
|
|
end else begin
|
228 |
|
|
`ifdef ITERATE
|
229 |
|
|
if (init) begin
|
230 |
|
|
x_1 <= x_i;
|
231 |
|
|
y_1 <= y_i;
|
232 |
|
|
z_1 <= z_i;
|
233 |
|
|
end else
|
234 |
|
|
`endif
|
235 |
|
|
`ifdef ROTATE
|
236 |
|
|
if (z_i < 0) begin
|
237 |
|
|
`endif
|
238 |
|
|
`ifdef VECTOR
|
239 |
|
|
if (y_i > 0) begin
|
240 |
|
|
`endif
|
241 |
|
|
x_1 <= x_i + y_i_shifted; //shifter(y_1,i); //(y_1 >> i);
|
242 |
|
|
y_1 <= y_i - x_i_shifted; //shifter(x_1,i); //(x_1 >> i);
|
243 |
|
|
z_1 <= z_i + tangle;
|
244 |
|
|
end else begin
|
245 |
|
|
x_1 <= x_i - y_i_shifted; //shifter(y_1,i); //(y_1 >> i);
|
246 |
|
|
y_1 <= y_i + x_i_shifted; //shifter(x_1,i); //(x_1 >> i);
|
247 |
|
|
z_1 <= z_i - tangle;
|
248 |
|
|
end
|
249 |
|
|
end
|
250 |
|
|
assign x_o = x_1;
|
251 |
|
|
assign y_o = y_1;
|
252 |
|
|
assign z_o = z_1;
|
253 |
|
|
endmodule
|
254 |
|
|
/*
|
255 |
|
|
CORDIC
|
256 |
|
|
|
257 |
|
|
*/
|
258 |
|
|
module cordic (
|
259 |
|
|
input wire clk,
|
260 |
|
|
input wire rst,
|
261 |
|
|
`ifdef ITERATE
|
262 |
|
|
input wire init,
|
263 |
|
|
`endif
|
264 |
|
|
input wire signed [`XY_BITS:0] x_i,
|
265 |
|
|
input wire signed [`XY_BITS:0] y_i,
|
266 |
|
|
input wire signed [`THETA_BITS:0] theta_i,
|
267 |
|
|
|
268 |
|
|
output wire signed [`XY_BITS:0] x_o,
|
269 |
|
|
output wire signed [`XY_BITS:0] y_o,
|
270 |
|
|
output wire signed [`THETA_BITS:0] theta_o
|
271 |
|
|
`ifdef VALID_FLAG
|
272 |
|
|
,input wire valid_in, output wire valid_out
|
273 |
|
|
`endif
|
274 |
|
|
);
|
275 |
|
|
|
276 |
|
|
`ifdef RADIAN_16
|
277 |
|
|
/*
|
278 |
|
|
arctan table in radian format 16 bit + sign bit.
|
279 |
|
|
*/
|
280 |
|
|
function [`THETA_BITS:0] tanangle;
|
281 |
|
|
input [3:0] i;
|
282 |
|
|
begin
|
283 |
|
|
case (i)
|
284 |
|
|
4'b0000: tanangle = 17'd25735 ; // 1/1
|
285 |
|
|
4'b0001: tanangle = 17'd15192; // 1/2
|
286 |
|
|
4'b0010: tanangle = 17'd8027; // 1/4
|
287 |
|
|
4'b0011: tanangle = 17'd4075; // 1/8
|
288 |
|
|
4'b0100: tanangle = 17'd2045; // 1/16
|
289 |
|
|
4'b0101: tanangle = 17'd1024; // 1/32
|
290 |
|
|
4'b0110: tanangle = 17'd512; // 1/64
|
291 |
|
|
4'b0111: tanangle = 17'd256; // 1/128
|
292 |
|
|
4'b1000: tanangle = 17'd128; // 1/256
|
293 |
|
|
4'b1001: tanangle = 17'd64; // 1/512
|
294 |
|
|
4'b1010: tanangle = 17'd32; // 1/1024
|
295 |
|
|
4'b1011: tanangle = 17'd16; // 1/2048
|
296 |
|
|
4'b1100: tanangle = 17'd8; // 1/4096
|
297 |
|
|
4'b1101: tanangle = 17'd4; // 1/8192
|
298 |
|
|
4'b1110: tanangle = 17'd2; // 1/16k
|
299 |
|
|
4'b1111: tanangle = 17'd1; // 1/32k
|
300 |
|
|
endcase
|
301 |
|
|
end
|
302 |
|
|
endfunction
|
303 |
|
|
`endif
|
304 |
|
|
`ifdef DEGREE_8_8
|
305 |
|
|
/*
|
306 |
|
|
arctan table in degree U(8,8) format 16 bits + sign bit
|
307 |
|
|
*/
|
308 |
|
|
function [`THETA_BITS:0] tanangle;
|
309 |
|
|
input [3:0] i;
|
310 |
|
|
begin
|
311 |
|
|
case (i)
|
312 |
|
|
0: tanangle = 17'd11520; // theta = 45.000000
|
313 |
|
|
1: tanangle = 17'd6800; // theta = 22.500000
|
314 |
|
|
2: tanangle = 17'd3593; // theta = 11.250000
|
315 |
|
|
3: tanangle = 17'd1824; // theta = 5.625000
|
316 |
|
|
4: tanangle = 17'd915; // theta = 2.812500
|
317 |
|
|
5: tanangle = 17'd458; // theta = 1.406250
|
318 |
|
|
6: tanangle = 17'd229; // theta = 0.703125
|
319 |
|
|
7: tanangle = 17'd114; // theta = 0.351562
|
320 |
|
|
8: tanangle = 17'd57; // theta = 0.175781
|
321 |
|
|
9: tanangle = 17'd28; // theta = 0.087891
|
322 |
|
|
10: tanangle = 17'd14; // theta = 0.043945
|
323 |
|
|
11: tanangle = 17'd7; // theta = 0.021973
|
324 |
|
|
12: tanangle = 17'd3; // theta = 0.010986
|
325 |
|
|
13: tanangle = 17'd1; // theta = 0.005493
|
326 |
|
|
14: tanangle = 17'd0; // theta = 0.002747
|
327 |
|
|
15: tanangle = 17'd0; // theta = 0.001373
|
328 |
|
|
endcase
|
329 |
|
|
end
|
330 |
|
|
endfunction
|
331 |
|
|
`endif
|
332 |
|
|
|
333 |
|
|
`ifdef GENERATE_LOOP
|
334 |
|
|
wire signed [`XY_BITS:0] x [`ITERATIONS-1:0];
|
335 |
|
|
wire signed [`XY_BITS:0] y [`ITERATIONS-1:0];
|
336 |
|
|
wire signed [`THETA_BITS:0] z [`ITERATIONS-1:0];
|
337 |
|
|
assign x[0] = x_i;
|
338 |
|
|
assign y[0] = y_i;
|
339 |
|
|
assign z[0] = theta_i;
|
340 |
|
|
assign x_o = x[`ITERATIONS-1];
|
341 |
|
|
assign y_o = y[`ITERATIONS-1];
|
342 |
|
|
assign theta_o = z[`ITERATIONS-1];
|
343 |
|
|
`endif // GENERATE_LOOP
|
344 |
|
|
|
345 |
|
|
`ifdef VALID_FLAG
|
346 |
|
|
wire [`ITERATIONS-1:0] v;
|
347 |
|
|
assign valid_out v[`ITERATIONS-1];
|
348 |
|
|
always @ (posedge clk or posedge rst)
|
349 |
|
|
if (rst) v <= 0;
|
350 |
|
|
else begin
|
351 |
|
|
v <= v << 1;
|
352 |
|
|
v[0] <= valid_in;
|
353 |
|
|
end
|
354 |
|
|
`endif
|
355 |
|
|
|
356 |
|
|
`ifdef GENERATE_LOOP
|
357 |
|
|
genvar i;
|
358 |
|
|
generate for(i=0;i<`ITERATIONS-1;i=i+1) begin
|
359 |
|
|
rotator U (clk,rst,x[i],y[i],z[i],x[i+1],y[i+1],z[i+1]);
|
360 |
|
|
defparam U.iteration = i;
|
361 |
|
|
defparam U.tangle = tanangle(i);
|
362 |
|
|
end
|
363 |
|
|
endgenerate
|
364 |
|
|
`endif
|
365 |
|
|
|
366 |
|
|
`ifdef ITERATE
|
367 |
|
|
reg [`ITERATION_BITS:0] iteration;
|
368 |
|
|
wire signed [`XY_BITS:0] x,y,z;
|
369 |
|
|
assign x = init ? x_i : x_o;
|
370 |
|
|
assign y = init ? y_i : y_o;
|
371 |
|
|
assign z = init ? theta_i : theta_o;
|
372 |
|
|
always @ (posedge clk or posedge init)
|
373 |
|
|
if (init) iteration <= 0;
|
374 |
|
|
else iteration <= iteration + 1;
|
375 |
|
|
rotator U (clk,rst,init,iteration,tanangle(iteration),x,y,z,x_o,y_o,theta_o);
|
376 |
|
|
`endif
|
377 |
|
|
endmodule
|
378 |
|
|
|
379 |
|
|
|