VHDL ve Matlab ile CORDIC Algoritması

CORDIC (COordinate, Rotation DIgital Computer) sinüs, cosinüs, üstel fonksiyonlar, logaritma gibi çeşitli gerçek zamanlı yüksek prezisyonlu aritmetik hesaplamalar için geliştirilen zeki ve etkin bir algoritma ailesidir. 1959 yılında Volder tarafından ortaya konulan gerçekten önemli bu algoritmalar, n iterasyonda n bit doğrulukla sözkonusu fonksiyonları hesaplayabilmekte ve her iterasyonda az sayıda toplama ve öteleme işlemlerini gerektirmektedir. Algoritma, Walther  tarafından genişletilerek bölme, çarpma, karakök hesaplama, hiperbolik ve üstel fonksiyon hesaplama gibi diğer aritmetik işlemleri de yapabilecek yeteneğe kavuşturuldu.

 

Cordic algoritması ile ilgili açıklayıcı işlemler, Matlab, VHDL kodları ve simülasyon görüntüleri aşağıdadır.

btr

btr

btr

 

 

 

Matlab Kodu=>

% prompt = 'Angle=? '; 
% angle = input(prompt);
ginput(1);
format short
for degree=0:360
    angle=degree;
region =1;
if angle <=180 && angle > 90
    angle = 180 - angle;
    region =2;
 
 
elseif angle <=270 && angle > 180
    angle = -180 + angle;
    region =3;
 
 
elseif angle <=360 && angle > 270
    angle = 360-angle;
    region =4;
end
 
 
 
N=20;
x(1) = 1;
y(1) = 0;
k=1;
preangle(1)=0;
for i=0:N-1
 
k = k*1/(sqrt(1+2^(-2*i)));
end
 
for i=2:N
 
    if angle > preangle(i-1)
        sigma = 1;
    else
        sigma = -1;
    end
 
    x(i) = x(i-1)-sigma*2^(-i+2)*y(i-1); 
    y(i) = y(i-1)+sigma*2^(-i+2)*x(i-1); 
 
    preangle(i) = preangle(i-1)+sigma*atan(2^(-i+2))*180/pi;
 
 
 
 
 
end
 
switch region
    case 1
        cosine = k*x(N);
        sine = k*y(N);
        title(['Degree = ' num2str(degree) ',    Cosine = ' num2str(round(cosine, 3)) ',    Sine = ' num2str(round(sine, 3)), '    Region = ' num2str(region)],'Color', 'k')
    case 2
        cosine = -k*x(N);
        sine = k*y(N);
        title(['Degree = ' num2str(degree) ',    Cosine = ' num2str(round(cosine, 3)) ',    Sine = ' num2str(round(sine, 3)), '    Region = ' num2str(region)],'Color', 'g')
    case 3
        cosine = -k*x(N);
        sine = -k*y(N);
        title(['Degree = ' num2str(degree) ',    Cosine = ' num2str(round(cosine, 3)) ',    Sine = ' num2str(round(sine, 3)), '    Region = ' num2str(region)],'Color', 'm')
    case 4
        cosine = k*x(N);
        sine = -k*y(N);
        title(['Degree = ' num2str(degree) ',    Cosine = ' num2str(round(cosine, 3)) ',    Sine = ' num2str(round(sine, 3)), '    Region = ' num2str(region)],'Color', 'r')
end
figure(1)
grid on
hold on 
h(1).graph=plot(degree,sine,'.','MarkerEdgeColor','b');
h(2).graph=plot(degree,cosine,'.','MarkerEdgeColor','c');
legend ('sine','cosine')
xlabel ('Degree')
ylabel ('Value')
%title(['Degree = ' num2str(degree) ',    Cosine = ' num2str(round(cosine, 3)) ',    Sine = ' num2str(round(sine, 3)), '    Region = ' num2str(region)],'Color', 'r')
axis([0 360 -1 1])
s=[0 45 90 135 180 225 270 315 360];
set(gca,'XTick',s)
pause(0.02)
end
 
 
 
round(sine, 3)

 

VHDL Kodu =>

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.MATH_REAL.ALL;
 
 
entity deneme8 is
end deneme8;
 
architecture Behavioral of deneme8 is
 
type state is array (19 downto 0) of real;
constant clk_period : time := 10 ns;
signal clk:std_logic;
signal cosine:real;
signal sine:real;
signal real_angle:integer:=0;
			function LUT return state is
				variable atan:state;
				begin
				for I in 0 to 19 loop
					atan(I) := arctan(2.0**(-1.0*real(I)))*180.0/MATH_PI;
					end loop;
					return atan;
			end LUT;
 
			function K_cal return real is
				variable K: real := 1.0;
				begin
				for I in 0 to 19 loop
                K:=K * 1.0/sqrt(1.0+2.0**(-2.0*real(I)));
				end loop;
				return K;
			end K_cal;	
 
			function call(temp,real_angle:integer) return real is
				variable s_tan:state;
				variable x:state;
				variable y:state;
				variable preangle:state;
				variable diff:state;
				variable region:integer;
				variable degree:integer;
				variable cosine:real;
				variable sine:real;
				variable K_val : real;
				begin
				K_val := K_cal;
				preangle(0):= 0.0;
				x(0) := 1.0;
				y(0) := 0.0;
				s_tan :=LUT;
				if (real_angle >= 0) and (real_angle < 90) then
				degree :=real_angle;
				region := 1;
				elsif (real_angle >= 90) and (real_angle < 180) then
				degree :=180 - real_angle;
				region := 2;
				elsif (real_angle <270) and (real_angle >= 180) then
				degree := -180 + real_angle;
				region :=3;
				else
				degree := 360-real_angle;
				region :=4;
				end if;
				for i in 0 to 18 loop
				diff(i) := real(degree) - preangle(i);
				if (diff(i) >= 0.0) then
				preangle(i+1) := preangle(i) + s_tan(i);
				x(i+1) := x(i) - (2.0**(real(-i)))*y(i);
				y(i+1) := y(i) + (2.0**(real(-i)))*x(i);
				else
				preangle(i+1) := preangle(i) - s_tan(i);
				x(i+1) := x(i) +(2.0**(real(-i)))*y(i);
				y(i+1) := y(i) -(2.0**(real(-i)))*x(i);
				end if;
				end loop;  
 
				case region is
 
				when 1 =>
				cosine := K_val*x(19);
				sine := K_val*y(19);
				when 2 =>
				cosine := -K_val*x(19);
				sine := K_val*y(19);
				when 3 =>
				cosine := -K_val*x(19);
				sine := -K_val*y(19);
				when others =>
				cosine := K_val*x(19);
				sine := -K_val*y(19);
 
				end case;
 
 
 
 
				if temp=1 then
				return cosine;
 
				else
				return sine;
				end if;
 
 
			end call;
 
 
 
 
 
 
begin
 
cosine <=call(1,real_angle);
sine <=call(2,real_angle);
 
clk_process :process
   begin
		clk <= '0';
		wait for clk_period/2;
		clk <= '1';
		wait for clk_period/2;
		real_angle <= (real_angle +1) mod 360 ; 
   end process;
 
 
end Behavioral;

 

Yararlanılan Kaynaklar ve daha detaylı bilgi için =>

http://www.alicavuslu.gen.tr/2019/03/11/vhdl-ile-cordic-algoritmasinin-gerceklenmesi-dairesel-aci-donusumu/

http://bertantaskin.com/cordic-algoritmasi-ve-fpga-uzerinde-uygulamasi/

http://www.saujs.sakarya.edu.tr/download/article-file/265449

https://www.cncdesigner.com/wordpress/?p=5198

http://www.emo.org.tr/ekler/aaece81f2d731fb_ek.pdf

http://www.picproje.org/index.php?topic=61071.0

http://farukcansaglam.net/cordic-algoritmasi/

 

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.