% Minimal IMDD model for investigating FFE noise enhancement. % Parameters mirror the current IMDD_base_system/imdd_it.m, % IMDD_base_system/imdd_model.m, and the FFE branch in dsp_scope_signal.m. clearvars; close all; %% Sweep parameters from imdd_it.m fsym_values = 172e9;%(152:16:200).*1e9; precomp = 0; laser_wavelength = 1310; M = 4; link_length = 2; channel_alpha = 0.5; duob_mode = db_mode.db_precoded; decoding_mode = db_decoder.sequencedetection; channel_mode = channel_model.physical; channel_snr_dB = 20; rop = 0; %% Inner model parameters from imdd_model.m bitrate = []; apply_pulsef = 0; fdac = 256e9; fadc = 256e9; random_key = 1; rcalpha = 0.05; kover = 16; vbias_rel = 0.5; u_pi = 3; vbias = -vbias_rel*u_pi; laser_linewidth = 0; eml_alpha = 0; len_tr = 4096*2; pf_ncoeffs = 1; mu_dc = 0.005; nRates = numel(fsym_values); eq_names = ["FFE","VNLE"]; nEqs = numel(eq_names); emptyResult = struct("fsym",[],"ROP",[],"equalizer",[],"BER",[],"SNR",[],"numBitErr",[], ... "eq_noise",[],"eq_signal_sd",[],"eq",[],"Rx_sig",[],"Tx_sig",[],"Tx_symbols",[]); results = repmat(emptyResult,nRates,nEqs); cols = flip(cbrewer2('RdYlBu',nRates+4)); midIdx = floor(size(cols,1)/2) + (-1:2); cols(midIdx,:) = []; for i = 1:numel(fsym_values) fsym = fsym_values(i); fprintf("Running %.0f GBd (%d/%d)\n", fsym*1e-9, i, numel(fsym_values)); if isempty(bitrate) bitrateCurrent = fsym * log2(M); end Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rc","pulselength",18,"alpha",rcalpha); [Digi_sig, Symbols, Bits] = PAMsource( ... "fsym",fsym,"M",M,"order",18,"useprbs",0, ... "fs_out",fdac, ... "applyclipping",0,"clipfactor",1.5, ... "applypulseform",apply_pulsef,"pulseformer",Pform, ... "randkey",random_key, ... "duobinary_mode",duob_mode, ... "mrds_code",0,"mrds_blocklength",512).process(); rateResults = repmat(emptyResult,nEqs); Tx_sig = Digi_sig; El_sig = M8199B("kover",kover).process(Digi_sig); tx_bwl = 85e9; El_sig = Filter("filtdegree",4,"f_cutoff",tx_bwl,"fs",fdac*kover, ... "filterType",filtertypes.bessel_inp,"active",true).process(El_sig); El_sig = El_sig.normalize("mode","oneone"); scaling = 0.7*(u_pi/2-abs(vbias-u_pi/2)); El_sig = El_sig .* scaling; Opt_sig = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs, ... "lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi, ... "linewidth",laser_linewidth,"randomkey",random_key+1, ... "alpha",eml_alpha).process(El_sig); Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length, ... "alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig); Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power", ... "amplification_db",rop).process(Opt_sig); Rx_sig = Photodiode("fsimu",fdac*kover,"dark_current",2e-08, ... "responsivity",0.6,"temperature",20,"nep",1.8e-11).process(Rx_sig); rx_bwl = 90e9; Rx_sig = Filter("filtdegree",4,"f_cutoff",rx_bwl,"fs",fdac*kover, ... "filterType",filtertypes.butterworth,"active",true).process(Rx_sig); Lp_scpe = Filter("filtdegree",4,"f_cutoff",110e9,"fs",fadc, ... "filterType",filtertypes.butterworth,"active",true); Rx_sig = Scope("fsimu",fdac*kover,"fadc",fadc, ... "delay",0,"fixed_delay",0,"filtertype",filtertypes.butterworth, ... "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 Scpe_sig = preprocessSignal(Rx_sig, Symbols, fsym, ... "mode","auto", ... "tx_pulseformer",txPulseformer, ... "debug_plots",0); Scpe_sig.signal = Scpe_sig.signal(1:2*Symbols.length); Scpe_sig.signal = real(Scpe_sig.signal); %% % -------------------- VNLE + MLSE -------------------- pf_ncoeffs = 1; ffe_order3 = [50, 0, 0]; eq_ = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",len_tr, ... "mu_dd",1e-3,"mu_tr",0.4,"order",50, ... "sps",2,"decide",0,"optmize_mus",0,"dd_mode",1, ... "adaption_technique","nlms","mu_dc",1e-3); pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1); mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels); [vnle_results, mlse_results] = vnle_postfilter_mlse(eq_, pf_, mlse_, M, Scpe_sig, Symbols, Bits, ... "precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [], "eth_style_symbol_mapping", 0); end