1. 背景
CORDIC(Coordinate Rotation Digital Computer)坐标旋转数字计算机是一种计算三角函数,双曲函数和其他数学函数的有效技术。CORDIC仅使用加法,减法,位移和表查找来执行简单计算,这些计算在FPGA中以及更一般地在硬件中实现是有效的。设计人员必须在结果的准确性,性能和设计的资源利用率之间进行仔细权衡。
CORDIC背后的核心思想是在二维平面中有效地执行一组矢量旋转。 通过用一些简单的控制决策使用这些旋转,我们可以执行各种基本操作,例如三角函数,双曲线函数和对数函数,实数和复数乘法,以及矩阵分解和分解。 CORDIC已广泛应用于各种应用,包括信号处理,机器人,通信和许多科学计算。 CORDIC通常用于FPGA设计,因为它的资源使用量很小。
CORDIC算法的基本目标是以有效的方式执行一系列旋转。 让我们首先考虑如何进行轮换。 在二维中,旋转矩阵是
CORDIC使用迭代算法将矢量v旋转到某个角度目标,这取决于CORDIC正在执行的功能。 一次旋转是
vi=Ri⋅vi−1
v
i
=
R
i
⋅
v
i
−
1
形式的矩阵向量乘法。 因此,在CORDIC的每次迭代中,我们执行以下操作来执行一次旋转,即矩阵向量乘法:
写出线性方程,新旋转矢量的坐标是:
再次考虑旋转矩阵
我们可以得到:
如果 tan(θi)=2−i tan ( θ i ) = 2 − i ,则
使用 σi σ i 来表示旋转的方向,则
累积比例因子是:
处理增益(processing gain):
i | 2−i 2 − i | Rotating Angle | Scaling Factor | CORDIC Gain |
---|---|---|---|---|
0 | 1.0 | 45.000∘ 45.000 ∘ | 1.41421 | 1.41421 |
1 | 0.5 | 26.565∘ 26.565 ∘ | 1.11803 | 1.58114 |
2 | 0.25 | 14.036∘ 14.036 ∘ | 1.03078 | 1.62980 |
3 | 0.125 | 7.125∘ 7.125 ∘ | 1.00778 | 1.64248 |
4 | 0.0625 | 3.576∘ 3.576 ∘ | 1.00195 | 1.64569 |
5 | 0.03125 | 1.790∘ 1.790 ∘ | 1.00049 | 1.64649 |
6 | 0.015625 | 0.895∘ 0.895 ∘ | 1.00012 | 1.64669 |
3. 计算正余弦
#include "ap_int.h"
#include "ap_fixed.h"
#define NUM_ITERATIONS 7
typedef ap_fixed<8, 2, AP_RND, AP_SAT> COS_SIN_TYPE;
typedef ap_fixed<8, 2, AP_RND, AP_SAT> THETA_TYPE;
// The file cordic.h holds definitions for the data types and constant values
#include "cordic.h"
// The cordic_phase array holds the angle for the current rotation
THETA_TYPE cordic_phase[NUM_ITERATIONS] = {45, 26.565, 14.036, 7.125,
3.576, 1.790, 0.895};
void cordic(THETA_TYPE theta, COS_SIN_TYPE &s, COS_SIN_TYPE &c)
{
// Set the initial vector that we will rotate
// current_cos = I; current_sin = Q
COS_SIN_TYPE current_cos = 0.60735;
COS_SIN_TYPE current_sin = 0.0;
// Factor is the 2^(-L) value
COS_SIN_TYPE factor = 1.0;
// This loop iteratively rotates the initial vector to find the
// sine and cosine values corresponding to the input theta angle
for (int j = 0; j < NUM_ITERATIONS; j++) {
// Determine if we are rotating by a positive or negative angle
int sigma = (theta < 0) ? -1 : 1;
// Save the current_cos, so that it can be used in the sine calculation
COS_SIN_TYPE temp_cos = current_cos;
// Perform the rotation
current_cos = current_cos - current_sin * sigma * factor;
current_sin = temp_cos * sigma * factor + current_sin;
// Determine the new theta
theta = theta - sigma * cordic_phase[j];
// Calculate next 2^(-L) value
factor = factor >> 1;
}
// Set the final sine and cosine values
s = current_sin; c = current_cos;
}
此代码接近“软件”版本。它可以通过多种方式进行优化,以提高性能,减少面积。
位宽的改变