一、概述
本文介绍了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