diff --git a/Classes/00_signals/Signal.m b/Classes/00_signals/Signal.m index 9e9fc7e..f6ea035 100644 --- a/Classes/00_signals/Signal.m +++ b/Classes/00_signals/Signal.m @@ -22,6 +22,7 @@ classdef Signal obj.logbook = table(SignalType,TimeStamp,Length,SignalPower,Nase,Description); + end %% CONVERT TO INFORMATIONSIGNAL @@ -72,6 +73,7 @@ classdef Signal end + %% CONVERT TO Opticalsignal function o_sig = Opticalsignal(obj, options) @@ -130,7 +132,7 @@ classdef Signal SignalType = [string(class(obj))]; TimeStamp = [(datetime('now','TimeZone','local','Format','HH:mm:ss'))]; - Length = [obj.length]; + Length = num2str(obj.length, ['%' sprintf('.%df', 0)]);%[obj.length]; SignalPower = [obj.power]; Nase = [0]; diff --git a/Classes/01_transmit/Pulseformer.m b/Classes/01_transmit/Pulseformer.m index aae5c49..7b8347e 100644 --- a/Classes/01_transmit/Pulseformer.m +++ b/Classes/01_transmit/Pulseformer.m @@ -132,7 +132,7 @@ classdef Pulseformer %Check output integrity if round(up/dn * length(data_in)) ~= length(data_out) %warning('Check signal length after pulse shaping'); - disp('Check signal length after pulse shaping'); + %disp('Check signal length after pulse shaping'); end diff --git a/Classes/02_etc/Amplifier.m b/Classes/02_etc/Amplifier.m index de3970c..4289061 100644 --- a/Classes/02_etc/Amplifier.m +++ b/Classes/02_etc/Amplifier.m @@ -156,7 +156,7 @@ classdef Amplifier function [noisy_sig, osnr] = applyAseToSignal(~, opticalsignal, nase_numeric) noisy_sig = opticalsignal + nase_numeric ; osnr = pow2db(mean(abs(opticalsignal.^2))/mean(abs(nase_numeric.^2))); - disp(osnr); + % disp(osnr); end end end diff --git a/Functions/calc_ber.m b/Functions/calc_ber.m index 387ea9d..5bc9686 100644 --- a/Functions/calc_ber.m +++ b/Functions/calc_ber.m @@ -3,10 +3,7 @@ function [bits,errors,BER] = calc_ber(data_in,data_ref,skip) data_ref=logical(data_ref)'; data_in = logical(data_in)'; bits = 0; -errors=0; -data_ref_overlap=zeros(size(data_ref,1),skip+(length(data_ref)-size(data_in,2))); -data_ref_pointer=0; % Determine BER bits = bits+size(data_in,2)-skip; diff --git a/imddmodel.m b/imddmodel.m new file mode 100644 index 0000000..cb5f9bf --- /dev/null +++ b/imddmodel.m @@ -0,0 +1,173 @@ +function BER = imddmodel(dc_mu,sir,linewidth) + +rng(2023); + +%% Set Simulation Variables + +sir = sir; + +delay = 300; %mpi delay in meter + +fiblen = 0.5; %main link in km + +laser_linewidth = linewidth; + + +O = 18; %order of prbs +N = 2^(O-1); %length of prbs +[~,seed] = prbs(O,1); %initialize first seed of prbs + +% Modulation +M = 4; %PAM-M +bitpattern = zeros(N,log2(M)); + +% Symbol Rate +fsym = 112e9; + +% DAC Rate +fdac = 120e9; + +% Simulation oversampling rate "k"; +kover = 16; + +% ADC Rate +fadc = 256e9; + +% Simulation frequency in "analog domain" +fsimu = kover * fdac ; + + +%% CONSTRUCT ALL CLASSES + +digimod = PAMmapper(M,0); + +pulseform = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.1); + +awg = AWG('fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5); + +lp_laser = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); + +u_pi = 3.5; +vbias = (0.5*u_pi)-u_pi; +extmodlaser = EML("mode",eml_mode.im_cosinus,"power",15,"fsimu",fsimu,"lambda",1550,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth); + +fib = Fiber("fsimu",fdac*kover,"fiber_length",fiblen,"alpha",0.2,"D",16,"lambda0",thz2nm(193.1),"gamma",0); + +reflectionpoint = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",sir); +reflectionprop = Fiber("fsimu",fdac*kover,"fiber_length",2*delay/1000,"alpha",0.2,"D",16,"lambda0",1550,"gamma",0); + + +opticatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",-5); + +edfaamp = Amplifier("amp_mode","edfa_increase_nase","gain_mode","output_power","amplification_db",0,"nase_mode","generate_ase","noifig",10.5); + +phdiode = Photodiode("fsimu",fdac*kover,"dark_current",0,"responsivity",1,"temperature",20); + +lp_diode = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); + +scp = Scope("fsimu",fdac*kover,"fadc",fadc,... + "delay",0,"fixed_delay",0,"lpf_bw",113e9,"filtertype",filtertypes.butterworth,... + "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... + "adcresolution",6,"quantbuffer",0.1,'block_dc',1); + +eq = EQ("K",2,"plottrain",0,"plotfinal",0,... + "training_length",1024,"training_loops",5,... + "Ne",[50,0,0],"Nb",[0,0,0],... + "DCmu",dc_mu,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0.00,... + "dd_loops",2,"epsilon",[10 100 1000 ],"M",4,... + "thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",1,"rho",0.0005,"ideal_dfe",0,"DB_aim",0); + + +%% PROCESS + +% PRBS Generation +for i = 1:log2(M) + [bitpattern(:,i),seed] = prbs(O,N,seed); +end + +%bitpattern = prms_out'; + +% Build Inf. signal class +bits = Informationsignal(bitpattern); + +% Digi Mod +mod_out = digimod.map(bits); + +% merken für EQ training +reference = mod_out; + +% shape shape +X = pulseform.process(mod_out); +test = applyPulseShaping(reference.signal,fsym,fdac); + +% AWG -> ELECTRICAL DOMAIN +awg_out = awg.process(X); + +X = lp_laser.process(awg_out); +X = lp_laser.process(X); + +X = X.normalize("mode","oneone"); +X.signal = X.signal .* 1.3800; + +% Laser; Modulation -> OPTICAL DOMAIN +X = extmodlaser.process(X); + +% Fiber Propagation +X = fib.process(X); + +%% Reflect with attenuation +R = reflectionpoint.process(X); + +% Propagate +R = reflectionprop.process(R); + +disp(['SIR ',num2str(10*log10(X.power/R.power))]); + +% Delay +R = R.delay("delay_meter",delay); + +% Add together +X = X+R; + +%% +X = opticatten.process(X); +X = edfaamp.process(X); + +% Photo Diode -> ELECTRICAL DOMAIN +X = phdiode.process(X); +X = lp_diode.process(X); + + +% Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation) +X = scp.process(X); + +% Resample to Symbol Rate +X = X.resample("fs_out",2*fsym,"fs_in",fadc); + +% Normalize +X = X.normalize("mode","rms"); + +% Equalizer +X = eq.process(X,reference); + +%% MPI reduction +wl = 10000; +mpi_red = X; +mpi_red.signal = X.signal - 1/wl .* movsum( X.signal,[wl/2,wl/2]); + + +% Digi Demod +demap_out = digimod.demap(X); +demap_out_a1 = digimod.demap(mpi_red); + +% BER +[bits,errors,ber] = calc_ber(demap_out.signal(1:end-1,:),bitpattern(1:end,:),0); +[bits,errors,ber_a1] = calc_ber(demap_out_a1.signal(1:end-1,:),bitpattern(1:end,:),0); + +disp(['BER: ', sprintf('%2E',ber), ' ERRORS: ' ,num2str(sum(errors))]); +disp(['BER: ', sprintf('%2E',ber_a1), ' ERRORS: ' ,num2str(sum(errors))]); + + +BER.ber = ber; +BER.ber_a1 = ber_a1; +end \ No newline at end of file diff --git a/run_loop.m b/run_loop.m new file mode 100644 index 0000000..fe35284 --- /dev/null +++ b/run_loop.m @@ -0,0 +1,61 @@ + +dc_mu = [0 0.001 0.1]; +sirloop = -25:1:0; +lw_loop = [0e6:1e6:10e6]; + +ber = zeros(length(dc_mu),length(sirloop),length(lw_loop)); +ber_a1 = zeros(length(dc_mu),length(sirloop),length(lw_loop)); + +iterations=size(ber); + +parfor ix = 1:numel(ber) + + [u1,u2,u3] = ind2sub(iterations,ix); + + BER = imddmodel(dc_mu(u1),sirloop(u2),lw_loop(u3)); + + ber(ix) = BER.ber; + ber_a1(ix) = BER.ber_a1; + +end + + +hdfec = 3.8e-3.*ones(size(sirloop)); + +for dc = 1:size(ber,1) + for lw = 1:size(ber,3) + a = InterX([sirloop;ber(dc,:,lw)],[sirloop;hdfec]); + thres(dc,lw) = -a(1); + end +end + +contour(thres,'LineWidth',2); +ylabel("DC Tap"); +xlabel("Linewidth in MHz"); + +yticks(1:length(dc_mu)) +yticklabels(dc_mu); + +xticks(1:length(lw_loop)); +xticklabels(lw_loop*1e-6); + +grid on + +% +% col = cbrewer2('Paired',12); +% scatter(-1.*thres(1),thres(2),'MarkerEdgeColor',col(2*i,:),'LineWidth',6,'DisplayName',['DC tap ',num2str(dc_mu(i))]); +% +% figure(1) +% hold on +% for i = 1:length(dc_mu) +% plot(-1.*sirloop,ber(i,:),"LineWidth",2,"Marker","o","MarkerSize",3,'Color',col(2*i,:),'DisplayName',['DC tap ',num2str(dc_mu(i))]); +% plot(-1.*sirloop,ber_a1(i,:),"LineWidth",2,"Marker","o","MarkerSize",3,'Color',col(2*i-1,:),'DisplayName',['A1. Linewidth in MHz ',num2str(dc_mu(i)*1e-6)]); +% end +% +% yline(3.8e-3,'LineWidth',2,'LineStyle','--','HandleVisibility','off'); +% set(gca,'yscale','log'); +% grid minor +% legend +% xlabel("SIR"); +% ylabel("BER"); +% title("BER for different SIR") \ No newline at end of file diff --git a/setup_simulation.m b/setup_simulation.m index 125c2a3..14f779c 100644 --- a/setup_simulation.m +++ b/setup_simulation.m @@ -1,10 +1,16 @@ +sir_loop = -30:5:-10; -rng(2020); +for lp = 1:5 + +sir = sir_loop(lp); + +rkey = 13; +rng(rkey); %% Set Simulation Variables -O = 17; %order of prbs +O = 18; %order of prbs N = 2^(O-1); %length of prbs [~,seed] = prbs(O,1); %initialize first seed of prbs @@ -32,27 +38,30 @@ fsimu = kover * fdac ; digimod = PAMmapper(M,0); -pulseform = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.05); +pulseform = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.1); awg = AWG('fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5); lp_laser = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); -u_pi = 4.6; +u_pi = 3.5; vbias = (0.5*u_pi)-u_pi; extmodlaser = EML("mode",eml_mode.im_cosinus,"power",5,"fsimu",fsimu,"lambda",1550,"bias",vbias,"u_pi",u_pi,"linewidth",1e6); -fib = Fiber("fsimu",fdac*kover,"fiber_length",1,"alpha",0.2,"D",17,"lambda0",1550,"gamma",0); +fib = Fiber("fsimu",fdac*kover,"fiber_length",0,"alpha",0.2,"D",16,"lambda0",thz2nm(193.1),"gamma",0); -reflectionpoint = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",-20); -reflectionprop = Fiber("fsimu",fdac*kover,"fiber_length",1,"alpha",0.2,"D",17,"lambda0",1550,"gamma",0); +reflectionpoint = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",sir); +reflectionprop = Fiber("fsimu",fdac*kover,"fiber_length",1,"alpha",0.2,"D",16,"lambda0",1550,"gamma",0); -opticatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",0); -edfaamp = Amplifier("amp_mode","edfa_increase_nase","gain_mode","output_power","amplification_db",0,"nase_mode","generate_ase","noifig",5); +opticatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",-5); -phdiode = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity",1,"temperature",20); +edfaamp = Amplifier("amp_mode","edfa_increase_nase","gain_mode","output_power","amplification_db",0,"nase_mode","generate_ase","noifig",10.5); + + + +phdiode = Photodiode("fsimu",fdac*kover,"dark_current",0,"responsivity",1,"temperature",20); lp_diode = Filter('filtdegree',1,"f_cutoff",50e9,"fsamp",fdac*kover,"filterType",filtertypes.bessel_inp); @@ -61,7 +70,7 @@ scp = Scope("fsimu",fdac*kover,"fadc",fadc,... "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... "adcresolution",6,"quantbuffer",0.1,'block_dc',1); -eq = EQ("K",2,"plottrain",0,"plotfinal",0,... +eq = EQ("K",2,"plottrain",0,"plotfinal",0,... "training_length",4096,"training_loops",5,... "Ne",[50,0,0],"Nb",[0,0,0],... "DCmu",0.005,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0.00,... @@ -71,107 +80,97 @@ eq = EQ("K",2,"plottrain",0,"plotfinal",0,... %% PROCESS -fiblen = 0; -for lp1 = 1:length(fiblen) - - % change parameters - fib.fiber_length = fiblen(lp1); - % PRBS Generation - for i = 1:log2(M) - [bitpattern(:,i),seed] = prbs(O,N,seed); - end - - bitpattern = prms_out'; - - % Build Inf. signal class - bits = Informationsignal(bitpattern); - - % Digi Mod - mod_out = digimod.map(bits); - - % merken für EQ training - reference = mod_out; - - % shape shape - X = pulseform.process(mod_out); - test = applyPulseShaping(reference.signal,fsym,fdac); - - % AWG -> ELECTRICAL DOMAIN - awg_out = awg.process(X); - - X = lp_laser.process(awg_out); - X = lp_laser.process(X); - - X = X.normalize("mode","oneone"); - X.signal = X.signal .* 1.3800; - - % Laser; Modulation -> OPTICAL DOMAIN - X = extmodlaser.process(X); - - % Fiber Propagation - X = fib.process(X); - - %% Reflect with attenuation - R = reflectionpoint.process(X); - - % Propagate - R = reflectionprop.process(R); - - % Delay - R = R.delay("delay_meter",200); - - % Add together - X = X+R; - - %% - X = opticatten.process(X); - X = edfaamp.process(X); - - % Photo Diode -> ELECTRICAL DOMAIN - X = phdiode.process(X); - X = lp_diode.process(X); - %X.spectrum(fsimu,"displayname",'diode out','figurename','after diode'); - % Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation) - X = scp.process(X); - - % Resample to Symbol Rate - X = X.resample("fs_out",2*fsym,"fs_in",fadc); - - % Normalize - X = X.normalize("mode","rms"); - - % Equalizer - eq_out = eq.process(X,reference); - rx_series = eq_out.signal; - - % Digi Demod - demap_out = digimod.demap(eq_out); - - % BER - [bits,errors,BER] = calc_ber(demap_out.signal(1:end-2,:),bitpattern(1:end,:),0); - - disp(['BER: ', sprintf('%2E',BER), ' ERRORS: ' ,num2str(sum(errors))]); - - bercurve(lp1) = BER; - errorscurve(lp1) = sum(errors); +% PRBS Generation +for i = 1:log2(M) + [bitpattern(:,i),seed] = prbs(O,N,seed); end +%bitpattern = prms_out'; +% Build Inf. signal class +bits = Informationsignal(bitpattern); + +% Digi Mod +mod_out = digimod.map(bits); + +% merken für EQ training +reference = mod_out; + +% shape shape +X = pulseform.process(mod_out); + +% AWG -> ELECTRICAL DOMAIN +awg_out = awg.process(X); + +X = lp_laser.process(awg_out); +X = lp_laser.process(X); + +X = X.normalize("mode","oneone"); +X.signal = X.signal .* 0.6*(u_pi/2-abs(((0.5*u_pi)-u_pi/2))); + +% Laser; Modulation -> OPTICAL DOMAIN +X = extmodlaser.process(X); + +% Fiber Propagation +X = fib.process(X); + +%% Reflect with attenuation +R = reflectionpoint.process(X); + +% Propagate +R = reflectionprop.process(R); + +% Delay +R = R.delay("delay_meter",200); + +% Add together +X = X+R; + +X.spectrum(fsimu,"displayname",['SIR: ',num2str(sir)],"figurename",'spectrum') + +%% +X = opticatten.process(X); +X = edfaamp.process(X); + +% Photo Diode -> ELECTRICAL DOMAIN +X = phdiode.process(X); +X = lp_diode.process(X); + + +% Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation) +X = scp.process(X); + +% Resample to Symbol Rate +X = X.resample("fs_out",2*fsym,"fs_in",fadc); + +% Normalize +X = X.normalize("mode","rms"); + +% Equalizer +eq_out = eq.process(X,reference); + +% Digi Demod +demap_out = digimod.demap(eq_out); + +% BER +[bits,errors,BER] = calc_ber(demap_out.signal(1:end-1,:),bitpattern(1:end,:),1000); + +disp(['BER: ', sprintf('%2E',BER), ' ERRORS: ' ,num2str(sum(errors))]); %% Generate some Plots -if 1 +if 0 col = cbrewer2('Paired',8); - figure(22) + figure(11) clf subplot(2,1,1) hold on plot(reference.signal(4150:4175),'DisplayName','Tx','Color',col(1,:),'LineWidth',3); - plot(rx_series(4150:4175),'DisplayName','Rx after EQ','Color',col(6,:),'LineWidth',1); + plot(eq_out.signal(4150:4175),'DisplayName','Rx after EQ','Color',col(6,:),'LineWidth',1); title('Modulated Sequence Zoom'); legend hold off @@ -183,24 +182,29 @@ if 1 legend hold off +end +if 1 + col = cbrewer2('Paired',8); xax = 1:eq_out.length; - figure(12) + figure(3) sgtitle('') - subplot(1,4,1:2) - scatter(1:4:X.length,X.signal(1:4:end),4,'.','MarkerEdgeColor',col(6,:),'DisplayName','Before EQ'); - xlim([1, xax(end)]); - %ylim([-2 2]); - xlabel('Sampling Index') - ylabel('Amplitude') - legend +% subplot(1,4,1:2) +% scatter(1:4:X.length,X.signal(1:4:end),4,'.','MarkerEdgeColor',col(6,:),'DisplayName','Before EQ'); +% xlim([1, xax(end)]); +% %ylim([-2 2]); +% xlabel('Sampling Index') +% ylabel('Amplitude') +% legend - subplot(1,4,3:4) + subplot(1,5,lp) scatter(xax,eq_out.signal,4,'.','MarkerEdgeColor',col(6,:),'DisplayName','After EQ'); xlim([1, xax(end)]); - %ylim([-2 2]); + ylim([-2 2]); xlabel('Sampling Index') ylabel('Amplitude') legend end + +end