0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深度解析CORDIC算法原理

FPGA設(shè)計(jì)論壇 ? 來源:至芯科技 ? 2024-04-29 16:48 ? 次閱讀

CORDIC算法詳解

1 平面坐標(biāo)系旋轉(zhuǎn)

CORDIC算法的思想是通過迭代的方法,使得累計(jì)旋轉(zhuǎn)過的角度的和無限接近目標(biāo)角度。它是一種數(shù)值計(jì)算逼近的方法,運(yùn)算只有移位和加減。

通過圓坐標(biāo)系可以了解CORDIC算法的基本思想,如圖1所示,初始向量( x 1 , y 1 ) left( x_{1},y_{1} ight)(x1,y1)旋轉(zhuǎn)θ hetaθ角度之后得到向量( x 2 , y 2 ) left( x_{2},y_{2} ight)(x2,y2),兩者之間滿足(公式1)關(guān)系。

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

通過提取因數(shù)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 偽旋轉(zhuǎn)

如果去掉cos ? θ cos hetacosθ,我們可以的到偽旋轉(zhuǎn)方程式(公式3),即旋轉(zhuǎn)的角度是正確的,但是x xx,y yy的值增加了cos ? ? 1 θ cos^{- 1} hetacos?1θ倍,由于cos ? ? 1 θ > 1 cos^{- 1} heta > 1cos?1θ>1,所以模值變大。這里并不能通過數(shù)學(xué)方法去除cos ? θ cos hetacosθ項(xiàng),但是可以化簡坐標(biāo)平面旋轉(zhuǎn)的計(jì)算。

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θ后偽坐標(biāo)系

3 CORDIC方法

這里為了便于硬件的計(jì)算,采用迭代的思想,旋轉(zhuǎn)角度θ hetaθ可以通過若干步實(shí)現(xiàn),每一步旋轉(zhuǎn)一個(gè)角度θ i heta^{i}θi。并且約定每一次旋轉(zhuǎn)的角度的正切值為2的倍數(shù),即tan ? θ i = 2 ? i { an heta^{i} = 2}^{- i}tanθi=2?i。下面表格是用于CORDIC算法中每個(gè)迭代i的旋轉(zhuǎn)角度。這樣,乘以正切值就可以變成移位操作。

表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,用于確定旋轉(zhuǎn)的方向。其中第i步順時(shí)針旋轉(zhuǎn)時(shí)d i = ? 1 d_{i} = - 1di=?1,逆時(shí)針旋轉(zhuǎn)d i = 1 d_{i} = 1di=1。前面的偽旋轉(zhuǎn)坐標(biāo)方程現(xiàn)在可以表示為:

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

這里,我們引入第三個(gè)方程,被稱為角度累加器,用來在每次迭代過程中追蹤累加的旋轉(zhuǎn)角度,表示第n次旋轉(zhuǎn)后剩下未旋轉(zhuǎ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移位-加法算法

因此,原始的算法現(xiàn)在已經(jīng)被簡化為使用向量的偽旋轉(zhuǎn)方程式(公式6)來表示迭代(移位-加法)算法。

2次移位;
(2 ? i 2^{- i}2?i用移位實(shí)現(xiàn),每右移n位就把原來數(shù)值乘以2的-i次方了)

1次查找表;(每一次迭代都會(huì)有一個(gè)固定角度θ i heta^{i}θi的累加,這個(gè)角度是2 ? i 2^{- i}2?i對(duì)應(yīng)的角度值,使用查表實(shí)現(xiàn)。θ 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 伸縮因子

當(dāng)簡化算法以偽旋轉(zhuǎn)時(shí),cos ? θ cos hetacosθ項(xiàng)被忽略,這樣( x n , y n ) left( x_{n},y_{n} ight)(xn,yn)就被伸縮了K n K_{n}Kn倍。如果迭代次數(shù)已知,可以預(yù)先計(jì)算伸縮因子K n K_{n}Kn。同樣1 / K n 1/K_{n}1/Kn也可被預(yù)先計(jì)算以得到( 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,當(dāng)n ? > ∞ n - > inftyn?>∞

1 / K n ? > 0.607253 1/K_{n} - > 0.6072531/Kn?>0.607253,當(dāng)n ? > ∞ n - > inftyn?>∞

7 旋轉(zhuǎn)模式

CORDIC方法有兩種模式,旋轉(zhuǎn)模式和向量模式。工作模式?jīng)Q定了控制算子d i d_{i}di的條件。在旋轉(zhuǎn)模式中,旋轉(zhuǎn)剩余角度初始變量z 0 = θ z_{0} = hetaz0=θ,經(jīng)過n次旋轉(zhuǎn)后,使z 0 = 0 z_{0} = 0z0=0。整個(gè)旋轉(zhuǎn)過程可以表示為一系列旋轉(zhuǎn)角度不斷偏擺,從而逼近所需旋轉(zhuǎn)角度的迭代過程。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

通過設(shè)置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可以計(jì)算cos ? z 0 cos z_{0}cosz0和sin ? z 0 sin z_{0}sinz0。分析可知CORDIC算法在圓周系統(tǒng)旋轉(zhuǎn)模式下可以用來計(jì)算一個(gè)輸入角的正弦值、余弦值。

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 旋轉(zhuǎn)模式角度逼近

8 象限判斷

對(duì)于任意角度θ hetaθ,都可以通過旋轉(zhuǎn)一系列小角度來i完成。第一次迭代旋轉(zhuǎn)45°,第二次迭代旋轉(zhuǎn)26.6°,第三次迭代旋轉(zhuǎn)14°。很顯然,每次旋轉(zhuǎn)的方向都影響到最終的累計(jì)角度。在-99.7°

9溢出處理

通過表2可以看出,把初始θ hetaθ角度設(shè)置為90°,由于x 0 x_{0}x0賦的初值存在誤差(一般是偏大),最終獲得的x n x_{n}xn和y n y_{n}yn是有可能大于1的。所以設(shè)計(jì)時(shí)需要做溢出保護(hù)。或者把x 0 x_{0}x0初值減小,這可能會(huì)犧牲精度。

表2θ hetaθ接近90°數(shù)據(jù)溢出

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代碼實(shí)現(xiàn)

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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[1] <= x[0] + y[0];
y[1] <= y[0] - x[0];
z[1] <= z[0] + arctan_0;
end          // 剩余角度為正數(shù),順時(shí)針旋轉(zhuǎn),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

// >>>符號(hào)表示算術(shù)右移,不改變符號(hào)位
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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[2] <= x[1] + (y[1] >>> 1);
y[2] <= y[1] - (x[1] >>> 1);
z[2] <= z[1] + arctan_1;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[3] <= x[2] + (y[2] >>> 2);
y[3] <= y[2] - (x[2] >>> 2);
z[3] <= z[2] + arctan_2;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[4] <= x[3] + (y[3] >>> 3);
y[4] <= y[3] - (x[3] >>> 3);
z[4] <= z[3] + arctan_3;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[5] <= x[4] + (y[4] >>> 4);
y[5] <= y[4] - (x[4] >>> 4);
z[5] <= z[4] + arctan_4;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[6] <= x[5] + (y[5] >>> 5);
y[6] <= y[5] - (x[5] >>> 5);
z[6] <= z[5] + arctan_5;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[7] <= x[6] + (y[6] >>> 6);
y[7] <= y[6] - (x[6] >>> 6);
z[7] <= z[6] + arctan_6;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[8] <= x[7] + (y[7] >>> 7);
y[8] <= y[7] - (x[7] >>> 7);
z[8] <= z[7] + arctan_7;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[9] <= x[8] + (y[8] >>> 8);
y[9] <= y[8] - (x[8] >>> 8);
z[9] <= z[8] + arctan_8;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[10] <= x[9] + (y[9] >>> 9);
y[10] <= y[9] - (x[9] >>> 9);
z[10] <= z[9] + arctan_9;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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]) // 剩余角度為負(fù)數(shù),順時(shí)針旋轉(zhuǎn),d=-1
begin
x[11] <= x[10] + (y[10] >>> 10);
y[11] <= y[10] - (x[10] >>> 10);
z[11] <= z[10] + arctan_10;
end          // 剩余角度為正數(shù),逆時(shí)針旋轉(zhuǎn),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

審核編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4678

    瀏覽量

    94303
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4363

    瀏覽量

    63786
  • CORDIC
    +關(guān)注

    關(guān)注

    0

    文章

    37

    瀏覽量

    20135

原文標(biāo)題:CORDIC算法詳解

文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    CORDIC理論分析

      1、CORDIC 理論   1.1、 坐標(biāo)旋轉(zhuǎn)數(shù)字計(jì)算機(jī)CORDIC   坐標(biāo)旋轉(zhuǎn)數(shù)字計(jì)算機(jī)CORDIC(COordinate Rotation DIgital Computer)
    發(fā)表于 07-28 17:57 ?1910次閱讀

    基于改進(jìn)的CORDIC算法的FFT復(fù)乘及其FPGA實(shí)現(xiàn)

    耗費(fèi)了FFT運(yùn)算中大量的乘法器資源。CORDIC算法只需簡單的移位與加減運(yùn)算就能實(shí)現(xiàn)向量旋轉(zhuǎn),具有使用資源少、硬件規(guī)模小等優(yōu)勢。因此在FFT蝶形運(yùn)算中用其代替?zhèn)鹘y(tǒng)FFT運(yùn)算中的復(fù)數(shù)乘法器,可以獲得更好
    發(fā)表于 07-11 21:32

    CORDIC算法求助

    請(qǐng)問CORDIC算法用verilog算法實(shí)現(xiàn)時(shí),角度累加器中的45度,26.56度,14.04度怎么跟verilog語言相對(duì)應(yīng)?
    發(fā)表于 07-11 20:18

    FPGA設(shè)計(jì)中必須掌握的Cordic算法

    大多數(shù)工程師在碰到需要在 FPGA 中實(shí)現(xiàn)諸如正弦、余弦或開平方這樣的數(shù)學(xué)函數(shù)時(shí),首先會(huì)想到的是用查找表,可能再結(jié)合線性內(nèi)插或者冪級(jí)數(shù)(如果有乘法器可用)。不過對(duì)這種工作來說,CORDIC 算法
    發(fā)表于 09-19 09:07

    高性能HPOR CORDIC算法及實(shí)現(xiàn)

    CORDIC 算法在通信和圖像處理等各個(gè)領(lǐng)域有著廣泛的應(yīng)用,但是浮點(diǎn)CORDIC 由于迭代延時(shí)大且實(shí)現(xiàn)復(fù)雜沒有得到很好的應(yīng)用,本文提出了一種修正浮點(diǎn)CORDIC
    發(fā)表于 12-15 14:27 ?15次下載

    基于CORDIC算法的載波同步鎖相環(huán)設(shè)計(jì)

    研究了一種利用CORDIC算法的矢量及旋轉(zhuǎn)模式對(duì)載波同步中相位偏移進(jìn)行估計(jì)并校正的方法。設(shè)計(jì)并實(shí)現(xiàn)了基于CORDIC算法的數(shù)字鎖相環(huán)。通過仿真,驗(yàn)證了設(shè)計(jì)的有效性和高效性。
    發(fā)表于 12-15 14:49 ?0次下載
    基于<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>的載波同步鎖相環(huán)設(shè)計(jì)

    基于CORDIC算法2FSK調(diào)制器的FPGA設(shè)計(jì)

    本文提出了應(yīng)用CORDIC(Coordinate Rotation Digital Computer)算法實(shí)時(shí)計(jì)算正弦值的方案,并基于CORDIC算法在FPGA芯片上設(shè)計(jì)了2FSK調(diào)制
    發(fā)表于 05-31 10:22 ?1940次閱讀
    基于<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>2FSK調(diào)制器的FPGA設(shè)計(jì)

    雙模式CORDIC算法的FPGA實(shí)現(xiàn)

    CORDIC算法將復(fù)雜的算術(shù)運(yùn)算轉(zhuǎn)化為簡單的加法和移位操作,然后逐次逼近結(jié)果。這種方法很好的兼顧了精度、速度和硬件復(fù)雜度,它與VLSI技術(shù)的結(jié)合對(duì)DSP算法的硬件實(shí)現(xiàn)具有極大的意義
    發(fā)表于 06-27 17:27 ?66次下載
    雙模式<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>的FPGA實(shí)現(xiàn)

    cordic算法verilog實(shí)現(xiàn)(簡單版)

    cordic算法verilog實(shí)現(xiàn)(簡單版)(轉(zhuǎn)載)module cordic(clk, phi, cos, sin); parameter W = 13, W_Z = 14; input clk; input [W_Z-1
    發(fā)表于 02-11 03:06 ?3369次閱讀
    <b class='flag-5'>cordic</b><b class='flag-5'>算法</b>verilog實(shí)現(xiàn)(簡單版)

    高速低功耗CORDIC算法的研究與實(shí)現(xiàn)

    針對(duì)傳統(tǒng)CORDIC算法流水線結(jié)構(gòu)的迭代次數(shù)過多,運(yùn)算速度不夠快,消耗硬件資源較多的缺點(diǎn),改進(jìn)了一種基于旋轉(zhuǎn)模式并行運(yùn)算的CORDIC算法。該算法
    發(fā)表于 11-16 10:46 ?14次下載
    高速低功耗<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>的研究與實(shí)現(xiàn)

    基于FPGA的Cordic算法實(shí)現(xiàn)的設(shè)計(jì)與驗(yàn)證

    本文是基于FPGA實(shí)現(xiàn)Cordic算法的設(shè)計(jì)與驗(yàn)證,使用Verilog HDL設(shè)計(jì),初步可實(shí)現(xiàn)正弦、余弦、反正切函數(shù)的實(shí)現(xiàn)。將復(fù)雜的運(yùn)算轉(zhuǎn)化成FPGA擅長的加減法和乘法,而乘法運(yùn)算可以用移位運(yùn)算代替
    發(fā)表于 07-03 10:18 ?2996次閱讀
    基于FPGA的<b class='flag-5'>Cordic</b><b class='flag-5'>算法</b>實(shí)現(xiàn)的設(shè)計(jì)與驗(yàn)證

    基于CORDIC的高速Sobel算法實(shí)現(xiàn)

    為提高圖像邊緣檢測的處理速度,提出一種基于CORDIC的高速Sobel算法實(shí)現(xiàn)。
    的頭像 發(fā)表于 10-05 09:54 ?3705次閱讀
    基于<b class='flag-5'>CORDIC</b>的高速Sobel<b class='flag-5'>算法</b>實(shí)現(xiàn)

    CORDIC算法的原理及具體應(yīng)用

    CORDIC(Coordinate Rotation Digital Computer)算法即坐標(biāo)旋轉(zhuǎn)數(shù)字計(jì)算方法,是J.D.Volder1于1959年首次提出,主要用于三角函數(shù)、雙曲線、指數(shù)、對(duì)數(shù)
    的頭像 發(fā)表于 11-13 07:09 ?6861次閱讀

    一文帶你們了解什么是CORDIC算法

    CORDIC算法簡介 在信號(hào)處理領(lǐng)域,CORDIC(Coordinate Rotation Digital Computer,坐標(biāo)旋轉(zhuǎn)數(shù)字計(jì)算機(jī))算法具有重大工程意義。
    的頭像 發(fā)表于 04-11 11:16 ?1.5w次閱讀
    一文帶你們了解什么是<b class='flag-5'>CORDIC</b><b class='flag-5'>算法</b>

    CORDIC算法簡介

    在信號(hào)處理領(lǐng)域,CORDIC(Coordinate Rotation Digital Computer,坐標(biāo)旋轉(zhuǎn)數(shù)字計(jì)算機(jī))算法具有重大工程意義。
    的頭像 發(fā)表于 03-28 09:39 ?2577次閱讀

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品