Equalizer with different DC removal positions

This commit is contained in:
Silas Oettinghaus
2023-09-29 08:18:22 +02:00
parent 8b3bc688dd
commit fce274c4cf
6 changed files with 443 additions and 326 deletions

View File

@@ -49,6 +49,8 @@ classdef EQ_silas < handle
trainloops
ddloops
dcmode
@@ -73,6 +75,8 @@ classdef EQ_silas < handle
options.mu_dc_dd = 0.01;
options.mu_combined_dd = [0.0004 0.0005 0.0006 0.0007 ];
options.dcmode
end
fn = fieldnames(options);
@@ -151,18 +155,32 @@ classdef EQ_silas < handle
m = m+1;
%get Sigal input vectors with correct length for VNLE
x_in_block = obj.x_in(obj.Ne(1)+n+(obj.sps-1):-1:n+obj.sps).';
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_vnle_format = obj.calcVNLENonlinVecs(x_in_block,obj.Ie2,obj.Ie3,obj.Ne,[1,1,1]);
%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);
% Calculate the Error
obj.e_ffe = obj.e.' * x_in_vnle_format;
obj.e_dfe = obj.b.' * d_vnle_format;
obj.error = obj.e_dc + obj.e_ffe - obj.e_dfe - obj.d(obj.Nb(1)-1+m-obj.delay);
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
%update FFE coefficients with LMS
obj.e = obj.e - obj.error*conj(x_in_vnle_format)*obj.mu_ffe_train;
@@ -179,6 +197,7 @@ classdef EQ_silas < handle
end
function decisionDirectedMode(obj)
%start the dd mode with coefficients from training
@@ -195,6 +214,10 @@ classdef EQ_silas < handle
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_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)];
end
y = zeros(1,floor(obj.x_length/obj.sps));
@@ -207,29 +230,47 @@ classdef EQ_silas < handle
m=m+1;
%get Sigal input vectors with correct length for VNLE
x = obj.x_in(obj.Ne(1)+k-1:-1:k).';
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_vnle = obj.calcVNLENonlinVecs(x,obj.Ie2,obj.Ie3,obj.Ne,[1,1,1]);
%combine FFE with DFE to one vector (cursor between the two sequences)
x_d = [x_vnle;-d_vnle];
%Apply filter
y(m) = obj.e_dc + x_d.'* coeff;
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
%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
obj.error = y(m) - d_hat(k);
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
%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);
coeff = coeff - mu_mat*obj.error*conj(x_d);
if 1 %mu_mat ~= 0
obj.e_dc = obj.e_dc - obj.mu_dc_dd * obj.error;
obj.error_log(ddloop,m) = obj.e_dc.^2;
end
obj.e_dc = obj.e_dc - obj.mu_dc_dd * obj.error;
obj.error_log(ddloop,m) = obj.e_dc.^2;
% Append new decision to decision feedback
if obj.Nb(1) > 0