BCJR implementation
WDM code added (Pol Cont., Opt MUX/DEMUX, Opt Atten, DP_Fiber) -> the codebase is not optimized to always work with dp signals!
This commit is contained in:
@@ -96,11 +96,11 @@ try
|
||||
adaption= 1;
|
||||
use_dd_mode = 1;
|
||||
|
||||
use_ffe = 0;
|
||||
use_dfe = 0;
|
||||
use_ffe = 1;
|
||||
use_dfe = 1;
|
||||
use_vnle_mlse = 1;
|
||||
use_dbtgt = 1;
|
||||
use_dbenc = 1;
|
||||
use_dbenc = 0;
|
||||
|
||||
addProcessingResultToDatabase = 0;
|
||||
|
||||
@@ -125,13 +125,12 @@ try
|
||||
|
||||
|
||||
%
|
||||
eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
% mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels);
|
||||
|
||||
eq_post = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-4,"mu_tr",0,"order",2001,"sps",1,"decide",0,"adaption_technique","lms");
|
||||
|
||||
eq_post =FFE("epochs_tr",5,"epochs_dd",2,"len_tr",2^13,"mu_dd",mu_dd,"mu_tr",mu_tr,"order",25,"sps",2,"decide",0, "adaption",adaption_method(adaption),"dd_mode",use_dd_mode);
|
||||
% Duobinary signaling (db encoded)
|
||||
mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels);
|
||||
eq_db_enc = EQ("Ne", ffe_order, "Nb", dfe_order, "training_length", len_tr, ...
|
||||
@@ -194,60 +193,78 @@ try
|
||||
if use_vnle_mlse
|
||||
|
||||
pf_ncoeffs = 1;
|
||||
ffe_order = [50, 5, 5];
|
||||
eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
% mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
|
||||
useviterbi = 0;
|
||||
if useviterbi
|
||||
mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
else
|
||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
end
|
||||
|
||||
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||
"precode_mode", duob_mode,...
|
||||
'showAnalysis', 1, ...
|
||||
'showAnalysis', 0, ...
|
||||
"postFFE", [],...
|
||||
"eth_style_symbol_mapping", 0);
|
||||
|
||||
ffe_results.metrics.print;
|
||||
ffe_results.config.equalizer_structure = "vnle";
|
||||
mlse_results.metrics.print;
|
||||
|
||||
|
||||
output.mlse_package{r} = mlse_results;
|
||||
output.vnle_package{r} = ffe_results;
|
||||
|
||||
|
||||
if options.append_to_db
|
||||
database.addProcessingResult(run_id, mlse_results.metrics, mlse_results.config);
|
||||
database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config);
|
||||
end
|
||||
|
||||
pf_ncoeffs = 2;
|
||||
eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
% mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
% pf_ncoeffs = 2;
|
||||
% eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
% pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||
% % mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
% mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
%
|
||||
% [ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||
% "precode_mode", duob_mode,...
|
||||
% 'showAnalysis', 0, ...
|
||||
% "postFFE", [],...
|
||||
% "eth_style_symbol_mapping", 0);
|
||||
%
|
||||
% ffe_results.metrics.print;
|
||||
% mlse_results.metrics.print;
|
||||
%
|
||||
% output.mlse_package{r} = mlse_results;
|
||||
% output.vnle_package{r} = ffe_results;
|
||||
%
|
||||
% if options.append_to_db
|
||||
% database.addProcessingResult(run_id, mlse_results.metrics, mlse_results.config);
|
||||
% database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config);
|
||||
% end
|
||||
|
||||
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||
"precode_mode", duob_mode,...
|
||||
'showAnalysis', 1, ...
|
||||
"postFFE", [],...
|
||||
"eth_style_symbol_mapping", 0);
|
||||
|
||||
ffe_results.metrics.print;
|
||||
mlse_results.metrics.print;
|
||||
|
||||
output.mlse_package{r} = mlse_results;
|
||||
output.vnle_package{r} = ffe_results;
|
||||
|
||||
if options.append_to_db
|
||||
database.addProcessingResult(run_id, mlse_results.metrics, mlse_results.config);
|
||||
database.addProcessingResult(run_id, ffe_results.metrics, ffe_results.config);
|
||||
end
|
||||
end
|
||||
|
||||
if use_dbtgt
|
||||
|
||||
useviterbi = 0;
|
||||
if useviterbi
|
||||
mlse_db_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
||||
else
|
||||
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels);
|
||||
end
|
||||
ffe_order = [50, 5, 5];
|
||||
eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5,"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
||||
|
||||
dbt_results = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||
"precode_mode", duob_mode, ...
|
||||
'showAnalysis', 0,...
|
||||
"postFFE", []);
|
||||
|
||||
dbt_results.metrics.print;
|
||||
|
||||
output.dbtgt_package{r} = dbt_results;
|
||||
|
||||
if options.append_to_db
|
||||
|
||||
@@ -23,8 +23,14 @@ if ~isempty(options.postFFE)
|
||||
end
|
||||
|
||||
mlse_.DIR = [1,1];
|
||||
% mlse_sig_sd = mlse_.process(eq_signal);
|
||||
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
||||
%
|
||||
|
||||
if isa(mlse_,'MLSE_viterbi')
|
||||
mlse_sig_sd = mlse_.process(eq_signal);
|
||||
else
|
||||
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
||||
end
|
||||
|
||||
mlse_sig_hd = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).quantize(mlse_sig_sd);
|
||||
|
||||
% precoding to mitigate error propagation, most prominently used in
|
||||
@@ -43,8 +49,8 @@ switch options.precode_mode
|
||||
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
||||
|
||||
tx_bits_precoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols_precoded);
|
||||
|
||||
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd_precoded);
|
||||
|
||||
[~,errors_db_diff_precoded,ber_db_diff_precoded,~] = calc_ber(rx_bits_mlse.signal,tx_bits_precoded.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
|
||||
%B) Just determine BER
|
||||
@@ -59,24 +65,42 @@ switch options.precode_mode
|
||||
mlse_sig_hd_decoded = Duobinary().encode(mlse_sig_hd,"M",M);
|
||||
mlse_sig_hd_decoded = Duobinary().decode(mlse_sig_hd_decoded,"M",M);
|
||||
rx_bits_mlse_decoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd_decoded);
|
||||
[~,errors_db_diff_precoded,ber_db_diff_precoded,~] = calc_ber(rx_bits_mlse_decoded.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
|
||||
[~,errors_db_diff_precoded,ber_db_diff_precoded,a] = calc_ber(rx_bits_mlse_decoded.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
burst_db_precoded = count_error_bursts(a, 40);
|
||||
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||
|
||||
tx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols);
|
||||
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
||||
[bits_db,errors_db,ber_db,~] = calc_ber(rx_bits_mlse.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
[bits_db,errors_db,ber_db,a] = calc_ber(rx_bits_mlse.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
burst_db = count_error_bursts(a, 40);
|
||||
|
||||
cols = linspecer(8);
|
||||
figure();hold on;
|
||||
stem(1:40,burst_db,'LineWidth',1,'Color',cols(4,:),'Marker','_','DisplayName','w/o diff. precoder');
|
||||
stem(1:40,burst_db_precoded,'LineWidth',1,'Color',cols(3,:),'Marker','.','LineStyle','-','DisplayName','w diff. precoder');
|
||||
xlabel('Bit Error Burst Length')
|
||||
ylabel('Occurence')
|
||||
set(gca, 'yscale', 'log');
|
||||
end
|
||||
|
||||
% M = numel(unique(tx_symbols.signal));
|
||||
rx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
||||
|
||||
[bits_db,errors_db,ber_db,errorIndice_db] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
alpha = arburg(eq_noise.signal,1);%pf_.coefficients(2);
|
||||
alpha = alpha(2);
|
||||
gmi_mlse = GMI_MLSE;
|
||||
air_mlse = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_mlse ./ log2(double(M));
|
||||
if isa(mlse_,'MLSE_viterbi')
|
||||
gmi_mlse = NaN;
|
||||
air_mlse = NaN;
|
||||
else
|
||||
gmi_mlse = GMI_MLSE;
|
||||
air_mlse = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_mlse ./ log2(double(M));
|
||||
end
|
||||
|
||||
db_results = struct();
|
||||
db_results.metrics = Metricstruct;
|
||||
|
||||
@@ -49,7 +49,10 @@ eq_signal_hd = PAMmapper(M, 0).quantize(eq_signal_sd);
|
||||
|
||||
%% Calculate performance metrics
|
||||
[snr, snr_lvl] = calc_snr(tx_symbols.signal, eq_noise.signal);
|
||||
[gmi] = calc_air(eq_signal_sd, tx_symbols, "skip_front", 10000, "skip_end", 10000);
|
||||
% [gmi] = calc_air(eq_signal_sd, tx_symbols, "skip_front", 10000, "skip_end", 10000);
|
||||
[gmi] = calc_ngmi(eq_signal_sd,tx_symbols);
|
||||
gmi = max(gmi,0);
|
||||
|
||||
air = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi ./ log2(double(M));
|
||||
[evm_total, evm_lvl] = calc_evm(eq_signal_sd, tx_symbols);
|
||||
[std_total, std_lvl] = calc_std(eq_signal_sd, tx_symbols);
|
||||
|
||||
@@ -34,7 +34,7 @@ end
|
||||
% FFE or VNLE
|
||||
[eq_signal_sd, eq_noise] = eq_.process(rx_signal, tx_symbols);
|
||||
|
||||
% Apply post-FFE if provided
|
||||
% Apply post-FFE if provided (does not work properly at the moment...very sad)
|
||||
if ~isempty(options.postFFE)
|
||||
tic
|
||||
[eq_signal_sd, eq_noise] = options.postFFE.process(eq_signal_sd, tx_symbols);
|
||||
@@ -43,13 +43,18 @@ end
|
||||
|
||||
% Hard decision on VNLE output
|
||||
eq_signal_hd = PAMmapper(M, 0).quantize(eq_signal_sd);
|
||||
eq_signal_hd.spectrum("displayname",'after full response FFE','fignum',2025,'normalizeTo0dB',1);
|
||||
|
||||
% Process through postfilter and MLSE
|
||||
[mlse_sig_sd,whitened_noise] = pf_.process(eq_signal_sd, eq_noise);
|
||||
mlse_.DIR = pf_.coefficients;
|
||||
|
||||
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(mlse_sig_sd,tx_symbols);
|
||||
GMI_MLSE = NaN;
|
||||
if isa(mlse_,'MLSE_viterbi')
|
||||
[mlse_sig_sd] = mlse_.process(mlse_sig_sd);
|
||||
else
|
||||
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(mlse_sig_sd,tx_symbols);
|
||||
end
|
||||
|
||||
mlse_sig_hd = PAMmapper(M, 0, "eth_style", options.eth_style_symbol_mapping).quantize(mlse_sig_sd);
|
||||
|
||||
%% Calculate BER based on precoding mode
|
||||
@@ -58,7 +63,12 @@ mlse_sig_hd = PAMmapper(M, 0, "eth_style", options.eth_style_symbol_mapping).qua
|
||||
%% Calculate performance metrics
|
||||
% VNLE metrics
|
||||
[snr_vnle, snr_vnle_lvl] = calc_snr(tx_symbols.signal, eq_noise.signal);
|
||||
[gmi_vnle] = calc_air(eq_signal_sd, tx_symbols, "skip_front", 10000, "skip_end", 10000);
|
||||
% [gmi_vnle] = calc_air(eq_signal_sd, tx_symbols, "skip_front", 10000, "skip_end", 10000);
|
||||
|
||||
%calculate bitwise GMI
|
||||
[gmi_vnle] = calc_ngmi(eq_signal_sd,tx_symbols);
|
||||
gmi_vnle = max(gmi_vnle,0);
|
||||
|
||||
air_vnle = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_vnle ./ log2(double(M));
|
||||
[evm_vnle_total, evm_vnle_lvl] = calc_evm(eq_signal_sd, tx_symbols);
|
||||
[std_vnle_total, std_vnle_lvl] = calc_std(eq_signal_sd, tx_symbols);
|
||||
@@ -67,7 +77,7 @@ air_vnle = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_vnle ./ log2(dou
|
||||
% MLSE metrics
|
||||
alpha = arburg(eq_noise.signal,1);%pf_.coefficients(2);
|
||||
alpha = alpha(2);
|
||||
gmi_mlse = GMI_MLSE;
|
||||
gmi_mlse = max(GMI_MLSE,0);
|
||||
air_mlse = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_mlse ./ log2(double(M));
|
||||
|
||||
%% Display analysis if requested
|
||||
@@ -77,6 +87,10 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
%% Prepare output structures
|
||||
% Determine postFFE order
|
||||
if ~isempty(options.postFFE)
|
||||
@@ -119,8 +133,6 @@ ffe_results.config.eq = jsonencode(eq_);
|
||||
ffe_results.config.equalizer_structure = int32(equalizer_structure.vnle);
|
||||
ffe_results.config.comment = 'function: vnle_postfilter_mlse - FFE part';
|
||||
|
||||
|
||||
|
||||
mlse_results = struct();
|
||||
mlse_results.metrics = Metricstruct;
|
||||
mlse_results.metrics.result_id = NaN;
|
||||
@@ -141,7 +153,6 @@ mlse_results.metrics.Alpha = alpha;
|
||||
mlse_results.metrics.MLSE_dir = mlse_.DIR;
|
||||
|
||||
% Create MLSE results structure
|
||||
|
||||
mlse_results.config = Equalizerstruct();
|
||||
mlse_results.config.eq = jsonencode(eq_);
|
||||
mlse_.DIR = length(mlse_.DIR)-1;
|
||||
@@ -203,7 +214,7 @@ switch precode_mode
|
||||
mlse_sig_hd_decoded = Duobinary().encode(mlse_sig_hd, "M", M);
|
||||
mlse_sig_hd_decoded = Duobinary().decode(mlse_sig_hd_decoded, "M", M);
|
||||
rx_bits_mlse_decoded = mapper.demap(mlse_sig_hd_decoded);
|
||||
[~, errors.mlse_precoded, ber.mlse_precoded, ~] = calc_ber(rx_bits_mlse_decoded.signal, tx_bits.signal, "skip_front", 100, "skip_end", 150, "returnErrorLocation", 1);
|
||||
[~, errors.mlse_precoded, ber.mlse_precoded, err_loc_precoded] = calc_ber(rx_bits_mlse_decoded.signal, tx_bits.signal, "skip_front", 100, "skip_end", 150, "returnErrorLocation", 1);
|
||||
|
||||
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||
tx_bits_demapped = mapper.demap(tx_symbols);
|
||||
@@ -213,6 +224,19 @@ switch precode_mode
|
||||
rx_bits_mlse = mapper.demap(mlse_sig_hd);
|
||||
[numbits.mlse, errors.mlse, ber.mlse, error_locations.mlse] = calc_ber(rx_bits_mlse.signal, tx_bits_demapped.signal, "skip_front", 100, "skip_end", 150, "returnErrorLocation", 1);
|
||||
end
|
||||
|
||||
% cols = linspecer(8);
|
||||
% burst_precoded = count_error_bursts(err_loc_precoded, 40);
|
||||
% burst_normal = count_error_bursts(error_locations.mlse, 40);
|
||||
% figure();hold on;
|
||||
% stem(1:40,burst_normal,'LineWidth',1,'Color',cols(1,:),'Marker','_','DisplayName','w/o diff. precoder');
|
||||
% stem(1:40,burst_precoded,'LineWidth',1,'Color',cols(2,:),'Marker','.','LineStyle','-','DisplayName','w diff. precoder');
|
||||
% xlabel('Bit Error Burst Length')
|
||||
% ylabel('Occurence')
|
||||
% set(gca, 'yscale', 'log');
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user