📄 atan_cordic.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 + -