基于FPGA的CORDIC旋转模式实现sin和cos运算

一、概述

本文介绍了CORDIC旋转模式实现sin和cos运算的算法原理,并在此基础上,介绍了CORDIC旋转模式的Verilog HDL实现方案,将复杂的三角函数运算转化成普通的加、减和移位运算,并且模块可综合,最终使用Modelsim进行波形仿真,与MATLAB实现结果进行比较,算法验证通过。

二、CORDIC旋转模式设计原理

CORDIC(Coordinate Rotation Digital Computer,即坐标旋转数字计算方法)是数字信号处理中的常用算法,主要用于三角函数、双曲线、指数、对数的计算。在FPGA平台上,CORDIC是数字信号处理应用(如多输入多输出(MIMO)、波束形成以及其他自适应系统)中实现三角函数运算的一种重要且常用的方案。

如图1所示,假设在直角坐标系中有一个点P1(x1,y1),将点P1绕原点旋转θ角度后,得到点P2(x2,y2),于是可以得到P1和P2的关系。

图1 CORDIC算法原理

转换为矩阵形式为

公式(2)计算的是逆时针旋转时的计算公式,对于顺时针旋转,公式(2)需要修改为:

不妨假设一个变量k,当K为1时,代表逆时针旋转,当K为-1时,代表顺时针旋转,则矩阵可以修改为:

对于第n次迭代,可以推导出如下公式:

对于旋转模式,初始时,令x0=1,y0=0,则n次迭代旋转的计算公式如下:

去掉cos相关的计算,即为伪旋转,如公式(7)所示。

其中,令tan θi = 2-(i-1),即对于第i次迭代,和tan θi相乘的结果为右移(i-1)位,通过反正切即可求出对应的旋转角度,对于20次迭代,使用MATLAB计算对应的旋转角度分别为:

45

26.5650511770780

14.0362434679265

7.12501634890180

3.57633437499735

1.78991060824607

0.895173710211074

0.447614170860553

0.223810500368538

0.111905677066207

0.0559528918938037

0.0279764526170037

0.0139882271422650

0.00699411367535292

0.00349705685070401

0.00174852842698045

0.000874264213693780

0.000437132106872335

0.000218566053439348

0.000109283026720072

对于前20次迭代的形式分别为:第1次迭代旋转45度,第2次迭代旋转26.565度......第20次迭代旋转0.0001度。

由于FPGA不能直接对浮点数进行运算,需要对这些角度乘以65536,进行量化,量化后的结果如下:2949120、1740967、919879、466945、234379、117304、58666、29335、14668、7334、3667、1833、917、458、229、115、57、29、14、7。

经过公式(7)的伪旋转运算后,为了保证结果的正确性,计算结果要乘以伸缩因子,如公式(8)所示,n等于20时,伸缩因子K值为0.607252935009250。最终的计算结果x即为cos值,y即为sin值

三、模块设计与仿真

CORDIC旋转模式计算模块的端口信号如图2所示,in_flag和out_flag分别为输入信号和输出信号有效标志信号,in_alpha为输入角度,这里是对输入角度乘以65536进行量化后的结果;out_cos和out_sin分别为对应角度的余弦值和正弦值,并且是乘以2^24进行量化后的结果。

图2 端口信号

本模块的迭代次数为20次,主要实现步骤如下:

(1)将量化后的20个迭代角度写入寄存器数组中。

(2)输入角度范围为0~360度,需要进行象限判断,将角度限制在0~90度,并得到象限结果。

(3)进行20次旋转迭代,定义旋转角度中间变量,如果旋转角度大于输入角度,则进行顺时针旋转;如果旋转角度小于输入角度,则进行逆时针旋转。

(4)旋转迭代后,寄存输出结果。

(5)对伸缩因子0.607252935009250乘以2^16进行量化,量化后的值为39797,所以寄存输出后的结果要再乘以39797(使用移位和加法操作实现),并将数据右移16位。

(6)根据象限结果判断数据输出,比如迭代计算结果都为整数,如果输入为第三象限的角度,则将迭代计算的结果加上负号再输出。

完成设计模块后,编写TestBench,对模块进行波形仿真。TestBench中要求实例化CORDIC旋转模式运算模块,并生成1~360度的输入角度,最后输出这些角度的sin和cos值。

Modelsim的仿真波形界面如图3所示,将sin和cos的计算结果的数据类型设置成有符号数,并用模拟波形表示,计算结果符合sin和cos的运算规律,符合预期。

图3 sin和cos仿真波形

上一篇文章讲到用DDS生成正弦波波形,从图3的仿真波形可以看出,使用CORDIC旋转模式也可以生成正弦波波形,只需要令输入角度在0~360之间不断循环即可。

将out_cos和out_sin开始的数据和MATLAB的cos和sin函数计算结果(乘以2^24进行量化后)进行比较,如图4所示,结果基本一致。

图4 数据比较结果-数据起始部分

将out_cos和out_sin结尾的数据和MATLAB的cos和sin函数计算结果(乘以2^24进行量化后)进行比较,如图5所示,结果基本一致。

图5 数据比较结果-数据结尾部分

四、工程获取方式

加入知识星球【FPGA设计入门与提高】: https://t.zsxq.com/ytILk

相关推荐
dadaobusi3 小时前
学习:chiesel,scala
学习·fpga开发·scala
爱吃汽的小橘4 小时前
异步FIFO核心揭秘:格雷码与指针同步
fpga开发
璞致电子5 小时前
基于 P201Pro | 接收端基础知识——Costas环锁定后为何仍会错?DQPSK与前导码相位校正(6)
经验分享·fpga开发·ad9361·软件无线电·sdr·qpsk·pzsdr
璞致电子1 天前
基于 AD9361 (PZSDR‑P201Pro) 软件无线电实战综述:从板卡选型、硬件平台升级到 GNU Radio QPSK 完整收发链路
经验分享·嵌入式硬件·fpga开发·软件无线电·sdr·璞致电子
炎龙铠甲会合体1 天前
从 SPEC 到上板:在 Zynq-7020 上用 RTL 手写一个 YOLO 卷积加速器(完整教程)
yolo·fpga开发·axi·芯片验证
FPGA小徐1 天前
Vivado 按键消抖与复位模块代码修复详解:KEY_TOP、key、rst_gen 完整实战
fpga开发
炎龙铠甲会合体1 天前
AXI2ICACHE— AXI4-Full 四路组相联指令 Cache 设计与 UVM 验证
fpga开发·面试·芯片验证
bingcheby1 天前
FMQL15/20/45 (复旦微青龙系列 PSOC)新手使用说明
fpga开发
漫漫长远1 天前
低功耗UPF介绍(一)
笔记·嵌入式硬件·学习·fpga开发
自小吃多2 天前
【Verilog/FPGA】存储器(数组)
嵌入式硬件·fpga开发