Current work is on MLSE and SD Decoding etc. MLSE is currently not 100% working, the scalings are maybe off?!
125 lines
5.0 KiB
Matlab
125 lines
5.0 KiB
Matlab
function [db_results] = duobinary_target(eq_, mlse_,M, rx_signal, tx_symbols, tx_bits, options)
|
|
|
|
arguments
|
|
eq_
|
|
mlse_
|
|
M
|
|
rx_signal
|
|
tx_symbols
|
|
tx_bits
|
|
options.precode_mode db_mode
|
|
options.showAnalysis = 0;
|
|
options.eth_style_symbol_mapping = 0;
|
|
options.postFFE = [];
|
|
end
|
|
|
|
%Duobinary Targeting
|
|
db_ref_sequence = Duobinary().encode(tx_symbols);
|
|
db_ref_constellation = unique(db_ref_sequence.signal);
|
|
[eq_signal, eq_noise] = eq_.process(rx_signal,db_ref_sequence);
|
|
|
|
if ~isempty(options.postFFE)
|
|
[eq_signal,eq_noise] = options.postFFE.process(eq_signal,db_ref_sequence);
|
|
end
|
|
|
|
mlse_.DIR = [1,1];
|
|
% mlse_sig_sd = mlse_.process(eq_signal);
|
|
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
|
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
|
|
% combination with duobinary signaling to avoid catastrophic error
|
|
% behavior (see J.W.M. Bergmans, Digital Baseband Transmission and Recording -> partial response signaling)
|
|
switch options.precode_mode
|
|
|
|
case db_mode.no_db
|
|
% TX Data is not precoded:
|
|
|
|
% A) Emulate diff precoding
|
|
mlse_sig_hd_precoded = Duobinary().encode(mlse_sig_hd,"M",M);
|
|
mlse_sig_hd_precoded = Duobinary().decode(mlse_sig_hd_precoded,"M",M);
|
|
|
|
tx_symbols_precoded = Duobinary().encode(tx_symbols);
|
|
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
|
|
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
|
[bits_mlse,errors_mlse,ber_db,~] = calc_ber(rx_bits_mlse.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
|
|
|
case db_mode.db_precoded
|
|
|
|
% Daten SIND TATSÄCHLICH precoded auf TX Seite:
|
|
|
|
% A) Decode at Rx if no DB targeting was applied (we are in VNLE or MLSE EQ structure here!
|
|
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);
|
|
|
|
% 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);
|
|
|
|
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));
|
|
|
|
db_results = struct();
|
|
db_results.metrics = Metricstruct;
|
|
db_results.metrics.result_id = NaN;
|
|
db_results.metrics.run_id = NaN;
|
|
db_results.metrics.eqParam_id = NaN;
|
|
db_results.metrics.date_of_processing = datetime('now');
|
|
db_results.metrics.BER = ber_db;
|
|
db_results.metrics.numBits = bits_db;
|
|
db_results.metrics.numBitErr = errors_db;
|
|
db_results.metrics.BER_precoded = ber_db_diff_precoded;
|
|
db_results.metrics.numBitErr_precoded = errors_db_diff_precoded;
|
|
db_results.metrics.GMI = gmi_mlse;
|
|
db_results.metrics.AIR = air_mlse;
|
|
db_results.metrics.MLSE_dir = mlse_.DIR;
|
|
db_results.metrics.Alpha = alpha;
|
|
|
|
% Create DB results structure
|
|
db_results.config = Equalizerstruct();
|
|
eq_.e = [];
|
|
eq_.e2 = [];
|
|
eq_.e3 = [];
|
|
db_results.config.eq = jsonencode(eq_);
|
|
% mlse_.DIR = [];
|
|
db_results.config.mlse = jsonencode(mlse_);
|
|
db_results.config.equalizer_structure = int32(equalizer_structure.vnle_db_mlse);
|
|
db_results.config.comment = 'function: Duobinary tgt. (VNLE -> MLSE)';
|
|
|
|
if options.showAnalysis
|
|
eq_noise = eq_noise - mean(eq_noise.signal);
|
|
|
|
rx_signal.spectrum("normalizeTo0dB",1,"fignum",250,"displayname","Rx Spectrum");
|
|
|
|
Duobinary().encode(tx_symbols).spectrum("normalizeTo0dB",1,"fignum",10,"displayname","DB encoded reference");
|
|
|
|
showEQNoisePSD(eq_noise,"fignum",250,"displayname",'Duobinary Target Noise after Equalization');
|
|
|
|
fprintf('DB tgt BER: %.2e \n',ber_db);
|
|
|
|
figure(341); clf;
|
|
showLevelHistogram(eq_signal, db_ref_sequence, "fignum", 341);
|
|
|
|
end
|
|
|
|
|
|
end |