Simulation preps for high speed.

This commit is contained in:
Silas Oettinghaus
2025-11-14 11:45:13 +01:00
parent 0080cb2264
commit 888cbbd23e
9 changed files with 384 additions and 535 deletions

View File

@@ -97,10 +97,10 @@ try
use_ffe = 0;
use_dfe = 0;
use_vnle_mlse = 0;
use_vnle_mlse = 1;
use_dbtgt = 0;
use_dbenc = 0;
use_ml_mlse = 1;
use_ml_mlse = 0;
addProcessingResultToDatabase = 0;
@@ -140,7 +140,7 @@ try
% Preprocess signal
Scpe_sig = preprocessSignal(Scpe_cell{r}, Symbols, fsym);
% Scpe_sig.spectrum("fignum",2223,"normalizeTo0dB",1,"displayname",'Rx');
Scpe_sig.spectrum("fignum",2223,"normalizeTo0dB",1,"displayname",'Rx');
% Scpe_sig.spectrum("fignum",22233,"normalizeTo0dB",0,"displayname",'Rx');
% Scpe_sig.eye(fsym,M,"fignum",1024);
@@ -194,7 +194,8 @@ try
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);
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",0);
% eq_ = VNLE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",[0.0004 0.0005 0.0006],"mu_tr",0.0004,"order",[50,5,5],"sps",2,"decide",0);
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
useviterbi = 0;
@@ -288,6 +289,8 @@ try
if duob_mode == db_mode.db_encoded
mlse_db_enc = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels);
db_results = duobinary_signaling(eq_db_enc, mlse_db_enc, M, Scpe_sig, Symbols, Tx_bits, "precode_mode",duob_mode, "showAnalysis",0,"postFFE",[]);
output.dbenc_package{r} = db_results;
if options.append_to_db

View File

@@ -35,8 +35,26 @@ if ~isempty(options.postFFE)
[eq_signal, eq_noise] = options.postFFE.process(eq_signal, tx_symbols);
end
% Process through MLSE
[mlse_signal] = mlse_.process(eq_signal);
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);
end
% tx_symbols_ = Duobinary().decode(tx_symbols);
% [mlse_signal,~,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);

View File

@@ -44,31 +44,35 @@ try
end
ml_mlse_results.config = Equalizerstruct();
eq_small = strip_eq(eq_, 10);
json_str = jsonencode(eq_small);
ml_mlse_results.config.eq = jsonencode(eq_);
ml_mlse_results.config.equalizer_structure = int32(equalizer_structure.ml_mlse);
ml_mlse_results.config.comment = 'function: ML-based MLSE';
ml_mlse_results.metrics = Metricstruct;
ml_mlse_results.metrics.result_id = NaN;
ml_mlse_results.metrics.run_id = NaN;
ml_mlse_results.metrics.eqParam_id = NaN;
% ml_mlse_results.metrics.result_id = NaN;
% ml_mlse_results.metrics.run_id = NaN;
% ml_mlse_results.metrics.eqParam_id = NaN;
ml_mlse_results.metrics.date_of_processing = datetime('now');
ml_mlse_results.metrics.BER = ber;
ml_mlse_results.metrics.numBits = bits;
ml_mlse_results.metrics.numBitErr = errors;
ml_mlse_results.metrics.BER_precoded = ber_precoded;
ml_mlse_results.metrics.numBitErr_precoded = errors_precoded;
ml_mlse_results.metrics.SNR = NaN;
ml_mlse_results.metrics.SNR_level = NaN;
ml_mlse_results.metrics.STD = NaN;
ml_mlse_results.metrics.STD_level = NaN;
ml_mlse_results.metrics.STDrx = NaN;
ml_mlse_results.metrics.STDrx_level = NaN;
ml_mlse_results.metrics.GMI = NaN;
ml_mlse_results.metrics.AIR = NaN;
ml_mlse_results.metrics.EVM = NaN;
ml_mlse_results.metrics.EVM_level = NaN;
ml_mlse_results.metrics.Alpha = NaN;
% ml_mlse_results.metrics.SNR = NaN;
% ml_mlse_results.metrics.SNR_level = NaN;
% ml_mlse_results.metrics.STD = NaN;
% ml_mlse_results.metrics.STD_level = NaN;
% ml_mlse_results.metrics.STDrx = NaN;
% ml_mlse_results.metrics.STDrx_level = NaN;
% ml_mlse_results.metrics.GMI = NaN;
% ml_mlse_results.metrics.AIR = NaN;
% ml_mlse_results.metrics.EVM = NaN;
% ml_mlse_results.metrics.EVM_level = NaN;
% ml_mlse_results.metrics.Alpha = NaN;
end
@@ -111,3 +115,26 @@ switch precode_mode
[bits, errors, ber, error_pos] = calc_ber(rx_bits.signal, tx_bits_demapped.signal, "skip_front", 30000, "skip_end", 150, "returnErrorLocation", 1);
end
end
function eq_out = strip_eq(eq_, max_elems)
% strip_eq removes all large fields from the ML_MLSE object
% eq_out = strip_eq(eq_, max_elems)
% max_elems ... maximum number of elements to keep (default = 10)
if nargin < 2
max_elems = 10; % default threshold
end
props = properties(eq_);
for i = 1:numel(props)
val = eq_.(props{i});
if ~isempty(val)
% Count total number of elements
if numel(val) > max_elems
eq_.(props{i}) = [];
end
end
end
eq_out = eq_;
end

View File

@@ -45,7 +45,26 @@ end
eq_signal_hd = PAMmapper(M, 0).quantize(eq_signal_sd);
% Process through postfilter and MLSE
[mlse_sig_sd,whitened_noise] = pf_.process(eq_signal_sd, eq_noise);
if 0 %tx_symbols.fs > 190e9
if pf_.ncoeff == 1
if pf_.coefficients(2) < 0
% coeff is negative for too high/ bad VNLE convergence
pf_.coefficients(2) = 0.9;
end
else
%long memory / pf respinse - not sure what to set here in a worst
%case :-)
end
%do it again:
pf_.useBurg = 0;
[mlse_sig_sd,whitened_noise] = pf_.process(eq_signal_sd, eq_noise);
end
mlse_.DIR = pf_.coefficients;
GMI_MLSE = NaN;
@@ -249,7 +268,8 @@ figure(336);
hold on;
eq_signal_sd.spectrum("displayname",'Equalized Signal','fignum',336,'normalizeTo0dB',0);
eq_noise.spectrum("displayname",'Equalized Signal','fignum',336,'normalizeTo0dB',0);
showEQNoisePSD(eq_noise, "fignum", 336, "displayname", 'Residual Noise after VNLE', 'postfilter_taps', pf_.coefficients);
showEQNoisePSD(eq_noise, "fignum", 338, "displayname", 'Residual Noise after VNLE', 'postfilter_taps', pf_.coefficients);
for t = 1:4
pf_.ncoeff = t;
@@ -263,6 +283,7 @@ if ~isempty(postFFE)
showEQcoefficients('n1', postFFE.e, "displayname", 'Coefficients', 'fignum', 338);
end
showEQcoefficients('n1', eq_.e,'n2', eq_.e2,'n3', eq_.e3, "displayname", 'Coefficients', 'fignum', 339);
showEQfilter(eq_.e, eq_signal_sd.fs.*2);
figure(340); clf;