cordic算法原理及verilog实现

cordic算法原理及verilog实现

  1. 算法原理 



    由此我们可以推出,当(x0,y0)与(x1,y1)的夹角为Θ时,满足如下关系: 
     
    由此可得,当(x1,y1)长度为1时,,当根据坐标旋转法旋转Θ角度后,坐标点变为(1,0)。因此,根据cordic算法求就是将初始线段旋转至(1,0)后,所得的(x,y)的值。 
    下面,我们将这些旋转步骤细化,看看每一步是如何工作的。 
    假设第n次旋转为顺时针旋转时,会得到如下结果: 
     
    此时提取会得到如下公式: 
     
    令每次旋转的角度Θ满足,则每次旋转最终的角度Θ满足:,且当顺时针旋转时,逆时针旋转时。结合以上公式我们可以得到: 因此每次迭代都能提出来,最后他们的乘积是个常数K: 
    因此我们的计算过程是从点(1,0)开始,每次旋转角度,Xn与Yn每次只需做移位运算即可。最终当等于Θ时,所得到的即为
  2. 基于FPGA的算法设计 
    采用十六位补码的形式来表示输入角度和输出结果。输入角度采用角度制。十六位补码形式为:第一位表示符号位,第二位到第九位共八位表示整数位,第十位到第十六位共七位表示小数位。 
    采用十六级流水线的形式实现算法。每级流水线实现一次迭代。迭代开始之前需要先计算满足的Θ的值,并将他们转换成角度的表示形式存储起来作为中间变量。 
    在开始迭代之前,还要先将输入的角度转换为第一象限0-90度之间的角度进行迭代计算,并用一个flag位标识角度的正负。若为输入角度为负,则flag值为1,若角度为正,则flag值为0。此外还有九组临时变量x、y、z分别用来存储对应的横坐标、纵坐标以及剩余角度。 
    开始迭代之后,每次迭代都要根据cordic算法推出的公式计算x、y、z的值并将它们存储在中间变量中。 
    迭代完成之后,根据flag以及x8、y8的值计算最终的结果。如果flag值为1说明输入角度为负数,则将sinΘ等于(~y8+1),否则sinΘ等于y8。无论flag值为多少,cosΘ均等与x8。
  3. verilog代码实现
module cordic_2(rst,clk,datain,sin,cos);
input rst,clk;
input[15:0] datain;
output[15:0]sin,cos;
reg[15:0]sin,cos;

parameter[15:0] rot1 = 16‘b0000110101001000,
rot2 = 16‘b0000011100101110,
rot3 = 16‘b0000001110010000,
rot4 = 16‘b0000000111001010,
rot5 = 16‘b0000000011100101,
rot6 = 16‘b0000000001110011,
rot7 = 16‘b0000000000111001,
rot0 = 16‘b0001011010000000;

//parameter[15:0] k = 16‘b0000000001001110;
parameter[15:0] k = 16‘h004d;

reg[15:0] x0,y0,z0;
reg[15:0] x1,y1,z1;
reg[15:0] x2,y2,z2;
reg[15:0] x3,y3,z3;
reg[15:0] x4,y4,z4;
reg[15:0] x5,y5,z5;
reg[15:0] x6,y6,z6;
reg[15:0] x7,y7,z7;
reg[15:0] x8,y8,z8;

reg flag0,flag1,flag2,flag3,flag4,flag5,flag6,flag7,flag8;

//initial
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x0 <= 0;
        y0 <= 0;
        z0 <= 0;
        flag0 <= 0;
    end
    else if(datain == 0)
    begin
        x0 <= 0;
        y0 <= 0;
        z0 <= 0;
        flag0 <= 0;
    end
    else
    begin
        x0 <= k;
        y0 <= 0;
        if(datain[15])
            z0 <= ~(datain-1);
        else
            z0 <= datain;
        flag0 <= datain[15];
    end
end

//1
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x1 <= 0;
        y1 <= 0;
        z1 <= 0;
        flag1 <= 0;
    end
    else
    begin
//      if(z0[15])
//      begin
//          x1 <= x0 + y0;
//          y1 <= x0 - y0;
//          z1 <= z0 + rot0;
//          flag1 <= flag0;
//      end
//      else
//      begin
            x1 <= x0 - y0;
            y1 <= x0 + y0;
            z1 <= z0 - rot0;
            flag1 <= flag0;
//      end
    end
end
//2
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x2 <= 0;
        y2 <= 0;
        z2 <= 0;
        flag2 <= 0;
    end
    else
    begin
        if(z1[15])
        begin
            x2 <= x1 + {y1[15],y1[15:1]};
            y2 <= y1 - {x1[15],x1[15:1]};
            z2 <= z1 + rot1;
            flag2 <= flag1;
        end
        else
        begin
            x2 <= x1 - {y1[15],y1[15:1]};
            y2 <= y1 + {x1[15],x1[15:1]};
            z2 <= z1 - rot1;
            flag2 <= flag1;
        end
    end
end
//3
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x3 <= 0;
        y3 <= 0;
        z3 <= 0;
        flag3 <= 0;
    end
    else
    begin
        if(z2[15])
        begin
            x3 <= x2 + {{2{y2[15]}},y2[15:2]};
            y3 <= y2 - {{2{x2[15]}},x2[15:2]};
            z3 <= z2 + rot2;
            flag3 <= flag2;
        end
        else
        begin
            x3 <= x2 - {{2{y2[15]}},y2[15:2]};
            y3 <= y2 + {{2{x2[15]}},x2[15:2]};
            z3 <= z2 - rot2;
            flag3 <= flag2;
        end
    end
end
//4
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x4 <= 0;
        y4 <= 0;
        z4 <= 0;
        flag4 <= 0;
    end
    else
    begin
        if(z3[15])
        begin
            x4 <= x3 + {{3{y3[15]}},y3[15:3]};
            y4 <= y3 - {{3{x3[15]}},x3[15:3]};
            z4 <= z3 + rot3;
            flag4 <= flag3;
        end
        else
        begin
            x4 <= x3 - {{3{y3[15]}},y3[15:3]};
            y4 <= y3 + {{3{x3[15]}},x3[15:3]};
            z4 <= z3 - rot3;
            flag4 <= flag3;
        end
    end
end
//5
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x5 <= 0;
        y5 <= 0;
        z5 <= 0;
        flag5 <= 0;
    end
    else
    begin
        if(z4[15])
        begin
            x5 <= x4 + {{4{y4[15]}},y4[15:4]};
            y5 <= y4 - {{4{x4[15]}},x4[15:4]};
            z5 <= z4 + rot4;
            flag5 <= flag4;
        end
        else
        begin
            x5 <= x4 - {{4{y4[15]}},y4[15:4]};
            y5 <= y4 + {{4{x4[15]}},x4[15:4]};
            z5 <= z4 - rot4;
            flag5 <= flag4;
        end
    end
end
//6
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x6 <= 0;
        y6 <= 0;
        z6 <= 0;
        flag6 <= 0;
    end
    else
    begin
        if(z5[15])
        begin
            x6 <= x5 + {{5{y5[15]}},y5[15:5]};
            y6 <= y5 - {{5{x5[15]}},x5[15:5]};
            z6 <= z5 + rot5;
            flag6 <= flag5;
        end
        else
        begin
            x6 <= x5 - {{5{y5[15]}},y5[15:5]};
            y6 <= y5 + {{5{x5[15]}},x5[15:5]};
            z6 <= z5 - rot5;
            flag6 <= flag5;
        end
    end
end
//7
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x7 <= 0;
        y7 <= 0;
        z7 <= 0;
        flag7 <= 0;
    end
    else
    begin
        if(z6[15])
        begin
            x7 <= x6 + {{6{y6[15]}},y6[15:6]};
            y7 <= y6 - {{6{x6[15]}},x6[15:6]};
            z7 <= z6 + rot6;
            flag7 <= flag6;
        end
        else
        begin
            x7 <= x6 - {{6{y6[15]}},y6[15:6]};
            y7 <= y6 + {{6{x6[15]}},x6[15:6]};
            z7 <= z6 - rot6;
            flag7 <= flag6;
        end
    end
end
//8
always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        x8 <= 0;
        y8 <= 0;
        z8 <= 0;
        flag8 <= 0;
    end
    else
    begin
        if(z7[15])
        begin
            x8 <= x7 + {{7{y7[15]}},y7[15:7]};
            y8 <= y7 - {{7{x7[15]}},x7[15:7]};
            z8 <= z7 + rot7;
            flag8 <= flag7;
        end
        else
        begin
            x8 <= x7 - {{7{y7[15]}},y7[15:7]};
            y8 <= y7 + {{7{x7[15]}},x7[15:7]};
            z8 <= z7 - rot7;
            flag8 <= flag7;
        end
    end
end

always @(posedge clk or negedge rst)
begin
    if(!rst)
    begin
        sin <= 0;
        cos <= 0;
    end
    else
    begin
        if(flag8)
        begin
            sin <= (~y8)+1;
            cos <= x8;
        end
        else
        begin
            sin <= y8;
            cos <= x8;
        end
    end
end
endmodule

4.结果 
输入值: 

sin值: 

cos值: 

5.参考文献 
cordic算法的verilog实现及modelsim仿真 
cordic算法

时间: 2024-11-05 14:48:05

cordic算法原理及verilog实现的相关文章

一个CORDIC算法在圆周系统下的向量模式下获取角度的Verilog 程序

下面给出一个CORDIC算法在圆周系统下的向量模式下获取角度的Verilog 程序: /*==============================================================================*\        Filename : Cordic.v        Discription : 坐标旋转数字计算方法.通过该算法,对输入的向量坐标进行9次迭代     计算,得到该向量的模值和相角.        \*===============

Adaboost算法原理分析和实例+代码(简明易懂)

Adaboost算法原理分析和实例+代码(简明易懂) [尊重原创,转载请注明出处] http://blog.csdn.net/guyuealian/article/details/70995333     本人最初了解AdaBoost算法着实是花了几天时间,才明白他的基本原理.也许是自己能力有限吧,很多资料也是看得懵懵懂懂.网上找了一下关于Adaboost算法原理分析,大都是你复制我,我摘抄你,反正我也搞不清谁是原创.有些资料给出的Adaboost实例,要么是没有代码,要么省略很多步骤,让初学者

FP Tree算法原理总结

在Apriori算法原理总结中,我们对Apriori算法的原理做了总结.作为一个挖掘频繁项集的算法,Apriori算法需要多次扫描数据,I/O是很大的瓶颈.为了解决这个问题,FP Tree算法(也称FP Growth算法)采用了一些技巧,无论多少数据,只需要扫描两次数据集,因此提高了算法运行的效率.下面我们就对FP Tree算法做一个总结. 1. FP Tree数据结构 为了减少I/O次数,FP Tree算法引入了一些数据结构来临时存储数据.这个数据结构包括三部分,如下图所示: 第一部分是一个项

分布式memcached学习(四)&mdash;&mdash; 一致性hash算法原理

    分布式一致性hash算法简介 当你看到"分布式一致性hash算法"这个词时,第一时间可能会问,什么是分布式,什么是一致性,hash又是什么.在分析分布式一致性hash算法原理之前,我们先来了解一下这几个概念. 分布式 分布式(distributed)是指在多台不同的服务器中部署不同的服务模块,通过远程调用协同工作,对外提供服务. 以一个航班订票系统为例,这个航班订票系统有航班预定.网上值机.旅客信息管理.订单管理.运价计算等服务模块.现在要以集中式(集群,cluster)和分布

POJ1523(求连用分量数目,tarjan算法原理理解)

SPF Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7406   Accepted: 3363 Description Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a

Kmeans聚类算法原理与实现

Kmeans聚类算法 1 Kmeans聚类算法的基本原理 K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一.K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类.通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果. 假设要把样本集分为k个类别,算法描述如下: (1)适当选择k个类的初始中心,最初一般为随机选取: (2)在每次迭代中,对任意一个样本,分别求其到k个中心的欧式距离,将该样本归到距离最短的中心所在的类: (3)利用

【转】两种非对称算法原理:RSA和DH

转自:http://blog.chinaunix.net/uid-7550780-id-2611984.html 两种非对称算法原理:RSA和DH 虽然对称算法的效率高,但是密钥的传输需要另外的信道.非对称算法RSA和DH可以解决密钥的传输问题(当然,它们的作用不限于此).这两个算法的名字都是来自于算法作者的缩写,希望有朝一日能够出现用中国人命名的加密算法.非对称算法的根本原理就是单向函数,f(a)=b,但是用b很难得到a. RSA算法 RSA算法是基于大数难于分解的原理.不但可以用于认证,也可

Canny边缘检测算法原理及其VC实现详解(一)

转自:http://blog.csdn.net/likezhaobin/article/details/6892176 图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值.图象的边缘部分集中了图象的大部分信息,图象边缘的确定与提取对于整个图象场景的识别与理解是非常重要的,同时也是图象分割所依赖的重要特征,边缘检测主要是图象的灰度变化的度量.检测和定位,自从1959提出边缘检测以来,经过五十多年

排序算法原理及实现

算法一:直接插入排序 算法实现原理:就是计算一个新元素是应该放在哪里?每次进来一个都会进行和原来顺序进行重新组合. 代码实现:Java public int[] testInsertionSort(int[] data){ // this methord is very easy. for(int i = 1;i < data.length;i++){ int temp = data[i]; int j =i; while(j>0 && data[j-1]>temp){