>
i=1 0.463648
+ or - + or - >
i=2 0.244979
+ or - + or - >
i=3 0.124355
+ or - + or - >
i=4 0.062419
Block Diagram i=1 i=2 i=3 i=4 0.463648 0.244979 0.124355 - - PowerPoint PPT Presentation
Block Diagram i=1 i=2 i=3 i=4 0.463648 0.244979 0.124355 0.062419 + or - + or - + or - + or - > > > > + or - + or - + or - + or - 2 i 2 i 2 i 2 i 1 1 1 1 2 1 2 1 2
i=1 0.463648
i=2 0.244979
i=3 0.124355
i=4 0.062419
>> atan(2.^(-(0:20))) i=0 0.785398163397448 0.463647609000806 0.244978663126864 0.124354994546761 0.062418809995957 0.031239833430268 0.015623728620477 0.007812341060101 0.003906230131967 0.001953122516479 0.000976562189559 0.000488281211195 0.000244140620149 0.000122070311894 0.000061035156174 0.000030517578116 0.000015258789061 0.000007629394531 0.000003814697266 0.000001907348633 i=20 0.000000953674316 >> dec2hex(round(atan(2.^(-(0:15)))*(2^16)/(2*pi))) i=0 '2000' '12E4' '09FB' '0511' '028B' '0146' '00A3' '0051' '0029' '0014' '000A' '0005' '0003' '0001' '0001' i=15 '0000‘
i=1 0.463648
i=2 0.244979
i=3 0.124355
i=4 0.062419
wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; ... Number Formats: Amplitudes: cosines and sines are 16-bit 2’s comp values from -1 to 1. Angles: rotation angles, thetas are 16-bit 2’s comp values from –π to π. (scaled radians) Input theta is a 16-bit value from 0 to 2π. (scaled radians) *** could actually be signed from –π to π because of periodicity *** >> %initial scaling factor >> scale = prod(cos(atan(2.^(-(0:15))))) %this is an amplitude 0.607252935008973 >> dec2hex(floor(scale*(2^15-1))) %don’t want to go all the way to 1 ‘4DB9’
Number Formats: Amplitudes: cosines and sines are 16-bit 2’s comp values from -1 to 1. Angles: rotation angles, thetas are 16-bit 2’s comp values from –π to π. (scaled radians) Input theta is a 16-bit value from 0 to 2π. (scaled radians) *** could actually be signed from –π to π because of periodicity ***
i=1 angles[1] 0.463648
i=2 angles[2] 0.244979
i=3 angles[3] 0.124355
i=4 angles[4] 0.062419
theta_approx[1] rotation[1] rotation[2] rotation[3] rotation[4] theta_approx[2] theta_approx[3] theta_approx[4]
cos_approx[1] sin_approx[1] cos_approx[2] sin_approx[2] cos_approx[3] sin_approx[3] cos_approx[4] sin_approx[4] cos_approx[0] sin_approx[0]
rotation[0] theta_approx[0] theta_desired
wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; ...
wire signed [15:0] theta_desired; wire [1:0] quadrant; assign theta_desired = (theta_in[14]) ? 16’h4000 – theta_in[13:0] : theta_in[13:0] ; assign quadrant = theta_in[15:14];
wire signed [15:0] cos_approx [15:0]; wire signed [15:0] sin_approx [15:0]; assign cos_approx[0] = 16’h4DB9; assign sin_approx[0] = 16’h4DB9; i=1 angles[1] 0.463648
i=2 angles[2] 0.244979
i=3 angles[3] 0.124355
i=4 angles[4] 0.062419
theta_approx[1]
wire rotation [15:0]; assign rotation[0] = 1’b1;
rotation[1] rotation[2] rotation[3] rotation[4] theta_approx[2] theta_approx[3] theta_approx[4]
wire signed [15:0] theta_approx [15:0]; assign theta_approx[0] = angles[0];
cos_approx[1] sin_approx[1] cos_approx[2] sin_approx[2] cos_approx[3] sin_approx[3] cos_approx[4] sin_approx[4]
Number Formats: Amplitudes: (cos_approx and sin_approx) are 16-bit 2’s comp values from -1 to 1. Angles: (angles, theta_desired, and theta_approx) are 16-bit 2’s comp values from –π to π. (scaled radians) (theta) is a 16-bit value from 0 to 2π. (scaled radians) *** could actually be signed from –π to π because of periodicity ***
wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; ...
wire signed [15:0] theta_desired; wire [1:0] quadrant; assign theta_desired = (theta_in[14]) ? 16’h4000 – theta_in[13:0] : theta_in[13:0] ; assign quadrant = theta_in[15:14];
wire signed [15:0] cos_approx [15:0]; wire signed [15:0] cos_approx [15:0]; assign cos_approx[0] = 16’h4DB9; assign sin_approx[0] = 16’h4DB9; i=1 angles[1] 0.463648
i=2 angles[2] 0.244979
i=3 angles[3] 0.124355
i=4 angles[4] 0.062419
theta_approx[1]
wire rotation [15:0]; assign rotation[0] = 1’b1;
rotation[1] rotation[2] rotation[3] rotation[4] theta_approx[2] theta_approx[3] theta_approx[4]
wire signed [15:0] theta_approx [15:0]; assign theta_approx[0] = angles[0];
cos_approx[1] sin_approx[1] cos_approx[2] sin_approx[2] cos_approx[3] sin_approx[3] cos_approx[4] sin_approx[4]
Number Formats: Amplitudes: (cos_approx and sin_approx) are 16-bit 2’s comp values from -1 to 1. Angles: (angles, theta_desired, and theta_approx) are 16-bit 2’s comp values from –π to π. (scaled radians) (theta) is a 16-bit value from 0 to 2π. (scaled radians) *** could actually be signed from –π to π because of periodicity *** assign rotation[i] = theta_desired > theta_approx[i-1]; assign theta_approx[i] = (rotation[i]) ? theta_approx[i-1] + angles[i] : theta_approx[i-1] – angles[i] ; assign cos_approx[i] = (rotation[i]) ? cos_approx[i-1] – (sin_approx[i-1] >>> i) : cos_approx[i-1] + (sin_approx[i-1] >>> i) ; assign sin_approx[i] = (rotation[i]) ? sin_approx[i-1] + (cos_approx[i-1] >>> i) : sin_approx[i-1] - (cos_approx[i-1] >>> i) ; wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; ...
wire signed [15:0] theta_desired; wire [1:0] quadrant; assign theta_desired = (theta_in[14]) ? 16’h4000 – theta_in[13:0] : theta_in[13:0] ; assign quadrant = theta_in[15:14];
wire signed [15:0] cos_approx [15:0]; wire signed [15:0] sin_approx [15:0]; assign cos_approx[0] = 16’h4DB9; assign sin_approx[0] = 16’h4DB9; assign cos_out = (quadrant[1]^quadrant[0]) ?
cos_approx[15] ; assign sin_out = (quadrant[1]) ?
sin_approx[15] ; i=1 angles[1] 0.463648
i=2 angles[2] 0.244979
i=3 angles[3] 0.124355
i=4 angles[4] 0.062419
theta_approx[1]
wire rotation [15:0]; assign rotation[0] = 1’b1;
rotation[1] rotation[2] rotation[3] rotation[4] theta_approx[2] theta_approx[3] theta_approx[4]
wire signed [15:0] theta_approx [15:0]; assign theta_approx[0] = angles[0];
cos_approx[1] sin_approx[1] cos_approx[2] sin_approx[2] cos_approx[3] sin_approx[3] cos_approx[4] sin_approx[4]
Number Formats: Amplitudes: (cos_approx and sin_approx) are 16-bit 2’s comp values from -1 to 1. Angles: (angles, theta_desired, and theta_approx) are 16-bit 2’s comp values from –π to π. (scaled radians) (theta) is a 16-bit value from 0 to 2π. (scaled radians) *** could actually be signed from –π to π because of periodicity *** assign rotation[i] = theta_desired > theta_approx[i-1]; assign theta_approx[i] = (rotation[i]) ? theta_approx[i-1] + angles[i] : theta_approx[i-1] – angles[i] ; assign cos_approx[i] = (rotation[i]) ? cos_approx[i-1] – (sin_approx[i-1] >>> i) : cos_approx[i-1] + (sin_approx[i-1] >>> i) ; assign sin_approx[i] = (rotation[i]) ? sin_approx[i-1] + (cos_approx[i-1] >>> i) : sin_approx[i-1] - (cos_approx[i-1] >>> i) ; wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; ...
module CORDIC_comb ( input wire [15:0] theta_in,
wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; assign angles[3] = 16’h0511; assign angles[4] = 16’h028B; assign angles[5] = 16’h0146; assign angles[6] = 16’h00A3; assign angles[7] = 16’h0051; assign angles[8] = 16’h0029; assign angles[9] = 16’h0014; assign angles[10] = 16’h000A; assign angles[11] = 16’h0005; assign angles[12] = 16’h0003; assign angles[13] = 16’h0001; assign angles[14] = 16’h0001; assign angles[15] = 16’h0000; wire signed [15:0] theta_desired; wire [1:0] quadrant; assign theta_desired = (theta_in[14]) ? 16’h4000 – theta_in[13:0] : theta_in[13:0] ; assign quadrant = theta_in[15:14]; wire signed [15:0] theta_approx [15:0]; assign theta_approx[0] = angles[0]; wire signed [15:0] cos_approx [15:0]; wire signed [15:0] sin_approx [15:0]; assign cos_approx[0] = 16’h4DB9; assign sin_approx[0] = 16’h4DB9; wire rotation [15:0]; assign rotation[0] = 1’b1; genvar i; generate for (i=1;i<16;i=i+1) begin assign rotation[i] = (theta_desired > theta_approx[i-1]); assign theta_approx[i] = (rotation[i]) ? theta_approx[i-1] + angles[i] : theta_approx[i-1] – angles[i] ; assign cos_approx[i] = (rotation[i]) ? cos_approx[i-1] – (sin_approx[i-1] >>> i) : cos_approx[i-1] + (sin_approx[i-1] >>> i) ; assign sin_approx[i] = (rotation[i]) ? sin_approx[i-1] + (cos_approx[i-1] >>> i) : sin_approx[i-1] - (cos_approx[i-1] >>> i) ; end endgenerate assign cos_out = (quadrant[1]^quadrant[0]) ?
cos_approx[15] ; assign sin_out = (quadrant[1]) ?
sin_approx[15] ; endmodule: CORDIC_comb
i=1
i=2
i=3
i=4
z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1
reg signed [15:0] theta_desired [15:0]; reg [1:0] quadrant [15:0]; theta_desired[0] <= (theta_in[14]) ? 16’h4000 – theta_in[13:0] : theta_in[13:0] ; quadrant[0] <= theta_in[15:14];
reg signed [15:0] cos_approx [15:0]; reg signed [15:0] sin_approx [15:0]; cos_approx[0] <= 16’h4DB9; sin_approx[0] <= 16’h4DB9; cos_out <= (quadrant[15][1]^quadrant[15][0]) ?
cos_approx[15] ; sin_out <= (quadrant[15][1]) ?
sin_approx[15] ; i=1
i=2
i=3
i=4
theta_approx[1]
wire rotation [15:0]; assign rotation[0] = 1’b1;
rotation[1] rotation[2] rotation[3] rotation[4] theta_approx[2] theta_approx[3] theta_approx[4]
reg signed [15:0] theta_approx [15:0]; theta_approx[0] <= angles[0];
cos_approx[1] sin_approx[1] cos_approx[2] sin_approx[2] cos_approx[3] sin_approx[3] cos_approx[4] sin_approx[4]
Number Formats: Amplitudes: (cos_approx and sin_approx) are 16-bit 2’s comp values from -1 to 1. Angles: (angles, theta_desired, and theta_approx) are 16-bit 2’s comp values from –π to π. (scaled radians) (theta) is a 16-bit value from 0 to 2π. (scaled radians) *** could actually be signed from –π to π because of periodicity *** assign rotation[i] = (theta_desired[i-1] > theta_approx[i-1]); theta_approx[i] <= (rotation[i]) ? theta_approx[i-1] + angles[i] : theta_approx[i-1] – angles[i] ; cos_approx[i] <= (rotation[i]) ? cos_approx[i-1] – (sin_approx[i-1] >>> i) : cos_approx[i-1] + (sin_approx[i-1] >>> i) ; sin_approx[i] <= (rotation[i]) ? sin_approx[i-1] + (cos_approx[i-1] >>> i) : sin_approx[i-1] - (cos_approx[i-1] >>> i) ; wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; ...
z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1 z-1
i=0 theta_desired[i] <= theta_desired[i-1]; quadrant[i] <= quadrant[i-1];
theta_approx[0] theta_desired[0] theta_desired[1] theta_desired[2] theta_desired[3] theta_desired[4]
cos_approx[0] sin_approx[0]
module CORDIC_pipe ( input wire clock, input wire [15:0] theta_in,
signed [15:0] cos_out,
signed [15:0] sin_out); wire signed [15:0] angles [15:0]; assign angles[0] = 16’h2000; assign angles[1] = 16’h12E4; assign angles[2] = 16’h09FB; assign angles[3] = 16’h0511; assign angles[4] = 16’h028B; assign angles[5] = 16’h0146; assign angles[6] = 16’h00A3; assign angles[7] = 16’h0051; assign angles[8] = 16’h0029; assign angles[9] = 16’h0014; assign angles[10] = 16’h000A; assign angles[11] = 16’h0005; assign angles[12] = 16’h0003; assign angles[13] = 16’h0001; assign angles[14] = 16’h0001; assign angles[15] = 16’h0000; reg signed [15:0] theta_desired [15:0]; reg [1:0] quadrant [15:0]; reg signed [15:0] theta_approx [15:0]; reg signed [15:0] cos_approx [15:0]; reg signed [15:0] sin_approx [15:0]; always@(posedge clock) begin theta_desired[0] <= (theta_in[14]) ? 16’h4000 – theta_in[13:0] : theta_in[13:0] ; quadrant[0] <= theta_in[15:14]; theta_approx[0] <= angles[0]; cos_approx[0] <= 16’h4DB9; sin_approx[0] <= 16’h4DB9; end wire rotation [15:0]; assign rotation[0] = 1’b1; genvar i; generate for (i=1;i<16;i=i+1) begin assign rotation[i] = (theta_desired[i-1] > theta_approx[i-1]); always@(posedge clock) begin theta_desired[i] <= theta_desired[i-1]; quadrant[i] <= quadrant[i-1]; theta_approx[i] <= (rotation[i]) ? theta_approx[i-1] + angles[i] : theta_approx[i-1] – angles[i] ; cos_approx[i] <= (rotation[i]) ? cos_approx[i-1] – (sin_approx[i-1] >>> i) : cos_approx[i-1] + (sin_approx[i-1] >>> i) ; sin_approx[i] <= (rotation[i]) ? sin_approx[i-1] + (cos_approx[i-1] >>> i) : sin_approx[i-1] - (cos_approx[i-1] >>> i) ; end end endgenerate always@(posedge clock) begin cos_out <= (quadrant[15][1]^quadrant[15][0]) ?
cos_approx[15] ; sin_out <= (quadrant[15][1]) ?
sin_approx[15] ; end endmodule: CORDIC_pipe