关于FPGA之CORDIC算法的纯逻辑实现,善良的一休军“https://blog.csdn.net/qq_39210023/article/details/77456031”的博文均给出了较为详细完整的代码,整个算法的思想较为简单,就

是利用迭代流水线的思想,让角度不停逼近所求角度,一般迭代16次就已经比较接近所求角度值:

1、算法实现步骤:

1)设置迭代次数为16,则x0 = 0.607253,y0 = 0(关于初值的设定,上一篇博文有写到)并输入待计算的角度θ,θ在[-99.7°,99.7°]范围内。

2)根据三个迭代公式进行迭代,i从0至15:
xi+1 = xi – d iy i2-i
yi+1 = yi + d ix i2-i
zi+1 = zi - diθi
注:z0 = θ,di与zi同符号。

3) 经过16次迭代计算后,得到的x16 和y16分别为cosθ和sinθ。

2、代码解析:

1)16级流水线迭代实现

always  @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= (din<<);
end
else if(din_vld_ff[]) begin //初始化设置赋值 x0==0.607253*2^16,y0=0;
x[] <= {'b0,COS_LM};
y[] <= ;
z[] <= {'b0,din_ff,16'b0}; //角度初始化设置
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT0;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT0;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT1;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT1;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT2;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT2;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT3;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT3;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT4;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT4;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT5;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT5;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT6;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT6;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT7;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT7;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT8;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT8;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT9;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT9;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT10;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT10;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT11;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT11;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT12;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT12;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT13;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT13;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT14;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT14;
end
end
end always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
x[] <= ;
y[] <= ;
z[] <= ;
end
else if(din_vld_ff[])begin
if(z[][]==)begin
x[] <= x[] - (y[]>>>);
y[] <= y[] + (x[]>>>);
z[] <= z[] - `ROT15;
end
else begin
x[] <= x[] + (y[]>>>);
y[] <= y[] - (x[]>>>);
z[] <= z[] + `ROT15;
end
end
end

2)打拍同步

这点是我看了博主“洋葱洋葱”的代码,发现的简洁打拍写法。

a、din_vld是单比特信号,假设信号din_vld打4拍输入,可以对比下简洁写法和传统写法的代码量:

//传统写法:将信号din_vld_ff打4拍
always @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
din_vld_ff <=;
din_vld_ff0 <= ;
din_vld_ff1 <= ;
din_vld_ff2 <= ;
end
else begin
din_vld_ff0 <= din_vld_ff;
din_vld_ff1 <= din_vld_ff0;
din_vld_ff2 <= din_vld_ff1;
end
end //简洁写法:将信号din_vld_ff打4拍
always @(posedge clk or negedge rst_n )begin
if(rst_n==) begin
din_vld_ff <= () ;
end
else begin
din_vld_ff <= ({din_vld_ff[:],din_vld}) ; //din_vld为1bit
end
end

以上是单比特din_vld打4拍的对比写法,假如是要打十几拍,可以明显看出简洁写法的代码量少很多,这种打拍子的写法值得推崇。

b、din_vld是多比特信号,假设din_vld同样打4拍输入,利用简洁写法可以写成:

always @(posedge clk or negedge rst_n )begin
if(rst_n==) begin
din_vld_ff <= () ;
end
else begin
din_vld_ff <= ({din_vld_ff[5:],din_vld}) ; //din_vld为2bit
end
end

3)反正切函数,要注意由于θ在[-99.7°,99.7°]范围内,因此在角度输入时要注意换成第一、第四象限,最后结果输出时要注意还原成真实角度。

always  @(posedge clk or negedge rst_n)begin
if(rst_n=='b0)begin
din_ff <= ;
flag <= ;
end
else if(din_vld)begin
if(din<)begin
din_ff = din;
flag = ;
end
else if(din<)begin
din_ff = din-;
flag = ;
end
else if(din<)begin
din_ff = din-;
flag = ;
end
else begin
din_ff = din-;
flag = ;
end
end
end
//角度还原为真实值
always @(posedge clk or negedge rst_n )begin
if(rst_n==) begin
dout_sin <= () ;
end
else if(flag_ff[:]==)begin //第一象限,y(16) = sin(x)
dout_sin <= (y[]) ;
end
else if(flag_ff[:]==)begin //第二象限,Sin(X)=Sin(A+90)=CosA,Cos(X)=Cos(A+90)=-SinA
dout_sin <= (x[]) ;
end
else if(flag_ff[:]==)begin //第三象限,the Sin(X)=Sin(A+180)=-SinA,Cos(X)=Cos(A+180)=-CosA
dout_sin <= ~(y[]) + 'b1 ;
end
else if(flag_ff[:]==)begin //第四象限,the Sin(X)=Sin(A+270)=-CosA,Cos(X)=Cos(A+270)=SinA
dout_sin <= ~(x[])

至此,基于FPGA的cordic算法代码实现需要注意的问题就讨论到这里。

FPGA之CORDIC算法实现_代码实现(下)的更多相关文章

  1. FPGA之CORDIC算法实现_理论篇(上)

    关于cordic的算法原理核心思想就是规定好旋转角度,然后通过不停迭代逐步逼近的思想来实现数学求解,网上关于这部分的资料非常多,主要可以参考: 1)https://blog.csdn.net/qq_3 ...

  2. 基于FPGA的Cordic算法实现

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

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

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

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

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

  5. cordic算法的fpga实现

    cordic算法参考:http://wenku.baidu.com/view/6c623aa8910ef12d2bf9e732.html 这是百度文库的一个文档,详细介绍了cordic算法的基本内容. ...

  6. [黑金原创教程] FPGA那些事儿《数学篇》- CORDIC 算法

    简介 一本为完善<设计篇>的书,教你CORDIC算法以及定点数等,内容请看目录. 贴士 这本教程难度略高,请先用<时序篇>垫底. 目录 Experiment 01:认识CORD ...

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

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

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

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

  9. Cordic算法——verilog实现

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

随机推荐

  1. Linux server配置安装Java,Tomcat服务器

    系统:Ubuntu 16.04 dev_desktop 1.Java安装并配置环境变量 (1)从Java官方网站下载最新版JDK: http://www.oracle.com/technetwork/ ...

  2. Python学习---Python的框架基础学习

    框架基础 框架实质: 所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端 B/S结构的响应: import socket def handle_requ ...

  3. Sqoop操作集合

    1.在hive中建一个与mysql中一模一样的表 sqoop create-hive-table --connect jdbc:mysql://***.**.***.**:3306/数据库名称 --t ...

  4. 为什么TCP协议终止链接要四次?

    为什么TCP协议终止链接要四次? 1.当主机A确认发送完数据且知道B已经接受完了,想要关闭发送数据口(当然确认信号还是可以发),就会发FIN给主机B. 2.主机B收到A发送的FIN,表示收到了,就会发 ...

  5. 微软最新设计Fluent Design System初体验

    微软最新设计Fluent Design System初体验 本文图片不全!建议移步知乎专栏查看!!! https://zhuanlan.zhihu.com/p/30582886 原创 2017-11- ...

  6. strerror的坑

    最近写的一段代码,总是出core,精简了一下,稳定复现. #include <stdio.h> #include <errno.h> int main() { printf(& ...

  7. Hadoop学习之路(二十)MapReduce求TopN

    前言 在Hadoop中,排序是MapReduce的灵魂,MapTask和ReduceTask均会对数据按Key排序,这个操作是MR框架的默认行为,不管你的业务逻辑上是否需要这一操作. 技术点 MapR ...

  8. BurpSuite Intruder 4种攻击模式

    BurpSuite intruder attack-type 4种爆破模式 Sniper 单参数爆破,多参数时同一个字典按顺序替换各参数,总之初始值有一个参数不变 Battering ram 多参数同 ...

  9. array和matrix

    array:数组 matrix:矩阵 list:列表 a = [[1,2,3],[4,5,6]] 两种array的定义方式,第一种方式可以看出list不是array,但却有很大的联系 a = np.a ...

  10. 每天to do list

    至少写一页书 写代码做一个实验 读10+页专业书 一年时间,如果经济状况没有改善的话,回归企业.