最近学习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

 

学习cordic算法所得(流水线结构、Verilog标准)的更多相关文章

  1. Cordic算法——verilog实现

    上两篇博文Cordic算法--圆周系统之旋转模式.Cordic算法--圆周系统之向量模式做了理论分析和实现,但是所用到的变量依然是浮点型,而cordic真正的用处是基于FPGA等只能处理定点的平台.只 ...

  2. 使用CORDIC算法求解角度正余弦及Verilog实现

    本文是用于记录在了解和学习CORDIC算法期间的收获,以供日后自己及他人参考:并且附上了使用Verilog实现CORDIC算法求解角度的正弦和余弦的代码.简单的testbench测试代码.以及在Mod ...

  3. 基于FPGA的Cordic算法实现

    CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲线.指数.对数的 ...

  4. cordic算法的verilog实现及modelsim仿真

    1. 算法介绍 CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲 ...

  5. 基于FPGA的cordic算法的verilog初步实现

    最近在看cordic算法,由于还不会使用matlab,真是痛苦,一系列的笔算才大概明白了这个算法是怎么回事.于是尝试用verilog来实现.用verilog实现之前先参考软件的程序,于是先看了此博文h ...

  6. 定点CORDIC算法求所有三角函数及向量模的原理分析、硬件实现(FPGA)

    一.CORDIC算法 CORDIC(Coordinate Rotation DIgital Computer)是一种通过迭代对多种数学函数求值的方法,它可以对三角函数.双曲函数和平面旋转问题进行求解. ...

  7. 三角函数计算,Cordic 算法入门

    [-] 三角函数计算Cordic 算法入门 从二分查找法说起 减少乘法运算 消除乘法运算 三角函数计算,Cordic 算法入门 三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来 ...

  8. (转)三角函数计算,Cordic 算法入门

    由于最近要使用atan2函数,但是时间上消耗比较多,因而网上搜了一下简化的算法. 原帖地址:http://blog.csdn.net/liyuanbhu/article/details/8458769 ...

  9. DeepLearning.ai学习笔记(三)结构化机器学习项目--week2机器学习策略(2)

    一.进行误差分析 很多时候我们发现训练出来的模型有误差后,就会一股脑的想着法子去减少误差.想法固然好,但是有点headlong~ 这节视频中吴大大介绍了一个比较科学的方法,具体的看下面的例子 还是以猫 ...

随机推荐

  1. python批量修改word文件名

    最近不小心把硬盘给格式化了,由于当时的文件没有备份,所以一下所有的文件都没有了,于是只能采取补救措施,用文件恢复软件恢复了一部分的数据出来,但是恢复完毕的文件的文件名全丢了,所有的文件只有代号,如下面 ...

  2. 页面固定DIV层CSS代码

    有时候为了用户体验更好些,网页设计师会把网站导航放在一个固定的DIV层里面,不随滚动条滚动.本方法是利用CSS,position:fixed属性来固定层,fixed是特殊的absolute,即fixe ...

  3. PHP常用表达式用法

    1.匹配正整数:/^[1-9]\d*$/ 2.匹配非负整数(正整数+0):/^\d+$/ 3.匹配中文:/^[\x{4e00}-\x{9fa5}]+$/u 4.匹配Email:/^\w+([-+.]\ ...

  4. win10 UWP 显示地图

    微软自带的地图很简单 引用地图xmlns:Map="using:Windows.UI.Xaml.Controls.Maps" 写在<Page> 然后在Grid 用Map ...

  5. UVa816,Ordering Tasks,WA

    #include <iostream> #include <cstdio> #include <string> #include <cstring> # ...

  6. BootStrap教程完整版

    http://www.runoob.com/bootstrap/bootstrap-navbar.html

  7. swiper使用小结

    最近做一个移动端项目想用Swiper移动端插件,需求实现一个轮播图的效果,并且需要自定义分页器,效果跟这个差不多这里demo 好吧,开始动手! 注意参考的3.0Swiper的API文档需要引入3.0版 ...

  8. [maven(1)]myeclipse2014下如何配置maven

    1.maven工程下载,解压压缩包到某一目录中 2.配置环境变量 在电脑环境变量中新建M2_HOME M2_HOME:D:\MAVEN\apache-maven-3.3.9(类似Java_Home) ...

  9. jQuery图片轮播(一)轮播实现并封装

      利用面向对象自己动手写了一个封装好的jquery轮播对象,可满足一般需求,需要使用时只需调用此对象的轮播方法即可. demo:https://github.com/zsqosos/shopweb ...

  10. spring 学习笔记1

    Spring 学习记录 任何一个成功的应用都是由多个为了实现某一个业务目标而相互协作的组件构成的.这些组件必须彼此了解,并相互协作来完成工作. 在Spring 中,对象无需自己负责查找或创建与其关联的 ...