Update April
This commit is contained in:
@@ -4,7 +4,6 @@ classdef AWG
|
||||
|
||||
properties(Access=public)
|
||||
|
||||
preset
|
||||
kover %oversampling factor e.g. 16
|
||||
repetitions %repeat the signal to generate a longer sequence?
|
||||
fdac %needed
|
||||
@@ -32,7 +31,6 @@ classdef AWG
|
||||
% Detailed explanation goes here
|
||||
|
||||
arguments
|
||||
options.preset = 'none';
|
||||
options.kover = 16;
|
||||
options.repetitions = 1;
|
||||
options.normalize = 1;
|
||||
@@ -45,6 +43,7 @@ classdef AWG
|
||||
options.lpf_active = 0;
|
||||
options.lpf_type = 0;
|
||||
options.f_cutoff = 32e9;
|
||||
options.H_lpf Filter
|
||||
end
|
||||
|
||||
fn = fieldnames(options);
|
||||
@@ -54,40 +53,34 @@ classdef AWG
|
||||
end
|
||||
end
|
||||
|
||||
if options.preset == "M8196A"
|
||||
% M8196A (92GBd) https://www.keysight.com/us/en/product/M8196A/92-gsa-s-arbitrary-waveform-generators.html
|
||||
obj.dac_max = 0.5;
|
||||
obj.dac_min = -.5;
|
||||
obj.f_cutoff = 50e9;
|
||||
elseif options.preset == "M8199B"
|
||||
%https://www.keysight.com/us/en/assets/3120-1465/data-sheets/M8199A-128-256-GSa-s-Arbitrary-Waveform-Generator.pdf
|
||||
% obj.fdac = 256e9;
|
||||
obj.dac_max = 0.5;
|
||||
obj.dac_min = -.5;
|
||||
obj.f_cutoff = 80e9;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function signalclass_out = process(obj,signalclass_in)
|
||||
|
||||
|
||||
len_in = length(signalclass_in.signal);
|
||||
|
||||
% actual processing of the signal (steps 1. - 3.)
|
||||
% 1-3. actual processing of the signal (normalize->quantize->sample hold)
|
||||
signalclass_in.signal = obj.process_(signalclass_in.signal);
|
||||
|
||||
% 4. Apply LPF on the signal
|
||||
if obj.lpf_active
|
||||
lpf = Filter('filtdegree',5,"f_cutoff",obj.f_cutoff,"fsamp",obj.kover*obj.fdac,"filterType",obj.lpf_type);
|
||||
signalclass_in = lpf.process(signalclass_in);
|
||||
if isa(obj.H_lpf,'Filter')
|
||||
%4.A) user already specified a complete filter class when
|
||||
% initializing the AWG module
|
||||
signalclass_in = obj.H_lpf.process(signalclass_in);
|
||||
else
|
||||
%4.B) just use a standard filter
|
||||
lpf = Filter('filtdegree',5,"f_cutoff",obj.f_cutoff,"fsamp",obj.kover*obj.fdac,"filterType",obj.lpf_type);
|
||||
signalclass_in = lpf.process(signalclass_in);
|
||||
end
|
||||
end
|
||||
|
||||
% cast the inform. signal to electrical signal
|
||||
signalclass_in = Electricalsignal(signalclass_in,"fs",obj.fdac*obj.kover,"logbook",signalclass_in.logbook);
|
||||
|
||||
% append to logbook
|
||||
lbdesc = ['AWG preset ', obj.preset, 'k_over:',num2str(obj.kover),'. f_dac:',num2str(obj.fdac*1e-9),'GHz. Resolution:',num2str(obj.bit_resolution),' bits.'];
|
||||
current_class = class(obj);
|
||||
lbdesc = ['AWG ', current_class , '// k_over:',num2str(obj.kover),'. f_dac:',num2str(obj.fdac*1e-9),'GHz. Resolution:',num2str(obj.bit_resolution),' bits.'];
|
||||
signalclass_in = signalclass_in.logbookentry(lbdesc);
|
||||
|
||||
% write to output
|
||||
|
||||
35
Classes/01_transmit/M8196A.m
Normal file
35
Classes/01_transmit/M8196A.m
Normal file
@@ -0,0 +1,35 @@
|
||||
classdef M8196A < AWG
|
||||
properties
|
||||
|
||||
end
|
||||
|
||||
methods
|
||||
|
||||
function obj = M8196A()
|
||||
%This is a ready to use AWG simulation that resembles the
|
||||
%properties of the Keysighe M8196A % M8196A (92GBd) https://www.keysight.com/us/en/product/M8196A/92-gsa-s-arbitrary-waveform-generators.html
|
||||
arguments
|
||||
%options.bla = 1;
|
||||
end
|
||||
|
||||
obj = obj@AWG();
|
||||
obj.dac_max = 0.5;
|
||||
obj.dac_min = -.5;
|
||||
obj.bit_resolution = 5.5;
|
||||
|
||||
obj.fdac = 92e9;
|
||||
|
||||
obj.lpf_active = 1;
|
||||
|
||||
obj.f_cutoff = 32e9;
|
||||
obj.lpf_type = filtertypes.gaussian;
|
||||
obj.H_lpf = Filter('filtdegree',5,"f_cutoff",obj.f_cutoff,"fsamp",obj.kover*obj.fdac,"filterType",obj.lpf_type);
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
34
Classes/01_transmit/M8199B.m
Normal file
34
Classes/01_transmit/M8199B.m
Normal file
@@ -0,0 +1,34 @@
|
||||
classdef M8199B < AWG
|
||||
properties
|
||||
|
||||
end
|
||||
|
||||
methods
|
||||
|
||||
function obj = M8199B()
|
||||
%This is a ready to use AWG simulation that resembles the
|
||||
%properties of the Keysighe M8199B https://www.keysight.com/us/en/assets/3120-1465/data-sheets/M8199A-128-256-GSa-s-Arbitrary-Waveform-Generator.pdf
|
||||
arguments
|
||||
%options.bla = 1;
|
||||
end
|
||||
|
||||
obj = obj@AWG();
|
||||
obj.dac_max = 0.5;
|
||||
obj.dac_min = -.5;
|
||||
obj.bit_resolution = 5.5;
|
||||
|
||||
obj.fdac = 256e9;
|
||||
|
||||
obj.lpf_active = 1;
|
||||
|
||||
obj.f_cutoff = 80e9;
|
||||
obj.lpf_type = filtertypes.gaussian;
|
||||
obj.H_lpf = Filter('filtdegree',5,"f_cutoff",obj.f_cutoff,"fsamp",obj.kover*obj.fdac,"filterType",obj.lpf_type);
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -19,10 +19,16 @@ classdef PAMmapper
|
||||
|
||||
end
|
||||
|
||||
function signalclass_out = map(obj,signalclass_in)
|
||||
signalclass_in.signal = obj.map_(signalclass_in.signal);
|
||||
signalclass_in = signalclass_in.logbookentry();
|
||||
signalclass_out = signalclass_in;
|
||||
function out = map(obj,signal_in)
|
||||
|
||||
if isa(signal_in,'Signal')
|
||||
signal_in.signal = obj.map_(signal_in.signal);
|
||||
signal_in = signal_in.logbookentry();
|
||||
out = signal_in;
|
||||
else
|
||||
out = signal_in;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function signalclass_out = demap(obj,signalclass_in)
|
||||
@@ -157,7 +163,7 @@ classdef PAMmapper
|
||||
case 2
|
||||
% 4-ASK
|
||||
|
||||
data_out=[comp_real(:,:,2); ones(s1,s2)-comp_real(:,:,1)+comp_real(:,:,3)];
|
||||
data_out=[comp_real(:,:,2); ones(s1,s2) - comp_real(:,:,1) + comp_real(:,:,3)];
|
||||
|
||||
|
||||
case 3
|
||||
@@ -179,16 +185,43 @@ classdef PAMmapper
|
||||
|
||||
end
|
||||
|
||||
function [data_out] = decide_pamlevel(obj,data_in)
|
||||
function [data_out] = decide_pamlevel(obj,data_in,options)
|
||||
arguments
|
||||
obj
|
||||
data_in Signal
|
||||
options.symbol_levels = []
|
||||
end
|
||||
|
||||
%A) normally return the preproduct of the decision
|
||||
a = squeeze(repmat(real(data_in.signal),[1 1 length(obj.thresholds)])); %Eingangssignal in 3 spalten
|
||||
b = squeeze(repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in.signal) 1])); %Threshold in 3 Spalten
|
||||
comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3
|
||||
|
||||
data_out = data_in;
|
||||
data_out.signal = sum(comp_real,2);
|
||||
|
||||
%Option: return the actual level values/ just map onto given
|
||||
%symbol levels
|
||||
if ~isempty(options.symbol_levels)
|
||||
data_out.signal = options.symbol_levels(data_out.signal+1);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
data_out = sum(comp_real,2);
|
||||
function [out] = separate_pamlevels(obj,data_in)
|
||||
|
||||
%A) normally return the preproduct of the decision
|
||||
a = squeeze(repmat(real(data_in.signal),[1 1 length(obj.thresholds)])); %Eingangssignal in 3 spalten
|
||||
b = squeeze(repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in.signal) 1])); %Threshold in 3 Spalten
|
||||
comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3
|
||||
comp_real_sum = sum(comp_real,2);
|
||||
|
||||
%data_out = (data_out*2)-3;
|
||||
out = NaN(length(data_in),length(obj.thresholds)+1);
|
||||
|
||||
for idx = 1:length(data_in)
|
||||
out(idx,comp_real_sum(idx)+1) = data_in.signal(idx);
|
||||
end
|
||||
|
||||
%data_out = pam_level_decision .* 1/sqrt(5);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ classdef Pulseformer
|
||||
properties(Access=public)
|
||||
fdac
|
||||
fsym
|
||||
pulseform
|
||||
pulse
|
||||
pulselength
|
||||
rrcalpha
|
||||
end
|
||||
@@ -18,7 +18,7 @@ classdef Pulseformer
|
||||
arguments
|
||||
options.fdac double
|
||||
options.fsym double
|
||||
options.pulseform pulseform = pulseform.rrc
|
||||
options.pulse pulseform = pulseform.rrc
|
||||
options.pulselength double {mustBeInteger} = 32
|
||||
options.rrcalpha double = 0.05
|
||||
end
|
||||
@@ -44,6 +44,9 @@ classdef Pulseformer
|
||||
lbdesc = 'Applied Pulseshaping';
|
||||
signalclass_in = signalclass_in.logbookentry(lbdesc);
|
||||
|
||||
% write fs to signal
|
||||
signalclass_in.fs = obj.fdac;
|
||||
|
||||
% write to output
|
||||
signalclass_out = signalclass_in;
|
||||
|
||||
@@ -62,11 +65,11 @@ classdef Pulseformer
|
||||
% Detailed explanation goes here
|
||||
arguments(Input)
|
||||
obj
|
||||
data_in double
|
||||
data_in
|
||||
end
|
||||
|
||||
arguments(Output)
|
||||
data_out double
|
||||
data_out
|
||||
end
|
||||
|
||||
if ~rem(obj.fdac,obj.fsym)
|
||||
@@ -81,9 +84,9 @@ classdef Pulseformer
|
||||
sps= up;
|
||||
end
|
||||
|
||||
if obj.pulseform == pulseform.rrc
|
||||
if obj.pulse == pulseform.rrc
|
||||
%Bau das Filter (hier rrc)
|
||||
racos_len = obj.pulselength*2 ;
|
||||
racos_len = obj.pulselength*2;
|
||||
alpha = obj.rrcalpha;
|
||||
h = rcosdesign(alpha,racos_len,sps);
|
||||
h = h./ max(h);
|
||||
@@ -115,12 +118,13 @@ classdef Pulseformer
|
||||
|
||||
|
||||
% %Apply Filter using Matlab build in fctn.
|
||||
% data_out = upfirdn(data_in,h,up,dn);
|
||||
h = rcosdesign(alpha,racos_len,sps);
|
||||
h = h./ max(h);
|
||||
%data_out_ = upfirdn(data_in,h,up,dn);
|
||||
%
|
||||
% %cut signal, which is longer due to fir filter
|
||||
st = round(up/dn*racos_len/2); %we need to cut y_out
|
||||
% en = round(st + (length(data_in)*up/dn) -1);
|
||||
%
|
||||
% data_out = data_out(st:en);
|
||||
|
||||
%scaling?! see pulsef module line 696
|
||||
|
||||
Reference in New Issue
Block a user