算法原理参考:
https://blog.youkuaiyun.com/qwe1006/article/details/138124263
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 16:22:06 01/09/2016
// Design Name:
// Module Name: CORDIC_V
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module CORDIC_V(clock, x_start, y_start, x_end, y_end, angle);
parameter width = 16;
// Inputs
input clock;
input signed [width-1:0] x_start,y_start;
// Outputs
output signed [31:0] angle;
output signed [width:0] x_end,y_end;
// Generate table of atan values
wire signed [31:0] atan_table [0:30];
assign atan_table[00] = 'b00100000000000000000000000000000; // 45.000 degrees -> atan(2^0)
assign atan_table[01] = 'b00010010111001000000010100011101; // 26.565 degrees -> atan(2^-1)
assign atan_table[02] = 'b00001001111110110011100001011011; // 14.036 degrees -> atan(2^-2)
assign atan_table[03] = 'b00000101000100010001000111010100; // atan(2^-3)
assign atan_table[04] = 'b00000010100010110000110101000011;
assign atan_table[05] = 'b00000001010001011101011111100001;
assign atan_table[06] = 'b00000000101000101111011000011110;
assign atan_table[07] = 'b00000000010100010111110001010101;
assign atan_table[08] = 'b00000000001010001011111001010011;
assign atan_table[09] = 'b00000000000101000101111100101110;
assign atan_table[10] = 'b00000000000010100010111110011000;
assign atan_table[11] = 'b00000000000001010001011111001100;
assign atan_table[12] = 'b00000000000000101000101111100110;
assign atan_table[13] = 'b00000000000000010100010111110011;
assign atan_table[14] = 'b00000000000000001010001011111001;
assign atan_table[15] = 'b00000000000000000101000101111100;
assign atan_table[16] = 'b00000000000000000010100010111110;
assign atan_table[17] = 'b00000000000000000001010001011111;
assign atan_table[18] = 'b00000000000000000000101000101111;
assign atan_table[19] = 'b00000000000000000000010100010111;
assign atan_table[20] = 'b00000000000000000000001010001011;
assign atan_table[21] = 'b00000000000000000000000101000101;
assign atan_table[22] = 'b00000000000000000000000010100010;
assign atan_table[23] = 'b00000000000000000000000001010001;
assign atan_table[24] = 'b00000000000000000000000000101000;
assign atan_table[25] = 'b00000000000000000000000000010100;
assign atan_table[26] = 'b00000000000000000000000000001010;
assign atan_table[27] = 'b00000000000000000000000000000101;
assign atan_table[28] = 'b00000000000000000000000000000010;
assign atan_table[29] = 'b00000000000000000000000000000001;
assign atan_table[30] = 'b00000000000000000000000000000000;
reg signed [width:0] x [0:width-1];
reg signed [width:0] y [0:width-1];
reg signed [31:0] z [0:width-1];
// make sure rotation angle is in -pi/2 to pi/2 range
wire [1:0] quadrant;
assign quadrant = {x_start[width-1],y_start[width-1]};
always @(posedge clock)
begin // make sure the rotation angle is in the -pi/2 to pi/2 range
case(quadrant)
2'b00,
2'b01: // no changes needed for these quadrants
begin
x[0] <= x_start;
y[0] <= y_start;
z[0] <= 32'd0;
//$display("nonononononono!!!!!");
end
2'b11:
begin
x[0] <= -y_start;
y[0] <= x_start;
z[0] <= 32'b11000000000000000000000000000000; // subtract pi/2 for angle in this quadrant
end
2'b10:
begin
x[0] <= y_start;
y[0] <= -x_start;
z[0] <= 32'b0100000000000000000000000000000; // add pi/2 to angles in this quadrant
end
endcase
end
// run through iterations
genvar i;
generate
for (i=0; i < (width-1); i=i+1)
begin: xyz
wire y_sign;
wire signed [width:0] x_shr, y_shr;
assign x_shr = x[i] >>> i; // signed shift right
assign y_shr = y[i] >>> i;
//the sign of the current rotation angle
assign y_sign = y[i][width];
always @(posedge clock)
begin
// add/subtract shifted data
x[i+1] <= y_sign ? x[i] - y_shr : x[i] + y_shr;
y[i+1] <= y_sign ? y[i] + x_shr : y[i] - x_shr;
z[i+1] <= y_sign ? z[i] - atan_table[i] : z[i] + atan_table[i];
end
end
endgenerate
endmodule
程序下载链接,包含测试文件:https://download.youkuaiyun.com/download/qwe1006/89276425
https://download.youkuaiyun.com/download/qwe1006/89276419
如需其他函数计算,可私信。