使用CORDIC计算平方根
这个例子展示了如何在MATLAB®中使用CORDIC内核算法计算平方根。基于cordic的算法对于许多嵌入式应用都是至关重要的,包括电机控制、导航、信号处理和无线通信。
介绍
CORDIC是坐标旋转数字计算机的首字母缩写。基于Givens旋转的CORDIC算法(见[1,2])是硬件效率最高的算法之一,因为它只需要迭代的shift-add操作。CORDIC算法消除了显式乘法器的需要,适用于计算各种函数,如正弦、余弦、反正弦、反余弦、反正切、矢量幅值、除、平方根、双曲和对数函数。
定点CORDIC算法需要进行如下操作:
1表查找每个迭代
2班每个迭代
3增加每个迭代
注意,对于基于双曲cordic的算法,例如平方根,某些迭代(i = 4,13,40,121,…, k, 3k+1,…),以实现结果收敛。
使用双曲计算模式的CORDIC内核算法
您可以使用CORDIC计算模式算法来计算双曲函数,例如双曲三角函数、平方根、log、exp等。
双曲矢量模式下的Cordic方程
计算采用双曲矢量模式平方根。
对于矢量模式,CORDIC方程如下:
在哪里
如果
,
否则。
此模式提供了以下结果方法
:
在哪里
。
通常选择为一个足够大的常数值。因此,
可能是预先计算好的。
还要注意,对于平方根我们将只使用结果。
CORDIC双曲矢量算法的MATLAB实现
下面是CORDIC双曲矢量核算法的MATLAB代码实现示例(对于标量的情况x
,y
,z
).这段代码既可以用于定点数据类型,也可以用于浮点数据类型。
双曲矢量核
K = 4;用于重复的(3*k + 1)迭代步骤
为Idx = 1:n XTMP = bitsra(x, Idx);%乘以2^(-idx)Ytmp = bitsra(y, idx);%乘以2^(-idx)如果Y < 0 x(:) = x + ytmp;Y (:) = Y + xtmp;z(:) = z - atanhLookupTable(idx);其他的X (:) = X - ytmp;Y (:) = Y - xtmp;z(:) = z + atanhLookupTable(idx);结束
如果idx==k XTMP = bitsra(x, idx);%乘以2^(-idx) ytmp = bitsra(y, idx);%乘以2^(-idx)如果y < 0 x(:) = x + ytmp;Y (:) = Y + xtmp;z(:) = z - atanhLookupTable(idx);Else x(:) = x - ytmp;Y (:) = Y - xtmp;z(:) = z + atanhLookupTable(idx);端k = 3*k + 1;结束结束% idx循环
基于cordic的平方根计算
使用CORDIC双曲矢量核的平方根计算
初值的明智选择允许CORDIC核双曲矢量模式算法计算平方根。
首先,执行以下初始化步骤:
设置为
。
设置为
。
后迭代时,这些初始值会导致以下输出
方法
:
这可以进一步简化如下:
在哪里是上面定义的CORDIC增益。
注意:对于平方根,和
atanhLookupTable
对结果没有影响。因此,和
atanhLookupTable
不使用。
一个CORDIC平方根核的MATLAB实现
下面是CORDIC平方根核算法的MATLAB代码实现示例(对于标量的情况x
和y
).这段代码既可以用于定点数据类型,也可以用于浮点数据类型。
CORDIC平方根内核
K = 4;用于重复的(3*k + 1)迭代步骤
为Idx = 1:n XTMP = bitsra(x, Idx);%乘以2^(-idx)Ytmp = bitsra(y, idx);%乘以2^(-idx)如果Y < 0 x(:) = x + ytmp;Y (:) = Y + xtmp;其他的X (:) = X - ytmp;Y (:) = Y - xtmp;结束
如果idx==k XTMP = bitsra(x, idx);%乘以2^(-idx) ytmp = bitsra(y, idx);%乘以2^(-idx)如果y < 0 x(:) = x + ytmp;Y (:) = Y + xtmp;Else x(:) = x - ytmp;Y (:) = Y - xtmp;端k = 3*k + 1;结束结束% idx循环
此代码与双曲矢量核除了上面的实现z
和atanhLookupTable
不使用。这节省了每次迭代查找1个表和添加1个表的成本。
例子
使用CORDICSQRT函数来计算的近似平方根v_fix
使用10次CORDIC内核迭代:
Step = 2^-7;V_fix = fi(0.5:step:(2-step), 1,20);%范围[.]的定点输入。5、2)镍= 10;CORDIC迭代次数的%X_sqr = cordicsqrt(v_fix, niter);获取CORDIC输出的真实世界值(RWV)进行比较%,并绘制MATLAB参考值与CORDIC平方根值之间的误差X_cdc = double(x_sqr);% CORDIC结果(按An_hp缩放)V_ref = double(v_fix);引用浮点输入值X_ref =√(v_ref);MATLAB参考浮点结果图;次要情节(211);情节(v_ref x_cdc,“r”。, v_ref, x_ref,“b -”);传奇(“CORDIC”,“参考”,“位置”,“东南”);标题(CORDIC平方根(范围内)和MATLAB参考结果);次要情节(212);absErr = abs(x_ref - x_cdc);情节(v_ref absErr);标题(绝对误差(相对于MATLAB SQRT参考结果));
克服算法输入范围限制
许多平方根算法将输入值归一化,,到[0.5,2)范围内。这种预处理通常使用固定的字长归一化来完成,并且可以用于支持小的和大的输入值范围。金宝app
基于cordic的平方根算法实现对超出这个范围的输入特别敏感。函数CORDICSQRT通过基于以下数学关系的归一化方法克服了这种算法范围限制:
,对一些人来说
还有一个偶数
。
因此:
的值在CORDICSQRT函数中和
,上面所描述的,都是在输入的规范化过程中发现的
。
输入的二进制表示中前导零最高有效位(msb)的数量是多少
。这些值是通过一系列按位逻辑和移位找到的。注意:因为
必须是偶数,如果前导零msb的数量是奇数,额外的位移位要做
偶数。这些移位后的结果值就是该值
。
成为基于cordic的平方根内核的输入,其中的近似值为
计算。然后将结果按比例缩放
这样它就回到了正确的输出范围。这是通过一个简单的位移位实现的
位。(向左或向右)移位方向取决于的符号
。
例子
使用CORDIC计算具有较小非负范围的10位定点输入数据的平方根。将基于cordic的算法结果与相同输入范围内的浮点MATLAB参考结果进行比较。
Step = 2^-8;U_ref = 0:step:(0.5-step);输入数组(值范围小)U_in_arb = fi(u_ref,0,10);% 10位无符号定点输入数据值U_len = number (u_ref);Sqrt_ref = sqrt(double(u_in_arb));% MATLAB根号参考结果镍= 10;结果= 0 (u_len, 2);Results (:,2) = sqrt_ref(:);计算用于绘图的等效真实世界值结果。。绘制CORDIC和MATLAB参考结果的真实世界值(RWV)。X_out = cordicsqrt(u_in_arb, niter);Results (:,1) = double(x_out);图;次要情节(211);情节(u_ref结果(:1),“r”。, u_ref, results(:,2),“b -”);传奇(“CORDIC”,“参考”,“位置”,“东南”);标题(CORDIC平方根(小输入范围)和MATLAB参考结果);轴([0 0.5 0 0.75]);次要情节(212);absErr = abs(results(:,2) - results(:,1));情节(u_ref absErr);标题(绝对误差(相对于MATLAB SQRT参考结果));
例子
使用CORDIC计算具有较大正范围的16位定点输入数据的平方根。将基于cordic的算法结果与相同输入范围内的浮点MATLAB参考结果进行比较。
U_ref = 0:5:2500;输入数组(更大范围的值)U_in_arb = fi(u_ref,0,16);% 16位无符号定点输入数据值U_len = number (u_ref);Sqrt_ref = sqrt(double(u_in_arb));% MATLAB根号参考结果镍= 16;结果= 0 (u_len, 2);Results (:,2) = sqrt_ref(:);计算用于绘图的等效真实世界值结果。。绘制CORDIC和MATLAB参考结果的真实世界值(RWV)。X_out = cordicsqrt(u_in_arb, niter);Results (:,1) = double(x_out);图;次要情节(211);情节(u_ref结果(:1),“r”。, u_ref, results(:,2),“b -”);传奇(“CORDIC”,“参考”,“位置”,“东南”);标题(CORDIC平方根(大输入范围)和MATLAB参考结果);轴([0 2500 0 55]);次要情节(212);absErr = abs(results(:,2) - results(:,1));情节(u_ref absErr);标题(绝对误差(相对于MATLAB SQRT参考结果));
参考文献
Jack E. Volder, CORDIC三角计算技术,电子计算机学报,卷EC-8, 1959年9月,第330-334页。
Ray Andraka,基于FPGA的计算机CORDIC算法的研究,1998年ACM/SIGDA第六届现场可编程门阵列国际研讨会论文集,1998年2月22-24日,pp191-200