Unify scope preprocessing and simulation DSP handoff
This commit is contained in:
@@ -38,6 +38,7 @@ try
|
|||||||
"parameters", options.parameters);
|
"parameters", options.parameters);
|
||||||
|
|
||||||
output.ffe_package{r} = scopeOutput.ffe_package;
|
output.ffe_package{r} = scopeOutput.ffe_package;
|
||||||
|
output.dfe_package{r} = scopeOutput.dfe_package;
|
||||||
output.mlse_package{r} = scopeOutput.mlse_package;
|
output.mlse_package{r} = scopeOutput.mlse_package;
|
||||||
output.vnle_package{r} = scopeOutput.vnle_package;
|
output.vnle_package{r} = scopeOutput.vnle_package;
|
||||||
output.dbtgt_package{r} = scopeOutput.dbtgt_package;
|
output.dbtgt_package{r} = scopeOutput.dbtgt_package;
|
||||||
@@ -58,6 +59,7 @@ end
|
|||||||
|
|
||||||
function output = initializeOutput()
|
function output = initializeOutput()
|
||||||
output.ffe_package = {};
|
output.ffe_package = {};
|
||||||
|
output.dfe_package = {};
|
||||||
output.mlse_package = {};
|
output.mlse_package = {};
|
||||||
output.vnle_package = {};
|
output.vnle_package = {};
|
||||||
output.dbtgt_package = {};
|
output.dbtgt_package = {};
|
||||||
|
|||||||
@@ -9,9 +9,13 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options)
|
|||||||
options.M
|
options.M
|
||||||
options.duob_mode
|
options.duob_mode
|
||||||
options.parameters struct = struct()
|
options.parameters struct = struct()
|
||||||
|
options.preprocess_mode string = "auto"
|
||||||
|
options.tx_pulseformer = []
|
||||||
|
options.debug_plots (1,1) logical = false
|
||||||
end
|
end
|
||||||
|
|
||||||
output.ffe_package = [];
|
output.ffe_package = [];
|
||||||
|
output.dfe_package = [];
|
||||||
output.mlse_package = [];
|
output.mlse_package = [];
|
||||||
output.vnle_package = [];
|
output.vnle_package = [];
|
||||||
output.dbtgt_package = [];
|
output.dbtgt_package = [];
|
||||||
@@ -24,8 +28,13 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options)
|
|||||||
|
|
||||||
len_tr = 4096*2;
|
len_tr = 4096*2;
|
||||||
|
|
||||||
ffe_order = [50, 5, 5];
|
ffe_order_ffe = [50, 0, 0];
|
||||||
dfe_order = [0, 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;
|
pf_ncoeffs = 1;
|
||||||
mu_ffe = [0.0001, 0.0008, 0.001];
|
mu_ffe = [0.0001, 0.0008, 0.001];
|
||||||
mu_dfe = 0.0004;
|
mu_dfe = 0.0004;
|
||||||
@@ -43,6 +52,8 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options)
|
|||||||
use_dbtgt = 0;
|
use_dbtgt = 0;
|
||||||
use_dbenc = 0;
|
use_dbenc = 0;
|
||||||
use_ml_mlse = 0;
|
use_ml_mlse = 0;
|
||||||
|
showAnalysis = 0;
|
||||||
|
decoding_mode = [];
|
||||||
|
|
||||||
addProcessingResultToDatabase = 0; %#ok<NASGU>
|
addProcessingResultToDatabase = 0; %#ok<NASGU>
|
||||||
|
|
||||||
@@ -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<NASGU>
|
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<NASGU>
|
||||||
|
|
||||||
mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels); %#ok<NASGU>
|
mlse_db_enc = MLSE("DIR", [1,1], "duobinary_output", 0, "M", M, "trellis_states", PAMmapper(M,0).levels); %#ok<NASGU>
|
||||||
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, ...
|
"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);
|
"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",200,"normalizeTo0dB",1,"displayname",'Rx','addDCoffset',-6);
|
||||||
Scpe_sig.spectrum("fignum",201,"normalizeTo0dB",0,"displayname",'Rx');
|
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 duob_mode ~= db_mode.db_encoded
|
||||||
if use_ffe
|
if use_ffe
|
||||||
ffe_order = [50, 0, 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);
|
||||||
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);
|
|
||||||
|
|
||||||
ffe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
ffe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
"precode_mode", duob_mode, ...
|
"precode_mode", duob_mode, ...
|
||||||
'showAnalysis', 0, ...
|
'showAnalysis', showAnalysis, ...
|
||||||
"postFFE", [], ...
|
"postFFE", [], ...
|
||||||
"eth_style_symbol_mapping", 0);
|
"eth_style_symbol_mapping", 0);
|
||||||
|
|
||||||
output.ffe_package = ffe_results;
|
|
||||||
ffe_results.metrics.print;
|
|
||||||
ffe_results.config.equalizer_structure = "ffe";
|
ffe_results.config.equalizer_structure = "ffe";
|
||||||
|
ffe_results.metrics.print;
|
||||||
|
output.ffe_package = ffe_results;
|
||||||
end
|
end
|
||||||
|
|
||||||
if use_dfe
|
if use_dfe
|
||||||
ffe_order = [50, 5, 5];
|
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);
|
||||||
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);
|
|
||||||
|
|
||||||
dfe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
dfe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
"precode_mode", duob_mode, ...
|
"precode_mode", duob_mode, ...
|
||||||
'showAnalysis', 0, ...
|
'showAnalysis', showAnalysis, ...
|
||||||
"postFFE", [], ...
|
"postFFE", [], ...
|
||||||
"eth_style_symbol_mapping", 0);
|
"eth_style_symbol_mapping", 0);
|
||||||
|
|
||||||
output.ffe_package = dfe_results;
|
|
||||||
dfe_results.config.equalizer_structure = "dfe";
|
dfe_results.config.equalizer_structure = "dfe";
|
||||||
dfe_results.metrics.print;
|
dfe_results.metrics.print;
|
||||||
|
output.dfe_package = dfe_results;
|
||||||
end
|
end
|
||||||
|
|
||||||
if use_vnle_mlse
|
if use_vnle_mlse
|
||||||
pf_ncoeffs = 1;
|
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);
|
||||||
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);
|
|
||||||
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
|
||||||
|
|
||||||
useviterbi = 0;
|
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, ...
|
[ffe_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
"precode_mode", duob_mode, ...
|
"precode_mode", duob_mode, ...
|
||||||
'showAnalysis', 0, ...
|
'showAnalysis', showAnalysis, ...
|
||||||
"postFFE", [], ...
|
"postFFE", [], ...
|
||||||
"eth_style_symbol_mapping", 0);
|
"eth_style_symbol_mapping", 0);
|
||||||
|
|
||||||
ffe_results.metrics.print;
|
|
||||||
ffe_results.config.equalizer_structure = "vnle";
|
ffe_results.config.equalizer_structure = "vnle";
|
||||||
|
ffe_results.metrics.print;
|
||||||
mlse_results.metrics.print;
|
mlse_results.metrics.print;
|
||||||
|
|
||||||
output.mlse_package = mlse_results;
|
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);
|
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
|
end
|
||||||
|
|
||||||
ffe_order = [50, 5, 5];
|
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);
|
||||||
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);
|
|
||||||
|
|
||||||
dbt_results = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ...
|
if isempty(decoding_mode)
|
||||||
"precode_mode", duob_mode, ...
|
dbt_results = duobinary_target(eq_, mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
'showAnalysis', 0, ...
|
"precode_mode", duob_mode, ...
|
||||||
"postFFE", []);
|
'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;
|
dbt_results.metrics.print;
|
||||||
output.dbtgt_package = dbt_results;
|
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<NASGU>
|
mlse_db_enc = MLSE_viterbi("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); %#ok<NASGU>
|
||||||
mlse_db_enc = MLSE("DIR", [1,1], "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",[]);
|
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;
|
output.dbenc_package = db_results;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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
|
% PREPROCESSSIGNAL Performs standard preprocessing on a signal
|
||||||
%
|
%
|
||||||
% Inputs:
|
% Inputs:
|
||||||
@@ -9,19 +9,35 @@ function Scpe_sig = preprocessSignal(Scpe_sig, Symbols, fsym)
|
|||||||
% Outputs:
|
% Outputs:
|
||||||
% Scpe_sig - Preprocessed signal
|
% Scpe_sig - Preprocessed signal
|
||||||
|
|
||||||
% Resample to 2x symbol rate
|
arguments
|
||||||
Scpe_sig = Scpe_sig.resample("fs_out", 2*fsym);
|
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
|
preprocessMode = resolvePreprocessMode(options.mode, options.tx_pulseformer, Symbols);
|
||||||
[Scpe_sig, ~] = Scpe_sig.tsynch("reference", Symbols, "fs_ref", fsym, "debug_plots", 0);
|
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
|
% Apply Gaussian filter
|
||||||
if 1
|
if options.apply_gaussian_filter
|
||||||
Scpe_sig = Filter('filtdegree', 8, "f_cutoff", Symbols.fs.*0.52, ...
|
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);
|
|
||||||
else
|
|
||||||
Scpe_sig = Filter('filtdegree', 4, "f_cutoff", Symbols.fs.*0.6, ...
|
|
||||||
"fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
|
"fs", Scpe_sig.fs, "filterType", filtertypes.gaussian, ...
|
||||||
"active", true).process(Scpe_sig);
|
"active", true).process(Scpe_sig);
|
||||||
end
|
end
|
||||||
@@ -30,3 +46,100 @@ end
|
|||||||
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
|
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
|
||||||
|
|
||||||
end
|
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
|
||||||
|
|||||||
86
Functions/Job_Processing/findSignalPulseformer.m
Normal file
86
Functions/Job_Processing/findSignalPulseformer.m
Normal file
@@ -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
|
||||||
@@ -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;
|
close all;
|
||||||
|
|
||||||
if 1
|
if 1
|
||||||
|
|||||||
@@ -62,7 +62,9 @@ mu_dfe = 0.0004;
|
|||||||
|
|
||||||
dfe_ = sum(dfe_order)>0;
|
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
|
%%% change specific parameter if given in varargin
|
||||||
% Parse optional input arguments
|
% 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,...
|
"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);
|
"adcresolution",8,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',Lp_scpe).process(Rx_sig);
|
||||||
|
|
||||||
output = struct();
|
txPulseformer = [];
|
||||||
|
if apply_pulsef
|
||||||
%%%%%% Sample to 2x fsym %%%%%%
|
txPulseformer = Pform;
|
||||||
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
|
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;
|
||||||
|
|
||||||
|
disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ')
|
||||||
|
fprintf('\n')
|
||||||
|
|||||||
Reference in New Issue
Block a user