diff --git a/lib/radio/nco/ghdl/tb_mix_results.m b/lib/radio/nco/ghdl/tb_mix_results.m new file mode 100644 index 0000000..fb6d7ff --- /dev/null +++ b/lib/radio/nco/ghdl/tb_mix_results.m @@ -0,0 +1,90 @@ +% Read data +function tb_mix_results() +fa = 100.0; +f = textread('freq.txt')*1E-6 +R = 128; +fa_dec = fa/R +N_pfir = 63; + +I_in = textread('i_in.txt')'; +I_out = textread('i_out.txt')'; +Q_out = textread('q_out.txt')'; + +N= length(I_out) +N_fft = N +N_fft2 = fix(N_fft/2); + +fft_y2 = 2/N_fft*abs(fft(I_out(1:N_fft).*hann(N_fft)')); + +[i, v] = get_maxpur(fft_y2, fa, f); +max_spur_freq = (i*fa/N_fft); +max_spur_value = 20*log10(v); + +fft_y3 = 2/N_fft*abs(fft(I_in(1:N_fft).*hann(N_fft)')); + +[i, v] = get_maxpur(fft_y3, fa, f); +max_ditherd_spur_freq = (i*fa/N_fft); +max_ditherd_spur_value = 20*log10(v); + +I_out_dec = cic_filter(R, 1, 3, I_out); +Q_out_dec = cic_filter(R, 1, 3, Q_out); +N_dec = length(I_out_dec)-2*N_pfir; +N_fft_dec = N_dec +N_fft2_dec = N_fft_dec/2; +fft_y2_dec = 2/N_fft_dec*abs(fft(I_out_dec(2*N_pfir+1:N_fft_dec+2*N_pfir).*hann(N_fft_dec)')); + +pfir_b = sinc(0.1*(-(N_pfir-1)/2:1:(N_pfir)/2)); +pfir_b = pfir_b/sum(pfir_b).*blackman(N_pfir)'; +I_out_dec_pfir = filter(pfir_b, 1, I_out_dec); +Q_out_dec_pfir = filter(pfir_b, 1, Q_out_dec); +fft_y2_dec_pfir = 2/N_fft_dec*abs(fft(I_out_dec_pfir(2*N_pfir+1:N_fft_dec+2*N_pfir).*hann(N_fft_dec)')); + +% Output +close all; + +plot(fa/(R*N_fft_dec)*(0:N_fft2_dec),20*log10(fft_y2_dec(1:N_fft2_dec+1)), '-', fa/(R*N_fft_dec)*(0:N_fft2_dec),20*log10(fft_y2_dec_pfir(1:N_fft2_dec+1)), '-'); grid; + +figure; +plot(1:length(I_out_dec_pfir), I_out_dec_pfir, 1:length(Q_out_dec_pfir), Q_out_dec_pfir); grid; + +figure; +freqz(pfir_b, 1, 1000); + +figure; +plot(pfir_b); grid; + + +figure; +subplot(2,1,1) +plot(fa/N_fft*(0:N_fft2),20*log10(fft_y2(1:N_fft2+1)), '-', fa/N_fft*(0:N_fft2), max_spur_value*ones(1,N_fft2+1), 'r-', [max_spur_freq], [max_spur_value], 'ro'); grid; +spur_legend = sprintf('Max. spur %.1fdB at %.3fMHz', max_spur_value, max_spur_freq); +legend('With dithering', spur_legend); +legend('No dithering', spur_legend); +title('Table'); +ylabel('dB'); +xlabel('f/MHz'); +axis([0 fa/2 -140 0]); +subplot(2,1,2) +plot(fa/N_fft*(0:N_fft2),20*log10(fft_y3(1:N_fft2+1)), '-', fa/N_fft*(0:N_fft2), max_ditherd_spur_value*ones(1,N_fft2+1), 'r-', [max_ditherd_spur_freq], [max_ditherd_spur_value], 'ro'); grid; +spur_legend = sprintf('Max. spur %.1fdB at %.3fMHz', max_ditherd_spur_value, max_ditherd_spur_freq); +legend('With dithering', spur_legend); +title('Table'); +ylabel('dB'); +xlabel('f/MHz'); +axis([0 fa/2 -140 0]); + +plot(1:N, I_out, 1:N, Q_out); grid; + +function [max_i, max_v] = get_maxpur(spec, fa, f) +max_v = 0; +max_i = 0; +for ii=1:fix(length(spec)/2+1), + fi = ii*fa/length(spec); + dfi = fi - f; + if abs(dfi) > 0.005*f + if spec(ii) > max_v + max_v = spec(ii); + max_i = ii-1; + end + end; +end; diff --git a/lib/radio/nco/ghdl/tb_nco_results.m b/lib/radio/nco/ghdl/tb_nco_results.m new file mode 100644 index 0000000..df59df0 --- /dev/null +++ b/lib/radio/nco/ghdl/tb_nco_results.m @@ -0,0 +1,61 @@ +% Read data +function tb_nco_results(nbins) +fa = 100.0; +f = textread('freq.txt')*1E-6 + +I_ud = textread('q_ud.txt')'; +I_d = textread('q_d.txt')'; +LFSR = textread('lfsr.txt'); + +N= length(I_ud); +N_fft = min(16384, N); +N_fft2 = fix(N_fft/2); + +fft_y2 = 2/N_fft*abs(fft(I_ud(1:N_fft).*hann(N_fft)')); +fft_y3 = 2/N_fft*abs(fft(I_d(1:N_fft).*hann(N_fft)')); + +[i, v] = get_maxpur(fft_y2, fa, f); +max_spur_freq = (i*fa/N_fft); +max_spur_value = 20*log10(v); + +[i, v] = get_maxpur(fft_y3, fa, f); +max_ditherd_spur_freq = (i*fa/N_fft); +max_ditherd_spur_value = 20*log10(v); + +% Output +close all; + +subplot(2,1,1) +plot(fa/N_fft*(0:N_fft2),20*log10(fft_y2(1:N_fft2+1)), '-', fa/N_fft*(0:N_fft2), max_spur_value*ones(1,N_fft2+1), 'r-', [max_spur_freq], [max_spur_value], 'ro'); grid; +spur_legend = sprintf('Max. spur %.1fdB at %.1fMHz', max_spur_value, max_spur_freq); +legend('With dithering', spur_legend); +legend('No dithering', spur_legend); +title('Table'); +ylabel('dB'); +xlabel('f/MHz'); +axis([0 fa/2 -140 0]); +subplot(2,1,2) +plot(fa/N_fft*(0:N_fft2),20*log10(fft_y3(1:N_fft2+1)), '-', fa/N_fft*(0:N_fft2), max_ditherd_spur_value*ones(1,N_fft2+1), 'r-', [max_ditherd_spur_freq], [max_ditherd_spur_value], 'ro'); grid; +spur_legend = sprintf('Max. spur %.1fdB at %.1fMHz', max_ditherd_spur_value, max_ditherd_spur_freq); +legend('With dithering', spur_legend); +title('Table'); +ylabel('dB'); +xlabel('f/MHz'); +axis([0 fa/2 -140 0]); + +figure; +hist(LFSR, nbins) + +function [max_i, max_v] = get_maxpur(spec, fa, f) +max_v = 0; +max_i = 0; +for ii=1:fix(length(spec)/2+1), + fi = ii*fa/length(spec); + dfi = fi - f; + if abs(dfi) > 0.05*f + if spec(ii) > max_v + max_v = spec(ii); + max_i = ii; + end + end; +end;