function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options) %DSP_SCOPE_SIGNAL Run the common DSP chain starting from a scope signal. arguments Scpe_sig_raw Symbols Tx_bits options.fsym options.M options.duob_mode options.userParameters 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 = []; output.dbenc_package = []; output.mlmlse_package = []; fsym = options.fsym; M = options.M; duob_mode = options.duob_mode; len_tr = 4096*2; 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; mu_dc = 0.005; dc_buffer_len = 1; %#ok mu_tr = 0; mu_dd = 0.05; adaption = 1; use_dd_mode = 1; use_ffe = 1; use_dfe = 1; use_vnle_mlse = 1; use_dbtgt = 1; use_dbenc = 0; use_ml_mlse = 0; showAnalysis = 0; decoding_mode = []; addProcessingResultToDatabase = 0; %#ok paramStruct = options.userParameters; if ~isempty(paramStruct) paramNames = fieldnames(paramStruct); for i = 1:numel(paramNames) thisName = paramNames{i}; thisValue = paramStruct.(thisName); eval([thisName ' = thisValue;']); end end pf_ = Postfilter("ncoeff", pf_ncoeffs, "useBurg", 1); %#ok mlse_ = MLSE("duobinary_output", 0, 'M', M, 'trellis_states', PAMmapper(M,0).levels); %#ok 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","mu_dc",mu_dc); %#ok 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_technique",adaption_method(adaption),"dd_mode",use_dd_mode,"mu_dc",mu_dc); %#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_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, ... "mode", options.preprocess_mode, ... "tx_pulseformer", options.tx_pulseformer, ... "debug_plots", 0); % Scpe_sig.spectrum("fignum",200,"normalizeTo0dB",1,"displayname",'Rx','addDCoffset',-6); % ylim([-30,3]); % xlim([-5,100]); Scpe_sig.signal = Scpe_sig.signal(1:2*Symbols.length); Scpe_sig.signal = real(Scpe_sig.signal); if duob_mode ~= db_mode.db_encoded if use_ffe eq_ffe = 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); eq_ffe = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",4096*2,"mu_dd",1e-1,"mu_tr",0.4,"order",ffe_order_ffe(1),... "sps",2,"decide",0,"optmize_mus",0,"dd_mode",1,"adaption_technique","nlms","mu_dc",1.021e-05); ffe_results = ffe(eq_ffe, M, Scpe_sig, Symbols, Tx_bits, ... "precode_mode", duob_mode, ... 'showAnalysis', options.debug_plots, ... "postFFE", [], ... "eth_style_symbol_mapping", 0); ffe_results.config.equalizer_structure = "ffe"; ffe_results.metrics.print("description",'FFE'); output.ffe_package = ffe_results; end if use_dfe 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', options.debug_plots, ... "postFFE", [], ... "eth_style_symbol_mapping", 0); dfe_results.config.equalizer_structure = "dfe"; dfe_results.metrics.print("description",'DFE'); output.dfe_package = dfe_results; end if use_vnle_mlse 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; if useviterbi mlse_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); else if duob_mode == db_mode.no_db && M == 6 trellexlusion = 1; else trellexlusion = 0; end mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',trellexlusion,'trellis_state_mode',2); end [ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ... "precode_mode", duob_mode, ... 'showAnalysis', showAnalysis, ... "postFFE", [], ... "eth_style_symbol_mapping", 0); ffe_results.config.equalizer_structure = "vnle"; ffe_results.metrics.print("description",'VNLE'); mlse_results.metrics.print("description",'MLSE'); output.mlse_package = mlse_results; output.vnle_package = ffe_results; end if use_ml_mlse mu_ml = 0.01; training_epochs = 100; ml_mlse_equalizer = ML_MLSE("epochs_tr",training_epochs,"epochs_dd",1, ... "len_tr",length(Scpe_sig)/4,"mu_dd",mu_ml,"mu_tr",mu_ml,"order",11,"sps",2, ... "traceback_depth",128,"L",1,"delta",4,"adaptive_mu",0); ml_mlse_results = ml_mlse(ml_mlse_equalizer, M, Scpe_sig, Symbols, Tx_bits, "precode_mode", duob_mode); output.mlmlse_package = ml_mlse_results; end if use_dbtgt useviterbi = 0; if useviterbi mlse_db_ = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); else if duob_mode == db_mode.no_db && M == 6 trellexlusion = 1; else trellexlusion = 0; end 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 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); 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("description",'Duob. Target'); output.dbtgt_package = dbt_results; end end if duob_mode == db_mode.db_encoded 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",showAnalysis,"postFFE",[]); output.dbenc_package = db_results; end end