start with 400G analysis work

This commit is contained in:
Silas Oettinghaus
2026-07-20 10:22:11 +02:00
parent cae81c0dae
commit 125d8508ca
43 changed files with 4089 additions and 123 deletions

View File

@@ -21,10 +21,13 @@ arguments
tx_symbols
tx_bits
options.precode_mode db_mode
options.decoding_mode db_decoder = db_decoder.sequencedetection;
options.showAnalysis = 0
options.eth_style_symbol_mapping = 0
options.postFFE = []
options.database = []
end
%% Process signals through equalizer
@@ -35,43 +38,72 @@ if ~isempty(options.postFFE)
[eq_signal, eq_noise] = options.postFFE.process(eq_signal, tx_symbols);
end
if isa(mlse_,'MLSE_viterbi')
[mlse_signal] = mlse_.process(eq_signal);
else
% Aufpassen mit welcher Sequenz man hier vergleicht für LLR stuff...
% gespeichtere "Symbols" sind schon DB codiert, das wollen wir hier
% nicht! Sondern die precoded aber nicht db-encoded müssen als ref in
% die LLR berechnung gehen!
ref_sym = PAMmapper(M,0).map(tx_bits); %ist klar
ref_sym_dpc = Duobinary().precode(ref_sym); % precoded
% ref_sym_dbenc = Duobinary().encode(ref_sym_dpc); %encoded - das wurde gesendet!
% ref_sym_dec = Duobinary().decode(ref_sym_dbenc); %ref_sym wieder zurück!
mlse_.trellis_states = PAMmapper(M,0).levels;
mlse_.trellis_state_mode = 1;
[mlse_signal,LLR,GMI_MLSE] = mlse_.process(eq_signal,ref_sym_dpc);
run_both_detection_schemes = 1;
if options.decoding_mode == db_decoder.sequencedetection || run_both_detection_schemes %MLSE
if isa(mlse_,'MLSE_viterbi')
[mlse_signal] = mlse_.process(eq_signal);
else
% Aufpassen mit welcher Sequenz man hier vergleicht für LLR stuff...
% gespeichtere "Symbols" sind schon DB codiert, das wollen wir hier
% nicht! Sondern die precoded aber nicht db-encoded müssen als ref in
% die LLR berechnung gehen!
ref_sym = PAMmapper(M,0).map(tx_bits); %ist klar
ref_sym_dpc = Duobinary().precode(ref_sym); % precoded
% ref_sym_dbenc = Duobinary().encode(ref_sym_dpc); %encoded - das wurde gesendet!
% ref_sym_dec = Duobinary().decode(ref_sym_dbenc); %ref_sym wieder zurück!
mlse_.trellis_states = PAMmapper(M,0).levels;
% mlse_.scale_mode = 2;
if M == 6
mlse_.trellis_exclusion = 0;
end
mlse_.debug = 0;
[mlse_signal,LLR,GMI_MLSE] = mlse_.process(eq_signal.normalize("mode","rms"),ref_sym_dpc);
end
% Apply duobinary encoding and decoding
mlse_signal = Duobinary().encode(mlse_signal,"M",M);
mlse_signal = Duobinary().decode(mlse_signal,"M",M);
% Demap symbols to bits
rx_bits = PAMmapper(M, 0, "eth_style", options.eth_style_symbol_mapping).demap(mlse_signal);
[bits_db, ~, ber_sequencedetection, ~] = calc_ber(rx_bits.signal, tx_bits.signal, "skip_front", 100, "skip_end", 150, "returnErrorLocation", 1);
end
if options.decoding_mode == db_decoder.memoryless || run_both_detection_schemes
db_ref_constellation = unique(tx_symbols.signal);
eq_signal_hd = PAMmapper(M, 0).quantize(eq_signal,'custom_const',db_ref_constellation.');
eq_signal_hd = Duobinary().decode(eq_signal_hd,"M",M);
% Demap
rx_bits = PAMmapper(M, 0, "eth_style", options.eth_style_symbol_mapping).demap(eq_signal_hd);
[bits_db, ~, ber_memoryless, ~] = calc_ber(rx_bits.signal, tx_bits.signal, "skip_front", 100, "skip_end", 150, "returnErrorLocation", 1);
end
% tx_symbols_ = Duobinary().decode(tx_symbols);
% [mlse_signal,~,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
% Apply duobinary encoding and decoding
mlse_signal = Duobinary().encode(mlse_signal);
mlse_signal = Duobinary().decode(mlse_signal);
% Demap symbols to bits
rx_bits = PAMmapper(M, 0, "eth_style", options.eth_style_symbol_mapping).demap(mlse_signal);
%% Calculate BER and metrics
[bits_db, errors_db, ber_db, error_pos] = calc_ber(rx_bits.signal, tx_bits.signal, "skip_front", 100, "skip_end", 150, "returnErrorLocation", 1);
% Calculate BER and metrics
% Calculate performance metrics after duobinary FFE!
[snr, snr_lvl] = calc_snr(tx_symbols.signal, eq_noise.signal); %SNR of duobinary sequence - not directly comparable to
[gmi] = calc_air(eq_signal, tx_symbols, "skip_front", 10000, "skip_end", 10000);
air = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi ./ log2(double(M));
% [gmi] = calc_air(eq_signal, tx_symbols, "skip_front", 10000, "skip_end", 10000); % Not working for Duobinary == Channel with memory
% air = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi ./ log2(double(M));
if options.decoding_mode == db_decoder.sequencedetection || run_both_detection_schemes
[gmi] = GMI_MLSE;
air = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi ./ log2(double(M));
end
[evm_total, evm_lvl] = calc_evm(eq_signal, tx_symbols);
[std_total, std_lvl] = calc_std(eq_signal, tx_symbols);
[std_rxraw_total, std_rxraw_lvl] = calc_std(rx_signal.resample("fs_out", tx_symbols.fs), tx_symbols);
@@ -91,9 +123,12 @@ 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.BER = ber_sequencedetection; % THIS IS A CONVENTION
db_results.metrics.BER_precoded = ber_memoryless; % THIS IS A CONVENTION
% db_results.metrics.BER_DB_memoryless = ber_memoryless;
% db_results.metrics.BER_DB_sequencedetection = ber_sequencedetection;
db_results.metrics.numBits = bits_db;
db_results.metrics.numBitErr = errors_db;
% db_results.metrics.numBitErr = NaN;
db_results.metrics.SNR = snr;
db_results.metrics.SNR_level = snr_lvl;
db_results.metrics.STD = std_total;