⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atan_cordic.m

📁 atan函数
💻 M
字号:

function out = atan_cordic(in, mode, pipe_len, in_dw, out_dw)
% out = atan( imag(in)/real(in) )
% atan_cordic is a fixed-point function to calculate the phase of a complex.
% in is a complex number, out is the phase
% if mode==1 out = [-1, 1]; else out = [-pi, pi]
% pipe_len is the length of pipeline, default value is 15
% in_dw is the input data width (including sign bit, max=20bit)
% out_dw is the output data width (including sign bit, max=20bit)

% %%%%%%%%%%%%%%%%%%%% test input
% xin = -7149;
% yin = -20;
% in = fix(xin + j*yin);
% 
% in_dw = 20;         %20bit
% out_dw = 16;        %20bit
% pipe_len = 15;      %pipe_len must be less than dw_ap
% mode = 1;
% %%%%%%%%%%%%%%%%%%%% end of test input

xin = real(in);
yin = imag(in);
dw_ap = 20;
if in_dw>20 sprintf('sorry, now the maximum input datawidth is 20 bit!')
end

if out_dw>20 sprintf('sorry, now the maximum output datawidth is 20 bit!')
end

flag = Check_Overflow(in, in_dw-1);
if flag==1  sprintf('input of atan_cordic is overflowed!') 
end

if xin<0    x_sign = 1;
else        x_sign = 0;
end

if yin<0    y_sign = 1;
else        y_sign = 0;
end

x = abs(xin);
y = abs(yin);

if y > x
    swap = 1;
    tt = x;
    x = y;
    y = tt;
else
    swap = 0;
end


% --if z(n)<0,	s(n)=-1
% --if z(n)>=0,	s(n)=+1
% 
% --	x(n+1) = x(n) - s(n)*2^(-n)*y(n)
% --	y(n+1) = y(n) + s(n)*2^(-n)*x(n)
% --    z(n+1) = z(n) - s(n)*atan(1/2^n)

x = bitshift_cplx(x, dw_ap-in_dw);      %in_dw <= dw_ap = 20
y = bitshift_cplx(y, dw_ap-in_dw);
if x >= 2^(dw_ap-2) | x<= -2^(dw_ap-2) | y >= 2^(dw_ap-2) | y <= -2^(dw_ap-2)
    x=bitshift_cplx(x, -2);
    y=bitshift_cplx(y, -2);
else 
    if x >= 2^(dw_ap-3) | x<= -2^(dw_ap-3) | y >= 2^(dw_ap-3) | y <= -2^(dw_ap-3)
        x=bitshift_cplx(x, -1);
        y=bitshift_cplx(y, -1);
    end
end

        
z = 0;
for n = 0: pipe_len-1
  if mode==1  
    catan = round(atan(1/2^n)*2^dw_ap/(2*pi));
  else  
    catan = round(atan(1/2^n)*2^dw_ap/8);
    %catan_hex = dec2hex(catan)
  end
    x_old = x; y_old = y;
    if y<0   s=1;
    else     s=-1; 
    end
    x = x_old - s*bitshift_cplx(y_old, -n);
    y = y_old + s*bitshift_cplx(x_old, -n);
    z = z - s*catan;   
end

if abs(y) >= 50
    sprintf('y is not converged!!')
end

if z<0  z=0; end
if mode==1
const_pi2 = 2^(dw_ap - 2);   %262144; 
const_pi = 2^(dw_ap - 1);    %524288;
const_2pi = 0;
else
const_pi2 = round( pi/4 * 2^(dw_ap - 2));   %262144; 
const_pi = round( pi/4 * 2^(dw_ap - 1));    %524288;
const_2pi = 0;
end


if swap==1    z = const_pi2 - z; end
if x_sign==1  z = const_pi - z; end
if y_sign==1  z = const_2pi - z; end

out = bitshift_cplx(z, out_dw - dw_ap);                    %output as 'out_dw' bit
% out = round(z*2^(out_dw - dw_ap));                    %output as 'out_dw' bit
% out = round(angle(in)*2^(out_dw-3));                    %output as 'out_dw' bit

% %%%% compared with atan function.
% %% out_ref = fix (atan(abs(yin/xin)) * (2^(out_dw-1)) /pi);    %output as 'out_dw' bit
% %% if x_sign==1  out_ref = 2^(out_dw-1) - out_ref; end
% %% if y_sign==1  out_ref = 0 - out_ref; end
%  if mode==1 
%     out_ref = fix (atan2(yin,xin) * (2^(out_dw-1)) /pi)    %output as 'out_dw' bit
%  else
%     out_ref = fix (atan2(yin,xin) * 2^(out_dw-3))     %output as 'out_dw' bit
%  end
%  SNR = -10 * log10(abs((out-out_ref)/out_ref))
%  sprintf('----end----')


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -