cordic算法的总结和verilog代码的编写

coridc算法,说到底就是通过向量通过变化来求解角度和和一些基本函数的方法,原理如下所示

注意,此处的x2,y2的计算的正负号会随着旋转方向的不同而不同。

求解向量的赋值:

通过旋转下,x,y,经过一定的旋转次数后,xn即是被扩大后的向量赋值。

在求解角度时:则利用上图的两公式将y,x赋值给特定的值后求解,具体赋值请自行查找。


verilog求解相位幅度程序

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

`timescale 1ns/1ps
//------------------------------------------------------------------------
//用于计算fft后输出虚数的幅度和相位。
//输入参数:
//clk_in : 时钟
//sys_rst : 复位,低电平有效
//data_in_en : 输入数据使能端
//data_ina ,data_inb:输入数据,可自定义长度
//输出参数
//data_out_en :输出数据使能端
//esp_out:输出幅度值
//atan_out : 角度输出
//------------------------------------------------------------------------
module AMTITUD_PHASE
#(parameter DATA_WIDTH = 16)
(
input clk_in,
input sys_rst,
input data_in_en,
input [DATA_WIDTH-1 :0] data_ina,
input [DATA_WIDTH-1:0] data_inb,
output reg data_out_en,
output reg [DATA_WIDTH-1:0] eps_out,
output reg [DATA_WIDTH-1:0] atan_out
);
//---------旋转角度,根据16位数据位计算而得,当位数改变需重新计算---------
//360 对应 2^16

//角度旋转值,

//----------------------------------------------------------------------------------------------------
localparam rot0 = 16'h2000;    //45
localparam rot1 = 16'h2000;    //45
localparam rot2 = 16'h2000;    //45
localparam rot3 = 16'h12e4;    //26.5651
localparam rot4 = 16'h09fb;    //14.0362
localparam rot5 = 16'h0511;   //7.1250
localparam rot6 = 16'h028b;    //3.5763
localparam rot7 = 16'h0145;    //1.7899
localparam rot8 = 16'h00a3;    //0.8952
localparam rot9 = 16'h0051;    //0.4476
localparam rot10 = 16'h0028;    //0.2238
localparam rot11 = 16'h0014;    //0.1119
localparam rot12= 16'h000a;   //0.0560
localparam rot13= 16'h0005;    //0.0280
localparam rot14= 16'h0003;    //0.0140
localparam rot15= 16'h0001;    //0.0070
localparam rot16= 16'h0001;    //0.0035
//---------------------------------------------------------------------------------------
localparam PIPELINE = 8;
localparam REGESTER_SIZE = 32;
reg [REGESTER_SIZE-1:0] x0=0,y0=0,z0=0;
reg [REGESTER_SIZE-1:0] x1=0,y1=0,z1=0;
reg [REGESTER_SIZE-1:0] x2=0,y2=0,z2=0;
reg [REGESTER_SIZE-1:0] x3=0,y3=0,z3=0;
reg [REGESTER_SIZE-1:0] x4=0,y4=0,z4=0;
reg [REGESTER_SIZE-1:0] x5=0,y5=0,z5=0;
reg [REGESTER_SIZE-1:0] x6=0,y6=0,z6=0;
reg [REGESTER_SIZE-1:0] x7=0,y7=0,z7=0;
reg [REGESTER_SIZE-1:0] x8=0,y8=0,z8=0;
reg [REGESTER_SIZE-1:0] x9=0,y9=0,z9=0;
reg [REGESTER_SIZE-1:0] x10=0,y10=0,z10=0;
reg [REGESTER_SIZE-1:0] x11=0,y11=0,z11=0;
/*reg [REGESTER_SIZE-1:0] x12=0,y12=0,z12=0;
reg [REGESTER_SIZE-1:0] x13=0,y13=0,z13=0;
reg [REGESTER_SIZE-1:0] x14=0,y14=0,z14=0;
reg [REGESTER_SIZE-1:0] x15=0,y15=0,z15=0;
reg [REGESTER_SIZE-1:0] x16=0,y16=0,z16=0;*/
reg [5:0]piple_cnt;


//---------------------------------------------------------------------------------------
always  @ (posedge clk_in or negedge sys_rst)
if(sys_rst == 1'b0) begin
piple_cnt <= 6'd0;
end
else if (data_in_en == 1'b1) begin
if(piple_cnt == PIPELINE) piple_cnt <= 6'd0; 
else piple_cnt <= piple_cnt + 1'b1;
end
else piple_cnt <= 6'd0;

//--------------- 三次旋转 -----------------------------

//将角度旋转到正半轴来

always @ (posedge clk_in) begin
x0 <= {data_ina[REGESTER_SIZE-1],data_ina,16'd0};
y0 <= {data_inb[REGESTER_SIZE-1],data_inb,16'd0};
z0 <= 32'd0;
end

always @ (posedge clk_in)            //第一次旋转
if(y0[REGESTER_SIZE-1]) begin
x1 = x0 - y0;
y1 = y0 + x0;
z1 = z0 - rot0;
end
else begin
x1 = x0 + y0;
y1 = y0 - x0;
z1 = z0 + rot0;
end

always @ (posedge clk_in)            //第二次旋转
if(y1[REGESTER_SIZE-1]) begin
x2 = x1 - y1;
y2 = y1 + x1;
z2 = z1 - rot1;
end
else begin
x2 = x1 + y1;
y2 = y1 - x1;
z2 = z1 + rot1;
end

always @ (posedge clk_in)            //第三次旋转
if(y2[REGESTER_SIZE-1]) begin
x3 = x2 - y2;
y3 = y2 + x2;
z3 = z2 - rot2;
end
else begin
x3 = x2 + y2;
y3 = y2 - x2;
z3 = z2 + rot2;
end
//---------------- 流水 8级的流水操作 ------------------------------------------------------------
always @ (posedge clk_in)            //第一级流水
if(y3[REGESTER_SIZE-1]) begin
x4 <= x3 - {y3[REGESTER_SIZE-1],y3[REGESTER_SIZE-1:1]};
y4 <= y3 + {x3[REGESTER_SIZE-1],x3[REGESTER_SIZE-1:1]};
z4 <= z3 - rot3;
end
else begin
x4 <= x3 + {y3[REGESTER_SIZE-1],y3[REGESTER_SIZE-1:1]};
y4 <= y3 - {x3[REGESTER_SIZE-1],x3[REGESTER_SIZE-1:1]};
z4 <= z3 + rot3;
end


always @ (posedge clk_in)            //2
if(y4[REGESTER_SIZE-1]) begin
x5 <= x4 - {{2{y4[REGESTER_SIZE-1]}},y4[REGESTER_SIZE-1:2]};
y5 <= y4 + {{2{x4[REGESTER_SIZE-1]}},x4[REGESTER_SIZE-1:2]};
z5 <= z4 - rot4;
end
else begin
x5 <= x4 + {{2{y4[REGESTER_SIZE-1]}},y4[REGESTER_SIZE-1:2]};
y5 <= y4 - {{2{x4[REGESTER_SIZE-1]}},x4[REGESTER_SIZE-1:2]};
z5 <= z4 + rot4;
end

always @ (posedge clk_in)            //3
if(y5[REGESTER_SIZE-1]) begin
x6 <= x5 - {{3{y5[REGESTER_SIZE-1]}},y5[REGESTER_SIZE-1:3]};
y6 <= y5 + {{3{x5[REGESTER_SIZE-1]}},x5[REGESTER_SIZE-1:3]};
z6 <= z5 - rot5;
end
else begin
x6 <= x5 + {{3{y5[REGESTER_SIZE-1]}},y5[REGESTER_SIZE-1:3]};
y6 <= y5 - {{3{x5[REGESTER_SIZE-1]}},x5[REGESTER_SIZE-1:3]};
z6 <= z5 + rot5;
end


always @ (posedge clk_in)             //4
if(y6[REGESTER_SIZE-1]) begin
x7 <= x6 - {{4{y6[REGESTER_SIZE-1]}},y6[REGESTER_SIZE-1:4]};
y7 <= y6 + {{4{x6[REGESTER_SIZE-1]}},x6[REGESTER_SIZE-1:4]};
z7 <= z6 - rot6;
end
else begin
x7 <= x6 + {{4{y6[REGESTER_SIZE-1]}},y6[REGESTER_SIZE-1:4]};
y7 <= y6 - {{4{x6[REGESTER_SIZE-1]}},x6[REGESTER_SIZE-1:4]};
z7 <= z6 + rot6;
end

always @ (posedge clk_in)            //5
if(y7[REGESTER_SIZE-1]) begin
x8 <= x7 - {{5{y7[REGESTER_SIZE-1]}},y7[REGESTER_SIZE-1:5]};
y8 <= y7 + {{5{x7[REGESTER_SIZE-1]}},x7[REGESTER_SIZE-1:5]};
z8 <= z7 - rot7;
end
else begin
x8 <= x7 + {{5{y7[REGESTER_SIZE-1]}},y7[REGESTER_SIZE-1:5]};
y8 <= y7 - {{5{x7[REGESTER_SIZE-1]}},x7[REGESTER_SIZE-1:5]};
z8 <= z7 + rot7;
end

always @ (posedge clk_in)            //6
if(y8[REGESTER_SIZE-1]) begin
x9 <= x8 - {{6{y8[REGESTER_SIZE-1]}},y8[REGESTER_SIZE-1:6]};
y9 <= y8 + {{6{x8[REGESTER_SIZE-1]}},x8[REGESTER_SIZE-1:6]};
z9 <= z8 - rot8;
end
else begin
x9 <= x8 + {{6{y8[REGESTER_SIZE-1]}},y8[REGESTER_SIZE-1:6]};
y9 <= y8 - {{6{x8[REGESTER_SIZE-1]}},x8[REGESTER_SIZE-1:6]};
z9 <= z8 + rot8;
end


always @ (posedge clk_in)            //7
if(y9[REGESTER_SIZE-1]) begin
x10 <= x9 - {{7{y9[REGESTER_SIZE-1]}},y9[REGESTER_SIZE-1:7]};
y10 <= y9 + {{7{x9[REGESTER_SIZE-1]}},x9[REGESTER_SIZE-1:7]};
z10 <= z9 - rot9;
end
else begin
x10 <= x9 + {{7{y9[REGESTER_SIZE-1]}},y9[REGESTER_SIZE-1:7]};
y10 <= y9 - {{7{x9[REGESTER_SIZE-1]}},x9[REGESTER_SIZE-1:7]};
z10 <= z9 + rot9;
end

always @ (posedge clk_in)             //8
if(y10[REGESTER_SIZE-1]) begin
x11 <= x10 - {{8{y10[REGESTER_SIZE-1]}},y10[REGESTER_SIZE-1:8]};
y11 <= y10 + {{8{x10[REGESTER_SIZE-1]}},x10[REGESTER_SIZE-1:8]};
z11 <= z10 - rot10;
end
else begin
x11 <= x10 + {{8{y10[REGESTER_SIZE-1]}},y10[REGESTER_SIZE-1:8]};
y11 <= y10 - {{8{x10[REGESTER_SIZE-1]}},x10[REGESTER_SIZE-1:8]};
z11 <= z10 + rot10;
end

always @ (posedge clk_in)  begin  
  if(data_in_en == 1'b1 && piple_cnt  == PIPELINE) begin
        data_out_en <= 1'b1;
atan_out[DATA_WIDTH-1:0] <= z11[DATA_WIDTH-1:0];
eps_out[DATA_WIDTH-1:0] <= x11>>10;  //结位问题
      end
  else if(data_in_en == 1'b0 && piple_cnt  == PIPELINE) begin
        data_out_en <= 1'b0;
atan_out <= atan_out;
eps_out <= eps_out;
      end
  else begin
        data_out_en <= data_out_en;
atan_out <= atan_out;
eps_out <= eps_out;
      end
  
  end

endmodule








































 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值