CORDIC arithmetic
发布时间
阅读量:
阅读量
传统CORDIC算法code
Verilog代码:
时钟为50Mhz;
输出设置均设置为有符号数,主要是因为计算CORDIC算法时,需要判断Z通道的符号,来得到迭代过程中旋转方向。

然后根据缩放因子和arctan 2^-n 的预定义并乘以2^16 来进行后续计算,根据迭代方程写出代码;最后将(0度到90度)中正弦值与余弦值来扩大至(0度至360度)的正弦值与余弦值。
module cordic(
input clk_50M,
input rst,
input [31:0] angle,
output reg signed [31:0] sin,
output reg signed [31:0] cos,
output reg signed [31:0] error);
`define rot0 32'd2949_120
`define rot1 32'd1740_967
`define rot2 32'd9198_79
`define rot3 32'd4669_45
`define rot4 32'd2343_78
`define rot5 32'd1173_04
`define rot6 32'd5866_6
`define rot7 32'd2933_4
`define rot8 32'd1466_8
`define rot9 32'd7334
`define rot10 32'd3667
`define rot11 32'd1833
`define rot12 32'd917
`define rot13 32'd458
`define rot14 32'd229
`define rot15 32'd115
parameter pipeline =16;
parameter k=32'd39797;
reg signed [31:0] x0,y0,z0;
reg signed [31:0] x1,y1,z1;
reg signed [31:0] x2,y2,z2;
reg signed [31:0] x3,y3,z3;
reg signed [31:0] x4,y4,z4;
reg signed [31:0] x5,y5,z5;
reg signed [31:0] x6,y6,z6;
reg signed [31:0] x7,y7,z7;
reg signed [31:0] x8,y8,z8;
reg signed [31:0] x9,y9,z9;
reg signed [31:0] x10,y10,z10;
reg signed [31:0] x11,y11,z11;
reg signed [31:0] x12,y12,z12;
reg signed [31:0] x13,y13,z13;
reg signed [31:0] x14,y14,z14;
reg signed [31:0] x15,y15,z15;
reg signed [31:0] x16,y16,z16;
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x0<=0;
y0<=0;
z0<=0;
end
else
begin
x0<=k;
y0<=0;
z0<=angle[15:0]<<16;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x1<=0;
y1<=0;
z1<=0;
end
else if(z0[31])
begin
x1<=x0+(y0>>0);
y1<=y0-(x0>>0);
z1<=z0+`rot0;
end
else
begin
x1<=x0-(y0>>0);
y1<=y0+(x0>>0);
z1<=z0-`rot0;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x2<=0;
y2<=0;
z2<=0;
end
else if(z1[31])
begin
x2<=x1+(y1>>1);
y2<=y1-(x1>>1);
z2<=z1+`rot1;
end
else
begin
x2<=x1-(y1>>1);
y2<=y1+(x1>>1);
z2<=z1-`rot1;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x3<=0;
y3<=0;
z3<=0;
end
else if(z2[31])
begin
x3<=x2+(y2>>2);
y3<=y2-(x2>>2);
z3<=z2+`rot2;
end
else
begin
x3<=x2-(y2>>2);
y3<=y2+(x2>>2);
z3<=z2-`rot2;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x4<=0;
y4<=0;
z4<=0;
end
else if(z3[31])
begin
x4<=x3+(y3>>3);
y4<=y3-(x3>>3);
z4<=z3+`rot3;
end
else
begin
x4<=x3-(y3>>3);
y4<=y3+(x3>>3);
z4<=z3-`rot3;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x5<=0;
y5<=0;
z5<=0;
end
else if(z4[31])
begin
x5<=x4+(y4>>4);
y5<=y4-(x4>>4);
z5<=z4+`rot4;
end
else
begin
x5<=x4-(y4>>4);
y5<=y4+(x4>>4);
z5<=z4-`rot4;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x6<=0;
y6<=0;
z6<=0;
end
else if(z5[31])
begin
x6<=x5+(y5>>5);
y6<=y5-(x5>>5);
z6<=z5+`rot5;
end
else
begin
x6<=x5-(y5>>5);
y6<=y5+(x5>>5);
z6<=z5-`rot5;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x7<=0;
y7<=0;
z7<=0;
end
else if(z6[31])
begin
x7<=x6+(y6>>6);
y7<=y6-(x6>>6);
z7<=z6+`rot6;
end
else
begin
x7<=x6-(y6>>6);
y7<=y6+(x6>>6);
z7<=z6-`rot6;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x8<=0;
y8<=0;
z8<=0;
end
else if(z7[31])
begin
x8<=x7+(y7>>7);
y8<=y7-(x7>>7);
z8<=z7+`rot7;
end
else
begin
x8<=x7-(y7>>7);
y8<=y7+(x7>>7);
z8<=z7-`rot7;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x9<=0;
y9<=0;
z9<=0;
end
else if(z8[31])
begin
x9<=x8+(y8>>8);
y9<=y8-(x8>>8);
z9<=z8+`rot8;
end
else
begin
x9<=x8-(y8>>8);
x9<=y8+(x8>>8);
z9<=z8-`rot8;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x10<=0;
y10<=0;
z10<=0;
end
else if(z9[31])
begin
x10<=x9+(y9>>9);
y10<=y9-(x9>>9);
z10<=z9+`rot9;
end
else
begin
x10<=x9-(y9>>9);
y10<=y9+(x9>>9);
z10<=z9-`rot9;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x11<=0;
y11<=0;
z11<=0;
end
else if(z10[31])
begin
x11<=x10+(y10>>10);
y11<=y10-(x10>>10);
z11<=z10+`rot10;
end
else
begin
x11<=x10-(y10>>10);
y11<=y10+(x10>>10);
z11<=z10-`rot10;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x12<=0;
y12<=0;
z12<=0;
end
else if(z11[31])
begin
x12<=x11+(y11>>11);
y12<=y11-(x11>>11);
z12<=z11+`rot11;
end
else
begin
x12<=x11-(y11>>11);
y12<=y11+(x11>>11);
z12<=z11-`rot11;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x13<=0;
y13<=0;
z13<=0;
end
else if(z12[31])
begin
x13<=x12+(y12>>12);
y13<=y12-(x12>>12);
z13<=z12+`rot12;
end
else
begin
x13<=x12-(y12>>12);
y13<=y12+(x12>>12);
z13<=z12-`rot12;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x14<=0;
y14<=0;
z14<=0;
end
else if(z13[31])
begin
x14<=x13+(y13>>13);
y14<=y13-(x13>>13);
z14<=z13+`rot13;
end
else
begin
x14<=x13-(y13>>13);
y14<=y13+(x13>>13);
z14<=z13-`rot13;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x15<=0;
y15<=0;
z15<=0;
end
else if(z14[31])
begin
x15<=x14+(y14>>14);
y15<=y14-(x14>>14);
z15<=z14+`rot14;
end
else
begin
x15<=x14-(y14>>14);
y15<=y14+(x14>>14);
z15<=z14-`rot14;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
x16<=0;
y16<=0;
z16<=0;
end
else if(z15[31])
begin
x16<=x15+(y15>>15);
y16<=y15-(x15>>15);
z16<=z15+`rot15;
end
else
begin
x16<=x15-(y15>>15);
y16<=y15+(x15>>15);
z16<=z15-`rot15;
end
end
always@(posedge clk_50M or negedge rst)
begin
if(!rst)
begin
sin<=0;
cos<=0;
error<=0;
end
else if(0<=angle<=31'd90)
begin
sin<=y16;
cos<=x16;
end
else if(31'd90<=angle<=31'd180)
begin
cos<=~(y16)+1;
sin<=x16;
end
else if(31'd180<=angle<=31'd270)
begin
cos<=~(x16)+1;
sin<=~(y16)+1;
end
else if(31'd270<=angle<=31'd360)
begin
cos<=y16;
sin<=~x16+1;
end
else
begin
sin<=0;
cos<=0;
error<=0;
end
end
endmodule

编写的tb文件如下:
module tb();
reg clk_50M;
reg rst;
reg [31:0] angle;
wire [31:0] sin;
wire [31:0] cos;
wire [31:0] error;
parameter period=20;
initial
begin
clk_50M=0;
forever #(period/2) clk_50M=~clk_50M;
end
task rst_n;
input [31:0] rst_time;
begin
rst=0;
#(rst_time) rst=1;
end
endtask
initial
begin
rst_n(60);
angle=31'd46;
end
cordic u1(
.clk_50M(clk_50M),
.rst(rst),
.angle(angle),
.sin(sin),
.cos(cos),
.error(error));
endmodule

最终使用VCS 检查输入角度为46度时,输出的结果是否正确;将结果除以2^16可以得出最终结果,由于sin46=0.7193398 而仿真结果为0.7193909
而cos46=0.69465839,而仿真结果为0.694641113;误差率大于在10^-5

全部评论 (0)
还没有任何评论哟~
