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

Subversion Repositories verilog_cordic_core

[/] [verilog_cordic_core/] [web_uploads/] [cordic.v] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
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
 

powered by: WebSVN 2.1.0

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