在旋转模式中曾提到:由于每次伪旋转都导致向量模长发生了变化,以Ki表示第i次伪旋转模长补偿因子,所以第i次伪旋转真实旋转的结果应该为:

经过n次伪旋转,得到的伪旋转点最终结果可以表示为:

当n趋近于无穷大时,An逼近1.646760258,令xo=1/An且yo=0即可得到目标旋转角度的正弦、余弦值。

那么,我们现在就让xo=1/An且yo=0且(即x0=1/1.646760258=0.6073),就可以得到z0(旋转角所对应的正弦、余弦值)。

我在想:为什么常量定义中定义的是反正切函数的一半、一半、一半逐个减半,而不是角度一半、一半、一半的减小呢?没想通,反正就是反正切函数的值(角度)逐个减半吧?不对!当然是使用反正切函数的变量值逐个减半更好!因为这样的话逐个将tan>>>(带符号右移)一位就好,要是角度的话一半一半的话绝逼有小数!想出这个CORDIC求解tan、sin、cos的人真的好厉害!!!

verilog代码:

module cordic
(input CLOCK,RESET,input iCall, output oDone,input [31:0]iData,output [31:0]cos,output [31:0]sin,/*输出的x为cos值,输出的y为sin值,x=qx,y=qy*/output [31:0]q_deg,q_y,q_x
);reg [31:0] atan [15:0];//声明atan反正切函数常量表,该常量表从tan(45)度开始每次减小一半儿initial beginatan[0] = 32'd2949120; atan[1] = 32'd1740992; atan[2] = 32'd919872; atan[3] = 32'd466944;atan[4] = 32'd234368; atan[5] = 32'd117312; atan[6] = 32'd58688; atan[7] = 32'd29312; atan[8] = 32'd14656; atan[9] = 32'd7360; atan[10] = 32'd3648; atan[11] = 32'd1856; atan[12] = 32'd896;  atan[13] = 32'd448; atan[14] = 32'd256; atan[15] = 32'd128;end//带符号位的寄存器声明reg signed [31:0]x,y,tx,ty,deg;reg [7:0]i;reg isDone;always @ ( posedge CLOCK or negedge RESET )if( !RESET )begin{ x,y,tx,ty,deg } <= { 32'd0,32'd0,32'd0,32'd0,32'd0 };i <= 8'd0;isDone <= 1'b0;endelse if( iCall )case( i )0:begin x <= 0.607253 * 65536; y <= 32'd0; deg <= iData << 16; i <= i + 1'b1; end1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16:/*在剩余角度大于0时,需要继续逆时针旋转,在单位圆上逆时针旋转的话横坐标会减小,纵坐标会增大*/if( deg > 0 )beginty = y >>> i-1;tx = x >>> i-1;x <= x - ty;y <= y + tx;deg <= deg - atan[i-1];i <= i + 1'b1;endelse/*在剩余角度小于0时候,需要顺时针旋转,顺时针旋转的话纵坐标会减小,横坐标会增大*/beginty = y >>> i-1;tx = x >>> i-1;x <= x + ty ;y <= y - tx ;deg <= deg + atan[i-1];i <= i + 1'b1;end17:begin isDone <= 1'b1; i <= i + 1'b1; end18:begin isDone <= 1'b0; i <= 8'd0; endendcaseassign oDone = isDone;assign cos = x;assign sin = y;assign { q_deg,q_y,q_x } = { deg,y,x };endmodule

仿真代码:

`timescale 1ns/1ns
module cordic_tb;reg clk;  //系统时钟
reg rst_n;//复位信号
reg iCall;//模块调用信号
reg [31:0]iData; //待求角度
wire oDone;      //迭代完成标志
wire [31:0]cos;  //cos值
wire [31:0]sin;  //sin值
wire [31:0]deg_left; //剩余角度
cordic u0(
.CLOCK(clk),
.RESET(rst_n),
.iCall(iCall),
.oDone(oDone),
.iData(iData),
.cos(cos),
.sin(sin),/*输出的x为cos值,输出的y为sin值,x=qx,y=qy*/
.q_deg(deg_left)
);initial begin
clk=0;
forever #5 clk=~clk;
end initial begin
rst_n=0;
#10;
rst_n=1;
end reg [7:0]i;
always@(posedge clk or negedge rst_n)
if(~rst_n)
begini<=8'd0;iCall<=1'b0;iData<=32'd0;
end
else
case(i)
0: //z=30beginif(oDone)beginiCall<=1'b0;i<=i+1'b1;end else beginiCall<=1'b1;iData<=32'd30;end end
1: //z=45beginif(oDone)beginiCall<=1'b0;i<=i+1'b1;end else beginiCall<=1'b1;iData<=32'd45;end  end
2: //z=60beginif(oDone)beginiCall<=1'b0;i<=i+1'b1;end else beginiCall<=1'b1;iData<=32'd60;end  end
3: //z=75beginif(oDone)beginiCall<=1'b0;i<=i+1'b1;end else beginiCall<=1'b1;iData<=32'd75;end  end
4: //z=90beginif(oDone)beginiCall<=1'b0;i<=i+1'b1;end else beginiCall<=1'b1;iData<=32'd90;end end 5:i<=i;endcase
endmodule

仿真结果:

真实结果         迭代结果

sin30=0.5000   32769/65536=0.5000

cos30=0.8660   56759/65536=0.8661

sin45=0.7071   46341/65536=0.7071

cos45=0.7071   46342/65536=0.7071

sin60=0.8660   56759/65536=0.8661

cos60=0.5000    32769/65536=0.5000

cordic的FPGA实现(三)sin、cos函数运算与源码分析相关推荐

  1. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析-[Android取经之路]

    摘要:本节主要来讲解Android10.0 logd.logcat读写日志源码内容 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...

  2. Java的三种代理模式【附源码分析】

    Java的三种代理模式&完整源码分析 代理模式分为两种,静态代理和动态代理,动态代理包括JDK动态代理和Cglib动态代理. 静态代理 静态代理在使用时,需要定义接口或者父类,被代理对象与代理 ...

  3. Bytom Dapp 开发笔记(三):Dapp Demo前端源码分析

    本章内容会针对比原官方提供的dapp-demo,分析里面的前端源码,分析清楚整个demo的流程,然后针对里面开发过程遇到的坑,添加一下个人的见解还有解决的方案. 储蓄分红合约简述 为了方便理解,这里简 ...

  4. Android服务函数远程调用源码分析

    在Android服务查询完整过程源码分析中介绍了客户进程向ServiceManager进程查询服务的完整过程,ServiceManager进程根据服务名称在自身维护的服务链表中查找ServiceMan ...

  5. 全景视频拼接(三)--并查集法及源码分析

    原文: http://blog.csdn.net/skeeee/article/details/20471949 1.简述 在实现多图像无序输入的拼接中,我们先使用surf算法对任意两幅图像进行特 ...

  6. Kylin源码分析系列三—rowKey编码

    Kylin源码分析系列三-rowKey编码 注:Kylin源码分析系列基于Kylin的2.5.0版本的源码,其他版本可以类比. 1. 相关概念 前面介绍了Kylin中Cube构建的流程,但Cube数据 ...

  7. Android源码分析-PackageManagerService(PMS)源码分析(三)- queryIntentActivities函数来查找activity

    queryIntentActivities函数的作用: 在Android应用程序开发中,用startActivity可以开启另外一个Activity或应用.startActivity函数必须包含Int ...

  8. kubeadm源码分析(内含kubernetes离线包,三步安装)

    k8s离线安装包 三步安装,简单到难以置信 kubeadm源码分析 说句实在话,kubeadm的代码写的真心一般,质量不是很高. 几个关键点来先说一下kubeadm干的几个核心的事: kubeadm ...

  9. Ant Design源码分析(三):Wave组件

    Wave组件效果预览 在上一篇文章Button组件的源码分析中遇到了一个Wave组件, Wave组件在Ant design中提供了通用的表单控件点击效果,在自己阅读源码之前,也并没有过更多留心过在这些 ...

最新文章

  1. 5行Python代码实现图像分割
  2. ceph rados命令使用
  3. 《Java核心技术 卷Ⅱ 高级特性(原书第10版)》一3.7.5 使用StAX写出XML文档
  4. js 对象深拷贝_这一次,彻底理解JavaScript深拷贝
  5. python从list列表中选出一个数和其对应的坐标
  6. 通过连接实例解读TCP/IP协议
  7. 「LOJ 2289」「THUWC 2017」在美妙的数学王国中畅游——LCT泰勒展开
  8. Scapy学习笔记二
  9. AS3 in FlashDevelop
  10. Jest中Mock网络请求
  11. halcon显示坐标_机器视觉之halcon入门(10)-一文弄懂halcon例程:color_fuse.hdev
  12. .net垃圾回收学些【The Truth of garbage collection】【续】
  13. 在项目中经历生死的系统,才会成熟
  14. 按学号查找学生信息 用c语言表达,学生信息管理系统C语言编程.docx
  15. 《集体智慧编程》第8章 构建价格模型 个人笔记
  16. 什么是IEC球压测试?
  17. Stable Baselines/用户向导/矢量化环境
  18. 独家深挖!F1赛车协会“刹车表现”是如何进行数据分析的?
  19. 《软件工程》实验一:可行性分析
  20. 安卓自动化工具:解锁屏幕+打开支付宝蚂蚁森林+收取能量+种树浇水+自动退出

热门文章

  1. java messagepack_MessagePack解析实例Java
  2. CCNA的笔记转载的
  3. 为什么merge的时候要用squash
  4. 【算法题解】24. 模拟机器人行走
  5. PCL区域生长分割算法
  6. 基于区块链的p2p平台治理方案
  7. 用户运营几个阶段具体怎么做?
  8. 有限扩散集团凝聚模型(DLCA)第三讲:流动水流中的凝聚模拟(1)
  9. python API 源码
  10. CTR --- AFM论文阅读笔记,及tf2复现