| |
FPGA实现三角函数利用cordic算法
之前,有简单介绍过cordic算法。Cordic算法是利用迭代的方法,来计算一些复杂的数学运算。在本讲中,利用cordic算法实现三角函数。
从上图中,看出,当输入x的值为0.60725。y的值为0。Z的值为计算的角度值。在迭代过程中,让z趋向于0。最终的迭代结果,x的值就为cosz的值。Y的值就为sinz的值。
上次是用matlab实现的,主要是理解该算法。此次将算法转化为硬件实现。用verilog编写代码,并仿真,看结果。
Matlab中实现的时候,迭代的次数,选取的很大,但是在硬件实现中,这迭代的次数就不能选取的很大,因为迭代次数越大,耗费的资源越多。计算就越慢。因此需要折衷考虑。
本次实现是采用迭代7次的方法,
根据伪代码:
For n=0 to [inf]
If (Z(n)
>= 0) then
X(n
+ 1) := X(n) – (Yn/2^n);
Y(n + 1) := Y(n) + (Xn/2^n);
Z(n
+ 1) := Z(n) – atan(1/2^n);
Else
X(n
+ 1) := X(n) + (Yn/2^n);
Y(n + 1) := Y(n) – (Xn/2^n);
Z(n
+ 1) := Z(n) + atan(1/2^n);
End if;
End for;
首先要将atan(1/2^n)给处理一下。因为这个值是可以预先计算的,因此可以先将对应每次迭代的这个值计算出来。然后再运算中直接运用。
采用16位来表示角度值。最高位为符号位,接着的7位为角度的整数值,最后的8为为角度的小数值。这里精确到小数点后两位。
首先预先计算atan(1/2^n)的值,并用二进制来表示。
迭代值i |
偏转角度 |
偏转角度的正切值 |
0 |
45.0 |
1 |
1 |
26.555051177 |
0.5 |
2 |
14.036243467 |
0.25 |
3 |
7.125016348 |
0.125 |
4 |
3.576334374 |
0.0625 |
5 |
1.78991060824 |
0.03125 |
6 |
0.8951737102 |
0.015625 |
因为角度精确到小数点后两位,并采用16位表示。表示值如下表:
角度值 |
16位二进制值 |
对应十进制值 |
45 |
0_0101101_00000000 |
11520 |
26.56 |
0_0011010_10001111 |
6799 |
14.04 |
0_0001110_00001010 |
3594 |
7.13 |
0_0000111_00100001 |
1825 |
3.58 |
0_0000011_10010100 |
916 |
1.79 |
0_0000001_11001010 |
458 |
0.9 |
0_0000000_11100110 |
230 |
表示小数,需要将小数扩大,用整数来表示:
列如:26.56。整数部分为26。二进制表示为11010。小数0.56.采用8位表示,将数值扩大,143.36,取整数143。用二进制表示为10001111。和上表中数据一样。
其余的依次计算即可。
角度搞定之后,剩下就是输入的值和输出的值了。这里,输入输出都采用17位表示。最高位为符号位,剩下16位为数据位。因为三角函数的输出值最大为1。因此,16位数据位不需要整数表示,全部表示小数。
X的输入0.60725 。二进制表示:
0.60725*2^16 = 39797(四舍五入) = 0_1001101101110100
至于输出的值,只要除以65536,就为对应的小数了。