diff --git a/Classes/04_DSP/EQ_silas.m b/Classes/04_DSP/EQ_silas.m index d32d875..47b0591 100644 --- a/Classes/04_DSP/EQ_silas.m +++ b/Classes/04_DSP/EQ_silas.m @@ -5,11 +5,11 @@ classdef EQ_silas < handle % Important Signals x_in %Input Sequence to be equalized x_length - x_norm + x_norm d %reference signal d_norm - d_constellation %constellation points of the reference + d_constellation %constellation points of the reference y_out %equalizer output signal @@ -35,12 +35,15 @@ classdef EQ_silas < handle e_dc error_log + % coefficients mu_dc_train mu_ffe_train mu_dfe_train mu_dc_dd - mu_combined_dd + mu_ffe_dd + mu_dfe_dd + mu_combined_dd % [1st order FFE, 2nd order FFE, 3rd order FFE, all orders DFE] delay trainlength @@ -74,7 +77,8 @@ classdef EQ_silas < handle options.mu_dfe_train = 0.005; options.mu_dc_dd = 0.01; - options.mu_combined_dd = [0.0004 0.0005 0.0006 0.0007 ]; + options.mu_ffe_dd = [0.0004 0.0005 0.0006]; + options.mu_dfe_dd = 0.0005; options.dcmode = 1; end @@ -106,7 +110,7 @@ classdef EQ_silas < handle % actual processing of the signal (steps 1. - 3.) % 1 normalize RMS - signalclass_in = signalclass_in.normalize("mode","rms"); + %signalclass_in = signalclass_in.normalize("mode","rms"); % Process the EQ optimization obj.process_(signalclass_in.signal', reference_signalclass_in.signal'); @@ -155,35 +159,31 @@ classdef EQ_silas < handle m = m+1; %get Sigal input vectors with correct length for VNLE - - if obj.dcmode ~= 3 - x_in_block = obj.x_in(obj.Ne(1)+n+(obj.sps-1):-1:n+obj.sps).'; - elseif obj.dcmode == 3 - x_in_block = obj.x_in(obj.Ne(1)+n+(obj.sps-1):-1:n+obj.sps).' + obj.e_dc; - end + x_in_block = obj.x_in(obj.Ne(1)+n+(obj.sps-1):-1:n+obj.sps).'; - x_in_vnle_format = obj.calcVNLENonlinVecs(x_in_block,obj.Ie2,obj.Ie3,obj.Ne,[1,1,1]); + x_in_vnle_format = obj.calcVNLENonlinVecs(x_in_block,obj.Ie2,obj.Ie3,obj.Ne,obj.x_norm); %get Reference input vectors with correct length for VNLE d_block = obj.d(obj.Nb(1)-obj.delay+m-2:-1:m-obj.delay-1).'; d_vnle_format = obj.calcVNLENonlinVecs(d_block,obj.Ib2,obj.Ib3,obj.Nb,obj.d_norm); - obj.e_dfe = obj.b.' * d_vnle_format; - obj.e_ffe = obj.e.' * x_in_vnle_format; - % Calculate the Error - if obj.dcmode == 1 - obj.error = obj.e_dc + obj.e_ffe - obj.e_dfe - obj.d(obj.Nb(1)-1+m-obj.delay); - elseif obj.dcmode == 2 - obj.e_ffe = obj.e_ffe + obj.e_dc; - obj.error = obj.e_ffe - obj.e_dfe - obj.d(obj.Nb(1)-1+m-obj.delay); - elseif obj.dcmode == 3 - obj.error = obj.e_ffe - obj.e_dfe - obj.d(obj.Nb(1)-1+m-obj.delay); - end + obj.e_dfe = obj.b.' * d_vnle_format; - %update FFE coefficients with LMS - obj.e = obj.e - obj.error*conj(x_in_vnle_format)*obj.mu_ffe_train; + % Calculate the Error + obj.error = obj.e_dc + obj.e_ffe - obj.e_dfe - obj.d(obj.Nb(1)-1+m-obj.delay); + + err_track(n) = obj.error; + + + if obj.mu_ffe_train ~= 0 + %update FFE coefficients with LMS + obj.e = obj.e - obj.error*conj(x_in_vnle_format)*obj.mu_ffe_train; + else + %update FFE coefficients with NLMS + obj.e = obj.e - obj.error*x_in_vnle_format/(x_in_vnle_format.'*x_in_vnle_format); + end %update DFE coefficients with LMS obj.b = obj.b + obj.mu_dfe_train*obj.error*d_vnle_format; @@ -208,16 +208,16 @@ classdef EQ_silas < handle m = 0; - mu_mat = diag([ones(1,obj.Ce(1))*obj.mu_combined_dd(1)... %1st order ffe - ones(1,obj.Ce(2))*obj.mu_combined_dd(2)... %2nd order ffe - ones(1,obj.Ce(3))*obj.mu_combined_dd(3)... %3rd order ffe - ones(1,sum(obj.Cb))*obj.mu_combined_dd(4)]); %all order dfe + mu_mat = diag([ones(1,obj.Ce(1))*obj.mu_ffe_dd(1)... %1st order ffe + ones(1,obj.Ce(2))*obj.mu_ffe_dd(2)... %2nd order ffe + ones(1,obj.Ce(3))*obj.mu_ffe_dd(3)... %3rd order ffe + ones(1,sum(obj.Cb))*obj.mu_dfe_dd]); %all order dfe - mu_ffe = [ones(1,obj.Ce(1))*obj.mu_combined_dd(1)... %1st order ffe - ones(1,obj.Ce(2))*obj.mu_combined_dd(2)... %2nd order ffe - ones(1,obj.Ce(3))*obj.mu_combined_dd(3)]; - - mu_dfe = ones(1,sum(obj.Cb))*obj.mu_combined_dd(4); + mu_ffe = [ones(1,obj.Ce(1))*obj.mu_ffe_dd(1)... %1st order ffe + ones(1,obj.Ce(2))*obj.mu_ffe_dd(2)... %2nd order ffe + ones(1,obj.Ce(3))*obj.mu_ffe_dd(3)]; + + mu_dfe = ones(1,sum(obj.Cb))*obj.mu_dfe_dd; y = zeros(1,floor(obj.x_length/obj.sps)); @@ -230,44 +230,30 @@ classdef EQ_silas < handle m=m+1; %get Sigal input vectors with correct length for VNLE - if obj.dcmode ~= 3 - x = obj.x_in(obj.Ne(1)+k-1:-1:k).'; - elseif obj.dcmode == 3 - x = obj.x_in(obj.Ne(1)+k-1:-1:k).' + obj.e_dc; - end + x = obj.x_in(obj.Ne(1)+k-1:-1:k).'; - x_vnle = obj.calcVNLENonlinVecs(x,obj.Ie2,obj.Ie3,obj.Ne,[1,1,1]); + x_vnle = obj.calcVNLENonlinVecs(x,obj.Ie2,obj.Ie3,obj.Ne,obj.x_norm); %combine FFE with DFE to one vector (cursor between the two sequences) x_d = [x_vnle;-d_vnle]; %Apply filter - if obj.dcmode == 1 - y(m) = obj.e_dc + x_d.'* coeff; - elseif obj.dcmode == 2 || obj.dcmode == 3 -% x_ffe = obj.e.' * x_vnle; -% x_dfe = obj.b.' * d_vnle; -% y(m) = x_ffe - x_dfe; - y(m) = x_d.'* coeff; - end + y(m) = obj.e_dc + x_d.'* coeff; %Decision [~,symbol_idx] = min(abs(y(m) - obj.d_constellation)); % decision for closest constellation point d_hat(k) = obj.d_constellation(symbol_idx); %Error between FFE & DFE filtered signal and Decision - if obj.dcmode == 1 || obj.dcmode == 3 - obj.error = y(m) - d_hat(k); - elseif obj.dcmode == 2 - obj.error = y(m) - d_hat(k) + obj.e_dc; - end + obj.error = y(m) - d_hat(k); %Update coefficients (both FFE and DFE) - obj.e = obj.e - obj.error * mu_ffe * conj(x_vnle); - obj.b = obj.b + obj.error * mu_dfe * conj(d_vnle); + % obj.e = obj.e - obj.error * mu_ffe * conj(x_vnle); + % obj.b = obj.b + obj.error * mu_dfe * conj(d_vnle); + % coeff = [obj.e;obj.b]; coeff = coeff - mu_mat*obj.error*conj(x_d); - + obj.e_dc = obj.e_dc - obj.mu_dc_dd * obj.error; obj.error_log(ddloop,m) = obj.e_dc.^2;