0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深度解析CORDIC算法原理

FPGA设计论坛 来源:至芯科技 2024-04-29 16:48 次阅读

CORDIC算法详解

1 平面坐标系旋转

CORDIC算法的思想是通过迭代的方法,使得累计旋转过的角度的和无限接近目标角度。它是一种数值计算逼近的方法,运算只有移位和加减。

通过圆坐标系可以了解CORDIC算法的基本思想,如图1所示,初始向量( x 1 , y 1 ) left( x_{1},y_{1} ight)(x1,y1)旋转θ hetaθ角度之后得到向量( x 2 , y 2 ) left( x_{2},y_{2} ight)(x2,y2),两者之间满足(公式1)关系。

2fd0c67e-0605-11ef-a297-92fbcf53809c.png

图1 CORDIC算法原理示意图

{ x 2 = x 1 cos ⁡ θ n − y 1 sin ⁡ θ n y 2 = y 1 cos ⁡ θ n − x 1 sin ⁡ θ n left{ egin{matrix} x_{2} = x_{1} cos heta_{n} - y_{1} sin heta_{n} \ y_{2} = y_{1} cos heta_{n} - x_{1}sin heta_{n} \ end{matrix} ight.{x2=x1cosθn−y1sinθny2=y1cosθn−x1sinθn

通过提取因数cos ⁡ θ cos hetacosθ,方程式可以改写成下面的形式:

x 2 = x 1 cos ⁡ θ − y 1 sin ⁡ θ = cos ⁡ θ ( x 1 − y 1 tan ⁡ θ ) y 2 = y 1 cos ⁡ θ − x 1 sin ⁡ θ = cos ⁡ θ ( y 1 + x 1 tan ⁡ θ ) egin{matrix} x_{2} = x_{1} cos heta - y_{1} sin heta = cos hetaleft( x_{1} - y_{1} an heta ight) \ y_{2} = y_{1} cos heta - x_{1}sin heta = cos hetaleft( y_{1} + x_{1} an heta ight) \ end{matrix}x2=x1cosθ−y1sinθ=cosθ(x1−y1tanθ)y2=y1cosθ−x1sinθ=cosθ(y1+x1tanθ)

2 伪旋转

如果去掉cos ⁡ θ cos hetacosθ,我们可以的到伪旋转方程式(公式3),即旋转的角度是正确的,但是x xx,y yy的值增加了cos ⁡ − 1 θ cos^{- 1} hetacos−1θ倍,由于cos ⁡ − 1 θ > 1 cos^{- 1} heta > 1cos−1θ>1,所以模值变大。这里并不能通过数学方法去除cos ⁡ θ cos hetacosθ项,但是可以化简坐标平面旋转的计算。

x ^ 2 = x 1 − y 1 tan ⁡ θ y ^ 2 = y 1 + x 1 tan ⁡ θ egin{matrix} {widehat{x}}_{2} = x_{1} - y_{1} an heta \ {widehat{y}}_{2} = y_{1} + x_{1} an heta \ end{matrix}x2=x1−y1tanθy2=y1+x1tanθ

2ff140f2-0605-11ef-a297-92fbcf53809c.png

图2 去除cos ⁡ θ cos hetacosθ后伪坐标系

3 CORDIC方法

这里为了便于硬件的计算,采用迭代的思想,旋转角度θ hetaθ可以通过若干步实现,每一步旋转一个角度θ i heta^{i}θi。并且约定每一次旋转的角度的正切值为2的倍数,即tan ⁡ θ i = 2 − i { an heta^{i} = 2}^{- i}tanθi=2−i。下面表格是用于CORDIC算法中每个迭代i的旋转角度。这样,乘以正切值就可以变成移位操作。

表1 迭代角度θ i heta^{i}θi正切值

i ii θ i heta^{i}θi(degree) tan ⁡ θ i = 2 − i { an heta^{i} = 2}^{- i}tanθi=2−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

4 角度累加器

引入控制算子d i d_{i}di,用于确定旋转的方向。其中第i步顺时针旋转时d i = − 1 d_{i} = - 1di=−1,逆时针旋转d i = 1 d_{i} = 1di=1。前面的伪旋转坐标方程现在可以表示为:

x i + 1 = x i − d i 2 − i y i y i + 1 = y i + d i 2 − i x i egin{matrix} x_{i + 1} = x_{i} - {d_{i}2^{- i} y}_{i} \ y_{i + 1} = y_{i} + {d_{i} 2^{- i} x}_{i} \ end{matrix}xi+1=xi−di2−iyiyi+1=yi+di2−ixi

这里,我们引入第三个方程,被称为角度累加器,用来在每次迭代过程中追踪累加的旋转角度,表示第n次旋转后剩下未旋转的角度,定义为

z i + 1 = z i − d i θ i z_{i + 1} = z_{i} - d_{i} heta^{i}zi+1=zi−diθi,其中d i = ± 1 d_{i} = pm 1di=±1

5移位-加法算法

因此,原始的算法现在已经被简化为使用向量的伪旋转方程式(公式6)来表示迭代(移位-加法)算法。

2次移位;
(2 − i 2^{- i}2−i用移位实现,每右移n位就把原来数值乘以2的-i次方了)

1次查找表;(每一次迭代都会有一个固定角度θ i heta^{i}θi的累加,这个角度是2 − i 2^{- i}2−i对应的角度值,使用查表实现。θ i = arc tan ⁡ 2 − i heta^{i} = { ext{arc} an}2^{- i}θi=arctan2−i)

3次加法;(x,y,z的累加,共三次)

x i + 1 = x i − d i 2 − i y i y i + 1 = y i + d i 2 − i x i z i + 1 = z i − d i θ i egin{matrix} x_{i + 1} = x_{i} - {d_{i} 2^{- i} y}_{i} \ y_{i + 1} = y_{i} + {d_{i} 2^{- i} x}_{i} \ z_{i + 1} = z_{i} - d_{i} heta^{i} \ end{matrix}xi+1=xi−di2−iyiyi+1=yi+di2−ixizi+1=zi−diθi

6 伸缩因子

当简化算法以伪旋转时,cos ⁡ θ cos hetacosθ项被忽略,这样( x n , y n ) left( x_{n},y_{n} ight)(xn,yn)就被伸缩了K n K_{n}Kn倍。如果迭代次数已知,可以预先计算伸缩因子K n K_{n}Kn。同样1 / K n 1/K_{n}1/Kn也可被预先计算以得到( x n , y n ) left( x_{n},y_{n} ight)(xn,yn)的真值。

K n = ∏ n 1 cos ⁡ θ i = ∏ n ( 1 + 2 − 2 i ) K_{n} = prod_{n}^{}frac{1}{cos heta^{i}} = prod_{n}^{}left( sqrt{1 + 2^{- 2i}} ight)Kn=n∏cosθi1=n∏(1+2−2i)

这里K n − > 1.64676 K_{n} - > 1.64676Kn−>1.64676,当n − > ∞ n - > inftyn−>∞

1 / K n − > 0.607253 1/K_{n} - > 0.6072531/Kn−>0.607253,当n − > ∞ n - > inftyn−>∞

7 旋转模式

CORDIC方法有两种模式,旋转模式和向量模式。工作模式决定了控制算子d i d_{i}di的条件。在旋转模式中,旋转剩余角度初始变量z 0 = θ z_{0} = hetaz0=θ,经过n次旋转后,使z 0 = 0 z_{0} = 0z0=0。整个旋转过程可以表示为一系列旋转角度不断偏摆,从而逼近所需旋转角度的迭代过程。n次迭代后可以得到:

x n = K n ( x 0 cos ⁡ z 0 − y 0 sin ⁡ z 0 ) y n = K n ( y 0 cos ⁡ z 0 + x 0 sin ⁡ z 0 ) z n = 0 egin{matrix} x_{n} = K_{n}left( x_{0} cos z_{0} - y_{0} sin z_{0} ight) \ y_{n} = K_{n}left( y_{0} cos z_{0} + x_{0} sin z_{0} ight) \ z_{n} = 0 \ end{matrix}xn=Kn(x0cosz0−y0sinz0)yn=Kn(y0cosz0+x0sinz0)zn=0

通过设置x 0 = 1 / K n = 0.6073 x_{0} = 1/K_{n} = 0.6073x0=1/Kn=0.6073和y 0 = 0 y_{0} = 0y0=0可以计算cos ⁡ z 0 cos z_{0}cosz0和sin ⁡ z 0 sin z_{0}sinz0。分析可知CORDIC算法在圆周系统旋转模式下可以用来计算一个输入角的正弦值、余弦值。

x n = K n ( x 0 cos ⁡ z 0 − y 0 sin ⁡ z 0 ) = cos ⁡ θ y n = K n ( y 0 cos ⁡ z 0 + x 0 sin ⁡ z 0 ) = sin ⁡ θ egin{matrix} x_{n} = K_{n}left( x_{0} cos z_{0} - y_{0} sin z_{0} ight) = cos heta \ y_{n} = K_{n}left( y_{0} cos z_{0} + x_{0} sin z_{0} ight) = sin heta \ end{matrix}xn=Kn(x0cosz0−y0sinz0)=cosθyn=Kn(y0cosz0+x0sinz0)=sinθ

30058684-0605-11ef-a297-92fbcf53809c.png

图 3 旋转模式角度逼近

8 象限判断

对于任意角度θ hetaθ,都可以通过旋转一系列小角度来i完成。第一次迭代旋转45°,第二次迭代旋转26.6°,第三次迭代旋转14°。很显然,每次旋转的方向都影响到最终的累计角度。在-99.7°< θ heta θ< 99.7°的范围内任意角度都可以旋转。对于该角度范围之外的角度,可以通过三角函数等式转化成该范围内的角度。因此设计时通常把角度 θ heta θ转化到第一象限角,根据 θ heta θ所在的圆坐标系象限获得 x n x_{n} xn和 y n y_{n} yn。

9溢出处理

通过表2可以看出,把初始θ hetaθ角度设置为90°,由于x 0 x_{0}x0赋的初值存在误差(一般是偏大),最终获得的x n x_{n}xn和y n y_{n}yn是有可能大于1的。所以设计时需要做溢出保护。或者把x 0 x_{0}x0初值减小,这可能会牺牲精度。

表2θ hetaθ接近90°数据溢出

i d theta z y x SIN COS
0 1 45 89.9970 0 0.6073 0 19900
1 1 26.6 44.9970 0.6073 0.6073 19900 19900
2 1 14 18.3970 0.9110 0.3037 29850 9950
3 1 7.1 4.3970 0.9869 0.0759 32338 2488
4 -1 3.6 -2.7030 0.9964 -0.0474 32648 -1555
5 1 1.8 0.8970 0.9993 0.0148 32746 486
6 -1 0.9 -0.9030 0.9998 -0.0164 32761 -537
7 -1 0.4 -0.0030 1.0000 -0.0008 32769 -26
8 1 0.2 0.3970 1.0000 0.0070 32769 230
9 1 0.1 0.1970 1.0001 0.0031 32770 102
10 1 0.056 0.0970 1.0001 0.0012 32770 38
11 1 0.027 0.0410 1.0001 0.0002 32771 6

10 Verilog代码实现

CORDIC算法代码

module MyCORDIC(
input clk,
input rst_n,
input  [15:0]theta,
output reg [15:0]sin_theta,
output reg [15:0]cos_theta
);

parameter Kn  = 'd19898;    // 0.607253*2^15
parameter iKn = 'd53961;    // 1.64676*2^15 

parameter arctan_0 = 8192    ;  // arctan(1/2)
parameter arctan_1 = 4836    ;  // arctan(1/2^1)
parameter arctan_2 = 2555    ;  // arctan(1/2^2)
parameter arctan_3 = 1297    ;  // arctan(1/2^3)
parameter arctan_4 = 651     ;  // arctan(1/2^4)
parameter arctan_5 = 326     ;  // arctan(1/2^5)
parameter arctan_6 = 163     ;  // arctan(1/2^6)
parameter arctan_7 = 81      ;  // arctan(1/2^7)
parameter arctan_8 = 41      ;  // arctan(1/2^8)
parameter arctan_9 = 20      ;  // arctan(1/2^9)
parameter arctan_10 = 10     ;  // arctan(1/2^10)
parameter arctan_11 = 5      ;  // arctan(1/2^11)

reg signed [15:0] x [11:0];
reg signed [15:0] y [11:0];
reg signed [15:0] z [11:0];

wire [15:0]x_tmp;
wire [15:0]y_tmp;

reg signed [15:0]theta_1;
wire [2:0] Quadrant;//theta角所在的象限

// 象限判断
assign Quadrant = theta[15:14] + 1;

always@(*)
begin
begin
theta_1 <= {2'b00,theta[13:0]};
if(Quadrant==1)
begin
theta_1 <= theta;
end
else if(Quadrant==2)
begin
theta_1 <= 32768 - theta;
end
else if(Quadrant==3)
begin
theta_1 <= theta - 32768;
end
else if(Quadrant==4)
begin
theta_1 <= 65536 - theta;
end
end
end

always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
x[0] <= 16'd0;
y[0] <= 16'd0;
z[0] <= 16'd0;
end
else
begin
x[0] <= Kn;
y[0] <= 16'd0;
z[0] <= theta_1;
end
end

always@(posedge clk or negedge rst_n) // i=0
begin
if(!rst_n)
begin
x[1] <= 16'd0;
y[1] <= 16'd0;
z[1] <= 16'd0;
end
else
begin
if(z[0][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[1] <= x[0] + y[0];
y[1] <= y[0] - x[0];
z[1] <= z[0] + arctan_0;
end          // 剩余角度为正数,顺时针旋转,d=+1
else
begin
x[1] <= x[0] - y[0];
y[1] <= y[0] + x[0];
z[1] <= z[0] - arctan_0;
end
end
end

// >>>符号表示算术右移,不改变符号位
always@(posedge clk or negedge rst_n) // i=1
begin
if(!rst_n)
begin
x[2] <= 16'd0;
y[2] <= 16'd0;
z[2] <= 16'd0;
end
else
begin
if(z[1][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[2] <= x[1] + (y[1] >>> 1);
y[2] <= y[1] - (x[1] >>> 1);
z[2] <= z[1] + arctan_1;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[2] <= x[1] - (y[1] >>> 1);
y[2] <= y[1] + (x[1] >>> 1);
z[2] <= z[1] - arctan_1;
end
end
end

always@(posedge clk or negedge rst_n) // i=2
begin
if(!rst_n)
begin
x[3] <= 16'd0;
y[3] <= 16'd0;
z[3] <= 16'd0;
end
else
begin
if(z[2][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[3] <= x[2] + (y[2] >>> 2);
y[3] <= y[2] - (x[2] >>> 2);
z[3] <= z[2] + arctan_2;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[3] <= x[2] - (y[2] >>> 2);
y[3] <= y[2] + (x[2] >>> 2);
z[3] <= z[2] - arctan_2;
end
end
end

always@(posedge clk or negedge rst_n) // i=3
begin
if(!rst_n)
begin
x[4] <= 16'd0;
y[4] <= 16'd0;
z[4] <= 16'd0;
end
else
begin
if(z[3][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[4] <= x[3] + (y[3] >>> 3);
y[4] <= y[3] - (x[3] >>> 3);
z[4] <= z[3] + arctan_3;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[4] <= x[3] - (y[3] >>> 3);
y[4] <= y[3] + (x[3] >>> 3);
z[4] <= z[3] - arctan_3;
end
end
end


always@(posedge clk or negedge rst_n) // i=4
begin
if(!rst_n)
begin
x[5] <= 16'd0;
y[5] <= 16'd0;
z[5] <= 16'd0;
end
else
begin
if(z[4][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[5] <= x[4] + (y[4] >>> 4);
y[5] <= y[4] - (x[4] >>> 4);
z[5] <= z[4] + arctan_4;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[5] <= x[4] - (y[4] >>> 4);
y[5] <= y[4] + (x[4] >>> 4);
z[5] <= z[4] - arctan_4;
end
end
end

always@(posedge clk or negedge rst_n) // i=5
begin
if(!rst_n)
begin
x[6] <= 16'd0;
y[6] <= 16'd0;
z[6] <= 16'd0;
end
else
begin
if(z[5][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[6] <= x[5] + (y[5] >>> 5);
y[6] <= y[5] - (x[5] >>> 5);
z[6] <= z[5] + arctan_5;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[6] <= x[5] - (y[5] >>> 5);
y[6] <= y[5] + (x[5] >>> 5);
z[6] <= z[5] - arctan_5;
end
end
end

always@(posedge clk or negedge rst_n) // i=6
begin
if(!rst_n)
begin
x[7] <= 16'd0;
y[7] <= 16'd0;
z[7] <= 16'd0;
end
else
begin
if(z[6][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[7] <= x[6] + (y[6] >>> 6);
y[7] <= y[6] - (x[6] >>> 6);
z[7] <= z[6] + arctan_6;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[7] <= x[6] - (y[6] >>> 6);
y[7] <= y[6] + (x[6] >>> 6);
z[7] <= z[6] - arctan_6;
end
end
end


always@(posedge clk or negedge rst_n) // i=7
begin
if(!rst_n)
begin
x[8] <= 16'd0;
y[8] <= 16'd0;
z[8] <= 16'd0;
end
else
begin
if(z[7][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[8] <= x[7] + (y[7] >>> 7);
y[8] <= y[7] - (x[7] >>> 7);
z[8] <= z[7] + arctan_7;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[8] <= x[7] - (y[7] >>> 7);
y[8] <= y[7] + (x[7] >>> 7);
z[8] <= z[7] - arctan_7;
end
end
end

always@(posedge clk or negedge rst_n) // i=8
begin
if(!rst_n)
begin
x[9] <= 16'd0;
y[9] <= 16'd0;
z[9] <= 16'd0;
end
else
begin
if(z[8][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[9] <= x[8] + (y[8] >>> 8);
y[9] <= y[8] - (x[8] >>> 8);
z[9] <= z[8] + arctan_8;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[9] <= x[8] - (y[8] >>> 8);
y[9] <= y[8] + (x[8] >>> 8);
z[9] <= z[8] - arctan_8;
end
end
end

always@(posedge clk or negedge rst_n) // i=9
begin
if(!rst_n)
begin
x[10] <= 16'd0;
y[10] <= 16'd0;
z[10] <= 16'd0;
end
else
begin
if(z[9][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[10] <= x[9] + (y[9] >>> 9);
y[10] <= y[9] - (x[9] >>> 9);
z[10] <= z[9] + arctan_9;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[10] <= x[9] - (y[9] >>> 9);
y[10] <= y[9] + (x[9] >>> 9);
z[10] <= z[9] - arctan_9;
end
end
end

always@(posedge clk or negedge rst_n) // i=10
begin
if(!rst_n)
begin
x[11] <= 16'd0;
y[11] <= 16'd0;
z[11] <= 16'd0;
end
else
begin
if(z[10][15]) // 剩余角度为负数,顺时针旋转,d=-1
begin
x[11] <= x[10] + (y[10] >>> 10);
y[11] <= y[10] - (x[10] >>> 10);
z[11] <= z[10] + arctan_10;
end          // 剩余角度为正数,逆时针旋转,d=+1
else
begin
x[11] <= x[10] - (y[10] >>> 10);
y[11] <= y[10] + (x[10] >>> 10);
z[11] <= z[10] - arctan_10;
end
end
end

// 溢出判断
assign x_tmp = x[11][15]==1 ? 16'h7FFF : x[11];
assign y_tmp = y[11][15]==1 ? 16'h7FFF : y[11];
//assign x_tmp = x[11];
//assign y_tmp = y[11];

always@(posedge clk or negedge rst_n) // i=11
begin
if(!rst_n)
begin
sin_theta <= 16'd0;
cos_theta <= 16'd0;
end
else
begin
if(Quadrant == 3'd1)
begin
sin_theta <= y_tmp;
cos_theta <= x_tmp;
end
else if(Quadrant == 3'd2)
begin
sin_theta <= y_tmp;
cos_theta <= -x_tmp;
end
else if(Quadrant == 3'd3)
begin
sin_theta <= -y_tmp;
cos_theta <= -x_tmp;
end
else if(Quadrant == 3'd4)
begin
sin_theta <= -y_tmp;
cos_theta <= x_tmp;
end
else
begin
sin_theta <= sin_theta;
cos_theta <= cos_theta;
end
end
end
endmodule

testbench文件

`timescale 1 ns/ 1 ns

module MyCORDIC_tb(
);

integer i;

reg clk,rst_n;
reg [15:0] theta,theta_n;
wire [15:0]sin_theta,cos_theta;

reg [15:0] cnt,cnt_n;

MyCORDIC u0(
.clk       (clk      ),
.rst_n     (rst_n    ),
.theta     (theta    ),
.sin_theta (sin_theta),
.cos_theta (cos_theta)
);

initial
begin
    #0 clk = 1'b0;
    #10 rst_n = 1'b0;
    #10 rst_n = 1'b1;
    #10000000 $stop;
end 

initial
begin
    #0 theta = 16'd20;
   for(i=0;i<10000;i=i+1)
begin
#400;
theta <= theta + 16'd200;
end
end 

always #10
begin
    clk = ~clk;
end

endmodule

ModelSim仿真

3023bf28-0605-11ef-a297-92fbcf53809c.png

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4595

    浏览量

    92569
  • 函数
    +关注

    关注

    3

    文章

    4299

    浏览量

    62361
  • CORDIC
    +关注

    关注

    0

    文章

    37

    浏览量

    19950

原文标题:CORDIC算法详解

文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    CORDIC理论分析

      1、CORDIC 理论   1.1、 坐标旋转数字计算机CORDIC   坐标旋转数字计算机CORDIC(COordinate Rotation DIgital Computer)
    发表于 07-28 17:57 1807次阅读

    基于改进的CORDIC算法的FFT复乘及其FPGA实现

    耗费了FFT运算中大量的乘法器资源。CORDIC算法只需简单的移位与加减运算就能实现向量旋转,具有使用资源少、硬件规模小等优势。因此在FFT蝶形运算中用其代替传统FFT运算中的复数乘法器,可以获得更好
    发表于 07-11 21:32

    CORDIC算法求助

    请问CORDIC算法用verilog算法实现时,角度累加器中的45度,26.56度,14.04度怎么跟verilog语言相对应?
    发表于 07-11 20:18

    FPGA设计中必须掌握的Cordic算法

    大多数工程师在碰到需要在 FPGA 中实现诸如正弦、余弦或开平方这样的数学函数时,首先会想到的是用查找表,可能再结合线性内插或者幂级数(如果有乘法器可用)。不过对这种工作来说,CORDIC 算法
    发表于 09-19 09:07

    高性能HPOR CORDIC算法及实现

    CORDIC 算法在通信和图像处理等各个领域有着广泛的应用,但是浮点CORDIC 由于迭代延时大且实现复杂没有得到很好的应用,本文提出了一种修正浮点CORDIC
    发表于 12-15 14:27 15次下载

    基于CORDIC算法的载波同步锁相环设计

    研究了一种利用CORDIC算法的矢量及旋转模式对载波同步中相位偏移进行估计并校正的方法。设计并实现了基于CORDIC算法的数字锁相环。通过仿真,验证了设计的有效性和高效性。
    发表于 12-15 14:49 0次下载
    基于<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>的载波同步锁相环设计

    基于CORDIC算法2FSK调制器的FPGA设计

    本文提出了应用CORDIC(Coordinate Rotation Digital Computer)算法实时计算正弦值的方案,并基于CORDIC算法在FPGA芯片上设计了2FSK调制
    发表于 05-31 10:22 1778次阅读
    基于<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>2FSK调制器的FPGA设计

    双模式CORDIC算法的FPGA实现

    CORDIC算法将复杂的算术运算转化为简单的加法和移位操作,然后逐次逼近结果。这种方法很好的兼顾了精度、速度和硬件复杂度,它与VLSI技术的结合对DSP算法的硬件实现具有极大的意义
    发表于 06-27 17:27 66次下载
    双模式<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>的FPGA实现

    cordic算法verilog实现(简单版)

    cordic算法verilog实现(简单版)(转载)module cordic(clk, phi, cos, sin); parameter W = 13, W_Z = 14; input clk; input [W_Z-1
    发表于 02-11 03:06 3243次阅读
    <b class='flag-5'>cordic</b><b class='flag-5'>算法</b>verilog实现(简单版)

    高速低功耗CORDIC算法的研究与实现

    针对传统CORDIC算法流水线结构的迭代次数过多,运算速度不够快,消耗硬件资源较多的缺点,改进了一种基于旋转模式并行运算的CORDIC算法。该算法
    发表于 11-16 10:46 14次下载
    高速低功耗<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>的研究与实现

    基于FPGA的Cordic算法实现的设计与验证

    本文是基于FPGA实现Cordic算法的设计与验证,使用Verilog HDL设计,初步可实现正弦、余弦、反正切函数的实现。将复杂的运算转化成FPGA擅长的加减法和乘法,而乘法运算可以用移位运算代替
    发表于 07-03 10:18 2665次阅读
    基于FPGA的<b class='flag-5'>Cordic</b><b class='flag-5'>算法</b>实现的设计与验证

    基于CORDIC的高速Sobel算法实现

    为提高图像边缘检测的处理速度,提出一种基于CORDIC的高速Sobel算法实现。
    的头像 发表于 10-05 09:54 3533次阅读
    基于<b class='flag-5'>CORDIC</b>的高速Sobel<b class='flag-5'>算法</b>实现

    CORDIC算法的原理及具体应用

    CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数、双曲线、指数、对数
    的头像 发表于 11-13 07:09 6603次阅读

    一文带你们了解什么是CORDIC算法

    CORDIC算法简介 在信号处理领域,CORDIC(Coordinate Rotation Digital Computer,坐标旋转数字计算机)算法具有重大工程意义。
    的头像 发表于 04-11 11:16 1.5w次阅读
    一文带你们了解什么是<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>

    CORDIC算法简介

    在信号处理领域,CORDIC(Coordinate Rotation Digital Computer,坐标旋转数字计算机)算法具有重大工程意义。
    的头像 发表于 03-28 09:39 2158次阅读