Guest User

cordic

a guest
Apr 25th, 2016
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. `timescale 1 ns / 1 ps
  2. // NOTE: 1. Input angle is a modulo of 2*PI scaled to fit in a 32bit register. The user must translate
  3. //          this angle to a value from 0 - (2^32-1).  0 deg = 32'h0, 359.9999... = 32'hFF_FF_FF_FF
  4. //          To translate from degrees to a 32 bit value, multiply 2^32 by the angle (in degrees),
  5. //          then divide by 360
  6. //       2. Size of Xout, Yout is 1 bit larger due to a system gain of 1.647 (which is < 2)
  7. module cordic(clk, zi, xi, yi, zo, xo, yo);
  8.   parameter XY_WIDTH = 16;   // width of input and output data
  9.   parameter Z_WIDTH = 30;   // width of input and output data
  10.   parameter MODE = "ROTOR";
  11.   localparam STG = XY_WIDTH; // same as bit width of X and Y
  12.  
  13.   input clk;                 
  14.   // angle is a signed value in the range of -PI to +PI that must be represented as a Z_WIDTH bit signed number
  15.   input  signed [(Z_WIDTH-1):0] zi;
  16.   output signed [(Z_WIDTH-1):0] zo;
  17.   input  signed [(XY_WIDTH-1):0] xi;
  18.   input  signed [(XY_WIDTH-1):0] yi;
  19.   output signed [XY_WIDTH:0] xo;
  20.   output signed [XY_WIDTH:0] yo;
  21.   //------------------------------------------------------------------------------
  22.   //                             arctan table
  23.   //------------------------------------------------------------------------------
  24.   // Note: The atan_table was chosen to be 31 bits wide giving resolution up to atan(2^-30)
  25.   wire signed [31:0] atan [0:30];
  26.   // upper 2 bits = 2'b00 which represents 0 - PI/2 range
  27.   // upper 2 bits = 2'b01 which represents PI/2 to PI range
  28.   // upper 2 bits = 2'b10 which represents PI to 3*PI/2 range (i.e. -PI/2 to -PI)
  29.   // upper 2 bits = 2'b11 which represents 3*PI/2 to 2*PI range (i.e. 0 to -PI/2)
  30.   // The upper 2 bits therefore tell us which quadrant we are in.
  31.   assign atan[00] = 32'b00100000000000000000000000000000; // 45.000 degrees -> atan(2^0)
  32.   assign atan[01] = 32'b00010010111001000000010100011101; // 26.565 degrees -> atan(2^-1)
  33.   assign atan[02] = 32'b00001001111110110011100001011011; // 14.036 degrees -> atan(2^-2)
  34.   assign atan[03] = 32'b00000101000100010001000111010100; // atan(2^-3)
  35.   assign atan[04] = 32'b00000010100010110000110101000011;
  36.   assign atan[05] = 32'b00000001010001011101011111100001;
  37.   assign atan[06] = 32'b00000000101000101111011000011110;
  38.   assign atan[07] = 32'b00000000010100010111110001010101;
  39.   assign atan[08] = 32'b00000000001010001011111001010011;
  40.   assign atan[09] = 32'b00000000000101000101111100101110;
  41.   assign atan[10] = 32'b00000000000010100010111110011000;
  42.   assign atan[11] = 32'b00000000000001010001011111001100;
  43.   assign atan[12] = 32'b00000000000000101000101111100110;
  44.   assign atan[13] = 32'b00000000000000010100010111110011;
  45.   assign atan[14] = 32'b00000000000000001010001011111001;
  46.   assign atan[15] = 32'b00000000000000000101000101111101;
  47.   assign atan[16] = 32'b00000000000000000010100010111110;
  48.   assign atan[17] = 32'b00000000000000000001010001011111;
  49.   assign atan[18] = 32'b00000000000000000000101000101111;
  50.   assign atan[19] = 32'b00000000000000000000010100011000;
  51.   assign atan[20] = 32'b00000000000000000000001010001100;
  52.   assign atan[21] = 32'b00000000000000000000000101000110;
  53.   assign atan[22] = 32'b00000000000000000000000010100011;
  54.   assign atan[23] = 32'b00000000000000000000000001010001;
  55.   assign atan[24] = 32'b00000000000000000000000000101000;
  56.   assign atan[25] = 32'b00000000000000000000000000010100;
  57.   assign atan[26] = 32'b00000000000000000000000000001010;
  58.   assign atan[27] = 32'b00000000000000000000000000000101;
  59.   assign atan[28] = 32'b00000000000000000000000000000010;
  60.   assign atan[29] = 32'b00000000000000000000000000000001; // atan(2^-29)
  61.   assign atan[30] = 32'b00000000000000000000000000000000;
  62.   //stage outputs
  63.   reg signed [XY_WIDTH:0] x [0:(STG-1)];
  64.   reg signed [XY_WIDTH:0] y [0:(STG-1)];
  65.   reg signed [(Z_WIDTH-1):0] z [0:(STG-1)]; // 32bit
  66.   //------------------------------------------------------------------------------
  67.   //                               stage 0
  68.   //------------------------------------------------------------------------------
  69.   generate  
  70.   always @(posedge clk)
  71.   begin // make sure the rotation angle is in the -pi/2 to pi/2 range.  If not then pre-rotate
  72.     if(MODE == "ROTOR") begin
  73.       x[0] <= (zi[(Z_WIDTH-1)] == zi[(Z_WIDTH-2)]) ? xi : -xi;
  74.       y[0] <= (zi[(Z_WIDTH-1)] == zi[(Z_WIDTH-2)]) ? yi : -yi;
  75.       z[0] <= { zi[(Z_WIDTH-2)], zi[(Z_WIDTH-2):0] };    
  76.     end
  77.     else if (MODE == "VECTOR") begin
  78.       x[0] <= (xi < 0) ? -xi : xi;
  79.       y[0] <= (xi < 0) ? -yi : yi;
  80.       z[0] <= (xi < 0) ?  zi + { 1'b1, {(Z_WIDTH-1){1'b0}}} : zi;
  81.     end
  82.   end    
  83.   endgenerate
  84. //------------------------------------------------------------------------------
  85. //                           generate stages 1 to STG-1
  86. //------------------------------------------------------------------------------
  87.   genvar i;      
  88.   generate   
  89.   for(i = 0; i < (STG-1); i = (i+1))
  90.   begin: XYZ
  91.     wire signed [XY_WIDTH:0] xs = x[i] >>> i; // signed shift right
  92.     wire signed [XY_WIDTH:0] ys = y[i] >>> i;
  93.     //rounded arctan
  94.     wire [(Z_WIDTH-1):0] zs = (Z_WIDTH == 32) ? atan[i] : (Z_WIDTH)'(atan[i] >>> (32-Z_WIDTH)) + 1'(atan[i] >>> (31-Z_WIDTH));
  95.     //the sign of the current rotation angle
  96.     wire s = (MODE == "ROTOR") ? z[i][(Z_WIDTH-1)] : ~y[i][(XY_WIDTH-1)];
  97.     always @(posedge clk)
  98.     begin
  99.     // add/subtract shifted data
  100.       x[(i+1)] <= s ? x[i] + ys : x[i] - ys;
  101.       if (i < STG-2 || MODE == "ROTOR") begin
  102.         y[(i+1)] <= s ? y[i] - xs : y[i] + xs;
  103.       end  
  104.       if (i < STG-2 || MODE == "VECTOR") begin
  105.         z[(i+1)] <= s ? z[i] + zs : z[i] - zs;
  106.       end
  107.     end
  108.   end
  109.   endgenerate
  110.   assign xo = x[(STG-1)];
  111.   assign yo = y[(STG-1)];
  112.   assign zo = z[(STG-1)];
  113. endmodule
Advertisement
Add Comment
Please, Sign In to add comment