162 lines
6.4 KiB
Matlab
162 lines
6.4 KiB
Matlab
|
|
M = 4;
|
|
order = 18;
|
|
randkey = 1;
|
|
|
|
% bitpattern = [];
|
|
% s = RandStream('twister','Seed',randkey);
|
|
% for i = 1:log2(M)
|
|
% N = 2^(order-1); %length of prbs
|
|
% bitpattern(:,i) = randi(s,[0 1], N, 1);
|
|
% end
|
|
%
|
|
% if M == 6
|
|
% bitpattern = reshape(bitpattern',[],1);
|
|
% bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
|
|
% end
|
|
%
|
|
% Bits = Informationsignal(bitpattern);
|
|
|
|
Bits = Signalgenerator( ...
|
|
"form", signalform.prms, ...
|
|
"M", M, ...
|
|
"order", order).process();
|
|
|
|
Symbols = PAMmapper(M,0).map(Bits);
|
|
Symbols.fs = 200e9;
|
|
|
|
Bits_ = PAMmapper(M, 0, "eth_style", 0).demap(Symbols);
|
|
|
|
% --- Channel: minimal ISI response + AWGN ---
|
|
h = [0.3 0.9 0.3,0.1]; % impulse response (normalized later if desired)
|
|
h = h / norm(h); % optional normalization for unit energy
|
|
|
|
symbols_filt = Symbols.filter(h,1);
|
|
|
|
|
|
%% SHOW FIG 3 in Paper: "ML Base Pre-Eq"
|
|
|
|
SNR_dB = [15:2:25];
|
|
|
|
ber_ffe = zeros(size(SNR_dB));
|
|
ber_mlse_l5 = zeros(size(SNR_dB));
|
|
ber_nwf_mlse_l2 = zeros(size(SNR_dB));
|
|
ber_ml_mlse_l2 = zeros(size(SNR_dB));
|
|
ber_ml_mlse_l3 = zeros(size(SNR_dB));
|
|
ber_ml_mlse_l4 = zeros(size(SNR_dB));
|
|
|
|
epochs_training = 100;
|
|
|
|
parfor i = 1:numel(SNR_dB)
|
|
|
|
symbols_noi = symbols_filt;
|
|
symbols_noi.signal = awgn(symbols_filt.signal, SNR_dB(i), 'measured'); % AWGN with given SNR
|
|
|
|
% Sequence Est L=5
|
|
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',0,'trellis_exclusion',0,'trellis_state_mode',2,'debug',0,'DIR',h);
|
|
mlse_.DIR = h;
|
|
[y_mlse] = mlse_.process(symbols_noi,Symbols);
|
|
mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_mlse);
|
|
[~, ~, ber_mlse_l5(i), ~] = calc_ber(mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
|
fprintf('MLSE L5: %.2e \n',ber_mlse_l5(i));
|
|
|
|
% 2nd Approach
|
|
mu_lms = 0.0005;
|
|
pf_ncoeffs = 1;
|
|
eq_ = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",2^13,"mu_dd",mu_lms,"mu_tr",mu_lms,"order",16,"sps",1,"dd_mode",1,"adaption_technique","lms");
|
|
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
|
|
|
% FFE
|
|
[y_ffe, ffe_noise] = eq_.process(symbols_noi, Symbols);
|
|
|
|
Eq_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ffe);
|
|
[~, ~, ber_ffe(i), ~] = calc_ber(Eq_bits.signal, Bits.signal, "skip_front", 0, "skip_end", 0, "returnErrorLocation", 1);
|
|
fprintf('FFE: %.2e \n',ber_ffe(i));
|
|
|
|
% Postfilter
|
|
[y_white,~] = pf_.process(y_ffe, ffe_noise);
|
|
|
|
% Sequence Est
|
|
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',0,'trellis_exclusion',0,'trellis_state_mode',2,'debug',0,'DIR',pf_.coefficients);
|
|
[y_mlse] = mlse_.process(y_white,Symbols);
|
|
mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_mlse);
|
|
[~, errors, ber_nwf_mlse_l2(i), errpos] = calc_ber(mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
|
fprintf('MLSE: %.2e \n',ber_nwf_mlse_l2(i));
|
|
|
|
% ML-base MLSE L=2
|
|
adaptive_mu = 0;
|
|
mu_lms = 0.15;
|
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",epochs_training,"epochs_dd",1,"len_tr",2^15,...
|
|
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",11,"sps",1,...
|
|
"traceback_depth",128,"L",2,"delta",4,"adaptive_mu",adaptive_mu);
|
|
[y_ml_mlse,~] = ml_mlse_equalizer.process(symbols_noi,Symbols);
|
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
|
[~, errors, ber_ml_mlse_l2(i), errpos] = calc_ber(ml_mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
|
fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse_l2(i));
|
|
|
|
% ML-base MLSE L=3
|
|
mu_lms = 0.15;
|
|
ml_mlse_equalizer = ML_MLSE("epochs_tr",epochs_training,"epochs_dd",1,"len_tr",2^16,...
|
|
"mu_dd",mu_lms,"mu_tr",mu_lms,"order",11,"sps",1,...
|
|
"traceback_depth",128,"L",3,"delta",4,"adaptive_mu",adaptive_mu);
|
|
[y_ml_mlse,~] = ml_mlse_equalizer.process(symbols_noi,Symbols);
|
|
ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
|
[~, errors, ber_ml_mlse_l3(i), errpos] = calc_ber(ml_mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
|
fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse_l3(i));
|
|
|
|
% % ML-base MLSE L=5
|
|
% mu_lms = 0.15;
|
|
% ml_mlse_equalizer = ML_MLSE("epochs_tr",epochs_training,"epochs_dd",1,"len_tr",2^15,...
|
|
% "mu_dd",mu_lms,"mu_tr",mu_lms,"order",11,"sps",1,...
|
|
% "traceback_depth",128,"L",5,"delta",4);
|
|
% [y_ml_mlse,~] = ml_mlse_equalizer.process(symbols_noi,Symbols);
|
|
% ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse);
|
|
% [~, errors, ber_ml_mlse_l5(i), errpos] = calc_ber(ml_mlse_bits.signal, Bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
|
% fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse_l5(i));
|
|
|
|
|
|
end
|
|
|
|
%%
|
|
figure(); hold on;
|
|
|
|
% --- define scheme colors (consistent palette)
|
|
cols = cbrewer2('SET1',8);
|
|
colFFE = cols(1,:); % blue
|
|
colMLSE = cols(2,:); % orange
|
|
colML_MLSE = cols(3,:); % green
|
|
colNWF_MLSE = cols(4,:); % purple
|
|
|
|
% --- local simulation results
|
|
plot(SNR_dB, ber_ffe, '-o', 'Color', colFFE, 'DisplayName','FFE (N=16)');
|
|
if M==2, plot(FFE_wpd.X, FFE_wpd.Y, ':', 'LineWidth',1.5, 'Color', colFFE, 'DisplayName','Paper FFE'); end
|
|
|
|
|
|
plot(SNR_dB, ber_mlse_l5, '-s', 'Color', colMLSE, 'DisplayName','MLSE (L=5)');
|
|
if M==2, plot(MLSE_wpd.X, MLSE_wpd.Y, ':', 'LineWidth',1.5, 'Color', colMLSE, 'DisplayName','Paper MLSE L=5'); end
|
|
|
|
plot(SNR_dB, ber_nwf_mlse_l2,'--^','Color', colNWF_MLSE, 'DisplayName','FFE+PF+MLSE (L=2)');
|
|
plot(SNR_dB, ber_ml_mlse_l2, '-v', 'Color', colML_MLSE, 'DisplayName','ML-based MLSE (L=2)');
|
|
if M==2, plot(ML_MLSE_L_2_wpd.X,ML_MLSE_L_2_wpd.Y,':', 'LineWidth',1.5, 'Color', colML_MLSE, 'DisplayName','Paper ML-based MLSE L=2'); end
|
|
|
|
|
|
plot(SNR_dB, ber_ml_mlse_l3, '-d', 'Color', colML_MLSE, 'DisplayName','ML-based MLSE (L=3)');
|
|
|
|
if M==2, plot(SNR_dB, ber_ml_mlse_l5, '-p', 'Color', colML_MLSE, 'DisplayName','ML-based MLSE (L=5)'); end
|
|
if M==2, plot(ML_MLSE_L_5_wpd.X,ML_MLSE_L_5_wpd.Y,':', 'LineWidth',1.5, 'Color', colML_MLSE, 'DisplayName','Paper ML-based MLSE L=5'); end
|
|
% --- imported WebPlotDigitizer data (dotted)
|
|
|
|
yline(3.8e-3,'HandleVisibility','off');
|
|
yline(2.2e-4,'HandleVisibility','off');
|
|
|
|
% --- formatting
|
|
beautifyBERplot;
|
|
xlim([SNR_dB(1), SNR_dB(end)]);
|
|
ylim([1e-5 0.1]);
|
|
xlabel('Input SNR [dB]');
|
|
ylabel('Bit Error Rate (BER)');
|
|
title('PAM-4; M=4; AWGN Channel');
|
|
legend('Location','southwest');
|
|
grid on;
|
|
|