//cordic processor // Larry Doolittle and Ming Choy // Copyright 2003 LBNL // // 16 bit input for x, y // 17 bit input for phase, including highest order bit (pi) // (but because of rounding errors, the output is really only accurate // to about 13 bits) // still could use some language cleanup // reference: // http://www.fpga-guru.com/cordic.htm `timescale 1ns / 1ns module adder16(a,b,sum,control); input [15:0] a,b; input control; output [15:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder15(a,b,sum,control); input [14:0] a,b; input control; output [14:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder14(a,b,sum,control); input [13:0] a,b; input control; output [13:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder13(a,b,sum,control); input [12:0] a,b; input control; output [12:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder12(a,b,sum,control); input [11:0] a,b; input control; output [11:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder11(a,b,sum,control); input [10:0] a,b; input control; output [10:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder10(a,b,sum,control); input [ 9:0] a,b; input control; output [ 9:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder9(a,b,sum,control); input [ 8:0] a,b; input control; output [ 8:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder8(a,b,sum,control); input [ 7:0] a,b; input control; output [ 7:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder7(a,b,sum,control); input [ 6:0] a,b; input control; output [ 6:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder6(a,b,sum,control); input [ 5:0] a,b; input control; output [ 5:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder5(a,b,sum,control); input [ 4:0] a,b; input control; output [ 4:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder4(a,b,sum,control); input [ 3:0] a,b; input control; output [ 3:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder3(a,b,sum,control); input [ 2:0] a,b; input control; output [ 2:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module adder2(a,b,sum,control); input [ 1:0] a,b; input control; output [ 1:0] sum; assign sum = control ? (a + b) : (a - b); endmodule module cordic(clk, xin, yin, phasein, xout, yout, phaseout); input clk; input [15:0] xin, yin; input [16:0] phasein; output[15:0] xout, yout; output[1:0] phaseout; wire [15:0] xw0, xw1, xw2, xw3, xw4, xw5, xw6, xw7, xw8, xw9, xw10, xw11, xw12, xw13, xw14, xw15; wire [15:0] yw0, yw1, yw2, yw3, yw4, yw5, yw6, yw7, yw8, yw9, yw10, yw11, yw12, yw13, yw14, yw15; reg [15:0] x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; reg [15:0] y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, y15; wire [15:0] zw0; wire [15:0] zw1; wire [15:0] zw2; wire [14:0] zw3; wire [13:0] zw4; wire [12:0] zw5; wire [11:0] zw6; wire [10:0] zw7; wire [ 9:0] zw8; wire [ 8:0] zw9; wire [ 7:0] zw10; wire [ 6:0] zw11; wire [ 5:0] zw12; wire [ 4:0] zw13; wire [ 3:0] zw14; wire [ 2:0] zw15; reg [15:0] z0; reg [15:0] z1; reg [14:0] z2; reg [13:0] z3; reg [12:0] z4; reg [11:0] z5; reg [10:0] z6; reg [ 9:0] z7; reg [ 8:0] z8; reg [ 7:0] z9; reg [ 6:0] z10; reg [ 5:0] z11; reg [ 4:0] z12; reg [ 3:0] z13; reg [ 2:0] z14; reg [ 1:0] z15; // signed 12-bit input angle [-2048 , 2047 ] represents the range [ -pi/2 , pi/2 ) // atan((0.5).^[0:12]')/(2*pi)*8192*4 // floor(atan((0.5).^[0:14]')/(2*pi)*2**(17)+.5) // keep one high order 0 bit so these are valid signed numbers wire [15:0] a0 = 16384; // pi/4 wire [15:0] a1 = 9672; wire [14:0] a2 = 5110; wire [13:0] a3 = 2594; wire [12:0] a4 = 1302; wire [11:0] a5 = 652; wire [10:0] a6 = 326; wire [ 9:0] a7 = 163; wire [ 8:0] a8 = 81; wire [ 7:0] a9 = 41; wire [ 6:0] a10 = 20; wire [ 5:0] a11 = 10; wire [ 4:0] a12 = 5; wire [ 3:0] a13 = 3; wire [ 2:0] a14 = 1; assign xout = x15; assign yout = y15; assign phaseout = z15; adder16 ax0 (16'b0000000000000000, xin, xw0, ~phasein[16]^phasein[15]); adder16 ay0 (16'b0000000000000000, yin, yw0, ~phasein[16]^phasein[15]); assign zw0 = phasein[15:0]; adder16 ax1 (x0, y0 , xw1, z0 [15]); adder16 ay1 (y0, x0 , yw1, ~z0 [15]); adder16 az1 (z0, a0, zw1, z0 [15]); adder16 ax2 (x1, {{ 1{y1 [15]}},y1 [15:1]}, xw2, z1 [15]); adder16 ay2 (y1, {{ 1{x1 [15]}},x1 [15:1]}, yw2, ~z1 [15]); adder16 az2 (z1, a1, zw2, z1 [15]); adder16 ax3 (x2, {{ 2{y2 [15]}},y2 [15:2]}, xw3, z2 [14]); adder16 ay3 (y2, {{ 2{x2 [15]}},x2 [15:2]}, yw3, ~z2 [14]); adder15 az3 (z2, a2, zw3, z2 [14]); adder16 ax4 (x3, {{ 3{y3 [15]}},y3 [15:3]}, xw4, z3 [13]); adder16 ay4 (y3, {{ 3{x3 [15]}},x3 [15:3]}, yw4, ~z3 [13]); adder14 az4 (z3, a3, zw4, z3 [13]); adder16 ax5 (x4, {{ 4{y4 [15]}},y4 [15:4]}, xw5, z4 [12]); adder16 ay5 (y4, {{ 4{x4 [15]}},x4 [15:4]}, yw5, ~z4 [12]); adder13 az5 (z4, a4, zw5, z4 [12]); adder16 ax6 (x5, {{ 5{y5 [15]}},y5 [15:5]}, xw6, z5 [11]); adder16 ay6 (y5, {{ 5{x5 [15]}},x5 [15:5]}, yw6, ~z5 [11]); adder12 az6 (z5, a5, zw6, z5 [11]); adder16 ax7 (x6, {{ 6{y6 [15]}},y6 [15:6]}, xw7, z6 [10]); adder16 ay7 (y6, {{ 6{x6 [15]}},x6 [15:6]}, yw7, ~z6 [10]); adder11 az7 (z6, a6, zw7, z6 [10]); adder16 ax8 (x7, {{ 7{y7 [15]}},y7 [15:7]}, xw8, z7 [ 9]); adder16 ay8 (y7, {{ 7{x7 [15]}},x7 [15:7]}, yw8, ~z7 [ 9]); adder10 az8 (z7, a7, zw8, z7 [ 9]); adder16 ax9 (x8, {{ 8{y8 [15]}},y8 [15:8]}, xw9, z8 [ 8]); adder16 ay9 (y8, {{ 8{x8 [15]}},x8 [15:8]}, yw9, ~z8 [ 8]); adder9 az9 (z8, a8, zw9, z8 [ 8]); adder16 ax10(x9, {{ 9{y9 [15]}},y9 [15:9]}, xw10, z9 [ 7]); adder16 ay10(y9, {{ 9{x9 [15]}},x9 [15:9]}, yw10, ~z9 [ 7]); adder8 az10(z9, a9, zw10, z9 [ 7]); adder16 ax11(x10, {{10{y10[15]}},y10[15:10]}, xw11, z10[ 6]); adder16 ay11(y10, {{10{x10[15]}},x10[15:10]}, yw11, ~z10[ 6]); adder7 az11(z10, a10, zw11, z10[ 6]); adder16 ax12(x11, {{11{y11[15]}},y11[15:11]}, xw12, z11[ 5]); adder16 ay12(y11, {{11{x11[15]}},x11[15:11]}, yw12, ~z11[ 5]); adder6 az12(z11, a11, zw12, z11[ 5]); adder16 ax13(x12, {{12{y12[15]}},y12[15:12]}, xw13, z12[ 4]); adder16 ay13(y12, {{12{x12[15]}},x12[15:12]}, yw13, ~z12[ 4]); adder5 az13(z12, a12, zw13, z12[ 4]); adder16 ax14(x13, {{13{y13[15]}},y13[15:13]}, xw14, z13[ 3]); adder16 ay14(y13, {{13{x13[15]}},x13[15:13]}, yw14, ~z13[ 3]); adder4 az14(z13, a13, zw14, z13[ 3]); adder16 ax15(x14, {{14{y14[15]}},y14[15:14]}, xw15, z14[ 2]); adder16 ay15(y14, {{14{x14[15]}},x14[15:14]}, yw15, ~z14[ 2]); adder3 az15(z14, a14, zw15, z14[ 2]); always @ (posedge clk) begin x0 <= xw0; y0 <= yw0; z0 <= zw0; x1 <= xw1; y1 <= yw1; z1 <= zw1; x2 <= xw2; y2 <= yw2; z2 <= zw2; x3 <= xw3; y3 <= yw3; z3 <= zw3; x4 <= xw4; y4 <= yw4; z4 <= zw4; x5 <= xw5; y5 <= yw5; z5 <= zw5; x6 <= xw6; y6 <= yw6; z6 <= zw6; x7 <= xw7; y7 <= yw7; z7 <= zw7; x8 <= xw8; y8 <= yw8; z8 <= zw8; x9 <= xw9; y9 <= yw9; z9 <= zw9; x10 <= xw10; y10 <= yw10; z10 <= zw10; x11 <= xw11; y11 <= yw11; z11 <= zw11; x12 <= xw12; y12 <= yw12; z12 <= zw12; x13 <= xw13; y13 <= yw13; z13 <= zw13; x14 <= xw14; y14 <= yw14; z14 <= zw14; x15 <= xw15; y15 <= yw15; z15 <= zw15; end endmodule