Many changes for 400G DSP

Minimal Example
...
This commit is contained in:
sioe
2024-12-17 16:17:58 +01:00
parent 397cfa61dd
commit e47a4dbbbe
68 changed files with 2749 additions and 2948 deletions

View File

@@ -0,0 +1,75 @@
useprbs = 1;
M = 4;
randkey = 1;
datarate = 224e9;
fsym = round(datarate / log2(M)) ;
db_pre = 1;
Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rrc","pulselength",16,"rrcalpha",0.05);
[d,Symbols,Bits] = PAMsource(...
"fsym",fsym,"M",M,"order",17,"useprbs",1,...
"fs_out",fsym,...
"applyclipping",0,"clipfactor",1.5,...
"applypulseform",0,"pulseformer",Pform,...
"randkey",1,...
"db_precode",db_pre,"db_encode",0,...
"mrds_code",0,"mrds_blocklength",512).process();
%%%CHANNEL
% s = RandStream('twister','Seed',2);
% start = 10000;
% burstwidth = 100;
% d_burst = d;
% for pos = start:start+burstwidth
% lvls = 1.5 .* PAMmapper(M,0).levels / rms(PAMmapper(M,0).levels);
% d_burst.signal(pos) = d.signal(pos)+randn(s,1,1);
% end
d_resample = d.resample("fs_out",2.*fsym);
eq_ffe = FFE("epochs_tr",5,"epochs_dd",5,"len_tr",1024,"mu_dd",0.0004,"mu_tr",0,"order",25,"sps",2,"decide",1);
d_eq = eq_ffe.process(d_resample,Symbols);
% s = RandStream('twister','Seed',2);
% start = 10000;
% burstwidth = 100;
% d_burst = d_eq;
% for pos = start:start+burstwidth
% lvls = 1.5 .* PAMmapper(M,0).levels / rms(PAMmapper(M,0).levels);
% d_burst.signal(pos) = d_eq.signal(pos)+randn(s,1,1);
% end
%
% d_burst = PAMmapper(M,0).decide_pamlevel(d_burst);
if db_pre
% Entschiedene Symbole codieren: d_DB(n) = d(n) + d(n-1) (im Fall von PAM4 7 level [0 1 2 3 4 5 6])
d_db = Duobinary().encode(d);
% Entschiedene codierte Symbole decodieren: d_dec(n) = d_DB(n) mod4
d_dec = Duobinary().decode(d_db);
else
d_dec = d_burst;
end
% Vergleichen von b(n) und d_dec(n)
Rx_bits = PAMmapper(M,0).demap(d_dec);
Tx_bits = Bits;
[~,error_num,ber,error_pos] = calc_ber(Tx_bits.signal,Rx_bits.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1);
disp(['BER: ',sprintf('%.1E',ber),' - - PAM-',num2str(M)]);
figure(200)
clf
hold on
idxs = start-10:start+burstwidth+10;
scatter(idxs,d.signal(idxs),'DisplayName',['Orig Signal'],'Marker','o');
scatter(idxs,d_burst.signal(idxs),'DisplayName',['Error Signal'],'Marker','x');
scatter(idxs,d_dec.signal(idxs),'DisplayName',['EQ Signal'],'Marker','x');
yline(PAMmapper(M,0).thresholds,'HandleVisibility','off');
legend
ylim([-2 2])

View File

@@ -1,43 +1,55 @@
useprbs = 1;
M = 6;
M = 4;
randkey = 1;
datarate = 448e9;
fsym = round(datarate / log2(M)) ;
%%%%% PRBS Generation in correct shape for Modulation Format %%%%%%
O = 17; %order of prbs
O = 15; %O of prbs
N = 2^(O); %length of prbs
[~,seed] = prbs(O,1); %initialize first seed of prbs
bitpattern=[];
if useprbs
for i = 1:log2(M)
[bitpattern(:,i),seed] = prbs(O,N,seed);
end
else
s = RandStream('twister','Seed',randkey);
for i = 1:log2(M)
bitpattern(:,i) = randi(s,[0 1], N, 1);
end
end
state = struct();
para = struct();
if M == 6
bitpattern = reshape(bitpattern,[],1);
bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
para.bl = 2^(O-2);
para.dimension = 5;
else
para.bl = 2^(O-1);
para.dimension = log2(M); %2.5bits/sym -> 2 bit/sym
end
para.rand = 0;
para.order = floor(O / log2(M));
para.skip =0;
para.bruijn = 0;
para.reset_prms = 0;
para.method = 1;
data_in = [];
global loop;
loop = 0;
[data_out,state_] = prms(data_in, state, para);
loop = 1;
[data_out,state_out] = prms(data_in, state_, para);
bitpattern = data_out';
Tx_bits = Informationsignal(bitpattern);
Symbols_tx = PAMmapper(M,0).map(Tx_bits);
Symbols_tx.fs = fsym;
Symbols = Duobinary().precode(Symbols_tx);
Symbols1 = Duobinary().precode(Symbols_tx);
Symbols = Duobinary().encode(Symbols);
Symbols2 = Duobinary().encode(Symbols1);
Symbols = Duobinary().decode(Symbols);
Symbols3 = Duobinary().decode(Symbols2);
Rx_bits = PAMmapper(M,0).demap(Symbols);
Rx_bits = PAMmapper(M,0).demap(Symbols3);
[~,error_num,ber,error_pos] = calc_ber(Tx_bits.signal,Rx_bits.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1);

32
test/exampleFunction.m Normal file
View File

@@ -0,0 +1,32 @@
function output = exampleFunction(varargin)
% Default values for optional variables
var_1 = 1;
var_2 = 2;
var_4 = 10; % Default value for var4
var_5 = 20; % Default value for var5
var_6 = 30; % Default value for var6
var_7 = 40; % Default value for var7
var_8 = 50; % Default value for var8
var_9 = 60; % Default value for var9
var_10 = 70; % Default value for var10
% Parse optional input arguments
if ~isempty(varargin)
var_s = varargin{1};
if isstruct(var_s)
fields = fieldnames(var_s);
for i = 1:numel(fields)
eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']);
fprintf("%s <-- %.2f \n",fields{i},var_s.(fields{i}))
end
else
error('Optional variables should be passed as a struct.');
end
end
output = var_4+var_10+var_9+var_8+var_1+var_2;
end

100
test/run_examplefcn.m Normal file
View File

@@ -0,0 +1,100 @@
% Define ranges for variables to iterate over
var1_range = [1, 2, 3, 4, 6];
var2_range = [10, 20];
var3_range = [100, 200];
% Prepare the parallel pool
if isempty(gcp('nocreate'))
parpool; % Start a parallel pool if not already running
end
% Array to hold measurement futures
measurements = parallel.FevalFuture.empty();
% Array to hold DSP results
dsp_results = parallel.Future.empty();
% Nested for loops for all parameter combinations
lin_idx = 1;
for v1 = var1_range
for v2 = var2_range
for v3 = var3_range
% Construct the struct of optional variables for this iteration
optionalVars = struct('var_4', v1, 'var_5', v2, 'var_6', v3);
% Submit the measurement function to the parallel pool
measurements(lin_idx) = parfeval(@measurement, 1, optionalVars);
% Link DSP function to run after measurement completes
dsp_results(lin_idx) = afterEach(measurements(lin_idx), @(output) rundsp(output, optionalVars), 1);
lin_idx = lin_idx + 1; % Increment linear index
end
end
end
% Fetch and display DSP results
final_results = cell(numel(dsp_results), 1);
for i = 1:numel(dsp_results)
fprintf('Fetching DSP result for job %d...\n', i);
final_results{i} = fetchOutputs(dsp_results(i)); % Fetch each DSP result individually
end
fprintf('All DSP evaluations completed.\n');
disp('Final Results:');
disp(final_results);
% --- Measurement Function ---
function output = measurement(varargin)
% Default values for optional variables
var_1 = 1;
var_2 = 2;
var_4 = 10; % Default value for var4
var_5 = 20; % Default value for var5
var_6 = 30; % Default value for var6
var_7 = 40; % Default value for var7
var_8 = 50; % Default value for var8
var_9 = 60; % Default value for var9
var_10 = 70; % Default value for var10
% Parse optional input arguments
if ~isempty(varargin)
var_s = varargin{1};
if isstruct(var_s)
fields = fieldnames(var_s);
for i = 1:numel(fields)
eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']);
fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i}));
end
else
error('Optional variables should be passed as a struct.');
end
end
% Simulate output with a random delay
output = randi(5); % Random result
pause(output); % Simulate processing time
end
% --- DSP Function ---
function output = rundsp(measurement_output, varargin)
% Parse optional input arguments
if ~isempty(varargin)
var_s = varargin{1};
if isstruct(var_s)
fields = fieldnames(var_s);
for i = 1:numel(fields)
eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']);
fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i}));
end
else
error('Optional variables should be passed as a struct.');
end
end
% Simulate DSP processing based on measurement output
output = measurement_output + 10; % Add 10 to measurement output
pause(measurement_output); % Simulate DSP processing time
end