From d3235a5c9c3260725001526344fca5af3f4fa8d1 Mon Sep 17 00:00:00 2001 From: Silas Oettinghaus Date: Wed, 25 Mar 2026 14:52:43 +0100 Subject: [PATCH] Unify scope preprocessing and simulation DSP handoff --- Functions/EQ_structures/dsp_runid.m | 2 + Functions/EQ_structures/dsp_scope_signal.m | 67 +++++---- Functions/EQ_structures/preprocessSignal.m | 137 ++++++++++++++++-- .../Job_Processing/findSignalPulseformer.m | 86 +++++++++++ projects/IMDD_base_system/imdd_it.m | 15 +- projects/IMDD_base_system/imdd_model.m | 126 ++++++---------- 6 files changed, 317 insertions(+), 116 deletions(-) create mode 100644 Functions/Job_Processing/findSignalPulseformer.m diff --git a/Functions/EQ_structures/dsp_runid.m b/Functions/EQ_structures/dsp_runid.m index 28ae128..ea67304 100644 --- a/Functions/EQ_structures/dsp_runid.m +++ b/Functions/EQ_structures/dsp_runid.m @@ -38,6 +38,7 @@ try "parameters", options.parameters); output.ffe_package{r} = scopeOutput.ffe_package; + output.dfe_package{r} = scopeOutput.dfe_package; output.mlse_package{r} = scopeOutput.mlse_package; output.vnle_package{r} = scopeOutput.vnle_package; output.dbtgt_package{r} = scopeOutput.dbtgt_package; @@ -58,6 +59,7 @@ end function output = initializeOutput() output.ffe_package = {}; + output.dfe_package = {}; output.mlse_package = {}; output.vnle_package = {}; output.dbtgt_package = {}; diff --git a/Functions/EQ_structures/dsp_scope_signal.m b/Functions/EQ_structures/dsp_scope_signal.m index 32f5578..bbb376e 100644 --- a/Functions/EQ_structures/dsp_scope_signal.m +++ b/Functions/EQ_structures/dsp_scope_signal.m @@ -9,9 +9,13 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) options.M options.duob_mode options.parameters struct = struct() + options.preprocess_mode string = "auto" + options.tx_pulseformer = [] + options.debug_plots (1,1) logical = false end output.ffe_package = []; + output.dfe_package = []; output.mlse_package = []; output.vnle_package = []; output.dbtgt_package = []; @@ -24,8 +28,13 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) len_tr = 4096*2; - ffe_order = [50, 5, 5]; - dfe_order = [0, 0, 0]; + ffe_order_ffe = [50, 0, 0]; + ffe_order_dfe = [50, 5, 5]; + ffe_order_vnle = [50, 5, 5]; + ffe_order_dbtgt = [50, 5, 5]; + dfe_order_vnle = [0, 0, 0]; + dfe_order_dbtgt = [0, 0, 0]; + dfe_feedback_order = [2, 0, 0]; pf_ncoeffs = 1; mu_ffe = [0.0001, 0.0008, 0.001]; mu_dfe = 0.0004; @@ -43,6 +52,8 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) use_dbtgt = 0; use_dbenc = 0; use_ml_mlse = 0; + showAnalysis = 0; + decoding_mode = []; addProcessingResultToDatabase = 0; %#ok @@ -63,11 +74,14 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) 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); %#ok mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels); %#ok - eq_db_enc = EQ("Ne", ffe_order, "Nb", dfe_order, "training_length", len_tr, ... + eq_db_enc = EQ("Ne", ffe_order_dbtgt, "Nb", dfe_order_dbtgt, "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); - Scpe_sig = preprocessSignal(Scpe_sig_raw, Symbols, fsym); + Scpe_sig = preprocessSignal(Scpe_sig_raw, Symbols, fsym, ... + "mode", options.preprocess_mode, ... + "tx_pulseformer", options.tx_pulseformer, ... + "debug_plots", options.debug_plots); Scpe_sig.spectrum("fignum",200,"normalizeTo0dB",1,"displayname",'Rx','addDCoffset',-6); Scpe_sig.spectrum("fignum",201,"normalizeTo0dB",0,"displayname",'Rx'); @@ -79,39 +93,35 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) if duob_mode ~= db_mode.db_encoded if use_ffe - ffe_order = [50, 0, 0]; - eq_dfe = EQ("Ne",ffe_order,"Nb",[0,0,0],"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_dfe = EQ("Ne",ffe_order_ffe,"Nb",[0,0,0],"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); ffe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ... "precode_mode", duob_mode, ... - 'showAnalysis', 0, ... + 'showAnalysis', showAnalysis, ... "postFFE", [], ... "eth_style_symbol_mapping", 0); - output.ffe_package = ffe_results; - ffe_results.metrics.print; ffe_results.config.equalizer_structure = "ffe"; + ffe_results.metrics.print; + output.ffe_package = ffe_results; end if use_dfe - ffe_order = [50, 5, 5]; - eq_dfe = EQ("Ne",ffe_order,"Nb",[2,0,0],"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_dfe = EQ("Ne",ffe_order_dfe,"Nb",dfe_feedback_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); dfe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ... "precode_mode", duob_mode, ... - 'showAnalysis', 0, ... + 'showAnalysis', showAnalysis, ... "postFFE", [], ... "eth_style_symbol_mapping", 0); - output.ffe_package = dfe_results; dfe_results.config.equalizer_structure = "dfe"; dfe_results.metrics.print; + output.dfe_package = dfe_results; end 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",0); + eq_ = EQ("Ne",ffe_order_vnle,"Nb",dfe_order_vnle,"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); pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1); useviterbi = 0; @@ -129,12 +139,12 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) [ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ... "precode_mode", duob_mode, ... - 'showAnalysis', 0, ... + 'showAnalysis', showAnalysis, ... "postFFE", [], ... "eth_style_symbol_mapping", 0); - ffe_results.metrics.print; ffe_results.config.equalizer_structure = "vnle"; + ffe_results.metrics.print; mlse_results.metrics.print; output.mlse_package = mlse_results; @@ -165,13 +175,20 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',trellexlusion,'trellis_state_mode',3); 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); + eq_ = EQ("Ne",ffe_order_dbtgt,"Nb",dfe_order_dbtgt,"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", []); + if isempty(decoding_mode) + dbt_results = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ... + "precode_mode", duob_mode, ... + 'showAnalysis', showAnalysis, ... + "postFFE", []); + else + dbt_results = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ... + "precode_mode", duob_mode, ... + 'showAnalysis', showAnalysis, ... + "postFFE", [], ... + "decoding_mode", decoding_mode); + end dbt_results.metrics.print; output.dbtgt_package = dbt_results; @@ -182,7 +199,7 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) mlse_db_enc = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); %#ok 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",[]); + db_results = duobinary_signaling(eq_db_enc, mlse_db_enc, M, Scpe_sig, Symbols, Tx_bits, "precode_mode",duob_mode, "showAnalysis",showAnalysis,"postFFE",[]); output.dbenc_package = db_results; end end diff --git a/Functions/EQ_structures/preprocessSignal.m b/Functions/EQ_structures/preprocessSignal.m index 6932697..cc02b01 100644 --- a/Functions/EQ_structures/preprocessSignal.m +++ b/Functions/EQ_structures/preprocessSignal.m @@ -1,4 +1,4 @@ -function Scpe_sig = preprocessSignal(Scpe_sig, Symbols, fsym) +function Scpe_sig = preprocessSignal(Scpe_sig, Symbols, fsym, options) % PREPROCESSSIGNAL Performs standard preprocessing on a signal % % Inputs: @@ -9,19 +9,35 @@ function Scpe_sig = preprocessSignal(Scpe_sig, Symbols, fsym) % Outputs: % Scpe_sig - Preprocessed signal -% Resample to 2x symbol rate -Scpe_sig = Scpe_sig.resample("fs_out", 2*fsym); +arguments + Scpe_sig + Symbols + fsym + options.mode string = "auto" + options.tx_pulseformer = [] + options.debug_plots (1,1) logical = false + options.apply_gaussian_filter (1,1) logical = true + options.gaussian_cutoff_factor (1,1) double = 0.52 +end -% Synchronize with reference -[Scpe_sig, ~] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 0); +preprocessMode = resolvePreprocessMode(options.mode, options.tx_pulseformer, Symbols); +targetFs = 2 * fsym; + +switch preprocessMode + case "matched_filter" + matchedPulseformer = buildMatchedPulseformer(options.tx_pulseformer, Symbols, fsym, targetFs); + Scpe_sig = matchedPulseformer.process(Scpe_sig); + case "resample" + Scpe_sig = Scpe_sig.resample("fs_out", targetFs); + otherwise + error('preprocessSignal:InvalidMode', 'Unsupported preprocessing mode "%s".', preprocessMode); +end + +[Scpe_sig, ~] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", options.debug_plots); % Apply Gaussian filter -if 1 - Scpe_sig = Filter('filtdegree', 8, "f_cutoff", Symbols.fs.*0.52, ... - "fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ... - "active", true).process(Scpe_sig); -else - Scpe_sig = Filter('filtdegree', 4, "f_cutoff", Symbols.fs.*0.6, ... +if options.apply_gaussian_filter + Scpe_sig = Filter('filtdegree', 8, "f_cutoff", Symbols.fs.*options.gaussian_cutoff_factor, ... "fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ... "active", true).process(Scpe_sig); end @@ -29,4 +45,101 @@ end %Remove DC offset Scpe_sig = Scpe_sig - mean(Scpe_sig.signal); -end \ No newline at end of file +end + +function preprocessMode = resolvePreprocessMode(requestedMode, txPulseformer, Symbols) + requestedMode = string(requestedMode); + if requestedMode ~= "auto" + preprocessMode = requestedMode; + return + end + + pulseformer = txPulseformer; + if isempty(pulseformer) + pulseformer = findSignalPulseformer(Symbols); + end + + if isRootRaisedCosinePulseformer(pulseformer) + preprocessMode = "matched_filter"; + else + preprocessMode = "resample"; + end +end + +function tf = isRootRaisedCosinePulseformer(pulseformer) + tf = false; + if isempty(pulseformer) + return + end + + pulseValue = readPulseformerField(pulseformer, 'pulse', []); + if isempty(pulseValue) + return + end + + pulseValue = normalizePulseValue(pulseValue); + tf = pulseValue == pulseform.rrc; +end + +function matchedPulseformer = buildMatchedPulseformer(txPulseformer, Symbols, fsym, targetFs) + pulseformerMeta = txPulseformer; + if isempty(pulseformerMeta) + pulseformerMeta = findSignalPulseformer(Symbols); + end + + pulseValue = normalizePulseValue(readPulseformerField(pulseformerMeta, 'pulse', pulseform.rrc)); + alphaValue = readPulseformerField(pulseformerMeta, 'alpha', 0.05); + pulseLengthValue = readPulseformerField(pulseformerMeta, 'pulselength', 16); + + if isempty(alphaValue) + alphaValue = 0.05; + end + + matchedPulseformer = Pulseformer( ... + "fsym", fsym, ... + "fdac", targetFs, ... + "pulse", pulseValue, ... + "pulselength", pulseLengthValue, ... + "alpha", alphaValue, ... + "matched", 1); +end + +function value = readPulseformerField(pulseformerMeta, fieldName, defaultValue) + value = defaultValue; + if isempty(pulseformerMeta) + return + end + + if isstruct(pulseformerMeta) && isfield(pulseformerMeta, fieldName) + candidate = pulseformerMeta.(fieldName); + if ~isempty(candidate) + value = candidate; + end + return + end + + if isobject(pulseformerMeta) && isprop(pulseformerMeta, fieldName) + candidate = pulseformerMeta.(fieldName); + if ~isempty(candidate) + value = candidate; + end + end +end + +function pulseValue = normalizePulseValue(rawValue) + if isa(rawValue, 'pulseform') + pulseValue = rawValue; + return + end + + if iscell(rawValue) + rawValue = rawValue{1}; + end + + if isstring(rawValue) || ischar(rawValue) + pulseValue = pulseform.(char(string(rawValue))); + return + end + + pulseValue = pulseform(rawValue); +end diff --git a/Functions/Job_Processing/findSignalPulseformer.m b/Functions/Job_Processing/findSignalPulseformer.m new file mode 100644 index 0000000..5ff5c31 --- /dev/null +++ b/Functions/Job_Processing/findSignalPulseformer.m @@ -0,0 +1,86 @@ +function pulseformer = findSignalPulseformer(signalLike) +%FINDSIGNALPULSEFORMER Try to recover TX pulseformer metadata from a signal logbook. + + pulseformer = []; + + if isempty(signalLike) || ~isprop(signalLike, 'logbook') || isempty(signalLike.logbook) + return + end + + if ~ismember('ModifierCopy', signalLike.logbook.Properties.VariableNames) + return + end + + modifierCopies = signalLike.logbook.ModifierCopy; + for idx = numel(modifierCopies):-1:1 + pulseformer = extractPulseformerCandidate(modifierCopies{idx}); + if ~isempty(pulseformer) + return + end + end +end + +function pulseformer = extractPulseformerCandidate(candidate) + pulseformer = []; + + if isempty(candidate) + return + end + + if isa(candidate, 'Pulseformer') + pulseformer = candidate; + return + end + + if iscell(candidate) + for cellIdx = 1:numel(candidate) + pulseformer = extractPulseformerCandidate(candidate{cellIdx}); + if ~isempty(pulseformer) + return + end + end + return + end + + if isstruct(candidate) + if isfield(candidate, 'pulseformer') + pulseformer = extractPulseformerCandidate(candidate.pulseformer); + if ~isempty(pulseformer) + return + end + end + + if hasPulseformerFields(candidate) + pulseformer = candidate; + end + return + end + + try + if isprop(candidate, 'pulseformer') + pulseformer = extractPulseformerCandidate(candidate.pulseformer); + if ~isempty(pulseformer) + return + end + end + catch + end + + try + if hasPulseformerFields(candidate) + pulseformer = candidate; + end + catch + end +end + +function tf = hasPulseformerFields(candidate) + tf = false; + + if isstruct(candidate) + tf = isfield(candidate, 'pulse') && isfield(candidate, 'pulselength'); + return + end + + tf = isobject(candidate) && isprop(candidate, 'pulse') && isprop(candidate, 'pulselength'); +end diff --git a/projects/IMDD_base_system/imdd_it.m b/projects/IMDD_base_system/imdd_it.m index 3bc9185..16d715e 100644 --- a/projects/IMDD_base_system/imdd_it.m +++ b/projects/IMDD_base_system/imdd_it.m @@ -1,3 +1,16 @@ +% IMDD simulation entrypoint +% +% Processing stages: + +% -> imdd_it +% -> submit_handle +% -> imdd_model + % -> PAMsource / AWG / EML / Fiber / Photodiode / Filter / Scope +% -> dsp_scope_signal + % -> preprocessSignal + % -> FFE / DFE / VNLE+MLSE / DB target DSP branches +% -> result packages stored in DataStorage + close all; if 1 @@ -553,4 +566,4 @@ ylabel('BER'); % clabel(C,h,'Color','k','FontWeight','bold'); % % beautifyBERplot(); -% legend('BER contour lines'); \ No newline at end of file +% legend('BER contour lines'); diff --git a/projects/IMDD_base_system/imdd_model.m b/projects/IMDD_base_system/imdd_model.m index b2e8c6a..fdbf366 100644 --- a/projects/IMDD_base_system/imdd_model.m +++ b/projects/IMDD_base_system/imdd_model.m @@ -62,7 +62,9 @@ mu_dfe = 0.0004; dfe_ = sum(dfe_order)>0; -% duob_mode = db_mode.no_db; +duob_mode = db_mode.no_db; +decoding_mode = []; +bitrate = fsym * log2(M); %%% change specific parameter if given in varargin % Parse optional input arguments @@ -158,82 +160,50 @@ Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,... "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... "adcresolution",8,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',Lp_scpe).process(Rx_sig); +txPulseformer = []; +if apply_pulsef + txPulseformer = Pform; +end + +dspParameters = struct(); +dspParameters.len_tr = len_tr; +dspParameters.mu_ffe = mu_ffe; +dspParameters.mu_dfe = mu_dfe; +dspParameters.mu_dc = mu_dc; +dspParameters.use_ffe = 1; +dspParameters.use_dfe = 1; +dspParameters.use_vnle_mlse = 1; +dspParameters.use_dbtgt = 1; +dspParameters.use_dbenc = 0; +dspParameters.use_ml_mlse = 0; +dspParameters.showAnalysis = 0; +dspParameters.pf_ncoeffs = pf_ncoeffs; +dspParameters.ffe_order_ffe = [50, 0, 0]; +dspParameters.ffe_order_dfe = [50, 0, 0]; +dspParameters.dfe_feedback_order = [2, 0, 0]; +dspParameters.ffe_order_vnle = [200, 0, 0]; +dspParameters.dfe_order_vnle = dfe_order; +dspParameters.ffe_order_dbtgt = [50, 0, 0]; +dspParameters.dfe_order_dbtgt = dfe_order; +dspParameters.decoding_mode = decoding_mode; + +scopeOutput = dsp_scope_signal(Scpe_sig, Symbols, Tx_bits, ... + "fsym", fsym, ... + "M", M, ... + "duob_mode", duob_mode, ... + "parameters", dspParameters, ... + "preprocess_mode", "auto", ... + "tx_pulseformer", txPulseformer, ... + "debug_plots", false); + output = struct(); +output.ffe_results = scopeOutput.ffe_package; +output.dfe_results = scopeOutput.dfe_package; +output.vnle_results = scopeOutput.vnle_package; +output.mlse_results = scopeOutput.mlse_package; +output.dbt_results = scopeOutput.dbtgt_package; +output.dbenc_results = scopeOutput.dbenc_package; +output.mlmlse_results = scopeOutput.mlmlse_package; -%%%%%% Sample to 2x fsym %%%%%% -Scpe_sig = Scpe_sig.resample("fs_out",2*fsym); -Scpe_sig.signal = Scpe_sig.signal(1:2*length(Symbols)); - -%%%%%% Sync Rx signal with reference %%%%%% -[Scpe_sig,~] = Scpe_sig.tsynch("reference",Symbols,"fs_ref",fsym,"debug_plots",0); - -Scpe_sig = Filter('filtdegree',4,"f_cutoff",Symbols.fs.*0.5,"fs",Scpe_sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Scpe_sig); - -Scpe_sig = Scpe_sig - mean(Scpe_sig.signal); - -%%% EQUALIZING - -if 1 - % -------------------- FFE -------------------- - ffe_order = [50, 0, 0]; - eq_ffe = EQ("Ne",ffe_order,"Nb",[0,0,0], ... - "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); - - % -------------------- FFE -------------------- - ffe_order = [50, 0, 0]; - eq_ffe = EQ("Ne",ffe_order,"Nb",[0,0,0], ... - "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); - - output.ffe_results = ffe(eq_ffe,M,Scpe_sig,Symbols,Tx_bits, ... - "precode_mode",duob_mode,'showAnalysis',0,"postFFE",[], ... - "eth_style_symbol_mapping",0); - - output.ffe_results.metrics.print - - % -------------------- DFE -------------------- - eq_dfe = EQ("Ne",ffe_order,"Nb",[2,0,0], ... - "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); - - output.dfe_results = ffe(eq_dfe,M,Scpe_sig,Symbols,Tx_bits, ... - "precode_mode",duob_mode,'showAnalysis',0,"postFFE",[], ... - "eth_style_symbol_mapping",0); - - output.dfe_results.metrics.print("description",'DFE'); - - - % -------------------- VNLE + MLSE -------------------- - pf_ncoeffs = 1; - ffe_order3 = [200, 0, 0]; - eq_v = EQ("Ne",ffe_order3,"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("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); - - [output.vnle_results, output.mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ... - "precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", [], "eth_style_symbol_mapping", 0); - - - % -------------------- DB target -------------------- - mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,'trellis_states',PAMmapper(M,0).levels); - ffe_order = [50, 0, 0]; - 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); - output.dbt_results = duobinary_target(eq_,mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ... - "precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", [], "decoding_mode", decoding_mode); - - output.dbt_results.metrics.print("description",'Duobinary'); - - - disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ') - fprintf('\n') - -end \ No newline at end of file +disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ') +fprintf('\n')