最近学习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. springboot scheduled并发配置

    本文介绍如何使用springboot的sheduled实现任务的定时调度,并将调度的任务实现为并发的方式. 1.定时调度配置scheduled 1)注册定时任务 package com.xiaoju. ...

  2. 记录一次因为硬盘写满造成的redis无法连接

    缘起: 今天早晨收到报警,服务不干活了,赶紧起来看问题... 为了尽快让服务可用,尝试重启服务,发现服务起不来,报错 redis connection failed! 看起来是redis挂了,但是发现 ...

  3. jquery事件使用方法总结

    jquery提供了许多的事件处理函数,学习前端一段时间了,下面对其总结一下,梳理一下知识点. 一.鼠标事件 1. click():鼠标单击事件 $div = $("div") $d ...

  4. 前端魔法堂——异常不仅仅是try/catch

    前言  编程时我们往往拿到的是业务流程正确的业务说明文档或规范,但实际开发中却布满荆棘和例外情况,而这些例外中包含业务用例的例外,也包含技术上的例外.对于业务用例的例外我们别无它法,必须要求实施人员与 ...

  5. 声明数组变量/// 计算所有元素的总和/打印所有元素总和/输出/foreach循环/数组作为函数的参数/调用printArray方法打印

    实例 下面是这两种语法的代码示例: double[] myList; // 首选的方法 或 double myList[]; // 效果相同,但不是首选方法 创建数组 Java语言使用new操作符来创 ...

  6. win10 & Ubuntu16 双系统安装

    忽然心血来潮吧,本机在已经安装了win10的背景下,想要再加一个linux系统学习学习,几经波折,终于成功. 博主笔记本里有两块固态,一个250G的装了win10,装的时间不久,镜像是在msdn上下载 ...

  7. Noip2016愤怒的小鸟(状压DP)

    题目描述 题意大概就是坐标系上第一象限上有N只猪,每次可以构造一条经过原点且开口向下的抛物线,抛物线可能会经过某一或某些猪,求使所有猪被至少经过一次的抛物线最少数量. 原题中还有一个特殊指令M,对于正 ...

  8. 使用速卖通开放平台云API调用菜鸟组件实现云打印

    公司是跨境电商,使用速卖通平台卖玩具,我们自己研发的ERP是基于速卖通开放平台API,实现订单的发货提交,打印面单等功能 近期公司要求使用菜鸟组件云打印,去平台里看下,有这个API,如下图所示 实现也 ...

  9. Unity3D手机斗地主游戏开发实战(01)_发牌功能实现

    园子荒废多年,闲来无事,用Unity3D来尝试做一个简单的小游戏,一方面是对最近研究的Unity3D有点总结,一方面跟广大的园友相互学习和提高.话不多说,进入正题~ 一.创建项目 1.创建Unity2 ...

  10. 浅析Java源码之ArrayList

    面试题经常会问到LinkedList与ArrayList的区别,与其背网上的废话,不如直接撸源码! 文章源码来源于JRE1.8,java.util.ArrayList 既然是浅析,就主要针对该数据结构 ...