From 3de17083a202f9adbd97753119738150105e712b Mon Sep 17 00:00:00 2001 From: drowe67 Date: Wed, 28 Mar 2012 02:27:58 +0000 Subject: [PATCH] added techniques to optimise PAPR and simulate PA clipping, managed to improve PAPR by 6dB git-svn-id: https://svn.code.sf.net/p/freetel/code@356 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/fdmdv.m | 26 +++++++++++++++++-- codec2-dev/octave/fdmdv_ut.m | 48 +++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index 3df287d3..71a098c2 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -82,6 +82,9 @@ function tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits, modulation) tx_bits_matrix(1:Nc,2) = tx_bits(2:Nb:Nb*Nc); if (strcmp(modulation,'dqpsk')) + + + if 1 % map to (Nc,1) DQPSK symbols for c=1:Nc @@ -99,7 +102,22 @@ function tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits, modulation) if ((msb == 1) && (lsb == 1)) tx_symbols(c) = -j*prev_tx_symbols(c); endif + end + else + % map to pi/4 DQPSK from spra341 Eq (6) & (7) + + for c=1:Nc + + msb = tx_bits_matrix(c,1); lsb = tx_bits_matrix(c,2); + a = 2*msb - 1; + b = 2*lsb - 1; + p = prev_tx_symbols(c); + inphase = (real(p)*a - imag(p)*b)*0.707; + quadrature = (imag(p)*a + real(p)*b)*0.707; + tx_symbols(c) = inphase + j*quadrature; + end end + else % QPSK mapping tx_symbols = -1 + 2*tx_bits_matrix(:,1) - j + 2j*tx_bits_matrix(:,2); @@ -492,7 +510,7 @@ function [sync bit_errors] = put_test_bits(rx_bits) ber = bit_errors/Ntest_bits; sync = 0; - if (ber < 0.1) + if (ber < 0.2) sync = 1; endif endfunction @@ -517,7 +535,11 @@ end freq(Nc+1) = exp(j*2*pi*Fcentre/Fs); -global phase_tx = ones(Nc+1,1); +% Spread initial FDM carrier phase out as far as possible. +% This really helped PAPR. We don't need to adjust rx +% phase a DPSK takes care of that + +global phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1)); global phase_rx = ones(Nc+1,1); % Freq offset estimator states diff --git a/codec2-dev/octave/fdmdv_ut.m b/codec2-dev/octave/fdmdv_ut.m index 670c18a9..89c02c14 100644 --- a/codec2-dev/octave/fdmdv_ut.m +++ b/codec2-dev/octave/fdmdv_ut.m @@ -17,6 +17,7 @@ frames = 100; EbNo_dB = 7.3; Foff_hz = -100; modulation = 'dqpsk'; +hpa_clip = 10; % ------------------------------------------------------------ @@ -31,13 +32,14 @@ total_bits = 0; rx_fdm_log = []; rx_baseband_log = []; rx_bits_offset = zeros(Nc*Nb*2); -prev_tx_symbols = sqrt(2)*ones(Nc+1,1)*exp(j*pi/4); +prev_tx_symbols = sqrt(2)*ones(Nc+1,1); prev_tx_symbols(Nc+1) = 1; -prev_rx_symbols = sqrt(2)*ones(Nc+1,1)*exp(j*pi/4); +prev_rx_symbols = sqrt(2)*ones(Nc+1,1); foff_log = []; tx_baseband_log = []; tx_fdm_log = []; sync_log = []; +bit_errors_log = []; Ndelay = M+20; rx_fdm_delay = zeros(Ndelay,1); @@ -92,13 +94,20 @@ for i=1:frames tx_baseband = tx_filter(tx_symbols); tx_baseband_log = [tx_baseband_log tx_baseband]; [tx_fdm pilot] = fdm_upconvert(tx_baseband); - tx_fdm_log = [tx_fdm_log tx_fdm]; tx_pwr = 0.9*tx_pwr + 0.1*real(tx_fdm)*real(tx_fdm)'/(M); % ------------------- % Channel simulation % ------------------- + % HPA non-linearity + + i = find(abs(tx_fdm) > hpa_clip); + tx_fdm(i) = hpa_clip*exp(j*angle(tx_fdm(i))); + tx_fdm_log = [tx_fdm_log tx_fdm]; + + rx_fdm = tx_fdm; + % frequency offset for i=1:M @@ -108,7 +117,7 @@ for i=1:frames Foff = Foff_hz; freq_offset = exp(j*2*pi*Foff/Fs); phase_offset *= freq_offset; - rx_fdm(i) = phase_offset*real(tx_fdm(i)); + rx_fdm(i) = phase_offset*real(rx_fdm(i)); end % AWGN noise @@ -167,6 +176,9 @@ for i=1:frames if (test_frame_sync == 1) total_bit_errors = total_bit_errors + bit_errors; total_bits = total_bits + Ntest_bits; + bit_errors_log = [bit_errors_log bit_errors]; + else + bit_errors_log = [bit_errors_log -1]; end end @@ -175,11 +187,16 @@ end % Print Stats % --------------------------------------------------------------------- -peak = max(real(tx_fdm_log)); -ber = total_bit_errors/total_bits; -printf("Eb/No (meas): %2.2f (%2.2f) dB %d bits %d errors BER: (%1.4f) Pk/rms: %1.2f\n", +ber = total_bit_errors / total_bits; + +% Peak to Average Power Ratio from http://www.dsplog.com + +papr = max(tx_fdm_log.*conj(tx_fdm_log)) / mean(tx_fdm_log.*conj(tx_fdm_log)); +papr_dB = 10*log10(papr); + +printf("Eb/No (meas): %2.2f (%2.2f) dB %d bits %d errors BER: (%1.4f) PAPR: %1.2f dB SNR: %2.1f dB\n", EbNo_dB, 10*log10(0.25*tx_pwr*Fs/(Rs*Nc*noise_pwr)), - total_bits, total_bit_errors, ber, peak/std(real(tx_fdm_log)) ); + total_bits, total_bit_errors, ber, papr_dB, SNR ); % --------------------------------------------------------------------- % Plots @@ -204,9 +221,22 @@ figure(3) clf; subplot(211) plot(real(tx_fdm_log)); +title('FDM Tx Signal'); subplot(212) -stem(sync_log) +Nfft=Fs; +S=fft(rx_fdm_log,Nfft); +SdB=20*log10(abs(S)); +plot(SdB(1:Fs/4)) +title('FDM Tx Spectrum'); +figure(4) +clf; +subplot(211) +stem(sync_log) +title('BPSK Sync') +subplot(212) +stem(bit_errors_log); +title('Bit Errors for test data') % TODO % + handling sample slips, extra plus/minus samples -- 2.25.1