最近学习cordic算法,并利用FPGA实现,在整个学习过程中,对cordic算法原理、FPGA中流水线设计、Verilog标准有了更加深刻的理解。

首先,cordic算法的基本思想是通过一系列固定的、与运算基数有关的角度的不断偏,摆以逼近所需的旋转角度。

为了避免复杂的乘法运算,用一系列微旋转来处理,第i次旋转可表示为:
由式(7)可知:xn,yn分别为输入角H的余弦和正弦值。
在Verilog实现上,主要体会到了流水线设计的重要性。流水线设计的本质是将一个时钟周期完成的较大的组合逻辑(也可理解为一个逻辑需要多个时钟周期,使得数据不能再每个时钟都有输出)通过合理的切割分由多个时钟周期完成(每个时钟都有数据输出),以n=14为例,若不采用流水线设计,则旋转一个角度就需要14个时钟周期,这样输出正余弦波的最大频率变为Fclk/(2N*14),若采用流水线设计,则输出最大频率变为Fclk/2N,N为输出数据位宽,所以流水线设计具有非常重要的意义。
在reg型变量移位过程中,也对Verilog语言标准有了更新的了解,见:http://www.cnblogs.com/tshell/p/3236476.html
module Test(clk,rst,Phase_Word,Sin_Val,Cos_Val);

input clk,rst;
input[:] Phase_Word;
output reg [:] Sin_Val,Cos_Val; parameter Data_Width=; //输出数据宽度
parameter Itera_Num=;
parameter Kn = 'h4DBA; //Kn为旋转后缩放比例因子系数,Kn=0.607253*2^16
`define Rot_Angle0
`define Rot_Angle1
`define Rot_Angle2
`define Rot_Angle3
`define Rot_Angle4
`define Rot_Angle5
`define Rot_Angle6
`define Rot_Angle7
`define Rot_Angle8
`define Rot_Angle9
`define Rot_Angle10
`define Rot_Angle11
`define Rot_Angle12
`define Rot_Angle13 reg [Data_Width:] X[Itera_Num:]; //X轴坐标值,最终对应cos
reg [Data_Width:] Y[Itera_Num:]; //Y轴坐标值,最终对应sin
reg [Data_Width:] Z[Itera_Num:]; //角度累加器 reg[:] quadrant[Itera_Num:]; //象限,00:第一象限;01,10,11分别为二、三、四象限 /*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=0
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
X[] <= {'b0,Kn};
Y[] <= ;
Z[] <= {'b0,Phase_Word[13:0]};//相位控制在(0-Pi/2),注意Phase_word需为reg signed类型。
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=1
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
X[] <= X[] - Y[];
Y[] <= X[] + Y[];
Z[] <= Z[] - `Rot_Angle0;//第一次默认逆时针旋转45度
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=2
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle1; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle1; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=3
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle2; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle2; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=4
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle3; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle3; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=5
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle4; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle4; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=6
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle5; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle5; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=7
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle6; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle6; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=8
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle7; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle7; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=9
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle8; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle8; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=10
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle9; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle9; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=11
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle10; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle10; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=12
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle11; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle11; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=13
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle12; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle12; //逆时针旋转
end
end
/*****************************************************
功能:流水线实现cordic算法
说明:Itera_Num=14
*****************************************************/
always @(posedge clk or negedge rst)
if(!rst)
begin
X[] <= ;
Y[] <= ;
Z[] <= ;
end
else
begin
if(Z[][])
begin
X[] <= X[] + {{{Y[][]}},Y[][:]};
Y[] <= Y[] - {{{X[][]}},X[][:]};
Z[] <= Z[] + `Rot_Angle13; //顺时针旋转
end
else
begin
X[] <= X[] - {{{Y[][]}},Y[][:]};
Y[] <= Y[] + {{{X[][]}},X[][:]};
Z[] <= Z[] - `Rot_Angle13; //逆时针旋转
end
end
/*****************************************************
功能:获取象限信息
*****************************************************/
always @ (posedge clk or negedge rst)
begin
if(!rst)
begin
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
quadrant[] <= ;
end
else
begin
quadrant[] <= Phase_Word[:];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
quadrant[] <= quadrant[];
end
end
/*****************************************************
功能:根据象限确定输出值
说明:当角度A=theta+pi/2在(pi/2~pi)时,
cos(theta+pi/2)=-sin(theta).其中,theta为第一象限角
二进制中,负数等于整数取反再加一
*****************************************************/
always @ (posedge clk or negedge rst)
begin
if(!rst)
begin
Sin_Val <= ;
Cos_Val <= ;
end
else
begin
case(quadrant[])
'b00:begin
Cos_Val <= X[];
Sin_Val <= Y[];
end
'b01:begin
Cos_Val <= ~Y[] + 'b1;
Sin_Val <= X[];
end
'b10:begin
Cos_Val <= ~X[] + 'b1;
Sin_Val <= ~Y[] + 'b1;
end
'b11:begin
Cos_Val <= Y[];
Sin_Val <= ~X[] + 'b1;
end
endcase
end
end endmodule

整个源码设计主要参考了aikimi7的设计,连接:http://www.cnblogs.com/aikimi7/p/3929592.html

 

最新文章

  1. HTML5 Drop API
  2. STL迭代器笔记
  3. This absolute uri http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
  4. ExtJS4.x 开发环境搭建
  5. C语言小结之链表
  6. CakePHP之控制器
  7. #include &lt;boost/shared_array.hpp&gt;
  8. SQL Server 空间监测
  9. 编写高质量代码改善C#程序的157个建议[1-3]
  10. 201521123090《Java程序设计》第6周学习总结
  11. XP实验报告
  12. Smobiler 4.4 更新预告 Part 2(Smobiler能让你在Visual Studio上开发APP)
  13. JS全选反选功能
  14. VirtualBox CentOS7 Mini 安装增强工具
  15. Web大前端面试题-Day12
  16. 安装Jade
  17. 【转】ssh-copy-id帮你建立信任
  18. UWP 播放直播流 3MU8
  19. 二叉树题目集合 python
  20. mongodb聚合 group

热门文章

  1. javascript集合的交,并,补,子集,长度,新增,删除,清空等操作
  2. WebApi实现自定义错误日志
  3. JQuery自定义插件详解之Banner图滚动插件
  4. 工信部:我国4G用户近9.5亿 用户平均使用流量近2G
  5. 【JAVA零基础入门系列】Day9 Java中的那个大数值
  6. Java 7 JVM和垃圾收集
  7. [Java第一课]环境变量的配置以及eclipse一些常用快捷键
  8. IDEA-最简单的struts2项目 关于lib项目的默认位置
  9. 65、django之模型层(model)--添加、单表查询、修改基础
  10. bootstrap select多选