如果theta是固定的话,可以先用matlab生成一个表,然后查表就可以了。如果每次用到 floor( theta/unit ) * unit都需要计算的话可能比较慢。或者你可以这样考虑,不是每一步都需要把数这样处理,干脆整数化,最后在乘以相应的Scaling. 以下就是一个NCO的例子,里面的变量都整数化了。
% Phase Truncation DDS
clear;clc;
% declare parameter for phase accumulator
fclk = 100e6;
phase_depth = 32;
fout = 20e6;
% declare parameter for lookup table
table_depth = 16;
output_precision = 16;
% phase increment calculation
phase_inc = fout*2^phase_depth/fclk;
phase_inc = floor(phase_inc);
actual_freq = phase_inc*fclk/2^phase_depth;
fprintf('For output frequcecy = %d Hz\n',fout);
fprintf('With clock frequcecy = %d Hz\n',fclk);
fprintf('With phase bit width = %d bit\n',phase_depth);
fprintf('Phase inc value is = %d\n',phase_inc);
fprintf('Aactual frequency is = %d\n',actual_freq);
% build lookup table
N = 2^table_depth;
t = (0:N-1)*2*pi/N;
% sine/cosine calculation
cos_lut = cos(t);
sin_lut = sin(t);
% output scaling
lut_max = 2^(output_precision-1) - 1;
lut_min =-2^(output_precision-1) + 1;
cos_lut = round(cos_lut*2^(output_precision-1));
cos_lut(cos_lut>lut_max) = lut_max;
cos_lut(cos_lut<lut_min) = lut_min;
sin_lut = round(sin_lut*2^(output_precision-1));
sin_lut(sin_lut>lut_max) = lut_max;
cos_lut(cos_lut<lut_min) = lut_min;
% phase accumulator
M = 2^phase_depth;
acc = 0;
num_of_sample = 2^14; % number of samples
l = zeros(1,num_of_sample);
for i = 1:num_of_sample
acc = acc + phase_inc;
l(i) = mod(acc,M);
end
% phase quantization
l = floor(l./2^(phase_depth-table_depth)) + 1;
% sine/cosine output
cos_out = cos_lut(l);
sin_out = sin_lut(l); |