File Comparison Report

C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_450beta1.m vs. C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_450beta2.m

richardm

15-Apr-2024

Files

Left FileRight File
File namecom_ieee8023_93a_450beta1com_ieee8023_93a_450beta2
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified04-Apr-2024 15:14:0812-Apr-2024 15:15:54

Environment

MATLAB9.14 (R2023a)

Comparison Results

+

Insertion

Deletion

Modification
1

function results=com_ieee8023_93a(varargin)

1

function results=com_ieee8023_93a(varargin)

2

% This is NOT an official IEEE document.

2

% This is NOT an official IEEE document.

3

%% Implementation example of annex 93A IEEE Std 802.3

3

%% Implementation example of annex 93A IEEE Std 802.3

4

% http://www.ieee802.org/3/ck/public/adhoc/index.html

4

% http://www.ieee802.org/3/ck/public/adhoc/index.html

5

% result=com_ieee8023_93a(config_file, num_fext, num_next [, <s4p files>])

5

% result=com_ieee8023_93a(config_file, num_fext, num_next [, <s4p files>])

6

% - config_file: xls, xls, mat file which contains configuration settings

6

% - config_file: xls, xls, mat file which contains configuration settings

7

% - num_fext: number of FEXT s4p files in the listfigure(300+package_testcase_i);

7

% - num_fext: number of FEXT s4p files in the listfigure(300+package_testcase_i);

8

% - num_next: number of NEXT s4p files in the list

8

% - num_next: number of NEXT s4p files in the list

9

% - <s4p_files>: (1+num_fext+num_nefxt) file names. If not supplied, program

9

% - <s4p_files>: (1+num_fext+num_nefxt) file names. If not supplied, program

10

% will ask for each of the files interactively.opupu

10

% will ask for each of the files interactively.opupu

11

%

11

%

12

% This program is intended for the development of standard specifications

12

% This program is intended for the development of standard specifications

13

% and reflects activity of IEEE P802.3bj, .3by, .3bm, .3bs, .3cd, .3ck

13

% and reflects activity of IEEE P802.3bj, .3by, .3bm, .3bs, .3cd, .3ck

14

% found in Annex 93A IEEE Std 802.3™ and project =updates

14

% found in Annex 93A IEEE Std 802.3™ and project =updates

15

% original proposal for COM may be found at

15

% original proposal for COM may be found at

16

% http://www.ieee802.org/3/bj/public/jul12/mellitz_01_0712.pdf in July 2012

16

% http://www.ieee802.org/3/bj/public/jul12/mellitz_01_0712.pdf in July 2012

17

% from the following authors and affiliations in 2012.

17

% from the following authors and affiliations in 2012.

18

% Richard Mellitz, Intel Corporation

18

% Richard Mellitz, Intel Corporation

19

% Charles Moore, Avago Technologies

19

% Charles Moore, Avago Technologies

20

% Mike Dudek, QLogic Corporation

20

% Mike Dudek, QLogic Corporation

21

% Mike Peng Li, Altera Corporation

21

% Mike Peng Li, Altera Corporation

22

% Adee Ran, Intel Corporation

22

% Adee Ran, Intel Corporation

23

%

23

%

24

% Some of the authors and Contributors:

24

% Some of the authors and Contributors:

25

% Adee Ran

25

% Adee Ran

26

% Richard Mellitz

26

% Richard Mellitz

27

% Yasuo Hidaka

27

% Yasuo Hidaka

28

% John Ewen

28

% John Ewen

29

% Bill Kirkland

29

% Bill Kirkland

30

% Adam Gregory

30

% Adam Gregory

31

% Howard Heck

31

% Howard Heck

32

% Jingbo Li

32

% Jingbo Li

33

% Adam Healey

33

% Adam Healey

34

% Matt Brown

34

% Matt Brown

35

% Sameh Elnagar

35

% Sameh Elnagar

36

% Hossein Shakiba

36

% Hossein Shakiba

37

zzz_list_of_changes()

37

zzz_list_of_changes()

38

38

39

%% Opening Preface

39

%% Opening Preface

40

% acquire parsing command string and set up OP control structure. Then read in files

40

% acquire parsing command string and set up OP control structure. Then read in files

41

close(findall(0, 'tag', 'TMWWaitbar', '-or', 'tag', 'COM'));

41

close(findall(0, 'tag', 'TMWWaitbar', '-or', 'tag', 'COM'));

42

try % version number at end of call string

42

try % version number at end of call string

43

cmdfile=mfilename;

43

cmdfile=mfilename;

44

hindx=strfind(mfilename,'_');

44

hindx=strfind(mfilename,'_');

45

ver=cmdfile(hindx(end)+1:end);

45

ver=cmdfile(hindx(end)+1:end);

46

output_args.code_revision = [ver(1), '.',ver(2:end)];

46

output_args.code_revision = [ver(1), '.',ver(2:end)];

47

catch

47

catch

48

output_args.code_revision ='';

48

output_args.code_revision ='';

49

end

49

end

50

teststr='';

50

teststr='';

51

OP.TESTING=0;

51

OP.TESTING=0;

52

if OP.TESTING == 1 % set to 1 or pre release

52

if OP.TESTING == 1 % set to 1 or pre release

53

teststr='testing';

53

teststr='testing';

54

testmsg=sprintf('Evaluation Copy: COM%s%s\n',output_args.code_revision,teststr);

54

testmsg=sprintf('Evaluation Copy: COM%s%s\n',output_args.code_revision,teststr);

55

htest = msgbox(testmsg);

55

htest = msgbox(testmsg);

56

set(htest,'Color','y', 'tag', 'COM');movegui(htest,'northeast');

56

set(htest,'Color','y', 'tag', 'COM');movegui(htest,'northeast');

57

end

57

end

58

disp('This is NOT an official IEEE document.')

58

disp('This is NOT an official IEEE document.')

59

fprintf('Revision:<strong> %s%s </strong>This is a computation example for exploring COM and ERL \n',output_args.code_revision,teststr)

59

fprintf('Revision:<strong> %s%s </strong>This is a computation example for exploring COM and ERL \n',output_args.code_revision,teststr)

60

disp(' for projects like IEEE P802.3bj/b/bs/cd/ck with some exploratory extensions and is not normative or official')

60

disp(' for projects like IEEE P802.3bj/b/bs/cd/ck with some exploratory extensions and is not normative or official')

61

t0=tic;

61

t0=tic;

62

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

62

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

63

% reset to tex on exit

63

% reset to tex on exit

64

%% file_setup

64

%% file_setup

65

%%

65

%%

66

% need to see what happens for version 8

66

% need to see what happens for version 8

67

if verLessThan('matlab', '7.4.1')

67

if verLessThan('matlab', '7.4.1')

68

error('Matlab version 7.4 or higher required')

68

error('Matlab version 7.4 or higher required')

69

end

69

end

70

70

71

results=[];

71

results=[];

72

72

73

%% New Command Line parser

73

%% New Command Line parser

74

[config_file,num_fext,num_next,Remember_keyword,OP,varargin]=COM_CommandLine_Parse(OP,varargin{:});

74

[config_file,num_fext,num_next,Remember_keyword,OP,varargin]=COM_CommandLine_Parse(OP,varargin{:});

75

75

76

76

77

%% get the first 3 arguments and allow for interactive input.

77

%% get the first 3 arguments and allow for interactive input.

78

if isempty(config_file)

78

if isempty(config_file)

79

config_file=input('Enter config XLS file or return will just pop a window to ask for the XLS file]: ','s');

79

config_file=input('Enter config XLS file or return will just pop a window to ask for the XLS file]: ','s');

80

if isempty(config_file)

80

if isempty(config_file)

81

[config_file, config_file_path] = uigetfile([{ '*.xls;*.xlsx'} ; {'*.mat'}],'INPUT CONFIG FILE .xls');

81

[config_file, config_file_path] = uigetfile([{ '*.xls;*.xlsx'} ; {'*.mat'}],'INPUT CONFIG FILE .xls');

82

else

82

else

83

[config_file_path,cname,cext]=fileparts(config_file);

83

[config_file_path,cname,cext]=fileparts(config_file);

84

config_file=[cname cext];

84

config_file=[cname cext];

85

end

85

end

86

if config_file==0

86

if config_file==0

87

% cancel - exit gracefully

87

% cancel - exit gracefully

88

return;

88

return;

89

end

89

end

90

config_file = fullfile(config_file_path, config_file);

90

config_file = fullfile(config_file_path, config_file);

91

end

91

end

92

output_args.config_file = config_file;

92

output_args.config_file = config_file;

93

OP.SAVE_KEYWORD_FILE=0;

93

OP.SAVE_KEYWORD_FILE=0;

94

if OP.SAVE_KEYWORD_FILE

94

if OP.SAVE_KEYWORD_FILE

95

if exist('keyworklog.mat','file')==2

95

if exist('keyworklog.mat','file')==2

96

delete('keyworklog.mat');

96

delete('keyworklog.mat');

97

end

97

end

98

end

98

end

99

[param, OP] = read_ParamConfigFile(config_file,OP);

99

[param, OP] = read_ParamConfigFile(config_file,OP);

100

if OP.CONFIG2MAT_ONLY

100

if OP.CONFIG2MAT_ONLY

101

return;

101

return;

102

end

102

end

103

if isempty(num_fext)

103

if isempty(num_fext)

104

if OP.RX_CALIBRATION

104

if OP.RX_CALIBRATION

105

num_fext=1;

105

num_fext=1;

106

disp('First prompt is for the measured test thru channel and following prompt is for Rx noise path channel')

106

disp('First prompt is for the measured test thru channel and following prompt is for Rx noise path channel')

107

else

107

else

108

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2 % OP.ERL=2 is for package ERL, param.tfx = 1 means fixture time not set and need to be determinind for test fixture channel

108

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2 % OP.ERL=2 is for package ERL, param.tfx = 1 means fixture time not set and need to be determinind for test fixture channel

109

num_fext=1;

109

num_fext=1;

110

disp('First prompt is for the s2p measured data following prompt is for s4p of of the test fixtrure channel')

110

disp('First prompt is for the s2p measured data following prompt is for s4p of of the test fixtrure channel')

111

elseif ~OP.ERL_ONLY

111

elseif ~OP.ERL_ONLY

112

num_fext=input('How many FEXT channels are to be entered? [return means no FEXT] ');

112

num_fext=input('How many FEXT channels are to be entered? [return means no FEXT] ');

113

else

113

else

114

num_fext=0;

114

num_fext=0;

115

end

115

end

116

end

116

end

117

if isempty(num_fext)==1, num_fext=0; end

117

if isempty(num_fext)==1, num_fext=0; end

118

end

118

end

119

if isempty(num_next)

119

if isempty(num_next)

120

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2 % OP.ERL=2 is for package ERL, param.tfx = 1 means fixture time not set and need to be determinind for test fixture channel

120

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2 % OP.ERL=2 is for package ERL, param.tfx = 1 means fixture time not set and need to be determinind for test fixture channel

121

num_next=0;

121

num_next=0;

122

else

122

else

123

if OP.RX_CALIBRATION

123

if OP.RX_CALIBRATION

124

num_next=0;

124

num_next=0;

125

elseif ~OP.ERL_ONLY

125

elseif ~OP.ERL_ONLY

126

num_next=input('How many NEXT channels are to be entered? [return means no NEXT] ');

126

num_next=input('How many NEXT channels are to be entered? [return means no NEXT] ');

127

else

127

else

128

num_next=0;

128

num_next=0;

129

end

129

end

130

end

130

end

131

if isempty(num_next)==1, num_next=0; end

131

if isempty(num_next)==1, num_next=0; end

132

end

132

end

133

% Allow string inputs for running compiled version from OS command-line

133

% Allow string inputs for running compiled version from OS command-line

134

if ischar(num_fext), num_fext=str2double(num_fext); end

134

if ischar(num_fext), num_fext=str2double(num_fext); end

135

if ischar(num_next), num_next=str2double(num_next); end

135

if ischar(num_next), num_next=str2double(num_next); end

136

xtk=num_fext+num_next; % total number of crosstalk aggressors

136

xtk=num_fext+num_next; % total number of crosstalk aggressors

137

param.num_next=num_next;

137

param.num_next=num_next;

138

param.num_fext=num_fext;

138

param.num_fext=num_fext;

139

param.num_s4p_files=num_fext+num_next+1;

139

param.num_s4p_files=num_fext+num_next+1;

140

% checking for data when running for rx compliance BBN calibration

140

% checking for data when running for rx compliance BBN calibration

141

if OP.RX_CALIBRATION == 1

141

if OP.RX_CALIBRATION == 1

142

if num_fext ~=1

142

if num_fext ~=1

143

h = msgbox('One and only noise path channel is required'); set(h,'Color',[1 .85 0]);

143

h = msgbox('One and only noise path channel is required'); set(h,'Color',[1 .85 0]);

144

movegui(h,'northwest')

144

movegui(h,'northwest')

145

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

145

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

146

if OP.DEBUG ~= 1

146

if OP.DEBUG ~= 1

147

return

147

return

148

end

148

end

149

end

149

end

150

h = msgbox('Please make sure the measured "sigma_RJ", A_DD, and SNR_TX" fields in the config xls file have been modified from the Tx measurement. '); set(h,'Color',[0 1 1]);

150

h = msgbox('Please make sure the measured "sigma_RJ", A_DD, and SNR_TX" fields in the config xls file have been modified from the Tx measurement. '); set(h,'Color',[0 1 1]);

151

movegui(h,'southeast')

151

movegui(h,'southeast')

152

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

152

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

153

end

153

end

154

154

155

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2

155

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2

156

if num_fext ~=1

156

if num_fext ~=1

157

h = msgbox('One and only test channel is required'); set(h,'Color',[1 .85 0]);

157

h = msgbox('One and only test channel is required'); set(h,'Color',[1 .85 0]);

158

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

158

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

159

movegui(h,'northwest')

159

movegui(h,'northwest')

160

if OP.DEBUG ~= 1

160

if OP.DEBUG ~= 1

161

return

161

return

162

end

162

end

163

end

163

end

164

h = msgbox('The test fixture file is use to gate measurements '); set(h,'Color',[0 1 1]);

164

h = msgbox('The test fixture file is use to gate measurements '); set(h,'Color',[0 1 1]);

165

movegui(h,'southeast')

165

movegui(h,'southeast')

166

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

166

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

167

end

167

end

168

168

169

169

170

% create result directory if needed

170

% create result directory if needed

171

if ~exist(OP.RESULT_DIR,'dir'); mkdir(OP.RESULT_DIR); end

171

if ~exist(OP.RESULT_DIR,'dir'); mkdir(OP.RESULT_DIR); end

172

% allow finite impulse response input rather that s-parameters with

172

% allow finite impulse response input rather that s-parameters with

173

% OP.EXTERNAL = true. However the use_external_IR function is not provided

173

% OP.EXTERNAL = true. However the use_external_IR function is not provided

174

if ~isempty(varargin) % process case where file names are passed in function call

174

if ~isempty(varargin) % process case where file names are passed in function call

175

if strfind(upper(char(varargin(1))),'EXTERNAL_IR') ~= 0

175

if strfind(upper(char(varargin(1))),'EXTERNAL_IR') ~= 0

176

error('External IR mode is no longer supported');

176

error('External IR mode is no longer supported');

177

%OP.EXTERNAL = true;

177

%OP.EXTERNAL = true;

178

%OP.GET_FD = 0;

178

%OP.GET_FD = 0;

179

%ir1a= varargin(2);

179

%ir1a= varargin(2);

180

%ex_var = varargin(3);

180

%ex_var = varargin(3);

181

%[chdata OP param ] = use_external_IR(param, OP ,num_fext,num_next,0,ir1a,ex_var);

181

%[chdata OP param ] = use_external_IR(param, OP ,num_fext,num_next,0,ir1a,ex_var);

182

else

182

else

183

if OP.TDMODE

183

if OP.TDMODE

184

OP.GET_FD=false;

184

OP.GET_FD=false;

185

end

185

end

186

if length(varargin) < xtk +1 % check that number of varargin arguments passed is at least number of crosstalk files+1 (thru)

186

if length(varargin) < xtk +1 % check that number of varargin arguments passed is at least number of crosstalk files+1 (thru)

187

error('files must include next + fext + a thru');

187

error('files must include next + fext + a thru');

188

end

188

end

189

%% eveluate any extra arguments as possible modifications of parameters

189

%% eveluate any extra arguments as possible modifications of parameters

190

extra_args = varargin(xtk+2:end);

190

extra_args = varargin(xtk+2:end);

191

for k=1:2:floor(length(extra_args)/2)*2

191

for k=1:2:floor(length(extra_args)/2)*2

192

try

192

try

193

orig_value_is_str = 1;

193

orig_value_is_str = 1;

194

orig_value=eval(extra_args{k});

194

orig_value=eval(extra_args{k});

195

if ~ischar(orig_value)

195

if ~ischar(orig_value)

196

orig_value_is_str = 0;

196

orig_value_is_str = 0;

197

orig_value=mat2str(orig_value);

197

orig_value=mat2str(orig_value);

198

end

198

end

199

catch eval_err

199

catch eval_err

200

if isequal(eval_err.identifier, 'MATLAB:nonExistentField')

200

if isequal(eval_err.identifier, 'MATLAB:nonExistentField')

201

% trying to modify a nonexistent parameter - probably a

201

% trying to modify a nonexistent parameter - probably a

202

% typo. save the user from his error.

202

% typo. save the user from his error.

203

error('COM:BadExtraParameter', 'Attempted override of a non-existing parameter %s.', extra_args{k});

203

error('COM:BadExtraParameter', 'Attempted override of a non-existing parameter %s.', extra_args{k});

204

else

204

else

205

% unexpected condition

205

% unexpected condition

206

rethrow(eval_err);

206

rethrow(eval_err);

207

end

207

end

208

end

208

end

209

try

209

try

210

if orig_value_is_str

210

if orig_value_is_str

211

mod_string = sprintf('%s = ''%s'';', extra_args{k}, extra_args{k+1});

211

mod_string = sprintf('%s = ''%s'';', extra_args{k}, extra_args{k+1});

212

else

212

else

213

mod_string = sprintf('%s = %s;', extra_args{k}, extra_args{k+1});

213

mod_string = sprintf('%s = %s;', extra_args{k}, extra_args{k+1});

214

end

214

end

215

eval(mod_string);

215

eval(mod_string);

216

fname=['mod_str' num2str(k)];

216

fname=['mod_str' num2str(k)];

217

% begin yasuo patch 2/11/2018

217

% begin yasuo patch 2/11/2018

218

% output_args.(fname)=mod_string;

218

% output_args.(fname)=mod_string;

219

% If mod_string contains a comma, enclose it by double quotes to avoid misaligned column in the CSV output.

219

% If mod_string contains a comma, enclose it by double quotes to avoid misaligned column in the CSV output.

220

220

221

% re-patch yasuo 3/18/2019

221

% re-patch yasuo 3/18/2019

222

% v2.56 if contains(mod_string,',')

222

% v2.56 if contains(mod_string,',')

223

% v2.57 if isempty(strfind(mod_string,','))

223

% v2.57 if isempty(strfind(mod_string,','))

224

% Here, if-condition was inverted by the change of function from 'contains()' to 'isempty()'.

224

% Here, if-condition was inverted by the change of function from 'contains()' to 'isempty()'.

225

% So, it is changed back by adding an '~' operator.

225

% So, it is changed back by adding an '~' operator.

226

% if isempty(strfind(mod_string,','))

226

% if isempty(strfind(mod_string,','))

227

if ~isempty(strfind(mod_string,','))

227

if ~isempty(strfind(mod_string,','))

228

output_args.(fname)=['"' mod_string '"'];

228

output_args.(fname)=['"' mod_string '"'];

229

else

229

else

230

output_args.(fname)=mod_string;

230

output_args.(fname)=mod_string;

231

end

231

end

232

fprintf('Applied parameter modification: %s (override %s)\n', mod_string, orig_value);

232

fprintf('Applied parameter modification: %s (override %s)\n', mod_string, orig_value);

233

catch eval_err

233

catch eval_err

234

error(eval_err.identifier, 'Error evaluating "%s".', mod_string);

234

error(eval_err.identifier, 'Error evaluating "%s".', mod_string);

235

end

235

end

236

end

236

end

237

end

237

end

238

end

238

end

239

%% Parameters computationally defined by values from the settings files

239

%% Parameters computationally defined by values from the settings files

240

param.ui=1/param.fb;

240

param.ui=1/param.fb;

241

param.sample_dt = param.ui/param.samples_per_ui;

241

param.sample_dt = param.ui/param.samples_per_ui;

242

param.sigma_X=sqrt( (param.levels^2-1)/ (3*(param.levels-1)^2) );

242

param.sigma_X=sqrt( (param.levels^2-1)/ (3*(param.levels-1)^2) );

243

factor_3db=0.473037;

243

factor_3db=0.473037;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

244

param.fb_BT_cutoff=factor_3db*param.f_r;

245

param.fb_BW_cutoff=param.f_r;

245

param.fb_BW_cutoff=param.f_r;

246

param.Tx_rd_sel=1;

246

param.Tx_rd_sel=1;

247

param.Rx_rd_sel=2;

247

param.Rx_rd_sel=2;

248

if isempty(param.snpPortsOrder) || any(isnan(param.snpPortsOrder))

248

if isempty(param.snpPortsOrder) || any(isnan(param.snpPortsOrder))

249

param.snpPortsOrder = [1 3 2 4]; % default order normally used.

249

param.snpPortsOrder = [1 3 2 4]; % default order normally used.

250

end

250

end

251

%% size adjust vector parameters which may be entered as one element

251

%% size adjust vector parameters which may be entered as one element

252

param=parameter_size_adjustment(param,OP);

252

param=parameter_size_adjustment(param,OP);

253

253

254

%% get input models

254

%% get input models

255

param.FLAG.S2P=0;

255

param.FLAG.S2P=0;

256

if OP.TDMODE

256

if OP.TDMODE

257

OP.FIXTURE_CALIBRATION= 0;

257

OP.FIXTURE_CALIBRATION= 0;

258

[chdata, param] = get_TD_files(param, OP, num_fext, num_next, varargin);

258

[chdata, param] = get_TD_files(param, OP, num_fext, num_next, varargin);

259

else

259

else

260

OP.FIXTURE_CALIBRATION= 0;

260

OP.FIXTURE_CALIBRATION= 0;

261

[chdata, param] = get_s4p_files(param, OP, num_fext, num_next, varargin);

261

[chdata, param] = get_s4p_files(param, OP, num_fext, num_next, varargin);

262

if any(strcmpi({chdata.ext},'.s2p'))

262

if any(strcmpi({chdata.ext},'.s2p'))

263

param.FLAG.S2P=1;

263

param.FLAG.S2P=1;

264

end

264

end

265

end

265

end

266

266

267

OP.SAVE_CMD_STR=1;

267

OP.SAVE_CMD_STR=1;

268

if OP.SAVE_CMD_STR

268

if OP.SAVE_CMD_STR

269

cmd_str = save_cmd_line([Remember_keyword ''',''' config_file], chdata, num_fext,num_next,mfilename );

269

cmd_str = save_cmd_line([Remember_keyword ''',''' config_file], chdata, num_fext,num_next,mfilename );

270

setappdata(0,'cmd_str',cmd_str);

270

setappdata(0,'cmd_str',cmd_str);

271

end

271

end

272

%% from here on, multiple package test cases are run. results will be saved separately.

272

%% from here on, multiple package test cases are run. results will be saved separately.

273

results = cell(size(OP.pkg_len_select));

273

results = cell(size(OP.pkg_len_select));

274

COM = inf;

274

COM = inf;

275

min_COM=inf; % reset COM prior to calibration

275

min_COM=inf; % reset COM prior to calibration

276

% min_VEO = inf;

276

% min_VEO = inf;

277

min_VEO_mV = inf;

277

min_VEO_mV = inf;

278

max_VEC_dB = -inf;

278

max_VEC_dB = -inf;

279

threshold_DER=inf;

279

threshold_DER=inf;

280

% begin yasuo patch 3/18/2019

280

% begin yasuo patch 3/18/2019

281

threshold_DER_max = 0; % reset worst DER

281

threshold_DER_max = 0; % reset worst DER

282

% end yasuo patch

282

% end yasuo patch

283

sigma_bn=0;

283

sigma_bn=0;

284

DO_ONCE=true;

284

DO_ONCE=true;

285

low_COM_found = 0;

285

low_COM_found = 0;

286

% at this point only the impulse responses are needed. However vestiges of FD may be intermingled

286

% at this point only the impulse responses are needed. However vestiges of FD may be intermingled

287

while (OP.RX_CALIBRATION==1 || DO_ONCE==true)

287

while (OP.RX_CALIBRATION==1 || DO_ONCE==true)

288

if ~DO_ONCE

288

if ~DO_ONCE

289

if abs(min_COM - param.pass_threshold)<0.1 || (sigma_bn==0 && min_COM < param.pass_threshold)

289

if abs(min_COM - param.pass_threshold)<0.1 || (sigma_bn==0 && min_COM < param.pass_threshold)

290

break;

290

break;

291

elseif min_COM > param.pass_threshold

291

elseif min_COM > param.pass_threshold

292

% increase noise level linearly until low COM found; then perform binary search.

292

% increase noise level linearly until low COM found; then perform binary search.

293

if low_COM_found

293

if low_COM_found

294

if OP.sigma_bn_STEP>0 % previous increase too small

294

if OP.sigma_bn_STEP>0 % previous increase too small

295

OP.sigma_bn_STEP = OP.sigma_bn_STEP/2; % gearshift

295

OP.sigma_bn_STEP = OP.sigma_bn_STEP/2; % gearshift

296

else % previously decrease too large

296

else % previously decrease too large

297

OP.sigma_bn_STEP = -OP.sigma_bn_STEP/2; % gearshift and change direction

297

OP.sigma_bn_STEP = -OP.sigma_bn_STEP/2; % gearshift and change direction

298

end

298

end

299

end

299

end

300

else % binary searchparam.Pkg_len_TX

300

else % binary searchparam.Pkg_len_TX

301

low_COM_found=1;

301

low_COM_found=1;

302

if OP.sigma_bn_STEP>0 % previous increase too large

302

if OP.sigma_bn_STEP>0 % previous increase too large

303

OP.sigma_bn_STEP = -OP.sigma_bn_STEP/2; % gearshift and change direction

303

OP.sigma_bn_STEP = -OP.sigma_bn_STEP/2; % gearshift and change direction

304

else % previously decrease too small

304

else % previously decrease too small

305

OP.sigma_bn_STEP = OP.sigma_bn_STEP/2; % gearshift

305

OP.sigma_bn_STEP = OP.sigma_bn_STEP/2; % gearshift

306

end

306

end

307

end

307

end

308

min_COM = inf; % ignore previous iterations

308

min_COM = inf; % ignore previous iterations

309

min_VEO_mV = inf;

309

min_VEO_mV = inf;

310

max_VEC_dB = -inf;

310

max_VEC_dB = -inf;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

311

sigma_bn = sigma_bn + OP.sigma_bn_STEP;

312

end

312

end

313

msgctr=1;

313

msgctr=1;

314

for package_testcase_i = 1:length(OP.pkg_len_select)

314

for package_testcase_i = 1:length(OP.pkg_len_select)

315

CSV_FILE=sprintf('%s%s_case%d_results.csv', OP.RESULT_DIR, chdata(1).base, package_testcase_i);

315

CSV_FILE=sprintf('%s%s_case%d_results.csv', OP.RESULT_DIR, chdata(1).base, package_testcase_i);

316

package_testcase=OP.pkg_len_select(package_testcase_i);

316

package_testcase=OP.pkg_len_select(package_testcase_i);

317

param.Pkg_len_TX = param.z_p_tx_cases(package_testcase,:);

317

param.Pkg_len_TX = param.z_p_tx_cases(package_testcase,:);

318

param.Pkg_len_NEXT = param.z_p_next_cases(package_testcase,:);

318

param.Pkg_len_NEXT = param.z_p_next_cases(package_testcase,:);

319

param.Pkg_len_FEXT = param.z_p_fext_cases(package_testcase,:);

319

param.Pkg_len_FEXT = param.z_p_fext_cases(package_testcase,:);

320

param.Pkg_len_RX = param.z_p_rx_cases(package_testcase,:);

320

param.Pkg_len_RX = param.z_p_rx_cases(package_testcase,:);

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

321

param.AC_CM_RMS_TX= param.AC_CM_RMS(package_testcase);

322

if param.PKG_Tx_FFE_preset ~=0

322

if param.PKG_Tx_FFE_preset ~=0

323

param.Pkg_TXFFE_preset= param.PKG_Tx_FFE_preset(package_testcase,:);

323

param.Pkg_TXFFE_preset= param.PKG_Tx_FFE_preset(package_testcase,:);

324

else

324

else

325

param.Pkg_TXFFE_preset=0;

325

param.Pkg_TXFFE_preset=0;

326

end

326

end

327

% ki=package_testcase;

327

% ki=package_testcase;

328

% % param.Pkg_Zc=[ param.pkg_Z_c(ki,1); param.pkg_Z_c(ki,2) ];

328

% % param.Pkg_Zc=[ param.pkg_Z_c(ki,1); param.pkg_Z_c(ki,2) ];

329

% param.Pkg_Zc=[ param.pkg_Z_c(ki,:) ];SDDp2p

329

% param.Pkg_Zc=[ param.pkg_Z_c(ki,:) ];SDDp2p

330

param.Pkg_Zc= param.pkg_Z_c;

330

param.Pkg_Zc= param.pkg_Z_c;

331

[cmele,centries] = size(param.Pkg_Zc);

331

[cmele,centries] = size(param.Pkg_Zc);

332

[mele, ncases] = size(param.Pkg_len_TX);

332

[mele, ncases] = size(param.Pkg_len_TX);

333

if cmele ~=1 && centries ~=2 && mele ~= 1

333

if cmele ~=1 && centries ~=2 && mele ~= 1

334

param.Pkg_Zc=reshape(param.Pkg_Zc,2,4);

334

param.Pkg_Zc=reshape(param.Pkg_Zc,2,4);

335

end

335

end

336

param.package_testcase_i = package_testcase_i;

336

param.package_testcase_i = package_testcase_i;

337

337

338

%% Fill in chdata

338

%% Fill in chdata

339

if OP.TDMODE

339

if OP.TDMODE

340

[chdata, param ] = read_PR_files(param, OP, chdata);

340

[chdata, param ] = read_PR_files(param, OP, chdata);

341

[chdata, param, SDDch, SDDp2p ] = TD_FD_fillin(param, OP, chdata); % fill in fd data to keep rest of SW happy

341

[chdata, param, SDDch, SDDp2p ] = TD_FD_fillin(param, OP, chdata); % fill in fd data to keep rest of SW happy

342

else

342

else

343

%fill in chada with s-parameters

343

%fill in chada with s-parameters

344

[chdata, SDDch, SDDp2p ] = read_s4p_files(param, OP, chdata);

344

[chdata, SDDch, SDDp2p ] = read_s4p_files(param, OP, chdata);

345

[chdata, param] = process_sxp(param, OP, chdata, SDDch);

345

[chdata, param] = process_sxp(param, OP, chdata, SDDch);

346

end

346

end

347

if OP.BREAD_CRUMBS

347

if OP.BREAD_CRUMBS

348

output_args.RL.f=chdata(1).faxis; % RIM 07/19/2019 only use the first index

348

output_args.RL.f=chdata(1).faxis; % RIM 07/19/2019 only use the first index

349

output_args.RL.rl1=chdata(1).sdd11_raw; % RIM 07/19/2019 only use the first index

349

output_args.RL.rl1=chdata(1).sdd11_raw; % RIM 07/19/2019 only use the first index

350

if isfield(chdata(1),'sdd22_raw')% RIM 10/15/2019 only use the first index

350

if isfield(chdata(1),'sdd22_raw')% RIM 10/15/2019 only use the first index

351

output_args.RL.r22=chdata(1).sdd22_raw; % RIM 07/19/2019 only use the first index

351

output_args.RL.r22=chdata(1).sdd22_raw; % RIM 07/19/2019 only use the first index

352

end

352

end

353

if isfield(chdata(1),'TX_RL')% RIM 10/09/2020 report Tx RL with RD

353

if isfield(chdata(1),'TX_RL')% RIM 10/09/2020 report Tx RL with RD

354

output_args.RL.TXRL=chdata(1).TX_RL; %R IM 10/09/2020 report Tx RL with RD

354

output_args.RL.TXRL=chdata(1).TX_RL; %R IM 10/09/2020 report Tx RL with RD

355

end

355

end

356

end

356

end

357

if param.FLAG.S2P, OP.ERL_ONLY =1;end

357

if param.FLAG.S2P, OP.ERL_ONLY =1;end

358

358

359

%% Process TDR & ERL

359

%% Process TDR & ERL

360

[output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param);

360

[output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param);

361

if OP.ERL_ONLY

361

if OP.ERL_ONLY

362

results = cell(1);

362

results = cell(1);

363

results{1} = output_args;

363

results{1} = output_args;

364

rt=toc(t0);

364

rt=toc(t0);

365

output_args.rtmin=rt/60;

365

output_args.rtmin=rt/60;

366

if 1

366

if 1

367

fprintf('run time = %g min\n',output_args.rtmin)

367

fprintf('run time = %g min\n',output_args.rtmin)

368

end

368

end

369

if OP.CSV_REPORT ==1

369

if OP.CSV_REPORT ==1

370

Write_CSV(output_args,CSV_FILE);

370

Write_CSV(output_args,CSV_FILE);

371

end

371

end

372

break;

372

break;

373

end

373

end

374

374

375

%% FD processing s-parameter

375

%% FD processing s-parameter

376

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

376

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

377

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

377

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

378

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

378

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

379

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

379

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

380

% at this point sdd21 responses and faxis (frequency) array are defined

380

% at this point sdd21 responses and faxis (frequency) array are defined

381

%most operations now wrapped into FD_Processing function

381

%most operations now wrapped into FD_Processing function

382

param.number_of_s4p_files=length(chdata);

382

param.number_of_s4p_files=length(chdata);

383

%ICN=0;

383

%ICN=0;

384

output_args.ICN_mV=0;

384

output_args.ICN_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

385

output_args.MDNEXT_ICN_92_46_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

386

output_args.MDFEXT_ICN_92_47_mV=0;

387

if OP.WC_PORTZ

387

if OP.WC_PORTZ

388

param.SNR_TX=param.SNDR(param.Tx_rd_sel);

388

param.SNR_TX=param.SNDR(param.Tx_rd_sel);

389

else

389

else

390

param.SNR_TX=param.SNDR(package_testcase);

390

param.SNR_TX=param.SNDR(package_testcase);

391

end

391

end

392

392

393

%TD Mode now also calls FD_Processing but skips the main parts

393

%TD Mode now also calls FD_Processing but skips the main parts

394

[chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE);

394

[chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE);

395

395

396

%% Convert from Frequency Domain to Time Domain

396

%% Convert from Frequency Domain to Time Domain

397

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

397

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

398

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

398

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

399

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

399

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

400

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

400

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

401

if DO_ONCE

401

if DO_ONCE

402

if ~OP.TDMODE

402

if ~OP.TDMODE

403

chdata=COM_FD_to_TD(chdata,param,OP);

403

chdata=COM_FD_to_TD(chdata,param,OP);

404

output_args.VMC_HF_mV=chdata(1).VCM_HF_struct.DCn*1000;

404

output_args.VMC_HF_mV=chdata(1).VCM_HF_struct.DCn*1000;

405

output_args.SCMR_dB=chdata(1).SCMR;

405

output_args.SCMR_dB=chdata(1).SCMR;

406

end

406

end

407

end

407

end

408

408

409

%% Determine equalization settings

409

%% Determine equalization settings

410

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

410

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

411

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

411

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

412

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

412

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

413

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

413

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

414

%---------------------

414

%---------------------

415

do_C2M=0;

415

do_C2M=0;

416

if param.T_O~=0 && param.Min_VEO_Test~=0

416

if param.T_O~=0 && param.Min_VEO_Test~=0

417

do_C2M=1;

417

do_C2M=1;

418

end

418

end

419

OP.COMPUTE_COM=false;

419

OP.COMPUTE_COM=false;

420

fom_result = optimize_fom(OP,param, chdata, sigma_bn,do_C2M);

420

fom_result = optimize_fom(OP,param, chdata, sigma_bn,do_C2M);

421

if fom_result.eq_failed ; return; end % RIM 12-20-2023

421

if fom_result.eq_failed ; return; end % RIM 12-20-2023

422

OP.COMPUTE_COM=true;

422

OP.COMPUTE_COM=true;

423

%% Apply Equalization (returns pulse response with CTLE, TXLE, RXFFE)

423

%% Apply Equalization (returns pulse response with CTLE, TXLE, RXFFE)

424

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

424

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

425

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

425

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

426

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

426

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

427

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

427

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

428

428

429

A_s=abs(fom_result.A_s); % this is the "s" in SNR (PAM4 gain in handled in last sections

429

A_s=abs(fom_result.A_s); % this is the "s" in SNR (PAM4 gain in handled in last sections

430

param.use_bmax=fom_result.best_bmax.';

430

param.use_bmax=fom_result.best_bmax.';

431

%AJG021820

431

%AJG021820

432

param.use_bmin=fom_result.best_bmin.';

432

param.use_bmin=fom_result.best_bmin.';

433

% Recommended Delta_y no larger than As/1000 or 0.01 mV

433

% Recommended Delta_y no larger than As/1000 or 0.01 mV

434

param.current_ffegain=fom_result.best_current_ffegain;

434

param.current_ffegain=fom_result.best_current_ffegain;

435

if OP.force_pdf_bin_size

435

if OP.force_pdf_bin_size

436

param.delta_y = OP.BinSize;

436

param.delta_y = OP.BinSize;

437

else

437

else

438

param.delta_y = min(A_s/1000, OP.BinSize);

438

param.delta_y = min(A_s/1000, OP.BinSize);

439

end

439

end

440

% the pdf for PAM4 uses the full swing SBR but assigns voltage for the PDF accordingly

440

% the pdf for PAM4 uses the full swing SBR but assigns voltage for the PDF accordingly

441

if OP.RX_CALIBRATION, param.number_of_s4p_files=1; end

441

if OP.RX_CALIBRATION, param.number_of_s4p_files=1; end

442

442

443

chdata=Apply_EQ(param,fom_result,chdata,OP);

443

chdata=Apply_EQ(param,fom_result,chdata,OP);

444

PSD_results=[]; % need to define because passed to Create_Noise_PDF for backward compatability

444

PSD_results=[]; % need to define because passed to Create_Noise_PDF for backward compatability

445

if (strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

445

if (strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

446

OP.WO_TXFFE=1;

446

OP.WO_TXFFE=1;

447

PSD_results.w=fom_result.RxFFE;

447

PSD_results.w=fom_result.RxFFE;

448

% chdata(1).eq_pulse_response includes rx FFE from Apply_EQ as

448

% chdata(1).eq_pulse_response includes rx FFE from Apply_EQ as

449

% well as CTLE (CTF) and tx FFE

449

% well as CTLE (CTF) and tx FFE

450

PSD_results.S_rn=fom_result.PSD_results.S_rn; % get_PSDs will adjust S_rn for Rxffe

450

PSD_results.S_rn=fom_result.PSD_results.S_rn; % get_PSDs will adjust S_rn for Rxffe

451

PSD_results = get_PSDs(PSD_results,chdata(1).eq_pulse_response,fom_result.t_s, fom_result.txffe,param.ctle_gdc_values(fom_result.ctle),param.g_DC_HP_values(fom_result.best_G_high_pass),param,chdata,OP);

451

PSD_results = get_PSDs(PSD_results,chdata(1).eq_pulse_response,fom_result.t_s, fom_result.txffe,param.ctle_gdc_values(fom_result.ctle),param.g_DC_HP_values(fom_result.best_G_high_pass),param,chdata,OP);

452

OP.WO_TXFFE=0;

452

OP.WO_TXFFE=0;

453

PSD_results.S_xn=fom_result.PSD_results.S_xn; % get_PSDs will adjust S_xn for Rxffe

453

PSD_results.S_xn=fom_result.PSD_results.S_xn; % get_PSDs will adjust S_xn for Rxffe

454

PSD_results.S_tn=fom_result.PSD_results.S_tn; % get_PSDs will adjust S_tn for Rxffe

454

PSD_results.S_tn=fom_result.PSD_results.S_tn; % get_PSDs will adjust S_tn for Rxffe

455

PSD_results.S_jn =fom_result.PSD_results.S_jn; % get_PSDs will adjust S_jn for Rxffe

455

PSD_results.S_jn =fom_result.PSD_results.S_jn; % get_PSDs will adjust S_jn for Rxffe

456

PSD_results.S_rj_jn = fom_result.PSD_results.S_rj_jn;% get_PSDs will adjust S_rj_jn for Rxffe

456

PSD_results.S_rj_jn = fom_result.PSD_results.S_rj_jn;% get_PSDs will adjust S_rj_jn for Rxffe

457

PSD_results = get_PSDs(PSD_results,chdata(1).eq_pulse_response,fom_result.t_s, fom_result.txffe,param.ctle_gdc_values(fom_result.ctle),param.g_DC_HP_values(fom_result.best_G_high_pass),param,chdata,OP);

457

PSD_results = get_PSDs(PSD_results,chdata(1).eq_pulse_response,fom_result.t_s, fom_result.txffe,param.ctle_gdc_values(fom_result.ctle),param.g_DC_HP_values(fom_result.best_G_high_pass),param,chdata,OP);

458

output_args.noiseRMS_mV.rn=PSD_results.S_rn_rms*1000;

458

output_args.noiseRMS_mV.rn=PSD_results.S_rn_rms*1000;

459

output_args.noiseRMS_mV.tn=PSD_results.S_tn_rms*1000;

459

output_args.noiseRMS_mV.tn=PSD_results.S_tn_rms*1000;

460

output_args.noiseRMS_mV.xn=PSD_results.S_xn_rms*1000;

460

output_args.noiseRMS_mV.xn=PSD_results.S_xn_rms*1000;

461

output_args.noiseRMS_mV.tn=PSD_results.S_tn_rms*1000;

461

output_args.noiseRMS_mV.tn=PSD_results.S_tn_rms*1000;

462

output_args.noiseRMS_mV.jn=PSD_results.S_jn_rms*1000;

462

output_args.noiseRMS_mV.jn=PSD_results.S_jn_rms*1000;

463

end

463

end

464

%% Create ISI PDF & Individual Crosstalk PDFs

464

%% Create ISI PDF & Individual Crosstalk PDFs

465

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

465

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

466

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

466

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

467

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

467

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

468

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

468

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

469

if ~OP.DISPLAY_WINDOW, fprintf('processing COM PDF '); end

469

if ~OP.DISPLAY_WINDOW, fprintf('processing COM PDF '); end

470

for i=1:param.number_of_s4p_files

470

for i=1:param.number_of_s4p_files

471

if ~OP.DISPLAY_WINDOW, fprintf('%d ', i); end

471

if ~OP.DISPLAY_WINDOW, fprintf('%d ', i); end

472

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

472

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

473

473

474

pdf = get_pdf(chdata(i), param.delta_y, fom_result.t_s, param, OP,fom_result.PSD_results.iphase(i)) ;

474

pdf = get_pdf(chdata(i), param.delta_y, fom_result.t_s, param, OP,fom_result.PSD_results.iphase(i)) ;

475

else

475

else

476

pdf = get_pdf(chdata(i), param.delta_y, fom_result.t_s, param, OP,[]);

476

pdf = get_pdf(chdata(i), param.delta_y, fom_result.t_s, param, OP,[]);

477

end

477

end

478

if OP.DEBUG && OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

478

if OP.DEBUG && OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

479

figure(150+package_testcase_i);set(gcf,'Tag','COM');

479

figure(150+package_testcase_i);set(gcf,'Tag','COM');

480

subplot(2,1,2);

480

subplot(2,1,2);

481

pdf0.x=pdf.x(pdf.y~=0);

481

pdf0.x=pdf.x(pdf.y~=0);

482

pdf0.y=pdf.y(pdf.y~=0);

482

pdf0.y=pdf.y(pdf.y~=0);

483

semilogy(pdf0.x, pdf0.y,'disp', chdata(i).base);

483

semilogy(pdf0.x, pdf0.y,'disp', chdata(i).base);

484

current_ylim=ylim; ylim([param.specBER/100, current_ylim(2)]);

484

current_ylim=ylim; ylim([param.specBER/100, current_ylim(2)]);

485

hold on; title('PDF')

485

hold on; title('PDF')

486

recolor_plots(gca);

486

recolor_plots(gca);

487

end

487

end

488

488

489

chdata(i).pdfr=pdf;

489

chdata(i).pdfr=pdf;

490

% reporting

490

% reporting

491

a=find(cumsum(chdata(i).pdfr.y) >1e-12,1,'first');

491

a=find(cumsum(chdata(i).pdfr.y) >1e-12,1,'first');

492

chdata(i).maxquickpdf=(chdata(i).pdfr.y(a));

492

chdata(i).maxquickpdf=(chdata(i).pdfr.y(a));

493

493

494

end

494

end

495

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

495

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

496

496

497

%% Return final PDF & CDF and Package all noise parameters in Noise_Struct

497

%% Return final PDF & CDF and Package all noise parameters in Noise_Struct

498

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

498

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

499

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

499

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

500

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

500

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

501

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

501

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

502

[PDF,CDF,Noise_Struct]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results);

502

[PDF,CDF,Noise_Struct]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results);

503

combined_interference_and_noise_pdf=PDF;

503

combined_interference_and_noise_pdf=PDF;

504

combined_interference_and_noise_cdf=CDF;

504

combined_interference_and_noise_cdf=CDF;

505

505

506

506

507

%% Calculate COM and other associated outputs

507

%% Calculate COM and other associated outputs

508

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

508

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

509

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

509

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

510

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

510

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

511

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

511

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

512

% The noise and interference amplitude, A_ni, is the magnitude of the value of y0

512

% The noise and interference amplitude, A_ni, is the magnitude of the value of y0

513

% that satisfies the relationship P(y0) = DER_0

513

% that satisfies the relationship P(y0) = DER_0

514

A_ni_ix=find(combined_interference_and_noise_cdf>param.specBER, 1, 'first');

514

A_ni_ix=find(combined_interference_and_noise_cdf>param.specBER, 1, 'first');

515

A_ni = abs(combined_interference_and_noise_pdf.x(A_ni_ix));

515

A_ni = abs(combined_interference_and_noise_pdf.x(A_ni_ix));

516

516

517

% begin yasuo patch 3/18/2019

517

% begin yasuo patch 3/18/2019

518

% estimate DER at threshold COM

518

% estimate DER at threshold COM

519

threshold_ix=find(combined_interference_and_noise_pdf.x>-A_s/(10^(param.pass_threshold/20)),1);

519

threshold_ix=find(combined_interference_and_noise_pdf.x>-A_s/(10^(param.pass_threshold/20)),1);

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

522

% end yasuo patch

522

% end yasuo patch

523

523

524

if OP.RX_CALIBRATION ==0 && OP.EW == 1

524

if OP.RX_CALIBRATION ==0 && OP.EW == 1

525

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,param.delta_y,fom_result,param,OP,Noise_Struct,0);

525

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,param.delta_y,fom_result,param,OP,Noise_Struct,0);

526

EW_UI=floor((Left_EW+Right_EW))/param.samples_for_C2M;

526

EW_UI=floor((Left_EW+Right_EW))/param.samples_for_C2M;

527

if OP.DISPLAY_WINDOW && OP.DEBUG

527

if OP.DISPLAY_WINDOW && OP.DEBUG

528

figure_name = 'Eye at DER0 estimate';

528

figure_name = 'Eye at DER0 estimate';

529

fig=findobj('Name', figure_name);

529

fig=findobj('Name', figure_name);

530

if isempty(fig), fig=figure('Name', figure_name); end

530

if isempty(fig), fig=figure('Name', figure_name); end

531

figure(fig);set(gcf,'Tag','COM');

531

figure(fig);set(gcf,'Tag','COM');

532

movegui(fig,'southwest')

532

movegui(fig,'southwest')

533

plot(eye_contour)

533

plot(eye_contour)

534

xlabel('UI %')

534

xlabel('UI %')

535

ylabel('V')

535

ylabel('V')

536

end

536

end

537

537

538

else

538

else

539

EW_UI=0;

539

EW_UI=0;

540

eye_contour=[];

540

eye_contour=[];

541

end

541

end

542

if OP.MLSE==0

542

if OP.MLSE==0

543

if param.T_O ~=0

543

if param.T_O ~=0

544

eye_opening=EH_T_C2M-EH_B_C2M;

544

eye_opening=EH_T_C2M-EH_B_C2M;

545

A_ni=2*A_s-eye_opening;

545

A_ni=2*A_s-eye_opening;

546

%eq 124E-4

546

%eq 124E-4

547

vec_arg=2*A_s/eye_opening;

547

vec_arg=2*A_s/eye_opening;

548

if vec_arg<eps

548

if vec_arg<eps

549

vec_arg=eps;

549

vec_arg=eps;

550

end

550

end

551

VEC_dB = 20*log10(vec_arg);

551

VEC_dB = 20*log10(vec_arg);

552

COM=20*log10(2*A_s/A_ni);

552

COM=20*log10(2*A_s/A_ni);

553

VEO_mV=eye_opening*1000;

553

VEO_mV=eye_opening*1000;

554

min_COM = min(min_COM, COM);

554

min_COM = min(min_COM, COM);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

557

else

557

else

558

VEO_mV = 1000*(A_s-A_ni)*2;

558

VEO_mV = 1000*(A_s-A_ni)*2;

559

vec_arg=(A_s-A_ni)/A_s;

559

vec_arg=(A_s-A_ni)/A_s;

560

if vec_arg<eps

560

if vec_arg<eps

561

vec_arg=eps;

561

vec_arg=eps;

562

end

562

end

563

VEC_dB = -20*log10(vec_arg);

563

VEC_dB = -20*log10(vec_arg);

564

COM=20*log10(A_s/A_ni);

564

COM=20*log10(A_s/A_ni);

565

min_COM = min(min_COM, COM);

565

min_COM = min(min_COM, COM);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

568

end

568

end

569

MLSE_results=struct;

569

MLSE_results=struct;

570

else % MLSE case added U3 option

570

else % MLSE case added U3 option

571

if OP.MLSE==1

571

if OP.MLSE==1

572

[MLSE_results] = MLSE(param,fom_result.DFE_taps(1),A_s,A_ni,PDF,CDF);

572

[MLSE_results] = MLSE(param,fom_result.DFE_taps(1),A_s,A_ni,PDF,CDF);

573

elseif OP.MLSE==2

573

elseif OP.MLSE==2

574

[MLSE_results] = MLSE_instu(param,fom_result.DFE_taps(1),A_s,A_ni,PDF,CDF);

574

[MLSE_results] = MLSE_instu(param,fom_result.DFE_taps(1),A_s,A_ni,PDF,CDF);

575

elseif OP.MLSE==3

575

elseif OP.MLSE==3

576

[MLSE_results] = MLSE_U1_c(param,fom_result.DFE_taps(1),A_s,A_ni,PDF,CDF,PSD_results);

576

[MLSE_results] = MLSE_U1_c(param,fom_result.DFE_taps(1),A_s,A_ni,PDF,CDF,PSD_results);

577

else

577

else

578

warning('unsuported MLSE option')

578

warning('unsuported MLSE option')

579

end

579

end

580

if param.T_O ~=0

580

if param.T_O ~=0

581

eye_opening=EH_T_C2M-EH_B_C2M;

581

eye_opening=EH_T_C2M-EH_B_C2M;

582

A_ni=2*A_s-eye_opening;

582

A_ni=2*A_s-eye_opening;

583

%eq 124E-4

583

%eq 124E-4

584

vec_arg=2*A_s/eye_opening;

584

vec_arg=2*A_s/eye_opening;

585

if vec_arg<eps

585

if vec_arg<eps

586

vec_arg=eps;

586

vec_arg=eps;

587

end

587

end

588

VEC_dB_orig = 20*log10(vec_arg); % was negative in 400 beta1 ... Fixed 2-2-23

588

VEC_dB_orig = 20*log10(vec_arg); % was negative in 400 beta1 ... Fixed 2-2-23

589

VEC_dB=MLSE_results.delta_com_CDF-20*log10( (10^(MLSE_results.delta_com_CDF/20)-1)*10^(VEC_dB_orig/20)+1)+VEC_dB_orig;

589

VEC_dB=MLSE_results.delta_com_CDF-20*log10( (10^(MLSE_results.delta_com_CDF/20)-1)*10^(VEC_dB_orig/20)+1)+VEC_dB_orig;

590

COM_orig=20*log10(2*A_s/A_ni);

590

COM_orig=20*log10(2*A_s/A_ni);

591

COM=MLSE_results.COM_CDF;

591

COM=MLSE_results.COM_CDF;

592

VEO_mV=eye_opening*1000;

592

VEO_mV=eye_opening*1000;

593

min_COM = min(min_COM, COM);

593

min_COM = min(min_COM, COM);

594

min_VEO_mV = min(min_VEO_mV,VEO_mV);

594

min_VEO_mV = min(min_VEO_mV,VEO_mV);

595

max_VEC_dB = max(max_VEC_dB, VEC_dB);

595

max_VEC_dB = max(max_VEC_dB, VEC_dB);

596

output_args.delta_COM=MLSE_results.delta_com_CDF;

596

output_args.delta_COM=MLSE_results.delta_com_CDF;

597

output_args.delta_VEC=MLSE_results.delta_com_CDF-20*log10( (10^(MLSE_results.delta_com_CDF/20)-1)*10^(VEC_dB_orig/20)+1);

597

output_args.delta_VEC=MLSE_results.delta_com_CDF-20*log10( (10^(MLSE_results.delta_com_CDF/20)-1)*10^(VEC_dB_orig/20)+1);

598

else

598

else

599

VEO_mV = 1000*(A_s-A_ni)*2;

599

VEO_mV = 1000*(A_s-A_ni)*2;

600

vec_arg=(A_s-A_ni)/A_s;

600

vec_arg=(A_s-A_ni)/A_s;

601

if vec_arg<eps

601

if vec_arg<eps

602

vec_arg=eps;

602

vec_arg=eps;

603

end

603

end

604

VEC_dB_orig = -20*log10(vec_arg);

604

VEC_dB_orig = -20*log10(vec_arg);

605

VEC_dB=MLSE_results.delta_com_CDF-20*log10( (10^(MLSE_results.delta_com_CDF/20)-1)*10^(VEC_dB_orig/20)+1)+VEC_dB_orig;

605

VEC_dB=MLSE_results.delta_com_CDF-20*log10( (10^(MLSE_results.delta_com_CDF/20)-1)*10^(VEC_dB_orig/20)+1)+VEC_dB_orig;

606

COM_orig=20*log10(A_s/A_ni);

606

COM_orig=20*log10(A_s/A_ni);

607

COM=MLSE_results.COM_CDF;

607

COM=MLSE_results.COM_CDF;

608

min_COM = min(min_COM, COM);

608

min_COM = min(min_COM, COM);

609

min_VEO_mV = min(min_VEO_mV,VEO_mV);

609

min_VEO_mV = min(min_VEO_mV,VEO_mV);

610

max_VEC_dB = max(max_VEC_dB, VEC_dB);

610

max_VEC_dB = max(max_VEC_dB, VEC_dB);

611

output_args.delta_COM=MLSE_results.delta_com_CDF;

611

output_args.delta_COM=MLSE_results.delta_com_CDF;

612

end

612

end

613

end

613

end

614

614

615

%% Create COM_SNR_Struct to hold the main COM outputs

615

%% Create COM_SNR_Struct to hold the main COM outputs

616

COM_SNR_Struct.A_s=A_s;

616

COM_SNR_Struct.A_s=A_s;

617

COM_SNR_Struct.A_ni=A_ni;

617

COM_SNR_Struct.A_ni=A_ni;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

618

COM_SNR_Struct.threshold_DER=threshold_DER;

619

COM_SNR_Struct.EW_UI=EW_UI;

619

COM_SNR_Struct.EW_UI=EW_UI;

620

COM_SNR_Struct.COM=COM;

620

COM_SNR_Struct.COM=COM;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

621

COM_SNR_Struct.VEC_dB=VEC_dB;

622

if OP.MLSE == 0

622

if OP.MLSE == 0

623

COM_SNR_Struct.COM_orig=[];

623

COM_SNR_Struct.COM_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

624

COM_SNR_Struct.VEC_dB_orig=[];

625

else

625

else

626

COM_SNR_Struct.COM_orig=COM_orig;

626

COM_SNR_Struct.COM_orig=COM_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

627

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

628

end

628

end

629

COM_SNR_Struct.VEO_mV=VEO_mV;

629

COM_SNR_Struct.VEO_mV=VEO_mV;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

630

COM_SNR_Struct.combined_interference_and_noise_pdf=combined_interference_and_noise_pdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

631

COM_SNR_Struct.combined_interference_and_noise_cdf=combined_interference_and_noise_cdf;

632

COM_SNR_Struct.eye_contour=eye_contour;

632

COM_SNR_Struct.eye_contour=eye_contour;

633

633

634

634

635

%% Save TD

635

%% Save TD

636

if OP.SAVE_TD

636

if OP.SAVE_TD

637

sbr=timeseries(fom_result.sbr,fom_result.t);

637

sbr=timeseries(fom_result.sbr,fom_result.t);

638

if ~OP.TDMODE

638

if ~OP.TDMODE

639

fir=timeseries(fom_result.IR,fom_result.t);

639

fir=timeseries(fom_result.IR,fom_result.t);

640

end

640

end

641

for i=1:param.number_of_s4p_files

641

for i=1:param.number_of_s4p_files

642

Pulses(i).uneq_responce= timeseries(chdata(i).uneq_pulse_response, chdata(i).t );

642

Pulses(i).uneq_responce= timeseries(chdata(i).uneq_pulse_response, chdata(i).t );

643

Pulses(i).eq_responce= timeseries(chdata(i).eq_pulse_response, chdata(i).t );

643

Pulses(i).eq_responce= timeseries(chdata(i).eq_pulse_response, chdata(i).t );

644

if ~OP.TDMODE

644

if ~OP.TDMODE

645

FIR(i).uneq_imp_response= timeseries(chdata(i).uneq_imp_response, chdata(i).t );

645

FIR(i).uneq_imp_response= timeseries(chdata(i).uneq_imp_response, chdata(i).t );

646

FIR(i).eq_imp_response= timeseries(chdata(i).eq_imp_response, chdata(i).t );

646

FIR(i).eq_imp_response= timeseries(chdata(i).eq_imp_response, chdata(i).t );

647

end

647

end

648

end

648

end

649

if OP.TDMODE

649

if OP.TDMODE

650

save( [OP.RESULT_DIR 'sbr_fir_' param.base '.mat'],'sbr','Pulses');

650

save( [OP.RESULT_DIR 'sbr_fir_' param.base '.mat'],'sbr','Pulses');

651

else

651

else

652

save( [OP.RESULT_DIR 'sbr_fir_' param.base '.mat'],'sbr','fir','Pulses','FIR')

652

save( [OP.RESULT_DIR 'sbr_fir_' param.base '.mat'],'sbr','fir','Pulses','FIR')

653

end

653

end

654

end

654

end

655

655

656

%% Bathtub/Contribution Plot

656

%% Bathtub/Contribution Plot

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

657

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

658

Bathtub_Contribution_Wrapper(COM_SNR_Struct,Noise_Struct,param,chdata,OP);

658

Bathtub_Contribution_Wrapper(COM_SNR_Struct,Noise_Struct,param,chdata,OP);

659

end

659

end

660

660

661

%% Msg management

661

%% Msg management

662

if ~exist('msg','var')

662

if ~exist('msg','var')

663

msg=[];

663

msg=[];

664

end

664

end

665

if OP.DEBUG

665

if OP.DEBUG

666

[ncases, mele]=size(param.z_p_tx_cases);

666

[ncases, mele]=size(param.z_p_tx_cases);

667

switch param.flex

667

switch param.flex

668

case 4

668

case 4

669

msg = sprintf('%s: Case %g: z_p=(%g:%g:%g:%g, %g:%g:%g:%g, %g:%g:%g:%g, %g:%g:%g:%g) (TX, RX, NEXT, FEXT):\n', ...

669

msg = sprintf('%s: Case %g: z_p=(%g:%g:%g:%g, %g:%g:%g:%g, %g:%g:%g:%g, %g:%g:%g:%g) (TX, RX, NEXT, FEXT):\n', ...

670

msg,package_testcase_i, param.Pkg_len_TX, param.Pkg_len_RX, param.Pkg_len_NEXT, param.Pkg_len_FEXT ...

670

msg,package_testcase_i, param.Pkg_len_TX, param.Pkg_len_RX, param.Pkg_len_NEXT, param.Pkg_len_FEXT ...

671

);

671

);

672

case 2

672

case 2

673

msg = sprintf('%s: Case %g: z_p=(%g:%g, %g:%g, %g:%g, %g:%g) (TX, RX, NEXT, FEXT):\n', ...

673

msg = sprintf('%s: Case %g: z_p=(%g:%g, %g:%g, %g:%g, %g:%g) (TX, RX, NEXT, FEXT):\n', ...

674

msg,package_testcase_i, param.Pkg_len_TX(1:2), param.Pkg_len_RX(1:2), param.Pkg_len_NEXT(1:2), param.Pkg_len_FEXT(1:2) ...

674

msg,package_testcase_i, param.Pkg_len_TX(1:2), param.Pkg_len_RX(1:2), param.Pkg_len_NEXT(1:2), param.Pkg_len_FEXT(1:2) ...

675

);

675

);

676

otherwise

676

otherwise

677

msg = sprintf('%s: Case %g: z_p=(%g, %g, %g, %g) (TX, RX, NEXT, FEXT):', ...

677

msg = sprintf('%s: Case %g: z_p=(%g, %g, %g, %g) (TX, RX, NEXT, FEXT):', ...

678

msg, package_testcase_i, param.Pkg_len_TX, param.Pkg_len_RX, param.Pkg_len_NEXT, param.Pkg_len_FEXT ...

678

msg, package_testcase_i, param.Pkg_len_TX, param.Pkg_len_RX, param.Pkg_len_NEXT, param.Pkg_len_FEXT ...

679

);

679

);

680

680

681

end

681

end

682

else

682

else

683

msg = sprintf('Case %d:', package_testcase_i );

683

msg = sprintf('Case %d:', package_testcase_i );

684

end

684

end

685

685

686

if OP.TDMODE

686

if OP.TDMODE

687

min_ERL=inf;

687

min_ERL=inf;

688

ERL=[inf inf];

688

ERL=[inf inf];

689

end

689

end

690

[msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL, VEO_mV,VEC_dB,threshold_DER,OP.DISPLAY_WINDOW); % {} forces no ERL print

690

[msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL, VEO_mV,VEC_dB,threshold_DER,OP.DISPLAY_WINDOW); % {} forces no ERL print

691

691

692

692

693

%% Output Args

693

%% Output Args

694

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

694

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

695

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

695

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

696

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

696

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

697

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

697

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

698

output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP);

698

output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP);

699

rt=toc(t0);

699

rt=toc(t0);

700

output_args.rtmin=rt/60;

700

output_args.rtmin=rt/60;

701

701

702

if OP.BREAD_CRUMBS

702

if OP.BREAD_CRUMBS

703

output_args.OP=OP;

703

output_args.OP=OP;

704

output_args.param=param;

704

output_args.param=param;

705

output_args.chdata=chdata;

705

output_args.chdata=chdata;

706

output_args.fom_result = fom_result;

706

output_args.fom_result = fom_result;

707

output_args.PDF=PDF; % for exploration

707

output_args.PDF=PDF; % for exploration

708

output_args.CDF=CDF; % for exploration

708

output_args.CDF=CDF; % for exploration

709

output_args.MLSE_results=MLSE_results;

709

output_args.MLSE_results=MLSE_results;

710

output_args.PSD_results=PSD_results;

710

output_args.PSD_results=PSD_results;

711

end

711

end

712

% results{package_testcase_i} = output_args;% moved RIM 04-14-2023

712

% results{package_testcase_i} = output_args;% moved RIM 04-14-2023

713

713

714

%% making csv file

714

%% making csv file

715

if OP.CSV_REPORT ==1

715

if OP.CSV_REPORT ==1

716

Write_CSV(output_args,CSV_FILE);

716

Write_CSV(output_args,CSV_FILE);

717

end

717

end

718

%% making mat file

718

%% making mat file

719

if(OP.DEBUG)

719

if(OP.DEBUG)

720

save (sprintf('%s%s_case%d_results.mat', OP.RESULT_DIR, chdata(1).base, package_testcase_i), ...

720

save (sprintf('%s%s_case%d_results.mat', OP.RESULT_DIR, chdata(1).base, package_testcase_i), ...

721

'output_args','param','OP');

721

'output_args','param','OP');

722

end

722

end

723

if 1

723

if 1

724

fprintf(' Die to die loss = %g dB \n',output_args.IL_db_die_to_die_at_Fnq)

724

fprintf(' Die to die loss = %g dB \n',output_args.IL_db_die_to_die_at_Fnq)

725

fprintf('run time = %g min \n',output_args.rtmin)

725

fprintf('run time = %g min \n',output_args.rtmin)

726

end

726

end

727

727

728

if nargout==0

728

if nargout==0

729

fprintf('<strong>--- Testcase %d results ---</strong>\n', package_testcase_i);

729

fprintf('<strong>--- Testcase %d results ---</strong>\n', package_testcase_i);

730

disp(output_args)

730

disp(output_args)

731

end

731

end

732

732

733

if OP.BREAD_CRUMBS

733

if OP.BREAD_CRUMBS

734

[my_path,rootname]=fileparts(chdata(1).filename);

734

[my_path,rootname]=fileparts(chdata(1).filename);

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

736

%Attempt to reduce the size of output_args.chdata by removing certain fields

736

%Attempt to reduce the size of output_args.chdata by removing certain fields

737

try

737

try

738

output_args.chdata=Bread_Crumb_Chdata_Reduction(output_args.chdata,OP.BREAD_CRUMBS_FIELDS);

738

output_args.chdata=Bread_Crumb_Chdata_Reduction(output_args.chdata,OP.BREAD_CRUMBS_FIELDS);

739

catch

739

catch

740

fprintf('Failed to reduce output_args.chdata\n');

740

fprintf('Failed to reduce output_args.chdata\n');

741

end

741

end

742

end

742

end

743

save (sprintf('%s%s_case%d_results.mat', OP.RESULT_DIR, rootname, package_testcase), ...

743

save (sprintf('%s%s_case%d_results.mat', OP.RESULT_DIR, rootname, package_testcase), ...

744

'output_args','param','OP');

744

'output_args','param','OP');

745

end

745

end

746

746

747

results{package_testcase_i} = output_args; % moved to after chdata field reduction RIM 04-14-2023

747

results{package_testcase_i} = output_args; % moved to after chdata field reduction RIM 04-14-2023

748

end

748

end

749

[tmp] = end_display_control('WC All cases',param,OP,output_args,min_COM,min_ERL,ERL,min_VEO_mV,max_VEC_dB,threshold_DER,0);

749

[tmp] = end_display_control('WC All cases',param,OP,output_args,min_COM,min_ERL,ERL,min_VEO_mV,max_VEC_dB,threshold_DER,0);

750

%%

750

%%

751

751

752

if OP.RX_CALIBRATION ==1

752

if OP.RX_CALIBRATION ==1

753

sigma_hp= Noise_Struct.sigma_hp; % added for clause 162 else sigma_bn = sigma_hp (RIM 09-30-2022)

753

sigma_hp= Noise_Struct.sigma_hp; % added for clause 162 else sigma_bn = sigma_hp (RIM 09-30-2022)

754

display ([' LOOP with [sigma_bn sigma_hp] = [' num2str(sigma_bn) ' ' num2str(sigma_hp) '] performed with COM = ' num2str(min_COM) ])

754

display ([' LOOP with [sigma_bn sigma_hp] = [' num2str(sigma_bn) ' ' num2str(sigma_hp) '] performed with COM = ' num2str(min_COM) ])

755

end

755

end

756

DO_ONCE=false;

756

DO_ONCE=false;

757

end

757

end

758

758

759

%% Final cleanup

759

%% Final cleanup

760

if OP.DISPLAY_WINDOW

760

if OP.DISPLAY_WINDOW

761

savefigs(param, OP);

761

savefigs(param, OP);

762

set(0,'defaulttextinterpreter','tex'); % reset defaut text interpreter to tex

762

set(0,'defaulttextinterpreter','tex'); % reset defaut text interpreter to tex

763

end

763

end

764

764

765

if OP.RX_CALIBRATION==1 % updated for clause 162 else sigma_bn = sigma_hp (RIM 09-30-2022)

765

if OP.RX_CALIBRATION==1 % updated for clause 162 else sigma_bn = sigma_hp (RIM 09-30-2022)

766

if ~param.f_hp==0

766

if ~param.f_hp==0

767

fprintf ('Set Tx calibration noise(sigma_hp) rms voltage to %g mV\n', sigma_hp*1000);

767

fprintf ('Set Tx calibration noise(sigma_hp) rms voltage to %g mV\n', sigma_hp*1000);

768

if OP.DISPLAY_WINDOW

768

if OP.DISPLAY_WINDOW

769

message=sprintf('Set Tx calibration noise (sigma_hp) rms voltage to %g mV.',sigma_hp*1000);

769

message=sprintf('Set Tx calibration noise (sigma_hp) rms voltage to %g mV.',sigma_hp*1000);

770

hlast = msgbox(message,'sigma_hp','help');

770

hlast = msgbox(message,'sigma_hp','help');

771

set(hlast,'Color','y', 'tag', 'COM');

771

set(hlast,'Color','y', 'tag', 'COM');

772

end

772

end

773

else

773

else

774

fprintf ('Set calibration noise (sigma_bn)rms voltage to %g mV\n', sigma_bn*1000);

774

fprintf ('Set calibration noise (sigma_bn)rms voltage to %g mV\n', sigma_bn*1000);

775

if OP.DISPLAY_WINDOW

775

if OP.DISPLAY_WINDOW

776

message=sprintf('Set calibration noise rms (sigma_bn) voltage to %g mV.',sigma_bn*1000);

776

message=sprintf('Set calibration noise rms (sigma_bn) voltage to %g mV.',sigma_bn*1000);

777

hlast = msgbox(message,'sigma_bn','help');

777

hlast = msgbox(message,'sigma_bn','help');

778

set(hlast,'Color','y', 'tag', 'COM');

778

set(hlast,'Color','y', 'tag', 'COM');

779

end

779

end

780

end

780

end

781

end

781

end

782

782

783

if length(results)==1, results = results{1}; end

783

if length(results)==1, results = results{1}; end

784

redo_cmd_str=' redo string is: eval([''My_var_0 = '' getappdata(0,''cmd_str'')])';

784

redo_cmd_str=' redo string is: eval([''My_var_0 = '' getappdata(0,''cmd_str'')])';

785

disp(redo_cmd_str);

785

disp(redo_cmd_str);

786

if isdeployed

786

if isdeployed

787

if OP.exit_if_deployed

787

if OP.exit_if_deployed

788

quit

788

quit

789

end

789

end

790

end

790

end

791

%%

791

%%

792

%--------------------------------------------------------------------------

792

%--------------------------------------------------------------------------

793

%--------------- Helper functions -----------------------------------------

793

%--------------- Helper functions -----------------------------------------

794

%--------------------------------------------------------------------------

794

%--------------------------------------------------------------------------

795

function chdata=Apply_EQ(param,fom_result,chdata,OP)

795

function chdata=Apply_EQ(param,fom_result,chdata,OP)

796

796

797

FB=param.fb;

797

FB=param.fb;

798

FZ=param.CTLE_fz(fom_result.ctle);

798

FZ=param.CTLE_fz(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

802

if ~isempty(param.f_HP)

802

if ~isempty(param.f_HP)

803

FHP=param.f_HP(fom_result.best_G_high_pass);

803

FHP=param.f_HP(fom_result.best_G_high_pass);

804

end

804

end

805

if ~isempty(param.g_DC_HP_values)

805

if ~isempty(param.g_DC_HP_values)

806

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

806

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

807

end

807

end

808

if ~isempty(param.f_HP_Z)

808

if ~isempty(param.f_HP_Z)

809

FHPZ=param.f_HP_Z(fom_result.ctle);

809

FHPZ=param.f_HP_Z(fom_result.ctle);

810

end

810

end

811

if ~isempty(param.f_HP_P)

811

if ~isempty(param.f_HP_P)

812

FHPP=param.f_HP_P(fom_result.ctle);

812

FHPP=param.f_HP_P(fom_result.ctle);

813

end

813

end

814

%Handle the scenario where the pulse response is not long enough to

814

%Handle the scenario where the pulse response is not long enough to

815

%contain all DFE taps. the SBR recorded in fom_result has the proper

815

%contain all DFE taps. the SBR recorded in fom_result has the proper

816

%length

816

%length

817

SBR_Len=length(fom_result.sbr);

817

SBR_Len=length(fom_result.sbr);

818

if length(chdata(1).uneq_imp_response)<SBR_Len

818

if length(chdata(1).uneq_imp_response)<SBR_Len

819

samples_added=SBR_Len-length(chdata(1).uneq_imp_response);

819

samples_added=SBR_Len-length(chdata(1).uneq_imp_response);

820

chdata(1).uneq_imp_response(end+1:SBR_Len)=0;

820

chdata(1).uneq_imp_response(end+1:SBR_Len)=0;

821

chdata(1).uneq_pulse_response(end+1:SBR_Len)=0;

821

chdata(1).uneq_pulse_response(end+1:SBR_Len)=0;

822

chdata(1).t(end+1:SBR_Len)=(1:samples_added)/param.fb/param.samples_per_ui+chdata(1).t(end);

822

chdata(1).t(end+1:SBR_Len)=(1:samples_added)/param.fb/param.samples_per_ui+chdata(1).t(end);

823

end

823

end

824

for i=1:param.number_of_s4p_files

824

for i=1:param.number_of_s4p_files

825

% get quick PDF results but only for THRU when in Rx calibration

825

% get quick PDF results but only for THRU when in Rx calibration

826

uneq_ir=chdata(i).uneq_imp_response;% includes packages, Hx, and Hr

826

uneq_ir=chdata(i).uneq_imp_response;% includes packages, Hx, and Hr

827

if OP.INCLUDE_CTLE==1

827

if OP.INCLUDE_CTLE==1

828

switch param.CTLE_type

828

switch param.CTLE_type

829

case 'CL93'

829

case 'CL93'

830

eq_ir = TD_CTLE(uneq_ir, FB, FZ, FP1, FP2, GDC, param.samples_per_ui);

830

eq_ir = TD_CTLE(uneq_ir, FB, FZ, FP1, FP2, GDC, param.samples_per_ui);

831

case 'CL120d'

831

case 'CL120d'

832

eq_ir = TD_CTLE(uneq_ir, FB, FZ, FP1, FP2, GDC, param.samples_per_ui);

832

eq_ir = TD_CTLE(uneq_ir, FB, FZ, FP1, FP2, GDC, param.samples_per_ui);

833

eq_ir = TD_CTLE(eq_ir, FB, FHP, FHP, 100e100 , GDCHP, param.samples_per_ui);

833

eq_ir = TD_CTLE(eq_ir, FB, FHP, FHP, 100e100 , GDCHP, param.samples_per_ui);

834

case 'CL120e' % z has been adjusted for gain

834

case 'CL120e' % z has been adjusted for gain

835

eq_ir = TD_CTLE(uneq_ir, FB, FZ, FP1, FP2, GDC, param.samples_per_ui);

835

eq_ir = TD_CTLE(uneq_ir, FB, FZ, FP1, FP2, GDC, param.samples_per_ui);

836

eq_ir = TD_CTLE(eq_ir,FB, FHPZ, FHPP,1e99, 0, param.samples_per_ui);

836

eq_ir = TD_CTLE(eq_ir,FB, FHPZ, FHPP,1e99, 0, param.samples_per_ui);

837

end

837

end

838

else

838

else

839

eq_ir=uneq_ir;

839

eq_ir=uneq_ir;

840

end

840

end

841

chdata(i).eq_imp_response=eq_ir;

841

chdata(i).eq_imp_response=eq_ir;

842

eq_pulse=filter(ones(1, param.samples_per_ui), 1, chdata(i).eq_imp_response);

842

eq_pulse=filter(ones(1, param.samples_per_ui), 1, chdata(i).eq_imp_response);

843

843

844

if isequal(chdata(i).type, 'FEXT') || isequal(chdata(i).type, 'THRU')

844

if isequal(chdata(i).type, 'FEXT') || isequal(chdata(i).type, 'THRU')

845

eq_pulse = FFE( fom_result.txffe ,fom_result.cur-1 , param.samples_per_ui, eq_pulse );

845

eq_pulse = FFE( fom_result.txffe ,fom_result.cur-1 , param.samples_per_ui, eq_pulse );

846

end

846

end

847

% chdata(i).ctle_imp_response

847

% chdata(i).ctle_imp_response

848

if OP.RxFFE

848

if OP.RxFFE

849

if isequal(upper(OP.FFE_OPT_METHOD),'MMSE')

849

if isequal(upper(OP.FFE_OPT_METHOD),'MMSE')

850

chdata(i).ctle_imp_response = FFE( fom_result.RxFFE ,fom_result.cur-1 , param.samples_per_ui, eq_ir );

850

chdata(i).ctle_imp_response = FFE( fom_result.RxFFE ,fom_result.cur-1 , param.samples_per_ui, eq_ir );

851

end

851

end

852

[ eq_pulse, C]=force(eq_pulse,param,OP,fom_result.t_s,fom_result.RxFFE);

852

[ eq_pulse, C]=force(eq_pulse,param,OP,fom_result.t_s,fom_result.RxFFE);

853

end

853

end

854

chdata(i).eq_pulse_response=eq_pulse;% includes packages, Hf, and Hr, Ht, and Hffe(from tx)

854

chdata(i).eq_pulse_response=eq_pulse;% includes packages, Hf, and Hr, Ht, and Hffe(from tx)

855

end

855

end

856

function Bathtub_Contribution_Wrapper(COM_SNR_Struct,Noise_Struct,param,chdata,OP)

856

function Bathtub_Contribution_Wrapper(COM_SNR_Struct,Noise_Struct,param,chdata,OP)

857

857

858

% display bathtub curves in one axis per test case.

858

% display bathtub curves in one axis per test case.

859

case_number=param.package_testcase_i;

859

case_number=param.package_testcase_i;

860

if ~OP.COM_CONTRIBUTION_CURVES

860

if ~OP.COM_CONTRIBUTION_CURVES

861

figure_name = 'Voltage bathtub curves';

861

figure_name = 'Voltage bathtub curves';

862

fig=findobj('Name', figure_name);

862

fig=findobj('Name', figure_name);

863

if isempty(fig), fig=figure('Name', figure_name); end

863

if isempty(fig), fig=figure('Name', figure_name); end

864

figure(fig);set(gcf,'Tag','COM');

864

figure(fig);set(gcf,'Tag','COM');

865

movegui(fig,'south')

865

movegui(fig,'south')

866

hax = subplot(length(OP.pkg_len_select), 1, case_number);

866

hax = subplot(length(OP.pkg_len_select), 1, case_number);

867

plot_bathtub_curves( hax ...

867

plot_bathtub_curves( hax ...

868

, COM_SNR_Struct.A_s ...

868

, COM_SNR_Struct.A_s ...

869

, Noise_Struct.sci_pdf ...

869

, Noise_Struct.sci_pdf ...

870

, Noise_Struct.cci_pdf ...

870

, Noise_Struct.cci_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

872

, Noise_Struct.noise_pdf ...

872

, Noise_Struct.noise_pdf ...

873

, Noise_Struct.jitt_pdf ...

873

, Noise_Struct.jitt_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

875

, param.delta_y ...

875

, param.delta_y ...

876

);

876

);

877

set(hax, 'tag', 'BTC');

877

set(hax, 'tag', 'BTC');

878

title(hax, sprintf('case %d VBC: %s ', case_number, regexprep([chdata(1).base,' '],'_',' ')));

878

title(hax, sprintf('case %d VBC: %s ', case_number, regexprep([chdata(1).base,' '],'_',' ')));

879

ylim(hax, [param.specBER/10 1]);

879

ylim(hax, [param.specBER/10 1]);

880

% show BER target line

880

% show BER target line

881

hp=plot(get(hax, 'xlim'), param.specBER*[1 1], 'r:');

881

hp=plot(get(hax, 'xlim'), param.specBER*[1 1], 'r:');

882

set(get(get(hp,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

882

set(get(get(hp,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

883

else

883

else

884

figure_name = 'COM Contributions (Rough Allocations)';

884

figure_name = 'COM Contributions (Rough Allocations)';

885

fig=findobj('Name', figure_name);

885

fig=findobj('Name', figure_name);

886

if isempty(fig), fig=figure('Name', figure_name); end

886

if isempty(fig), fig=figure('Name', figure_name); end

887

figure(fig);set(gcf,'Tag','COM');

887

figure(fig);set(gcf,'Tag','COM');

888

movegui(fig,'south')

888

movegui(fig,'south')

889

hax = subplot(length(OP.pkg_len_select), 1, case_number);

889

hax = subplot(length(OP.pkg_len_select), 1, case_number);

890

890

891

plot_pie_com( hax ...

891

plot_pie_com( hax ...

892

, COM_SNR_Struct.A_s ...

892

, COM_SNR_Struct.A_s ...

893

, Noise_Struct.sci_pdf ...

893

, Noise_Struct.sci_pdf ...

894

, Noise_Struct.cci_pdf ...

894

, Noise_Struct.cci_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

896

, Noise_Struct.noise_pdf ...

896

, Noise_Struct.noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

898

, param.delta_y, param...

898

, param.delta_y, param...

899

);

899

);

900

set(hax, 'tag', 'BTC');

900

set(hax, 'tag', 'BTC');

901

title(hax, sprintf('case %d rough COM impact: %s ', case_number, regexprep([chdata(1).base,' '],'_',' ')));

901

title(hax, sprintf('case %d rough COM impact: %s ', case_number, regexprep([chdata(1).base,' '],'_',' ')));

902

end

902

end

903

903

904

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

904

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

905

btc_axes = findobj('tag', 'BTC');

905

btc_axes = findobj('tag', 'BTC');

906

if ~isempty(btc_axes), linkaxes(btc_axes, 'x'); end

906

if ~isempty(btc_axes), linkaxes(btc_axes, 'x'); end

907

end

907

end

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

909

909

910

if use_BT

910

if use_BT

911

a = bessel( param.BTorder );

911

a = bessel( param.BTorder );

912

acoef=fliplr( a );

912

acoef=fliplr( a );

913

H_bt =a(1)./ polyval(acoef, (1i*f./(param.fb_BT_cutoff*param.fb)));

913

H_bt =a(1)./ polyval(acoef, (1i*f./(param.fb_BT_cutoff*param.fb)));

914

else

914

else

915

H_bt=ones(1,length(f));

915

H_bt=ones(1,length(f));

916

end

916

end

917

917

918

918

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

920

920

921

%This optional function reduces the size of output_args.chdata by parsing user supplied fields in a txt file

921

%This optional function reduces the size of output_args.chdata by parsing user supplied fields in a txt file

922

%The first line of the file must be #reduce or #include

922

%The first line of the file must be #reduce or #include

923

%All subsequent lines are field names in chdata

923

%All subsequent lines are field names in chdata

924

%If using #reduce, the list of fields are the fields to remove from chdata

924

%If using #reduce, the list of fields are the fields to remove from chdata

925

%If using #include, the list of fields are the fields to include in chdata

925

%If using #include, the list of fields are the fields to include in chdata

926

%

926

%

927

%Example file to remove the fields "sdd12_raw" "sdd21_raw" "sdd22_raw" "sdd11_raw"

927

%Example file to remove the fields "sdd12_raw" "sdd21_raw" "sdd22_raw" "sdd11_raw"

928

%#reduce

928

%#reduce

929

%sdd12_raw

929

%sdd12_raw

930

%sdd21_raw

930

%sdd21_raw

931

%sdd22_raw

931

%sdd22_raw

932

%sdd11_raw

932

%sdd11_raw

933

%

933

%

934

934

935

fid=fopen(fields_file,'r');

935

fid=fopen(fields_file,'r');

936

file_data=textscan(fid,'%s','Delimiter','\n');

936

file_data=textscan(fid,'%s','Delimiter','\n');

937

937

938

file_data=file_data{1};

938

file_data=file_data{1};

939

fclose(fid);

939

fclose(fid);

940

940

941

%remove blank lines

941

%remove blank lines

942

L=cellfun('length',file_data);

942

L=cellfun('length',file_data);

943

file_data=file_data(L~=0);

943

file_data=file_data(L~=0);

944

944

945

%first line must be '#reduce' or '#include'

945

%first line must be '#reduce' or '#include'

946

type=file_data{1};

946

type=file_data{1};

947

field_names=file_data(2:end);

947

field_names=file_data(2:end);

948

switch lower(type)

948

switch lower(type)

949

case '#reduce'

949

case '#reduce'

950

remove_fields=field_names;

950

remove_fields=field_names;

951

case '#include'

951

case '#include'

952

all_fields=fieldnames(chdata);

952

all_fields=fieldnames(chdata);

953

remove_fields=setdiff(all_fields,field_names);

953

remove_fields=setdiff(all_fields,field_names);

954

otherwise

954

otherwise

955

error('Bad first line. Must be "#reduce" or "#include"');

955

error('Bad first line. Must be "#reduce" or "#include"');

956

end

956

end

957

957

958

%remove the "remove_fields" from chdata

958

%remove the "remove_fields" from chdata

959

for j=1:length(remove_fields)

959

for j=1:length(remove_fields)

960

this_field=remove_fields{j};

960

this_field=remove_fields{j};

961

if isfield(chdata,this_field)

961

if isfield(chdata,this_field)

962

chdata=rmfield(chdata,this_field);

962

chdata=rmfield(chdata,this_field);

963

end

963

end

964

end

964

end

965

function [p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,DFE_taps,param,OP)

965

function [p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,DFE_taps,param,OP)

966

966

967

% an error burst of length N will cause each of the first N taps tap to mis-correct and create a PAM (2 or

967

% an error burst of length N will cause each of the first N taps tap to mis-correct and create a PAM (2 or

968

% 4) noise term - depending on the N'th previous symbol, with double the tap voltage. From this we calculate

968

% 4) noise term - depending on the N'th previous symbol, with double the tap voltage. From this we calculate

969

% the probability of staying in error state, i.e. burst of length N+1.

969

% the probability of staying in error state, i.e. burst of length N+1.

970

970

971

A_s=COM_SNR_Struct.A_s;

971

A_s=COM_SNR_Struct.A_s;

972

% initialize loop with uncorrelated noise and BER

972

% initialize loop with uncorrelated noise and BER

973

error_propagation_noise_pdf{1}=COM_SNR_Struct.combined_interference_and_noise_pdf; % PDF for burst of length 1 is the uncorrelated PDF

973

error_propagation_noise_pdf{1}=COM_SNR_Struct.combined_interference_and_noise_pdf; % PDF for burst of length 1 is the uncorrelated PDF

974

974

975

% Assume an error will occur if the noise excceds the available signal

975

% Assume an error will occur if the noise excceds the available signal

976

% reduced by some dB. reduction is by COM threshold minus Error

976

% reduced by some dB. reduction is by COM threshold minus Error

977

% propagation margin (a positive EP margin reduces uncorrelated error probability

977

% propagation margin (a positive EP margin reduces uncorrelated error probability

978

% below target BER).

978

% below target BER).

979

error_threshold = A_s./10^((param.pass_threshold-OP.COM_EP_margin)/20);

979

error_threshold = A_s./10^((param.pass_threshold-OP.COM_EP_margin)/20);

980

% Find the probability of this event by integration of the PDF. Use 1e-20 as a floor probabilty if noise PDF isn't wide enough.

980

% Find the probability of this event by integration of the PDF. Use 1e-20 as a floor probabilty if noise PDF isn't wide enough.

981

x_error_propagation = find(error_propagation_noise_pdf{1}.x >= error_threshold, 1, 'first');

981

x_error_propagation = find(error_propagation_noise_pdf{1}.x >= error_threshold, 1, 'first');

982

if isempty(x_error_propagation)

982

if isempty(x_error_propagation)

983

p_error_propagation(1) = 1e-20;

983

p_error_propagation(1) = 1e-20;

984

else

984

else

985

p_error_propagation(1) = sum(error_propagation_noise_pdf{1}.y(x_error_propagation:end)); % uncorrelated BER

985

p_error_propagation(1) = sum(error_propagation_noise_pdf{1}.y(x_error_propagation:end)); % uncorrelated BER

986

end

986

end

987

987

988

sorted_abs_dfe_taps = sort(abs(DFE_taps), 'descend');

988

sorted_abs_dfe_taps = sort(abs(DFE_taps), 'descend');

989

for k=2:min(param.ndfe, OP.nburst)

989

for k=2:min(param.ndfe, OP.nburst)

990

% (arrays kept to allow tracking during development, though not really needed)

990

% (arrays kept to allow tracking during development, though not really needed)

991

if OP.use_simple_EP_model

991

if OP.use_simple_EP_model

992

post_error_dfe_noise_pdf{k} = get_pdf_from_sampled_signal( 2*A_s*max(sorted_abs_dfe_taps), param.levels, param.delta_y ); %#ok<AGROW>

992

post_error_dfe_noise_pdf{k} = get_pdf_from_sampled_signal( 2*A_s*max(sorted_abs_dfe_taps), param.levels, param.delta_y ); %#ok<AGROW>

993

error_propagation_noise_pdf{k} = conv_fct(error_propagation_noise_pdf{1}, post_error_dfe_noise_pdf{k}); %#ok<AGROW>

993

error_propagation_noise_pdf{k} = conv_fct(error_propagation_noise_pdf{1}, post_error_dfe_noise_pdf{k}); %#ok<AGROW>

994

else

994

else

995

post_error_dfe_noise_pdf{k} = get_pdf_from_sampled_signal( 2*A_s*sorted_abs_dfe_taps(k-1), param.levels, param.delta_y ); %#ok<AGROW>

995

post_error_dfe_noise_pdf{k} = get_pdf_from_sampled_signal( 2*A_s*sorted_abs_dfe_taps(k-1), param.levels, param.delta_y ); %#ok<AGROW>

996

error_propagation_noise_pdf{k} = conv_fct(error_propagation_noise_pdf{k-1}, post_error_dfe_noise_pdf{k}); %#ok<AGROW>

996

error_propagation_noise_pdf{k} = conv_fct(error_propagation_noise_pdf{k-1}, post_error_dfe_noise_pdf{k}); %#ok<AGROW>

997

end

997

end

998

998

999

% Assume an error will propagate if this noise exceeds the threshold defined above

999

% Assume an error will propagate if this noise exceeds the threshold defined above

1000

x_error_propagation = find(error_propagation_noise_pdf{k}.x >= error_threshold, 1, 'first');

1000

x_error_propagation = find(error_propagation_noise_pdf{k}.x >= error_threshold, 1, 'first');

1001

if isempty(x_error_propagation)

1001

if isempty(x_error_propagation)

1002

p_error_propagation(k) = 1e-20; %#ok<AGROW>

1002

p_error_propagation(k) = 1e-20; %#ok<AGROW>

1003

else

1003

else

1004

p_error_propagation(k) = sum(error_propagation_noise_pdf{k}.y(x_error_propagation:end)); %#ok<AGROW>

1004

p_error_propagation(k) = sum(error_propagation_noise_pdf{k}.y(x_error_propagation:end)); %#ok<AGROW>

1005

end

1005

end

1006

end

1006

end

1007

1007

1008

% Assume an uncorrelated error will occur if the original noise exceeds

1008

% Assume an uncorrelated error will occur if the original noise exceeds

1009

% the available signal reduced by pass_threhsold dB. Find the probability

1009

% the available signal reduced by pass_threhsold dB. Find the probability

1010

% of this event by partial sum of the PDF.

1010

% of this event by partial sum of the PDF.

1011

% p_uncorrelated_error_i = find(combined_interference_and_noise_pdf.x >= A_s./10^(param.pass_threshold/20), 1, 'first');

1011

% p_uncorrelated_error_i = find(combined_interference_and_noise_pdf.x >= A_s./10^(param.pass_threshold/20), 1, 'first');

1012

% p_uncorrelated_error = sum(combined_interference_and_noise_pdf.y(p_uncorrelated_error_i:end));

1012

% p_uncorrelated_error = sum(combined_interference_and_noise_pdf.y(p_uncorrelated_error_i:end));

1013

1013

1014

% probability of bursts of different lengths

1014

% probability of bursts of different lengths

1015

p_burst = cumprod(p_error_propagation);

1015

p_burst = cumprod(p_error_propagation);

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1017

1017

1018

if use_BW

1018

if use_BW

1019

H_bw = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(param.fb_BW_cutoff*param.fb));

1019

H_bw = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(param.fb_BW_cutoff*param.fb));

1020

else

1020

else

1021

H_bw=ones(1,length(f));

1021

H_bw=ones(1,length(f));

1022

end

1022

end

1023

function [CDF_ev] = CDF_ev(val,PDF,CDF)

1023

function [CDF_ev] = CDF_ev(val,PDF,CDF)

1024

index=find(PDF.x >= -val,1,'first');

1024

index=find(PDF.x >= -val,1,'first');

1025

CDF_ev=CDF(index);

1025

CDF_ev=CDF(index);

1026

function [CDF_inv_ev] = CDF_inv_ev(val,PDF,CDF)

1026

function [CDF_inv_ev] = CDF_inv_ev(val,PDF,CDF)

1027

index=find(CDF >= val,1,'first');

1027

index=find(CDF >= val,1,'first');

1028

if isempty(index)

1028

if isempty(index)

1029

CDF_inv_ev=PDF.x(end);

1029

CDF_inv_ev=PDF.x(end);

1030

else

1030

else

1031

CDF_inv_ev=PDF.x(index);

1031

CDF_inv_ev=PDF.x(index);

1032

end

1032

end

1033

function [config_file,num_fext,num_next,Remember_keyword,OP,varargin]=COM_CommandLine_Parse(OP,varargin)

1033

function [config_file,num_fext,num_next,Remember_keyword,OP,varargin]=COM_CommandLine_Parse(OP,varargin)

1034

1034

1035

1035

1036

keywords={'Legacy' 'TD' 'Config2Mat'};

1036

keywords={'Legacy' 'TD' 'Config2Mat'};

1037

Remember_keyword='Legacy';

1037

Remember_keyword='Legacy';

1038

OP.TDMODE=false;

1038

OP.TDMODE=false;

1039

OP.GET_FD=true;

1039

OP.GET_FD=true;

1040

OP.CONFIG2MAT_ONLY=false;

1040

OP.CONFIG2MAT_ONLY=false;

1041

config_file='';

1041

config_file='';

1042

num_fext=[];

1042

num_fext=[];

1043

num_next=[];

1043

num_next=[];

1044

if ~isempty(varargin)

1044

if ~isempty(varargin)

1045

if ~ischar(varargin{1})

1045

if ~ischar(varargin{1})

1046

error('First input must be a string');

1046

error('First input must be a string');

1047

end

1047

end

1048

keyword_idx=find(strcmpi(keywords,varargin{1}));

1048

keyword_idx=find(strcmpi(keywords,varargin{1}));

1049

if isempty(keyword_idx)

1049

if isempty(keyword_idx)

1050

%Legacy Mode

1050

%Legacy Mode

1051

[config_file,varargin]=varargin_extractor(varargin{:});

1051

[config_file,varargin]=varargin_extractor(varargin{:});

1052

[num_fext,varargin]=varargin_extractor(varargin{:});

1052

[num_fext,varargin]=varargin_extractor(varargin{:});

1053

[num_next,varargin]=varargin_extractor(varargin{:});

1053

[num_next,varargin]=varargin_extractor(varargin{:});

1054

else

1054

else

1055

%Keyword Mode

1055

%Keyword Mode

1056

my_keyword=varargin{1};

1056

my_keyword=varargin{1};

1057

Remember_keyword=my_keyword;

1057

Remember_keyword=my_keyword;

1058

varargin(1)=[];

1058

varargin(1)=[];

1059

switch my_keyword

1059

switch my_keyword

1060

1060

1061

case 'Legacy'

1061

case 'Legacy'

1062

[config_file,varargin]=varargin_extractor(varargin{:});

1062

[config_file,varargin]=varargin_extractor(varargin{:});

1063

[num_fext,varargin]=varargin_extractor(varargin{:});

1063

[num_fext,varargin]=varargin_extractor(varargin{:});

1064

[num_next,varargin]=varargin_extractor(varargin{:});

1064

[num_next,varargin]=varargin_extractor(varargin{:});

1065

case 'TD'

1065

case 'TD'

1066

OP.TDMODE=true;

1066

OP.TDMODE=true;

1067

OP.GET_FD=false;

1067

OP.GET_FD=false;

1068

[config_file,varargin]=varargin_extractor(varargin{:});

1068

[config_file,varargin]=varargin_extractor(varargin{:});

1069

[num_fext,varargin]=varargin_extractor(varargin{:});

1069

[num_fext,varargin]=varargin_extractor(varargin{:});

1070

[num_next,varargin]=varargin_extractor(varargin{:});

1070

[num_next,varargin]=varargin_extractor(varargin{:});

1071

case 'Config2Mat'

1071

case 'Config2Mat'

1072

OP.CONFIG2MAT_ONLY=true;

1072

OP.CONFIG2MAT_ONLY=true;

1073

[config_file,varargin]=varargin_extractor(varargin{:});

1073

[config_file,varargin]=varargin_extractor(varargin{:});

1074

end

1074

end

1075

end

1075

end

1076

end

1076

end

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1078

1078

1079

% get impulse responses which in interim step between equation for X(f) and

1079

% get impulse responses which in interim step between equation for X(f) and

1080

% H^(k)(t) without TX FFE or CTLE. These will we added later.

1080

% H^(k)(t) without TX FFE or CTLE. These will we added later.

1081

case_number=param.package_testcase_i;

1081

case_number=param.package_testcase_i;

1082

for i=1:param.number_of_s4p_files

1082

for i=1:param.number_of_s4p_files

1083

% RIM 2-01-2023 moved to FD_Processing

1083

% RIM 2-01-2023 moved to FD_Processing

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1085

% % Equation 93A-20 %%

1085

% % Equation 93A-20 %%

1086

% % H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1086

% % H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1087

% f=chdata(i).faxis;

1087

% f=chdata(i).faxis;

1088

% %

1088

% %

1089

% H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1089

% H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1090

% H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1090

% H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1091

% H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1091

% H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1092

% H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1092

% H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1093

% H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1093

% H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1094

% chdata(i).sdd21=chdata(i).sdd21.*H_r;

1094

% chdata(i).sdd21=chdata(i).sdd21.*H_r;

1095

% if OP.DISPLAY_WINDOW

1095

% if OP.DISPLAY_WINDOW

1096

% if i==1

1096

% if i==1

1097

% figure(300+param.package_testcase_i);

1097

% figure(300+param.package_testcase_i);

1098

% subplot(3,1,1)

1098

% subplot(3,1,1)

1099

% plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp','VTF (no Tx/Rx eq)')

1099

% plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp','VTF (no Tx/Rx eq)')

1100

% try

1100

% try

1101

% legend('NumColumns',2)

1101

% legend('NumColumns',2)

1102

% legend('location','south')

1102

% legend('location','south')

1103

% catch

1103

% catch

1104

% end

1104

% end

1105

% end

1105

% end

1106

% end

1106

% end

1107

% end

1107

% end

1108

[chdata(i).uneq_imp_response, ...

1108

[chdata(i).uneq_imp_response, ...

1109

chdata(i).t, ...

1109

chdata(i).t, ...

1110

chdata(i).causality_correction_dB, ...

1110

chdata(i).causality_correction_dB, ...

1111

chdata(i).truncation_dB] = s21_to_impulse_DC(chdata(i).sdd21 ,chdata(i).faxis, param.sample_dt, OP) ;

1111

chdata(i).truncation_dB] = s21_to_impulse_DC(chdata(i).sdd21 ,chdata(i).faxis, param.sample_dt, OP) ;

1112

if ~OP.RX_CALIBRATION || i==1 % DC (common to differentail model is not good used for RX_Calibrataion channel

1112

if ~OP.RX_CALIBRATION || i==1 % DC (common to differentail model is not good used for RX_Calibrataion channel

1113

chdata(i).uneq_imp_response=chdata(i).uneq_imp_response*chdata(i).A; % adjust IRx for amplitude

1113

chdata(i).uneq_imp_response=chdata(i).uneq_imp_response*chdata(i).A; % adjust IRx for amplitude

1114

[chdata(i).uneq_CD_imp_response, ...

1114

[chdata(i).uneq_CD_imp_response, ...

1115

chdata(i).t_DC, ...

1115

chdata(i).t_DC, ...

1116

chdata(i).causality_correction_DC_dB, ...

1116

chdata(i).causality_correction_DC_dB, ...

1117

chdata(i).truncation__DC_dB] = s21_to_impulse_DC(chdata(i).sdc21 ,chdata(i).faxis, param.sample_dt, OP) ;

1117

chdata(i).truncation__DC_dB] = s21_to_impulse_DC(chdata(i).sdc21 ,chdata(i).faxis, param.sample_dt, OP) ;

1118

end

1118

end

1119

% adjust voltage derive here once it's decided what to use

1119

% adjust voltage derive here once it's decided what to use

1120

%------------------------------------------------------------

1120

%------------------------------------------------------------

1121

% next find Pulse response (SBR) for each channel h^(k)(t)

1121

% next find Pulse response (SBR) for each channel h^(k)(t)

1122

if ~OP.DISPLAY_WINDOW && i==1, fprintf('processing COM PDF '); end

1122

if ~OP.DISPLAY_WINDOW && i==1, fprintf('processing COM PDF '); end

1123

1123

1124

chdata(i).uneq_pulse_response=filter(ones(1, param.samples_per_ui), 1, chdata(i).uneq_imp_response);

1124

chdata(i).uneq_pulse_response=filter(ones(1, param.samples_per_ui), 1, chdata(i).uneq_imp_response);

1125

chdata(i).uneq_pulse_DC_response=filter(ones(1, param.samples_per_ui), 1, chdata(i).uneq_CD_imp_response);

1125

chdata(i).uneq_pulse_DC_response=filter(ones(1, param.samples_per_ui), 1, chdata(i).uneq_CD_imp_response);

1126

chdata(i).uneq_pulse_CD_response=chdata(i).uneq_pulse_DC_response*chdata(i).A;

1126

chdata(i).uneq_pulse_CD_response=chdata(i).uneq_pulse_DC_response*chdata(i).A;

1127

if 1 % not really CD but DC = DC if the channel already has a the Tx added

1127

if 1 % not really CD but DC = DC if the channel already has a the Tx added

1128

% really need to add eq to the DC responce to calc rss. This is a first pass estimate

1128

% really need to add eq to the DC responce to calc rss. This is a first pass estimate

1129

rss=-inf;

1129

rss=-inf;

1130

for im=1:param.samples_per_ui

1130

for im=1:param.samples_per_ui

1131

rss=max(rss, norm( chdata(i).uneq_pulse_CD_response(im:param.samples_per_ui:end)));

1131

rss=max(rss, norm( chdata(i).uneq_pulse_CD_response(im:param.samples_per_ui:end)));

1132

end

1132

end

1133

chdata(i).CD_CM_RMS=rss*sqrt(param.sigma_X);

1133

chdata(i).CD_CM_RMS=rss*sqrt(param.sigma_X);

1134

chdata(i).VCM_HF_struct= get_cm_noise(param.samples_per_ui,chdata(i).uneq_pulse_CD_response,param.levels,param.specBER);

1134

chdata(i).VCM_HF_struct= get_cm_noise(param.samples_per_ui,chdata(i).uneq_pulse_CD_response,param.levels,param.specBER);

1135

chdata(i).SCMR=10*log10(max(chdata(1).uneq_pulse_response)^2/chdata(i).VCM_HF_struct.DCn^2);

1135

chdata(i).SCMR=10*log10(max(chdata(1).uneq_pulse_response)^2/chdata(i).VCM_HF_struct.DCn^2);

1136

end

1136

end

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1139

figure(150+case_number);set(gcf,'Tag','COM');

1139

figure(150+case_number);set(gcf,'Tag','COM');

1140

screen_size=get(0,'ScreenSize');

1140

screen_size=get(0,'ScreenSize');

1141

pos = get(gcf, 'OuterPosition');

1141

pos = get(gcf, 'OuterPosition');

1142

set(gcf, 'OuterPosition', ...

1142

set(gcf, 'OuterPosition', ...

1143

screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-1 -1 1 1] ...

1143

screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-1 -1 1 1] ...

1144

- (case_number-1)*[0 20 0 0]);

1144

- (case_number-1)*[0 20 0 0]);

1145

%movegui(gcf,'northeast')

1145

%movegui(gcf,'northeast')

1146

1146

1147

set(gcf, 'Name', sprintf('Case %d PR & PDF - %s', case_number, chdata(i).base));

1147

set(gcf, 'Name', sprintf('Case %d PR & PDF - %s', case_number, chdata(i).base));

1148

subplot(2,1,1); hold on; % all plots on the same axes

1148

subplot(2,1,1); hold on; % all plots on the same axes

1149

hp=plot(chdata(i).t, chdata(i).uneq_pulse_response,'Disp', chdata(i).base);

1149

hp=plot(chdata(i).t, chdata(i).uneq_pulse_response,'Disp', chdata(i).base);

1150

hold on; % leave on for s-parameter problem finding. RIM 10-02-2023

1150

hold on; % leave on for s-parameter problem finding. RIM 10-02-2023

1151

hp1=plot(chdata(i).t_DC, chdata(i).uneq_pulse_CD_response,'Disp', [ 'CD ' chdata(i).base ]) ;

1151

hp1=plot(chdata(i).t_DC, chdata(i).uneq_pulse_CD_response,'Disp', [ 'CD ' chdata(i).base ]) ;

1152

end

1152

end

1153

% hide thru PR in order to show xtalk in a reasonable

1153

% hide thru PR in order to show xtalk in a reasonable

1154

% scale. thru is shown in another plot.

1154

% scale. thru is shown in another plot.

1155

if isequal(chdata(i).type, 'THRU' ) && ~OP.RX_CALIBRATION %|| OP.RX_CALIBRATION % RIM 06-14-2022

1155

if isequal(chdata(i).type, 'THRU' ) && ~OP.RX_CALIBRATION %|| OP.RX_CALIBRATION % RIM 06-14-2022

1156

% set(hp, 'visible', 'off');

1156

% set(hp, 'visible', 'off');

1157

% set(get(get(hp,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

1157

% set(get(get(hp,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

1158

end

1158

end

1159

title(sprintf('Unequalized Crosstalk and CD Conversion \n Pulse Responses'))

1159

title(sprintf('Unequalized Crosstalk and CD Conversion \n Pulse Responses'))

1160

ylabel('Volts')

1160

ylabel('Volts')

1161

xlabel('seconds')

1161

xlabel('seconds')

1162

1162

1163

recolor_plots(gca);

1163

recolor_plots(gca);

1164

else

1164

else

1165

if param.ndfe~=0

1165

if param.ndfe~=0

1166

fprintf('%s\tUnequalized pulse peak = %.1f mV\n', chdata(i).base, 1000*max(abs(chdata(i).uneq_pulse_response)));

1166

fprintf('%s\tUnequalized pulse peak = %.1f mV\n', chdata(i).base, 1000*max(abs(chdata(i).uneq_pulse_response)));

1167

end

1167

end

1168

end

1168

end

1169

1169

1170

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1170

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1171

if OP.ENFORCE_CAUSALITY

1171

if OP.ENFORCE_CAUSALITY

1172

fprintf('\n');

1172

fprintf('\n');

1173

else

1173

else

1174

fprintf(' (not applied)\n');

1174

fprintf(' (not applied)\n');

1175

end

1175

end

1176

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1176

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1177

1177

1178

end

1178

end

1179

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1179

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1180

1180

1181

1181

1182

debug_plot=0;

1182

debug_plot=0;

1183

1183

1184

1184

1185

samp_UI=param.samples_for_C2M;

1185

samp_UI=param.samples_for_C2M;

1186

half_UI=get_center_of_UI(samp_UI);

1186

half_UI=get_center_of_UI(samp_UI);

1187

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1187

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1188

start_sample=half_UI-T_O;

1188

start_sample=half_UI-T_O;

1189

end_sample=half_UI+T_O;

1189

end_sample=half_UI+T_O;

1190

1190

1191

1191

1192

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1192

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1193

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1193

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1194

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1194

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1195

if pdf_range_flag

1195

if pdf_range_flag

1196

pdf_range=[start_sample end_sample];

1196

pdf_range=[start_sample end_sample];

1197

else

1197

else

1198

pdf_range=[];

1198

pdf_range=[];

1199

end

1199

end

1200

1200

1201

%pdf_full is self ISI pdf for each sample point

1201

%pdf_full is self ISI pdf for each sample point

1202

%h_j_full is the v/t calculation for each sample point

1202

%h_j_full is the v/t calculation for each sample point

1203

%the center vector for each should be identical to the standard COM variables

1203

%the center vector for each should be identical to the standard COM variables

1204

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1204

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1205

1205

1206

1206

1207

1207

1208

if isempty(pdf_range)

1208

if isempty(pdf_range)

1209

pdf_range=1:samp_UI;

1209

pdf_range=1:samp_UI;

1210

else

1210

else

1211

pdf_range=min(pdf_range):max(pdf_range);

1211

pdf_range=min(pdf_range):max(pdf_range);

1212

end

1212

end

1213

1213

1214

%Test doing Level PDFs

1214

%Test doing Level PDFs

1215

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1215

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1216

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1216

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1217

A_s_vec=A_s_vec*(param.levels-1);

1217

A_s_vec=A_s_vec*(param.levels-1);

1218

1218

1219

%add signal vector into pdf

1219

%add signal vector into pdf

1220

for n=1:param.levels

1220

for n=1:param.levels

1221

pdf_full{n}=pdf_full_1;

1221

pdf_full{n}=pdf_full_1;

1222

for j=pdf_range

1222

for j=pdf_range

1223

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1223

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1224

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1224

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1225

end

1225

end

1226

end

1226

end

1227

1227

1228

1228

1229

% figure;

1229

% figure;

1230

% hold on;

1230

% hold on;

1231

%This loop builds the same PDF/CDF structures from regular COM, but it is

1231

%This loop builds the same PDF/CDF structures from regular COM, but it is

1232

%computed for every sample point

1232

%computed for every sample point

1233

for n=1:param.levels

1233

for n=1:param.levels

1234

for j=pdf_range

1234

for j=pdf_range

1235

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1235

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1236

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1236

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1237

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1237

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1238

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1238

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1239

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1239

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1240

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1240

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1241

% change from adam gregory to include crosstalk

1241

% change from adam gregory to include crosstalk

1242

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1242

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1243

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1243

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1244

1244

1245

%PDF to CDF

1245

%PDF to CDF

1246

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1246

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1247

1247

1248

end

1248

end

1249

end

1249

end

1250

%hold off;

1250

%hold off;

1251

1251

1252

1252

1253

%For the given BER, find the top & bottom voltage level in the CDF

1253

%For the given BER, find the top & bottom voltage level in the CDF

1254

for n=1:param.levels

1254

for n=1:param.levels

1255

A_ni_bottom{n}=zeros(1,samp_UI);

1255

A_ni_bottom{n}=zeros(1,samp_UI);

1256

A_ni_top{n}=zeros(1,samp_UI);

1256

A_ni_top{n}=zeros(1,samp_UI);

1257

for j=pdf_range

1257

for j=pdf_range

1258

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1258

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1259

end

1259

end

1260

end

1260

end

1261

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1261

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1262

1262

1263

for n=1:param.levels-1

1263

for n=1:param.levels-1

1264

eye_contour{n}(:,1)=A_ni_top{n+1};

1264

eye_contour{n}(:,1)=A_ni_top{n+1};

1265

eye_contour{n}(:,2)=A_ni_bottom{n};

1265

eye_contour{n}(:,2)=A_ni_bottom{n};

1266

end

1266

end

1267

1267

1268

1268

1269

for n=1:param.levels-1

1269

for n=1:param.levels-1

1270

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1270

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1271

%define vref as middle of top eye height and bottom eye height. Now

1271

%define vref as middle of top eye height and bottom eye height. Now

1272

%that all eyes are created, vref is non-zero except for middle eye

1272

%that all eyes are created, vref is non-zero except for middle eye

1273

EH_top=eye_contour{n}(half_UI,1);

1273

EH_top=eye_contour{n}(half_UI,1);

1274

EH_bot=eye_contour{n}(half_UI,2);

1274

EH_bot=eye_contour{n}(half_UI,2);

1275

EH=EH_top-EH_bot;

1275

EH=EH_top-EH_bot;

1276

vref=EH_top/2+EH_bot/2;

1276

vref=EH_top/2+EH_bot/2;

1277

%This function finds left/right eye width by finding the vref crossings of

1277

%This function finds left/right eye width by finding the vref crossings of

1278

%the top and bottom eye contours

1278

%the top and bottom eye contours

1279

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1279

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1280

end

1280

end

1281

1281

1282

%For reporting to .csv, need eye contour to be a matrix instead of cell

1282

%For reporting to .csv, need eye contour to be a matrix instead of cell

1283

eye_contour_tmp=eye_contour;

1283

eye_contour_tmp=eye_contour;

1284

eye_contour=[];

1284

eye_contour=[];

1285

for n=1:param.levels-1

1285

for n=1:param.levels-1

1286

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1286

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1287

end

1287

end

1288

1288

1289

1289

1290

%Find VEC eye height

1290

%Find VEC eye height

1291

out_VT=[];

1291

out_VT=[];

1292

out_VB=[];

1292

out_VB=[];

1293

if param.T_O ~=0

1293

if param.T_O ~=0

1294

1294

1295

switch lower(OP.Histogram_Window_Weight)

1295

switch lower(OP.Histogram_Window_Weight)

1296

case {'gaussian' 'norm' 'normal' 'guassian'}

1296

case {'gaussian' 'norm' 'normal' 'guassian'}

1297

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1297

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1298

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1298

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1299

QL_sigma=T_O/param.QL;

1299

QL_sigma=T_O/param.QL;

1300

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1300

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1301

case 'triangle'

1301

case 'triangle'

1302

%triangle window. linear slope from 0 to 1 and back down to 0

1302

%triangle window. linear slope from 0 to 1 and back down to 0

1303

%for the weights

1303

%for the weights

1304

t_slope=1/(T_O);

1304

t_slope=1/(T_O);

1305

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1305

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1306

case 'rectangle'

1306

case 'rectangle'

1307

%default = rectangle. all weights = 1

1307

%default = rectangle. all weights = 1

1308

weights(1:2*T_O+1)=1;

1308

weights(1:2*T_O+1)=1;

1309

case 'dual_rayleigh'

1309

case 'dual_rayleigh'

1310

QL_sigma=T_O/param.QL;

1310

QL_sigma=T_O/param.QL;

1311

X=-T_O:T_O;

1311

X=-T_O:T_O;

1312

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1312

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1313

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1313

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1314

weights=weights/max(weights);

1314

weights=weights/max(weights);

1315

otherwise

1315

otherwise

1316

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1316

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1317

end

1317

end

1318

1318

1319

for n=1:param.levels

1319

for n=1:param.levels

1320

out_pdf{n}=[];

1320

out_pdf{n}=[];

1321

for j=start_sample:end_sample

1321

for j=start_sample:end_sample

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1323

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1323

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1324

if isempty(out_pdf{n})

1324

if isempty(out_pdf{n})

1325

out_pdf{n}=target_pdf;

1325

out_pdf{n}=target_pdf;

1326

else

1326

else

1327

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1327

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1328

end

1328

end

1329

end

1329

end

1330

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1330

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1331

end

1331

end

1332

1332

1333

for n=1:param.levels

1333

for n=1:param.levels

1334

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1334

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1335

end

1335

end

1336

1336

1337

for n=1:param.levels

1337

for n=1:param.levels

1338

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1338

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1339

end

1339

end

1340

1340

1341

for n=1:param.levels-1

1341

for n=1:param.levels-1

1342

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1342

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1343

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1343

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1344

end

1344

end

1345

1345

1346

%Report the top/bottom eye height of the worst eye

1346

%Report the top/bottom eye height of the worst eye

1347

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1347

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1348

[mineh,min_idx]=min(EH_VT);

1348

[mineh,min_idx]=min(EH_VT);

1349

out_VT=OUT_VT_L(min_idx,1);

1349

out_VT=OUT_VT_L(min_idx,1);

1350

out_VB=OUT_VT_L(min_idx,2);

1350

out_VB=OUT_VT_L(min_idx,2);

1351

1351

1352

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1352

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1354

% out_VB=-1*A_ni_bottom_O;

1354

% out_VB=-1*A_ni_bottom_O;

1355

1355

1356

if debug_plot

1356

if debug_plot

1357

figure;

1357

figure;

1358

hold on;

1358

hold on;

1359

for j=start_sample:end_sample

1359

for j=start_sample:end_sample

1360

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1360

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1361

end

1361

end

1362

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1362

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1363

hold off;

1363

hold off;

1364

end

1364

end

1365

end

1365

end

1366

1366

1367

1367

1368

1368

1369

1369

1370

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1370

function [PDF,CDF,NS]=Create_Noise_PDF(A_s,param,fom_result,chdata,OP,sigma_bn,PSD_results)

1371

1371

1372

%This block was originally in main COM function but was moved here for

1372

%This block was originally in main COM function but was moved here for

1373

%cleanup. It returns the combined interference and noise PDF & CDF as well

1373

%cleanup. It returns the combined interference and noise PDF & CDF as well

1374

%as a structure "NS" that contains all the noise parameters that are used

1374

%as a structure "NS" that contains all the noise parameters that are used

1375

%in other places in COM

1375

%in other places in COM

1376

1376

1377

if OP.RX_CALIBRATION

1377

if OP.RX_CALIBRATION

1378

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1378

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1379

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1379

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1380

switch param.CTLE_type

1380

switch param.CTLE_type

1381

case 'CL93'

1381

case 'CL93'

1382

H_low2=1;

1382

H_low2=1;

1383

case 'CL120d' % this clause uses two gain indexes

1383

case 'CL120d' % this clause uses two gain indexes

1384

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1384

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1385

case 'CL120e' % Z1 has been adjusted

1385

case 'CL120e' % Z1 has been adjusted

1386

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1386

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1387

end

1387

end

1388

H_ctf2=H_low2.*ctle_gain2;

1388

H_ctf2=H_low2.*ctle_gain2;

1389

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1389

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1390

else

1390

else

1391

sigma_ne=0;

1391

sigma_ne=0;

1392

end

1392

end

1393

1393

1394

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1394

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1395

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1395

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

1396

if ~OP.SNR_TXwC0

1396

if ~OP.SNR_TXwC0

1397

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1397

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1398

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1398

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1399

else

1399

else

1400

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1400

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1401

end

1401

end

1402

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1402

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1403

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1403

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1404

else

1404

else

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

+1408

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1408

end

1409

end

1409

% Equation 93A-41 %%

1410

% Equation 93A-41 %%

1410

1411

1411

1412

1412

% Equation 93A-42 %%

1413

% Equation 93A-42 %%

1413

% number of sigmas needed depends on the required BER.

1414

% number of sigmas needed depends on the required BER.

1414

if param.Noise_Crest_Factor == 0

1415

if param.Noise_Crest_Factor == 0

1415

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1416

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1416

else

1417

else

1417

NS.ber_q=param.Noise_Crest_Factor;

1418

NS.ber_q=param.Noise_Crest_Factor;

1418

end

1419

end

1419

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1420

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1420

% enable overriding the Q factor of the BBN instrument.

1421

% enable overriding the Q factor of the BBN instrument.

1421

if OP.force_BBN_Q_factor

1422

if OP.force_BBN_Q_factor

1422

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1423

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1423

else

1424

else

1424

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1425

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1425

end

1426

end

1426

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1427

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1427

1428

1428

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1429

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1429

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1430

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1430

1431

1431

% Equation 93A-43 % only used for reporting bathtub curves

1432

% Equation 93A-43 % only used for reporting bathtub curves

1432

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1433

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1433

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1434

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1434

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1435

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1435

1436

1436

% Implementation of 93A.1.7.3 combination procedure

1437

% Implementation of 93A.1.7.3 combination procedure

1437

% (effectively Equation 93A-44) %%

1438

% (effectively Equation 93A-44) %%

1438

1439

1439

% Self-Channel Interference is thru residual result

1440

% Self-Channel Interference is thru residual result

1440

NS.sci_pdf = chdata(1).pdfr;

1441

NS.sci_pdf = chdata(1).pdfr;

1441

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1442

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1442

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1443

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1443

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1444

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1444

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1445

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1445

if OP.RX_CALIBRATION ==0

1446

if OP.RX_CALIBRATION ==0

1446

% Co-Channel Interference PDFs (for information only):

1447

% Co-Channel Interference PDFs (for information only):

1447

% initialize to deltas

1448

% initialize to deltas

1448

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1449

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1449

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1450

% serially convolve FEXT/NEXT PDFs

1451

% serially convolve FEXT/NEXT PDFs

1451

for k=2:param.number_of_s4p_files

1452

for k=2:param.number_of_s4p_files

1452

if isequal(chdata(k).type, 'NEXT')

1453

if isequal(chdata(k).type, 'NEXT')

1453

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1454

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1454

else % ... must be FEXT

1455

else % ... must be FEXT

1455

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1456

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1456

end

1457

end

1457

end

1458

end

1458

1459

1459

% find "peaks" of MDNEXT/MDFEXT for reporting

1460

% find "peaks" of MDNEXT/MDFEXT for reporting

1460

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1461

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1461

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1462

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1462

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1463

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1463

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1464

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1464

1465

1465

% Combined crosstalk effect

1466

% Combined crosstalk effect

1466

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1467

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1467

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1468

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1468

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1469

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1470

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1470

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1471

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1471

% combine cci and sci

1472

% combine cci and sci

1472

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1473

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1473

else

1474

else

1474

% for calibration there is no cci

1475

% for calibration there is no cci

1475

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1476

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1476

end

1477

end

1477

1478

1478

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1479

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1479

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1480

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1480

1481

1481

1482

1482

% Equation 93A-45

1483

% Equation 93A-45

1483

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1484

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1484

PDF=combined_interference_and_noise_pdf;

1485

PDF=combined_interference_and_noise_pdf;

1485

1486

1486

% Equation 93A-37

1487

% Equation 93A-37

1487

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1488

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1488

CDF=combined_interference_and_noise_cdf;

1489

CDF=combined_interference_and_noise_cdf;

1489

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1490

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1490

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1491

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1491

1492

1492

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1493

function [chdata,output_args]=FD_Processing(chdata,output_args,param,OP,SDDp2p,DO_ONCE)

1493

%This function calculates various frequency domain metrics

1494

%This function calculates various frequency domain metrics

1494

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1495

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1495

db = @(x) 20*log10(abs(x));

1496

db = @(x) 20*log10(abs(x));

1496

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1497

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1497

if OP.WC_PORTZ

1498

if OP.WC_PORTZ

1498

A_thru = param.a_thru(param.Tx_rd_sel);

1499

A_thru = param.a_thru(param.Tx_rd_sel);

1499

A_fext = param.a_fext(param.Tx_rd_sel);

1500

A_fext = param.a_fext(param.Tx_rd_sel);

1500

A_next = param.a_next(param.Tx_rd_sel);

1501

A_next = param.a_next(param.Tx_rd_sel);

1501

else

1502

else

1502

A_thru = param.a_thru(package_testcase);

1503

A_thru = param.a_thru(package_testcase);

1503

A_fext = param.a_fext(package_testcase);

1504

A_fext = param.a_fext(package_testcase);

1504

A_next = param.a_next(package_testcase);

1505

A_next = param.a_next(package_testcase);

1505

end

1506

end

1506

for i=1:param.number_of_s4p_files

1507

for i=1:param.number_of_s4p_files

1507

if isequal(chdata(i).type, 'THRU')

1508

if isequal(chdata(i).type, 'THRU')

1508

chdata(i).A=A_thru;

1509

chdata(i).A=A_thru;

1509

chdata(i).Aicn=A_thru;

1510

chdata(i).Aicn=A_thru;

1510

elseif isequal(chdata(i).type, 'FEXT')

1511

elseif isequal(chdata(i).type, 'FEXT')

1511

chdata(i).A=A_fext;

1512

chdata(i).A=A_fext;

1512

chdata(i).Aicn=param.a_icn_fext;

1513

chdata(i).Aicn=param.a_icn_fext;

1513

elseif isequal(chdata(i).type, 'NEXT')

1514

elseif isequal(chdata(i).type, 'NEXT')

1514

chdata(i).A=A_next;

1515

chdata(i).A=A_next;

1515

chdata(i).Aicn=param.a_icn_next;

1516

chdata(i).Aicn=param.a_icn_next;

1516

end

1517

end

1517

end

1518

end

1518

if OP.TDMODE

1519

if OP.TDMODE

1519

for i=1:param.number_of_s4p_files % freq delta for integration

1520

for i=1:param.number_of_s4p_files % freq delta for integration

1520

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1521

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1521

end

1522

end

1522

end

1523

end

1523

if ~DO_ONCE

1524

if ~DO_ONCE

1524

return;

1525

return;

1525

end

1526

end

1526

%Any new output_args fields set in this function should be initialized here as empty

1527

%Any new output_args fields set in this function should be initialized here as empty

1527

output_args.fitted_IL_dB_at_Fnq = [];

1528

output_args.fitted_IL_dB_at_Fnq = [];

1528

output_args.cable__assembley_loss=[];

1529

output_args.cable__assembley_loss=[];

1529

output_args.loss_with_PCB=[];

1530

output_args.loss_with_PCB=[];

1530

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1531

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1531

output_args.IL_dB_channel_only_at_Fnq=[];

1532

output_args.IL_dB_channel_only_at_Fnq=[];

1532

output_args.VTF_loss_dB_at_Fnq=[];

1533

output_args.VTF_loss_dB_at_Fnq=[];

1533

output_args.IL_db_die_to_die_at_Fnq=[];

1534

output_args.IL_db_die_to_die_at_Fnq=[];

1534

output_args.FOM_TDILN=[];

1535

output_args.FOM_TDILN=[];

1535

output_args.TD_ILN=[];

1536

output_args.TD_ILN=[];

1536

output_args.FOM_RILN=[];

1537

output_args.FOM_RILN=[];

1537

output_args.FOM_ILD=[];

1538

output_args.FOM_ILD=[];

1538

%TD_Mode is just a pass through to set the empty values and return

1539

%TD_Mode is just a pass through to set the empty values and return

1539

if ~OP.GET_FD

1540

if ~OP.GET_FD

1540

return;

1541

return;

1541

end

1542

end

1542

case_number=param.package_testcase_i;

1543

case_number=param.package_testcase_i;

1543

f2=param.f2;

1544

f2=param.f2;

1544

f1=param.f1;

1545

f1=param.f1;

1545

MDFEXT_ICN=0; MDNEXT_ICN=0;

1546

MDFEXT_ICN=0; MDNEXT_ICN=0;

1546

for i=1:param.number_of_s4p_files

1547

for i=1:param.number_of_s4p_files

1547

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1548

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1548

% Equation 93A-20 %%

1549

% Equation 93A-20 %%

1549

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1550

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(i).faxis./(param.f_r*param.fb));

1550

f=chdata(i).faxis;

1551

f=chdata(i).faxis;

1551

%

1552

%

1552

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1553

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

1553

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1554

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

1554

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1555

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine); % conditionally include the RCos filter for all IR conversion using COM_FD_to_TD

1555

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1556

H_txffe= Tx_FFE_Filter(param,f,param.Pkg_TXFFE_preset); % RIM 08-18-2022 to add forced TX ffe per package case

1556

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1557

H_r=H_bw.*H_bt.*H_RCos.*H_txffe; % RIM 08-18-2022 to add forced TX ffe per package case

1557

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1558

chdata(i).sdd21=chdata(i).sdd21.*H_r;

1558

if OP.DISPLAY_WINDOW

1559

if OP.DISPLAY_WINDOW

1559

if i==1

1560

if i==1

1560

figure(300+param.package_testcase_i);

1561

figure(300+param.package_testcase_i);

1561

subplot(3,1,1)

1562

subplot(3,1,1)

1562

hold on

1563

hold on

1563

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1564

plot(chdata(i).faxis/1e9, 20*log10(abs(squeeze(chdata(i).sdd21))), 'k-','linewidth',2, 'Disp',sprintf('VTF (no Tx/Rx eq)')')

1564

try

1565

try

1565

legend('NumColumns',2)

1566

legend('NumColumns',2)

1566

legend('location','south')

1567

legend('location','south')

1567

catch

1568

catch

1568

end

1569

end

1569

end

1570

end

1570

end

1571

end

1571

end

1572

end

1572

end

1573

end

1573

for i=1:param.number_of_s4p_files

1574

for i=1:param.number_of_s4p_files

1574

if i == 2

1575

if i == 2

1575

PSXT(1:length(chdata(i).sdd21f))=0;

1576

PSXT(1:length(chdata(i).sdd21f))=0;

1576

MDFEXT(1:length(chdata(i).sdd21f))=0;

1577

MDFEXT(1:length(chdata(i).sdd21f))=0;

1577

MDNEXT(1:length(chdata(i).sdd21f))=0;

1578

MDNEXT(1:length(chdata(i).sdd21f))=0;

1578

end

1579

end

1579

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1580

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1580

if isempty(a)

1581

if isempty(a)

1581

f2=chdata(i).faxis(end);

1582

f2=chdata(i).faxis(end);

1582

index_f2=length(chdata(i).faxis);

1583

index_f2=length(chdata(i).faxis);

1583

else

1584

else

1584

index_f2=a(1);

1585

index_f2=a(1);

1585

end

1586

end

1586

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1587

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1587

if isempty(b)

1588

if isempty(b)

1588

f1=chdata(i).faxis(1);

1589

f1=chdata(i).faxis(1);

1589

index_f1=1;

1590

index_f1=1;

1590

else

1591

else

1591

index_f1=b(1);

1592

index_f1=b(1);

1592

end

1593

end

1593

% R is the frequency dependent parameter for the sinc function use in the

1594

% R is the frequency dependent parameter for the sinc function use in the

1594

% PWF for ICN

1595

% PWF for ICN

1595

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1596

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1596

if(chdata(i).faxis(1)==0)

1597

if(chdata(i).faxis(1)==0)

1597

temp_angle(1)=1e-20;% we don't want to divide by zero

1598

temp_angle(1)=1e-20;% we don't want to divide by zero

1598

end

1599

end

1599

SINC = sin(temp_angle)./temp_angle;

1600

SINC = sin(temp_angle)./temp_angle;

1600

PWF_data=SINC.^2;

1601

PWF_data=SINC.^2;

1601

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1602

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1602

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1603

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1603

fr=param.f_r*param.fb;

1604

fr=param.f_r*param.fb;

1604

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1605

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1605

PWF_highpass=1;

1606

PWF_highpass=1;

1606

% Equation 93A-57 %

1607

% Equation 93A-57 %

1607

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1608

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1608

% freq delta for integration

1609

% freq delta for integration

1609

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1610

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1610

% from ba spec, this is basically ICN

1611

% from ba spec, this is basically ICN

1611

faxis_GHz = chdata(i).faxis/1e9;

1612

faxis_GHz = chdata(i).faxis/1e9;

1612

if isequal(chdata(i).type, 'THRU')

1613

if isequal(chdata(i).type, 'THRU')

1613

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1614

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1614

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1615

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1615

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1616

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1616

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1617

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1617

chdata(i).fit_ILatNq = fit_loss;

1618

chdata(i).fit_ILatNq = fit_loss;

1618

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1619

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1619

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1620

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1620

chdata(i).ILatNq = IL_interp;

1621

chdata(i).ILatNq = IL_interp;

1621

if OP.include_pcb

1622

if OP.include_pcb

1622

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1623

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1623

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1624

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1624

output_args.cable__assembley_loss=cable_loss;

1625

output_args.cable__assembley_loss=cable_loss;

1625

output_args.loss_with_PCB=loss_with_PCB;

1626

output_args.loss_with_PCB=loss_with_PCB;

1626

end

1627

end

1627

Nq_loss=chdata(i).ILatNq;

1628

Nq_loss=chdata(i).ILatNq;

1628

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1629

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1629

% time domain ref RR = complex fit pulse

1630

% time domain ref RR = complex fit pulse

1630

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1631

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1631

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1632

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1632

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1633

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1633

FOM_ILN_complex= TD_ILN.FOM;

1634

FOM_ILN_complex= TD_ILN.FOM;

1634

end

1635

end

1635

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1636

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1636

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1637

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1637

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_ILN_complex= TD_ILN.FOM;

1639

FOM_ILN_complex= TD_ILN.FOM;

1639

end

1640

end

1640

if OP.COMPUTE_TDILN

1641

if OP.COMPUTE_TDILN

1641

output_args.FOM_TDILN=FOM_TDILN;

1642

output_args.FOM_TDILN=FOM_TDILN;

1642

output_args.TD_ILN=TD_ILN; % struct

1643

output_args.TD_ILN=TD_ILN; % struct

1643

end

1644

end

1644

if OP.COMPUTE_RILN

1645

if OP.COMPUTE_RILN

1645

% Get RIL, RILN, and TD_RILN

1646

% Get RIL, RILN, and TD_RILN

1646

[RIL_struct]= capture_RIL_RILN(chdata);

1647

[RIL_struct]= capture_RIL_RILN(chdata);

1647

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1648

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1648

output_args.FOM_RILN=FOM_RILN;

1649

output_args.FOM_RILN=FOM_RILN;

1649

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1650

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1650

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1651

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1651

if plot_tdomain_debug== 1

1652

if plot_tdomain_debug== 1

1652

figure(988); set(gcf,'Tag','COM')

1653

figure(988); set(gcf,'Tag','COM')

1653

ax_1= subplot(3,1,1);

1654

ax_1= subplot(3,1,1);

1654

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1655

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1655

hold on;

1656

hold on;

1656

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1657

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1657

hold on;

1658

hold on;

1658

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1659

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1659

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1660

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1660

grid on;

1661

grid on;

1661

box on;

1662

box on;

1662

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1663

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1663

xlabel('Time [nsec]');

1664

xlabel('Time [nsec]');

1664

ylabel('Pulse Response [mV]');

1665

ylabel('Pulse Response [mV]');

1665

1666

1666

ax_2= subplot(3,1,2);

1667

ax_2= subplot(3,1,2);

1667

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1668

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1668

hold on;

1669

hold on;

1669

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1670

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1670

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1671

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1671

grid on;

1672

grid on;

1672

box on;

1673

box on;

1673

legend('REF', 'TD\_RILN');

1674

legend('REF', 'TD\_RILN');

1674

xlabel('Time [nsec]');

1675

xlabel('Time [nsec]');

1675

ylabel('Pulse Response [mV]');

1676

ylabel('Pulse Response [mV]');

1676

ax_3= subplot(3,1,3);

1677

ax_3= subplot(3,1,3);

1677

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1678

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1678

hold on;

1679

hold on;

1679

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1680

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1680

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1681

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1681

grid on;

1682

grid on;

1682

box on;

1683

box on;

1683

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1684

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1684

xlabel('Time [nsec]');

1685

xlabel('Time [nsec]');

1685

ylabel('Pulse Response [mV]');

1686

ylabel('Pulse Response [mV]');

1686

1687

1687

linkaxes([ax_1, ax_2, ax_3], 'x');

1688

linkaxes([ax_1, ax_2, ax_3], 'x');

1688

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1689

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1689

end

1690

end

1690

%---end. plotting ILN based on ILD and RILN

1691

%---end. plotting ILN based on ILD and RILN

1691

end

1692

end

1692

% Equation 93A-56 %

1693

% Equation 93A-56 %

1693

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1694

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1694

output_args.FOM_ILD=FOM_ILD;

1695

output_args.FOM_ILD=FOM_ILD;

1695

if OP.DEBUG

1696

if OP.DEBUG

1696

if OP.DISPLAY_WINDOW

1697

if OP.DISPLAY_WINDOW

1697

figure(300+case_number);

1698

figure(300+case_number);

1698

set(gcf,'Tag','COM')

1699

set(gcf,'Tag','COM')

1699

screen_size=get(0,'ScreenSize');

1700

screen_size=get(0,'ScreenSize');

1700

pos = get(gcf, 'OuterPosition');

1701

pos = get(gcf, 'OuterPosition');

1701

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1702

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1702

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1703

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1703

- (case_number-1)*[0 20 0 0]);

1704

- (case_number-1)*[0 20 0 0]);

1704

subplot(3,1,1)

1705

subplot(3,1,1)

1705

title('Losses')

1706

title('Losses')

1706

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1707

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1707

hold on

1708

hold on

1708

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1710

ylim(get(gca, 'ylim'));

1711

ylim(get(gca, 'ylim'));

1711

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1713

subplot(3,1,3)

1714

subplot(3,1,3)

1714

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1715

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1715

if OP.PLOT_CM

1716

if OP.PLOT_CM

1716

if case_number ==1

1717

if case_number ==1

1717

h350=figure(350);set(gcf,'Tag','COM')

1718

h350=figure(350);set(gcf,'Tag','COM')

1718

screen_size=get(0,'ScreenSize');

1719

screen_size=get(0,'ScreenSize');

1719

pos = get(gcf, 'OuterPosition');

1720

pos = get(gcf, 'OuterPosition');

1720

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1721

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1721

movegui(gcf,'center');

1722

movegui(gcf,'center');

1722

htabgroup350 = uitabgroup(h350);

1723

htabgroup350 = uitabgroup(h350);

1723

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1724

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1724

hax1 = axes('Parent', htab1);

1725

hax1 = axes('Parent', htab1);

1725

set(h350,'CurrentAxes',hax1)

1726

set(h350,'CurrentAxes',hax1)

1726

hold on

1727

hold on

1727

set(gcf,'Tag','COM')

1728

set(gcf,'Tag','COM')

1728

screen_size=get(0,'ScreenSize');

1729

screen_size=get(0,'ScreenSize');

1729

pos = get(gcf, 'OuterPosition');

1730

pos = get(gcf, 'OuterPosition');

1730

title('IL & CM Losses')

1731

title('IL & CM Losses')

1731

base=strrep(chdata(i).base,'_',' ');

1732

base=strrep(chdata(i).base,'_',' ');

1732

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1734

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1734

ylabel('dB')

1735

ylabel('dB')

1735

xlabel('GHz')

1736

xlabel('GHz')

1736

legend show

1737

legend show

1737

legend('Location','eastoutside')

1738

legend('Location','eastoutside')

1738

hold on

1739

hold on

1739

grid on

1740

grid on

1740

if param.number_of_s4p_files > 1

1741

if param.number_of_s4p_files > 1

1741

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1742

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1742

hax2 = axes('Parent', htab2);

1743

hax2 = axes('Parent', htab2);

1743

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1744

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1744

hax3 = axes('Parent', htab3);

1745

hax3 = axes('Parent', htab3);

1745

end

1746

end

1746

1747

1747

end

1748

end

1748

end

1749

end

1749

else

1750

else

1750

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1751

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1751

end

1752

end

1752

end

1753

end

1753

else % NEXT or FEXT

1754

else % NEXT or FEXT

1754

if isequal(chdata(i).type, 'FEXT')

1755

if isequal(chdata(i).type, 'FEXT')

1755

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1756

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1756

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1757

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1757

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1758

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1758

elseif isequal(chdata(i).type, 'NEXT')

1759

elseif isequal(chdata(i).type, 'NEXT')

1759

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1760

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1760

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1761

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1761

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1762

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1762

end

1763

end

1763

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1764

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1764

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1765

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1765

output_args.ICN_mV=ICN*1000;

1766

output_args.ICN_mV=ICN*1000;

1766

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1767

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1767

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1768

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1768

if case_number ==1

1769

if case_number ==1

1769

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1770

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1770

% hax2 = axes('Parent', htab2);

1771

% hax2 = axes('Parent', htab2);

1771

set(h350,'CurrentAxes',hax2)

1772

set(h350,'CurrentAxes',hax2)

1772

hold on

1773

hold on

1773

title('CM Losses')

1774

title('CM Losses')

1774

base=strrep(chdata(i).base,'_',' ');

1775

base=strrep(chdata(i).base,'_',' ');

1775

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1776

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1776

legend('Location','eastoutside')

1777

legend('Location','eastoutside')

1777

hold on

1778

hold on

1778

grid on

1779

grid on

1779

set(h350,'CurrentAxes',hax3)

1780

set(h350,'CurrentAxes',hax3)

1780

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1781

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1781

legend('Location','eastoutside')

1782

legend('Location','eastoutside')

1782

hold on

1783

hold on

1783

grid on

1784

grid on

1784

end

1785

end

1785

end

1786

end

1786

end

1787

end

1787

end % for loop

1788

end % for loop

1788

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1789

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1789

if OP.DEBUG && OP.DISPLAY_WINDOW

1790

if OP.DEBUG && OP.DISPLAY_WINDOW

1790

figure(300+case_number);set(gcf,'Tag','COM');

1791

figure(300+case_number);set(gcf,'Tag','COM');

1791

if param.number_of_s4p_files > 1

1792

if param.number_of_s4p_files > 1

1792

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1793

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1793

subplot(3,1,1)

1794

subplot(3,1,1)

1794

hold on

1795

hold on

1795

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1796

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1796

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1797

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1797

subplot(3,1,2)

1798

subplot(3,1,2)

1798

grid on

1799

grid on

1799

ILtemp=20*log10(abs(chdata(1).sdd21f));

1800

ILtemp=20*log10(abs(chdata(1).sdd21f));

1800

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1801

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1801

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1802

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1802

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1803

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1803

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1804

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1804

hold on

1805

hold on

1805

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1806

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1806

end

1807

end

1807

subplot(3,1,1)

1808

subplot(3,1,1)

1808

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1809

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1809

grid on; legend show

1810

grid on; legend show

1810

subplot(3,1,2)

1811

subplot(3,1,2)

1811

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1812

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1812

ylim([0 80])

1813

ylim([0 80])

1813

xlim([.1 100])

1814

xlim([.1 100])

1814

grid on; %legend show

1815

grid on; %legend show

1815

subplot(3,1,3)

1816

subplot(3,1,3)

1816

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1817

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1817

ylim([-3 3])

1818

ylim([-3 3])

1818

grid on; legend show

1819

grid on; legend show

1819

end

1820

end

1820

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1821

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1821

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1822

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1822

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1823

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1823

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1824

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1824

output_args.VTF_loss_dB_at_Fnq=total_loss;

1825

output_args.VTF_loss_dB_at_Fnq=total_loss;

1825

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1826

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1826

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1827

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1827

function [ V0 ] = FFE( C , cmx,spui, V )

1828

function [ V0 ] = FFE( C , cmx,spui, V )

1828

% C FFE taps

1829

% C FFE taps

1829

% cmx number of precursors taps

1830

% cmx number of precursors taps

1830

% spui samples per ui

1831

% spui samples per ui

1831

% V input signal

1832

% V input signal

1832

%speed ups implemented:

1833

%speed ups implemented:

1833

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1834

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1834

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1835

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1835

1836

1836

V0=0;

1837

V0=0;

1837

if iscolumn(V); V=V.';end

1838

if iscolumn(V); V=V.';end

1838

for i=1:length(C)

1839

for i=1:length(C)

1839

if C(i)~=0

1840

if C(i)~=0

1840

ishift=(i-1-cmx)*spui;

1841

ishift=(i-1-cmx)*spui;

1841

V0=circshift(V',[ishift,0])*C(i)+V0;

1842

V0=circshift(V',[ishift,0])*C(i)+V0;

1842

end

1843

end

1843

end

1844

end

1844

%V0=circshift(V0,[(-cmx)*spui,0]);

1845

%V0=circshift(V0,[(-cmx)*spui,0]);

1845

% disp(max(V0));

1846

% disp(max(V0));

1846

1847

1847

1848

1848

% begin yasuo patch 12/11/2018

1849

% begin yasuo patch 12/11/2018

1849

% calculate sigma (standard deviation) value of PDF

1850

% calculate sigma (standard deviation) value of PDF

1850

function [ V0 ] = FFE_Fast( C,V_shift )

1851

function [ V0 ] = FFE_Fast( C,V_shift )

1851

% C FFE taps

1852

% C FFE taps

1852

% V input signal separated into length(C) columns with circshift already performed

1853

% V input signal separated into length(C) columns with circshift already performed

1853

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1854

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1854

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1855

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1855

% saved by pre-shifting it and remembering it across loops

1856

% saved by pre-shifting it and remembering it across loops

1856

% Another speed up: only multiply by indices of C that are not 0

1857

% Another speed up: only multiply by indices of C that are not 0

1857

1858

1858

V0=0;

1859

V0=0;

1859

for i=1:length(C)

1860

for i=1:length(C)

1860

if C(i)~=0

1861

if C(i)~=0

1861

V0=V_shift(:,i)*C(i)+V0;

1862

V0=V_shift(:,i)*C(i)+V0;

1862

end

1863

end

1863

end

1864

end

1864

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1865

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1865

1866

1866

hisi=h(isi_start:isi_end);

1867

hisi=h(isi_start:isi_end);

1867

hisi=hisi(param.N_tail_start:param.N_bmax);

1868

hisi=hisi(param.N_tail_start:param.N_bmax);

1868

bank_size = param.N_bf;

1869

bank_size = param.N_bf;

1869

num_groups = param.N_bg;

1870

num_groups = param.N_bg;

1870

1871

1871

1872

1872

%start with one by one Floating Tap

1873

%start with one by one Floating Tap

1873

num_isi=length(hisi);

1874

num_isi=length(hisi);

1874

max_isi=num_isi-bank_size+1;

1875

max_isi=num_isi-bank_size+1;

1875

valid_tap_locations=1:max_isi;

1876

valid_tap_locations=1:max_isi;

1876

all_idx=[];

1877

all_idx=[];

1877

for j=1:num_groups

1878

for j=1:num_groups

1878

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1879

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1879

for k=1:length(valid_tap_locations)

1880

for k=1:length(valid_tap_locations)

1880

this_location=valid_tap_locations(k);

1881

this_location=valid_tap_locations(k);

1881

new_idx = [all_idx this_location:this_location+bank_size-1];

1882

new_idx = [all_idx this_location:this_location+bank_size-1];

1882

new_idx=sort(new_idx);

1883

new_idx=sort(new_idx);

1883

new_idx = new_idx+param.N_tail_start-1;

1884

new_idx = new_idx+param.N_tail_start-1;

1884

%calculate FOM for each one

1885

%calculate FOM for each one

1885

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1886

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1886

end

1887

end

1887

%choose the location with best FOM

1888

%choose the location with best FOM

1888

%add it to the "all_idx" list and remove it from valid locations

1889

%add it to the "all_idx" list and remove it from valid locations

1889

[~,best_FOM_idx]=max(best_FOM);

1890

[~,best_FOM_idx]=max(best_FOM);

1890

start_tap = valid_tap_locations(best_FOM_idx);

1891

start_tap = valid_tap_locations(best_FOM_idx);

1891

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1892

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1892

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1893

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1893

remove_range(remove_range>length(valid_tap_locations))=[];

1894

remove_range(remove_range>length(valid_tap_locations))=[];

1894

valid_tap_locations(remove_range)=[];

1895

valid_tap_locations(remove_range)=[];

1895

1896

1896

%Also remove illegal taps from valid locations

1897

%Also remove illegal taps from valid locations

1897

%illegal taps are ones that would overlap with the chosen bank

1898

%illegal taps are ones that would overlap with the chosen bank

1898

bad_tap=start_tap-bank_size+1:start_tap-1;

1899

bad_tap=start_tap-bank_size+1:start_tap-1;

1899

bad_tap(bad_tap<1)=[];

1900

bad_tap(bad_tap<1)=[];

1900

for n=1:length(bad_tap)

1901

for n=1:length(bad_tap)

1901

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1902

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1902

if ~isempty(bad_tap_idx)

1903

if ~isempty(bad_tap_idx)

1903

valid_tap_locations(bad_tap_idx)=[];

1904

valid_tap_locations(bad_tap_idx)=[];

1904

end

1905

end

1905

end

1906

end

1906

end

1907

end

1907

1908

1908

%put idx back in the right location (adding N_tail_start)

1909

%put idx back in the right location (adding N_tail_start)

1909

idx = all_idx+param.N_tail_start-1;

1910

idx = all_idx+param.N_tail_start-1;

1910

idx = sort(idx);

1911

idx = sort(idx);

1911

function [ V0 ] = Fract_T_FFE( V , skew_step)

1912

function [ V0 ] = Fract_T_FFE( V , skew_step)

1912

% skew_step sub UI skew assuming param.samples_per_ui

1913

% skew_step sub UI skew assuming param.samples_per_ui

1913

% V input signal

1914

% V input signal

1914

% V0 output signal

1915

% V0 output signal

1915

% Richard Mellitz 8/17/2021

1916

% Richard Mellitz 8/17/2021

1916

V0=0;

1917

V0=0;

1917

if iscolumn(V); V=V.';end

1918

if iscolumn(V); V=V.';end

1918

ishift=skew_step;

1919

ishift=skew_step;

1919

V0=circshift(V',[ishift,0])'+V;

1920

V0=circshift(V',[ishift,0])'+V;

1920

V0=V0/2;

1921

V0=V0/2;

1921

function out=Full_Grid_Matrix(in)

1922

function out=Full_Grid_Matrix(in)

1922

1923

1923

%create a full grid matrix of input variables

1924

%create a full grid matrix of input variables

1924

%used to create the full grid of all txffe cases

1925

%used to create the full grid of all txffe cases

1925

%example:

1926

%example:

1926

%Full_Grid_Matrix({ [1 2] [100 200] })

1927

%Full_Grid_Matrix({ [1 2] [100 200] })

1927

%out =

1928

%out =

1928

% 1 100

1929

% 1 100

1929

% 1 200

1930

% 1 200

1930

% 2 100

1931

% 2 100

1931

% 2 200

1932

% 2 200

1932

%

1933

%

1933

%input can also be mixed between numeric and cell of char

1934

%input can also be mixed between numeric and cell of char

1934

%example:

1935

%example:

1935

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1936

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1936

%out =

1937

%out =

1937

% {[1]} {'A'}

1938

% {[1]} {'A'}

1938

% {[1]} {'B'}

1939

% {[1]} {'B'}

1939

% {[2]} {'A'}

1940

% {[2]} {'A'}

1940

% {[2]} {'B'}

1941

% {[2]} {'B'}

1941

1942

1942

if ~iscell(in)

1943

if ~iscell(in)

1943

error('input must be cell array of individual sweep variables');

1944

error('input must be cell array of individual sweep variables');

1944

end

1945

end

1945

1946

1946

num_columns=length(in);

1947

num_columns=length(in);

1947

num_cases=prod(cellfun('length',in));

1948

num_cases=prod(cellfun('length',in));

1948

1949

1949

cell_output=0;

1950

cell_output=0;

1950

cell_indices=cellfun(@(x) iscell(x),in);

1951

cell_indices=cellfun(@(x) iscell(x),in);

1951

if any(cell_indices)

1952

if any(cell_indices)

1952

cell_output=1;

1953

cell_output=1;

1953

end

1954

end

1954

if cell_output

1955

if cell_output

1955

for k=find(~cell_indices)

1956

for k=find(~cell_indices)

1956

in{k}=num2cell(in{k});

1957

in{k}=num2cell(in{k});

1957

end

1958

end

1958

end

1959

end

1959

1960

1960

if cell_output

1961

if cell_output

1961

out=cell(num_cases,num_columns);

1962

out=cell(num_cases,num_columns);

1962

else

1963

else

1963

out=zeros(num_cases,num_columns);

1964

out=zeros(num_cases,num_columns);

1964

end

1965

end

1965

1966

1966

%num_repetitions controls how many times each element of the column

1967

%num_repetitions controls how many times each element of the column

1967

%repeats. The first column is always just a copy of itself since every

1968

%repeats. The first column is always just a copy of itself since every

1968

%case will vary.

1969

%case will vary.

1969

num_repetitions=1;

1970

num_repetitions=1;

1970

for k=num_columns:-1:1

1971

for k=num_columns:-1:1

1971

this_column=in{k}(:);

1972

this_column=in{k}(:);

1972

%copy the column into a matrix to create the repetitions needed

1973

%copy the column into a matrix to create the repetitions needed

1973

B=repmat(this_column,[1 num_repetitions]);

1974

B=repmat(this_column,[1 num_repetitions]);

1974

%reshape into single column (actual repetitions)

1975

%reshape into single column (actual repetitions)

1975

C=reshape(B',[numel(B) 1]);

1976

C=reshape(B',[numel(B) 1]);

1976

%repeat the single column to build the entire length required

1977

%repeat the single column to build the entire length required

1977

num_repeats=num_cases/length(C);

1978

num_repeats=num_cases/length(C);

1978

D=repmat(C,[num_repeats 1]);

1979

D=repmat(C,[num_repeats 1]);

1979

out(:,k)=D;

1980

out(:,k)=D;

1980

%determine how many repetitions the next column needs

1981

%determine how many repetitions the next column needs

1981

num_repetitions=num_repetitions*length(this_column);

1982

num_repetitions=num_repetitions*length(this_column);

1982

end

1983

end

1983

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1984

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1984

% p=cpdf(type, ...)

1985

% p=cpdf(type, ...)

1985

%

1986

%

1986

% CPDF is a probability mass function for discrete distributions or an

1987

% CPDF is a probability mass function for discrete distributions or an

1987

% approxmation of a PDF for continuous distributions.

1988

% approxmation of a PDF for continuous distributions.

1988

%

1989

%

1989

% cpdf is internally normalized so that the sum of probabilities is 1

1990

% cpdf is internally normalized so that the sum of probabilities is 1

1990

% (regardless of bin size).

1991

% (regardless of bin size).

1991

1992

1992

% Internal fields:

1993

% Internal fields:

1993

% Min: *bin number* of minimum value.

1994

% Min: *bin number* of minimum value.

1994

% BinSize: size of PDF bins. Bin center is the representative value.

1995

% BinSize: size of PDF bins. Bin center is the representative value.

1995

% Vec: vector of probabilities per bin.

1996

% Vec: vector of probabilities per bin.

1996

1997

1997

pdf=EmptyPDF;

1998

pdf=EmptyPDF;

1998

1999

1999

rounded_values_div_binsize=round(values/pdf.BinSize);

2000

rounded_values_div_binsize=round(values/pdf.BinSize);

2000

%values=pdf.BinSize*rounded_values_div_binsize;

2001

%values=pdf.BinSize*rounded_values_div_binsize;

2001

2002

2002

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2003

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2003

% if all(values==0)

2004

% if all(values==0)

2004

% return;

2005

% return;

2005

% end

2006

% end

2006

%

2007

%

2007

% %speed up for all values rounded to the same bin

2008

% %speed up for all values rounded to the same bin

2008

% %The output pdf is the same as the

2009

% %The output pdf is the same as the

2009

% %empty pdf, but the x value is non-zero (but still scalar)

2010

% %empty pdf, but the x value is non-zero (but still scalar)

2010

% if all(values==values(1))

2011

% if all(values==values(1))

2011

% pdf.Min=rounded_values_div_binsize(1);

2012

% pdf.Min=rounded_values_div_binsize(1);

2012

% pdf.x=values(1);

2013

% pdf.x=values(1);

2013

% return;

2014

% return;

2014

% end

2015

% end

2015

%

2016

%

2016

% %The code below requires that values is

2017

% %The code below requires that values is

2017

% %sorted. Generally this should be true, but check to be sure

2018

% %sorted. Generally this should be true, but check to be sure

2018

% if ~issorted(values)

2019

% if ~issorted(values)

2019

% [values,si]=sort(values);

2020

% [values,si]=sort(values);

2020

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2021

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2021

% probs=probs(si);

2022

% probs=probs(si);

2022

% end

2023

% end

2023

2024

2024

2025

2025

%pdf.x=values(1):pdf.BinSize:values(end);

2026

%pdf.x=values(1):pdf.BinSize:values(end);

2026

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2027

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2027

pdf.Min=rounded_values_div_binsize(1);

2028

pdf.Min=rounded_values_div_binsize(1);

2028

2029

2029

pdf.y=zeros(size(pdf.x));

2030

pdf.y=zeros(size(pdf.x));

2030

%The rounded values divided by binsize will reveal the bin number if

2031

%The rounded values divided by binsize will reveal the bin number if

2031

%pdf.Min is subtracted from it

2032

%pdf.Min is subtracted from it

2032

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2033

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2033

%Can avoid one addition by inserting the first probability

2034

%Can avoid one addition by inserting the first probability

2034

%actually helps when calling this 2 million times

2035

%actually helps when calling this 2 million times

2035

pdf.y(bin_placement(1))=probs(1);

2036

pdf.y(bin_placement(1))=probs(1);

2036

for k=2:length(values)

2037

for k=2:length(values)

2037

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2038

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2038

end

2039

end

2039

2040

2040

2041

2041

%Have already ensured that sum(pdf.y)=1

2042

%Have already ensured that sum(pdf.y)=1

2042

%pdf.y=pdf.y/sum(pdf.y);

2043

%pdf.y=pdf.y/sum(pdf.y);

2043

2044

2044

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2045

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2045

% error('PDF must be real and nonnegative');

2046

% error('PDF must be real and nonnegative');

2046

% end

2047

% end

2047

2048

2048

% pMax=pdf.Min+length(pdf.y)-1;

2049

% pMax=pdf.Min+length(pdf.y)-1;

2049

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2050

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2050

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2051

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2051

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2052

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2052

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2053

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2053

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2054

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2054

2055

2055

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2056

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2056

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2057

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2057

2058

2058

%% step 0

2059

%% step 0

2059

COM_from_matlab=20*log10(A_s/A_ni);

2060

COM_from_matlab=20*log10(A_s/A_ni);

2060

L=param.levels;

2061

L=param.levels;

2061

DER0=param.specBER;

2062

DER0=param.specBER;

2062

%% step 1 from slide 6/5

2063

%% step 1 from slide 6/5

2063

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2064

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2064

main=A_peak;

2065

main=A_peak;

2065

k_DER=qfuncinv(param.specBER);

2066

k_DER=qfuncinv(param.specBER);

2066

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2067

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2067

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2068

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2068

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2069

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2069

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2070

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2070

if A_s >= A_ni

2071

if A_s >= A_ni

2071

%% step 2 slide 10/8

2072

%% step 2 slide 10/8

2072

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2073

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2073

%% step 2 slide 10/8

2074

%% step 2 slide 10/8

2074

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2075

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2075

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2076

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2076

%% step 3 side 11/9

2077

%% step 3 side 11/9

2077

j=1:200;

2078

j=1:200;

2078

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2079

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2079

DER_MLSE_CDF=0; jj=1;

2080

DER_MLSE_CDF=0; jj=1;

2080

DER_delta = inf;

2081

DER_delta = inf;

2081

while DER_delta > .001

2082

while DER_delta > .001

2082

last_DER_MLSE_CDF=DER_MLSE_CDF;

2083

last_DER_MLSE_CDF=DER_MLSE_CDF;

2083

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2084

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2084

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2085

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2085

jj=jj+1;

2086

jj=jj+1;

2086

end

2087

end

2087

%% step 4 slide 12/10

2088

%% step 4 slide 12/10

2088

SNR_DFE_eqivalent=SNR_DFE*(...

2089

SNR_DFE_eqivalent=SNR_DFE*(...

2089

(L-1)*sigma_noise/main * qfuncinv(...

2090

(L-1)*sigma_noise/main * qfuncinv(...

2090

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2091

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2091

) ...

2092

) ...

2092

)^2;

2093

)^2;

2093

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2094

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2094

(L-1)/main * CDF_inv_ev(...

2095

(L-1)/main * CDF_inv_ev(...

2095

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2096

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2096

,PDF, CDF ) ...

2097

,PDF, CDF ) ...

2097

)^2;

2098

)^2;

2098

2099

2099

%% step 5 slide 13/11

2100

%% step 5 slide 13/11

2100

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2101

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2101

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2102

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2102

new_com_CDF=COM_from_matlab+delta_com_CDF;

2103

new_com_CDF=COM_from_matlab+delta_com_CDF;

2103

else

2104

else

2104

warning('MLSE not applied because there is more noise than signal')

2105

warning('MLSE not applied because there is more noise than signal')

2105

DER_MLSE=[];

2106

DER_MLSE=[];

2106

DER_MLSE_CDF=[];

2107

DER_MLSE_CDF=[];

2107

SNR_DFE_eqivalent=[];

2108

SNR_DFE_eqivalent=[];

2108

SNR_DFE_eqivalent_CDF=[];

2109

SNR_DFE_eqivalent_CDF=[];

2109

new_com_CDF=COM_from_matlab;

2110

new_com_CDF=COM_from_matlab;

2110

delta_com_CDF=0;

2111

delta_com_CDF=0;

2111

delta_com=0;

2112

delta_com=0;

2112

SNR_DFE=[];

2113

SNR_DFE=[];

2113

end

2114

end

2114

2115

2115

%%

2116

%%

2116

MLSE_results.COM_from_matlab=COM_from_matlab;

2117

MLSE_results.COM_from_matlab=COM_from_matlab;

2117

MLSE_results.SNR_DFE=SNR_DFE;

2118

MLSE_results.SNR_DFE=SNR_DFE;

2118

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2119

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2119

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2120

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2120

MLSE_results.sigma_noise=sigma_noise;

2121

MLSE_results.sigma_noise=sigma_noise;

2121

MLSE_results.SNR_dB=SNR_dB ;

2122

MLSE_results.SNR_dB=SNR_dB ;

2122

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2123

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2123

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2124

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2124

MLSE_results.COM_Gaussian=new_com_CDF;

2125

MLSE_results.COM_Gaussian=new_com_CDF;

2125

MLSE_results.COM_CDF=new_com_CDF;

2126

MLSE_results.COM_CDF=new_com_CDF;

2126

MLSE_results.k_DER=k_DER;

2127

MLSE_results.k_DER=k_DER;

2127

MLSE_results.delta_com_CDF=delta_com_CDF;

2128

MLSE_results.delta_com_CDF=delta_com_CDF;

2128

MLSE_results.delta_com_Gaussian=delta_com;

2129

MLSE_results.delta_com_Gaussian=delta_com;

2129

2130

2130

2131

2131

2132

2132

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2133

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2133

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2134

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2134

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2135

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2135

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2136

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2136

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2137

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2137

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2138

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2138

%% step 0

2139

%% step 0

2139

COM_from_matlab=20*log10(A_s/A_ni);

2140

COM_from_matlab=20*log10(A_s/A_ni);

2140

L=param.levels;

2141

L=param.levels;

2141

DER0=param.specBER;

2142

DER0=param.specBER;

2142

%% step 1 from slide 6 shakiba_3dj_01_230116

2143

%% step 1 from slide 6 shakiba_3dj_01_230116

2143

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2144

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2144

main=A_peak;

2145

main=A_peak;

2145

k_DER=qfuncinv(param.specBER);

2146

k_DER=qfuncinv(param.specBER);

2146

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2147

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2147

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2148

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2148

% if A_s >= A_ni

2149

% if A_s >= A_ni

2149

if 1

2150

if 1

2150

%% step 2 slide 10 shakiba_3dj_01_230116

2151

%% step 2 slide 10 shakiba_3dj_01_230116

2151

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2152

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2152

%% step 2 slide 10 not used

2153

%% step 2 slide 10 not used

2153

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2154

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2154

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2155

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2155

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2156

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2156

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2157

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2157

Rn=ifft(S_n)*param.fb;

2158

Rn=ifft(S_n)*param.fb;

2158

Rho_row=Rn/Rn(1);

2159

Rho_row=Rn/Rn(1);

2159

Rn_len=length(Rn);

2160

Rn_len=length(Rn);

2160

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2161

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2161

for j=1:Rn_len

2162

for j=1:Rn_len

2162

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2163

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2163

end

2164

end

2164

rho_noiseEE_row=Rho_row.*alphas_row;

2165

rho_noiseEE_row=Rho_row.*alphas_row;

2165

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2166

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2166

for j=1:Rn_len

2167

for j=1:Rn_len

2167

rho_noiseEE(j,j)=(1-alpha)^2;

2168

rho_noiseEE(j,j)=(1-alpha)^2;

2168

end

2169

end

2169

rho_noiseEE(1,1)=1;

2170

rho_noiseEE(1,1)=1;

2170

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2171

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2171

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2172

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2172

% determine complete matrix

2173

% determine complete matrix

2173

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2174

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2174

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2175

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2175

%% shakiba_3dj_elec_01a_230504 slide 17

2176

%% shakiba_3dj_elec_01a_230504 slide 17

2176

j=1:Rn_len;

2177

j=1:Rn_len;

2177

DER_MLSE=[];

2178

DER_MLSE=[];

2178

DER_MLSE_CDF=0; jj=1;

2179

DER_MLSE_CDF=0; jj=1;

2179

DER_MLSE_CDFold=0;

2180

DER_MLSE_CDFold=0;

2180

DER_delta = inf;

2181

DER_delta = inf;

2181

% slight modified for PAM4 DER vs SER

2182

% slight modified for PAM4 DER vs SER

2182

while DER_delta > .0001 && jj<=Rn_len || jj==1

2183

while DER_delta > .0001 && jj<=Rn_len || jj==1

2183

last_DER_MLSE_CDF=DER_MLSE_CDF;

2184

last_DER_MLSE_CDF=DER_MLSE_CDF;

2184

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2185

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2185

DER_MLSE_CDF= ...

2186

DER_MLSE_CDF= ...

2186

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2187

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2187

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2188

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2188

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2189

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2189

jj=jj+1;

2190

jj=jj+1;

2190

end

2191

end

2191

%% shakiba_3dj_elec_01a_230504 slide 19

2192

%% shakiba_3dj_elec_01a_230504 slide 19

2192

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2193

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2193

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2194

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2194

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2195

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2195

(L-1)/main * CDF_inv_ev(...

2196

(L-1)/main * CDF_inv_ev(...

2196

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2197

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2197

,PDF, CDF ) ...

2198

,PDF, CDF ) ...

2198

)^2;

2199

)^2;

2199

%% step 5 shakiba_3dj_01_230116 slide 13

2200

%% step 5 shakiba_3dj_01_230116 slide 13

2200

delta_com=[];

2201

delta_com=[];

2201

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2202

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2202

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2203

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2203

new_com_CDF=COM_from_matlab+delta_com_CDF;

2204

new_com_CDF=COM_from_matlab+delta_com_CDF;

2204

else

2205

else

2205

warning('MLSE not applied because there is more noise than signal')

2206

warning('MLSE not applied because there is more noise than signal')

2206

DER_MLSE=[];

2207

DER_MLSE=[];

2207

DER_MLSE_CDF=[];

2208

DER_MLSE_CDF=[];

2208

SNR_DFE_eqivalent=[];

2209

SNR_DFE_eqivalent=[];

2209

SNR_DFE_eqivalent_CDF=[];

2210

SNR_DFE_eqivalent_CDF=[];

2210

new_com_CDF=COM_from_matlab;

2211

new_com_CDF=COM_from_matlab;

2211

delta_com_CDF=0;

2212

delta_com_CDF=0;

2212

delta_com=0;

2213

delta_com=0;

2213

SNR_DFE=[];

2214

SNR_DFE=[];

2214

end

2215

end

2215

SNR_DFE_eqivalent=[];

2216

SNR_DFE_eqivalent=[];

2216

%%

2217

%%

2217

MLSE_results.COM_from_matlab=COM_from_matlab;

2218

MLSE_results.COM_from_matlab=COM_from_matlab;

2218

MLSE_results.SNR_DFE=SNR_DFE;

2219

MLSE_results.SNR_DFE=SNR_DFE;

2219

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2220

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2220

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2221

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2221

MLSE_results.sigma_noise=sigma_noise;

2222

MLSE_results.sigma_noise=sigma_noise;

2222

MLSE_results.SNR_dB=SNR_dB ;

2223

MLSE_results.SNR_dB=SNR_dB ;

2223

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2224

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2224

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2225

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2225

MLSE_results.COM_Gaussian=new_com_CDF;

2226

MLSE_results.COM_Gaussian=new_com_CDF;

2226

MLSE_results.COM_CDF=new_com_CDF;

2227

MLSE_results.COM_CDF=new_com_CDF;

2227

MLSE_results.k_DER=k_DER;

2228

MLSE_results.k_DER=k_DER;

2228

MLSE_results.delta_com_CDF=delta_com_CDF;

2229

MLSE_results.delta_com_CDF=delta_com_CDF;

2229

MLSE_results.delta_com_Gaussian=delta_com;

2230

MLSE_results.delta_com_Gaussian=delta_com;

2230

2231

2231

2232

2232

2233

2233

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2234

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2234

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2235

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2235

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2236

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2236

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2237

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2237

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2238

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2238

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2239

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2239

%% step 0

2240

%% step 0

2240

COM_from_matlab=20*log10(A_s/A_ni);

2241

COM_from_matlab=20*log10(A_s/A_ni);

2241

L=param.levels;

2242

L=param.levels;

2242

DER0=param.specBER;

2243

DER0=param.specBER;

2243

%% step 1 from slide 6 shakiba_3dj_01_230116

2244

%% step 1 from slide 6 shakiba_3dj_01_230116

2244

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2245

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2245

main=A_peak;

2246

main=A_peak;

2246

k_DER=qfuncinv(param.specBER);

2247

k_DER=qfuncinv(param.specBER);

2247

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2248

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2248

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2249

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2249

% if A_s >= A_ni

2250

% if A_s >= A_ni

2250

if 1

2251

if 1

2251

%% step 2 slide 10 shakiba_3dj_01_230116

2252

%% step 2 slide 10 shakiba_3dj_01_230116

2252

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2253

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2253

%% step 2 slide 10 not used

2254

%% step 2 slide 10 not used

2254

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2255

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2255

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2256

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2256

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2257

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2257

S_n=PSD_results.S_n; % total agregate noise PSD

2258

S_n=PSD_results.S_n; % total agregate noise PSD

2258

Rn=ifft(S_n)*param.fb;

2259

Rn=ifft(S_n)*param.fb;

2259

Rho_row=Rn/Rn(1);

2260

Rho_row=Rn/Rn(1);

2260

Rn_len=length(Rn);

2261

Rn_len=length(Rn);

2261

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2262

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2262

for j=1:Rn_len

2263

for j=1:Rn_len

2263

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2264

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2264

end

2265

end

2265

rho_noiseEE_row=Rho_row.*alphas_row;

2266

rho_noiseEE_row=Rho_row.*alphas_row;

2266

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2267

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2267

for j=1:Rn_len

2268

for j=1:Rn_len

2268

rho_noiseEE(j,j)=(1-alpha)^2;

2269

rho_noiseEE(j,j)=(1-alpha)^2;

2269

end

2270

end

2270

rho_noiseEE(1,1)=1;

2271

rho_noiseEE(1,1)=1;

2271

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2272

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2272

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2273

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2273

% determine complete matrix

2274

% determine complete matrix

2274

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2275

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2275

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2276

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2276

%% shakiba_3dj_elec_01a_230504 slide 17

2277

%% shakiba_3dj_elec_01a_230504 slide 17

2277

j=1:Rn_len;

2278

j=1:Rn_len;

2278

DER_MLSE=[];

2279

DER_MLSE=[];

2279

DER_MLSE_CDF=0; jj=1;

2280

DER_MLSE_CDF=0; jj=1;

2280

DER_MLSE_CDFold=0;

2281

DER_MLSE_CDFold=0;

2281

DER_delta = inf;

2282

DER_delta = inf;

2282

% slight modified for PAM4 DER vs SER

2283

% slight modified for PAM4 DER vs SER

2283

while DER_delta > .0001 && jj<=Rn_len || jj==1

2284

while DER_delta > .0001 && jj<=Rn_len || jj==1

2284

last_DER_MLSE_CDF=DER_MLSE_CDF;

2285

last_DER_MLSE_CDF=DER_MLSE_CDF;

2285

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2286

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2286

DER_MLSE_CDF= ...

2287

DER_MLSE_CDF= ...

2287

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2288

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2288

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2289

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2289

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2290

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2290

jj=jj+1;

2291

jj=jj+1;

2291

end

2292

end

2292

%% shakiba_3dj_elec_01a_230504 slide 19

2293

%% shakiba_3dj_elec_01a_230504 slide 19

2293

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2294

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2294

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2295

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2295

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2296

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2296

(L-1)/main * CDF_inv_ev(...

2297

(L-1)/main * CDF_inv_ev(...

2297

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2298

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2298

,PDF, CDF ) ...

2299

,PDF, CDF ) ...

2299

)^2;

2300

)^2;

2300

%% step 5 shakiba_3dj_01_230116 slide 13

2301

%% step 5 shakiba_3dj_01_230116 slide 13

2301

delta_com=[];

2302

delta_com=[];

2302

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2303

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2303

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2304

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2304

new_com_CDF=COM_from_matlab+delta_com_CDF;

2305

new_com_CDF=COM_from_matlab+delta_com_CDF;

2305

else

2306

else

2306

warning('MLSE not applied because there is more noise than signal')

2307

warning('MLSE not applied because there is more noise than signal')

2307

DER_MLSE=[];

2308

DER_MLSE=[];

2308

DER_MLSE_CDF=[];

2309

DER_MLSE_CDF=[];

2309

SNR_DFE_eqivalent=[];

2310

SNR_DFE_eqivalent=[];

2310

SNR_DFE_eqivalent_CDF=[];

2311

SNR_DFE_eqivalent_CDF=[];

2311

new_com_CDF=COM_from_matlab;

2312

new_com_CDF=COM_from_matlab;

2312

delta_com_CDF=0;

2313

delta_com_CDF=0;

2313

delta_com=0;

2314

delta_com=0;

2314

SNR_DFE=[];

2315

SNR_DFE=[];

2315

end

2316

end

2316

SNR_DFE_eqivalent=[];

2317

SNR_DFE_eqivalent=[];

2317

%%

2318

%%

2318

MLSE_results.COM_from_matlab=COM_from_matlab;

2319

MLSE_results.COM_from_matlab=COM_from_matlab;

2319

MLSE_results.SNR_DFE=SNR_DFE;

2320

MLSE_results.SNR_DFE=SNR_DFE;

2320

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2321

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2321

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2322

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2322

MLSE_results.sigma_noise=sigma_noise;

2323

MLSE_results.sigma_noise=sigma_noise;

2323

MLSE_results.SNR_dB=SNR_dB ;

2324

MLSE_results.SNR_dB=SNR_dB ;

2324

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2325

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2325

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2326

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2326

MLSE_results.COM_Gaussian=new_com_CDF;

2327

MLSE_results.COM_Gaussian=new_com_CDF;

2327

MLSE_results.COM_CDF=new_com_CDF;

2328

MLSE_results.COM_CDF=new_com_CDF;

2328

MLSE_results.k_DER=k_DER;

2329

MLSE_results.k_DER=k_DER;

2329

MLSE_results.delta_com_CDF=delta_com_CDF;

2330

MLSE_results.delta_com_CDF=delta_com_CDF;

2330

MLSE_results.delta_com_Gaussian=delta_com;

2331

MLSE_results.delta_com_Gaussian=delta_com;

2331

2332

2332

2333

2333

2334

2334

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2335

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2335

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2336

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2336

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2337

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2337

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2338

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2338

2339

2339

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2340

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2340

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2341

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2341

2342

2342

%% step 0

2343

%% step 0

2343

COM_from_matlab=20*log10(A_s/A_ni);

2344

COM_from_matlab=20*log10(A_s/A_ni);

2344

L=param.levels;

2345

L=param.levels;

2345

DER0=param.specBER;

2346

DER0=param.specBER;

2346

%% step 1 from slide 6/5

2347

%% step 1 from slide 6/5

2347

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2348

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2348

main=A_peak;

2349

main=A_peak;

2349

k_DER=qfuncinv(param.specBER);

2350

k_DER=qfuncinv(param.specBER);

2350

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2351

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2351

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2352

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2352

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2353

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2353

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2354

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2354

if A_s >= A_ni

2355

if A_s >= A_ni

2355

%% step 2 slide 10/8

2356

%% step 2 slide 10/8

2356

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2357

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2357

%% step 2 slide 10/8

2358

%% step 2 slide 10/8

2358

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2359

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2359

2360

2360

%% step 3 side 11/9

2361

%% step 3 side 11/9

2361

j=1:200;

2362

j=1:200;

2362

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2363

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2363

DER_MLSE_CDF=0; jj=1;

2364

DER_MLSE_CDF=0; jj=1;

2364

DER_delta = inf;

2365

DER_delta = inf;

2365

while DER_delta > .001

2366

while DER_delta > .001

2366

last_DER_MLSE_CDF=DER_MLSE_CDF;

2367

last_DER_MLSE_CDF=DER_MLSE_CDF;

2367

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2368

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2368

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2369

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2369

jj=jj+1;

2370

jj=jj+1;

2370

end

2371

end

2371

%%

2372

%%

2372

dscale=.05;

2373

dscale=.05;

2373

scale=1;

2374

scale=1;

2374

last_scale_tune=inf;

2375

last_scale_tune=inf;

2375

scale_tune=inf;

2376

scale_tune=inf;

2376

while abs(scale_tune) >= .1

2377

while abs(scale_tune) >= .1

2377

istart=-PDF.Min+1;

2378

istart=-PDF.Min+1;

2378

scale=scale-dscale;

2379

scale=scale-dscale;

2379

PDF_SCALED = scalePDF(PDF,scale);

2380

PDF_SCALED = scalePDF(PDF,scale);

2380

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2381

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2381

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2382

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2382

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2383

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2383

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2384

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2384

if sign(scale_tune) ~= sign(last_scale_tune)

2385

if sign(scale_tune) ~= sign(last_scale_tune)

2385

% scale=scale+dscale % back up

2386

% scale=scale+dscale % back up

2386

dscale=-dscale/2;

2387

dscale=-dscale/2;

2387

end

2388

end

2388

last_scale_tune=scale_tune;

2389

last_scale_tune=scale_tune;

2389

end

2390

end

2390

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2391

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2391

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2392

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2392

else

2393

else

2393

warning('MLSE not applied because there is more noise than signal')

2394

warning('MLSE not applied because there is more noise than signal')

2394

DER_MLSE=[];

2395

DER_MLSE=[];

2395

DER_MLSE_CDF=[];

2396

DER_MLSE_CDF=[];

2396

SNR_DFE_eqivalent=[];

2397

SNR_DFE_eqivalent=[];

2397

SNR_DFE_eqivalent_CDF=[];

2398

SNR_DFE_eqivalent_CDF=[];

2398

new_com_CDF=COM_from_matlab;

2399

new_com_CDF=COM_from_matlab;

2399

delta_com_CDF=0;

2400

delta_com_CDF=0;

2400

delta_com=0;

2401

delta_com=0;

2401

SNR_DFE=[];

2402

SNR_DFE=[];

2402

PDF_SCALED=[];

2403

PDF_SCALED=[];

2403

cdf_scaled=[];

2404

cdf_scaled=[];

2404

end

2405

end

2405

2406

2406

%%

2407

%%

2407

MLSE_results.COM_from_matlab=COM_from_matlab;

2408

MLSE_results.COM_from_matlab=COM_from_matlab;

2408

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2409

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2409

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2410

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2410

MLSE_results.sigma_noise=sigma_noise;

2411

MLSE_results.sigma_noise=sigma_noise;

2411

MLSE_results.k_DER=k_DER;

2412

MLSE_results.k_DER=k_DER;

2412

MLSE_results.COM_CDF=new_com_CDF;

2413

MLSE_results.COM_CDF=new_com_CDF;

2413

MLSE_results.delta_com_CDF=delta_com;

2414

MLSE_results.delta_com_CDF=delta_com;

2414

MLSE_results.delta_com_Gaussian=delta_com;

2415

MLSE_results.delta_com_Gaussian=delta_com;

2415

MLSE_results.PDF=PDF_SCALED;

2416

MLSE_results.PDF=PDF_SCALED;

2416

MLSE_results.CDF=cdf_scaled.y;

2417

MLSE_results.CDF=cdf_scaled.y;

2417

MLSE_results.PDF_scale=scale;

2418

MLSE_results.PDF_scale=scale;

2418

2419

2419

2420

2420

2421

2421

2422

2422

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2423

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2423

if 1

2424

if 1

2424

num_ui=param.num_ui_RXFF_noise;

2425

num_ui=param.num_ui_RXFF_noise;

2425

M=param.samples_per_ui;

2426

M=param.samples_per_ui;

2426

L=param.levels;

2427

L=param.levels;

2427

sigma_X2=(L^2-1)/(3*(L-1)^2);

2428

sigma_X2=(L^2-1)/(3*(L-1)^2);

2428

fb=param.fb;

2429

fb=param.fb;

2429

R_LM=param.R_LM;

2430

R_LM=param.R_LM;

2430

end

2431

end

2431

h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2432

h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2432

h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2433

h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2433

h=reshape(h,1,[]); % make row vectors

2434

h=reshape(h,1,[]); % make row vectors

2434

h=[ h(1:floor(length(h)/M)*M) ];

2435

h=[ h(1:floor(length(h)/M)*M) ];

2435

h= [h zeros(1,num_ui*M-length(h)) ];

2436

h= [h zeros(1,num_ui*M-length(h)) ];

2436

h=h(1:M:end);% resample

2437

h=h(1:M:end);% resample

2437

N=length(h);

2438

N=length(h);

2438

dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2439

dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2439

dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2440

dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2440

if param.N_bg == 0

2441

if param.N_bg == 0

2441

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2442

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2442

bmax=param.bmax;

2443

bmax=param.bmax;

2443

bmin=param.bmin ;

2444

bmin=param.bmin ;

2444

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2445

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2445

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2446

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2446

idx=[];

2447

idx=[];

2447

else

2448

else

2448

Nfloating_taps=param.N_bf*param.N_bg;

2449

Nfloating_taps=param.N_bf*param.N_bg;

2449

Nmax=param.N_bmax;

2450

Nmax=param.N_bmax;

2450

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2451

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2451

Ng=param.N_bg;

2452

Ng=param.N_bg;

2452

Nf=param.N_bf;

2453

Nf=param.N_bf;

2453

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2454

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2454

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2455

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2455

% hisi=h(dh+2:((dh-dw)+Nw));

2456

% hisi=h(dh+2:((dh-dw)+Nw));

2456

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2457

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2457

% idx=sort(idx);

2458

% idx=sort(idx);

2458

bmax=param.bmax;

2459

bmax=param.bmax;

2459

bmin=param.bmin ;

2460

bmin=param.bmin ;

2460

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2461

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2461

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2462

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2462

end

2463

end

2463

Nb=param.ndfe; % DFE taps

2464

Nb=param.ndfe; % DFE taps

2464

d=dw+dh; % used for index in algorithms

2465

d=dw+dh; % used for index in algorithms

2465

indx(1:N)=(1:N)-dh-1;

2466

indx(1:N)=(1:N)-dh-1;

2466

S_n=PSD_results.S_n; % total agregate noise PSD

2467

S_n=PSD_results.S_n; % total agregate noise PSD

2467

Rn=ifft(S_n)*fb;

2468

Rn=ifft(S_n)*fb;

2468

%% HH and R

2469

%% HH and R

2469

2470

2470

%Test routine finding rxffe floating taps using best FOM for each bank

2471

%Test routine finding rxffe floating taps using best FOM for each bank

2471

isi_start = dh+2;

2472

isi_start = dh+2;

2472

isi_end = (dh-dw)+Nw;

2473

isi_end = (dh-dw)+Nw;

2473

hc1=[ h zeros(1,Nw-1) ];

2474

hc1=[ h zeros(1,Nw-1) ];

2474

hr1=[ h(1) zeros(1,Nw-1)];

2475

hr1=[ h(1) zeros(1,Nw-1)];

2475

H=toeplitz(hc1,hr1);

2476

H=toeplitz(hc1,hr1);

2476

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2477

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2477

if param.N_bg ~= 0

2478

if param.N_bg ~= 0

2478

switch lower(OP.RXFFE_FLOAT_CTL)

2479

switch lower(OP.RXFFE_FLOAT_CTL)

2479

case 'isi'

2480

case 'isi'

2480

hisi=h(dh+2:((dh-dw)+Nw));

2481

hisi=h(dh+2:((dh-dw)+Nw));

2481

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2482

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2482

idx=sort(idx);

2483

idx=sort(idx);

2483

otherwise

2484

otherwise

2484

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2485

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2485

idx=sort(idx);

2486

idx=sort(idx);

2486

end

2487

end

2487

end

2488

end

2488

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2489

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2489

MMSE_results.sigma_e=sigma_e; %

2490

MMSE_results.sigma_e=sigma_e; %

2490

MMSE_results.FOM=FOM;

2491

MMSE_results.FOM=FOM;

2491

Craw=w/w(dw+1); % returned Rx FFE taps

2492

Craw=w/w(dw+1); % returned Rx FFE taps

2492

% re-align Cmod to floating tap locations

2493

% re-align Cmod to floating tap locations

2493

if param.N_bg ~= 0

2494

if param.N_bg ~= 0

2494

C=Craw;

2495

C=Craw;

2495

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2496

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2496

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2497

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2497

else

2498

else

2498

C=Craw;

2499

C=Craw;

2499

end

2500

end

2500

MMSE_results.floating_tap_locations=idx;

2501

MMSE_results.floating_tap_locations=idx;

2501

MMSE_results.C=C;

2502

MMSE_results.C=C;

2502

2503

2503

2504

2504

2505

2505

2506

2506

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2507

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2507

if isempty(idx)

2508

if isempty(idx)

2508

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2509

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2509

bmax=param.bmax;

2510

bmax=param.bmax;

2510

bmin=param.bmin ;

2511

bmin=param.bmin ;

2511

else

2512

else

2512

Nfloating_taps=param.N_bf*param.N_bg;

2513

Nfloating_taps=param.N_bf*param.N_bg;

2513

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2514

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2514

Nfloating_taps = length(idx);

2515

Nfloating_taps = length(idx);

2515

Nmax=param.N_bmax;

2516

Nmax=param.N_bmax;

2516

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2517

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2517

Ng=param.N_bg;

2518

Ng=param.N_bg;

2518

Nf=param.N_bf;

2519

Nf=param.N_bf;

2519

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2520

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2520

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2521

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2521

end

2522

end

2522

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2523

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2523

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2524

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2524

% hc1=[ h zeros(1,Nw-1) ];

2525

% hc1=[ h zeros(1,Nw-1) ];

2525

% hr1=[ h(1) zeros(1,Nw-1)];

2526

% hr1=[ h(1) zeros(1,Nw-1)];

2526

% H=toeplitz(hc1,hr1);

2527

% H=toeplitz(hc1,hr1);

2527

2528

2528

if param.N_bg ~= 0

2529

if param.N_bg ~= 0

2529

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2530

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2530

end

2531

end

2531

%% HH and R

2532

%% HH and R

2532

HH= H'*H;

2533

HH= H'*H;

2533

if param.N_bg ~= 0

2534

if param.N_bg ~= 0

2534

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2535

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2535

end

2536

end

2536

R=HH+Rnn/sigma_X2;

2537

R=HH+Rnn/sigma_X2;

2537

%% hb and h0

2538

%% hb and h0

2538

Hb= H(d+2:d+Nb+1,:);

2539

Hb= H(d+2:d+Nb+1,:);

2539

h0=H(d+1,:);

2540

h0=H(d+1,:);

2540

% display(floor(h0));

2541

% display(floor(h0));

2541

2542

2542

%% Ib and zb (slide 10)

2543

%% Ib and zb (slide 10)

2543

ib=eye(Nb);

2544

ib=eye(Nb);

2544

zb=zeros(1,Nb);

2545

zb=zeros(1,Nb);

2545

wbl= [ R -Hb' -h0';...

2546

wbl= [ R -Hb' -h0';...

2546

-Hb ib zb'; ...

2547

-Hb ib zb'; ...

2547

h0 zb 0]\[h0'; zb' ;1];

2548

h0 zb 0]\[h0'; zb' ;1];

2548

2549

2549

%% re-adjust Nw to number of used taps

2550

%% re-adjust Nw to number of used taps

2550

if param.N_bg ~= 0

2551

if param.N_bg ~= 0

2551

Nw=Nwft;

2552

Nw=Nwft;

2552

end

2553

end

2553

%% check equalized pulse

2554

%% check equalized pulse

2554

w=wbl(1:Nw);

2555

w=wbl(1:Nw);

2555

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2556

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2556

2557

2557

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2558

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2558

blim = min(bmax(:), max(bmin(:), b));

2559

blim = min(bmax(:), max(bmin(:), b));

2559

if (Nb > 0) && ~isequal(b, blim)

2560

if (Nb > 0) && ~isequal(b, blim)

2560

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2561

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2561

w = wl(1:Nw);

2562

w = wl(1:Nw);

2562

end

2563

end

2563

2564

2564

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2565

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2565

%so need to chop off the extra indices on wmax and wmin

2566

%so need to chop off the extra indices on wmax and wmin

2566

if length(w)<length(wmax)

2567

if length(w)<length(wmax)

2567

wmax=wmax(1:length(w));

2568

wmax=wmax(1:length(w));

2568

wmin=wmin(1:length(w));

2569

wmin=wmin(1:length(w));

2569

end

2570

end

2570

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2571

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2571

if ~isequal(w, wlim)

2572

if ~isequal(w, wlim)

2572

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2573

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2573

if Nb > 0

2574

if Nb > 0

2574

b = Hb*wlim; % Update the feedback coefficients.

2575

b = Hb*wlim; % Update the feedback coefficients.

2575

blim = min(bmax(:), max(bmin(:), b));

2576

blim = min(bmax(:), max(bmin(:), b));

2576

end

2577

end

2577

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2578

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2578

wl = wl(1:Nw);

2579

% wl = wl(1:Nw);

2579

w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2580

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2580

end

2581

end

2581

w=w(1:Nw) ;

2582

% w=w(1:Nw) ;

2582

sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2583

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

+2584

w=wlim;

2585

b=blim;

2586

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2583

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2587

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2584

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2588

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2585

2589

2586

%not all output_args are filled here but most are

2590

%not all output_args are filled here but most are

2587

2591

2588

switch lower(OP.TDECQ)

2592

switch lower(OP.TDECQ)

2589

case { false 'none' } % should be the default

2593

case { false 'none' } % should be the default

2590

output_args.VMA=[];

2594

output_args.VMA=[];

2591

case 'vma'

2595

case 'vma'

2592

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2596

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2593

output_args.VMA=est_vma.VMA;

2597

output_args.VMA=est_vma.VMA;

2594

otherwise

2598

otherwise

2595

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2599

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2596

end

2600

end

2597

2601

2598

fileset_str=str2csv({chdata.base});

2602

fileset_str=str2csv({chdata.base});

2599

output_args.file_names=sprintf('"%s"', fileset_str);

2603

output_args.file_names=sprintf('"%s"', fileset_str);

2600

% [ahealey] Echo the termination parameters in the output arguments..

2604

% [ahealey] Echo the termination parameters in the output arguments..

2601

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2605

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2602

output_args.(odt_param{:}) = param.(odt_param{:});

2606

output_args.(odt_param{:}) = param.(odt_param{:});

2603

end

2607

end

2604

% [ahealey] End of modifications.

2608

% [ahealey] End of modifications.

2605

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2609

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2606

output_args.(pkg_params{:})= param.(pkg_params{:});

2610

output_args.(pkg_params{:})= param.(pkg_params{:});

2607

end

2611

end

2608

output_args.baud_rate_GHz=param.fb/1e9;

2612

output_args.baud_rate_GHz=param.fb/1e9;

2609

output_args.f_Nyquist_GHz = param.fb/2e9;

2613

output_args.f_Nyquist_GHz = param.fb/2e9;

2610

output_args.BER=param.specBER;

2614

output_args.BER=param.specBER;

2611

output_args.FOM = fom_result.FOM;

2615

output_args.FOM = fom_result.FOM;

2612

output_args.sigma_N=Noise_Struct.sigma_N;

2616

output_args.sigma_N=Noise_Struct.sigma_N;

2613

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2617

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2614

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2618

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2615

output_args.tail_RSS=fom_result.tail_RSS;

2619

output_args.tail_RSS=fom_result.tail_RSS;

2616

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2620

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2617

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2621

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2618

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2622

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2619

try

2623

try

2620

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2624

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2621

catch

2625

catch

2622

output_args.uneq_FIR_peak_time=[];

2626

output_args.uneq_FIR_peak_time=[];

2623

end

2627

end

2624

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2628

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2625

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2629

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2626

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2630

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2627

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2631

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2628

2632

2629

if OP.RX_CALIBRATION== 1

2633

if OP.RX_CALIBRATION== 1

2630

output_args.sigma_bn=sigma_bn;

2634

output_args.sigma_bn=sigma_bn;

2631

else

2635

else

2632

output_args.sigma_bn=[];

2636

output_args.sigma_bn=[];

2633

end

2637

end

2634

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2638

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2635

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2639

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2636

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2640

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2637

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2641

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2638

2642

2639

if OP.RX_CALIBRATION == 0

2643

if OP.RX_CALIBRATION == 0

2640

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2644

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2641

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2645

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2642

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2646

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2643

else

2647

else

2644

output_args.peak_MDXTK_interference_at_BER_mV=[];

2648

output_args.peak_MDXTK_interference_at_BER_mV=[];

2645

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2649

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2646

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2650

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2647

end

2651

end

2648

%output_args.ICN_mV=ICN*1000;

2652

%output_args.ICN_mV=ICN*1000;

2649

% output_args.ICN_test_mV=ICN_test*1000;

2653

% output_args.ICN_test_mV=ICN_test*1000;

2650

xtk=param.num_next+param.num_fext;

2654

xtk=param.num_next+param.num_fext;

2651

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2655

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2652

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2656

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2653

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2657

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2654

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2658

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2655

else

2659

else

2656

output_args.MDNEXT_ICN_92_46_mV=0;

2660

output_args.MDNEXT_ICN_92_46_mV=0;

2657

output_args.MDFEXT_ICN_92_47_mV=0;

2661

output_args.MDFEXT_ICN_92_47_mV=0;

2658

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2662

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2659

end

2663

end

2660

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2664

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2661

if 1

2665

if 1

2662

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2666

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2663

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2667

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2664

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2668

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2665

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2669

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2666

end

2670

end

2667

2671

2668

2672

2669

switch param.CTLE_type

2673

switch param.CTLE_type

2670

case 'CL93'

2674

case 'CL93'

2671

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2675

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2672

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2676

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2673

output_args.g_DC_HP=[];

2677

output_args.g_DC_HP=[];

2674

output_args.HP_poles_zero=[];

2678

output_args.HP_poles_zero=[];

2675

case 'CL120d'

2679

case 'CL120d'

2676

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2680

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2677

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2681

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2678

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2682

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2679

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2683

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2680

case 'CL120e'

2684

case 'CL120e'

2681

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2685

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2682

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2686

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2683

output_args.g_DC_HP=[];

2687

output_args.g_DC_HP=[];

2684

output_args.HP_poles_zero=[];

2688

output_args.HP_poles_zero=[];

2685

end

2689

end

2686

output_args.TXLE_taps=fom_result.txffe;

2690

output_args.TXLE_taps=fom_result.txffe;

2687

if length(output_args.TXLE_taps) >= 3

2691

if length(output_args.TXLE_taps) >= 3

2688

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2692

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2689

else

2693

else

2690

output_args.Pre2Pmax=[];

2694

output_args.Pre2Pmax=[];

2691

end

2695

end

2692

output_args.DFE_taps=fom_result.DFE_taps;

2696

output_args.DFE_taps=fom_result.DFE_taps;

2693

if param.Floating_DFE || param.Floating_RXFFE

2697

if param.Floating_DFE || param.Floating_RXFFE

2694

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2698

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2695

else

2699

else

2696

output_args.floating_tap_locations=[];

2700

output_args.floating_tap_locations=[];

2697

end

2701

end

2698

2702

2699

if OP.RxFFE

2703

if OP.RxFFE

2700

output_args.RxFFE=fom_result.RxFFE;

2704

output_args.RxFFE=fom_result.RxFFE;

2701

output_args.RxFFEgain=param.current_ffegain;

2705

output_args.RxFFEgain=param.current_ffegain;

2702

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2706

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2703

output_args.RxFFE=[];

2707

output_args.RxFFE=[];

2704

output_args.RxFFEgain=[];

2708

output_args.RxFFEgain=[];

2705

end

2709

end

2706

2710

2707

output_args.itick=fom_result.itick;

2711

output_args.itick=fom_result.itick;

2708

2712

2709

% Calculation of error propagation and burst probability

2713

% Calculation of error propagation and burst probability

2710

if OP.nburst>0

2714

if OP.nburst>0

2711

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2715

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2712

output_args.error_propagation_probability = p_error_propagation;

2716

output_args.error_propagation_probability = p_error_propagation;

2713

output_args.burst_probabilities = p_burst;

2717

output_args.burst_probabilities = p_burst;

2714

else

2718

else

2715

output_args.error_propagation_probability = [];

2719

output_args.error_propagation_probability = [];

2716

output_args.burst_probabilities = [];

2720

output_args.burst_probabilities = [];

2717

end

2721

end

2718

2722

2719

2723

2720

%begin yasuo patch 12/11/2018

2724

%begin yasuo patch 12/11/2018

2721

% collect sigma values to report

2725

% collect sigma values to report

2722

% pdf2sgm() is a function to calculate sigma value from PDF

2726

% pdf2sgm() is a function to calculate sigma value from PDF

2723

% It is added at the end of this file code.

2727

% It is added at the end of this file code.

2724

% I am not sure if an equivalent function already exists.

2728

% I am not sure if an equivalent function already exists.

2725

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2729

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2726

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2730

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2727

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2731

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2728

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2732

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2729

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2733

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2730

output_args.sgm_G = Noise_Struct.sigma_G;

2734

output_args.sgm_G = Noise_Struct.sigma_G;

2731

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2735

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2732

output_args.sgm_N = Noise_Struct.sigma_N;

2736

output_args.sgm_N = Noise_Struct.sigma_N;

2733

output_args.sgm_TX = Noise_Struct.sigma_TX;

2737

output_args.sgm_TX = Noise_Struct.sigma_TX;

2734

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2738

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2735

if OP.RX_CALIBRATION == 0

2739

if OP.RX_CALIBRATION == 0

2736

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2740

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2737

else

2741

else

2738

output_args.sgm_xt=[];

2742

output_args.sgm_xt=[];

2739

end

2743

end

2740

% end yasuo patch

2744

% end yasuo patch

2741

2745

2742

% r259 putting COM, VEO and loss last in report

2746

% r259 putting COM, VEO and loss last in report

2743

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2747

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2744

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2748

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2745

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2749

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2746

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2750

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2747

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2751

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2748

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2752

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2749

output_args.VEO_window_mUI= param.T_O;

2753

output_args.VEO_window_mUI= param.T_O;

2750

else

2754

else

2751

output_args.EW_UI_est=[];

2755

output_args.EW_UI_est=[];

2752

output_args.eye_contour=[];

2756

output_args.eye_contour=[];

2753

output_args.VEO_window_mUI= [];

2757

output_args.VEO_window_mUI= [];

2754

end

2758

end

2755

2759

2756

if sum(param.AC_CM_RMS) ~= 0

2760

if sum(param.AC_CM_RMS) ~= 0

2757

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2761

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2758

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2762

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2759

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2763

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2760

else

2764

else

2761

output_args.sigma_ACCM_at_tp0_mV=[];

2765

output_args.sigma_ACCM_at_tp0_mV=[];

2762

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2766

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2763

end

2767

end

2764

if OP.MLSE

2768

if OP.MLSE

2765

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2769

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2766

output_args.VEC_dB_orig=COM_SNR_Struct.VEC_dB_orig;

2770

output_args.VEC_dB_orig=COM_SNR_Struct.VEC_dB_orig;

2767

end

2771

end

2768

%

2772

%

2769

output_args.COM_dB=COM_SNR_Struct.COM;

2773

output_args.COM_dB=COM_SNR_Struct.COM;

2770

% end yasuo patch

2774

% end yasuo patch

2771

% begin yasuo patch 3/18/2019

2775

% begin yasuo patch 3/18/2019

2772

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2776

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2773

% end yasuo patch

2777

% end yasuo patch

2774

function [ seq syms syms_nrz ] = PRBS13Q( )

2778

function [ seq syms syms_nrz ] = PRBS13Q( )

2775

%UNTITLED Summary of this function goes here

2779

%UNTITLED Summary of this function goes here

2776

% Detailed explanation goes here

2780

% Detailed explanation goes here

2777

2781

2778

2782

2779

taps = ([13 12 2 1]);

2783

taps = ([13 12 2 1]);

2780

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2784

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2781

[seq_nrz c] =LFSR(seed,taps);

2785

[seq_nrz c] =LFSR(seed,taps);

2782

seq_nrz=2*(seq_nrz-0.5);

2786

seq_nrz=2*(seq_nrz-0.5);

2783

seq=pam(seq_nrz);

2787

seq=pam(seq_nrz);

2784

% syms=round(2*(seq+1));

2788

% syms=round(2*(seq+1));

2785

syms((round(2*(seq+1))/2==2))=3;

2789

syms((round(2*(seq+1))/2==2))=3;

2786

syms((round(2*(seq+1))/2==1.5))=2;

2790

syms((round(2*(seq+1))/2==1.5))=2;

2787

syms((round(2*(seq+1))/2==.5))=1;

2791

syms((round(2*(seq+1))/2==.5))=1;

2788

syms((round(2*(seq+1))/2==0))=0;

2792

syms((round(2*(seq+1))/2==0))=0;

2789

2793

2790

% syms_nrz=((seq_nrz+1)/2);

2794

% syms_nrz=((seq_nrz+1)/2);

2791

2795

2792

syms_nrz=seq_nrz;

2796

syms_nrz=seq_nrz;

2793

2797

2794

2798

2795

function[seq c]=LFSR(s,t)

2799

function[seq c]=LFSR(s,t)

2796

%s=initial state of LFSR, you can choose any lenght of LFSR

2800

%s=initial state of LFSR, you can choose any lenght of LFSR

2797

%Instruction:==========

2801

%Instruction:==========

2798

%Save LFSR.m in your current directory and type following

2802

%Save LFSR.m in your current directory and type following

2799

%on Command window for simulating 5 bit LFSR with tap [5 2]

2803

%on Command window for simulating 5 bit LFSR with tap [5 2]

2800

%---------------------

2804

%---------------------

2801

%>>s=[1 1 0 0 1]

2805

%>>s=[1 1 0 0 1]

2802

%>>t=[5 2]

2806

%>>t=[5 2]

2803

%>>[seq c] =LFSR(s,t)

2807

%>>[seq c] =LFSR(s,t)

2804

%---------------------------

2808

%---------------------------

2805

%seq = generated sequence

2809

%seq = generated sequence

2806

%c will be matrix containing the states of LFSR raw wise

2810

%c will be matrix containing the states of LFSR raw wise

2807

%

2811

%

2808

%-----------------------------------------------------------

2812

%-----------------------------------------------------------

2809

%If any doubt, confusion or feedback please contact me

2813

%If any doubt, confusion or feedback please contact me

2810

% NIKESH BAJAJ

2814

% NIKESH BAJAJ

2811

% bajaj.nikkey@gmail.com (+91-9915522564)

2815

% bajaj.nikkey@gmail.com (+91-9915522564)

2812

% Asst. Professor at Lovely Profesional University

2816

% Asst. Professor at Lovely Profesional University

2813

% Masters from Aligarh Muslim University,INDIA

2817

% Masters from Aligarh Muslim University,INDIA

2814

%--------------------------------------------------

2818

%--------------------------------------------------

2815

n=length(s);

2819

n=length(s);

2816

c(1,:)=s;

2820

c(1,:)=s;

2817

m=length(t);

2821

m=length(t);

2818

for k=1:2^n-2;

2822

for k=1:2^n-2;

2819

b(1)=xor(s(t(1)), s(t(2)));

2823

b(1)=xor(s(t(1)), s(t(2)));

2820

if m>2;

2824

if m>2;

2821

for i=1:m-2;

2825

for i=1:m-2;

2822

b(i+1)=xor(s(t(i+2)), b(i));

2826

b(i+1)=xor(s(t(i+2)), b(i));

2823

end

2827

end

2824

end

2828

end

2825

j=1:n-1;

2829

j=1:n-1;

2826

s(n+1-j)=s(n-j);

2830

s(n+1-j)=s(n-j);

2827

s(1)=b(m-1);

2831

s(1)=b(m-1);

2828

c(k+1,:)=s;

2832

c(k+1,:)=s;

2829

end

2833

end

2830

seq=c(:,n)';

2834

seq=c(:,n)';

2831

2835

2832

function [ dataout ] = pam( data )

2836

function [ dataout ] = pam( data )

2833

% mapping data usng Grey Coding

2837

% mapping data usng Grey Coding

2834

for i=1:2:floor(length(data)/2)*2

2838

for i=1:2:floor(length(data)/2)*2

2835

if data(i:i+1)==[ -1 -1 ]

2839

if data(i:i+1)==[ -1 -1 ]

2836

dataout(ceil(i/2)) = -1;

2840

dataout(ceil(i/2)) = -1;

2837

elseif data(i:i+1)==[ -1 1 ]

2841

elseif data(i:i+1)==[ -1 1 ]

2838

dataout(ceil(i/2)) = -1/3;

2842

dataout(ceil(i/2)) = -1/3;

2839

elseif data(i:i+1)==[ 1 1 ]

2843

elseif data(i:i+1)==[ 1 1 ]

2840

dataout(ceil(i/2)) = 1/3;

2844

dataout(ceil(i/2)) = 1/3;

2841

elseif data(i:i+1)==[ 1 -1 ]

2845

elseif data(i:i+1)==[ 1 -1 ]

2842

dataout(ceil(i/2)) = 1;

2846

dataout(ceil(i/2)) = 1;

2843

end

2847

end

2844

end

2848

end

2845

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2849

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2846

db = @(x) 20*log10(abs(x));

2850

db = @(x) 20*log10(abs(x));

2847

disp('computing TD_RILN...')

2851

disp('computing TD_RILN...')

2848

sdd21=squeeze(sdd21);

2852

sdd21=squeeze(sdd21);

2849

if iscolumn(sdd21)

2853

if iscolumn(sdd21)

2850

sdd21=sdd21.';

2854

sdd21=sdd21.';

2851

end

2855

end

2852

RIL=squeeze(RIL);

2856

RIL=squeeze(RIL);

2853

if iscolumn(RIL)

2857

if iscolumn(RIL)

2854

RIL=RIL.';

2858

RIL=RIL.';

2855

end

2859

end

2856

print_for_codereview=1;

2860

print_for_codereview=1;

2857

if exist('OP','var')

2861

if exist('OP','var')

2858

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2862

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2859

2863

2860

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2864

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2861

H_bw=Butterworth_Filter(param,faxis_f2,1);

2865

H_bw=Butterworth_Filter(param,faxis_f2,1);

2862

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2866

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2863

H_tw=Tukey_Window(faxis_f2,param);

2867

H_tw=Tukey_Window(faxis_f2,param);

2864

H_tw=ones(1,length(faxis_f2) );

2868

H_tw=ones(1,length(faxis_f2) );

2865

[RILN_TD_struct.REF.FIR, ...

2869

[RILN_TD_struct.REF.FIR, ...

2866

RILN_TD_struct.REF.t, ...

2870

RILN_TD_struct.REF.t, ...

2867

RILN_TD_struct.REF.causality_correction_dB, ...

2871

RILN_TD_struct.REF.causality_correction_dB, ...

2868

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2872

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2869

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2873

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2870

[RILN_TD_struct.FIT.FIR, ...

2874

[RILN_TD_struct.FIT.FIR, ...

2871

RILN_TD_struct.FIT.t, ...

2875

RILN_TD_struct.FIT.t, ...

2872

RILN_TD_struct.FIT.causality_correction_dB, ...

2876

RILN_TD_struct.FIT.causality_correction_dB, ...

2873

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2877

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2874

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2878

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2875

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2879

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2876

NrangeUI=1000;

2880

NrangeUI=1000;

2877

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2881

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2878

range=ipeak:range_end;

2882

range=ipeak:range_end;

2879

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2883

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2880

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2884

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2881

RILN_TD_struct.FOM=-inf;

2885

RILN_TD_struct.FOM=-inf;

2882

RILN_TD_struct.FOM_PDF=-inf;

2886

RILN_TD_struct.FOM_PDF=-inf;

2883

rms_fom=-inf;

2887

rms_fom=-inf;

2884

for im=1:param.samples_per_ui

2888

for im=1:param.samples_per_ui

2885

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2889

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2886

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2890

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2887

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2891

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2888

cdf=pdf; cdf.y=cumsum(pdf.y);

2892

cdf=pdf; cdf.y=cumsum(pdf.y);

2889

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2893

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2890

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2894

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2891

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2895

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2892

if print_for_codereview % remove once all checked out

2896

if print_for_codereview % remove once all checked out

2893

h=figure(191);set(gcf,'Tag','COM');

2897

h=figure(191);set(gcf,'Tag','COM');

2894

semilogy(-cdf.x,cdf.y);

2898

semilogy(-cdf.x,cdf.y);

2895

% xlim ([0,-cdf.x(1)])

2899

% xlim ([0,-cdf.x(1)])

2896

ylim([param.specBER 1]);title ('CDF of RILN')

2900

ylim([param.specBER 1]);title ('CDF of RILN')

2897

hold on

2901

hold on

2898

end

2902

end

2899

if rms>rms_fom

2903

if rms>rms_fom

2900

rms_fom=rms;

2904

rms_fom=rms;

2901

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2905

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2902

RILN_TD_struct.PDF=pdf;

2906

RILN_TD_struct.PDF=pdf;

2903

end

2907

end

2904

end

2908

end

2905

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2909

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2906

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2910

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2907

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2911

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2908

if print_for_codereview % remove once all checked out

2912

if print_for_codereview % remove once all checked out

2909

figure(9003);set(gcf,'Tag','COM');

2913

figure(9003);set(gcf,'Tag','COM');

2910

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2914

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2911

hold on

2915

hold on

2912

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2916

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2913

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2917

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2914

hold off

2918

hold off

2915

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2919

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2916

figure(9004);set(gcf,'Tag','COM');

2920

figure(9004);set(gcf,'Tag','COM');

2917

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2921

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2918

hold on

2922

hold on

2919

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2923

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2920

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2924

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2921

grid on

2925

grid on

2922

legend('show')

2926

legend('show')

2923

end

2927

end

2924

end

2928

end

2925

function is_illegal=RXFFE_Illegal(C,param,last_index)

2929

function is_illegal=RXFFE_Illegal(C,param,last_index)

2926

2930

2927

%check if RXFFE taps are illegal

2931

%check if RXFFE taps are illegal

2928

%C = RXFFE taps

2932

%C = RXFFE taps

2929

%param = COM param struct

2933

%param = COM param struct

2930

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2934

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2931

% in the Backoff region are not considered in the legality check.

2935

% in the Backoff region are not considered in the legality check.

2932

2936

2933

%If last index is omitted, set it to length(C)

2937

%If last index is omitted, set it to length(C)

2934

if nargin<3

2938

if nargin<3

2935

last_index=length(C);

2939

last_index=length(C);

2936

end

2940

end

2937

2941

2938

is_illegal=0;

2942

is_illegal=0;

2939

2943

2940

%Check cursor tap

2944

%Check cursor tap

2941

Ccur_i=param.RxFFE_cmx+1;

2945

Ccur_i=param.RxFFE_cmx+1;

2942

if C(Ccur_i) < param.ffe_main_cursor_min

2946

if C(Ccur_i) < param.ffe_main_cursor_min

2943

is_illegal=1;

2947

is_illegal=1;

2944

return;

2948

return;

2945

end

2949

end

2946

2950

2947

%Check postcursors

2951

%Check postcursors

2948

if param.ffe_post_tap_len ~=0

2952

if param.ffe_post_tap_len ~=0

2949

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2953

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2950

is_illegal=1;

2954

is_illegal=1;

2951

return;

2955

return;

2952

end

2956

end

2953

if (param.ffe_post_tap_len > 1)

2957

if (param.ffe_post_tap_len > 1)

2954

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2958

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2955

is_illegal=1;

2959

is_illegal=1;

2956

return;

2960

return;

2957

end

2961

end

2958

end

2962

end

2959

end

2963

end

2960

2964

2961

%Check precursors

2965

%Check precursors

2962

if param.ffe_pre_tap_len ~=0

2966

if param.ffe_pre_tap_len ~=0

2963

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2967

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2964

is_illegal=1;

2968

is_illegal=1;

2965

return;

2969

return;

2966

end

2970

end

2967

if (param.ffe_pre_tap_len > 1)

2971

if (param.ffe_pre_tap_len > 1)

2968

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2972

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2969

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2973

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2970

is_illegal=1;

2974

is_illegal=1;

2971

return;

2975

return;

2972

end % 11.22.2018 Yasou Hadaka

2976

end % 11.22.2018 Yasou Hadaka

2973

end

2977

end

2974

end

2978

end

2975

function S =R_series2(zref,f,R)

2979

function S =R_series2(zref,f,R)

2976

r=ones(1,length(f))*R;

2980

r=ones(1,length(f))*R;

2977

S.Parameters(1,1,:) = r./(r + 2*zref);

2981

S.Parameters(1,1,:) = r./(r + 2*zref);

2978

S.Parameters(2,2,:) = r./(r + 2*zref);

2982

S.Parameters(2,2,:) = r./(r + 2*zref);

2979

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2983

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2980

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2984

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2981

% Sm=sparameters(S.Parameters,f,zref);

2985

% Sm=sparameters(S.Parameters,f,zref);

2982

2986

2983

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2987

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2984

2988

2985

if use_RC

2989

if use_RC

2986

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2990

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2987

else

2991

else

2988

H_tw=ones(1,length(f));

2992

H_tw=ones(1,length(f));

2989

end

2993

end

2990

function SLD=SL(S,f,R)

2994

function SLD=SL(S,f,R)

2991

% source load impact return loss add to S21

2995

% source load impact return loss add to S21

2992

% S and SLD are the same structure

2996

% S and SLD are the same structure

2993

% S.Parameters

2997

% S.Parameters

2994

% S.Impedance

2998

% S.Impedance

2995

% S.NumPorts

2999

% S.NumPorts

2996

% S.Frequencies

3000

% S.Frequencies

2997

SLD=S; % assign the fields

3001

SLD=S; % assign the fields

2998

zref=100;

3002

zref=100;

2999

if R==0

3003

if R==0

3000

warndlg('Termination should not be set to zero');

3004

warndlg('Termination should not be set to zero');

3001

SLD=S;

3005

SLD=S;

3002

return

3006

return

3003

end

3007

end

3004

3008

3005

if R > zref

3009

if R > zref

3006

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3010

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3007

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3011

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3008

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3012

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3009

combines4p( ...

3013

combines4p( ...

3010

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3014

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3011

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3015

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3012

);

3016

);

3013

elseif R < zref

3017

elseif R < zref

3014

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3018

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3015

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3019

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3016

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3020

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3017

combines4p( ...

3021

combines4p( ...

3018

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3022

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3019

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3023

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3020

);

3024

);

3021

else

3025

else

3022

SLD=S;

3026

SLD=S;

3023

end

3027

end

3024

3028

3025

%%

3029

%%

3026

3030

3027

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3031

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3028

p1=param.CTLE_fp1(1);

3032

p1=param.CTLE_fp1(1);

3029

z1=param.CTLE_fz(1);

3033

z1=param.CTLE_fz(1);

3030

p2=param.CTLE_fp2(1);

3034

p2=param.CTLE_fp2(1);

3031

zlf=param.f_HP(1);

3035

zlf=param.f_HP(1);

3032

plf=param.f_HP(1);

3036

plf=param.f_HP(1);

3033

f_b=param.fb;

3037

f_b=param.fb;

3034

f_r=param.f_r;

3038

f_r=param.f_r;

3035

eta_0=param.eta_0;

3039

eta_0=param.eta_0;

3036

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3040

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3037

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3041

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3038

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3042

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3039

if 0

3043

if 0

3040

figure

3044

figure

3041

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3045

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3042

% see if it looks correct

3046

% see if it looks correct

3043

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3047

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3044

ylabel('dB');

3048

ylabel('dB');

3045

xlabel('GHz');

3049

xlabel('GHz');

3046

title( 'H_ctf with H_r')

3050

title( 'H_ctf with H_r')

3047

grid on

3051

grid on

3048

ylim([-30 0])

3052

ylim([-30 0])

3049

end

3053

end

3050

3054

3051

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3055

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3052

3056

3053

%Fill TDR data

3057

%Fill TDR data

3054

if package_testcase_i == 1

3058

if package_testcase_i == 1

3055

if OP.TDR

3059

if OP.TDR

3056

output_args.Z11est=chdata(1).TDR11.avgZport;

3060

output_args.Z11est=chdata(1).TDR11.avgZport;

3057

if ~param.FLAG.S2P

3061

if ~param.FLAG.S2P

3058

output_args.Z22est=chdata(1).TDR22.avgZport;

3062

output_args.Z22est=chdata(1).TDR22.avgZport;

3059

else

3063

else

3060

output_args.Z22est=[];

3064

output_args.Z22est=[];

3061

end

3065

end

3062

if OP.AUTO_TFX

3066

if OP.AUTO_TFX

3063

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3067

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3064

else

3068

else

3065

output_args.tfx_estimate=[];

3069

output_args.tfx_estimate=[];

3066

end

3070

end

3067

else

3071

else

3068

output_args.Z11est=[];

3072

output_args.Z11est=[];

3069

output_args.Z22est=[];

3073

output_args.Z22est=[];

3070

output_args.tfx_estimate=[];

3074

output_args.tfx_estimate=[];

3071

end

3075

end

3072

end

3076

end

3073

3077

3074

% Process ERL

3078

% Process ERL

3075

if package_testcase_i == 1

3079

if package_testcase_i == 1

3076

if OP.ERL

3080

if OP.ERL

3077

output_args.ERL11=chdata(1).TDR11.ERL;

3081

output_args.ERL11=chdata(1).TDR11.ERL;

3078

if ~param.FLAG.S2P

3082

if ~param.FLAG.S2P

3079

output_args.ERL22=chdata(1).TDR22.ERL;

3083

output_args.ERL22=chdata(1).TDR22.ERL;

3080

else

3084

else

3081

output_args.ERL22=[];

3085

output_args.ERL22=[];

3082

end

3086

end

3083

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3087

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3084

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3088

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3085

else

3089

else

3086

output_args.ERL11=[];

3090

output_args.ERL11=[];

3087

output_args.ERL22=[];

3091

output_args.ERL22=[];

3088

end

3092

end

3089

end

3093

end

3090

if OP.ERL

3094

if OP.ERL

3091

if OP.TDR_W_TXPKG

3095

if OP.TDR_W_TXPKG

3092

min_ERL=output_args.ERL22;

3096

min_ERL=output_args.ERL22;

3093

ERL= [ nan output_args.ERL22 ];

3097

ERL= [ nan output_args.ERL22 ];

3094

else

3098

else

3095

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3099

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3096

min_ERL=output_args.ERL11;

3100

min_ERL=output_args.ERL11;

3097

ERL= [ output_args.ERL11 nan ];

3101

ERL= [ output_args.ERL11 nan ];

3098

else

3102

else

3099

min_ERL=min(output_args.ERL11,output_args.ERL22);

3103

min_ERL=min(output_args.ERL11,output_args.ERL22);

3100

ERL= [ output_args.ERL11 output_args.ERL22 ];

3104

ERL= [ output_args.ERL11 output_args.ERL22 ];

3101

end

3105

end

3102

end

3106

end

3103

output_args.ERL=min_ERL;

3107

output_args.ERL=min_ERL;

3104

else

3108

else

3105

min_ERL=[];

3109

min_ERL=[];

3106

ERL= [];

3110

ERL= [];

3107

output_args.ERL=[];

3111

output_args.ERL=[];

3108

end

3112

end

3109

if OP.ERL_ONLY

3113

if OP.ERL_ONLY

3110

if OP.BREAD_CRUMBS

3114

if OP.BREAD_CRUMBS

3111

output_args.OP=OP;

3115

output_args.OP=OP;

3112

output_args.param=param;

3116

output_args.param=param;

3113

output_args.chdata=chdata;

3117

output_args.chdata=chdata;

3114

%This seems to be the intent of setting fom_result.ran=0. Add it

3118

%This seems to be the intent of setting fom_result.ran=0. Add it

3115

%to output_args so there is a fom_result field.

3119

%to output_args so there is a fom_result field.

3116

fom_result.ran=0;

3120

fom_result.ran=0;

3117

output_args.fom_result=fom_result;

3121

output_args.fom_result=fom_result;

3118

end

3122

end

3119

output_args.Z_t=param.Z_t;

3123

output_args.Z_t=param.Z_t;

3120

fileset_str=str2csv({chdata(1).base});

3124

fileset_str=str2csv({chdata(1).base});

3121

output_args.file_names=sprintf('"%s"', fileset_str);

3125

output_args.file_names=sprintf('"%s"', fileset_str);

3122

if OP.DISPLAY_WINDOW

3126

if OP.DISPLAY_WINDOW

3123

savefigs(param, OP);

3127

savefigs(param, OP);

3124

end

3128

end

3125

end

3129

end

3126

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3130

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3127

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3131

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3128

p1_ctle = -2*pi*f_p1;

3132

p1_ctle = -2*pi*f_p1;

3129

p2_ctle = -2*pi*f_p2;

3133

p2_ctle = -2*pi*f_p2;

3130

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3134

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3131

k_ctle = -p2_ctle;

3135

k_ctle = -p2_ctle;

3132

bilinear_fs = 2*fb*oversampling;

3136

bilinear_fs = 2*fb*oversampling;

3133

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3137

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3134

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3138

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3135

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3139

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3136

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3140

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3137

% allow for different pole zeros RIM 9-29-2015

3141

% allow for different pole zeros RIM 9-29-2015

3138

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3142

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3139

B_filt =k_ctle*kd*poly([zd, -1]);

3143

B_filt =k_ctle*kd*poly([zd, -1]);

3140

A_filt=poly([p1d, p2d]);

3144

A_filt=poly([p1d, p2d]);

3141

impulse_response=filter(B_filt,A_filt,ir_in);

3145

impulse_response=filter(B_filt,A_filt,ir_in);

3142

3146

3143

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3147

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3144

Over_sample=2;

3148

Over_sample=2;

3145

num_files=length(chdata);

3149

num_files=length(chdata);

3146

for i=1:num_files

3150

for i=1:num_files

3147

V=chdata(i).uneq_pulse_response;

3151

V=chdata(i).uneq_pulse_response;

3148

T=chdata(i).t;

3152

T=chdata(i).t;

3149

dt=T(2)-T(1);

3153

dt=T(2)-T(1);

3150

f=0:1/max(T):1/dt;

3154

f=0:1/max(T):1/dt;

3151

chdata(i).faxis=f;

3155

chdata(i).faxis=f;

3152

f75=find(f >= param.fb*.75,1,'first');

3156

f75=find(f >= param.fb*.75,1,'first');

3153

fnq=find(f >= param.fb*.5,1,'first');

3157

fnq=find(f >= param.fb*.5,1,'first');

3154

chdata(i).fmaxi = length(f);

3158

chdata(i).fmaxi = length(f);

3155

chdata(i).faxis = f;

3159

chdata(i).faxis = f;

3156

UI=param.ui; % unit interval

3160

UI=param.ui; % unit interval

3157

M=param.samples_per_ui; % sample per UI

3161

M=param.samples_per_ui; % sample per UI

3158

N_v=param.N_v; % number of UI for Vf determination

3162

N_v=param.N_v; % number of UI for Vf determination

3159

3163

3160

% filters

3164

% filters

3161

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3165

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3162

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3166

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3163

H_ftr=H_bw.*H_bt;

3167

H_ftr=H_bw.*H_bt;

3164

H_ftr=H_ftr(:);

3168

H_ftr=H_ftr(:);

3165

% fd of PR

3169

% fd of PR

3166

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3170

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3167

prr = prr(:);

3171

prr = prr(:);

3168

if f(1)==0, prr(1)=1; end %remove NaN

3172

if f(1)==0, prr(1)=1; end %remove NaN

3169

fd=fft(V);

3173

fd=fft(V);

3170

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3174

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3171

3175

3172

%% get Vf

3176

%% get Vf

3173

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3177

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3174

step_response=filter(V,1, shifting_vector);

3178

step_response=filter(V,1, shifting_vector);

3175

Vf=step_response(end);

3179

Vf=step_response(end);

3176

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3180

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3177

%%

3181

%%

3178

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3182

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3179

% figure

3183

% figure

3180

% plot(f(1:f75),ILest)

3184

% plot(f(1:f75),ILest)

3181

3185

3182

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3186

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3183

% set same variables as get_s4p_files

3187

% set same variables as get_s4p_files

3184

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3188

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3185

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3189

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3186

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3190

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3187

zero_vector=zeros(length(IL_conv),1);

3191

zero_vector=zeros(length(IL_conv),1);

3188

for j=1:length(IL_fields)

3192

for j=1:length(IL_fields)

3189

chdata(i).(IL_fields{j})=IL_conv;

3193

chdata(i).(IL_fields{j})=IL_conv;

3190

end

3194

end

3191

for j=1:length(Zero_fields)

3195

for j=1:length(Zero_fields)

3192

chdata(i).(Zero_fields{j})=zero_vector;

3196

chdata(i).(Zero_fields{j})=zero_vector;

3193

end

3197

end

3194

3198

3195

if i==1

3199

if i==1

3196

SDDch(:,1,2)=chdata.sdd12_raw;

3200

SDDch(:,1,2)=chdata.sdd12_raw;

3197

SDDch(:,2,1)=chdata.sdd21_raw;

3201

SDDch(:,2,1)=chdata.sdd21_raw;

3198

SDDch(:,1,1)=chdata.sdd11_raw;

3202

SDDch(:,1,1)=chdata.sdd11_raw;

3199

SDDch(:,2,2)=chdata.sdd22_raw;

3203

SDDch(:,2,2)=chdata.sdd22_raw;

3200

SDDp2p= zeros(length(IL_conv),1);

3204

SDDp2p= zeros(length(IL_conv),1);

3201

end

3205

end

3202

chdata(i).TX_RL=[];

3206

chdata(i).TX_RL=[];

3203

chdata(i).TDR11=[];

3207

chdata(i).TDR11=[];

3204

chdata(i).PDTR11=[];

3208

chdata(i).PDTR11=[];

3205

chdata(i).TDR22=[];

3209

chdata(i).TDR22=[];

3206

chdata(i).PDTR22=[];

3210

chdata(i).PDTR22=[];

3207

end

3211

end

3208

3212

3209

3213

3210

function H_tw=Tukey_Window(f,param,fr,fb)

3214

function H_tw=Tukey_Window(f,param,fr,fb)

3211

% RIM 05/26/2022 added optional fr and fb

3215

% RIM 05/26/2022 added optional fr and fb

3212

% fr is the start of the raised cosine window

3216

% fr is the start of the raised cosine window

3213

% fb is the end of the raised cosine window

3217

% fb is the end of the raised cosine window

3214

if ~exist('fr','var') && ~exist('fb','var')

3218

if ~exist('fr','var') && ~exist('fb','var')

3215

fb=param.fb;

3219

fb=param.fb;

3216

fr=param.f_r*param.fb;

3220

fr=param.f_r*param.fb;

3217

end

3221

end

3218

fperiod=2*(fb-fr);

3222

fperiod=2*(fb-fr);

3219

H_tw = [ ones(1,length(f(f<fr))) ...

3223

H_tw = [ ones(1,length(f(f<fr))) ...

3220

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3224

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3221

zeros(1,length(f(f>fb)) )];

3225

zeros(1,length(f(f>fb)) )];

3222

H_tw=H_tw(1:length(f));

3226

H_tw=H_tw(1:length(f));

3223

if 0

3227

if 0

3224

plot(f/1e9,H_tw)

3228

plot(f/1e9,H_tw)

3225

end

3229

end

3226

3230

3227

3231

3228

3232

3229

%% moved output control to functions

3233

%% moved output control to functions

3230

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3234

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3231

% Author: Richard Mellitz

3235

% Author: Richard Mellitz

3232

% Date: 7/29/2022

3236

% Date: 7/29/2022

3233

% generate FD tx ffe system function

3237

% generate FD tx ffe system function

3234

% varagins...

3238

% varagins...

3235

% param - stucture

3239

% param - stucture

3236

% param.fb baud rate

3240

% param.fb baud rate

3237

% param.Tx_FFE Tx FFE coef

3241

% param.Tx_FFE Tx FFE coef

3238

% f - freq array

3242

% f - freq array

3239

% Use_Tx_FFE = flag to use or not

3243

% Use_Tx_FFE = flag to use or not

3240

% H_TxFFE is system function for Tx_FFE

3244

% H_TxFFE is system function for Tx_FFE

3241

db = @(x) 20*log10(abs(x));

3245

db = @(x) 20*log10(abs(x));

3242

[param,varargin]=varargin_extractor(varargin{:});

3246

[param,varargin]=varargin_extractor(varargin{:});

3243

[f,varargin]=varargin_extractor(varargin{:});

3247

[f,varargin]=varargin_extractor(varargin{:});

3244

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3248

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3245

if isempty(Use_Tx_FFE)

3249

if isempty(Use_Tx_FFE)

3246

Use_Tx_FFE=0;

3250

Use_Tx_FFE=0;

3247

end

3251

end

3248

if isempty(param)

3252

if isempty(param)

3249

param.fb=106.25e9;

3253

param.fb=106.25e9;

3250

Tx_FFE=[1 ];

3254

Tx_FFE=[1 ];

3251

else

3255

else

3252

if ~isfield(param, 'Pkg_TXFFE_preset')

3256

if ~isfield(param, 'Pkg_TXFFE_preset')

3253

Tx_FFE=[ 1 ];

3257

Tx_FFE=[ 1 ];

3254

else

3258

else

3255

Tx_FFE=param.Pkg_TXFFE_preset;

3259

Tx_FFE=param.Pkg_TXFFE_preset;

3256

end

3260

end

3257

end

3261

end

3258

if isempty(f)

3262

if isempty(f)

3259

f=0:10e6:param.fb;

3263

f=0:10e6:param.fb;

3260

end

3264

end

3261

3265

3262

3266

3263

if Use_Tx_FFE ~=0

3267

if Use_Tx_FFE ~=0

3264

[mcur,icur] = max(Tx_FFE);

3268

[mcur,icur] = max(Tx_FFE);

3265

H_TxFFE=zeros(1,length(f));

3269

H_TxFFE=zeros(1,length(f));

3266

for ii=1:length(Tx_FFE)

3270

for ii=1:length(Tx_FFE)

3267

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3271

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3268

end

3272

end

3269

else

3273

else

3270

H_TxFFE=ones(1,length(f));

3274

H_TxFFE=ones(1,length(f));

3271

end

3275

end

3272

% figure (1102320)

3276

% figure (1102320)

3273

% plot(f/1e9,db(H_TxFFE))

3277

% plot(f/1e9,db(H_TxFFE))

3274

% hold on

3278

% hold on

3275

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3279

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3276

cmx=param.RxFFE_cmx;

3280

cmx=param.RxFFE_cmx;

3277

cpx=param.RxFFE_cpx;

3281

cpx=param.RxFFE_cpx;

3278

% do this early on so we can reuse the old code

3282

% do this early on so we can reuse the old code

3279

% to be replaced with MMSE function from healey...

3283

% to be replaced with MMSE function from healey...

3280

if param.N_bg ~=0 % must be floating taps

3284

if param.N_bg ~=0 % must be floating taps

3281

cpx=param.N_bmax; % N_f in spreadsheet

3285

cpx=param.N_bmax; % N_f in spreadsheet

3282

end

3286

end

3283

num_taps=cmx+cpx+1;

3287

num_taps=cmx+cpx+1;

3284

ndfe=param.ndfe;

3288

ndfe=param.ndfe;

3285

spui=param.samples_per_ui;

3289

spui=param.samples_per_ui;

3286

%% Start of WIENER-HOPF MMSE EQ code

3290

%% Start of WIENER-HOPF MMSE EQ code

3287

R_n = zeros(num_taps,num_taps);

3291

R_n = zeros(num_taps,num_taps);

3288

R_xt = zeros(num_taps,num_taps);

3292

R_xt = zeros(num_taps,num_taps);

3289

3293

3290

if OP.Do_Colored_Noise

3294

if OP.Do_Colored_Noise

3291

% Form Noise Autocorrelation matrix

3295

% Form Noise Autocorrelation matrix

3292

Noise_XC = reshape (Noise_XC,1,[]);

3296

Noise_XC = reshape (Noise_XC,1,[]);

3293

len = length(Noise_XC);

3297

len = length(Noise_XC);

3294

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3298

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3295

Noise_XC = Noise_XC(1:num_taps);

3299

Noise_XC = Noise_XC(1:num_taps);

3296

R_n = toeplitz (Noise_XC,Noise_XC);

3300

R_n = toeplitz (Noise_XC,Noise_XC);

3297

end

3301

end

3298

%% Calculate Cross Talk Correlation matrix at T intervals.

3302

%% Calculate Cross Talk Correlation matrix at T intervals.

3299

if OP.Do_XT_Noise

3303

if OP.Do_XT_Noise

3300

% Calculate variance of Tx signal based on +/-1 outer limits

3304

% Calculate variance of Tx signal based on +/-1 outer limits

3301

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3305

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3302

for jj = 2:length(chdata)

3306

for jj = 2:length(chdata)

3303

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3307

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3304

if isequal(chdata(jj).type, 'FEXT')

3308

if isequal(chdata(jj).type, 'FEXT')

3305

% len = length(chdata(jj).ctle_imp_response);

3309

% len = length(chdata(jj).ctle_imp_response);

3306

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3310

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3307

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3311

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3308

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3312

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3309

elseif isequal(chdata(jj).type, 'NEXT')

3313

elseif isequal(chdata(jj).type, 'NEXT')

3310

ch_imp = chdata(jj).ctle_imp_response;

3314

ch_imp = chdata(jj).ctle_imp_response;

3311

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3315

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3312

end

3316

end

3313

norms = zeros(1,spui);

3317

norms = zeros(1,spui);

3314

for ii = 1:spui

3318

for ii = 1:spui

3315

norms(ii) = norm(ch_imp(ii:spui:end));

3319

norms(ii) = norm(ch_imp(ii:spui:end));

3316

end

3320

end

3317

% Pick out sampling phase with largest noise contribution

3321

% Pick out sampling phase with largest noise contribution

3318

[~,cursor] = max(norms);

3322

[~,cursor] = max(norms);

3319

sub_sample_ch = ch_imp(cursor:spui:end);

3323

sub_sample_ch = ch_imp(cursor:spui:end);

3320

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3324

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3321

xc = xc(num_taps+1:end);

3325

xc = xc(num_taps+1:end);

3322

xc = xc(1:num_taps);

3326

xc = xc(1:num_taps);

3323

R = toeplitz (xc,xc);

3327

R = toeplitz (xc,xc);

3324

R_xt = R_xt + R;

3328

R_xt = R_xt + R;

3325

end

3329

end

3326

end

3330

end

3327

end

3331

end

3328

%% Noise + Cross Talk contribution to R matrix

3332

%% Noise + Cross Talk contribution to R matrix

3329

R_n_xc = zeros(num_taps+ndfe);

3333

R_n_xc = zeros(num_taps+ndfe);

3330

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3334

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3331

%% For least means squares, we want to solve

3335

%% For least means squares, we want to solve

3332

%

3336

%

3333

% ro = |Ryy Ryx| * w

3337

% ro = |Ryy Ryx| * w

3334

% |Rxy Rxx|

3338

% |Rxy Rxx|

3335

% see Cioffi chapter 3, 3.7.3

3339

% see Cioffi chapter 3, 3.7.3

3336

3340

3337

himp = vsampled;

3341

himp = vsampled;

3338

RefTap = cmx+1;

3342

RefTap = cmx+1;

3339

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3343

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3340

Ryy.r = [1:num_taps];

3344

Ryy.r = [1:num_taps];

3341

Ryy.c = [1:num_taps];

3345

Ryy.c = [1:num_taps];

3342

Ryx.r = 1:num_taps;

3346

Ryx.r = 1:num_taps;

3343

Ryx.c = num_taps + (1:ndfe);

3347

Ryx.c = num_taps + (1:ndfe);

3344

Rxy.r = num_taps + (1:ndfe);

3348

Rxy.r = num_taps + (1:ndfe);

3345

Rxy.c = 1:num_taps;

3349

Rxy.c = 1:num_taps;

3346

Rxx.r = num_taps+(1:ndfe);

3350

Rxx.r = num_taps+(1:ndfe);

3347

Rxx.c = num_taps+(1:ndfe);

3351

Rxx.c = num_taps+(1:ndfe);

3348

himp = reshape (himp,1,[]);

3352

himp = reshape (himp,1,[]);

3349

%% ro is simply the channel response reversed in time

3353

%% ro is simply the channel response reversed in time

3350

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3354

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3351

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3355

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3352

[~,pk] = max(himp_lr);

3356

[~,pk] = max(himp_lr);

3353

r_indx = (1:num_taps) - RefTap;

3357

r_indx = (1:num_taps) - RefTap;

3354

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3358

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3355

ro = ro*Signal_Variance;

3359

ro = ro*Signal_Variance;

3356

%% Setup up the covariance matrix

3360

%% Setup up the covariance matrix

3357

R = zeros(num_taps+ndfe);

3361

R = zeros(num_taps+ndfe);

3358

% Form Ryy

3362

% Form Ryy

3359

% Note: important to use whole impulse response

3363

% Note: important to use whole impulse response

3360

% not just the part that spans the FFE.

3364

% not just the part that spans the FFE.

3361

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3365

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3362

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3366

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3363

3367

3364

% Form Rxx

3368

% Form Rxx

3365

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3369

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3366

3370

3367

% Form Ryx columns

3371

% Form Ryx columns

3368

Ryx_indxs = (1:num_taps)-1;

3372

Ryx_indxs = (1:num_taps)-1;

3369

for jj = 0:ndfe-1

3373

for jj = 0:ndfe-1

3370

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3374

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3371

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3375

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3372

end

3376

end

3373

% Form Rxy rows

3377

% Form Rxy rows

3374

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3378

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3375

3379

3376

% add in Signal Variance

3380

% add in Signal Variance

3377

R = R*Signal_Variance;

3381

R = R*Signal_Variance;

3378

Rtmp = R;

3382

Rtmp = R;

3379

% Add in Xt and colored noise terms

3383

% Add in Xt and colored noise terms

3380

R = R + R_n_xc;

3384

R = R + R_n_xc;

3381

3385

3382

% SNR = 25 dB

3386

% SNR = 25 dB

3383

SNR = OP.FFE_SNR;

3387

SNR = OP.FFE_SNR;

3384

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3388

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3385

R_noise = diag(ones(1,num_taps))*Noise_var;

3389

R_noise = diag(ones(1,num_taps))*Noise_var;

3386

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3390

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3387

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3391

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3388

end

3392

end

3389

3393

3390

3394

3391

%% Solve for equalizer weights

3395

%% Solve for equalizer weights

3392

w = inv(R)*ro;

3396

w = inv(R)*ro;

3393

C = w;

3397

C = w;

3394

%% Deal with 1st post Cursor DFE weight saturation

3398

%% Deal with 1st post Cursor DFE weight saturation

3395

% ro = Rw by moving "saturated" weights over to the LHS

3399

% ro = Rw by moving "saturated" weights over to the LHS

3396

DFE_h1_indx = num_taps+1;

3400

DFE_h1_indx = num_taps+1;

3397

Indx_full = 1:length(C);

3401

Indx_full = 1:length(C);

3398

ws = C;

3402

ws = C;

3399

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3403

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3400

rtmp = reshape (ro,[],1);

3404

rtmp = reshape (ro,[],1);

3401

Rtmp = R;

3405

Rtmp = R;

3402

% Move saturated DFE weights over to left hand side of equation

3406

% Move saturated DFE weights over to left hand side of equation

3403

ws = zeros (size(C));

3407

ws = zeros (size(C));

3404

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3408

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3405

rtmp = rtmp - Rtmp*ws;

3409

rtmp = rtmp - Rtmp*ws;

3406

3410

3407

% and remove the corresponding column from R

3411

% and remove the corresponding column from R

3408

Rtmp(:,DFE_h1_indx) = [];

3412

Rtmp(:,DFE_h1_indx) = [];

3409

Indx_full (DFE_h1_indx) = [];

3413

Indx_full (DFE_h1_indx) = [];

3410

% now Rtmp isn't square so have to use the R'R trick

3414

% now Rtmp isn't square so have to use the R'R trick

3411

% Probably a little dicey "theoretically" because

3415

% Probably a little dicey "theoretically" because

3412

% w = inv(R)*ro is already the mmse solution

3416

% w = inv(R)*ro is already the mmse solution

3413

% now we at doing a R'R operation, but hey

3417

% now we at doing a R'R operation, but hey

3414

% seems to work

3418

% seems to work

3415

% Alternative, since R is now over specified, more rows than

3419

% Alternative, since R is now over specified, more rows than

3416

% columns, one could try removing one of the DFE rows from the

3420

% columns, one could try removing one of the DFE rows from the

3417

% Rxy Rxx portion of the R matrix.

3421

% Rxy Rxx portion of the R matrix.

3418

3422

3419

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3423

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3420

ws (Indx_full,:) = w_partial;

3424

ws (Indx_full,:) = w_partial;

3421

C = ws;

3425

C = ws;

3422

end

3426

end

3423

% From Cioffi, Chapter 3

3427

% From Cioffi, Chapter 3

3424

var_ffe_dfe = Signal_Variance-ws.'*ro;

3428

var_ffe_dfe = Signal_Variance-ws.'*ro;

3425

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3429

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3426

3430

3427

%% Scale FFE gain to target output voltage

3431

%% Scale FFE gain to target output voltage

3428

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3432

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3429

C = C*Target_ouput;

3433

C = C*Target_ouput;

3430

C = C(1:num_taps);

3434

C = C(1:num_taps);

3431

%% End MMSE dfe code

3435

%% End MMSE dfe code

3432

function Write_CSV(output_args,csv_file)

3436

function Write_CSV(output_args,csv_file)

3433

3437

3434

items = fieldnames(output_args);

3438

items = fieldnames(output_args);

3435

item_value_strings = cell(size(items));

3439

item_value_strings = cell(size(items));

3436

for field_id=1:length(items)

3440

for field_id=1:length(items)

3437

field_name=items{field_id};

3441

field_name=items{field_id};

3438

field_value=output_args.(field_name);

3442

field_value=output_args.(field_name);

3439

if isstruct(output_args.(field_name))

3443

if isstruct(output_args.(field_name))

3440

field_value='struct';

3444

field_value='struct';

3441

end

3445

end

3442

if ischar(field_value)

3446

if ischar(field_value)

3443

item_value_strings{field_id}=field_value;

3447

item_value_strings{field_id}=field_value;

3444

elseif isempty(field_value)

3448

elseif isempty(field_value)

3445

item_value_strings{field_id}='';

3449

item_value_strings{field_id}='';

3446

elseif numel(field_value)==1

3450

elseif numel(field_value)==1

3447

item_value_strings{field_id}=num2str(field_value);

3451

item_value_strings{field_id}=num2str(field_value);

3448

else

3452

else

3449

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3453

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3450

end

3454

end

3451

end

3455

end

3452

3456

3453

header_string = str2csv(items);

3457

header_string = str2csv(items);

3454

data_string = str2csv(item_value_strings);

3458

data_string = str2csv(item_value_strings);

3455

fid = fopen(csv_file,'w');

3459

fid = fopen(csv_file,'w');

3456

fprintf(fid,'%s\n', header_string);

3460

fprintf(fid,'%s\n', header_string);

3457

fprintf(fid,'%s\n', data_string);

3461

fprintf(fid,'%s\n', data_string);

3458

fclose(fid);

3462

fclose(fid);

3459

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3463

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3460

%% Used in Clause 92 for adding board trace between TP0 and TP2

3464

%% Used in Clause 92 for adding board trace between TP0 and TP2

3461

3465

3462

switch chdata.type

3466

switch chdata.type

3463

case 'THRU'

3467

case 'THRU'

3464

z_bp_tx = param.z_bp_tx;

3468

z_bp_tx = param.z_bp_tx;

3465

z_bp_rx = param.z_bp_rx;

3469

z_bp_rx = param.z_bp_rx;

3466

case 'NEXT'

3470

case 'NEXT'

3467

z_bp_tx = param.z_bp_rx;

3471

z_bp_tx = param.z_bp_rx;

3468

z_bp_rx = param.z_bp_next;

3472

z_bp_rx = param.z_bp_next;

3469

case 'FEXT'

3473

case 'FEXT'

3470

z_bp_tx = param.z_bp_fext;

3474

z_bp_tx = param.z_bp_fext;

3471

z_bp_rx = param.z_bp_rx;

3475

z_bp_rx = param.z_bp_rx;

3472

end

3476

end

3473

% Same cap on each tx and rx three is a data stratue for bifrucation but

3477

% Same cap on each tx and rx three is a data stratue for bifrucation but

3474

% logic no implemented here RIM 06/28/2019

3478

% logic no implemented here RIM 06/28/2019

3475

zref=param.Z0;

3479

zref=param.Z0;

3476

c1=param.C_0;

3480

c1=param.C_0;

3477

c2=param.C_1;

3481

c2=param.C_1;

3478

f=chdata.faxis;

3482

f=chdata.faxis;

3479

f(f<eps)=eps;

3483

f(f<eps)=eps;

3480

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3484

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3481

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3485

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3482

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3486

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3483

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3487

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3484

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3488

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3485

% add Tx caps

3489

% add Tx caps

3486

[s11tx, s12tx, s21tx, s22tx ]= ...

3490

[s11tx, s12tx, s21tx, s22tx ]= ...

3487

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3491

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3488

[s11tx, s12tx, s21tx, s22tx ]= ...

3492

[s11tx, s12tx, s21tx, s22tx ]= ...

3489

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3493

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3490

3494

3491

3495

3492

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3496

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3493

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3497

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3494

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3498

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3495

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3499

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3496

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3500

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3497

% add Rx caps

3501

% add Rx caps

3498

[s11rx, s12rx, s21rx, s22rx ]= ...

3502

[s11rx, s12rx, s21rx, s22rx ]= ...

3499

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3503

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3500

[s11rx, s12rx, s21rx, s22rx ]= ...

3504

[s11rx, s12rx, s21rx, s22rx ]= ...

3501

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3505

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3502

3506

3503

3507

3504

switch OP.include_pcb

3508

switch OP.include_pcb

3505

case 1

3509

case 1

3506

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3510

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3507

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3511

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3508

case 2

3512

case 2

3509

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3513

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3510

end

3514

end

3511

3515

3512

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3516

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3513

% Used in Clause 92 for adding board trace between TP0 and TP2

3517

% Used in Clause 92 for adding board trace between TP0 and TP2

3514

switch chdata.type

3518

switch chdata.type

3515

case 'THRU'

3519

case 'THRU'

3516

z_bp_tx = param.z_bp_tx;

3520

z_bp_tx = param.z_bp_tx;

3517

case 'NEXT'

3521

case 'NEXT'

3518

z_bp_tx = param.z_bp_next;

3522

z_bp_tx = param.z_bp_next;

3519

case 'FEXT'

3523

case 'FEXT'

3520

z_bp_tx = param.z_bp_fext;

3524

z_bp_tx = param.z_bp_fext;

3521

end

3525

end

3522

3526

3523

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3527

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3524

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3528

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3525

3529

3526

switch OP.include_pcb

3530

switch OP.include_pcb

3527

case 1

3531

case 1

3528

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3532

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3529

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3533

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3530

case 2

3534

case 2

3531

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3535

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3532

end

3536

end

3533

3537

3534

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3538

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3535

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3539

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3536

% applying a bank of DFE at desired location

3540

% applying a bank of DFE at desired location

3537

% hisi: waveform with cursor values;

3541

% hisi: waveform with cursor values;

3538

% idx: starting index of the bank;

3542

% idx: starting index of the bank;

3539

% tap_bk: number of taps in bank;

3543

% tap_bk: number of taps in bank;

3540

% bmaxg: maxmum coefficient in bank;

3544

% bmaxg: maxmum coefficient in bank;

3541

3545

3542

if nargin<6

3546

if nargin<6

3543

dfe_delta=0;

3547

dfe_delta=0;

3544

end

3548

end

3545

3549

3546

rng=idx:idx+tap_bk-1;

3550

rng=idx:idx+tap_bk-1;

3547

flt_curval=hisi(rng);

3551

flt_curval=hisi(rng);

3548

3552

3549

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3553

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3550

3554

3551

if dfe_delta~=0

3555

if dfe_delta~=0

3552

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3556

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3553

dfe_delta.*sign(flt_curval)*curval;

3557

dfe_delta.*sign(flt_curval)*curval;

3554

else

3558

else

3555

flt_curval_q=hisi(rng);

3559

flt_curval_q=hisi(rng);

3556

end

3560

end

3557

3561

3558

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3562

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3559

hisi(rng)= hisi(rng) - curval*tap_coef;

3563

hisi(rng)= hisi(rng) - curval*tap_coef;

3560

hisi_ref(rng)=0;

3564

hisi_ref(rng)=0;

3561

3565

3562

%AJG021820

3566

%AJG021820

3563

function [ a] = bessel( n )

3567

function [ a] = bessel( n )

3564

% bessel polynomial

3568

% bessel polynomial

3565

for ii= 0:n

3569

for ii= 0:n

3566

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3570

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3567

end

3571

end

3568

3572

3569

3573

3570

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3574

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3571

% History:

3575

% History:

3572

% 1. 14th October, 2021 (Intial release)

3576

% 1. 14th October, 2021 (Intial release)

3573

3577

3574

% Definition:

3578

% Definition:

3575

% This function captures the channel delay through the time domain using causality enforcement.

3579

% This function captures the channel delay through the time domain using causality enforcement.

3576

% Following are the steps being followed.

3580

% Following are the steps being followed.

3577

% Step 1. Cascade negative frequencies

3581

% Step 1. Cascade negative frequencies

3578

% Step 2. Extract magnitude

3582

% Step 2. Extract magnitude

3579

% Step 3. IFFT of the magnitude

3583

% Step 3. IFFT of the magnitude

3580

% Step 4. Multiply by the sign(t)

3584

% Step 4. Multiply by the sign(t)

3581

% Step 5. Calculate the phase of the 1j*causal_phase

3585

% Step 5. Calculate the phase of the 1j*causal_phase

3582

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3586

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3583

% Step 7. f-domain to t-domain pulse response

3587

% Step 7. f-domain to t-domain pulse response

3584

% Step 8. Calculate the delay

3588

% Step 8. Calculate the delay

3585

3589

3586

% Author:

3590

% Author:

3587

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3591

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3588

3592

3589

% Reference:

3593

% Reference:

3590

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3594

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3591

3595

3592

% Input:

3596

% Input:

3593

% freq %frequency in hertz (odd number points)

3597

% freq %frequency in hertz (odd number points)

3594

% sdd21 %insertion loss in complex (odd number points)

3598

% sdd21 %insertion loss in complex (odd number points)

3595

% param %COM native structure passed

3599

% param %COM native structure passed

3596

% OP %COM native structure passed

3600

% OP %COM native structure passed

3597

3601

3598

% Output:

3602

% Output:

3599

% delay_sec %channel delay in seconds

3603

% delay_sec %channel delay in seconds

3600

% delay_idx %channel delay index

3604

% delay_idx %channel delay index

3601

3605

3602

if iscolumn(sdd21)

3606

if iscolumn(sdd21)

3603

sdd21= sdd21.';

3607

sdd21= sdd21.';

3604

end

3608

end

3605

if iscolumn(freq)

3609

if iscolumn(freq)

3606

freq= freq.';

3610

freq= freq.';

3607

end

3611

end

3608

3612

3609

%---start. Step 1. Cascade negative frequencies

3613

%---start. Step 1. Cascade negative frequencies

3610

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3614

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3611

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3615

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3612

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3616

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3613

%---end. Step 1. Cascade negative frequencies

3617

%---end. Step 1. Cascade negative frequencies

3614

3618

3615

%---start. Step 2. Extract magnitude

3619

%---start. Step 2. Extract magnitude

3616

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3620

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3617

%---end. Step 2. Extract magnitude

3621

%---end. Step 2. Extract magnitude

3618

3622

3619

%---start. Step 3. IFFT of the magnitude

3623

%---start. Step 3. IFFT of the magnitude

3620

sdd21_mag_time = ifft(sdd21_mag_conj);

3624

sdd21_mag_time = ifft(sdd21_mag_conj);

3621

%---end. Step 3. IFFT of the magnitude

3625

%---end. Step 3. IFFT of the magnitude

3622

3626

3623

%---start. Step 4. Multiply by the sign(t)

3627

%---start. Step 4. Multiply by the sign(t)

3624

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3628

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3625

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3629

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3626

%---end. Step 4. Multiply by the sign(t)

3630

%---end. Step 4. Multiply by the sign(t)

3627

3631

3628

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3632

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3629

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3633

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3630

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3634

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3631

3635

3632

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3636

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3633

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3637

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3634

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3638

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3635

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3639

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3636

3640

3637

%---start. Step 7. f-domain to t-domain pulse response

3641

%---start. Step 7. f-domain to t-domain pulse response

3638

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3642

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3639

%--------- Extrapolation has been already done by the COM tool

3643

%--------- Extrapolation has been already done by the COM tool

3640

freq_array= freq;

3644

freq_array= freq;

3641

time_step= param.sample_dt;

3645

time_step= param.sample_dt;

3642

fmax=1/time_step/2;

3646

fmax=1/time_step/2;

3643

freq_step=(freq_array(3)-freq_array(2))/1;

3647

freq_step=(freq_array(3)-freq_array(2))/1;

3644

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3648

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3645

3649

3646

ILin=sdd21;

3650

ILin=sdd21;

3647

IL=interp_Sparam(ILin,freq_array,fout, ...

3651

IL=interp_Sparam(ILin,freq_array,fout, ...

3648

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3652

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3649

IL_nan = find(isnan(IL));

3653

IL_nan = find(isnan(IL));

3650

for in=IL_nan

3654

for in=IL_nan

3651

IL(in)=IL(in-1);

3655

IL(in)=IL(in-1);

3652

end

3656

end

3653

IL = IL(:);

3657

IL = IL(:);

3654

% add padding for time steps

3658

% add padding for time steps

3655

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3659

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3656

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3660

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3657

clear IL IL_nan IL_symmetric

3661

clear IL IL_nan IL_symmetric

3658

3662

3659

ILin=sdd21_causality_enforced;

3663

ILin=sdd21_causality_enforced;

3660

IL=interp_Sparam(ILin,freq_array,fout, ...

3664

IL=interp_Sparam(ILin,freq_array,fout, ...

3661

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3665

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3662

IL_nan = find(isnan(IL));

3666

IL_nan = find(isnan(IL));

3663

for in=IL_nan

3667

for in=IL_nan

3664

IL(in)=IL(in-1);

3668

IL(in)=IL(in-1);

3665

end

3669

end

3666

IL = IL(:);

3670

IL = IL(:);

3667

% add padding for time steps

3671

% add padding for time steps

3668

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3672

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3669

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3673

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3670

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3674

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3671

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3675

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3672

clear IL IL_nan IL_symmetric

3676

clear IL IL_nan IL_symmetric

3673

3677

3674

clear time_step fmax freq_step freq_array

3678

clear time_step fmax freq_step freq_array

3675

3679

3676

freq_step=(fout(3)-fout(2))/1;

3680

freq_step=(fout(3)-fout(2))/1;

3677

L= length(sdd21_PR);

3681

L= length(sdd21_PR);

3678

t_base = (0:L-1)/(freq_step*L);

3682

t_base = (0:L-1)/(freq_step*L);

3679

clear fout freq_step L

3683

clear fout freq_step L

3680

%---end. Step 7. f-domain to t-domain pulse response

3684

%---end. Step 7. f-domain to t-domain pulse response

3681

3685

3682

%---start. Step 8. Calculate the delay

3686

%---start. Step 8. Calculate the delay

3683

%------start. Remove the last 5% of the waveform for noise due to IFFT

3687

%------start. Remove the last 5% of the waveform for noise due to IFFT

3684

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3688

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3685

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3689

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3686

%------end. Remove the last 5% of the waveform for noise due to IFFT

3690

%------end. Remove the last 5% of the waveform for noise due to IFFT

3687

3691

3688

%---start. calculate the difference in index between the peaks

3692

%---start. calculate the difference in index between the peaks

3689

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3693

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3690

[~, peak_y_idx] = max(sdd21_PR_reduced);

3694

[~, peak_y_idx] = max(sdd21_PR_reduced);

3691

peak_idx_difference = peak_x_idx - peak_y_idx;

3695

peak_idx_difference = peak_x_idx - peak_y_idx;

3692

%---end. calculate the difference in index between the peaks

3696

%---end. calculate the difference in index between the peaks

3693

3697

3694

if peak_idx_difference~=0

3698

if peak_idx_difference~=0

3695

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3699

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3696

error_value = length(sdd21_causality_enforced_PR_reduced);

3700

error_value = length(sdd21_causality_enforced_PR_reduced);

3697

error_idx = 0;

3701

error_idx = 0;

3698

% i= 1;

3702

% i= 1;

3699

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3703

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3700

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3704

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3701

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3705

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3702

if (error_value > current_error)

3706

if (error_value > current_error)

3703

error_idx = shift_value;

3707

error_idx = shift_value;

3704

error_value = current_error;

3708

error_value = current_error;

3705

end

3709

end

3706

% error_idx_H(i)= error_idx;

3710

% error_idx_H(i)= error_idx;

3707

% i= i+ 1;

3711

% i= i+ 1;

3708

end

3712

end

3709

%plot(error_idx_H);

3713

%plot(error_idx_H);

3710

3714

3711

if error_idx==0

3715

if error_idx==0

3712

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3716

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3713

end

3717

end

3714

3718

3715

delay_idx = error_idx;

3719

delay_idx = error_idx;

3716

else

3720

else

3717

delay_idx= 1;

3721

delay_idx= 1;

3718

end

3722

end

3719

3723

3720

delay_sec= t_base(abs(delay_idx));

3724

delay_sec= t_base(abs(delay_idx));

3721

3725

3722

3726

3723

function [return_struct]= capture_RIL_RILN(chdata)

3727

function [return_struct]= capture_RIL_RILN(chdata)

3724

% History:

3728

% History:

3725

% 1. 12th April, 2019 (Intial release)

3729

% 1. 12th April, 2019 (Intial release)

3726

%

3730

%

3727

% 2. 11th October, 2021

3731

% 2. 11th October, 2021

3728

% - Details:

3732

% - Details:

3729

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3733

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3730

% 2] Revised the selection criteria for the solution of the quadratic

3734

% 2] Revised the selection criteria for the solution of the quadratic

3731

% equation in finding the reflection coefficient (rho).

3735

% equation in finding the reflection coefficient (rho).

3732

% - Impact:

3736

% - Impact:

3733

% => Zero impact in |RIL|, while impact on angle(RIL).

3737

% => Zero impact in |RIL|, while impact on angle(RIL).

3734

% - Previous:

3738

% - Previous:

3735

% %---start. For passive networks the reflection coefficient should be less than one

3739

% %---start. For passive networks the reflection coefficient should be less than one

3736

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3740

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3737

% rho_port2= solution_1;

3741

% rho_port2= solution_1;

3738

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3742

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3739

% rho_port2= solution_2;

3743

% rho_port2= solution_2;

3740

% else

3744

% else

3741

% rho_port2= solution_1;

3745

% rho_port2= solution_1;

3742

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3746

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3743

% end

3747

% end

3744

% %---end. For passive networks the reflection coefficient should be less than one

3748

% %---end. For passive networks the reflection coefficient should be less than one

3745

%

3749

%

3746

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3750

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3747

% - Change:

3751

% - Change:

3748

% %---start. Given the real part of the impedance is to be positive

3752

% %---start. Given the real part of the impedance is to be positive

3749

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3753

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3750

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3754

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3751

%

3755

%

3752

% rho_port2= zeros(length(solution_1), 1);

3756

% rho_port2= zeros(length(solution_1), 1);

3753

% for solution_idx= 1:length(solution_1)

3757

% for solution_idx= 1:length(solution_1)

3754

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3758

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3755

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3759

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3756

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3760

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3757

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3761

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3758

% else

3762

% else

3759

% error('An odd case has occured. Please contact the tool developer.');

3763

% error('An odd case has occured. Please contact the tool developer.');

3760

% end

3764

% end

3761

% end

3765

% end

3762

% %---end. Given the real part of the impedance is to be positive

3766

% %---end. Given the real part of the impedance is to be positive

3763

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3767

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3764

3768

3765

% Definition:

3769

% Definition:

3766

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3770

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3767

3771

3768

% Author:

3772

% Author:

3769

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3773

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3770

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3774

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3771

3775

3772

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3776

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3773

3777

3774

% Reference:

3778

% Reference:

3775

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3779

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3776

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3780

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3777

3781

3778

% Input:

3782

% Input:

3779

% 1] SCH: S-matrix structure

3783

% 1] SCH: S-matrix structure

3780

% SCH.Frequencies= faxis;

3784

% SCH.Frequencies= faxis;

3781

% SCH.Parameters(1,1,:)= sdd11;

3785

% SCH.Parameters(1,1,:)= sdd11;

3782

% SCH.Parameters(2,2,:)= sdd22;

3786

% SCH.Parameters(2,2,:)= sdd22;

3783

% SCH.Parameters(1,2,:)= sdd12;

3787

% SCH.Parameters(1,2,:)= sdd12;

3784

% SCH.Parameters(2,1,:)= sdd21;

3788

% SCH.Parameters(2,1,:)= sdd21;

3785

% SCH.NumPorts= 2;

3789

% SCH.NumPorts= 2;

3786

% SCH.Impedance= 100;

3790

% SCH.Impedance= 100;

3787

3791

3788

% Output: Struct returned has the following,

3792

% Output: Struct returned has the following,

3789

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3793

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3790

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3794

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3791

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3795

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3792

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3796

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3793

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3797

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3794

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3798

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3795

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3799

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3796

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3800

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3797

% return_struct.freq %Frequency axis

3801

% return_struct.freq %Frequency axis

3798

3802

3799

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3803

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3800

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3804

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3801

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3805

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3802

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3806

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3803

SCH.Frequencies=chdata(1).faxis;

3807

SCH.Frequencies=chdata(1).faxis;

3804

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3808

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3805

SCH.NumPorts= 2;

3809

SCH.NumPorts= 2;

3806

3810

3807

%---start. allowed is only a 2-port network having a transmitter and receiver

3811

%---start. allowed is only a 2-port network having a transmitter and receiver

3808

if size(SCH.Parameters, 1)~=2

3812

if size(SCH.Parameters, 1)~=2

3809

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3813

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3810

error('Allowed is only a 2-port network having a transmitter and receiver.');

3814

error('Allowed is only a 2-port network having a transmitter and receiver.');

3811

end

3815

end

3812

%---end. allowed is only a 2-port network having a transmitter and receiver

3816

%---end. allowed is only a 2-port network having a transmitter and receiver

3813

3817

3814

%---start. do not include the DC point given sinusoidals at DC are not

3818

%---start. do not include the DC point given sinusoidals at DC are not

3815

%defined

3819

%defined

3816

if SCH.Frequencies(1)==0

3820

if SCH.Frequencies(1)==0

3817

idx_start= 2;

3821

idx_start= 2;

3818

else

3822

else

3819

idx_start= 1;

3823

idx_start= 1;

3820

end

3824

end

3821

%---end. do not include the DC point given sinusoidals at DC are not

3825

%---end. do not include the DC point given sinusoidals at DC are not

3822

%defined

3826

%defined

3823

3827

3824

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3828

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3825

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3829

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3826

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3830

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3827

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3831

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3828

3832

3829

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3833

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3830

b= 1+ Sdd22.*conj(Sdd22)+...

3834

b= 1+ Sdd22.*conj(Sdd22)+...

3831

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3835

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3832

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3836

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3833

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3837

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3834

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3838

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3835

Sdd11.*conj(Sdd11);

3839

Sdd11.*conj(Sdd11);

3836

c= -conj(Sdd22)-...

3840

c= -conj(Sdd22)-...

3837

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3841

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3838

Sdd11.*conj(Sdd11).*conj(Sdd22);

3842

Sdd11.*conj(Sdd11).*conj(Sdd22);

3839

3843

3840

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3844

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3841

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3845

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3842

3846

3843

clear a b c

3847

clear a b c

3844

3848

3845

%---start. Given the real part of the impedance is to be positive

3849

%---start. Given the real part of the impedance is to be positive

3846

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3850

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3847

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3851

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3848

3852

3849

rho_port2= zeros(length(solution_1), 1);

3853

rho_port2= zeros(length(solution_1), 1);

3850

for solution_idx= 1:length(solution_1)

3854

for solution_idx= 1:length(solution_1)

3851

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3855

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3852

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3856

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3853

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3857

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3854

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3858

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3855

else

3859

else

3856

error('An odd case has occured. Please contact the tool developer.');

3860

error('An odd case has occured. Please contact the tool developer.');

3857

end

3861

end

3858

end

3862

end

3859

%---end. Given the real part of the impedance is to be positive

3863

%---end. Given the real part of the impedance is to be positive

3860

3864

3861

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3865

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3862

3866

3863

%---start. calculate the equivalent port impedance

3867

%---start. calculate the equivalent port impedance

3864

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3868

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3865

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3869

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3866

%---end. calculate the equivalent port impedance

3870

%---end. calculate the equivalent port impedance

3867

3871

3868

3872

3869

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3873

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3870

% %to zero reflections.

3874

% %to zero reflections.

3871

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3875

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3872

%---end. The reflectionless insertion loss is the insertion loss corresponding

3876

%---end. The reflectionless insertion loss is the insertion loss corresponding

3873

%to zero reflections.

3877

%to zero reflections.

3874

3878

3875

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3879

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3876

RILN= RIL- Sdd21;

3880

RILN= RIL- Sdd21;

3877

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3881

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3878

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3882

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3879

3883

3880

%---start. preparing returns struct

3884

%---start. preparing returns struct

3881

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3885

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3882

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3886

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3883

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3887

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3884

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3888

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3885

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3889

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3886

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3890

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3887

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3891

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3888

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3892

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3889

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3893

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3890

%---end. preparing returns struct

3894

%---end. preparing returns struct

3891

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3895

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3892

3896

3893

3897

3894

%For the given BER, find the top & bottom voltage level in the CDF

3898

%For the given BER, find the top & bottom voltage level in the CDF

3895

3899

3896

%for the top, just find the first index at the spec BER

3900

%for the top, just find the first index at the spec BER

3897

nidx=find(cdf.y>specBER, 1, 'first');

3901

nidx=find(cdf.y>specBER, 1, 'first');

3898

noise_bottom = cdf.x(nidx);

3902

noise_bottom = cdf.x(nidx);

3899

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3903

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3900

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3904

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3901

%the true index without flipping

3905

%the true index without flipping

3902

nidx=length(cdf.y)-nidx+1;

3906

nidx=length(cdf.y)-nidx+1;

3903

noise_top = cdf.x(nidx);

3907

noise_top = cdf.x(nidx);

3904

function p=comb_fct(p1, p2)

3908

function p=comb_fct(p1, p2)

3905

if p1.BinSize ~= p2.BinSize

3909

if p1.BinSize ~= p2.BinSize

3906

error('bin size must be equal')

3910

error('bin size must be equal')

3907

end

3911

end

3908

3912

3909

p=p1;

3913

p=p1;

3910

p.BinSize=p1.BinSize;

3914

p.BinSize=p1.BinSize;

3911

%p.Min=p1.Min+p2.Min;

3915

%p.Min=p1.Min+p2.Min;

3912

p.Min=min(p1.Min,p2.Min);

3916

p.Min=min(p1.Min,p2.Min);

3913

difsz=abs(p1.Min-p2.Min);

3917

difsz=abs(p1.Min-p2.Min);

3914

lp1=length(p1.y);

3918

lp1=length(p1.y);

3915

lp2=length(p2.y);

3919

lp2=length(p2.y);

3916

if p1.Min == p.Min

3920

if p1.Min == p.Min

3917

p2.y(difsz+1:lp2+difsz)=p2.y;

3921

p2.y(difsz+1:lp2+difsz)=p2.y;

3918

p2.y(1:difsz)=0;

3922

p2.y(1:difsz)=0;

3919

p2.y(lp2+difsz+1:lp1)=0;

3923

p2.y(lp2+difsz+1:lp1)=0;

3920

elseif p2.Min == p.Min

3924

elseif p2.Min == p.Min

3921

p1.y(difsz+1:lp1+difsz)=p1.y;

3925

p1.y(difsz+1:lp1+difsz)=p1.y;

3922

p1.y(1:difsz)=0;

3926

p1.y(1:difsz)=0;

3923

p1.y(lp1+difsz+1:lp2)=0;

3927

p1.y(lp1+difsz+1:lp2)=0;

3924

end

3928

end

3925

% p.y=conv(p1.y, p2.y);

3929

% p.y=conv(p1.y, p2.y);

3926

p.y=(p1.y+p2.y);

3930

p.y=(p1.y+p2.y);

3927

% p.y=p.y/sum(p.y);

3931

% p.y=p.y/sum(p.y);

3928

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3932

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3929

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3933

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3930

3934

3931

3935

3932

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3936

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3933

3937

3934

if pdf1.BinSize ~= pdf2.BinSize

3938

if pdf1.BinSize ~= pdf2.BinSize

3935

error('bin size must be equal')

3939

error('bin size must be equal')

3936

end

3940

end

3937

3941

3938

x1=pdf1.x;

3942

x1=pdf1.x;

3939

y1=pdf1.y;

3943

y1=pdf1.y;

3940

x2=pdf2.x;

3944

x2=pdf2.x;

3941

y2=pdf2.y;

3945

y2=pdf2.y;

3942

%find the pdf with a larger min, force it to have the same min, and insert

3946

%find the pdf with a larger min, force it to have the same min, and insert

3943

%probability = 0

3947

%probability = 0

3944

min1=pdf1.x(1);

3948

min1=pdf1.x(1);

3945

min2=pdf2.x(1);

3949

min2=pdf2.x(1);

3946

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3950

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3947

if min1<min2

3951

if min1<min2

3948

x2=[pdf1.x(1:shift_amount) pdf2.x];

3952

x2=[pdf1.x(1:shift_amount) pdf2.x];

3949

y2=[zeros(1,shift_amount) pdf2.y];

3953

y2=[zeros(1,shift_amount) pdf2.y];

3950

else

3954

else

3951

x1=[pdf2.x(1:shift_amount) pdf1.x];

3955

x1=[pdf2.x(1:shift_amount) pdf1.x];

3952

y1=[zeros(1,shift_amount) pdf1.y];

3956

y1=[zeros(1,shift_amount) pdf1.y];

3953

end

3957

end

3954

%find the pdf with smaller max, force it to have the same max, and insert

3958

%find the pdf with smaller max, force it to have the same max, and insert

3955

%probability=0

3959

%probability=0

3956

L1=length(x1);

3960

L1=length(x1);

3957

L2=length(x2);

3961

L2=length(x2);

3958

Ldiff=abs(L1-L2);

3962

Ldiff=abs(L1-L2);

3959

if L1>L2

3963

if L1>L2

3960

out_x=x1;

3964

out_x=x1;

3961

y2=[y2 zeros(1,Ldiff)];

3965

y2=[y2 zeros(1,Ldiff)];

3962

else

3966

else

3963

out_x=x2;

3967

out_x=x2;

3964

y1=[y1 zeros(1,Ldiff)];

3968

y1=[y1 zeros(1,Ldiff)];

3965

end

3969

end

3966

%now the 2 pdfs have the same voltage axis, add probabilities together

3970

%now the 2 pdfs have the same voltage axis, add probabilities together

3967

%renormalization is not handled here, so the output pdf will not have sum=1

3971

%renormalization is not handled here, so the output pdf will not have sum=1

3968

%It is the responsibility of the calling function to handle renormalization

3972

%It is the responsibility of the calling function to handle renormalization

3969

%if needed

3973

%if needed

3970

out_y=y1+y2;

3974

out_y=y1+y2;

3971

out_pdf.x=out_x;

3975

out_pdf.x=out_x;

3972

out_pdf.y=out_y;

3976

out_pdf.y=out_y;

3973

out_pdf.BinSize=pdf1.BinSize;

3977

out_pdf.BinSize=pdf1.BinSize;

3974

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3978

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3975

3979

3976

%original method:

3980

%original method:

3977

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3981

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3978

% for i=1:length(s11in1)

3982

% for i=1:length(s11in1)

3979

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3983

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3980

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3984

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3981

% end

3985

% end

3982

% t1=stot(s1);

3986

% t1=stot(s1);

3983

% t2=stot(s2);

3987

% t2=stot(s2);

3984

% for i=1:length(s11in1)

3988

% for i=1:length(s11in1)

3985

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3989

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3986

% end

3990

% end

3987

% s3=ttos(t3);

3991

% s3=ttos(t3);

3988

% s11out=s3(1,1,:);

3992

% s11out=s3(1,1,:);

3989

% s11out=transpose(s11out(:));

3993

% s11out=transpose(s11out(:));

3990

% s12out=s3(1,2,:);

3994

% s12out=s3(1,2,:);

3991

% s12out=transpose(s12out(:));

3995

% s12out=transpose(s12out(:));

3992

% s21out=s3(2,1,:);

3996

% s21out=s3(2,1,:);

3993

% s21out=transpose(s21out(:));

3997

% s21out=transpose(s21out(:));

3994

% s22out=s3(2,2,:);

3998

% s22out=s3(2,2,:);

3995

% s22out=transpose(s22out(:));

3999

% s22out=transpose(s22out(:));

3996

4000

3997

4001

3998

%vectorized method:

4002

%vectorized method:

3999

s1(1,1,:)=s11in1;

4003

s1(1,1,:)=s11in1;

4000

s1(1,2,:)=s12in1;

4004

s1(1,2,:)=s12in1;

4001

s1(2,1,:)=s21in1;

4005

s1(2,1,:)=s21in1;

4002

s1(2,2,:)=s22in1;

4006

s1(2,2,:)=s22in1;

4003

s2(1,1,:)=s11in2;

4007

s2(1,1,:)=s11in2;

4004

s2(1,2,:)=s12in2;

4008

s2(1,2,:)=s12in2;

4005

s2(2,1,:)=s21in2;

4009

s2(2,1,:)=s21in2;

4006

s2(2,2,:)=s22in2;

4010

s2(2,2,:)=s22in2;

4007

4011

4008

4012

4009

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4013

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4010

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4014

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4011

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4015

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4012

s21out = s2(2,1,:).*s1(2,1,:)./N;

4016

s21out = s2(2,1,:).*s1(2,1,:)./N;

4013

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4017

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4014

4018

4015

s11out=transpose(squeeze(s11out));

4019

s11out=transpose(squeeze(s11out));

4016

s12out=transpose(squeeze(s12out));

4020

s12out=transpose(squeeze(s12out));

4017

s21out=transpose(squeeze(s21out));

4021

s21out=transpose(squeeze(s21out));

4018

s22out=transpose(squeeze(s22out));

4022

s22out=transpose(squeeze(s22out));

4019

function p=conv_fct(p1, p2)

4023

function p=conv_fct(p1, p2)

4020

if p1.BinSize ~= p2.BinSize

4024

if p1.BinSize ~= p2.BinSize

4021

error('bin size must be equal')

4025

error('bin size must be equal')

4022

end

4026

end

4023

4027

4024

p=p1;

4028

p=p1;

4025

%p.BinSize=p1.BinSize;

4029

%p.BinSize=p1.BinSize;

4026

%p.Min=p1.Min+p2.Min;

4030

%p.Min=p1.Min+p2.Min;

4027

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4031

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4028

p.y=conv2(p1.y, p2.y);

4032

p.y=conv2(p1.y, p2.y);

4029

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4033

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4030

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4034

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4031

pMax=p.Min+length(p.y)-1;

4035

pMax=p.Min+length(p.y)-1;

4032

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4036

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4033

4037

4034

4038

4035

4039

4036

4040

4037

function p=conv_fct_MeanNotZero(p1, p2)

4041

function p=conv_fct_MeanNotZero(p1, p2)

4038

4042

4039

if p1.BinSize ~= p2.BinSize

4043

if p1.BinSize ~= p2.BinSize

4040

error('bin size must be equal')

4044

error('bin size must be equal')

4041

end

4045

end

4042

4046

4043

p=p1;

4047

p=p1;

4044

%p.BinSize=p1.BinSize;

4048

%p.BinSize=p1.BinSize;

4045

%p.Min=p1.Min+p2.Min;

4049

%p.Min=p1.Min+p2.Min;

4046

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4050

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4047

p.y=conv2(p1.y, p2.y);

4051

p.y=conv2(p1.y, p2.y);

4048

4052

4049

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4053

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4050

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4054

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4051

%vector by BinSize

4055

%vector by BinSize

4052

pMax=p.Min+length(p.y)-1;

4056

pMax=p.Min+length(p.y)-1;

4053

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4057

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4054

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4058

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4055

4059

4056

%IN:

4060

%IN:

4057

%sbr = pulse response

4061

%sbr = pulse response

4058

%param = COM "param" struct

4062

%param = COM "param" struct

4059

%OP = COM "OP" struct

4063

%OP = COM "OP" struct

4060

%peak_search_range= a limited range to search for the peak (for speed up)

4064

%peak_search_range= a limited range to search for the peak (for speed up)

4061

% it is usually +/- 20 UI

4065

% it is usually +/- 20 UI

4062

%

4066

%

4063

%OUT:

4067

%OUT:

4064

%cursor_i = sampling location

4068

%cursor_i = sampling location

4065

%no_zero_crossing = flag that reveals if sampling is not possible.

4069

%no_zero_crossing = flag that reveals if sampling is not possible.

4066

% When this function is called in optimize_fom, it signals to quit the current case

4070

% When this function is called in optimize_fom, it signals to quit the current case

4067

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4071

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4068

% time consuming, so saving the peak in one spot is advantageous

4072

% time consuming, so saving the peak in one spot is advantageous

4069

%zxi = zero crossing index (returned because RXFFE uses it)

4073

%zxi = zero crossing index (returned because RXFFE uses it)

4070

4074

4071

no_zero_crossing=0;

4075

no_zero_crossing=0;

4072

%need to set cursor_i to empty in case no_zero_crossing flag is set

4076

%need to set cursor_i to empty in case no_zero_crossing flag is set

4073

cursor_i=[];

4077

cursor_i=[];

4074

4078

4075

%get peak of pulse and peak index

4079

%get peak of pulse and peak index

4076

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4080

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4077

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4081

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4078

4082

4079

4083

4080

% initial guess at cursor location (t_s) - based on approximate zero crossing

4084

% initial guess at cursor location (t_s) - based on approximate zero crossing

4081

%limit search space for speed up

4085

%limit search space for speed up

4082

search_start=sbr_peak_i-4*param.samples_per_ui;

4086

search_start=sbr_peak_i-4*param.samples_per_ui;

4083

if search_start<1

4087

if search_start<1

4084

search_start=1;

4088

search_start=1;

4085

end

4089

end

4086

%Find zero crossings

4090

%Find zero crossings

4087

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4091

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4088

4092

4089

%Note: the original implementation of zxi:

4093

%Note: the original implementation of zxi:

4090

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4094

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4091

% zxi = zxi(zxi<sbr_peak_i);

4095

% zxi = zxi(zxi<sbr_peak_i);

4092

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4096

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4093

% The changes to limit search space and remember max(sbr) give 10x speed up

4097

% The changes to limit search space and remember max(sbr) give 10x speed up

4094

% A test case of 25k runs, reduced from 1.2s to 0.1s

4098

% A test case of 25k runs, reduced from 1.2s to 0.1s

4095

4099

4096

4100

4097

if isempty(zxi)

4101

if isempty(zxi)

4098

%if no zero crossing, the calling program must respond (since sample point will be empty)

4102

%if no zero crossing, the calling program must respond (since sample point will be empty)

4099

no_zero_crossing=1;

4103

no_zero_crossing=1;

4100

return;

4104

return;

4101

elseif length(zxi)>1

4105

elseif length(zxi)>1

4102

%only need the last zero crossing

4106

%only need the last zero crossing

4103

zxi=zxi(end);

4107

zxi=zxi(end);

4104

end

4108

end

4105

if param.ndfe==0

4109

if param.ndfe==0

4106

max_dfe1=0;

4110

max_dfe1=0;

4107

else

4111

else

4108

max_dfe1=param.bmax(1);

4112

max_dfe1=param.bmax(1);

4109

end

4113

end

4110

% adjust cursor_i to Solve equation 93A-25 %%

4114

% adjust cursor_i to Solve equation 93A-25 %%

4111

% Muller-Mueller criterion with DFE

4115

% Muller-Mueller criterion with DFE

4112

mm_range = zxi+(0:2*param.samples_per_ui);

4116

mm_range = zxi+(0:2*param.samples_per_ui);

4113

switch OP.CDR

4117

switch OP.CDR

4114

case 'Mod-MM'

4118

case 'Mod-MM'

4115

mm_metric = ...

4119

mm_metric = ...

4116

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4120

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4117

otherwise % MM

4121

otherwise % MM

4118

%MM is generally: first precursor = 0

4122

%MM is generally: first precursor = 0

4119

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4123

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4120

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4124

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4121

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4125

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4122

%first precursor = first postcursor - max_dfe

4126

%first precursor = first postcursor - max_dfe

4123

mm_metric = ...

4127

mm_metric = ...

4124

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4128

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4125

end

4129

end

4126

[~, mm_cursor_offset] = min(mm_metric);

4130

[~, mm_cursor_offset] = min(mm_metric);

4127

4131

4128

%cursor_i = the sample location

4132

%cursor_i = the sample location

4129

cursor_i = zxi+mm_cursor_offset-1;

4133

cursor_i = zxi+mm_cursor_offset-1;

4130

function pdf=d_cpdf( binsize, values, probs)

4134

function pdf=d_cpdf( binsize, values, probs)

4131

% p=cpdf(type, ...)

4135

% p=cpdf(type, ...)

4132

%

4136

%

4133

% CPDF is a probability mass function for discrete distributions or an

4137

% CPDF is a probability mass function for discrete distributions or an

4134

% approxmation of a PDF for continuous distributions.

4138

% approxmation of a PDF for continuous distributions.

4135

%

4139

%

4136

% cpdf is internally normalized so that the sum of probabilities is 1

4140

% cpdf is internally normalized so that the sum of probabilities is 1

4137

% (regardless of bin size).

4141

% (regardless of bin size).

4138

4142

4139

% Internal fields:

4143

% Internal fields:

4140

% Min: *bin number* of minimum value.

4144

% Min: *bin number* of minimum value.

4141

% BinSize: size of PDF bins. Bin center is the representative value.

4145

% BinSize: size of PDF bins. Bin center is the representative value.

4142

% Vec: vector of probabilities per bin.

4146

% Vec: vector of probabilities per bin.

4143

4147

4144

%speed up for initializing empty pdf

4148

%speed up for initializing empty pdf

4145

if all(values==0)

4149

if all(values==0)

4146

pdf.BinSize=binsize;

4150

pdf.BinSize=binsize;

4147

pdf.Min=0;

4151

pdf.Min=0;

4148

pdf.y=1;

4152

pdf.y=1;

4149

pdf.x=0;

4153

pdf.x=0;

4150

return;

4154

return;

4151

end

4155

end

4152

4156

4153

if ~issorted(values)

4157

if ~issorted(values)

4154

[values,si]=sort(values);

4158

[values,si]=sort(values);

4155

probs=probs(si);

4159

probs=probs(si);

4156

end

4160

end

4157

values=binsize*round(values/binsize);

4161

values=binsize*round(values/binsize);

4158

t=(values(1):binsize:values(end));

4162

t=(values(1):binsize:values(end));

4159

pdf.Min=values(1)/binsize;

4163

pdf.Min=values(1)/binsize;

4160

pdf.y=zeros(size(t));

4164

pdf.y=zeros(size(t));

4161

for k=1:length(values)

4165

for k=1:length(values)

4162

if k==1

4166

if k==1

4163

bin=1;

4167

bin=1;

4164

elseif k==length(values)

4168

elseif k==length(values)

4165

bin=length(t);

4169

bin=length(t);

4166

else

4170

else

4167

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4171

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4168

end

4172

end

4169

pdf.y(bin) = pdf.y(bin)+probs(k);

4173

pdf.y(bin) = pdf.y(bin)+probs(k);

4170

end

4174

end

4171

4175

4172

pdf.BinSize=binsize;

4176

pdf.BinSize=binsize;

4173

pdf.y=pdf.y/sum(pdf.y);

4177

pdf.y=pdf.y/sum(pdf.y);

4174

if any(~isreal(pdf.y)) || any(pdf.y<0)

4178

if any(~isreal(pdf.y)) || any(pdf.y<0)

4175

error('PDF must be real and nonnegative');

4179

error('PDF must be real and nonnegative');

4176

end

4180

end

4177

support=find(pdf.y);

4181

support=find(pdf.y);

4178

pdf.y=pdf.y(support(1):support(end));

4182

pdf.y=pdf.y(support(1):support(end));

4179

pdf.Min=pdf.Min+(support(1)-1);

4183

pdf.Min=pdf.Min+(support(1)-1);

4180

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4184

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4181

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4185

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4182

4186

4183

if isrow(input)

4187

if isrow(input)

4184

max_threshold=max_threshold(:).';

4188

max_threshold=max_threshold(:).';

4185

min_threshold=min_threshold(:).';

4189

min_threshold=min_threshold(:).';

4186

else

4190

else

4187

max_threshold=max_threshold(:);

4191

max_threshold=max_threshold(:);

4188

min_threshold=min_threshold(:);

4192

min_threshold=min_threshold(:);

4189

end

4193

end

4190

4194

4191

clip_output=input;

4195

clip_output=input;

4192

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4196

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4193

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4197

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4194

4198

4195

4199

4196

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4200

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4197

[ncases, mele]=size(param.z_p_tx_cases);

4201

[ncases, mele]=size(param.z_p_tx_cases);

4198

if mele ==2

4202

if mele ==2

4199

param.flex=2;

4203

param.flex=2;

4200

elseif mele==4

4204

elseif mele==4

4201

param.flex=4;

4205

param.flex=4;

4202

elseif mele==1

4206

elseif mele==1

4203

param.flex=1;

4207

param.flex=1;

4204

else

4208

else

4205

error(springf('config file syntax error'))

4209

error(springf('config file syntax error'))

4206

end

4210

end

4207

4211

4208

4212

4209

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4213

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4210

% display bathtub curves in one axis per test case.

4214

% display bathtub curves in one axis per test case.

4211

% h=findall(0, 'Name', 'COM results');

4215

% h=findall(0, 'Name', 'COM results');

4212

if ~exist('h','var')

4216

if ~exist('h','var')

4213

msgtext = cell(1, length(OP.pkg_len_select));

4217

msgtext = cell(1, length(OP.pkg_len_select));

4214

msgcolor = 'g';

4218

msgcolor = 'g';

4215

else

4219

else

4216

msgtext=get(findobj(h, 'type', 'text'), 'string');

4220

msgtext=get(findobj(h, 'type', 'text'), 'string');

4217

msgcolor = get(h, 'color');

4221

msgcolor = get(h, 'color');

4218

close(h); % will be recreated

4222

close(h); % will be recreated

4219

end

4223

end

4220

msgctr=size(msgtext,1)+1;

4224

msgctr=size(msgtext,1)+1;

4221

if ~OP.ERL_ONLY

4225

if ~OP.ERL_ONLY

4222

switch OP.PHY

4226

switch OP.PHY

4223

case 'C2M'

4227

case 'C2M'

4224

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4228

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4225

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4229

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4226

msg, VEO_mV);

4230

msg, VEO_mV);

4227

else

4231

else

4228

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4232

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4229

msg, VEO_mV);

4233

msg, VEO_mV);

4230

msgcolor = 'r';

4234

msgcolor = 'r';

4231

end

4235

end

4232

4236

4233

if VEC_dB <= param.VEC_pass_threshold

4237

if VEC_dB <= param.VEC_pass_threshold

4234

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4238

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4235

(msg), VEC_dB);

4239

(msg), VEC_dB);

4236

else

4240

else

4237

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4241

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4238

(msg), VEC_dB);

4242

(msg), VEC_dB);

4239

msgcolor = 'r';

4243

msgcolor = 'r';

4240

end

4244

end

4241

case 'C2C'

4245

case 'C2C'

4242

if COM >= param.pass_threshold

4246

if COM >= param.pass_threshold

4243

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4247

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4244

% msg, COM);

4248

% msg, COM);

4245

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4249

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4246

msg, COM);

4250

msg, COM);

4247

else

4251

else

4248

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4252

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4249

% msg, COM);

4253

% msg, COM);

4250

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4254

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4251

msg, COM);

4255

msg, COM);

4252

msgcolor = 'r';

4256

msgcolor = 'r';

4253

end

4257

end

4254

% begin yasuo patch 3/18/2019

4258

% begin yasuo patch 3/18/2019

4255

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4259

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4256

% end yasuo patch

4260

% end yasuo patch

4257

case 'C2Mcom'

4261

case 'C2Mcom'

4258

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4262

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4259

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4263

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4260

msg, VEO_mV);

4264

msg, VEO_mV);

4261

else

4265

else

4262

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4266

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4263

msg, VEO_mV);

4267

msg, VEO_mV);

4264

msgcolor = 'r';

4268

msgcolor = 'r';

4265

end

4269

end

4266

4270

4267

if VEC_dB <= param.VEC_pass_threshold

4271

if VEC_dB <= param.VEC_pass_threshold

4268

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4272

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4269

(msg), VEC_dB);

4273

(msg), VEC_dB);

4270

else

4274

else

4271

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4275

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4272

(msg), VEC_dB);

4276

(msg), VEC_dB);

4273

msgcolor = 'r';

4277

msgcolor = 'r';

4274

end

4278

end

4275

if COM >= param.pass_threshold

4279

if COM >= param.pass_threshold

4276

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4280

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4277

% msg, COM);

4281

% msg, COM);

4278

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4282

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4279

msg, COM);

4283

msg, COM);

4280

else

4284

else

4281

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4285

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4282

% msg, COM);

4286

% msg, COM);

4283

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4287

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4284

msg, COM);

4288

msg, COM);

4285

msgcolor = 'r';

4289

msgcolor = 'r';

4286

end

4290

end

4287

% begin yasuo patch 3/18/2019

4291

% begin yasuo patch 3/18/2019

4288

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4292

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4289

% end yasuo patch

4293

% end yasuo patch

4290

end

4294

end

4291

end

4295

end

4292

if OP.ERL

4296

if OP.ERL

4293

if ~isempty(ERL)

4297

if ~isempty(ERL)

4294

if min_ERL >= param.ERL_pass_threshold

4298

if min_ERL >= param.ERL_pass_threshold

4295

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4299

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4296

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4300

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4297

else

4301

else

4298

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4302

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4299

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4303

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4300

msgcolor = 'r';

4304

msgcolor = 'r';

4301

end

4305

end

4302

end

4306

end

4303

end

4307

end

4304

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4308

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4305

set(h, 'color', msgcolor, 'tag', 'COM');

4309

set(h, 'color', msgcolor, 'tag', 'COM');

4306

movegui(h, 'center');

4310

movegui(h, 'center');

4307

else % no windows

4311

else % no windows

4308

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4312

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4309

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4313

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4310

if ~OP.ERL_ONLY

4314

if ~OP.ERL_ONLY

4311

switch OP.PHY

4315

switch OP.PHY

4312

case 'C2C'

4316

case 'C2C'

4313

if COM >= param.pass_threshold

4317

if COM >= param.pass_threshold

4314

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4318

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4315

else

4319

else

4316

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4320

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4317

end

4321

end

4318

% begin yasuo patch 3/18/2019

4322

% begin yasuo patch 3/18/2019

4319

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4323

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4320

% end yasuo patch

4324

% end yasuo patch

4321

case 'C2Mcom'

4325

case 'C2Mcom'

4322

if VEC_dB <= param.VEC_pass_threshold

4326

if VEC_dB <= param.VEC_pass_threshold

4323

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4327

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4324

else

4328

else

4325

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4329

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4326

end

4330

end

4327

4331

4328

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4332

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4329

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4333

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4330

else

4334

else

4331

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4335

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4332

end

4336

end

4333

if COM >= param.pass_threshold

4337

if COM >= param.pass_threshold

4334

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4338

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4335

else

4339

else

4336

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4340

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4337

end

4341

end

4338

% begin yasuo patch 3/18/2019

4342

% begin yasuo patch 3/18/2019

4339

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4343

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4340

% end yasuo patch

4344

% end yasuo patch

4341

case 'C2M'

4345

case 'C2M'

4342

if VEC_dB <= param.VEC_pass_threshold

4346

if VEC_dB <= param.VEC_pass_threshold

4343

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4347

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4344

else

4348

else

4345

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4349

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4346

end

4350

end

4347

4351

4348

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4352

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4349

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4353

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4350

else

4354

else

4351

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4355

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4352

end

4356

end

4353

end

4357

end

4354

end

4358

end

4355

if OP.ERL

4359

if OP.ERL

4356

if ~isempty(ERL)

4360

if ~isempty(ERL)

4357

if min_ERL >= param.ERL_pass_threshold

4361

if min_ERL >= param.ERL_pass_threshold

4358

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4362

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4359

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4363

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4360

else

4364

else

4361

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4365

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4362

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4366

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4363

end

4367

end

4364

end

4368

end

4365

end

4369

end

4366

end

4370

end

4367

4371

4368

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4372

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4369

4373

4370

%Left eye Width (Top Eye)

4374

%Left eye Width (Top Eye)

4371

left_top=eye_contour(half_UI:-1:1,1);

4375

left_top=eye_contour(half_UI:-1:1,1);

4372

%vref_crossing is the first point less than vref (usually first point < 0)

4376

%vref_crossing is the first point less than vref (usually first point < 0)

4373

vref_crossing=find(left_top<vref,1,'first');

4377

vref_crossing=find(left_top<vref,1,'first');

4374

if isempty(vref_crossing)

4378

if isempty(vref_crossing)

4375

%this case handles completely open eye

4379

%this case handles completely open eye

4376

L1=half_UI;

4380

L1=half_UI;

4377

elseif vref_crossing==1

4381

elseif vref_crossing==1

4378

%this case handles completely closed eye

4382

%this case handles completely closed eye

4379

L1=0;

4383

L1=0;

4380

else

4384

else

4381

%this case handles the normal eye

4385

%this case handles the normal eye

4382

%INT is a linear interpolation between the 2 points on either side of

4386

%INT is a linear interpolation between the 2 points on either side of

4383

%vref to determine where the vref crossing occurred. In systems with

4387

%vref to determine where the vref crossing occurred. In systems with

4384

%a small number of samples_per_UI, interpolation improves accuracy over

4388

%a small number of samples_per_UI, interpolation improves accuracy over

4385

%just using the integer sample point

4389

%just using the integer sample point

4386

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4390

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4387

L1=half_UI-INT;

4391

L1=half_UI-INT;

4388

end

4392

end

4389

%Left eye Width (Bottom Eye)

4393

%Left eye Width (Bottom Eye)

4390

left_bot=eye_contour(half_UI:-1:1,2);

4394

left_bot=eye_contour(half_UI:-1:1,2);

4391

vref_crossing=find(left_bot>vref,1,'first');

4395

vref_crossing=find(left_bot>vref,1,'first');

4392

if isempty(vref_crossing)

4396

if isempty(vref_crossing)

4393

L0=half_UI;

4397

L0=half_UI;

4394

elseif vref_crossing==1

4398

elseif vref_crossing==1

4395

L0=0;

4399

L0=0;

4396

else

4400

else

4397

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4401

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4398

L0=half_UI-INT;

4402

L0=half_UI-INT;

4399

end

4403

end

4400

%Right eye Width (Top Eye)

4404

%Right eye Width (Top Eye)

4401

right_top=eye_contour(half_UI:end,1);

4405

right_top=eye_contour(half_UI:end,1);

4402

vref_crossing=find(right_top<vref,1,'first');

4406

vref_crossing=find(right_top<vref,1,'first');

4403

if isempty(vref_crossing)

4407

if isempty(vref_crossing)

4404

R1=samples_per_UI-half_UI;

4408

R1=samples_per_UI-half_UI;

4405

elseif vref_crossing==1

4409

elseif vref_crossing==1

4406

R1=0;

4410

R1=0;

4407

else

4411

else

4408

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4412

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4409

R1=INT-half_UI;

4413

R1=INT-half_UI;

4410

end

4414

end

4411

%Right eye Width (Bottom Eye)

4415

%Right eye Width (Bottom Eye)

4412

right_bot=eye_contour(half_UI:end,2);

4416

right_bot=eye_contour(half_UI:end,2);

4413

vref_crossing=find(right_bot>vref,1,'first');

4417

vref_crossing=find(right_bot>vref,1,'first');

4414

if isempty(vref_crossing)

4418

if isempty(vref_crossing)

4415

R0=samples_per_UI-half_UI;

4419

R0=samples_per_UI-half_UI;

4416

elseif vref_crossing==1

4420

elseif vref_crossing==1

4417

R0=0;

4421

R0=0;

4418

else

4422

else

4419

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4423

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4420

R0=INT-half_UI;

4424

R0=INT-half_UI;

4421

end

4425

end

4422

4426

4423

%L1 = top left eye width

4427

%L1 = top left eye width

4424

%L0 = bottom left eye width

4428

%L0 = bottom left eye width

4425

%Left eye width is the minimum

4429

%Left eye width is the minimum

4426

%R1 = top right eye width

4430

%R1 = top right eye width

4427

%R0 = bottom right eye width

4431

%R0 = bottom right eye width

4428

%Right eye width is the minimum

4432

%Right eye width is the minimum

4429

Left_EW=min([L1 L0]);

4433

Left_EW=min([L1 L0]);

4430

Right_EW=min([R1 R0]);

4434

Right_EW=min([R1 R0]);

4431

4435

4432

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4436

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4433

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4437

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4434

% find the location of the DFE bank

4438

% find the location of the DFE bank

4435

% hisi: waveform with cursor values;

4439

% hisi: waveform with cursor values;

4436

% idx_st: starting index;

4440

% idx_st: starting index;

4437

% idx_en: ending index ;

4441

% idx_en: ending index ;

4438

% tap_bk: number of taps per bank;

4442

% tap_bk: number of taps per bank;

4439

% bmaxg: maximum coefficient;

4443

% bmaxg: maximum coefficient;

4440

4444

4441

hisi=hisi(:);

4445

hisi=hisi(:);

4442

len=idx_en-idx_st+1;

4446

len=idx_en-idx_st+1;

4443

h0=abs(hisi(idx_st:idx_en));

4447

h0=abs(hisi(idx_st:idx_en));

4444

h1=max(0,h0-bmaxg*curval);

4448

h1=max(0,h0-bmaxg*curval);

4445

4449

4446

%if cursor value is negative, force h1 to all zeros

4450

%if cursor value is negative, force h1 to all zeros

4447

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4451

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4448

%this makes the weakest isi the most desirable to choose so everything breaks

4452

%this makes the weakest isi the most desirable to choose so everything breaks

4449

if curval<0

4453

if curval<0

4450

h1=zeros(size(h0));

4454

h1=zeros(size(h0));

4451

end

4455

end

4452

4456

4453

h0n=zeros(len-tap_bk+1,1);

4457

h0n=zeros(len-tap_bk+1,1);

4454

h1n=h0n;

4458

h1n=h0n;

4455

4459

4456

for ii=1:tap_bk

4460

for ii=1:tap_bk

4457

h0tmp=h0(ii:ii+len-tap_bk);

4461

h0tmp=h0(ii:ii+len-tap_bk);

4458

h0n=h0n+h0tmp.^2;

4462

h0n=h0n+h0tmp.^2;

4459

h1tmp=h1(ii:ii+len-tap_bk);

4463

h1tmp=h1(ii:ii+len-tap_bk);

4460

h1n=h1n+h1tmp.^2;

4464

h1n=h1n+h1tmp.^2;

4461

end

4465

end

4462

4466

4463

ndiff=h0n-h1n;

4467

ndiff=h0n-h1n;

4464

4468

4465

min_energy = -Inf;

4469

min_energy = -Inf;

4466

4470

4467

idx=zeros(1,tap_bk*N_bg);

4471

idx=zeros(1,tap_bk*N_bg);

4468

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4472

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4469

set_next_bank=0;

4473

set_next_bank=0;

4470

%Loop through each group

4474

%Loop through each group

4471

for k=1:N_bg

4475

for k=1:N_bg

4472

%Sort to choose the strongest

4476

%Sort to choose the strongest

4473

[~,val_sort]=sort(ndiff,'descend');

4477

[~,val_sort]=sort(ndiff,'descend');

4474

if k==1

4478

if k==1

4475

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4479

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4476

if isequal(sort(val_sort(ordered_set)),ordered_set)

4480

if isequal(sort(val_sort(ordered_set)),ordered_set)

4477

idx=1:N_bg*tap_bk;

4481

idx=1:N_bg*tap_bk;

4478

break;

4482

break;

4479

end

4483

end

4480

end

4484

end

4481

if set_next_bank>0

4485

if set_next_bank>0

4482

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4486

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4483

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4487

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4484

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4488

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4485

set_next_bank=0;

4489

set_next_bank=0;

4486

ndiff(new_bank)=min_energy;

4490

ndiff(new_bank)=min_energy;

4487

bad_start=new_bank(1)-tap_bk+1;

4491

bad_start=new_bank(1)-tap_bk+1;

4488

bad_end=new_bank(1)-1;

4492

bad_end=new_bank(1)-1;

4489

if bad_end<=0

4493

if bad_end<=0

4490

badV=[];

4494

badV=[];

4491

elseif bad_start>0

4495

elseif bad_start>0

4492

badV=bad_start:bad_end;

4496

badV=bad_start:bad_end;

4493

else

4497

else

4494

badV=1:bad_end;

4498

badV=1:bad_end;

4495

end

4499

end

4496

if ~isempty(badV)

4500

if ~isempty(badV)

4497

ndiff(badV)=min_energy;

4501

ndiff(badV)=min_energy;

4498

end

4502

end

4499

continue;

4503

continue;

4500

end

4504

end

4501

%potential bank = the strongest tap group

4505

%potential bank = the strongest tap group

4502

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4506

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4503

if k==N_bg

4507

if k==N_bg

4504

%Last group: just choose the strongest

4508

%Last group: just choose the strongest

4505

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4509

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4506

break;

4510

break;

4507

end

4511

end

4508

4512

4509

do_it_again=1;

4513

do_it_again=1;

4510

first_time=1;

4514

first_time=1;

4511

num_loops=0;

4515

num_loops=0;

4512

while do_it_again

4516

while do_it_again

4513

do_it_again=0;

4517

do_it_again=0;

4514

if num_loops>length(ndiff)

4518

if num_loops>length(ndiff)

4515

break;

4519

break;

4516

end

4520

end

4517

%note badV: taps smaller and less than 1 group away

4521

%note badV: taps smaller and less than 1 group away

4518

bad_start=new_bank(1)-tap_bk+1;

4522

bad_start=new_bank(1)-tap_bk+1;

4519

bad_end=new_bank(1)-1;

4523

bad_end=new_bank(1)-1;

4520

if bad_end<=0

4524

if bad_end<=0

4521

badV=[];

4525

badV=[];

4522

elseif bad_start>0

4526

elseif bad_start>0

4523

badV=bad_start:bad_end;

4527

badV=bad_start:bad_end;

4524

else

4528

else

4525

badV=1:bad_end;

4529

badV=1:bad_end;

4526

end

4530

end

4527

for j=length(badV):-1:1

4531

for j=length(badV):-1:1

4528

if any(badV(j)-idx==0)

4532

if any(badV(j)-idx==0)

4529

badV(j)=[];

4533

badV(j)=[];

4530

end

4534

end

4531

end

4535

end

4532

%note goodV: the tap exactly 1 tap_bk smaller

4536

%note goodV: the tap exactly 1 tap_bk smaller

4533

goodV=new_bank(1)-tap_bk;

4537

goodV=new_bank(1)-tap_bk;

4534

if ~isempty(badV)

4538

if ~isempty(badV)

4535

if ~first_time

4539

if ~first_time

4536

[~,val_sort]=sort(ndiff,'descend');

4540

[~,val_sort]=sort(ndiff,'descend');

4537

end

4541

end

4538

first_time=0;

4542

first_time=0;

4539

checkV=[badV new_bank];

4543

checkV=[badV new_bank];

4540

4544

4541

badV_pos=zeros(1,length(badV));

4545

badV_pos=zeros(1,length(badV));

4542

for j=1:length(badV)

4546

for j=1:length(badV)

4543

badV_pos(j)=find(badV(j)==val_sort);

4547

badV_pos(j)=find(badV(j)==val_sort);

4544

end

4548

end

4545

4549

4546

%loop through the sorted list to find the first tap outside the group and not a member of badV

4550

%loop through the sorted list to find the first tap outside the group and not a member of badV

4547

found_goodV=0;

4551

found_goodV=0;

4548

for ii=1:length(val_sort)

4552

for ii=1:length(val_sort)

4549

if val_sort(ii)==goodV

4553

if val_sort(ii)==goodV

4550

found_goodV=1;

4554

found_goodV=1;

4551

break;

4555

break;

4552

end

4556

end

4553

if all(val_sort(ii)-checkV~=0)

4557

if all(val_sort(ii)-checkV~=0)

4554

break;

4558

break;

4555

end

4559

end

4556

end

4560

end

4557

4561

4558

if ~found_goodV && min(badV_pos)<ii

4562

if ~found_goodV && min(badV_pos)<ii

4559

%if goodV wasn't found and bad taps occur before non group members are found

4563

%if goodV wasn't found and bad taps occur before non group members are found

4560

%throw out the strongest tap and take the next strongest

4564

%throw out the strongest tap and take the next strongest

4561

do_it_again=1;

4565

do_it_again=1;

4562

ndiff(new_bank(1))=min_energy;

4566

ndiff(new_bank(1))=min_energy;

4563

%speed up: new max_val is always val_sort(2)

4567

%speed up: new max_val is always val_sort(2)

4564

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4568

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4565

end

4569

end

4566

if found_goodV

4570

if found_goodV

4567

%if goodV was found, set the next bank to goodV

4571

%if goodV was found, set the next bank to goodV

4568

set_next_bank=goodV;

4572

set_next_bank=goodV;

4569

end

4573

end

4570

end

4574

end

4571

num_loops=num_loops+1;

4575

num_loops=num_loops+1;

4572

end

4576

end

4573

%at the end, the floating taps are set to idx

4577

%at the end, the floating taps are set to idx

4574

%and ndiff has illegal values set to zero

4578

%and ndiff has illegal values set to zero

4575

ndiff(new_bank)=min_energy;

4579

ndiff(new_bank)=min_energy;

4576

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4580

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4577

if ~isempty(badV)

4581

if ~isempty(badV)

4578

ndiff(badV)=min_energy;

4582

ndiff(badV)=min_energy;

4579

end

4583

end

4580

end

4584

end

4581

4585

4582

4586

4583

idx=idx+idx_st-1;

4587

idx=idx+idx_st-1;

4584

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4588

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4585

4589

4586

% hisi = postcursor isi

4590

% hisi = postcursor isi

4587

% N_b = number of fixed dfe taps (before floating taps begin)

4591

% N_b = number of fixed dfe taps (before floating taps begin)

4588

% N_bf = number of floating taps per group

4592

% N_bf = number of floating taps per group

4589

% N_bg = nubmber of groups

4593

% N_bg = nubmber of groups

4590

% N_bmax = max tap number that can be used for floating tap

4594

% N_bmax = max tap number that can be used for floating tap

4591

% bmaxg = max tap strength for floating taps

4595

% bmaxg = max tap strength for floating taps

4592

% curval = value of the cursor

4596

% curval = value of the cursor

4593

4597

4594

4598

4595

if nargin<8, dfe_delta=0;end

4599

if nargin<8, dfe_delta=0;end

4596

4600

4597

4601

4598

tap_coef=zeros(1,length(hisi));

4602

tap_coef=zeros(1,length(hisi));

4599

b=zeros(1,length(hisi));

4603

b=zeros(1,length(hisi));

4600

4604

4601

4605

4602

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4606

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4603

4607

4604

%Apply DFE to all taps

4608

%Apply DFE to all taps

4605

flt_curval=hisi(tap_loc);

4609

flt_curval=hisi(tap_loc);

4606

if dfe_delta~=0

4610

if dfe_delta~=0

4607

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4611

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4608

dfe_delta.*sign(flt_curval)*curval;

4612

dfe_delta.*sign(flt_curval)*curval;

4609

else

4613

else

4610

flt_curval_q=hisi(tap_loc);

4614

flt_curval_q=hisi(tap_loc);

4611

end

4615

end

4612

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4616

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4613

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4617

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4614

tap_coef(tap_loc)=applied_coef;

4618

tap_coef(tap_loc)=applied_coef;

4615

4619

4616

4620

4617

4621

4618

tap_loc=sort(tap_loc,'ascend');

4622

tap_loc=sort(tap_loc,'ascend');

4619

b(tap_loc)=bmaxg;

4623

b(tap_loc)=bmaxg;

4620

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4624

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4621

% Richard Mellitz: 04/23/2019

4625

% Richard Mellitz: 04/23/2019

4622

% hisi is the isi 1 ui/sample

4626

% hisi is the isi 1 ui/sample

4623

% N_b number of fixed dfe taps

4627

% N_b number of fixed dfe taps

4624

% N_bf number of floating taps per group

4628

% N_bf number of floating taps per group

4625

% N_bg number of floating tap groups. 1 2 or 3 right now

4629

% N_bg number of floating tap groups. 1 2 or 3 right now

4626

% N_bmax number of ui for the max reach of the floating taps

4630

% N_bmax number of ui for the max reach of the floating taps

4627

% bmaxg limit for the floating taps

4631

% bmaxg limit for the floating taps

4628

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4632

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4629

%

4633

%

4630

%

4634

%

4631

% function to remove isi or add noise above bmaxg

4635

% function to remove isi or add noise above bmaxg

4632

if ~exist('COOP','var'), COOP=0;end

4636

if ~exist('COOP','var'), COOP=0;end

4633

if iscolumn(hisi); hisi=hisi.';end

4637

if iscolumn(hisi); hisi=hisi.';end

4634

hsis_in=hisi;

4638

hsis_in=hisi;

4635

% find all the reduction group taken N_bf at a time

4639

% find all the reduction group taken N_bf at a time

4636

% we are looking for the group when when remove yield the miminim isi, h, power

4640

% we are looking for the group when when remove yield the miminim isi, h, power

4637

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4641

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4638

% add on switch and loop for each potential group

4642

% add on switch and loop for each potential group

4639

switch N_bg

4643

switch N_bg

4640

case 0

4644

case 0

4641

bmax=0;

4645

bmax=0;

4642

return

4646

return

4643

case 1

4647

case 1

4644

end1=N_bmax-N_bf;

4648

end1=N_bmax-N_bf;

4645

end2=N_b+1;

4649

end2=N_b+1;

4646

end3=N_b+1;

4650

end3=N_b+1;

4647

case 2

4651

case 2

4648

end1=N_bmax-N_bf;

4652

end1=N_bmax-N_bf;

4649

end2=N_bmax-N_bf;

4653

end2=N_bmax-N_bf;

4650

end3=N_b+1;

4654

end3=N_b+1;

4651

case 3

4655

case 3

4652

end1=N_bmax-N_bf;

4656

end1=N_bmax-N_bf;

4653

end2=N_bmax-N_bf;

4657

end2=N_bmax-N_bf;

4654

end3=N_bmax-N_bf;

4658

end3=N_bmax-N_bf;

4655

end

4659

end

4656

if COOP

4660

if COOP

4657

for ig1= N_b+1:end1 % now remove the 2nd group

4661

for ig1= N_b+1:end1 % now remove the 2nd group

4658

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4662

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4659

% loop for 2rd group

4663

% loop for 2rd group

4660

for ig2= N_b+1: end2

4664

for ig2= N_b+1: end2

4661

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4665

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4662

if N_bg < 2; hcap2 =hcap; end

4666

if N_bg < 2; hcap2 =hcap; end

4663

for ig3= N_b+1: end3

4667

for ig3= N_b+1: end3

4664

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4668

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4665

if N_bg < 3 ; hcap3=hcap2 ; end

4669

if N_bg < 3 ; hcap3=hcap2 ; end

4666

sigma=norm( hcap3 );

4670

sigma=norm( hcap3 );

4667

if sigma < best_sigma

4671

if sigma < best_sigma

4668

best_sigma=sigma;

4672

best_sigma=sigma;

4669

best_ig1=ig1;

4673

best_ig1=ig1;

4670

best_ig2=ig2;

4674

best_ig2=ig2;

4671

best_ig3=ig3;

4675

best_ig3=ig3;

4672

best_hcap=hcap3;

4676

best_hcap=hcap3;

4673

end

4677

end

4674

end

4678

end

4675

end

4679

end

4676

end

4680

end

4677

else % sequentail

4681

else % sequentail

4678

for ig1= N_b+1:end1 % now remove the 1st group

4682

for ig1= N_b+1:end1 % now remove the 1st group

4679

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4683

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4680

sigma=norm( hcap );

4684

sigma=norm( hcap );

4681

if sigma < best_sigma

4685

if sigma < best_sigma

4682

best_sigma=sigma;

4686

best_sigma=sigma;

4683

best_ig1=ig1;

4687

best_ig1=ig1;

4684

best_hcap=hcap;

4688

best_hcap=hcap;

4685

end

4689

end

4686

end

4690

end

4687

% loop for 2rd group

4691

% loop for 2rd group

4688

hisi=best_hcap;

4692

hisi=best_hcap;

4689

for ig2= N_b+1: end2

4693

for ig2= N_b+1: end2

4690

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4694

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4691

sigma=norm( hcap );

4695

sigma=norm( hcap );

4692

if sigma < best_sigma

4696

if sigma < best_sigma

4693

best_sigma=sigma;

4697

best_sigma=sigma;

4694

best_ig2=ig2;

4698

best_ig2=ig2;

4695

best_hcap=hcap;

4699

best_hcap=hcap;

4696

end

4700

end

4697

end

4701

end

4698

hisi=best_hcap;

4702

hisi=best_hcap;

4699

% loop for 3rd group

4703

% loop for 3rd group

4700

for ig3= N_b+1: end3

4704

for ig3= N_b+1: end3

4701

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4705

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4702

sigma=norm( hcap );

4706

sigma=norm( hcap );

4703

if sigma < best_sigma

4707

if sigma < best_sigma

4704

best_sigma=sigma;

4708

best_sigma=sigma;

4705

best_ig3=ig3;

4709

best_ig3=ig3;

4706

best_hcap=hcap;

4710

best_hcap=hcap;

4707

end

4711

end

4708

end

4712

end

4709

4713

4710

end

4714

end

4711

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4715

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4712

switch N_bg

4716

switch N_bg

4713

case 1

4717

case 1

4714

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4718

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4715

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4719

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4716

case 2

4720

case 2

4717

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4721

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4718

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4722

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4719

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4723

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4720

case 3

4724

case 3

4721

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4725

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4722

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4726

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4723

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4727

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4724

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4728

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4725

end

4729

end

4726

floating_tap_locations=sort(floating_tap_locations);

4730

floating_tap_locations=sort(floating_tap_locations);

4727

if 0 % for code debug

4731

if 0 % for code debug

4728

close force all

4732

close force all

4729

stem(best_hcap,'disp','hcap')

4733

stem(best_hcap,'disp','hcap')

4730

hold on

4734

hold on

4731

stem(bmax,'-k','disp','bmax')

4735

stem(bmax,'-k','disp','bmax')

4732

stem(hisi,'disp','hisi')

4736

stem(hisi,'disp','hisi')

4733

hold off

4737

hold off

4734

end

4738

end

4735

4739

4736

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4740

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4737

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4741

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4738

% Vfilter is vector forced filtered sbr

4742

% Vfilter is vector forced filtered sbr

4739

% Cmod is the ffe tap co-efficient vector

4743

% Cmod is the ffe tap co-efficient vector

4740

% if C is passed, just process V with C else compute C

4744

% if C is passed, just process V with C else compute C

4741

% cmx=param.rx_cmx; number of pre cursor taps

4745

% cmx=param.rx_cmx; number of pre cursor taps

4742

% cpx=param.rx_cps; number of post cursor taps

4746

% cpx=param.rx_cps; number of post cursor taps

4743

% V=sbr; pass pulse response

4747

% V=sbr; pass pulse response

4744

% ix the sample point in the passed pulse response

4748

% ix the sample point in the passed pulse response

4745

% the sample point is recomputed by optimize_fom

4749

% the sample point is recomputed by optimize_fom

4746

% idx - return floating tap location (RIM 9-19-2023)

4750

% idx - return floating tap location (RIM 9-19-2023)

4747

% OP not used for now

4751

% OP not used for now

4748

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4752

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4749

% this allows significant speed up in optimize_fom since FFE is time consuming

4753

% this allows significant speed up in optimize_fom since FFE is time consuming

4750

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4754

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4751

% Vfiltered to be calculated

4755

% Vfiltered to be calculated

4752

% test with load('SBR_FIR_resp.mydata','-mat')

4756

% test with load('SBR_FIR_resp.mydata','-mat')

4753

idx=[];

4757

idx=[];

4754

if nargin<4

4758

if nargin<4

4755

ix=find(V==max(V),1,'first');

4759

ix=find(V==max(V),1,'first');

4756

end

4760

end

4757

if nargin<5

4761

if nargin<5

4758

C=[];

4762

C=[];

4759

end

4763

end

4760

if nargin<6

4764

if nargin<6

4761

return_V=1;

4765

return_V=1;

4762

end

4766

end

4763

cmx=param.RxFFE_cmx;

4767

cmx=param.RxFFE_cmx;

4764

cpx=param.RxFFE_cpx;

4768

cpx=param.RxFFE_cpx;

4765

% do this early on so we can reuse the old code

4769

% do this early on so we can reuse the old code

4766

if param.N_bg ~=0 % must be floating taps

4770

if param.N_bg ~=0 % must be floating taps

4767

cpx=param.N_bmax; % N_f in spreadsheet

4771

cpx=param.N_bmax; % N_f in spreadsheet

4768

end

4772

end

4769

num_taps=cmx+cpx+1;

4773

num_taps=cmx+cpx+1;

4770

cstep=param.RxFFE_stepz;

4774

cstep=param.RxFFE_stepz;

4771

ndfe=param.ndfe;

4775

ndfe=param.ndfe;

4772

spui=param.samples_per_ui;

4776

spui=param.samples_per_ui;

4773

param.current_ffegain=0;

4777

param.current_ffegain=0;

4774

if return_V && ~isempty(C)

4778

if return_V && ~isempty(C)

4775

% RIM 2-3-23 when we just want to EQ not find EQ

4779

% RIM 2-3-23 when we just want to EQ not find EQ

4776

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4780

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4777

Cmod=C;

4781

Cmod=C;

4778

return

4782

return

4779

end

4783

end

4780

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4784

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4781

if ix < length(V)

4785

if ix < length(V)

4782

if isrow(V)

4786

if isrow(V)

4783

if mod(ix,spui) == 0

4787

if mod(ix,spui) == 0

4784

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4788

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4785

else

4789

else

4786

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4790

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4787

end

4791

end

4788

4792

4789

else

4793

else

4790

if mod(ix,spui) == 0

4794

if mod(ix,spui) == 0

4791

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4795

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4792

else

4796

else

4793

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4797

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4794

end

4798

end

4795

end

4799

end

4796

else

4800

else

4797

if isrow(V)

4801

if isrow(V)

4798

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4802

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4799

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4803

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4800

else

4804

else

4801

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4805

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4802

end

4806

end

4803

else

4807

else

4804

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4808

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4805

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4809

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4806

else

4810

else

4807

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4811

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4808

end

4812

end

4809

end

4813

end

4810

end

4814

end

4811

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4815

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4812

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4816

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4813

4817

4814

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4818

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4815

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4819

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4816

% Upen Kareti suggested fix for indexing 11/04/18

4820

% Upen Kareti suggested fix for indexing 11/04/18

4817

if ix < length(V)

4821

if ix < length(V)

4818

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4822

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4819

else

4823

else

4820

ivs=find(vsampled == max(vsampled),1,'first');

4824

ivs=find(vsampled == max(vsampled),1,'first');

4821

end

4825

end

4822

4826

4823

4827

4824

%% create VV matrix of shifted UI spaced sample of the pulse response

4828

%% create VV matrix of shifted UI spaced sample of the pulse response

4825

% only consider the VV matrix that correstonds to the FFE taps

4829

% only consider the VV matrix that correstonds to the FFE taps

4826

VV=zeros(num_taps,num_taps);

4830

VV=zeros(num_taps,num_taps);

4827

for i=1:num_taps

4831

for i=1:num_taps

4828

start_idx=ivs+i-1;

4832

start_idx=ivs+i-1;

4829

end_idx=start_idx-num_taps+1;

4833

end_idx=start_idx-num_taps+1;

4830

VV(:,i)=vsampled(start_idx:-1:end_idx);

4834

VV(:,i)=vsampled(start_idx:-1:end_idx);

4831

end

4835

end

4832

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4836

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4833

%% Apply RXFFE

4837

%% Apply RXFFE

4834

if isempty(C)

4838

if isempty(C)

4835

switch upper(OP.FFE_OPT_METHOD)

4839

switch upper(OP.FFE_OPT_METHOD)

4836

case 'WIENER-HOPF'

4840

case 'WIENER-HOPF'

4837

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4841

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4838

Cmod=C(1:num_taps);

4842

Cmod=C(1:num_taps);

4839

otherwise

4843

otherwise

4840

% cmx+1 is the cursor or sample point

4844

% cmx+1 is the cursor or sample point

4841

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4845

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4842

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4846

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4843

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4847

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4844

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4848

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4845

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4849

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4846

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4850

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4847

end

4851

end

4848

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4852

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4849

if diff(size(VV))==0

4853

if diff(size(VV))==0

4850

%For square matrix, can solve C using simple inv(VV')*FV'

4854

%For square matrix, can solve C using simple inv(VV')*FV'

4851

C=VV'\FV';

4855

C=VV'\FV';

4852

else

4856

else

4853

%otherwise use the general solution with psuedo inverse

4857

%otherwise use the general solution with psuedo inverse

4854

%note: this is the same as doing pinv(VV') but pinv is far slower

4858

%note: this is the same as doing pinv(VV') but pinv is far slower

4855

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4859

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4856

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4860

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4857

end

4861

end

4858

4862

4859

Cmod=C(1:num_taps);

4863

Cmod=C(1:num_taps);

4860

end

4864

end

4861

4865

4862

4866

4863

% added for 4.2 find floating taps with either ISI or taps

4867

% added for 4.2 find floating taps with either ISI or taps

4864

switch lower(OP.RXFFE_FLOAT_CTL)

4868

switch lower(OP.RXFFE_FLOAT_CTL)

4865

case 'taps'

4869

case 'taps'

4866

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4870

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4867

otherwise

4871

otherwise

4868

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4872

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4869

end

4873

end

4870

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4874

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4871

case 'unity cursor'

4875

case 'unity cursor'

4872

Cmod=Cmod/Cmod(cmx+1);

4876

Cmod=Cmod/Cmod(cmx+1);

4873

otherwise

4877

otherwise

4874

Cmod=C;

4878

Cmod=C;

4875

end

4879

end

4876

if cstep ~= 0

4880

if cstep ~= 0

4877

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4881

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4878

end

4882

end

4879

4883

4880

if ~isempty(idx)

4884

if ~isempty(idx)

4881

idx=sort(idx);

4885

idx=sort(idx);

4882

C1=Cmod;

4886

C1=Cmod;

4883

% C1(param.N_tail_start:end)=0;

4887

% C1(param.N_tail_start:end)=0;

4884

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4888

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4885

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4889

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4886

Cmod=C1;

4890

Cmod=C1;

4887

else

4891

else

4888

% Cmod=C;

4892

% Cmod=C;

4889

end

4893

end

4890

4894

4891

% now when ussing RxFFE floating taps need to tag stems correctly and

4895

% now when ussing RxFFE floating taps need to tag stems correctly and

4892

% make sure DFEfloating tap code does not get exectuted

4896

% make sure DFEfloating tap code does not get exectuted

4893

4897

4894

%

4898

%

4895

else

4899

else

4896

Cmod=C;%just us the FFE taps, C, passed for filtering

4900

Cmod=C;%just us the FFE taps, C, passed for filtering

4897

end

4901

end

4898

%%

4902

%%

4899

%% filter the pulse response with the solved FFE

4903

%% filter the pulse response with the solved FFE

4900

% (now option to avoid this and just return Cmod for speed up)

4904

% (now option to avoid this and just return Cmod for speed up)

4901

if return_V

4905

if return_V

4902

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4906

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4903

else

4907

else

4904

Vfiltered=[];

4908

Vfiltered=[];

4905

end

4909

end

4906

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4910

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4907

% used for FD IL fitting

4911

% used for FD IL fitting

4908

% sdd21 us a complex insertion loss

4912

% sdd21 us a complex insertion loss

4909

db = @(x) 20*log10(abs(x));

4913

db = @(x) 20*log10(abs(x));

4910

sdd21=squeeze(sdd21);

4914

sdd21=squeeze(sdd21);

4911

if iscolumn(sdd21)

4915

if iscolumn(sdd21)

4912

sdd21=sdd21.';

4916

sdd21=sdd21.';

4913

end

4917

end

4914

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4918

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4915

warning('off','MATLAB:nearlySingularMatrix');

4919

warning('off','MATLAB:nearlySingularMatrix');

4916

LGw=transpose(abs(sdd21).*db(sdd21));

4920

LGw=transpose(abs(sdd21).*db(sdd21));

4917

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4921

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4918

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4922

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4919

ILN = db(sdd21)-efit;

4923

ILN = db(sdd21)-efit;

4920

4924

4921

4925

4922

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4926

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4923

% Complex IL fitting

4927

% Complex IL fitting

4924

% sdd21 us a complex insertion loss

4928

% sdd21 us a complex insertion loss

4925

% efit and ILN are in db

4929

% efit and ILN are in db

4926

% faxix_f2 needs to be at least to fb

4930

% faxix_f2 needs to be at least to fb

4927

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4931

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4928

% still need to settle on voltage scaling.

4932

% still need to settle on voltage scaling.

4929

% maybe db(peak/Rss

4933

% maybe db(peak/Rss

4930

4934

4931

OP.interp_sparam_mag= 'trend_to_DC';

4935

OP.interp_sparam_mag= 'trend_to_DC';

4932

OP.interp_sparam_phase= 'interp_to_DC';

4936

OP.interp_sparam_phase= 'interp_to_DC';

4933

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4937

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4934

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4938

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4935

4939

4936

print_for_codereview=0;

4940

print_for_codereview=0;

4937

if ~exist('A_T','var')

4941

if ~exist('A_T','var')

4938

A_T=1;

4942

A_T=1;

4939

end

4943

end

4940

4944

4941

db = @(x) 20*log10(abs(x));

4945

db = @(x) 20*log10(abs(x));

4942

sdd21=squeeze(sdd21);

4946

sdd21=squeeze(sdd21);

4943

if iscolumn(sdd21)

4947

if iscolumn(sdd21)

4944

sdd21=sdd21.';

4948

sdd21=sdd21.';

4945

end

4949

end

4946

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4950

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4947

warning('off','MATLAB:nearlySingularMatrix');

4951

warning('off','MATLAB:nearlySingularMatrix');

4948

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4952

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4949

LGw=transpose(sdd21.*unwraplog);

4953

LGw=transpose(sdd21.*unwraplog);

4950

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4954

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4951

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4955

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4952

FIT=transpose(exp(transpose(efit_C)));

4956

FIT=transpose(exp(transpose(efit_C)));

4953

efit=db(abs(FIT));

4957

efit=db(abs(FIT));

4954

ILN = db(sdd21)-efit;

4958

ILN = db(sdd21)-efit;

4955

% time domain

4959

% time domain

4956

fprintf('computing TD_ILN (dB) ...')

4960

fprintf('computing TD_ILN (dB) ...')

4957

if exist('OP','var')

4961

if exist('OP','var')

4958

% OP.fraction_of_F_range_start_extrap_from=.95;

4962

% OP.fraction_of_F_range_start_extrap_from=.95;

4959

OP.impulse_response_truncation_threshold =1e-7;

4963

OP.impulse_response_truncation_threshold =1e-7;

4960

4964

4961

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4965

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4962

H_bw=Butterworth_Filter(param,faxis_f2,1);

4966

H_bw=Butterworth_Filter(param,faxis_f2,1);

4963

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4967

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4964

H_tw=Tukey_Window(faxis_f2,param);

4968

H_tw=Tukey_Window(faxis_f2,param);

4965

H_tw=ones(1,length(faxis_f2) );

4969

H_tw=ones(1,length(faxis_f2) );

4966

4970

4967

[TD_ILN.REF.FIR, ...

4971

[TD_ILN.REF.FIR, ...

4968

TD_ILN.REF.t, ...

4972

TD_ILN.REF.t, ...

4969

TD_ILN.REF.causality_correction_dB, ...

4973

TD_ILN.REF.causality_correction_dB, ...

4970

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4974

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4971

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4975

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4972

4976

4973

[TD_ILN.FIT.FIR, ...

4977

[TD_ILN.FIT.FIR, ...

4974

TD_ILN.FIT.t, ...

4978

TD_ILN.FIT.t, ...

4975

TD_ILN.FIT.causality_correction_dB, ...

4979

TD_ILN.FIT.causality_correction_dB, ...

4976

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4980

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4977

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4981

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4978

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4982

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4979

% NrangeUI=1000;

4983

% NrangeUI=1000;

4980

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4984

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4981

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4985

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4982

range=ipeak:range_end;

4986

range=ipeak:range_end;

4983

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4987

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4984

TD_ILN.t=TD_ILN.FIT.t(range);

4988

TD_ILN.t=TD_ILN.FIT.t(range);

4985

TD_ILN.FOM=-inf;

4989

TD_ILN.FOM=-inf;

4986

TD_ILN.FOM_PDF=-inf;

4990

TD_ILN.FOM_PDF=-inf;

4987

rms_fom=-inf;

4991

rms_fom=-inf;

4988

for im=1:param.samples_per_ui

4992

for im=1:param.samples_per_ui

4989

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4993

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4990

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4994

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4991

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4995

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4992

cdf=pdf; cdf.y=cumsum(pdf.y);

4996

cdf=pdf; cdf.y=cumsum(pdf.y);

4993

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4997

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4994

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4998

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4995

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4999

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4996

if print_for_codereview % remove once all checked out

5000

if print_for_codereview % remove once all checked out

4997

h=figure(190);set(gcf,'Tag','COM');

5001

h=figure(190);set(gcf,'Tag','COM');

4998

semilogy(-cdf.x,cdf.y);

5002

semilogy(-cdf.x,cdf.y);

4999

% xlim ([0,-cdf.x(1)])

5003

% xlim ([0,-cdf.x(1)])

5000

ylim([param.specBER 1]);title ('CDF of ILN')

5004

ylim([param.specBER 1]);title ('CDF of ILN')

5001

hold on

5005

hold on

5002

end

5006

end

5003

if rms>rms_fom

5007

if rms>rms_fom

5004

rms_fom=rms;

5008

rms_fom=rms;

5005

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5009

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5006

TD_ILN.PDF=pdf;

5010

TD_ILN.PDF=pdf;

5007

end

5011

end

5008

end

5012

end

5009

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5013

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5010

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5014

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5011

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5015

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5012

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5016

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5013

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5017

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5014

if print_for_codereview % remove once all checked out

5018

if print_for_codereview % remove once all checked out

5015

figure(9000);set(gcf,'Tag','COM');

5019

figure(9000);set(gcf,'Tag','COM');

5016

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5020

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5017

hold on

5021

hold on

5018

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5022

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5019

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5023

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5020

hold off

5024

hold off

5021

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5025

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5022

figure(9002);set(gcf,'Tag','COM');

5026

figure(9002);set(gcf,'Tag','COM');

5023

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5027

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5024

hold on

5028

hold on

5025

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5029

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5026

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5030

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5027

grid on

5031

grid on

5028

legend('show')

5032

legend('show')

5029

end

5033

end

5030

end

5034

end

5031

% display('got to end of get_ILN_cmp_td')

5035

% display('got to end of get_ILN_cmp_td')

5032

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5036

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5033

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5037

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5034

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5038

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5035

if 1 % force indent for doc

5039

if 1 % force indent for doc

5036

num_ui=param.num_ui_RXFF_noise;

5040

num_ui=param.num_ui_RXFF_noise;

5037

M=param.samples_per_ui;

5041

M=param.samples_per_ui;

5038

L=param.levels;

5042

L=param.levels;

5039

f_b=param.fb;

5043

f_b=param.fb;

5040

SNR_TX=param.SNR_TX;

5044

SNR_TX=param.SNR_TX;

5041

dw=param.RxFFE_cmx;

5045

dw=param.RxFFE_cmx;

5042

bmax=param.bmax;

5046

bmax=param.bmax;

5043

bmin=param.bmin ;

5047

bmin=param.bmin ;

5044

Nb=param.ndfe;

5048

Nb=param.ndfe;

5045

sigma_X2=(L^2-1)/(3*(L-1)^2);

5049

sigma_X2=(L^2-1)/(3*(L-1)^2);

5046

eta_0=param.eta_0; %V^2/GHz

5050

eta_0=param.eta_0; %V^2/GHz

5047

T_b=1/f_b;

5051

T_b=1/f_b;

5048

delta_f = f_b/num_ui; % Units are Hz.

5052

delta_f = f_b/num_ui; % Units are Hz.

5049

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5053

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5050

result.fvec=fvec;

5054

result.fvec=fvec;

5051

end

5055

end

5052

if OP.COMPUTE_COM

5056

if OP.COMPUTE_COM

5053

%% H_rxffe eq 178A-29 d0.2

5057

%% H_rxffe eq 178A-29 d0.2

5054

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5058

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5055

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5059

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5056

H_rxffe=0;

5060

H_rxffe=0;

5057

for nn=1:length(result.w)

5061

for nn=1:length(result.w)

5058

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5062

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5059

end

5063

end

5060

H_rxffe_2_of_f=abs(H_rxffe).^2;

5064

H_rxffe_2_of_f=abs(H_rxffe).^2;

5061

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5065

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5062

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5066

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5063

else

5067

else

5064

H_rxffe_2=1;

5068

H_rxffe_2=1;

5065

end

5069

end

5066

5070

5067

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5071

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5068

% --->this is the point in the code may fork where we add extra rx noise

5072

% --->this is the point in the code may fork where we add extra rx noise

5069

%% compute S_rn ( eq 178A-15 d0.2 )

5073

%% compute S_rn ( eq 178A-15 d0.2 )

5070

if ~OP.COMPUTE_COM

5074

if ~OP.COMPUTE_COM

5071

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5075

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5072

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5076

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5073

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5077

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5074

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5078

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5075

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5079

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5076

S_rn=S_rn(1:num_ui/2+1);

5080

S_rn=S_rn(1:num_ui/2+1);

5077

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5081

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5078

result.S_rn=S_rn;

5082

result.S_rn=S_rn;

5079

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5083

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5080

else

5084

else

5081

result.S_rn=result.S_rn.*H_rxffe_2;

5085

result.S_rn=result.S_rn.*H_rxffe_2;

5082

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5086

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5083

end

5087

end

5084

5088

5085

else % find noise for item that set have tx ffe for each loop

5089

else % find noise for item that set have tx ffe for each loop

5086

%% S_xn from eq 178A-16

5090

%% S_xn from eq 178A-16

5087

%% Crosstalk power spectral density

5091

%% Crosstalk power spectral density

5088

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5092

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5089

result.S_xn=0;

5093

result.S_xn=0;

5090

if length(chdata)~=1

5094

if length(chdata)~=1

5091

for xchan=2:length(chdata)

5095

for xchan=2:length(chdata)

5092

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5096

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5093

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5097

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5094

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5098

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5095

% enable less UI for computation speed improvement

5099

% enable less UI for computation speed improvement

5096

%%

5100

%%

5097

if num_ui*M > length(pulse_ctle)

5101

if num_ui*M > length(pulse_ctle)

5098

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5102

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5099

else

5103

else

5100

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5104

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5101

end

5105

end

5102

for i1=1:M

5106

for i1=1:M

5103

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5107

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5104

end

5108

end

5105

iphase(xchan)=find(hxn==max(hxn));

5109

iphase(xchan)=find(hxn==max(hxn));

5106

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5110

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5107

result.hk(xchan).hrn= hk(xchan).hrn;

5111

result.hk(xchan).hrn= hk(xchan).hrn;

5108

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5112

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5109

result.S_xn=hk(xchan).S_xn+result.S_xn;

5113

result.S_xn=hk(xchan).S_xn+result.S_xn;

5110

end

5114

end

5111

result.S_xn=result.S_xn;

5115

result.S_xn=result.S_xn;

5112

result.hk=hk;

5116

result.hk=hk;

5113

result.iphase=iphase;

5117

result.iphase=iphase;

5114

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5118

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5115

else % if no crosstalk, perserve structure and return 0 for S_xn

5119

else % if no crosstalk, perserve structure and return 0 for S_xn

5116

result.S_xn=0;

5120

result.S_xn=0;

5117

result.hk=[];

5121

result.hk=[];

5118

result.iphase=1;

5122

result.iphase=1;

5119

result.S_xn_rms = 0;

5123

result.S_xn_rms = 0;

5120

end

5124

end

5121

else % adjust for H_rxffe when computing COM

5125

else % adjust for H_rxffe when computing COM

5122

result.S_xn=result.S_xn.*H_rxffe_2;

5126

result.S_xn=result.S_xn.*H_rxffe_2;

5123

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5127

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5124

end

5128

end

5125

%% S_tn from eq 178A-17

5129

%% S_tn from eq 178A-17

5126

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5130

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5127

%% Transmitter noise power spectral density

5131

%% Transmitter noise power spectral density

5128

if ~OP.COMPUTE_COM

5132

if ~OP.COMPUTE_COM

5129

if ~OP.TDMODE

5133

if ~OP.TDMODE

5130

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5134

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5131

else % only use when the input was a pulse response not s-parameters

5135

else % only use when the input was a pulse response not s-parameters

5132

if isfield(chdata(1),'ctle_pulse_response')

5136

if isfield(chdata(1),'ctle_pulse_response')

5133

htn=chdata(1).ctle_pulse_response;

5137

htn=chdata(1).ctle_pulse_response;

5134

else

5138

else

5135

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5139

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5136

end

5140

end

5137

end

5141

end

5138

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5142

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5139

htn=reshape(htn,1,[]); % make row vectors

5143

htn=reshape(htn,1,[]); % make row vectors

5140

htn=[ htn(1:floor(length(htn)/M)*M) ];

5144

htn=[ htn(1:floor(length(htn)/M)*M) ];

5141

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5145

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5142

htn=htn(1:M:end);% resample

5146

htn=htn(1:M:end);% resample

5143

if num_ui>length(htn)

5147

if num_ui>length(htn)

5144

hext=[htn zeros(1,num_ui-length(htn))];

5148

hext=[htn zeros(1,num_ui-length(htn))];

5145

else

5149

else

5146

hext=htn(1:num_ui);

5150

hext=htn(1:num_ui);

5147

end

5151

end

5148

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5152

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5149

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5153

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5150

else

5154

else

5151

result.S_tn=result.S_tn.*H_rxffe_2;

5155

result.S_tn=result.S_tn.*H_rxffe_2;

5152

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5156

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5153

end

5157

end

5154

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5158

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5155

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5159

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5156

%% Power spectral density of noise due to jitter

5160

%% Power spectral density of noise due to jitter

5157

%% Eq. 93A-28 %%

5161

%% Eq. 93A-28 %%

5158

if ~OP.COMPUTE_COM

5162

if ~OP.COMPUTE_COM

5159

sampling_offset = mod(cursor_i, M);

5163

sampling_offset = mod(cursor_i, M);

5160

%ensure we can take early sample

5164

%ensure we can take early sample

5161

if sampling_offset<=1

5165

if sampling_offset<=1

5162

sampling_offset=sampling_offset+M;

5166

sampling_offset=sampling_offset+M;

5163

end

5167

end

5164

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5168

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5165

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5169

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5166

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5170

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5167

else

5171

else

5168

cursors_early_sample = h(sampling_offset-1:M:end);

5172

cursors_early_sample = h(sampling_offset-1:M:end);

5169

cursors_late_sample = h(sampling_offset+1:M:end);

5173

cursors_late_sample = h(sampling_offset+1:M:end);

5170

end

5174

end

5171

% ensure lengths are equal

5175

% ensure lengths are equal

5172

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5176

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5173

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5177

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5174

h_J=reshape(h_J,1,[]); % make row vectors

5178

h_J=reshape(h_J,1,[]); % make row vectors

5175

if num_ui>length(h_J)

5179

if num_ui>length(h_J)

5176

h_J=[h_J zeros(1,num_ui-length(h_J))];

5180

h_J=[h_J zeros(1,num_ui-length(h_J))];

5177

else

5181

else

5178

h_J=h_J(1:num_ui);

5182

h_J=h_J(1:num_ui);

5179

end

5183

end

5180

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5184

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5181

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5185

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5182

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5186

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5183

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5187

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5184

else

5188

else

5185

result.S_jn=result.S_jn.*H_rxffe_2;

5189

result.S_jn=result.S_jn.*H_rxffe_2;

5186

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5190

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5187

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5191

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5188

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5192

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5189

end

5193

end

5190

% result.S_jn

5194

% result.S_jn

5191

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5195

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5192

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5196

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5193

5197

5194

%%

5198

%%

5195

%% Hisi to be included in MLSE rho eq 178a-28

5199

%% Hisi to be included in MLSE rho eq 178a-28

5196

if OP.COMPUTE_COM

5200

if OP.COMPUTE_COM

5197

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5201

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5198

sampling_offset = mod(cursor_i, M);

5202

sampling_offset = mod(cursor_i, M-1)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5199

hisi=h(sampling_offset:M:end);

5203

hisi=h(sampling_offset:M:end);

5200

hisi=hisi(:).';

5204

hisi=hisi(:).';

5201

if num_ui>length(hisi)

5205

if num_ui>length(hisi)

5202

hisi=[hisi zeros(1,num_ui-length(hisi))];

5206

hisi=[hisi zeros(1,num_ui-length(hisi))];

5203

else

5207

else

5204

hisi=hisi(1:num_ui);

5208

hisi=hisi(1:num_ui);

5205

end

5209

end

5206

cursor_n=floor(cursor_i/M)+1;

5210

cursor_n=floor(cursor_i/M)+1;

5207

for ii=1:length(hisi)

5211

for ii=1:length(hisi)

5208

if ii==cursor_n % cursor

5212

if ii==cursor_n % cursor

5209

cursor=hisi(ii);

5213

cursor=hisi(ii);

5210

hisi(ii)= 0;

5214

hisi(ii)= 0;

5211

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5215

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5212

ib_indx=ii-cursor_n;

5216

ib_indx=ii-cursor_n;

5213

if hisi(ii) >= bmax(ib_indx)*cursor

5217

if hisi(ii) >= bmax(ib_indx)*cursor

5214

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5218

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5215

elseif hisi(ii) <= bmin(ib_indx)*cursor

5219

elseif hisi(ii) <= bmin(ib_indx)*cursor

5216

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5220

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5217

else

5221

else

5218

hisi(ii)=0;

5222

hisi(ii)=0;

5219

end

5223

end

5220

end

5224

end

5221

end

5225

end

5222

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5226

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5223

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5227

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5224

%%

5228

%%

5225

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5229

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5226

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5230

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5227

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5231

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5228

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5232

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5229

end

5233

end

5230

end

5234

end

5231

function result=get_PulseR(ir,param,cb_step,ZT)

5235

function result=get_PulseR(ir,param,cb_step,ZT)

5232

%ir = impulse response

5236

%ir = impulse response

5233

%t_base=time array with equal time steps

5237

%t_base=time array with equal time steps

5234

%samp_UI = number of samples per UI for ir

5238

%samp_UI = number of samples per UI for ir

5235

5239

5236

% t for debug

5240

% t for debug

5237

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5241

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5238

5242

5239

if cb_step

5243

if cb_step

5240

Ag=1;

5244

Ag=1;

5241

dt=1/param.fb/param.samples_per_ui;

5245

dt=1/param.fb/param.samples_per_ui;

5242

edge_time=param.TR_TDR*1e-9;

5246

edge_time=param.TR_TDR*1e-9;

5243

fedge=1/edge_time;

5247

fedge=1/edge_time;

5244

tedge=0:dt:edge_time*2;

5248

tedge=0:dt:edge_time*2;

5245

%

5249

%

5246

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5250

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5247

drive_pulse=[edge ones(1,param.samples_per_ui)];

5251

drive_pulse=[edge ones(1,param.samples_per_ui)];

5248

%pulse=filter(UI_ones,1,ir);

5252

%pulse=filter(UI_ones,1,ir);

5249

% t for debug

5253

% t for debug

5250

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5254

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5251

5255

5252

pulse=filter(drive_pulse,1,ir);

5256

pulse=filter(drive_pulse,1,ir);

5253

else

5257

else

5254

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5258

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5255

end

5259

end

5256

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5260

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5257

result.PDR=PDR_response;

5261

result.PDR=PDR_response;

5258

result.pulse=pulse;

5262

result.pulse=pulse;

5259

5263

5260

5264

5261

5265

5262

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5266

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5263

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5267

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5264

if ~iscolumn(H), H=H.';end

5268

if ~iscolumn(H), H=H.';end

5265

if ~iscolumn(H_r), H_r=H_r.';end

5269

if ~iscolumn(H_r), H_r=H_r.';end

5266

H=H(:).*H_r;

5270

H=H(:).*H_r;

5267

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5271

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5268

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5272

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5269

5273

5270

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5274

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5271

% Complex reflection and re-reflection noise using the concept of zero'ing

5275

% Complex reflection and re-reflection noise using the concept of zero'ing

5272

% out of reflections

5276

% out of reflections

5273

% sdd21 us a complex insertion loss

5277

% sdd21 us a complex insertion loss

5274

% RIL_struct is the output of capture_RIL_RILN()

5278

% RIL_struct is the output of capture_RIL_RILN()

5275

% faxix_f2 needs to be at least to fb

5279

% faxix_f2 needs to be at least to fb

5276

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5280

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5277

% still need to settle on voltage scaling.

5281

% still need to settle on voltage scaling.

5278

% maybe db(peak/Rss

5282

% maybe db(peak/Rss

5279

db = @(x) 20*log10(abs(x));

5283

db = @(x) 20*log10(abs(x));

5280

fprintf('computing TD_RILN (dB) ...');

5284

fprintf('computing TD_RILN (dB) ...');

5281

5285

5282

OP.interp_sparam_mag= 'trend_to_DC';

5286

OP.interp_sparam_mag= 'trend_to_DC';

5283

OP.interp_sparam_phase= 'interp_to_DC';

5287

OP.interp_sparam_phase= 'interp_to_DC';

5284

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5288

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5285

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5289

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5286

5290

5287

sdd21=squeeze(sdd21);

5291

sdd21=squeeze(sdd21);

5288

if iscolumn(sdd21)

5292

if iscolumn(sdd21)

5289

sdd21=sdd21.';

5293

sdd21=sdd21.';

5290

end

5294

end

5291

RIL=squeeze(RIL_struct.RIL);

5295

RIL=squeeze(RIL_struct.RIL);

5292

if iscolumn(RIL)

5296

if iscolumn(RIL)

5293

RIL=RIL.';

5297

RIL=RIL.';

5294

end

5298

end

5295

rho_port1=squeeze(RIL_struct.rho_port1);

5299

rho_port1=squeeze(RIL_struct.rho_port1);

5296

if iscolumn(rho_port1)

5300

if iscolumn(rho_port1)

5297

rho_port1=rho_port1.';

5301

rho_port1=rho_port1.';

5298

end

5302

end

5299

rho_port2=squeeze(RIL_struct.rho_port2);

5303

rho_port2=squeeze(RIL_struct.rho_port2);

5300

if iscolumn(rho_port2)

5304

if iscolumn(rho_port2)

5301

rho_port2=rho_port2.';

5305

rho_port2=rho_port2.';

5302

end

5306

end

5303

RIL_f=squeeze(RIL_struct.freq);

5307

RIL_f=squeeze(RIL_struct.freq);

5304

if iscolumn(RIL_f)

5308

if iscolumn(RIL_f)

5305

RIL_f=RIL_f.';

5309

RIL_f=RIL_f.';

5306

end

5310

end

5307

5311

5308

%---start. Calculate the reflection and re-reflection noise

5312

%---start. Calculate the reflection and re-reflection noise

5309

number_of_echos= 1e3;

5313

number_of_echos= 1e3;

5310

fmin= 1e9;%<-------------

5314

fmin= 1e9;%<-------------

5311

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5315

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5312

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5316

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5313

for m= 1:number_of_echos

5317

for m= 1:number_of_echos

5314

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5318

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5315

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5319

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5316

end

5320

end

5317

5321

5318

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5322

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5319

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5323

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5320

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5324

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5321

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5325

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5322

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5326

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5323

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5327

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5324

5328

5325

% clear RIL RIL_f rho_port1 rho_port2

5329

% clear RIL RIL_f rho_port1 rho_port2

5326

% clear fmin m

5330

% clear fmin m

5327

%---end. Calculate the reflection and re-reflection noise

5331

%---end. Calculate the reflection and re-reflection noise

5328

5332

5329

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5333

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5330

warning('off','MATLAB:nearlySingularMatrix');

5334

warning('off','MATLAB:nearlySingularMatrix');

5331

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5335

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5332

LGw=transpose(sdd21.*unwraplog);

5336

LGw=transpose(sdd21.*unwraplog);

5333

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5337

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5334

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5338

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5335

FIT=transpose(exp(transpose(efit_C)));

5339

FIT=transpose(exp(transpose(efit_C)));

5336

efit=db(abs(FIT));

5340

efit=db(abs(FIT));

5337

ILN = db(sdd21)-efit;

5341

ILN = db(sdd21)-efit;

5338

5342

5339

5343

5340

OP.impulse_response_truncation_threshold =1e-7;

5344

OP.impulse_response_truncation_threshold =1e-7;

5341

5345

5342

print_for_codereview=0;

5346

print_for_codereview=0;

5343

if exist('OP','var')

5347

if exist('OP','var')

5344

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5348

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5345

H_bw=Butterworth_Filter(param,faxis_f2,1);

5349

H_bw=Butterworth_Filter(param,faxis_f2,1);

5346

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5350

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5347

H_tw=Tukey_Window(faxis_f2,param);

5351

H_tw=Tukey_Window(faxis_f2,param);

5348

H_tw=ones(1,length(faxis_f2) );

5352

H_tw=ones(1,length(faxis_f2) );

5349

[RILN_TD_struct.REF.FIR, ...

5353

[RILN_TD_struct.REF.FIR, ...

5350

RILN_TD_struct.REF.t, ...

5354

RILN_TD_struct.REF.t, ...

5351

RILN_TD_struct.REF.causality_correction_dB, ...

5355

RILN_TD_struct.REF.causality_correction_dB, ...

5352

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5356

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5353

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5357

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5354

5358

5355

5359

5356

[RILN_TD_struct.FIT.FIR, ...

5360

[RILN_TD_struct.FIT.FIR, ...

5357

RILN_TD_struct.FIT.t, ...

5361

RILN_TD_struct.FIT.t, ...

5358

RILN_TD_struct.FIT.causality_correction_dB, ...

5362

RILN_TD_struct.FIT.causality_correction_dB, ...

5359

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5363

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5360

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5364

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5361

5365

5362

5366

5363

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5367

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5364

H_bw=Butterworth_Filter(param,RIL_f,1);

5368

H_bw=Butterworth_Filter(param,RIL_f,1);

5365

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5369

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5366

H_tw=Tukey_Window(RIL_f,param);

5370

H_tw=Tukey_Window(RIL_f,param);

5367

H_tw=ones(1,length(RIL_f) );

5371

H_tw=ones(1,length(RIL_f) );

5368

[RILN_TD_struct.RIL.FIR, ...

5372

[RILN_TD_struct.RIL.FIR, ...

5369

RILN_TD_struct.RIL.t, ...

5373

RILN_TD_struct.RIL.t, ...

5370

RILN_TD_struct.RIL.causality_correction_dB, ...

5374

RILN_TD_struct.RIL.causality_correction_dB, ...

5371

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5375

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5372

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5376

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5373

5377

5374

5378

5375

%---start. Calculate the channel delay

5379

%---start. Calculate the channel delay

5376

try

5380

try

5377

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5381

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5378

catch

5382

catch

5379

end

5383

end

5380

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5384

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5381

clear delay_sec delay_idx

5385

clear delay_sec delay_idx

5382

%---end. Calculate the channel delay

5386

%---end. Calculate the channel delay

5383

5387

5384

5388

5385

5389

5386

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5390

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5387

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5391

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5388

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5392

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5389

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5393

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5390

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5394

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5391

[RILN_TD_struct.REF_noise.FIR, ...

5395

[RILN_TD_struct.REF_noise.FIR, ...

5392

RILN_TD_struct.REF_noise.t, ...

5396

RILN_TD_struct.REF_noise.t, ...

5393

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5397

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5394

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5398

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5395

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5399

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5396

5400

5397

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5401

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5398

% NrangeUI=1000;

5402

% NrangeUI=1000;

5399

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5403

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5400

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5404

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5401

range=ipeak:range_end;

5405

range=ipeak:range_end;

5402

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5406

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5403

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5407

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5404

RILN_TD_struct.FOM=-inf;

5408

RILN_TD_struct.FOM=-inf;

5405

RILN_TD_struct.FOM_PDF=-inf;

5409

RILN_TD_struct.FOM_PDF=-inf;

5406

rms_fom=-inf;

5410

rms_fom=-inf;

5407

for im=1:param.samples_per_ui

5411

for im=1:param.samples_per_ui

5408

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5412

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5409

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5413

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5410

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5414

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5411

cdf=pdf; cdf.y=cumsum(pdf.y);

5415

cdf=pdf; cdf.y=cumsum(pdf.y);

5412

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5416

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5413

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5417

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5414

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5418

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5415

if print_for_codereview % remove once all checked out

5419

if print_for_codereview % remove once all checked out

5416

h=figure(190);set(gcf,'Tag','COM');

5420

h=figure(190);set(gcf,'Tag','COM');

5417

semilogy(-cdf.x,cdf.y);

5421

semilogy(-cdf.x,cdf.y);

5418

% xlim ([0,-cdf.x(1)])

5422

% xlim ([0,-cdf.x(1)])

5419

ylim([param.specBER 1]);title ('CDF of ILN')

5423

ylim([param.specBER 1]);title ('CDF of ILN')

5420

hold on

5424

hold on

5421

end

5425

end

5422

if rms>rms_fom

5426

if rms>rms_fom

5423

rms_fom=rms;

5427

rms_fom=rms;

5424

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5428

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5425

RILN_TD_struct.PDF=pdf;

5429

RILN_TD_struct.PDF=pdf;

5426

end

5430

end

5427

end

5431

end

5428

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5432

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5429

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5433

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5430

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5434

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5431

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5435

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5432

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5436

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5433

if print_for_codereview % remove once all checked out

5437

if print_for_codereview % remove once all checked out

5434

figure(9000);set(gcf,'Tag','COM');

5438

figure(9000);set(gcf,'Tag','COM');

5435

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5439

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5436

hold on

5440

hold on

5437

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5441

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5438

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5442

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5439

yyaxis right

5443

yyaxis right

5440

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5444

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5441

hold off

5445

hold off

5442

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5446

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5443

figure(9002);set(gcf,'Tag','COM');

5447

figure(9002);set(gcf,'Tag','COM');

5444

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5448

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5445

hold on

5449

hold on

5446

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5450

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5447

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5451

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5448

grid on

5452

grid on

5449

legend('show')

5453

legend('show')

5450

end

5454

end

5451

end

5455

end

5452

function result=get_StepR(ir,param,cb_step,ZT)

5456

function result=get_StepR(ir,param,cb_step,ZT)

5453

%ir = impulse response

5457

%ir = impulse response

5454

%t_base=time array with equal time steps

5458

%t_base=time array with equal time steps

5455

%samp_UI = number of samples per UI for ir

5459

%samp_UI = number of samples per UI for ir

5456

% result.SBR

5460

% result.SBR

5457

% t for debug

5461

% t for debug

5458

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5462

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5459

5463

5460

if cb_step

5464

if cb_step

5461

Ag=1;

5465

Ag=1;

5462

dt=1/param.fb/param.samples_per_ui;

5466

dt=1/param.fb/param.samples_per_ui;

5463

edge_time=param.TR_TDR*1e-9;

5467

edge_time=param.TR_TDR*1e-9;

5464

fedge=1/edge_time;

5468

fedge=1/edge_time;

5465

tedge=0:dt:edge_time*2;

5469

tedge=0:dt:edge_time*2;

5466

%

5470

%

5467

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5471

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5468

drive_pulse=[edge ones(1,param.samples_per_ui)];

5472

drive_pulse=[edge ones(1,param.samples_per_ui)];

5469

%pulse=filter(UI_ones,1,ir);

5473

%pulse=filter(UI_ones,1,ir);

5470

5474

5471

pulse=filter(drive_pulse,1,ir);

5475

pulse=filter(drive_pulse,1,ir);

5472

else

5476

else

5473

pulse=cumsum(ir);

5477

pulse=cumsum(ir);

5474

end

5478

end

5475

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5479

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5476

result.ZSR=TDR_response;

5480

result.ZSR=TDR_response;

5477

result.pulse=pulse;

5481

result.pulse=pulse;

5478

5482

5479

5483

5480

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5484

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5481

% sdd is differential s-parameters structure (2 port assumed)

5485

% sdd is differential s-parameters structure (2 port assumed)

5482

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5486

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5483

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5487

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5484

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5488

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5485

% TDR_results.t starting at t=0

5489

% TDR_results.t starting at t=0

5486

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5490

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5487

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5491

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5488

% TDR_results.f frequency for filter and s parameters

5492

% TDR_results.f frequency for filter and s parameters

5489

% TDR_results.ptdr_RL reflection waveform from the pulse

5493

% TDR_results.ptdr_RL reflection waveform from the pulse

5490

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5494

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5491

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5495

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5492

% TDR_results.ERL reported effective return loss

5496

% TDR_results.ERL reported effective return loss

5493

%

5497

%

5494

db = @(x) 20*log10(abs(x));

5498

db = @(x) 20*log10(abs(x));

5495

rms =@(x) norm(x)/sqrt(length(x));

5499

rms =@(x) norm(x)/sqrt(length(x));

5496

if isfield(OP,'TDR_duration')

5500

if isfield(OP,'TDR_duration')

5497

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5501

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5498

else

5502

else

5499

TDR_duration=5;

5503

TDR_duration=5;

5500

end

5504

end

5501

if ~isfield(OP,'DISPLAY_WINDOW')

5505

if ~isfield(OP,'DISPLAY_WINDOW')

5502

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5506

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5503

end

5507

end

5504

f=sdd.Frequencies;

5508

f=sdd.Frequencies;

5505

TDR_results.f=f;

5509

TDR_results.f=f;

5506

% OP.Zt_adj=2;

5510

% OP.Zt_adj=2;

5507

if param.FLAG.S2P == 0

5511

if param.FLAG.S2P == 0

5508

5512

5509

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5513

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5510

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5514

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5511

5515

5512

if param.RL_sel==1, other_port=2;end

5516

if param.RL_sel==1, other_port=2;end

5513

if param.RL_sel==2, other_port=1;end

5517

if param.RL_sel==2, other_port=1;end

5514

for i = 1:length(sdd.Frequencies)

5518

for i = 1:length(sdd.Frequencies)

5515

if size(sdd.Parameters,2) ==1 % for s2p files

5519

if size(sdd.Parameters,2) ==1 % for s2p files

5516

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5520

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5517

else

5521

else

5518

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5522

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5519

end

5523

end

5520

end

5524

end

5521

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5525

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5522

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5526

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5523

% Z_t=ZT;

5527

% Z_t=ZT;

5524

% zref=sdd.Impedance/2;

5528

% zref=sdd.Impedance/2;

5525

% if Z_t > zref

5529

% if Z_t > zref

5526

% radjust= (zref-Z_t);

5530

% radjust= (zref-Z_t);

5527

% S11adjust= radjust./(radjust + 2*zref);

5531

% S11adjust= radjust./(radjust + 2*zref);

5528

% RL=RL +S11adjust;

5532

% RL=RL +S11adjust;

5529

% elseif Z_t < zref

5533

% elseif Z_t < zref

5530

% rpad=-Z_t*zref/(Z_t-zref);

5534

% rpad=-Z_t*zref/(Z_t-zref);

5531

% S11adjust=zref/(rpad*(zref/rpad + 2));

5535

% S11adjust=zref/(rpad*(zref/rpad + 2));

5532

% RL=RL + S11adjust;

5536

% RL=RL + S11adjust;

5533

% else

5537

% else

5534

% RL=RL;

5538

% RL=RL;

5535

% end

5539

% end

5536

else

5540

else

5537

for i = 1:length(sdd.Frequencies)

5541

for i = 1:length(sdd.Frequencies)

5538

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5542

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5539

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5543

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5540

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5544

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5541

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5545

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5542

end

5546

end

5543

end

5547

end

5544

5548

5545

% end

5549

% end

5546

RL=squeeze(RL);

5550

RL=squeeze(RL);

5547

f9=f/1e9;

5551

f9=f/1e9;

5548

tr=param.TR_TDR;

5552

tr=param.TR_TDR;

5549

TDR_results.delay=500e-12 ;

5553

TDR_results.delay=500e-12 ;

5550

% determine max time from thue

5554

% determine max time from thue

5551

% if sdd.NumPorts==1

5555

% if sdd.NumPorts==1

5552

% try

5556

% try

5553

% maxtime=OP.N*param.ui;

5557

% maxtime=OP.N*param.ui;

5554

% catch

5558

% catch

5555

% maxtime=2e-9;

5559

% maxtime=2e-9;

5556

% end

5560

% end

5557

% pix=1;

5561

% pix=1;

5558

% else

5562

% else

5559

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5563

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5560

% pix=find(fir4del==max(fir4del),1);

5564

% pix=find(fir4del==max(fir4del),1);

5561

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5565

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5562

% if maxtime > tu(end); maxtime=tu(end);end

5566

% if maxtime > tu(end); maxtime=tu(end);end

5563

% endS

5567

% endS

5564

5568

5565

try

5569

try

5566

maxtime=OP.N*param.ui;

5570

maxtime=OP.N*param.ui;

5567

catch

5571

catch

5568

maxtime=2e-9;

5572

maxtime=2e-9;

5569

end

5573

end

5570

if OP.N==0

5574

if OP.N==0

5571

if sdd.NumPorts==1

5575

if sdd.NumPorts==1

5572

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5576

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5573

else

5577

else

5574

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5578

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5575

pix=find(fir4del==max(fir4del),1);

5579

pix=find(fir4del==max(fir4del),1);

5576

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5580

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5577

if maxtime > tu(end); maxtime=tu(end);end

5581

if maxtime > tu(end); maxtime=tu(end);end

5578

end

5582

end

5579

end

5583

end

5580

5584

5581

5585

5582

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5586

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5583

% (makes gausian edge somewhat causal)

5587

% (makes gausian edge somewhat causal)

5584

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5588

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5585

if ~isfield(OP,'cb_Guassian')

5589

if ~isfield(OP,'cb_Guassian')

5586

Use_gaussian=1;

5590

Use_gaussian=1;

5587

else

5591

else

5588

Use_gaussian=OP.cb_Guassian;

5592

Use_gaussian=OP.cb_Guassian;

5589

end

5593

end

5590

if Use_gaussian

5594

if Use_gaussian

5591

if iscolumn(H_t), H_t=H_t.'; end

5595

if iscolumn(H_t), H_t=H_t.'; end

5592

RLf=RL(:).'.*H_t;

5596

RLf=RL(:).'.*H_t;

5593

else % add extra 3x tr delay for causality

5597

else % add extra 3x tr delay for causality

5594

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5598

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5595

end

5599

end

5596

5600

5597

%Bessesl-Thomson turned off here (3rd input=0)

5601

%Bessesl-Thomson turned off here (3rd input=0)

5598

H_bt=Bessel_Thomson_Filter(param,f,0);

5602

H_bt=Bessel_Thomson_Filter(param,f,0);

5599

5603

5600

if isfield(OP,'TDR_Butterworth')

5604

if isfield(OP,'TDR_Butterworth')

5601

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5605

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5602

else

5606

else

5603

H_bw=ones(1,length(f));

5607

H_bw=ones(1,length(f));

5604

end

5608

end

5605

5609

5606

5610

5607

if param.Tukey_Window ~= 0

5611

if param.Tukey_Window ~= 0

5608

H_tw= Tukey_Window(f,param);

5612

H_tw= Tukey_Window(f,param);

5609

else

5613

else

5610

H_tw=ones(1,length(f));

5614

H_tw=ones(1,length(f));

5611

end

5615

end

5612

5616

5613

5617

5614

if iscolumn(H_tw), H_tw=H_tw.';end

5618

if iscolumn(H_tw), H_tw=H_tw.';end

5615

if iscolumn(H_bt), H_bt=H_bt.';end

5619

if iscolumn(H_bt), H_bt=H_bt.';end

5616

if iscolumn(H_bw), H_bw=H_bw.';end

5620

if iscolumn(H_bw), H_bw=H_bw.';end

5617

if iscolumn(RLf), RLf=RLf.';end

5621

if iscolumn(RLf), RLf=RLf.';end

5618

5622

5619

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5623

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5620

RLf=RLf.*TDR_results.Rx_filter;

5624

RLf=RLf.*TDR_results.Rx_filter;

5621

TDR_results.tx_filter=H_t;

5625

TDR_results.tx_filter=H_t;

5622

5626

5623

5627

5624

[IR, t, causality_correction_dB, truncation_dB] = ...

5628

[IR, t, causality_correction_dB, truncation_dB] = ...

5625

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5629

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5626

5630

5627

5631

5628

%

5632

%

5629

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5633

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5630

tfx=param.tfx(np); % use fixture delay for port (np)

5634

tfx=param.tfx(np); % use fixture delay for port (np)

5631

5635

5632

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5636

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5633

5637

5634

t = t-TDR_results.delay;

5638

t = t-TDR_results.delay;

5635

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5639

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5636

if isempty(tend), tend=length(t); end

5640

if isempty(tend), tend=length(t); end

5637

IR=IR(1:tend);

5641

IR=IR(1:tend);

5638

t=t(1:tend);

5642

t=t(1:tend);

5639

if isempty(tend), tend=length(t); end

5643

if isempty(tend), tend=length(t); end

5640

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5644

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5641

if isempty(tstart), tstart=1;end

5645

if isempty(tstart), tstart=1;end

5642

if isempty(tend) || tstart >= tend

5646

if isempty(tend) || tstart >= tend

5643

if isempty(tend) || tstart >= tend

5647

if isempty(tend) || tstart >= tend

5644

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5648

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5645

end

5649

end

5646

tend=length(t);

5650

tend=length(t);

5647

tstart=1;

5651

tstart=1;

5648

end

5652

end

5649

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5653

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5650

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5654

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5651

TDR_results.tdr= ch.ZSR;

5655

TDR_results.tdr= ch.ZSR;

5652

TDR_results.t = t(tstart:tend);

5656

TDR_results.t = t(tstart:tend);

5653

5657

5654

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5658

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5655

if OP.TDR || OP.PTDR % determin average impededance with

5659

if OP.TDR || OP.PTDR % determin average impededance with

5656

try

5660

try

5657

tfstart=find(t>=3*tr*1e-9,1);

5661

tfstart=find(t>=3*tr*1e-9,1);

5658

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5662

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5659

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5663

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5660

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5664

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5661

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5665

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5662

catch

5666

catch

5663

TDR_results.avgZport=0;

5667

TDR_results.avgZport=0;

5664

fit=zeros(1,1);

5668

fit=zeros(1,1);

5665

p=[0 0 0 0 ];

5669

p=[0 0 0 0 ];

5666

end

5670

end

5667

TDR_results.RL=RL;

5671

TDR_results.RL=RL;

5668

end

5672

end

5669

if OP.PTDR

5673

if OP.PTDR

5670

% param.N_bx=param.ndfe;

5674

% param.N_bx=param.ndfe;

5671

RL_equiv=-inf;

5675

RL_equiv=-inf;

5672

L=param.levels;

5676

L=param.levels;

5673

BinSize=OP.BinSize;

5677

BinSize=OP.BinSize;

5674

% param.specBER=1e-5;

5678

% param.specBER=1e-5;

5675

if OP.DISPLAY_WINDOW

5679

if OP.DISPLAY_WINDOW

5676

hwaitbar=waitbar(0);

5680

hwaitbar=waitbar(0);

5677

else

5681

else

5678

fprintf('Worst ERL searching');

5682

fprintf('Worst ERL searching');

5679

end

5683

end

5680

% adjust PTDR for NDFE

5684

% adjust PTDR for NDFE

5681

% ---------------------- 2.7 code

5685

% ---------------------- 2.7 code

5682

% ntx=find(TDR_results.t >= tfx,1,'first');

5686

% ntx=find(TDR_results.t >= tfx,1,'first');

5683

% % gatestartt=TDR_results.t(ntx);

5687

% % gatestartt=TDR_results.t(ntx);

5684

% % gatestartV=PTDR.pulse(ntx);

5688

% % gatestartV=PTDR.pulse(ntx);

5685

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5689

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5686

% tk=param.ui*1*(param.N_bx+1)+tfx;

5690

% tk=param.ui*1*(param.N_bx+1)+tfx;

5687

% -------------------

5691

% -------------------

5688

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5692

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5689

% time filter.

5693

% time filter.

5690

% ntx=find(TDR_results.t >= tfx,1,'first');

5694

% ntx=find(TDR_results.t >= tfx,1,'first');

5691

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5695

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5692

% gatestartt=TDR_results.t(ntx);

5696

% gatestartt=TDR_results.t(ntx);

5693

% gatestartV=PTDR.pulse(ntx);

5697

% gatestartV=PTDR.pulse(ntx);

5694

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5698

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5695

% tk=param.ui*1*(param.N_bx+1)+tfx;

5699

% tk=param.ui*1*(param.N_bx+1)+tfx;

5696

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5700

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5697

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5701

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5698

% [ahealey] End of modifications.

5702

% [ahealey] End of modifications.

5699

if isempty(ndfex), ndfex=length(TDR_results.t); end

5703

if isempty(ndfex), ndfex=length(TDR_results.t); end

5700

PTDR.pulse_orig=PTDR.pulse;

5704

PTDR.pulse_orig=PTDR.pulse;

5701

5705

5702

switch param.Grr

5706

switch param.Grr

5703

case 0 % pre .3cd release

5707

case 0 % pre .3cd release

5704

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5708

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5705

case 1 % .3cd release

5709

case 1 % .3cd release

5706

fctrx(1:length(PTDR.pulse_orig))=1;

5710

fctrx(1:length(PTDR.pulse_orig))=1;

5707

case 2 % .3ck working

5711

case 2 % .3ck working

5708

fctrx(1:length(PTDR.pulse_orig))=1;

5712

fctrx(1:length(PTDR.pulse_orig))=1;

5709

end

5713

end

5710

Gloss(1:length(TDR_results.t))=1;

5714

Gloss(1:length(TDR_results.t))=1;

5711

Grr(1:length(TDR_results.t))=1;

5715

Grr(1:length(TDR_results.t))=1;

5712

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5716

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5713

5717

5714

for ii=ntx:ndfex

5718

for ii=ntx:ndfex

5715

% adjust for near end loss

5719

% adjust for near end loss

5716

if param.N_bx>0 && param.beta_x~=0;

5720

if param.N_bx>0 && param.beta_x~=0;

5717

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5721

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5718

else

5722

else

5719

Gloss(ii)=1;

5723

Gloss(ii)=1;

5720

end

5724

end

5721

% ---------------------- 2.7 code

5725

% ---------------------- 2.7 code

5722

% x=(TDR_results.t(ii)-tfx)/param.ui;

5726

% x=(TDR_results.t(ii)-tfx)/param.ui;

5723

% ----------------------

5727

% ----------------------

5724

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5728

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5725

% rise time filter.

5729

% rise time filter.

5726

% x=(TDR_results.t(ii)-tfx)/param.ui;

5730

% x=(TDR_results.t(ii)-tfx)/param.ui;

5727

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5731

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5728

% determine how much of the return loss to use base on expected

5732

% determine how much of the return loss to use base on expected

5729

% missing reflections

5733

% missing reflections

5730

switch param.Grr

5734

switch param.Grr

5731

case 0 % pre .3cd release

5735

case 0 % pre .3cd release

5732

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5736

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5733

case 1 % .3cd release

5737

case 1 % .3cd release

5734

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5738

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5735

case 2 % .3ck working

5739

case 2 % .3ck working

5736

Grr(ii)= param.rho_x ;

5740

Grr(ii)= param.rho_x ;

5737

end

5741

end

5738

fctrx(ii)=Gloss(ii).*Grr(ii);

5742

fctrx(ii)=Gloss(ii).*Grr(ii);

5739

end

5743

end

5740

5744

5741

if isrow(fctrx), fctrx=fctrx(:);end

5745

if isrow(fctrx), fctrx=fctrx(:);end

5742

PTDR.pulse=PTDR.pulse.*fctrx;

5746

PTDR.pulse=PTDR.pulse.*fctrx;

5743

if 0

5747

if 0

5744

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5748

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5745

s1=subplot(2,1,1);

5749

s1=subplot(2,1,1);

5746

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5750

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5747

hold on

5751

hold on

5748

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5752

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5749

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5753

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5750

grid on

5754

grid on

5751

ylim([ 0 1.2])

5755

ylim([ 0 1.2])

5752

s2=subplot(2,1,2);

5756

s2=subplot(2,1,2);

5753

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5757

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5754

grid on

5758

grid on

5755

linkaxes([s1,s2],'x')

5759

linkaxes([s1,s2],'x')

5756

xlabel 'UI'

5760

xlabel 'UI'

5757

xlim ([ 1 200])

5761

xlim ([ 1 200])

5758

end

5762

end

5759

5763

5760

FAST_NOISE_CONV=0;

5764

FAST_NOISE_CONV=0;

5761

ERLRMS=rms(PTDR.pulse);

5765

ERLRMS=rms(PTDR.pulse);

5762

for ki=1:param.samples_per_ui

5766

for ki=1:param.samples_per_ui

5763

progress = ki/param.samples_per_ui;

5767

progress = ki/param.samples_per_ui;

5764

if OP.DISPLAY_WINDOW

5768

if OP.DISPLAY_WINDOW

5765

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5769

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5766

else

5770

else

5767

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5771

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5768

end

5772

end

5769

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5773

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5770

if OP.RL_norm_test

5774

if OP.RL_norm_test

5771

rl_fom=(norm(tps));

5775

rl_fom=(norm(tps));

5772

else

5776

else

5773

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5777

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5774

cdf_test=cumsum(testpdf.y);

5778

cdf_test=cumsum(testpdf.y);

5775

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5779

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5776

rl_fom=rl_test;

5780

rl_fom=rl_test;

5777

end

5781

end

5778

if rl_fom > RL_equiv

5782

if rl_fom > RL_equiv

5779

RL_equiv=rl_fom;

5783

RL_equiv=rl_fom;

5780

best_ki=ki;

5784

best_ki=ki;

5781

end

5785

end

5782

if ~OP.RL_norm_test

5786

if ~OP.RL_norm_test

5783

best_erl=rl_test;

5787

best_erl=rl_test;

5784

best_pdf=testpdf;

5788

best_pdf=testpdf;

5785

best_cdf=cdf_test;

5789

best_cdf=cdf_test;

5786

end

5790

end

5787

5791

5788

end

5792

end

5789

if OP.RL_norm_test

5793

if OP.RL_norm_test

5790

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5794

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5791

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5795

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5792

cdf_test=cumsum(testpdf.y);

5796

cdf_test=cumsum(testpdf.y);

5793

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5797

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5794

end

5798

end

5795

5799

5796

fprintf('\n');

5800

fprintf('\n');

5797

try

5801

try

5798

close(hwaitbar)

5802

close(hwaitbar)

5799

catch

5803

catch

5800

end

5804

end

5801

if ~exist('best_ki','var'),best_ki=1;end

5805

if ~exist('best_ki','var'),best_ki=1;end

5802

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5806

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5803

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5807

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5804

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5808

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5805

TDR_results.ERL=-db(best_erl);

5809

TDR_results.ERL=-db(best_erl);

5806

TDR_results.ERLRMS=-db(ERLRMS);

5810

TDR_results.ERLRMS=-db(ERLRMS);

5807

5811

5808

end

5812

end

5809

5813

5810

5814

5811

% end get TDR

5815

% end get TDR

5812

%%

5816

%%

5813

5817

5814

5818

5815

5819

5816

5820

5817

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5821

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5818

% filename parsing and acquisition

5822

% filename parsing and acquisition

5819

%------------------------------------------------------------------

5823

%------------------------------------------------------------------

5820

%----------put files names into chdata structure ---------

5824

%----------put files names into chdata structure ---------

5821

% The thru file has the index of 1

5825

% The thru file has the index of 1

5822

% crosstalk file are indexed from 2

5826

% crosstalk file are indexed from 2

5823

% nxi is incremented each time a file is read in so that nxi will end

5827

% nxi is incremented each time a file is read in so that nxi will end

5824

filepath=[]; % path name for file

5828

filepath=[]; % path name for file

5825

nxi=0; % file index

5829

nxi=0; % file index

5826

% get the THRU file

5830

% get the THRU file

5827

if size(file_list,2) ~= 0

5831

if size(file_list,2) ~= 0

5828

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5832

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5829

[filepath, basename, fileext]=fileparts(file_list{1});

5833

[filepath, basename, fileext]=fileparts(file_list{1});

5830

5834

5831

else

5835

else

5832

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5836

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5833

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5837

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5834

movegui(h,'northeast')

5838

movegui(h,'northeast')

5835

end

5839

end

5836

dir=fullfile(filepath, '*.csv');

5840

dir=fullfile(filepath, '*.csv');

5837

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5841

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5838

if filepath == 0

5842

if filepath == 0

5839

error('No Thru file')

5843

error('No Thru file')

5840

end

5844

end

5841

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5845

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5842

end

5846

end

5843

nxi=nxi+1;

5847

nxi=nxi+1;

5844

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5848

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5845

chdata(nxi).ext = fileext;

5849

chdata(nxi).ext = fileext;

5846

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5850

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5847

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5851

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5848

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5852

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5849

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5853

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5850

chdata(nxi).type='THRU';

5854

chdata(nxi).type='THRU';

5851

chdata(nxi).ftr=param.fb*param.f_v;

5855

chdata(nxi).ftr=param.fb*param.f_v;

5852

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5856

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5853

5857

5854

% now get FEXT file names into chdata structure

5858

% now get FEXT file names into chdata structure

5855

kxi=nxi;

5859

kxi=nxi;

5856

for nxi=kxi+1:num_fext+kxi

5860

for nxi=kxi+1:num_fext+kxi

5857

lastfilepath=filepath;

5861

lastfilepath=filepath;

5858

if size(file_list,2) ~= 0

5862

if size(file_list,2) ~= 0

5859

[filepath, basename, fileext]=fileparts(file_list{nxi});

5863

[filepath, basename, fileext]=fileparts(file_list{nxi});

5860

else

5864

else

5861

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5865

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5862

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5866

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5863

movegui(h,'northeast')

5867

movegui(h,'northeast')

5864

end

5868

end

5865

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5869

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5866

dir=fullfile(filepath, '*.csv');

5870

dir=fullfile(filepath, '*.csv');

5867

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5871

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5868

if filepath==0

5872

if filepath==0

5869

error('Not enough NEXT files')

5873

error('Not enough NEXT files')

5870

end

5874

end

5871

else

5875

else

5872

dir=fullfile(filepath, '*.csv');

5876

dir=fullfile(filepath, '*.csv');

5873

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5877

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5874

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5878

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5875

else

5879

else

5876

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5880

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5877

end

5881

end

5878

if filepath==0

5882

if filepath==0

5879

error('Not enough NEXT files')

5883

error('Not enough NEXT files')

5880

end

5884

end

5881

end

5885

end

5882

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5886

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5883

end

5887

end

5884

if isempty( filepath), filepath=lastfilepath; end

5888

if isempty( filepath), filepath=lastfilepath; end

5885

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5889

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5886

chdata(nxi).ext = fileext;

5890

chdata(nxi).ext = fileext;

5887

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5891

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5888

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5892

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5889

% chdata(nxi).A=param.a_fext;

5893

% chdata(nxi).A=param.a_fext;

5890

chdata(nxi).ftr=param.fb*param.f_f;

5894

chdata(nxi).ftr=param.fb*param.f_f;

5891

chdata(nxi).type='FEXT';

5895

chdata(nxi).type='FEXT';

5892

end

5896

end

5893

% now get NEXT file names into chdata structure

5897

% now get NEXT file names into chdata structure

5894

kxi=num_fext+kxi;

5898

kxi=num_fext+kxi;

5895

for nxi=kxi+1:num_next+kxi

5899

for nxi=kxi+1:num_next+kxi

5896

lastfilepath=filepath;

5900

lastfilepath=filepath;

5897

if size(file_list,2) ~= 0

5901

if size(file_list,2) ~= 0

5898

[filepath, basename, fileext]=fileparts(file_list{nxi});

5902

[filepath, basename, fileext]=fileparts(file_list{nxi});

5899

else

5903

else

5900

dir=fullfile(filepath, '*.csv');

5904

dir=fullfile(filepath, '*.csv');

5901

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5905

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5902

if filepath==0

5906

if filepath==0

5903

error('Not enough NEXT files')

5907

error('Not enough NEXT files')

5904

end

5908

end

5905

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5909

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5906

end

5910

end

5907

if isempty( filepath), filepath=lastfilepath; end

5911

if isempty( filepath), filepath=lastfilepath; end

5908

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5912

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5909

chdata(nxi).ext = fileext;

5913

chdata(nxi).ext = fileext;

5910

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5914

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5911

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5915

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5912

% chdata(nxi).A=param.A_next;

5916

% chdata(nxi).A=param.A_next;

5913

chdata(nxi).ftr=param.fb*param.f_n;

5917

chdata(nxi).ftr=param.fb*param.f_n;

5914

chdata(nxi).type='NEXT';

5918

chdata(nxi).type='NEXT';

5915

end

5919

end

5916

function half_UI=get_center_of_UI(samples_per_UI)

5920

function half_UI=get_center_of_UI(samples_per_UI)

5917

5921

5918

%half_UI reveals which value to use for the center of the UI. For eye

5922

%half_UI reveals which value to use for the center of the UI. For eye

5919

%width calculations, it is necessary to place the cursor in the center of the

5923

%width calculations, it is necessary to place the cursor in the center of the

5920

%UI window to ensure a 0 crossing on both left/right inside the window.

5924

%UI window to ensure a 0 crossing on both left/right inside the window.

5921

%This function was written in order to support even and odd samples_per_UI

5925

%This function was written in order to support even and odd samples_per_UI

5922

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5926

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5923

5927

5924

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5928

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5925

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5929

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5926

%the center of the UI is sample closest to 0.5

5930

%the center of the UI is sample closest to 0.5

5927

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5931

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5928

function results= get_cm_noise(M,PR,L,BER,OP)

5932

function results= get_cm_noise(M,PR,L,BER,OP)

5929

5933

5930

if ~exist('OP')

5934

if ~exist('OP')

5931

OP.DC_norm_test=0;

5935

OP.DC_norm_test=0;

5932

OP.DISPLAY_WINDOW=1;

5936

OP.DISPLAY_WINDOW=1;

5933

end

5937

end

5934

param.BinSize=1e-5;

5938

param.BinSize=1e-5;

5935

PR_test=-inf;

5939

PR_test=-inf;

5936

PR_fom_best=-inf;

5940

PR_fom_best=-inf;

5937

% hwaitbar=waitbar(0);

5941

% hwaitbar=waitbar(0);

5938

for ki=1:M

5942

for ki=1:M

5939

progress = ki/M;

5943

progress = ki/M;

5940

% if OP.DISPLAY_WINDOW

5944

% if OP.DISPLAY_WINDOW

5941

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5945

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5942

% else

5946

% else

5943

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5947

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5944

% end

5948

% end

5945

tps=PR(ki:M:end);

5949

tps=PR(ki:M:end);

5946

if OP.DC_norm_test

5950

if OP.DC_norm_test

5947

PR_fom=(norm(tps));

5951

PR_fom=(norm(tps));

5948

else

5952

else

5949

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5953

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5950

cdf_test=cumsum(testpdf.y);

5954

cdf_test=cumsum(testpdf.y);

5951

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5955

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5952

PR_fom=PRn_test;

5956

PR_fom=PRn_test;

5953

end

5957

end

5954

if PR_fom > PR_fom_best

5958

if PR_fom > PR_fom_best

5955

PR_fom_best=PR_fom;

5959

PR_fom_best=PR_fom;

5956

best_ki=ki;

5960

best_ki=ki;

5957

end

5961

end

5958

if ~OP.DC_norm_test

5962

if ~OP.DC_norm_test

5959

results.DCn=PR_fom_best;

5963

results.DCn=PR_fom_best;

5960

results.DCn_pdf=testpdf;

5964

results.DCn_pdf=testpdf;

5961

results.DCn_cdf=cdf_test;

5965

results.DCn_cdf=cdf_test;

5962

else

5966

else

5963

results.DCn=PR_fom_best;

5967

results.DCn=PR_fom_best;

5964

end

5968

end

5965

results.DCn_p2p=max(PR)-min(PR);

5969

results.DCn_p2p=max(PR)-min(PR);

5966

end

5970

end

5967

5971

5968

5972

5969

5973

5970

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5974

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5971

SBR=chdata.eq_pulse_response(:)'; % row vector

5975

SBR=chdata.eq_pulse_response(:)'; % row vector

5972

type=chdata.type;

5976

type=chdata.type;

5973

samp_UI=param.samples_per_ui;

5977

samp_UI=param.samples_per_ui;

5974

residual_response = SBR;

5978

residual_response = SBR;

5975

5979

5976

if isequal(type, 'THRU')

5980

if isequal(type, 'THRU')

5977

% for thru pulse response:

5981

% for thru pulse response:

5978

% remove the cursor and the DFE postcursors (up to their limit), since

5982

% remove the cursor and the DFE postcursors (up to their limit), since

5979

% we only care about the residuals.

5983

% we only care about the residuals.

5980

5984

5981

if ~param.Floating_DFE

5985

if ~param.Floating_DFE

5982

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5986

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5983

else

5987

else

5984

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5988

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5985

end

5989

end

5986

if param.dfe_delta ~= 0

5990

if param.dfe_delta ~= 0

5987

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5991

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5988

else

5992

else

5989

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5993

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5990

end

5994

end

5991

5995

5992

%AJG021820

5996

%AJG021820

5993

if ~param.Floating_DFE

5997

if ~param.Floating_DFE

5994

bmax_vec=residual_response(t_s)*[1,param.bmax];

5998

bmax_vec=residual_response(t_s)*[1,param.bmax];

5995

bmin_vec=residual_response(t_s)*[1,param.bmin];

5999

bmin_vec=residual_response(t_s)*[1,param.bmin];

5996

else

6000

else

5997

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6001

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5998

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6002

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5999

end

6003

end

6000

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6004

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6001

6005

6002

6006

6003

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6007

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6004

dfetaps=effective_cancelled_cursors/SBR(t_s);

6008

dfetaps=effective_cancelled_cursors/SBR(t_s);

6005

6009

6006

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6010

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6007

% really needed for COM, but helps debugging. May be factored out in future revisions.

6011

% really needed for COM, but helps debugging. May be factored out in future revisions.

6008

start_cancel = t_s-param.samples_per_ui/2;

6012

start_cancel = t_s-param.samples_per_ui/2;

6009

if ~param.Floating_DFE

6013

if ~param.Floating_DFE

6010

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6014

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6011

else

6015

else

6012

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6016

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6013

end

6017

end

6014

residual_response(start_cancel:end_cancel) = ...

6018

residual_response(start_cancel:end_cancel) = ...

6015

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6019

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6016

%else

6020

%else

6017

% for crosstalk pulse responses, nothing is cancelled, and all phases

6021

% for crosstalk pulse responses, nothing is cancelled, and all phases

6018

% are equally important.

6022

% are equally important.

6019

end

6023

end

6020

6024

6021

nui=round(length(residual_response)/param.samples_per_ui);

6025

nui=round(length(residual_response)/param.samples_per_ui);

6022

6026

6023

vs=zeros(nui-2, param.samples_per_ui);

6027

vs=zeros(nui-2, param.samples_per_ui);

6024

for i=1:param.samples_per_ui

6028

for i=1:param.samples_per_ui

6025

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6029

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6026

end

6030

end

6027

6031

6028

if OP.DISPLAY_WINDOW,

6032

if OP.DISPLAY_WINDOW,

6029

hwaitbar=waitbar(0);

6033

hwaitbar=waitbar(0);

6030

end

6034

end

6031

6035

6032

% determine which pdf to use

6036

% determine which pdf to use

6033

if isequal(type, 'THRU')

6037

if isequal(type, 'THRU')

6034

% one phase is interesting for thru

6038

% one phase is interesting for thru

6035

phases = mod(t_s,param.samples_per_ui);

6039

phases = mod(t_s,param.samples_per_ui);

6036

if phases==0, phases = param.samples_per_ui; end

6040

if phases==0, phases = param.samples_per_ui; end

6037

else

6041

else

6038

phases=1:samp_UI;

6042

phases=1:samp_UI;

6039

end

6043

end

6040

6044

6041

mxV = zeros(size(phases));

6045

mxV = zeros(size(phases));

6042

% we already found the phase in the PSD process for MMSE

6046

% we already found the phase in the PSD process for MMSE

6043

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6047

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6044

if isequal(type, 'THRU')

6048

if isequal(type, 'THRU')

6045

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6049

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6046

else

6050

else

6047

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6051

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6048

end

6052

end

6049

else

6053

else

6050

for k=phases

6054

for k=phases

6051

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6055

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6052

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6056

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6053

progress = k/length(phases);

6057

progress = k/length(phases);

6054

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6058

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6055

end

6059

end

6056

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6060

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6057

pdf=pdf_samples(pxi);

6061

pdf=pdf_samples(pxi);

6058

end

6062

end

6059

6063

6060

6064

6061

6065

6062

if OP.DISPLAY_WINDOW

6066

if OP.DISPLAY_WINDOW

6063

close(hwaitbar);

6067

close(hwaitbar);

6064

end

6068

end

6065

6069

6066

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6070

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6067

% Create PDF from interference vector using successive delta-set convolutions.

6071

% Create PDF from interference vector using successive delta-set convolutions.

6068

% input_vector = list of values of samples

6072

% input_vector = list of values of samples

6069

% return

6073

% return

6070

% pdf.x

6074

% pdf.x

6071

% pdf.y

6075

% pdf.y

6072

% pdf.vec

6076

% pdf.vec

6073

% pdf.bin

6077

% pdf.bin

6074

if ~exist('FAST_NOISE_CONV','var')

6078

if ~exist('FAST_NOISE_CONV','var')

6075

FAST_NOISE_CONV=0;

6079

FAST_NOISE_CONV=0;

6076

end

6080

end

6077

if max(input_vector) > BinSize

6081

if max(input_vector) > BinSize

6078

input_vector=input_vector(abs(input_vector)>BinSize);

6082

input_vector=input_vector(abs(input_vector)>BinSize);

6079

end

6083

end

6080

% for i = 1:length(input_vector)

6084

% for i = 1:length(input_vector)

6081

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6085

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6082

%end

6086

%end

6083

6087

6084

input_vector(abs(input_vector)<BinSize) = 0;

6088

input_vector(abs(input_vector)<BinSize) = 0;

6085

b=sign(input_vector);

6089

b=sign(input_vector);

6086

[input_vector,index]=sort(abs(input_vector),'descend');

6090

[input_vector,index]=sort(abs(input_vector),'descend');

6087

input_vector=input_vector.*b(index);

6091

input_vector=input_vector.*b(index);

6088

if FAST_NOISE_CONV

6092

if FAST_NOISE_CONV

6089

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6093

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6090

res_pdf= normal_dist(sig_res,5,BinSize);

6094

res_pdf= normal_dist(sig_res,5,BinSize);

6091

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6095

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6092

end

6096

end

6093

%% Equation 93A-39 %%

6097

%% Equation 93A-39 %%

6094

values = 2*(0:L-1)/(L-1)-1;

6098

values = 2*(0:L-1)/(L-1)-1;

6095

prob = ones(1,L)/L;

6099

prob = ones(1,L)/L;

6096

6100

6097

%% Initialize pdf to delta at 0

6101

%% Initialize pdf to delta at 0

6098

pdf=d_cpdf(BinSize, 0, 1);

6102

pdf=d_cpdf(BinSize, 0, 1);

6099

empty_pdf=pdf;

6103

empty_pdf=pdf;

6100

for k = 1:length(input_vector)

6104

for k = 1:length(input_vector)

6101

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6105

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6102

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6106

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6103

pdf=conv_fct(pdf, pdfn);

6107

pdf=conv_fct(pdf, pdfn);

6104

end

6108

end

6105

if FAST_NOISE_CONV

6109

if FAST_NOISE_CONV

6106

% pdf=conv_fct(pdf,res_pdf);

6110

% pdf=conv_fct(pdf,res_pdf);

6107

pdf=conv_fct_TEST(pdf,res_pdf);

6111

pdf=conv_fct_TEST(pdf,res_pdf);

6108

end

6112

end

6109

6113

6110

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6114

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6111

t_s_orig=t_s;

6115

t_s_orig=t_s;

6112

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6116

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6113

type=chdata.type;

6117

type=chdata.type;

6114

6118

6115

pulse_orig=chdata.eq_pulse_response(:)';

6119

pulse_orig=chdata.eq_pulse_response(:)';

6116

%build arbitrary time axis with step size = 1/samples per ui

6120

%build arbitrary time axis with step size = 1/samples per ui

6117

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6121

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6118

%force t_s at time =0 (makes the other things below easy)

6122

%force t_s at time =0 (makes the other things below easy)

6119

original_sample_time=old_time(t_s_orig);

6123

original_sample_time=old_time(t_s_orig);

6120

old_time=old_time-original_sample_time;

6124

old_time=old_time-original_sample_time;

6121

%build new time axis that forces time=0 to be in the axis

6125

%build new time axis that forces time=0 to be in the axis

6122

%unless the new/old samples per UI are integer ratios, time 0 will not be

6126

%unless the new/old samples per UI are integer ratios, time 0 will not be

6123

%there by default

6127

%there by default

6124

samp_UI=param.samples_for_C2M;

6128

samp_UI=param.samples_for_C2M;

6125

new_timea=[0:-1/samp_UI:min(old_time)];

6129

new_timea=[0:-1/samp_UI:min(old_time)];

6126

new_timeb=[0:1/samp_UI:max(old_time)];

6130

new_timeb=[0:1/samp_UI:max(old_time)];

6127

new_time=[fliplr(new_timea) new_timeb(2:end)];

6131

new_time=[fliplr(new_timea) new_timeb(2:end)];

6128

SBR=interp1(old_time,pulse_orig,new_time);

6132

SBR=interp1(old_time,pulse_orig,new_time);

6129

%new sample time is simply the point where new_time = 0

6133

%new sample time is simply the point where new_time = 0

6130

[tmp,t_s]=min(abs(new_time));

6134

[tmp,t_s]=min(abs(new_time));

6131

6135

6132

residual_response = SBR;

6136

residual_response = SBR;

6133

6137

6134

half_UI=get_center_of_UI(samp_UI);

6138

half_UI=get_center_of_UI(samp_UI);

6135

6139

6136

if isequal(type, 'THRU')

6140

if isequal(type, 'THRU')

6137

% for thru pulse response:

6141

% for thru pulse response:

6138

% remove the cursor and the DFE postcursors (up to their limit), since

6142

% remove the cursor and the DFE postcursors (up to their limit), since

6139

% we only care about the residuals.

6143

% we only care about the residuals.

6140

6144

6141

%AJG021820

6145

%AJG021820

6142

if ~param.Floating_DFE

6146

if ~param.Floating_DFE

6143

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6147

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6144

else

6148

else

6145

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6149

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6146

end

6150

end

6147

if param.dfe_delta ~= 0

6151

if param.dfe_delta ~= 0

6148

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6152

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6149

else

6153

else

6150

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6154

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6151

end

6155

end

6152

6156

6153

if ~param.Floating_DFE

6157

if ~param.Floating_DFE

6154

bmax_vec=residual_response(t_s)*[param.bmax];

6158

bmax_vec=residual_response(t_s)*[param.bmax];

6155

bmin_vec=residual_response(t_s)*[param.bmin];

6159

bmin_vec=residual_response(t_s)*[param.bmin];

6156

else

6160

else

6157

bmax_vec=residual_response(t_s)*[param.use_bmax];

6161

bmax_vec=residual_response(t_s)*[param.use_bmax];

6158

bmin_vec=residual_response(t_s)*[param.use_bmin];

6162

bmin_vec=residual_response(t_s)*[param.use_bmin];

6159

end

6163

end

6160

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6164

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6161

6165

6162

6166

6163

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6167

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6164

dfetaps=effective_cancelled_cursors/SBR(t_s);

6168

dfetaps=effective_cancelled_cursors/SBR(t_s);

6165

6169

6166

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6170

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6167

% really needed for COM, but helps debugging. May be factored out in future revisions.

6171

% really needed for COM, but helps debugging. May be factored out in future revisions.

6168

6172

6169

%avoid dividing samp_UI by 2 in case it is not even

6173

%avoid dividing samp_UI by 2 in case it is not even

6170

start_cancel=t_s-half_UI+1+samp_UI;

6174

start_cancel=t_s-half_UI+1+samp_UI;

6171

%AJG021820

6175

%AJG021820

6172

if ~param.Floating_DFE

6176

if ~param.Floating_DFE

6173

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6177

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6174

else

6178

else

6175

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6179

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6176

end

6180

end

6177

residual_response(start_cancel:end_cancel) = ...

6181

residual_response(start_cancel:end_cancel) = ...

6178

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6182

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6179

%else

6183

%else

6180

% for crosstalk pulse responses, nothing is cancelled, and all phases

6184

% for crosstalk pulse responses, nothing is cancelled, and all phases

6181

% are equally important.

6185

% are equally important.

6182

6186

6183

%remove entire cursor UI

6187

%remove entire cursor UI

6184

uiv_start=start_cancel-samp_UI;

6188

uiv_start=start_cancel-samp_UI;

6185

uiv_end=uiv_start+samp_UI-1;

6189

uiv_end=uiv_start+samp_UI-1;

6186

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6190

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6187

residual_response(uiv_start:uiv_end)=0;

6191

residual_response(uiv_start:uiv_end)=0;

6188

end

6192

end

6189

6193

6190

nui=round(length(residual_response)/samp_UI);

6194

nui=round(length(residual_response)/samp_UI);

6191

6195

6192

6196

6193

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6197

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6194

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6198

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6195

%response without DFE included. (Can't include DFE for jitter calc)

6199

%response without DFE included. (Can't include DFE for jitter calc)

6196

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6200

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6197

6201

6198

% if OP.DISPLAY_WINDOW,

6202

% if OP.DISPLAY_WINDOW,

6199

% hwaitbar=waitbar(0);

6203

% hwaitbar=waitbar(0);

6200

% end

6204

% end

6201

6205

6202

% determine which pdf to use

6206

% determine which pdf to use

6203

if isequal(type, 'THRU')

6207

if isequal(type, 'THRU')

6204

% one phase is interesting for thru

6208

% one phase is interesting for thru

6205

phases = mod(t_s,samp_UI);

6209

phases = mod(t_s,samp_UI);

6206

if phases==0, phases = samp_UI; end

6210

if phases==0, phases = samp_UI; end

6207

else

6211

else

6208

phases=1:samp_UI;

6212

phases=1:samp_UI;

6209

end

6213

end

6210

6214

6211

mxV = zeros(size(phases));

6215

mxV = zeros(size(phases));

6212

6216

6213

%phases reveals the raw position in the UI window of the cursor.

6217

%phases reveals the raw position in the UI window of the cursor.

6214

%shift_amount is the amount to shift so that it aligns with half_UI

6218

%shift_amount is the amount to shift so that it aligns with half_UI

6215

shift_amount=half_UI-phases;

6219

shift_amount=half_UI-phases;

6216

%vs_shift puts the cursor at the center

6220

%vs_shift puts the cursor at the center

6217

vs_shift=circshift(vs,[0 shift_amount]);

6221

vs_shift=circshift(vs,[0 shift_amount]);

6218

L=size(vs_raw,1);

6222

L=size(vs_raw,1);

6219

%allow partial UI computation through pdf_range

6223

%allow partial UI computation through pdf_range

6220

%if pdf_range is empty, do full UI

6224

%if pdf_range is empty, do full UI

6221

if isempty(pdf_range)

6225

if isempty(pdf_range)

6222

pdf_range=1:samp_UI;

6226

pdf_range=1:samp_UI;

6223

else

6227

else

6224

pdf_range=min(pdf_range):max(pdf_range);

6228

pdf_range=min(pdf_range):max(pdf_range);

6225

end

6229

end

6226

h_j_full=zeros(L,samp_UI);

6230

h_j_full=zeros(L,samp_UI);

6227

for k=pdf_range

6231

for k=pdf_range

6228

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6232

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6229

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6233

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6230

%progress = k/length(phases);

6234

%progress = k/length(phases);

6231

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6235

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6232

6236

6233

%build the circshift of h_j_full into the loop to support a reduced

6237

%build the circshift of h_j_full into the loop to support a reduced

6234

%range of sampling points. circshift at the end only works if doing the

6238

%range of sampling points. circshift at the end only works if doing the

6235

%full range of sampling points. And shifting before the loop will

6239

%full range of sampling points. And shifting before the loop will

6236

%yield the wrong answer at the edges of the UI

6240

%yield the wrong answer at the edges of the UI

6237

hk=k-shift_amount;

6241

hk=k-shift_amount;

6238

if hk<1

6242

if hk<1

6239

hk=hk+samp_UI;

6243

hk=hk+samp_UI;

6240

elseif hk>samp_UI

6244

elseif hk>samp_UI

6241

hk=hk-samp_UI;

6245

hk=hk-samp_UI;

6242

end

6246

end

6243

if hk==1

6247

if hk==1

6244

%when hk=1, the early UI is the last column

6248

%when hk=1, the early UI is the last column

6245

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6249

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6246

elseif hk==samp_UI

6250

elseif hk==samp_UI

6247

%when hk=samp_UI, the late UI is the first column

6251

%when hk=samp_UI, the late UI is the first column

6248

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6252

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6249

else

6253

else

6250

%for all other cases, do the normal late=+1, early = -1

6254

%for all other cases, do the normal late=+1, early = -1

6251

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6255

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6252

end

6256

end

6253

end

6257

end

6254

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6258

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6255

% filename parsing and acquisition

6259

% filename parsing and acquisition

6256

%------------------------------------------------------------------

6260

%------------------------------------------------------------------

6257

%----------put files names into chdata structure ---------

6261

%----------put files names into chdata structure ---------

6258

% The thru file has the index of 1

6262

% The thru file has the index of 1

6259

% crosstalk file are indexed from 2

6263

% crosstalk file are indexed from 2

6260

% nxi is incremented each time a file is read in so that nxi will end

6264

% nxi is incremented each time a file is read in so that nxi will end

6261

filepath=[]; % path name for file

6265

filepath=[]; % path name for file

6262

nxi=0; % file index

6266

nxi=0; % file index

6263

% get the THRU file

6267

% get the THRU file

6264

if size(file_list,2) ~= 0

6268

if size(file_list,2) ~= 0

6265

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6269

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6266

[filepath, basename, fileext]=fileparts(file_list{1});

6270

[filepath, basename, fileext]=fileparts(file_list{1});

6267

6271

6268

else

6272

else

6269

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6273

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6270

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6274

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6271

movegui(h,'northeast')

6275

movegui(h,'northeast')

6272

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6276

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6273

end

6277

end

6274

if OP.ERL == 2

6278

if OP.ERL == 2

6275

dir=fullfile(filepath, '*.s2p');

6279

dir=fullfile(filepath, '*.s2p');

6276

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6280

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6277

if filepath == 0

6281

if filepath == 0

6278

error('No RL measurement file')

6282

error('No RL measurement file')

6279

end

6283

end

6280

else

6284

else

6281

dir=fullfile(filepath, '*.s4p');

6285

dir=fullfile(filepath, '*.s4p');

6282

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6286

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6283

if filepath == 0

6287

if filepath == 0

6284

error('No Thru file')

6288

error('No Thru file')

6285

end

6289

end

6286

end

6290

end

6287

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6291

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6288

end

6292

end

6289

nxi=nxi+1;

6293

nxi=nxi+1;

6290

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6294

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6291

chdata(nxi).ext = fileext;

6295

chdata(nxi).ext = fileext;

6292

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6296

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6293

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6297

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6294

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6298

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6295

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6299

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6296

chdata(nxi).type='THRU';

6300

chdata(nxi).type='THRU';

6297

chdata(nxi).ftr=param.fb*param.f_v;

6301

chdata(nxi).ftr=param.fb*param.f_v;

6298

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6302

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6299

6303

6300

% now get FEXT file names into chdata structure

6304

% now get FEXT file names into chdata structure

6301

kxi=nxi;

6305

kxi=nxi;

6302

for nxi=kxi+1:num_fext+kxi

6306

for nxi=kxi+1:num_fext+kxi

6303

lastfilepath=filepath;

6307

lastfilepath=filepath;

6304

if size(file_list,2) ~= 0

6308

if size(file_list,2) ~= 0

6305

[filepath, basename, fileext]=fileparts(file_list{nxi});

6309

[filepath, basename, fileext]=fileparts(file_list{nxi});

6306

else

6310

else

6307

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6311

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6308

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6312

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6309

movegui(h,'northeast')

6313

movegui(h,'northeast')

6310

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6314

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6311

end

6315

end

6312

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6316

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6313

dir=fullfile(filepath, '*.s4p');

6317

dir=fullfile(filepath, '*.s4p');

6314

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6318

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6315

if filepath==0

6319

if filepath==0

6316

error('Not enough NEXT files')

6320

error('Not enough NEXT files')

6317

end

6321

end

6318

else

6322

else

6319

dir=fullfile(filepath, '*.s4p');

6323

dir=fullfile(filepath, '*.s4p');

6320

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6324

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6321

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6325

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6322

else

6326

else

6323

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6327

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6324

end

6328

end

6325

if filepath==0

6329

if filepath==0

6326

error('Not enough NEXT files')

6330

error('Not enough NEXT files')

6327

end

6331

end

6328

end

6332

end

6329

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6333

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6330

end

6334

end

6331

if isempty( filepath), filepath=lastfilepath; end

6335

if isempty( filepath), filepath=lastfilepath; end

6332

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6336

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6333

chdata(nxi).ext = fileext;

6337

chdata(nxi).ext = fileext;

6334

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6338

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6335

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6339

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6336

% chdata(nxi).A=param.a_fext;

6340

% chdata(nxi).A=param.a_fext;

6337

chdata(nxi).ftr=param.fb*param.f_f;

6341

chdata(nxi).ftr=param.fb*param.f_f;

6338

chdata(nxi).type='FEXT';

6342

chdata(nxi).type='FEXT';

6339

end

6343

end

6340

% now get NEXT file names into chdata structure

6344

% now get NEXT file names into chdata structure

6341

kxi=num_fext+kxi;

6345

kxi=num_fext+kxi;

6342

for nxi=kxi+1:num_next+kxi

6346

for nxi=kxi+1:num_next+kxi

6343

lastfilepath=filepath;

6347

lastfilepath=filepath;

6344

if size(file_list,2) ~= 0

6348

if size(file_list,2) ~= 0

6345

[filepath, basename, fileext]=fileparts(file_list{nxi});

6349

[filepath, basename, fileext]=fileparts(file_list{nxi});

6346

else

6350

else

6347

dir=fullfile(filepath, '*.s4p');

6351

dir=fullfile(filepath, '*.s4p');

6348

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6352

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6349

if filepath==0

6353

if filepath==0

6350

error('Not enough NEXT files')

6354

error('Not enough NEXT files')

6351

end

6355

end

6352

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6356

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6353

end

6357

end

6354

if isempty( filepath), filepath=lastfilepath; end

6358

if isempty( filepath), filepath=lastfilepath; end

6355

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6359

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6356

chdata(nxi).ext = fileext;

6360

chdata(nxi).ext = fileext;

6357

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6361

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6358

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6362

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6359

% chdata(nxi).A=param.A_next;

6363

% chdata(nxi).A=param.A_next;

6360

chdata(nxi).ftr=param.fb*param.f_n;

6364

chdata(nxi).ftr=param.fb*param.f_n;

6361

chdata(nxi).type='NEXT';

6365

chdata(nxi).type='NEXT';

6362

end

6366

end

6363

6367

6364

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6368

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6365

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6369

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6366

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6370

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6367

% H_r - receiver filter, Butterworth

6371

% H_r - receiver filter, Butterworth

6368

% H_ctf - total gain of CTLE and low freq filtering

6372

% H_ctf - total gain of CTLE and low freq filtering

6369

% H_dc - the common mode channel gain

6373

% H_dc - the common mode channel gain

6370

% param.eta_0 -input referred Rx noise

6374

% param.eta_0 -input referred Rx noise

6371

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6375

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6372

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6376

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6373

%% Equation 93A-35 - independent of FFE setting %%

6377

%% Equation 93A-35 - independent of FFE setting %%

6374

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6378

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6375

if sum(param.AC_CM_RMS) ~= 0

6379

if sum(param.AC_CM_RMS) ~= 0

6376

sigma_ACCM=0;

6380

sigma_ACCM=0;

6377

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6381

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6378

for i=1:length(chdata)

6382

for i=1:length(chdata)

6379

H_dc=abs(squeeze(chdata(i).sdc21));

6383

H_dc=abs(squeeze(chdata(i).sdc21));

6380

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6384

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6381

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6385

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6382

end

6386

end

6383

sigma_N=norm([sigma_N1,sigma_ACCM]);

6387

sigma_N=norm([sigma_N1,sigma_ACCM]);

6384

else

6388

else

6385

sigma_N=sigma_N1;

6389

sigma_N=sigma_N1;

6386

end

6390

end

6387

%%

6391

%%

6388

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6392

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6389

% for Rx calibratrion only

6393

% for Rx calibratrion only

6390

% the FEXT channel for calibration basically a DC connection unlike normal

6394

% the FEXT channel for calibration basically a DC connection unlike normal

6391

% FEXT channels which are nearly open at DC channels

6395

% FEXT channels which are nearly open at DC channels

6392

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6396

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6393

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6397

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6394

if size(chdata,2) >= 2

6398

if size(chdata,2) >= 2

6395

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6399

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6396

else

6400

else

6397

Hnoise_channel=1;

6401

Hnoise_channel=1;

6398

end

6402

end

6399

f=chdata(2).faxis;

6403

f=chdata(2).faxis;

6400

f_hp=param.f_hp;

6404

f_hp=param.f_hp;

6401

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6405

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6402

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6406

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6403

else

6407

else

6404

H_hp=ones(1,length(f));

6408

H_hp=ones(1,length(f));

6405

end

6409

end

6406

%% Equation 93A-47 or 162-12

6410

%% Equation 93A-47 or 162-12

6407

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6411

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6408

6412

6409

%% Equation 93A-48 or 162-14%%

6413

%% Equation 93A-48 or 162-14%%

6410

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6414

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6411

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6415

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6412

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6416

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6413

% Modified not to double count crosstalk: John Ewen 13/12/2018

6417

% Modified not to double count crosstalk: John Ewen 13/12/2018

6414

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6418

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6415

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6419

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6416

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6420

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6417

f=chdata(1).faxis;

6421

f=chdata(1).faxis;

6418

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6422

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6419

if(f(1)==0)

6423

if(f(1)==0)

6420

temp_angle(1)=1e-20;% we don't want to divide by zero

6424

temp_angle(1)=1e-20;% we don't want to divide by zero

6421

end

6425

end

6422

PWF_tx=ones(1,length(f));

6426

PWF_tx=ones(1,length(f));

6423

if max(upsampled_txffe) > 0

6427

if max(upsampled_txffe) > 0

6424

PWF_tx=zeros(1,length(f));

6428

PWF_tx=zeros(1,length(f));

6425

[mcur,icur] = max(upsampled_txffe);

6429

[mcur,icur] = max(upsampled_txffe);

6426

if exist('phase_memory','var') && ~isempty(phase_memory)

6430

if exist('phase_memory','var') && ~isempty(phase_memory)

6427

pre_calc=1;

6431

pre_calc=1;

6428

else

6432

else

6429

pre_calc=0;

6433

pre_calc=0;

6430

end

6434

end

6431

for ii=1:length(upsampled_txffe)

6435

for ii=1:length(upsampled_txffe)

6432

if upsampled_txffe(ii)==0

6436

if upsampled_txffe(ii)==0

6433

%speed up: skip cases when txffe=0

6437

%speed up: skip cases when txffe=0

6434

continue;

6438

continue;

6435

end

6439

end

6436

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6440

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6437

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6441

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6438

% that is needed

6442

% that is needed

6439

if ii==icur

6443

if ii==icur

6440

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6444

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6441

PWF_tx = PWF_tx + upsampled_txffe(ii);

6445

PWF_tx = PWF_tx + upsampled_txffe(ii);

6442

else

6446

else

6443

if pre_calc

6447

if pre_calc

6444

%speed up: avoid vector exp calculation by externally pre-calculating it

6448

%speed up: avoid vector exp calculation by externally pre-calculating it

6445

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6449

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6446

else

6450

else

6447

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6451

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6448

end

6452

end

6449

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6453

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6450

PWF_tx = PWF_tx + transpose(term_ii(:));

6454

PWF_tx = PWF_tx + transpose(term_ii(:));

6451

end

6455

end

6452

% /Adee

6456

% /Adee

6453

end

6457

end

6454

end

6458

end

6455

PWF_rx=ones(1,length(f));

6459

PWF_rx=ones(1,length(f));

6456

if exist('C','var')

6460

if exist('C','var')

6457

PWF_rx=zeros(1,length(f));

6461

PWF_rx=zeros(1,length(f));

6458

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6462

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6459

if C(ii+param.RxFFE_cmx+1)==0

6463

if C(ii+param.RxFFE_cmx+1)==0

6460

%speed up: skip cases when rxffe=0

6464

%speed up: skip cases when rxffe=0

6461

continue;

6465

continue;

6462

end

6466

end

6463

if ii+1==0

6467

if ii+1==0

6464

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6468

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6465

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6469

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6466

else

6470

else

6467

if pre_calc

6471

if pre_calc

6468

%speed up: avoid vector exp calculation by externally pre-calculating it

6472

%speed up: avoid vector exp calculation by externally pre-calculating it

6469

%The latter columns of phase_memory hold RXFFE shift vectors

6473

%The latter columns of phase_memory hold RXFFE shift vectors

6470

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6474

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6471

term_ii=transpose(term_ii);

6475

term_ii=transpose(term_ii);

6472

else

6476

else

6473

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6477

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6474

end

6478

end

6475

PWF_rx=PWF_rx+term_ii;

6479

PWF_rx=PWF_rx+term_ii;

6476

end

6480

end

6477

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6481

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6478

end

6482

end

6479

end

6483

end

6480

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6484

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6481

for ii=2:size(chdata,2)

6485

for ii=2:size(chdata,2)

6482

SINC = sin(temp_angle)./temp_angle;

6486

SINC = sin(temp_angle)./temp_angle;

6483

PWF_data=SINC.^2;

6487

PWF_data=SINC.^2;

6484

PWF=PWF_data.*PWF_rx; % power weight function

6488

PWF=PWF_data.*PWF_rx; % power weight function

6485

PWFnext=abs(PWF);

6489

PWFnext=abs(PWF);

6486

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6490

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6487

PWFfext=abs(PWF);

6491

PWFfext=abs(PWF);

6488

if isequal(chdata(ii).type, 'FEXT')

6492

if isequal(chdata(ii).type, 'FEXT')

6489

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6493

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6490

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6494

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6491

elseif isequal(chdata(ii).type, 'NEXT')

6495

elseif isequal(chdata(ii).type, 'NEXT')

6492

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6496

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6493

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6497

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6494

end

6498

end

6495

end

6499

end

6496

if nargout == 1 && isequal(type,'NEXT')

6500

if nargout == 1 && isequal(type,'NEXT')

6497

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6501

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6498

elseif nargout == 1 && isequal(type,'FEXT')

6502

elseif nargout == 1 && isequal(type,'FEXT')

6499

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6503

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6500

elseif nargout == 3

6504

elseif nargout == 3

6501

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6505

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6502

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6506

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6503

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6507

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6504

end

6508

end

6505

6509

6506

function out=hrem(h,index,N_bf,bmaxg)

6510

function out=hrem(h,index,N_bf,bmaxg)

6507

6511

6508

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6512

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6509

% faster than single line function

6513

% faster than single line function

6510

% hrem =@(h,index,N_bf,bmaxg) ...

6514

% hrem =@(h,index,N_bf,bmaxg) ...

6511

% [ h(1:index-1) ...

6515

% [ h(1:index-1) ...

6512

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6516

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6513

% h(index+N_bf:end) ]...

6517

% h(index+N_bf:end) ]...

6514

% ;

6518

% ;

6515

6519

6516

%% floating DFE taps

6520

%% floating DFE taps

6517

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6521

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6518

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6522

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6519

% Sout = interp_Sparam(Sin,fin,fout)

6523

% Sout = interp_Sparam(Sin,fin,fout)

6520

%

6524

%

6521

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6525

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6522

% fout.

6526

% fout.

6523

6527

6524

if ( fin(end)<fout(end) )

6528

if ( fin(end)<fout(end) )

6525

% warning('Channel high frequencies extrapolation might be inaccurate!');

6529

% warning('Channel high frequencies extrapolation might be inaccurate!');

6526

end

6530

end

6527

6531

6528

H_mag = abs(Sin);

6532

H_mag = abs(Sin);

6529

H_mag(H_mag<eps)=eps; % handle ill cases...

6533

H_mag(H_mag<eps)=eps; % handle ill cases...

6530

H_ph = unwrap(angle(Sin));

6534

H_ph = unwrap(angle(Sin));

6531

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6535

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6532

% user ignore that.

6536

% user ignore that.

6533

if mean(diff(H_ph))>0

6537

if mean(diff(H_ph))>0

6534

if OP.DEBUG

6538

if OP.DEBUG

6535

warning('Anti-causal response found. Finer frequency step is required for this channel');

6539

warning('Anti-causal response found. Finer frequency step is required for this channel');

6536

else

6540

else

6537

error('Anti-causal response found. Finer frequency step is required for this channel');

6541

error('Anti-causal response found. Finer frequency step is required for this channel');

6538

end

6542

end

6539

end

6543

end

6540

6544

6541

%opt_interp_Sparam_mag='linear_trend_to_DC';

6545

%opt_interp_Sparam_mag='linear_trend_to_DC';

6542

switch opt_interp_Sparam_mag

6546

switch opt_interp_Sparam_mag

6543

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6547

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6544

if -iscolumn(H_mag), H_mag=H_mag.';end

6548

if -iscolumn(H_mag), H_mag=H_mag.';end

6545

if -iscolumn(fin), fin=fin.';end

6549

if -iscolumn(fin), fin=fin.';end

6546

fin_x=fin;

6550

fin_x=fin;

6547

H_mag_x=H_mag(:);

6551

H_mag_x=H_mag(:);

6548

if fin(1)>0

6552

if fin(1)>0

6549

p=polyfit(fin(1:10), H_mag(1:10), 1);

6553

p=polyfit(fin(1:10), H_mag(1:10), 1);

6550

dc_trend_val=polyval(p, 0);

6554

dc_trend_val=polyval(p, 0);

6551

fin_x=[0, fin_x];

6555

fin_x=[0, fin_x];

6552

H_mag_x = [dc_trend_val; H_mag_x];

6556

H_mag_x = [dc_trend_val; H_mag_x];

6553

end

6557

end

6554

if fin(end)<fout(end)

6558

if fin(end)<fout(end)

6555

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6559

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6556

mid_freq_ind=round(length(fin)/2);

6560

mid_freq_ind=round(length(fin)/2);

6557

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6561

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6558

warning(warn_state);

6562

warning(warn_state);

6559

hf_trend_val=polyval(p, fout(end));

6563

hf_trend_val=polyval(p, fout(end));

6560

if hf_trend_val>H_mag(end)

6564

if hf_trend_val>H_mag(end)

6561

hf_trend_val=H_mag(end);

6565

hf_trend_val=H_mag(end);

6562

hf_logtrend_val = H_mag(end);

6566

hf_logtrend_val = H_mag(end);

6563

elseif hf_trend_val<eps

6567

elseif hf_trend_val<eps

6564

hf_trend_val=eps;

6568

hf_trend_val=eps;

6565

hf_logtrend_val = realmin;

6569

hf_logtrend_val = realmin;

6566

end

6570

end

6567

fin_x=[fin_x, fout(end)];

6571

fin_x=[fin_x, fout(end)];

6568

H_mag_x = [H_mag_x; hf_trend_val];

6572

H_mag_x = [H_mag_x; hf_trend_val];

6569

end

6573

end

6570

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6574

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6571

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6575

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6572

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6576

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6573

indx = find(fout > fin(end),1,'first');

6577

indx = find(fout > fin(end),1,'first');

6574

H_mag_i(indx:end) = H_logmag_i(indx:end);

6578

H_mag_i(indx:end) = H_logmag_i(indx:end);

6575

end

6579

end

6576

case 'trend_to_DC'

6580

case 'trend_to_DC'

6577

% extrapolate to trend value at DC.

6581

% extrapolate to trend value at DC.

6578

if -iscolumn(H_mag), H_mag=H_mag.';end

6582

if -iscolumn(H_mag), H_mag=H_mag.';end

6579

if -iscolumn(fin), fin=fin.';end

6583

if -iscolumn(fin), fin=fin.';end

6580

fin_x=fin;

6584

fin_x=fin;

6581

H_mag_x=H_mag;

6585

H_mag_x=H_mag;

6582

if fin(1)>0

6586

if fin(1)>0

6583

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6587

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6584

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6588

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6585

dc_trend_val=10^polyval(p, 0);

6589

dc_trend_val=10^polyval(p, 0);

6586

fin_x=[0, fin_x];

6590

fin_x=[0, fin_x];

6587

H_mag_x = [dc_trend_val H_mag_x];

6591

H_mag_x = [dc_trend_val H_mag_x];

6588

end

6592

end

6589

if fin(end)<fout(end)

6593

if fin(end)<fout(end)

6590

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6594

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6591

mid_freq_ind=round(length(fin)/2);

6595

mid_freq_ind=round(length(fin)/2);

6592

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6596

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6593

warning(warn_state);

6597

warning(warn_state);

6594

hf_trend_val=10^polyval(p, fout(end));

6598

hf_trend_val=10^polyval(p, fout(end));

6595

if hf_trend_val>H_mag(end)

6599

if hf_trend_val>H_mag(end)

6596

hf_trend_val=H_mag(end);

6600

hf_trend_val=H_mag(end);

6597

end

6601

end

6598

fin_x=[fin_x, fout(end)];

6602

fin_x=[fin_x, fout(end)];

6599

H_mag_x = [H_mag_x hf_trend_val];

6603

H_mag_x = [H_mag_x hf_trend_val];

6600

end

6604

end

6601

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6605

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6602

case 'extrap_to_DC_or_zero'

6606

case 'extrap_to_DC_or_zero'

6603

% same as extrap_to_DC but detect AC-coupled channels and

6607

% same as extrap_to_DC but detect AC-coupled channels and

6604

% extrapolate them to 0.

6608

% extrapolate them to 0.

6605

if fin(1)>0 && 20*log10(H_mag(1))<-20

6609

if fin(1)>0 && 20*log10(H_mag(1))<-20

6606

% assume AC coupling, with 0 at DC

6610

% assume AC coupling, with 0 at DC

6607

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6611

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6608

else

6612

else

6609

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6613

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6610

end

6614

end

6611

H_mag_i(fout>fin(end)) = H_mag(end);

6615

H_mag_i(fout>fin(end)) = H_mag(end);

6612

case 'extrap_to_DC'

6616

case 'extrap_to_DC'

6613

% first extrapolate down to DC, then use highest available frequency

6617

% first extrapolate down to DC, then use highest available frequency

6614

% for higher frequencies

6618

% for higher frequencies

6615

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6619

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6616

H_mag_i(fout>fin(end)) = H_mag(end);

6620

H_mag_i(fout>fin(end)) = H_mag(end);

6617

case 'old'

6621

case 'old'

6618

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6622

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6619

otherwise

6623

otherwise

6620

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6624

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6621

end

6625

end

6622

6626

6623

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6627

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6624

6628

6625

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6629

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6626

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6630

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6627

switch opt_interp_Sparam_phase

6631

switch opt_interp_Sparam_phase

6628

case 'old'

6632

case 'old'

6629

H_ph_i = H_ph_i-H_ph_i(1);

6633

H_ph_i = H_ph_i-H_ph_i(1);

6630

case 'zero_DC'

6634

case 'zero_DC'

6631

H_ph_i(1) = 0;

6635

H_ph_i(1) = 0;

6632

case 'interp_to_DC'

6636

case 'interp_to_DC'

6633

if fin(1) ~= 0

6637

if fin(1) ~= 0

6634

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6638

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6635

end

6639

end

6636

case 'extrap_cubic_to_dc_linear_to_inf'

6640

case 'extrap_cubic_to_dc_linear_to_inf'

6637

if fin(1) ~= 0

6641

if fin(1) ~= 0

6638

% estimate low frequency group delay

6642

% estimate low frequency group delay

6639

group_delay = -diff(H_ph(:))./diff(fin(:));

6643

group_delay = -diff(H_ph(:))./diff(fin(:));

6640

low_freq_gd = group_delay(1:50);

6644

low_freq_gd = group_delay(1:50);

6641

% calculate trend, throwing away outliers

6645

% calculate trend, throwing away outliers

6642

m = median(low_freq_gd); sigma = std(low_freq_gd);

6646

m = median(low_freq_gd); sigma = std(low_freq_gd);

6643

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6647

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6644

% correct outliers in first 10 phase samples

6648

% correct outliers in first 10 phase samples

6645

for k=10:-1:1

6649

for k=10:-1:1

6646

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6650

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6647

end

6651

end

6648

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6652

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6649

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6653

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6650

% modification - trend to inf

6654

% modification - trend to inf

6651

if (1)

6655

if (1)

6652

high_freq_gd = group_delay(end-50:end);

6656

high_freq_gd = group_delay(end-50:end);

6653

% calculate trend, throwing away outliers

6657

% calculate trend, throwing away outliers

6654

m = median(high_freq_gd); sigma = std(high_freq_gd);

6658

m = median(high_freq_gd); sigma = std(high_freq_gd);

6655

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6659

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6656

hf_extrap_range = find(fout>fin(end));

6660

hf_extrap_range = find(fout>fin(end));

6657

last_data_sample = hf_extrap_range(1)-1;

6661

last_data_sample = hf_extrap_range(1)-1;

6658

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6662

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6659

% for k=hf_range

6663

% for k=hf_range

6660

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6664

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6661

% end

6665

% end

6662

end

6666

end

6663

6667

6664

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6668

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6665

H_ph_i=H_ph_cubic;

6669

H_ph_i=H_ph_cubic;

6666

H_ph_i(indx:end) = H_ph_linear(indx:end);

6670

H_ph_i(indx:end) = H_ph_linear(indx:end);

6667

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6671

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6668

end

6672

end

6669

case 'interp_and_shift_to_DC'

6673

case 'interp_and_shift_to_DC'

6670

if fin(1) ~= 0

6674

if fin(1) ~= 0

6671

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6675

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6672

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6676

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6673

end

6677

end

6674

case 'trend_and_shift_to_DC'

6678

case 'trend_and_shift_to_DC'

6675

% estimate low frequency group delay

6679

% estimate low frequency group delay

6676

group_delay = -diff(H_ph(:))./diff(fin(:));

6680

group_delay = -diff(H_ph(:))./diff(fin(:));

6677

low_freq_gd = group_delay(1:50);

6681

low_freq_gd = group_delay(1:50);

6678

% calculate trend, throwing away outliers

6682

% calculate trend, throwing away outliers

6679

m = median(low_freq_gd); sigma = std(low_freq_gd);

6683

m = median(low_freq_gd); sigma = std(low_freq_gd);

6680

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6684

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6681

fin_x=fin;

6685

fin_x=fin;

6682

H_ph_x=H_ph(:);

6686

H_ph_x=H_ph(:);

6683

if fin(1) ~= 0

6687

if fin(1) ~= 0

6684

% correct outliers in first 10 phase samples

6688

% correct outliers in first 10 phase samples

6685

for k=10:-1:1

6689

for k=10:-1:1

6686

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6690

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6687

end

6691

end

6688

6692

6689

% shift all phase data so that DC extrapolation to 0 follows trend

6693

% shift all phase data so that DC extrapolation to 0 follows trend

6690

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6694

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6691

fin_x=[0, fin_x];

6695

fin_x=[0, fin_x];

6692

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6696

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6693

end

6697

end

6694

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6698

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6695

% the last two samples, so noise can create an inverted slope and

6699

% the last two samples, so noise can create an inverted slope and

6696

% non-causal response).

6700

% non-causal response).

6697

if fout(end)>fin(end)

6701

if fout(end)>fin(end)

6698

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6702

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6699

% p=polyfit(fin_x', H_ph_x, 1);

6703

% p=polyfit(fin_x', H_ph_x, 1);

6700

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6704

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6701

% hf_phase_trend=polyval(p,max(fout));

6705

% hf_phase_trend=polyval(p,max(fout));

6702

fin_x=[fin_x, fout(end)];

6706

fin_x=[fin_x, fout(end)];

6703

H_ph_x=[H_ph_x; hf_phase_trend];

6707

H_ph_x=[H_ph_x; hf_phase_trend];

6704

end

6708

end

6705

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6709

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6706

6710

6707

otherwise

6711

otherwise

6708

error('COM:Extrap:InvalidOption', ...

6712

error('COM:Extrap:InvalidOption', ...

6709

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6713

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6710

end

6714

end

6711

H_i = H_mag_i.*exp(1j*H_ph_i);

6715

H_i = H_mag_i.*exp(1j*H_ph_i);

6712

Sout=H_i;

6716

Sout=H_i;

6713

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6717

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6714

6718

6715

%This function makes the TX or RX package. The type input must be

6719

%This function makes the TX or RX package. The type input must be

6716

%'TX' or 'RX'

6720

%'TX' or 'RX'

6717

%If the mode argument is omitted, mode='dd' is assumed. Currently

6721

%If the mode argument is omitted, mode='dd' is assumed. Currently

6718

%mode='dc' is only used when making the TX package for AC CM noise

6722

%mode='dc' is only used when making the TX package for AC CM noise

6719

%inclusion. The Rx package for 'dc' mode is still generated using

6723

%inclusion. The Rx package for 'dc' mode is still generated using

6720

%the same parameters as 'dd' mode

6724

%the same parameters as 'dd' mode

6721

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6725

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6722

%

6726

%

6723

%One instance of package block looks like this (if no elements are set to 0):

6727

%One instance of package block looks like this (if no elements are set to 0):

6724

%-------------Lcomp----------Tline---------------

6728

%-------------Lcomp----------Tline---------------

6725

% | | |

6729

% | | |

6726

% Cpad Cbump Cball

6730

% Cpad Cbump Cball

6727

% | | |

6731

% | | |

6728

%------------------------------------------------

6732

%------------------------------------------------

6729

6733

6730

if nargin<6

6734

if nargin<6

6731

%optional input "include_die"=0 allows die parameters to be forced to 0

6735

%optional input "include_die"=0 allows die parameters to be forced to 0

6732

%this includes Cpad, Lcomp, and Cbump

6736

%this includes Cpad, Lcomp, and Cbump

6733

include_die=1;

6737

include_die=1;

6734

end

6738

end

6735

if nargin<5

6739

if nargin<5

6736

mode='dd';

6740

mode='dd';

6737

end

6741

end

6738

6742

6739

6743

6740

if ~isempty(param.PKG_NAME)

6744

if ~isempty(param.PKG_NAME)

6741

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6745

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6742

%so they are swapped in depending on if Tx or Rx is set for type

6746

%so they are swapped in depending on if Tx or Rx is set for type

6743

%Note that param is not returned from this function, so the swap does not persist

6747

%Note that param is not returned from this function, so the swap does not persist

6744

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6748

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6745

if strcmpi(type,'tx')

6749

if strcmpi(type,'tx')

6746

pkg_name = param.PKG_NAME{1};

6750

pkg_name = param.PKG_NAME{1};

6747

elseif strcmpi(type,'rx')

6751

elseif strcmpi(type,'rx')

6748

pkg_name = param.PKG_NAME{2};

6752

pkg_name = param.PKG_NAME{2};

6749

else

6753

else

6750

error('Pkg type must be Tx or Rx');

6754

error('Pkg type must be Tx or Rx');

6751

end

6755

end

6752

pkg_parameter_struct = param.PKG.(pkg_name);

6756

pkg_parameter_struct = param.PKG.(pkg_name);

6753

6757

6754

6758

6755

for j=1:length(swap_fields)

6759

for j=1:length(swap_fields)

6756

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6760

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6757

end

6761

end

6758

6762

6759

end

6763

end

6760

6764

6761

C_diepad = param.C_diepad;

6765

C_diepad = param.C_diepad;

6762

C_pkg_board = param.C_pkg_board;

6766

C_pkg_board = param.C_pkg_board;

6763

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6767

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6764

L_comp = param.L_comp;

6768

L_comp = param.L_comp;

6765

C_bump = param.C_bump;

6769

C_bump = param.C_bump;

6766

if ~include_die

6770

if ~include_die

6767

%best to multiply by 0. that way vectors maintain original size

6771

%best to multiply by 0. that way vectors maintain original size

6768

C_diepad=C_diepad*0;

6772

C_diepad=C_diepad*0;

6769

L_comp=L_comp*0;

6773

L_comp=L_comp*0;

6770

C_bump=C_bump*0;

6774

C_bump=C_bump*0;

6771

end

6775

end

6772

% [ahealey] End of modifications.

6776

% [ahealey] End of modifications.

6773

% generate TX package according to channel type.

6777

% generate TX package according to channel type.

6774

[ncases, mele]=size(param.z_p_next_cases);

6778

[ncases, mele]=size(param.z_p_next_cases);

6775

6779

6776

%Syntax update for C_diepad and L_comp

6780

%Syntax update for C_diepad and L_comp

6777

%Allow a chain of values to be entered as a matrix:

6781

%Allow a chain of values to be entered as a matrix:

6778

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6782

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6779

if isvector(C_diepad)

6783

if isvector(C_diepad)

6780

Cd_Tx=C_diepad(1);

6784

Cd_Tx=C_diepad(1);

6781

Cd_Rx=C_diepad(2);

6785

Cd_Rx=C_diepad(2);

6782

L_comp_Tx=L_comp(1);

6786

L_comp_Tx=L_comp(1);

6783

L_comp_Rx=L_comp(2);

6787

L_comp_Rx=L_comp(2);

6784

num_blocks=mele;

6788

num_blocks=mele;

6785

else

6789

else

6786

Cd_Tx=C_diepad(1,:);

6790

Cd_Tx=C_diepad(1,:);

6787

Cd_Rx=C_diepad(2,:);

6791

Cd_Rx=C_diepad(2,:);

6788

L_comp_Tx=L_comp(1,:);

6792

L_comp_Tx=L_comp(1,:);

6789

L_comp_Rx=L_comp(2,:);

6793

L_comp_Rx=L_comp(2,:);

6790

num_blocks=mele+length(Cd_Tx)-1;

6794

num_blocks=mele+length(Cd_Tx)-1;

6791

end

6795

end

6792

extra_LC=length(Cd_Tx)-1;

6796

extra_LC=length(Cd_Tx)-1;

6793

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6797

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6794

insert_zeros=zeros([1 extra_LC]);

6798

insert_zeros=zeros([1 extra_LC]);

6795

6799

6796

%Updated technique of building Tx/Rx packages

6800

%Updated technique of building Tx/Rx packages

6797

%each index corresponds to the package segment

6801

%each index corresponds to the package segment

6798

switch type

6802

switch type

6799

case 'TX'

6803

case 'TX'

6800

switch mele

6804

switch mele

6801

case 1

6805

case 1

6802

Cpad=Cd_Tx;

6806

Cpad=Cd_Tx;

6803

Lcomp=L_comp_Tx;

6807

Lcomp=L_comp_Tx;

6804

Cbump=C_bump(1);

6808

Cbump=C_bump(1);

6805

Cball=C_pkg_board(1);

6809

Cball=C_pkg_board(1);

6806

Zpkg=param.pkg_Z_c(1);

6810

Zpkg=param.pkg_Z_c(1);

6807

case 4

6811

case 4

6808

Cpad=[Cd_Tx 0 0 0];

6812

Cpad=[Cd_Tx 0 0 0];

6809

Lcomp=[L_comp_Tx 0 0 0];

6813

Lcomp=[L_comp_Tx 0 0 0];

6810

Cbump=[C_bump(1) 0 0 0];

6814

Cbump=[C_bump(1) 0 0 0];

6811

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6815

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6812

Zpkg=param.pkg_Z_c(1,:);

6816

Zpkg=param.pkg_Z_c(1,:);

6813

otherwise

6817

otherwise

6814

error('package syntax error')

6818

error('package syntax error')

6815

end

6819

end

6816

switch upper(channel_type)

6820

switch upper(channel_type)

6817

case 'THRU'

6821

case 'THRU'

6818

Len=param.Pkg_len_TX;

6822

Len=param.Pkg_len_TX;

6819

case 'NEXT'

6823

case 'NEXT'

6820

Len=param.Pkg_len_NEXT;

6824

Len=param.Pkg_len_NEXT;

6821

case 'FEXT'

6825

case 'FEXT'

6822

Len=param.Pkg_len_FEXT;

6826

Len=param.Pkg_len_FEXT;

6823

end

6827

end

6824

case 'RX'

6828

case 'RX'

6825

switch mele

6829

switch mele

6826

case 1

6830

case 1

6827

Cpad=Cd_Rx;

6831

Cpad=Cd_Rx;

6828

Lcomp=L_comp_Rx;

6832

Lcomp=L_comp_Rx;

6829

Cbump=C_bump(2);

6833

Cbump=C_bump(2);

6830

Cball=C_pkg_board(2);

6834

Cball=C_pkg_board(2);

6831

Zpkg=param.pkg_Z_c(2);

6835

Zpkg=param.pkg_Z_c(2);

6832

case 4

6836

case 4

6833

Cpad=[Cd_Rx 0 0 0];

6837

Cpad=[Cd_Rx 0 0 0];

6834

Lcomp=[L_comp_Rx 0 0 0];

6838

Lcomp=[L_comp_Rx 0 0 0];

6835

Cbump=[C_bump(2) 0 0 0];

6839

Cbump=[C_bump(2) 0 0 0];

6836

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6840

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6837

Zpkg=param.pkg_Z_c(2,:);

6841

Zpkg=param.pkg_Z_c(2,:);

6838

otherwise

6842

otherwise

6839

error('package syntax error')

6843

error('package syntax error')

6840

end

6844

end

6841

switch upper(channel_type)

6845

switch upper(channel_type)

6842

case 'THRU'

6846

case 'THRU'

6843

Len=param.Pkg_len_RX;

6847

Len=param.Pkg_len_RX;

6844

case 'NEXT'

6848

case 'NEXT'

6845

Len=param.Pkg_len_RX;

6849

Len=param.Pkg_len_RX;

6846

case 'FEXT'

6850

case 'FEXT'

6847

Len=param.Pkg_len_RX;

6851

Len=param.Pkg_len_RX;

6848

end

6852

end

6849

end

6853

end

6850

6854

6851

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6855

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6852

Cball=[insert_zeros Cball];

6856

Cball=[insert_zeros Cball];

6853

Cbump=[insert_zeros Cbump];

6857

Cbump=[insert_zeros Cbump];

6854

Len=[insert_zeros Len];

6858

Len=[insert_zeros Len];

6855

Zpkg=[insert_zeros Zpkg];

6859

Zpkg=[insert_zeros Zpkg];

6856

6860

6857

% debug_string='';

6861

% debug_string='';

6858

% for j=1:length(Zpkg)

6862

% for j=1:length(Zpkg)

6859

% if Cpad(j)~=0

6863

% if Cpad(j)~=0

6860

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6864

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6861

% end

6865

% end

6862

% if Lcomp(j)~=0

6866

% if Lcomp(j)~=0

6863

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6867

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6864

% end

6868

% end

6865

% if Cbump(j)~=0

6869

% if Cbump(j)~=0

6866

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6870

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6867

% end

6871

% end

6868

% if Len(j)~=0

6872

% if Len(j)~=0

6869

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6873

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6870

% end

6874

% end

6871

% if Cball(j)~=0

6875

% if Cball(j)~=0

6872

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6876

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6873

% end

6877

% end

6874

% end

6878

% end

6875

% if length(debug_string)>2

6879

% if length(debug_string)>2

6876

% debug_string=debug_string(3:end);

6880

% debug_string=debug_string(3:end);

6877

% end

6881

% end

6878

6882

6879

% tx package

6883

% tx package

6880

pkg_param=param;

6884

pkg_param=param;

6881

if strcmpi(mode,'dc')

6885

if strcmpi(mode,'dc')

6882

% change tx package to CC mode

6886

% change tx package to CC mode

6883

pkg_param.Z0=pkg_param.Z0/2;

6887

pkg_param.Z0=pkg_param.Z0/2;

6884

Cpad=Cpad*2;

6888

Cpad=Cpad*2;

6885

Cball=Cball*2;

6889

Cball=Cball*2;

6886

Zpkg=Zpkg*2;

6890

Zpkg=Zpkg*2;

6887

Lcomp=Lcomp/2;

6891

Lcomp=Lcomp/2;

6888

Cbump=Cbump*2;

6892

Cbump=Cbump*2;

6889

end

6893

end

6890

switch num_blocks

6894

switch num_blocks

6891

case 1

6895

case 1

6892

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6896

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6893

otherwise

6897

otherwise

6894

for j=1:num_blocks

6898

for j=1:num_blocks

6895

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6899

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6896

if j==1

6900

if j==1

6897

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6901

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6898

else

6902

else

6899

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6903

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6900

end

6904

end

6901

end

6905

end

6902

end

6906

end

6903

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6907

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6904

f(f<eps)=eps;

6908

f(f<eps)=eps;

6905

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6909

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6906

%% Equation 93A-8

6910

%% Equation 93A-8

6907

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6911

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6908

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6912

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6909

6913

6910

% [ahealey] Add compensating L and shunt C (bump) when requested.

6914

% [ahealey] Add compensating L and shunt C (bump) when requested.

6911

s12pad = s21pad;

6915

s12pad = s21pad;

6912

s22pad = s11pad;

6916

s22pad = s11pad;

6913

if nargin > 6

6917

if nargin > 6

6914

lcomp = varargin{1};

6918

lcomp = varargin{1};

6915

if lcomp>0

6919

if lcomp>0

6916

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6920

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6917

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6921

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6918

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6922

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6919

s11pad, s12pad, s21pad, s22pad, ...

6923

s11pad, s12pad, s21pad, s22pad, ...

6920

s11comp, s21comp, s21comp, s11comp);

6924

s11comp, s21comp, s21comp, s11comp);

6921

end

6925

end

6922

end

6926

end

6923

if nargin > 7

6927

if nargin > 7

6924

cbump = varargin{2};

6928

cbump = varargin{2};

6925

if cbump>0

6929

if cbump>0

6926

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6930

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6927

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6931

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6928

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6932

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6929

s11pad, s12pad, s21pad, s22pad, ...

6933

s11pad, s12pad, s21pad, s22pad, ...

6930

s11bump, s21bump, s21bump, s11bump);

6934

s11bump, s21bump, s21bump, s11bump);

6931

end

6935

end

6932

end

6936

end

6933

% [ahealey] End of modifications.

6937

% [ahealey] End of modifications.

6934

6938

6935

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6939

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6936

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6940

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6937

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6941

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6938

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6942

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6939

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6943

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6940

s11pad, s12pad, s21pad, s22pad, ...

6944

s11pad, s12pad, s21pad, s22pad, ...

6941

S11, S21, S21, S11);

6945

S11, S21, S21, S11);

6942

% [ahealey] End of modifications.

6946

% [ahealey] End of modifications.

6943

6947

6944

%% Equation 93A-8

6948

%% Equation 93A-8

6945

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6949

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6946

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6950

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6947

[ s11out, s12out, s21out, s22out ]= ...

6951

[ s11out, s12out, s21out, s22out ]= ...

6948

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6952

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6949

6953

6950

function missingParameter (parameterName)

6954

function missingParameter (parameterName)

6951

error( 'error:badParameterInformation', ...

6955

error( 'error:badParameterInformation', ...

6952

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6956

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6953

6957

6954

function pdf = normal_dist(sigma,nsigma,binsize)

6958

function pdf = normal_dist(sigma,nsigma,binsize)

6955

pdf.BinSize=binsize;

6959

pdf.BinSize=binsize;

6956

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6960

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6957

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6961

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6958

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6962

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6959

pdf.y=pdf.y/sum(pdf.y);

6963

pdf.y=pdf.y/sum(pdf.y);

6960

6964

6961

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6965

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6962

%% input

6966

%% input

6963

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6967

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6964

% baud_rate - baud rate in seconds

6968

% baud_rate - baud rate in seconds

6965

% param.samples_per_ui = samples per UI of IR

6969

% param.samples_per_ui = samples per UI of IR

6966

% param.max_ctle - maximum ac to dc gain in dB

6970

% param.max_ctle - maximum ac to dc gain in dB

6967

% param.tx_ffe(1) - maximum pre cursor (positive value)

6971

% param.tx_ffe(1) - maximum pre cursor (positive value)

6968

% param.tx_ffe(2) - maximum post cursor (positive value)

6972

% param.tx_ffe(2) - maximum post cursor (positive value)

6969

% param.tx_ffe_step - sweep step size for tx pre and post taps

6973

% param.tx_ffe_step - sweep step size for tx pre and post taps

6970

% param.ndfe - number of reference dfe taps

6974

% param.ndfe - number of reference dfe taps

6971

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6975

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6972

% output

6976

% output

6973

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6977

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6974

% result.eq.ctle - index of CTLE parameters in table

6978

% result.eq.ctle - index of CTLE parameters in table

6975

% result.IR - impulse response

6979

% result.IR - impulse response

6976

% result.avail_signal - maximum signal after equalization

6980

% result.avail_signal - maximum signal after equalization

6977

% result.avail_sig_index - index in result.IR of max signal

6981

% result.avail_sig_index - index in result.IR of max signal

6978

% result.best_FOM - best raw ISI

6982

% result.best_FOM - best raw ISI

6979

6983

6980

min_number_of_UI_in_response=40;

6984

min_number_of_UI_in_response=40;

6981

baud_rate=1/param.ui;

6985

baud_rate=1/param.ui;

6982

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6986

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6983

f=chdata(1).faxis;

6987

f=chdata(1).faxis;

6984

6988

6985

%Read user input of ts_sample_adj_range

6989

%Read user input of ts_sample_adj_range

6986

%if one value was entered, go from 0 to that value

6990

%if one value was entered, go from 0 to that value

6987

%if 2 values were entered, go from the 1st value to the 2nd value

6991

%if 2 values were entered, go from the 1st value to the 2nd value

6988

if length(param.ts_sample_adj_range)==1

6992

if length(param.ts_sample_adj_range)==1

6989

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6993

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6990

param.ts_sample_adj_range(1)=0;

6994

param.ts_sample_adj_range(1)=0;

6991

end

6995

end

6992

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6996

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6993

6997

6994

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6998

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6995

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6999

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6996

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7000

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6997

% need to include H_RCos in noise and when computing the system ir for thru

7001

% need to include H_RCos in noise and when computing the system ir for thru

6998

% and crosstalk

7002

% and crosstalk

6999

H_r=H_bw.*H_bt.*H_RCos;

7003

H_r=H_bw.*H_bt.*H_RCos;

7000

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7004

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7001

% Get f vector from 0 to Fs/2-delta_f.

7005

% Get f vector from 0 to Fs/2-delta_f.

7002

N_fft_by2 = 512;

7006

N_fft_by2 = 512;

7003

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7007

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7004

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7008

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7005

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7009

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7006

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7010

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7007

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7011

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7008

%%

7012

%%

7009

7013

7010

% system noise H_sy PSD

7014

% system noise H_sy PSD

7011

if OP.USE_ETA0_PSD

7015

if OP.USE_ETA0_PSD

7012

fspike=1e9;

7016

fspike=1e9;

7013

% requires communication tool box if used

7017

% requires communication tool box if used

7014

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7018

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7015

else

7019

else

7016

H_sy=ones(1,length(chdata(1).faxis));

7020

H_sy=ones(1,length(chdata(1).faxis));

7017

end

7021

end

7018

7022

7019

%Build txffe values dynamically

7023

%Build txffe values dynamically

7020

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7024

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7021

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7025

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7022

%where <X> is any integer

7026

%where <X> is any integer

7023

param_fields=fieldnames(param);

7027

param_fields=fieldnames(param);

7024

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7028

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7025

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7029

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7026

num_taps=num_pre+num_post;

7030

num_taps=num_pre+num_post;

7027

cur=num_pre+1;

7031

cur=num_pre+1;

7028

%txffe_cell combines all the txffe values into a single cell array

7032

%txffe_cell combines all the txffe values into a single cell array

7029

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7033

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7030

txffe_cell=cell(1,num_taps);

7034

txffe_cell=cell(1,num_taps);

7031

for k=num_pre:-1:1

7035

for k=num_pre:-1:1

7032

idx=num_pre-k+1;

7036

idx=num_pre-k+1;

7033

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7037

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7034

txffe_cell{idx}=param.(this_tx_field);

7038

txffe_cell{idx}=param.(this_tx_field);

7035

end

7039

end

7036

for k=1:num_post

7040

for k=1:num_post

7037

idx=k+num_pre;

7041

idx=k+num_pre;

7038

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7042

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7039

txffe_cell{idx}=param.(this_tx_field);

7043

txffe_cell{idx}=param.(this_tx_field);

7040

end

7044

end

7041

%total number of txffe runs is the product of the lengths of each tap

7045

%total number of txffe runs is the product of the lengths of each tap

7042

txffe_lengths=cellfun('length',txffe_cell);

7046

txffe_lengths=cellfun('length',txffe_cell);

7043

if isempty(txffe_cell)

7047

if isempty(txffe_cell)

7044

num_txffe_runs=1;

7048

num_txffe_runs=1;

7045

else

7049

else

7046

num_txffe_runs=prod(txffe_lengths);

7050

num_txffe_runs=prod(txffe_lengths);

7047

end

7051

end

7048

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7052

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7049

%any tap with length=1 can be ignored

7053

%any tap with length=1 can be ignored

7050

%Also is statistically likely that taps with greater number of values

7054

%Also is statistically likely that taps with greater number of values

7051

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7055

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7052

txffe_sweep_indices=find(txffe_lengths>1);

7056

txffe_sweep_indices=find(txffe_lengths>1);

7053

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7057

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7054

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7058

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7055

num_txffe_sweep_indices=length(txffe_sweep_indices);

7059

num_txffe_sweep_indices=length(txffe_sweep_indices);

7056

7060

7057

gdc_values = param.ctle_gdc_values;

7061

gdc_values = param.ctle_gdc_values;

7058

Gffe_values = param.cursor_gain;

7062

Gffe_values = param.cursor_gain;

7059

switch param.CTLE_type

7063

switch param.CTLE_type

7060

case 'CL93'

7064

case 'CL93'

7061

case 'CL120d'

7065

case 'CL120d'

7062

g_DC_HP_values =param.g_DC_HP_values;

7066

g_DC_HP_values =param.g_DC_HP_values;

7063

case 'CL120e'

7067

case 'CL120e'

7064

f_HP_Z=param.f_HP_Z;

7068

f_HP_Z=param.f_HP_Z;

7065

f_HP_P=param.f_HP_P;

7069

f_HP_P=param.f_HP_P;

7066

7070

7067

end

7071

end

7068

best_ctle = [];

7072

best_ctle = [];

7069

best_FOM = -inf;

7073

best_FOM = -inf;

7070

best_txffe = [];

7074

best_txffe = [];

7071

delta_sbr = [];

7075

delta_sbr = [];

7072

PSD_results=[];

7076

PSD_results=[];

7073

MMSE_results=[];

7077

MMSE_results=[];

7074

best_bmax=param.bmax;

7078

best_bmax=param.bmax;

7075

%AJG021820

7079

%AJG021820

7076

best_bmin=param.bmin;

7080

best_bmin=param.bmin;

7077

h_J=[];

7081

h_J=[];

7078

pxi=0;

7082

pxi=0;

7079

if OP.DISPLAY_WINDOW

7083

if OP.DISPLAY_WINDOW

7080

hwaitbar=waitbar(0);

7084

hwaitbar=waitbar(0);

7081

else

7085

else

7082

fprintf('FOM search ');

7086

fprintf('FOM search ');

7083

end

7087

end

7084

FOM=0;

7088

FOM=0;

7085

if ~OP.RxFFE

7089

if ~OP.RxFFE

7086

Gffe_values=0;

7090

Gffe_values=0;

7087

end

7091

end

7088

param.ndfe_passed=param.ndfe;

7092

param.ndfe_passed=param.ndfe;

7089

old_loops=0;

7093

old_loops=0;

7090

new_loops=0;

7094

new_loops=0;

7091

7095

7092

%GDC Qual construction

7096

%GDC Qual construction

7093

gqual= param.gqual;

7097

gqual= param.gqual;

7094

g2qual=param.g2qual;

7098

g2qual=param.g2qual;

7095

if ~strcmp(param.CTLE_type,'CL120d')

7099

if ~strcmp(param.CTLE_type,'CL120d')

7096

qual=ones(1,length(gdc_values));

7100

qual=ones(1,length(gdc_values));

7097

else

7101

else

7098

if isempty(gqual) && isempty(g2qual)

7102

if isempty(gqual) && isempty(g2qual)

7099

qual=ones(length(g_DC_HP_values),length(gdc_values));

7103

qual=ones(length(g_DC_HP_values),length(gdc_values));

7100

else

7104

else

7101

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7105

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7102

7106

7103

%prepare gqual and g2qual

7107

%prepare gqual and g2qual

7104

[g2qual,si]=sort(g2qual,'descend');

7108

[g2qual,si]=sort(g2qual,'descend');

7105

gqual=gqual(si,:);

7109

gqual=gqual(si,:);

7106

tmp=g2qual;

7110

tmp=g2qual;

7107

g2qual=zeros(length(tmp),2);

7111

g2qual=zeros(length(tmp),2);

7108

for kk=1:length(tmp)

7112

for kk=1:length(tmp)

7109

if kk==1

7113

if kk==1

7110

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7114

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7111

else

7115

else

7112

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7116

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7113

end

7117

end

7114

gqual(kk,:)=sort(gqual(kk,:),'descend');

7118

gqual(kk,:)=sort(gqual(kk,:),'descend');

7115

end

7119

end

7116

7120

7117

%Qual Construction

7121

%Qual Construction

7118

for jj=1:length(g_DC_HP_values)

7122

for jj=1:length(g_DC_HP_values)

7119

for ii=1:length(gdc_values)

7123

for ii=1:length(gdc_values)

7120

for kk=1:size(gqual,1)

7124

for kk=1:size(gqual,1)

7121

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7125

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7122

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7126

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7123

qual(jj,ii)=1;

7127

qual(jj,ii)=1;

7124

break;

7128

break;

7125

end

7129

end

7126

end

7130

end

7127

end

7131

end

7128

end

7132

end

7129

end

7133

end

7130

end

7134

end

7131

end

7135

end

7132

7136

7133

progress_interval=0.025;

7137

progress_interval=0.025;

7134

if do_C2M

7138

if do_C2M

7135

loop_count=[1 2];

7139

loop_count=[1 2];

7136

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7140

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7137

T_O=max(0,T_O);

7141

T_O=max(0,T_O);

7138

else

7142

else

7139

loop_count=1;

7143

loop_count=1;

7140

T_O=0;

7144

T_O=0;

7141

end

7145

end

7142

switch param.CTLE_type

7146

switch param.CTLE_type

7143

case 'CL93'

7147

case 'CL93'

7144

lf_indx=1;

7148

lf_indx=1;

7145

case 'CL120d'

7149

case 'CL120d'

7146

lf_indx=length(g_DC_HP_values);

7150

lf_indx=length(g_DC_HP_values);

7147

case 'CL120e'

7151

case 'CL120e'

7148

lf_indx=1;

7152

lf_indx=1;

7149

end

7153

end

7150

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7154

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7151

if OP.Optimize_loop_speed_up == 1

7155

if OP.Optimize_loop_speed_up == 1

7152

OP.BinSize = 1e-4;

7156

OP.BinSize = 1e-4;

7153

OP.impulse_response_truncation_threshold = 1e-3;

7157

OP.impulse_response_truncation_threshold = 1e-3;

7154

end

7158

end

7155

7159

7156

%Used to speed up FFE by only performing circshift when necessary

7160

%Used to speed up FFE by only performing circshift when necessary

7157

pulse_struc(1).pulse_ctle_circshift=[];

7161

pulse_struc(1).pulse_ctle_circshift=[];

7158

ctle_response_updated=1;

7162

ctle_response_updated=1;

7159

7163

7160

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7164

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7161

calc_exp_phase=0;

7165

calc_exp_phase=0;

7162

7166

7163

%calculate cur index and pre/post indices outside of the loop

7167

%calculate cur index and pre/post indices outside of the loop

7164

cur_start=cur;

7168

cur_start=cur;

7165

precursor_indices=[];

7169

precursor_indices=[];

7166

postcursor_indices=[];

7170

postcursor_indices=[];

7167

auto_count_trigger=0;

7171

auto_count_trigger=0;

7168

for kv=1:num_taps

7172

for kv=1:num_taps

7169

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7173

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7170

%precursor values fill the beginning of the vector. Any empty precursor means

7174

%precursor values fill the beginning of the vector. Any empty precursor means

7171

%cursor position must be subtracted by 1

7175

%cursor position must be subtracted by 1

7172

if kv<cur_start

7176

if kv<cur_start

7173

cur=cur-1;

7177

cur=cur-1;

7174

end

7178

end

7175

else

7179

else

7176

%non empty value: add to precursor or postcursor indices depending on position

7180

%non empty value: add to precursor or postcursor indices depending on position

7177

%in the vector

7181

%in the vector

7178

if kv<cur_start

7182

if kv<cur_start

7179

auto_count_trigger=1;

7183

auto_count_trigger=1;

7180

precursor_indices=[precursor_indices kv];

7184

precursor_indices=[precursor_indices kv];

7181

else

7185

else

7182

auto_count_trigger=0;

7186

auto_count_trigger=0;

7183

postcursor_indices=[postcursor_indices kv];

7187

postcursor_indices=[postcursor_indices kv];

7184

end

7188

end

7185

end

7189

end

7186

end

7190

end

7187

if ~isempty(postcursor_indices)

7191

if ~isempty(postcursor_indices)

7188

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7192

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7189

end

7193

end

7190

7194

7191

%Calculate the full grid matrix of all txffe combinations

7195

%Calculate the full grid matrix of all txffe combinations

7192

if isempty(txffe_cell)

7196

if isempty(txffe_cell)

7193

TXFFE_grid=0;

7197

TXFFE_grid=0;

7194

FULL_tx_index_vector=1;

7198

FULL_tx_index_vector=1;

7195

else

7199

else

7196

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7200

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7197

%Also calculate the full grid matrix for the index used in each txffe combination

7201

%Also calculate the full grid matrix for the index used in each txffe combination

7198

%(the index is used in the LOCAL SEARCH block)

7202

%(the index is used in the LOCAL SEARCH block)

7199

for k=1:num_taps

7203

for k=1:num_taps

7200

txffe_index_cell{k}=1:txffe_lengths(k);

7204

txffe_index_cell{k}=1:txffe_lengths(k);

7201

end

7205

end

7202

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7206

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7203

end

7207

end

7204

7208

7205

%pre-calculate cursor to save time

7209

%pre-calculate cursor to save time

7206

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7210

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7207

7211

7208

%pre-calculate full txffe for each iteration to save time

7212

%pre-calculate full txffe for each iteration to save time

7209

precursor_matrix=TXFFE_grid(:,precursor_indices);

7213

precursor_matrix=TXFFE_grid(:,precursor_indices);

7210

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7214

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7211

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7215

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7212

7216

7213

if OP.TDMODE

7217

if OP.TDMODE

7214

uneq_field='uneq_pulse_response';

7218

uneq_field='uneq_pulse_response';

7215

ctle_field='ctle_pulse_response';

7219

ctle_field='ctle_pulse_response';

7216

else

7220

else

7217

uneq_field='uneq_imp_response';

7221

uneq_field='uneq_imp_response';

7218

ctle_field='ctle_imp_response';

7222

ctle_field='ctle_imp_response';

7219

end

7223

end

7220

7224

7221

%Speed up search for max(sbr)

7225

%Speed up search for max(sbr)

7222

if OP.TDMODE

7226

if OP.TDMODE

7223

[~,init_max]=max(chdata(1).uneq_pulse_response);

7227

[~,init_max]=max(chdata(1).uneq_pulse_response);

7224

else

7228

else

7225

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7229

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7226

end

7230

end

7227

UI_max_window=20;

7231

UI_max_window=20;

7228

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7232

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7229

if start_max_idx<1

7233

if start_max_idx<1

7230

start_max_idx=1;

7234

start_max_idx=1;

7231

end

7235

end

7232

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7236

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7233

if end_max_idx>length(chdata(1).(uneq_field))

7237

if end_max_idx>length(chdata(1).(uneq_field))

7234

end_max_idx=length(chdata(1).(uneq_field));

7238

end_max_idx=length(chdata(1).(uneq_field));

7235

end

7239

end

7236

7240

7237

itick_skips=0;

7241

itick_skips=0;

7238

itick_cases=0;

7242

itick_cases=0;

7239

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7243

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7240

for i=loop_count

7244

for i=loop_count

7241

7245

7242

for Gffe_index=1:length(Gffe_values)

7246

for Gffe_index=1:length(Gffe_values)

7243

param.current_ffegain=Gffe_values(Gffe_index);

7247

param.current_ffegain=Gffe_values(Gffe_index);

7244

for ctle_index=1:length(gdc_values)

7248

for ctle_index=1:length(gdc_values)

7245

g_dc = gdc_values(ctle_index);

7249

g_dc = gdc_values(ctle_index);

7246

kacdc = 10^(g_dc/20);

7250

kacdc = 10^(g_dc/20);

7247

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7251

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7248

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7252

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7249

CTLE_fz = param.CTLE_fz(ctle_index);

7253

CTLE_fz = param.CTLE_fz(ctle_index);

7250

switch param.CTLE_type

7254

switch param.CTLE_type

7251

case 'CL93'

7255

case 'CL93'

7252

%

7256

%

7253

case 'CL120d'

7257

case 'CL120d'

7254

%

7258

%

7255

case 'CL120e'

7259

case 'CL120e'

7256

HP_Z = param.f_HP_Z(ctle_index);

7260

HP_Z = param.f_HP_Z(ctle_index);

7257

HP_P = param.f_HP_P(ctle_index);

7261

HP_P = param.f_HP_P(ctle_index);

7258

end

7262

end

7259

%% HF Boost

7263

%% HF Boost

7260

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7264

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7261

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7265

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7262

%% Mid Frequency Boost

7266

%% Mid Frequency Boost

7263

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7267

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7264

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7268

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7265

for g_LP_index=1:lf_indx

7269

for g_LP_index=1:lf_indx

7266

7270

7267

%GDC Qual Check

7271

%GDC Qual Check

7268

if qual(g_LP_index,ctle_index)==0

7272

if qual(g_LP_index,ctle_index)==0

7269

pxi=pxi+num_txffe_runs;

7273

pxi=pxi+num_txffe_runs;

7270

continue;

7274

continue;

7271

end

7275

end

7272

7276

7273

switch param.CTLE_type

7277

switch param.CTLE_type

7274

case 'CL93'

7278

case 'CL93'

7275

H_low=1;

7279

H_low=1;

7276

kacde_DC_low=1;

7280

kacde_DC_low=1;

7277

case 'CL120d'

7281

case 'CL120d'

7278

g_DC_low = g_DC_HP_values(g_LP_index);

7282

g_DC_low = g_DC_HP_values(g_LP_index);

7279

f_HP=param.f_HP(g_LP_index);

7283

f_HP=param.f_HP(g_LP_index);

7280

kacde_DC_low = 10^(g_DC_low/20);

7284

kacde_DC_low = 10^(g_DC_low/20);

7281

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7285

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7282

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7286

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7283

case 'CL120e' % z1 has been adusted on read in

7287

case 'CL120e' % z1 has been adusted on read in

7284

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7288

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7285

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7289

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7286

end

7290

end

7287

H_ctf=H_low.*ctle_gain;

7291

H_ctf=H_low.*ctle_gain;

7288

switch upper(OP.FFE_OPT_METHOD)

7292

switch upper(OP.FFE_OPT_METHOD)

7289

case 'WIENER-HOPF'

7293

case 'WIENER-HOPF'

7290

%% Bill Kirkland

7294

%% Bill Kirkland

7291

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7295

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7292

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7296

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7293

% use Fourier Transform pair for correlation as we have to

7297

% use Fourier Transform pair for correlation as we have to

7294

% take ifft of H_r anyways.

7298

% take ifft of H_r anyways.

7295

% onesided and two sided responses - tricky, tricky, tricky

7299

% onesided and two sided responses - tricky, tricky, tricky

7296

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7300

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7297

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7301

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7298

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7302

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7299

7303

7300

if OP.Do_White_Noise

7304

if OP.Do_White_Noise

7301

Noise_XC = Noise_XC(1);

7305

Noise_XC = Noise_XC(1);

7302

end

7306

end

7303

otherwise

7307

otherwise

7304

Noise_XC=[];

7308

Noise_XC=[];

7305

end

7309

end

7306

7310

7307

7311

7308

7312

7309

if OP.INCLUDE_CTLE==1

7313

if OP.INCLUDE_CTLE==1

7310

for k=1:param.num_s4p_files

7314

for k=1:param.num_s4p_files

7311

ir_peak = max(abs(chdata(k).(uneq_field)));

7315

ir_peak = max(abs(chdata(k).(uneq_field)));

7312

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7316

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7313

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7317

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7314

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7318

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7315

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7319

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7316

switch param.CTLE_type

7320

switch param.CTLE_type

7317

case 'CL93'

7321

case 'CL93'

7318

case 'CL120d'

7322

case 'CL120d'

7319

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7323

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7320

case 'CL120e' % z1 has been adusted on read in

7324

case 'CL120e' % z1 has been adusted on read in

7321

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7325

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7322

end

7326

end

7323

end

7327

end

7324

%set the flag to show ctle response was updated

7328

%set the flag to show ctle response was updated

7325

ctle_response_updated=1;

7329

ctle_response_updated=1;

7326

else

7330

else

7327

for k=1:param.num_s4p_files

7331

for k=1:param.num_s4p_files

7328

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7332

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7329

end

7333

end

7330

end

7334

end

7331

for k=1:param.num_s4p_files

7335

for k=1:param.num_s4p_files

7332

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7336

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7333

end

7337

end

7334

%% Equation 93A-22 %%

7338

%% Equation 93A-22 %%

7335

% figure(1000)

7339

% figure(1000)

7336

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7340

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7337

% hold on

7341

% hold on

7338

if OP.RX_CALIBRATION

7342

if OP.RX_CALIBRATION

7339

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7343

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7340

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7344

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7341

switch param.CTLE_type

7345

switch param.CTLE_type

7342

case 'CL93'

7346

case 'CL93'

7343

H_low2=1;

7347

H_low2=1;

7344

case 'CL120d'

7348

case 'CL120d'

7345

g_DC_low = g_DC_HP_values(g_LP_index);

7349

g_DC_low = g_DC_HP_values(g_LP_index);

7346

f_HP=param.f_HP(g_LP_index);

7350

f_HP=param.f_HP(g_LP_index);

7347

kacde_DC_low = 10^(g_DC_low/20);

7351

kacde_DC_low = 10^(g_DC_low/20);

7348

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7352

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7349

case 'CL120e' % z1 has been adusted on read in

7353

case 'CL120e' % z1 has been adusted on read in

7350

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7354

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7351

end

7355

end

7352

H_ctf2=H_low2.*ctle_gain2;

7356

H_ctf2=H_low2.*ctle_gain2;

7353

end

7357

end

7354

% RIM 11-30-2020 moved to a subfunction

7358

% RIM 11-30-2020 moved to a subfunction

7355

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7359

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7356

if OP.RX_CALIBRATION

7360

if OP.RX_CALIBRATION

7357

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7361

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7358

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7362

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7359

else

7363

else

7360

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7364

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7361

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7365

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7362

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7366

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7363

sigma_ne=0;

7367

sigma_ne=0;

7364

end

7368

end

7365

7369

7366

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7370

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7367

pxi=pxi+num_txffe_runs;

7371

pxi=pxi+num_txffe_runs;

7368

continue; % change per 0.3k draft 2.3

7372

continue; % change per 0.3k draft 2.3

7369

end

7373

end

7370

%%

7374

%%

7371

PSD_results=[];

7375

PSD_results=[];

7372

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7376

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7373

OP.WO_TXFFE=1;

7377

OP.WO_TXFFE=1;

7374

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7378

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7375

end

7379

end

7376

%TXFFE Loop

7380

%TXFFE Loop

7377

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7381

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7378

for TK=1:size(TXFFE_grid,1)

7382

for TK=1:size(TXFFE_grid,1)

7379

7383

7380

pxi=pxi+1;

7384

pxi=pxi+1;

7381

progress = pxi/runs;

7385

progress = pxi/runs;

7382

if OP.DISPLAY_WINDOW

7386

if OP.DISPLAY_WINDOW

7383

if ~mod(pxi,floor(runs*progress_interval))

7387

if ~mod(pxi,floor(runs*progress_interval))

7384

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7388

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7385

end

7389

end

7386

else

7390

else

7387

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7391

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7388

end

7392

end

7389

7393

7390

%get the cursor for this iteration

7394

%get the cursor for this iteration

7391

txffe_cur=txffe_cursor_vector(TK);

7395

txffe_cur=txffe_cursor_vector(TK);

7392

7396

7393

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7397

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7394

if txffe_cur<param.tx_ffe_c0_min

7398

if txffe_cur<param.tx_ffe_c0_min

7395

continue;

7399

continue;

7396

end

7400

end

7397

old_loops=old_loops+1;

7401

old_loops=old_loops+1;

7398

7402

7399

%get the index used for each tap on this iteration

7403

%get the index used for each tap on this iteration

7400

%this is needed for the LOCAL SEARCH block

7404

%this is needed for the LOCAL SEARCH block

7401

tx_index_vector=FULL_tx_index_vector(TK,:);

7405

tx_index_vector=FULL_tx_index_vector(TK,:);

7402

7406

7403

%Original LOCAL SEARCH Block:

7407

%Original LOCAL SEARCH Block:

7404

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7408

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7405

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7409

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7406

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7410

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7407

% % skip configurations more than

7411

% % skip configurations more than

7408

% % 2 steps away from current "best" point on any grid direction

7412

% % 2 steps away from current "best" point on any grid direction

7409

% % Matt Brown 11/19/2021 for cp2 and cp3

7413

% % Matt Brown 11/19/2021 for cp2 and cp3

7410

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7414

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7411

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7415

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7412

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7416

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7413

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7417

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7414

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7418

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7415

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7419

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7416

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7420

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7417

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7421

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7418

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7422

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7419

%

7423

%

7420

% continue;

7424

% continue;

7421

% end

7425

% end

7422

7426

7423

%Modular LOCAL_SEARCH block:

7427

%Modular LOCAL_SEARCH block:

7424

% speedup "local search" heuristic - Adee Ran 03-17-2020

7428

% speedup "local search" heuristic - Adee Ran 03-17-2020

7425

% skip configurations more than 2 steps away from current "best" point on any grid direction

7429

% skip configurations more than 2 steps away from current "best" point on any grid direction

7426

skip_it=0;

7430

skip_it=0;

7427

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7431

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7428

%instead of looping across all taps, only loop across

7432

%instead of looping across all taps, only loop across

7429

%those with length>1 (txffe_sweep_indices).

7433

%those with length>1 (txffe_sweep_indices).

7430

%It saves time since this block is encountered so often

7434

%It saves time since this block is encountered so often

7431

for kj=1:num_txffe_sweep_indices

7435

for kj=1:num_txffe_sweep_indices

7432

kv=txffe_sweep_indices(kj);

7436

kv=txffe_sweep_indices(kj);

7433

if kv==1

7437

if kv==1

7434

previous_loop_val=g_LP_index;

7438

previous_loop_val=g_LP_index;

7435

else

7439

else

7436

previous_loop_val=tx_index_vector(kv-1);

7440

previous_loop_val=tx_index_vector(kv-1);

7437

end

7441

end

7438

if previous_loop_val>1

7442

if previous_loop_val>1

7439

best_index_this_tap=best_txffe_index(kv);

7443

best_index_this_tap=best_txffe_index(kv);

7440

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7444

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7441

skip_it=1;

7445

skip_it=1;

7442

break;

7446

break;

7443

end

7447

end

7444

end

7448

end

7445

end

7449

end

7446

7450

7447

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7451

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7448

skip_it=1;

7452

skip_it=1;

7449

end

7453

end

7450

end

7454

end

7451

if skip_it

7455

if skip_it

7452

continue;

7456

continue;

7453

end

7457

end

7454

%End Modular LOCAL SEARCH block

7458

%End Modular LOCAL SEARCH block

7455

7459

7456

new_loops=new_loops+1;

7460

new_loops=new_loops+1;

7457

7461

7458

%fetch txffe for this iteration

7462

%fetch txffe for this iteration

7459

txffe=txffe_matrix(TK,:);

7463

txffe=txffe_matrix(TK,:);

7460

7464

7461

%The phase shift exponentials used in get_xtlk_noise are independent of

7465

%The phase shift exponentials used in get_xtlk_noise are independent of

7462

%everything except number of taps and cursor position

7466

%everything except number of taps and cursor position

7463

%So it can be calculated 1 time here to avoid thousands of re-calcs

7467

%So it can be calculated 1 time here to avoid thousands of re-calcs

7464

if ~calc_exp_phase

7468

if ~calc_exp_phase

7465

calc_exp_phase=1;

7469

calc_exp_phase=1;

7466

for k=1:length(txffe)

7470

for k=1:length(txffe)

7467

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7471

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7468

end

7472

end

7469

if OP.RxFFE

7473

if OP.RxFFE

7470

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7474

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7471

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7475

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7472

end

7476

end

7473

phase_memory=[phase_memory phase_memoryRXFFE];

7477

phase_memory=[phase_memory phase_memoryRXFFE];

7474

end

7478

end

7475

end

7479

end

7476

7480

7477

%% Unequalized Pulse Reponse & circshift for FFE

7481

%% Unequalized Pulse Reponse & circshift for FFE

7478

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7482

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7479

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7483

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7480

if ctle_response_updated

7484

if ctle_response_updated

7481

ctle_response_updated=0;

7485

ctle_response_updated=0;

7482

num_pre=cur-1;

7486

num_pre=cur-1;

7483

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7487

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7484

%Calculating here reduces number of convolutions by thousands

7488

%Calculating here reduces number of convolutions by thousands

7485

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7489

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7486

ich=1;

7490

ich=1;

7487

else

7491

else

7488

ich=param.num_s4p_files;

7492

ich=param.num_s4p_files;

7489

end

7493

end

7490

for ii=1:ich

7494

for ii=1:ich

7491

if OP.TDMODE

7495

if OP.TDMODE

7492

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7496

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7493

else

7497

else

7494

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7498

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7495

%"conv2" is faster than filter. Just need to chop off extra points at the end

7499

%"conv2" is faster than filter. Just need to chop off extra points at the end

7496

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7500

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7497

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7501

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7498

end

7502

end

7499

for k=1:length(txffe)

7503

for k=1:length(txffe)

7500

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7504

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7501

end

7505

end

7502

end

7506

end

7503

end

7507

end

7504

7508

7505

%% Apply TXFFE to pre-shifted pulse response

7509

%% Apply TXFFE to pre-shifted pulse response

7506

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7510

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7507

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7511

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7508

sbr_from_txffe=sbr;

7512

sbr_from_txffe=sbr;

7509

for ii=1:ich

7513

for ii=1:ich

7510

% this is sbr when ii=1; to be used in get_PSDs

7514

% this is sbr when ii=1; to be used in get_PSDs

7511

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7515

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7512

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7516

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7513

else

7517

else

7514

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7518

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7515

end

7519

end

7516

end

7520

end

7517

7521

7518

%% Find Sample Location

7522

%% Find Sample Location

7519

% If RXFFE is included, the sample location will be found again below

7523

% If RXFFE is included, the sample location will be found again below

7520

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7524

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7521

if param.ts_anchor==0

7525

if param.ts_anchor==0

7522

%keep MM

7526

%keep MM

7523

elseif param.ts_anchor==1

7527

elseif param.ts_anchor==1

7524

%peak sample

7528

%peak sample

7525

cursor_i=sbr_peak_i;

7529

cursor_i=sbr_peak_i;

7526

no_zero_crossing=0;

7530

no_zero_crossing=0;

7527

elseif param.ts_anchor==2

7531

elseif param.ts_anchor==2

7528

%max DV

7532

%max DV

7529

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7533

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7530

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7534

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7531

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7535

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7532

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7536

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7533

no_zero_crossing=0;

7537

no_zero_crossing=0;

7534

else

7538

else

7535

error('ts_anchor parameter must be 0, 1, or 2');

7539

error('ts_anchor parameter must be 0, 1, or 2');

7536

end

7540

end

7537

if no_zero_crossing

7541

if no_zero_crossing

7538

continue;

7542

continue;

7539

end

7543

end

7540

raw_cursor_i=cursor_i;

7544

raw_cursor_i=cursor_i;

7541

7545

7542

%%%%%%%%%%

7546

%%%%%%%%%%

7543

%%%%%%%%%%

7547

%%%%%%%%%%

7544

%%%%%%%%%%

7548

%%%%%%%%%%

7545

%NEW ITICK LOOP (not indenting everything yet)

7549

%NEW ITICK LOOP (not indenting everything yet)

7546

[~,si]=sort(abs(full_sample_range));

7550

[~,si]=sort(abs(full_sample_range));

7547

best_positive_itick_FOM=-inf;

7551

best_positive_itick_FOM=-inf;

7548

best_negative_itick_FOM=-inf;

7552

best_negative_itick_FOM=-inf;

7549

best_positive_itick_in_loop=[];

7553

best_positive_itick_in_loop=[];

7550

best_negative_itick_in_loop=[];

7554

best_negative_itick_in_loop=[];

7551

best_itick_FOM=-inf;

7555

best_itick_FOM=-inf;

7552

best_itick_in_cluster=[];

7556

best_itick_in_cluster=[];

7553

best_cluster=[];

7557

best_cluster=[];

7554

7558

7555

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7559

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7556

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7560

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

+7561

% Commit request4p4_7 healey_3dj_COM_01_240416

7562

%box_search=0;

7563

%middle_search=1;% should set 0 so all Ts sample points are used

7564

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7565

case 'full-sweep'

7566

box_search=0;

7567

middle_search=0;

7568

case 'middle'

7557

box_search=0;

7569

box_search=0;

7558

middle_search=1;% should set 0 so all Ts sample points are used

7570

middle_search=1;

7559

+7571

otherwise

7572

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7573

end

7560

if box_search

7574

if box_search

7561

box_size=5;

7575

box_size=5;

7562

box_mid=floor(box_size/2);

7576

box_mid=floor(box_size/2);

7563

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7577

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7564

CL=length(cluster);

7578

CL=length(cluster);

7565

loop_range=1:CL+box_mid*2;

7579

loop_range=1:CL+box_mid*2;

7566

elseif middle_search

7580

elseif middle_search

7567

loop_range=si;

7581

loop_range=si;

7568

else

7582

else

7569

loop_range=1:length(full_sample_range);

7583

loop_range=1:length(full_sample_range);

7570

end

7584

end

7571

7585

7572

for itickn=loop_range

7586

for itickn=loop_range

7573

if box_search

7587

if box_search

7574

if itickn<=CL

7588

if itickn<=CL

7575

itick=cluster(itickn);

7589

itick=cluster(itickn);

7576

else

7590

else

7577

if itickn==CL+1

7591

if itickn==CL+1

7578

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7592

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7579

end

7593

end

7580

if isempty(best_cluster)

7594

if isempty(best_cluster)

7581

continue;

7595

continue;

7582

end

7596

end

7583

itick=best_cluster(itickn-CL);

7597

itick=best_cluster(itickn-CL);

7584

end

7598

end

7585

else

7599

else

7586

itick=full_sample_range(itickn);

7600

itick=full_sample_range(itickn);

7587

end

7601

end

7588

7602

7589

itick_cases=itick_cases+1;

7603

itick_cases=itick_cases+1;

7590

7604

7591

sbr=sbr_from_txffe;

7605

sbr=sbr_from_txffe;

7592

cursor_i = raw_cursor_i+itick;

7606

cursor_i = raw_cursor_i+itick;

7593

7607

7594

%Local Search for +/- itick sweep

7608

%Local Search for +/- itick sweep

7595

if middle_search && param.LOCAL_SEARCH>0

7609

if middle_search && param.LOCAL_SEARCH>0

7596

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7610

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7597

itick_skips=itick_skips+1;

7611

itick_skips=itick_skips+1;

7598

continue;

7612

continue;

7599

end

7613

end

7600

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7614

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7601

itick_skips=itick_skips+1;

7615

itick_skips=itick_skips+1;

7602

continue;

7616

continue;

7603

end

7617

end

7604

end

7618

end

7605

7619

7606

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7620

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7607

if min_number_of_UI_in_response < triple_transit_time

7621

if min_number_of_UI_in_response < triple_transit_time

7608

min_number_of_UI_in_response = triple_transit_time;

7622

min_number_of_UI_in_response = triple_transit_time;

7609

end

7623

end

7610

7624

7611

cursor = sbr(cursor_i);

7625

cursor = sbr(cursor_i);

7612

7626

7613

%% RXFFE

7627

%% RXFFE

7614

if OP.RxFFE

7628

if OP.RxFFE

7615

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7629

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7616

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7630

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7617

%if isrow(sbr), sbr=sbr';end

7631

%if isrow(sbr), sbr=sbr';end

7618

7632

7619

%AJG: do not return sbr here (run time improvement)

7633

%AJG: do not return sbr here (run time improvement)

7620

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7634

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7621

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7635

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7622

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7636

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7623

% sbr at this point include the current setting

7637

% sbr at this point include the current setting

7624

% under consideration of txffe h21 ctf and fr

7638

% under consideration of txffe h21 ctf and fr

7625

switch upper(OP.FFE_OPT_METHOD)

7639

switch upper(OP.FFE_OPT_METHOD)

7626

case 'MMSE'

7640

case 'MMSE'

7627

OP.WO_TXFFE=0;

7641

OP.WO_TXFFE=0;

7628

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7642

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7629

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7643

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7630

if 0 % for debug

7644

if 0 % for debug

7631

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7645

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7632

hold on

7646

hold on

7633

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7647

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7634

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7648

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7635

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7649

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7636

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7650

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7637

xlim([0 0.5])

7651

xlim([0 0.5])

7638

% ylim([-190 -160])

7652

% ylim([-190 -160])

7639

set(gcf,'defaulttextinterpreter','none')

7653

set(gcf,'defaulttextinterpreter','none')

7640

xlabel('Normalized Frequency')

7654

xlabel('Normalized Frequency')

7641

ylabel('PSD dBm/Hz')

7655

ylabel('PSD dBm/Hz')

7642

hold on

7656

hold on

7643

grid on

7657

grid on

7644

legend show

7658

legend show

7645

title('PSD')

7659

title('PSD')

7646

end

7660

end

7647

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7661

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7648

% floating_tap_locations=MMSE_results.MLSE_results;

7662

% floating_tap_locations=MMSE_results.MLSE_results;

7649

C=MMSE_results.C;

7663

C=MMSE_results.C;

7650

FOM=MMSE_results.FOM;

7664

FOM=MMSE_results.FOM;

7651

floating_tap_locations=MMSE_results.floating_tap_locations;

7665

floating_tap_locations=MMSE_results.floating_tap_locations;

7652

otherwise

7666

otherwise

7653

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7667

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7654

end

7668

end

7655

%Now there is a stand alone function for determining if RXFFE taps are illegal

7669

%Now there is a stand alone function for determining if RXFFE taps are illegal

7656

%This is because the "force" function will also do a legality check when "backoff" is enabled

7670

%This is because the "force" function will also do a legality check when "backoff" is enabled

7657

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7671

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7658

if RXFFE_Illegal(C,param)

7672

if RXFFE_Illegal(C,param)

7659

continue;

7673

continue;

7660

end

7674

end

7661

end

7675

end

7662

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7676

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7663

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7677

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7664

if isrow(sbr), sbr=sbr';end

7678

if isrow(sbr), sbr=sbr';end

7665

7679

7666

%% second guess at cursor location (t_s) - based on approximate zero crossing

7680

%% second guess at cursor location (t_s) - based on approximate zero crossing

7667

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7681

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7668

%UPDATE: NOT RESAMPLING AFTER RXFFE

7682

%UPDATE: NOT RESAMPLING AFTER RXFFE

7669

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7683

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7670

% if no_zero_crossing

7684

% if no_zero_crossing

7671

% continue;

7685

% continue;

7672

% end

7686

% end

7673

7687

7674

cursor = sbr(cursor_i);

7688

cursor = sbr(cursor_i);

7675

end

7689

end

7676

A_p=sbr(sbr_peak_i);

7690

A_p=sbr(sbr_peak_i);

7677

%% 93A.1.6 step c defines A_s %%

7691

%% 93A.1.6 step c defines A_s %%

7678

A_s = param.R_LM*cursor/(param.levels-1);

7692

A_s = param.R_LM*cursor/(param.levels-1);

7679

if isempty(delta_sbr)

7693

if isempty(delta_sbr)

7680

delta_sbr = sbr;

7694

delta_sbr = sbr;

7681

end

7695

end

7682

sbr=sbr(:);

7696

sbr=sbr(:);

7683

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7697

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7684

7698

7685

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7699

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7686

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7700

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7687

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7701

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7688

param.ui/param.samples_per_ui;

7702

param.ui/param.samples_per_ui;

7689

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7703

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7690

precursors = precursors(end:-1:1);

7704

precursors = precursors(end:-1:1);

7691

7705

7692

% % Error message if the sbr is not long enough for the specified range of Nb

7706

% % Error message if the sbr is not long enough for the specified range of Nb

7693

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7707

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7694

% close(hwaitbar);

7708

% close(hwaitbar);

7695

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7709

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7696

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7710

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7697

% end

7711

% end

7698

7712

7699

7713

7700

7714

7701

%% skip this case if FOM has no chance of beating old FOM

7715

%% skip this case if FOM has no chance of beating old FOM

7702

%this is also done below but with excess_dfe_cursors included.

7716

%this is also done below but with excess_dfe_cursors included.

7703

%excess_dfe_cursors requires the floating DFE computation which is

7717

%excess_dfe_cursors requires the floating DFE computation which is

7704

%time consuming, so checking here can have significant run time improvements

7718

%time consuming, so checking here can have significant run time improvements

7705

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7719

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7706

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7720

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7707

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7721

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7708

continue

7722

continue

7709

end

7723

end

7710

end

7724

end

7711

7725

7712

%% Equation 93A-27, when 1<=n<=N_b

7726

%% Equation 93A-27, when 1<=n<=N_b

7713

%required length = cursor + all DFE UI + 1 additional UI

7727

%required length = cursor + all DFE UI + 1 additional UI

7714

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7728

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7715

if length(sbr)<sbr_required_length

7729

if length(sbr)<sbr_required_length

7716

sbr(end+1:sbr_required_length)=0;

7730

sbr(end+1:sbr_required_length)=0;

7717

end

7731

end

7718

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7732

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7719

if param.dfe_delta ~= 0

7733

if param.dfe_delta ~= 0

7720

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7734

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7721

7735

7722

else

7736

else

7723

dfecursors_q=dfecursors;

7737

dfecursors_q=dfecursors;

7724

end

7738

end

7725

if param.Floating_DFE

7739

if param.Floating_DFE

7726

%% floating taps

7740

%% floating taps

7727

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7741

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7728

7742

7729

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7743

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7730

7744

7731

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7745

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7732

param.use_bmax=newbmax;

7746

param.use_bmax=newbmax;

7733

%AJG021820

7747

%AJG021820

7734

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7748

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7735

else

7749

else

7736

param.use_bmax=param.bmax;

7750

param.use_bmax=param.bmax;

7737

%AJG021820

7751

%AJG021820

7738

param.use_bmin=param.bmin;

7752

param.use_bmin=param.bmin;

7739

end

7753

end

7740

7754

7741

%AJG021820

7755

%AJG021820

7742

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7756

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7743

if do_C2M

7757

if do_C2M

7744

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7758

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7745

% readjust SBR

7759

% readjust SBR

7746

if 0

7760

if 0

7747

%PR_DFE_center not currently used, so this is in "if 0" statement

7761

%PR_DFE_center not currently used, so this is in "if 0" statement

7748

PR_DFE_center=sbr;

7762

PR_DFE_center=sbr;

7749

for n=1:param.ndfe

7763

for n=1:param.ndfe

7750

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7764

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7751

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7765

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7752

% dper=sbr(i_sample)- actual_dfecursors(n);

7766

% dper=sbr(i_sample)- actual_dfecursors(n);

7753

% PR_DFE_center(i_sample)=dper;

7767

% PR_DFE_center(i_sample)=dper;

7754

% end

7768

% end

7755

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7769

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7756

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7770

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7757

end

7771

end

7758

end

7772

end

7759

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7773

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7760

else

7774

else

7761

excess_dfe_cursors=dfecursors-actual_dfecursors;

7775

excess_dfe_cursors=dfecursors-actual_dfecursors;

7762

end

7776

end

7763

dfetaps=actual_dfecursors/sbr(cursor_i);

7777

dfetaps=actual_dfecursors/sbr(cursor_i);

7764

7778

7765

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7779

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7766

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7780

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7767

if tail_RSS ~= 0

7781

if tail_RSS ~= 0

7768

if tail_RSS >= param.B_float_RSS_MAX

7782

if tail_RSS >= param.B_float_RSS_MAX

7769

param.use_bmax(param.N_tail_start:end)= ...

7783

param.use_bmax(param.N_tail_start:end)= ...

7770

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7784

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7771

%AJG021820

7785

%AJG021820

7772

param.use_bmin(param.N_tail_start:end)= ...

7786

param.use_bmin(param.N_tail_start:end)= ...

7773

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7787

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7774

end

7788

end

7775

end

7789

end

7776

7790

7777

%AJG021820

7791

%AJG021820

7778

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7792

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7779

if do_C2M

7793

if do_C2M

7780

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7794

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7781

else

7795

else

7782

excess_dfe_cursors=dfecursors-actual_dfecursors;

7796

excess_dfe_cursors=dfecursors-actual_dfecursors;

7783

end

7797

end

7784

dfetaps=actual_dfecursors/sbr(cursor_i);

7798

dfetaps=actual_dfecursors/sbr(cursor_i);

7785

7799

7786

else

7800

else

7787

tail_RSS=0;

7801

tail_RSS=0;

7788

end

7802

end

7789

%% Eq. 93A-28 %%

7803

%% Eq. 93A-28 %%

7790

sampling_offset = mod(cursor_i, param.samples_per_ui);

7804

sampling_offset = mod(cursor_i, param.samples_per_ui);

7791

%ensure we can take early sample

7805

%ensure we can take early sample

7792

if sampling_offset<=1

7806

if sampling_offset<=1

7793

sampling_offset=sampling_offset+param.samples_per_ui;

7807

sampling_offset=sampling_offset+param.samples_per_ui;

7794

end

7808

end

7795

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7809

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7796

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7810

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7797

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7811

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7798

else

7812

else

7799

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7813

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7800

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7814

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7801

end

7815

end

7802

% ensure lengths are equal

7816

% ensure lengths are equal

7803

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7817

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7804

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7818

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7805

if ~OP.SNR_TXwC0

7819

if ~OP.SNR_TXwC0

7806

%% Equation 93A-30 %%

7820

%% Equation 93A-30 %%

7807

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7821

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7808

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7822

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7809

else

7823

else

7810

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7824

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7811

end

7825

end

7812

%% Equation 93A-31 %%

7826

%% Equation 93A-31 %%

7813

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7827

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7814

ISI_N=param.sigma_X*norm( far_cursors);

7828

ISI_N=param.sigma_X*norm( far_cursors);

7815

%% break if FOM has no chance of beating old e

7829

%% break if FOM has no chance of beating old e

7816

OP.exe_mode=1;

7830

OP.exe_mode=1;

7817

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7831

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7818

switch OP.EXE_MODE

7832

switch OP.EXE_MODE

7819

case 0

7833

case 0

7820

case 1

7834

case 1

7821

if (20*log10(A_s/sigma_ISI) < best_FOM)

7835

if (20*log10(A_s/sigma_ISI) < best_FOM)

7822

continue

7836

continue

7823

end

7837

end

7824

case 2

7838

case 2

7825

if (20*log10(A_s/sigma_ISI) < best_FOM)

7839

if (20*log10(A_s/sigma_ISI) < best_FOM)

7826

break

7840

break

7827

end

7841

end

7828

end

7842

end

7829

end

7843

end

7830

%% Equation 93A-32 %%

7844

%% Equation 93A-32 %%

7831

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7845

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7832

7846

7833

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7847

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7834

if OP.RX_CALIBRATION

7848

if OP.RX_CALIBRATION

7835

sigma_XT=0;

7849

sigma_XT=0;

7836

else

7850

else

7837

if ~OP.RxFFE

7851

if ~OP.RxFFE

7838

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7852

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7839

%% Equation 93A-36 denominator (actually its sqrt)

7853

%% Equation 93A-36 denominator (actually its sqrt)

7840

else % John Ewen: 13/12/20018

7854

else % John Ewen: 13/12/20018

7841

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7855

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7842

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7856

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7843

else % use results from get_PSDs RIM 3/28/2024

7857

else % use results from get_PSDs RIM 3/28/2024

7844

sigma_XT=PSD_results.S_xn_rms;

7858

sigma_XT=PSD_results.S_xn_rms;

7845

end

7859

end

7846

end

7860

end

7847

end

7861

end

7848

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7862

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7849

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7863

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7850

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7864

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7851

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7865

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7852

f=chdata(1).faxis;

7866

f=chdata(1).faxis;

7853

H_Rx_FFE=zeros(1,length(f));

7867

H_Rx_FFE=zeros(1,length(f));

7854

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7868

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7855

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7869

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7856

if C(ii+param.RxFFE_cmx+1)==0

7870

if C(ii+param.RxFFE_cmx+1)==0

7857

%speed up: skip cases when rxffe=0

7871

%speed up: skip cases when rxffe=0

7858

continue;

7872

continue;

7859

end

7873

end

7860

if ii+1==0

7874

if ii+1==0

7861

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7875

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7862

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7876

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7863

else

7877

else

7864

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7878

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7865

end

7879

end

7866

end

7880

end

7867

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7881

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7868

end

7882

end

7869

end

7883

end

7870

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7884

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7871

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7885

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7872

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7886

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7873

else

7887

else

7874

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7888

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7875

end

7889

end

7876

if do_C2M

7890

if do_C2M

7877

if param.Noise_Crest_Factor == 0

7891

if param.Noise_Crest_Factor == 0

7878

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7892

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7879

else

7893

else

7880

ber_q=param.Noise_Crest_Factor;

7894

ber_q=param.Noise_Crest_Factor;

7881

end

7895

end

7882

if OP.force_pdf_bin_size

7896

if OP.force_pdf_bin_size

7883

delta_y = OP.BinSize;

7897

delta_y = OP.BinSize;

7884

else

7898

else

7885

delta_y = min(A_s/1000, OP.BinSize);

7899

delta_y = min(A_s/1000, OP.BinSize);

7886

end

7900

end

7887

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7901

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7888

cci_pdf = normal_dist(0, ber_q, delta_y);

7902

cci_pdf = normal_dist(0, ber_q, delta_y);

7889

chdata(1).eq_pulse_response=sbr;

7903

chdata(1).eq_pulse_response=sbr;

7890

tmp_result.t_s= cursor_i;

7904

tmp_result.t_s= cursor_i;

7891

tmp_result.A_s=A_s;

7905

tmp_result.A_s=A_s;

7892

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7906

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7893

if EH_1st <= param.Min_VEO_Test/1000 -.001

7907

if EH_1st <= param.Min_VEO_Test/1000 -.001

7894

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7908

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7895

continue

7909

continue

7896

else

7910

else

7897

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7911

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7898

end

7912

end

7899

Struct_Noise.sigma_N=sigma_N;

7913

Struct_Noise.sigma_N=sigma_N;

7900

Struct_Noise.sigma_TX=sigma_TX;

7914

Struct_Noise.sigma_TX=sigma_TX;

7901

Struct_Noise.cci_pdf=cci_pdf;

7915

Struct_Noise.cci_pdf=cci_pdf;

7902

Struct_Noise.ber_q=ber_q;

7916

Struct_Noise.ber_q=ber_q;

7903

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7917

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7904

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7918

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7905

EH=EH_T_C2M-EH_B_C2M;

7919

EH=EH_T_C2M-EH_B_C2M;

7906

N_i=(A_s*2-EH)/2;

7920

N_i=(A_s*2-EH)/2;

7907

if EH <= param.Min_VEO_Test/1000

7921

if EH <= param.Min_VEO_Test/1000

7908

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7922

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7909

continue

7923

continue

7910

else

7924

else

7911

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7925

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7912

end

7926

end

7913

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7927

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7914

FOM =20*log10(A_s/N_i);

7928

FOM =20*log10(A_s/N_i);

7915

end

7929

end

7916

else

7930

else

7917

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7931

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7918

FOM = 20*log10(A_s/total_noise_rms);

7932

FOM = 20*log10(A_s/total_noise_rms);

7919

end

7933

end

7920

% if strfind(param.CTLE_type,'CL120e')

7934

% if strfind(param.CTLE_type,'CL120e')

7921

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7935

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7922

end

7936

end

7923

if 0 % for loop analysis

7937

if 0 % for loop analysis

7924

result.FOM_array(new_loops)=FOM;

7938

result.FOM_array(new_loops)=FOM;

7925

end

7939

end

7926

7940

7927

if FOM>best_itick_FOM

7941

if FOM>best_itick_FOM

7928

best_itick_FOM=FOM;

7942

best_itick_FOM=FOM;

7929

best_itick_in_cluster=itick;

7943

best_itick_in_cluster=itick;

7930

end

7944

end

7931

7945

7932

if itick>=0 && FOM>best_positive_itick_FOM

7946

if itick>=0 && FOM>best_positive_itick_FOM

7933

best_positive_itick_FOM=FOM;

7947

best_positive_itick_FOM=FOM;

7934

best_positive_itick_in_loop=itick;

7948

best_positive_itick_in_loop=itick;

7935

end

7949

end

7936

if itick<=0 && FOM>best_negative_itick_FOM

7950

if itick<=0 && FOM>best_negative_itick_FOM

7937

best_negative_itick_FOM=FOM;

7951

best_negative_itick_FOM=FOM;

7938

best_negative_itick_in_loop=itick;

7952

best_negative_itick_in_loop=itick;

7939

end

7953

end

7940

7954

7941

itick_index=find(itick==full_sample_range);

7955

itick_index=find(itick==full_sample_range);

7942

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7956

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7943

7957

7944

if (FOM > best_FOM)

7958

if (FOM > best_FOM)

7945

best_current_ffegain=param.current_ffegain;

7959

best_current_ffegain=param.current_ffegain;

7946

best_txffe = txffe;

7960

best_txffe = txffe;

7947

%along with best_txffe, save the indices of the best_txffe

7961

%along with best_txffe, save the indices of the best_txffe

7948

%(saves time in LOCAL SEARCH block)

7962

%(saves time in LOCAL SEARCH block)

7949

best_txffe_index=tx_index_vector;

7963

best_txffe_index=tx_index_vector;

7950

best_sbr = sbr;

7964

best_sbr = sbr;

7951

best_ctle = ctle_index;

7965

best_ctle = ctle_index;

7952

best_G_high_pass =g_LP_index;

7966

best_G_high_pass =g_LP_index;

7953

best_FOM = FOM;

7967

best_FOM = FOM;

7954

best_cursor_i = cursor_i;

7968

best_cursor_i = cursor_i;

7955

best_itick = itick;

7969

best_itick = itick;

7956

if ~OP.TDMODE

7970

if ~OP.TDMODE

7957

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7971

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7958

best_IR=effective_channel;

7972

best_IR=effective_channel;

7959

end

7973

end

7960

best_sigma_N = sigma_N;

7974

best_sigma_N = sigma_N;

7961

best_h_J = h_J;

7975

best_h_J = h_J;

7962

best_A_s=A_s;

7976

best_A_s=A_s;

7963

best_A_p=A_p;

7977

best_A_p=A_p;

7964

best_ISI=ISI_N;

7978

best_ISI=ISI_N;

7965

best_bmax=param.use_bmax;

7979

best_bmax=param.use_bmax;

7966

%AJG021820

7980

%AJG021820

7967

best_bmin=param.use_bmin;

7981

best_bmin=param.use_bmin;

7968

best_tail_RSS=tail_RSS;

7982

best_tail_RSS=tail_RSS;

7969

best_dfetaps=dfetaps;

7983

best_dfetaps=dfetaps;

7970

if param.Floating_DFE

7984

if param.Floating_DFE

7971

best_floating_tap_locations=floating_tap_locations;

7985

best_floating_tap_locations=floating_tap_locations;

7972

best_floating_tap_coef=floating_tap_coef;

7986

best_floating_tap_coef=floating_tap_coef;

7973

end

7987

end

7974

if param.Floating_RXFFE

7988

if param.Floating_RXFFE

7975

best_floating_tap_locations=floating_tap_locations;

7989

best_floating_tap_locations=floating_tap_locations;

7976

% best_floating_tap_coef=floating_tap_coef;

7990

% best_floating_tap_coef=floating_tap_coef;

7977

end

7991

end

7978

if OP.RxFFE

7992

if OP.RxFFE

7979

best_RxFFE=C;

7993

best_RxFFE=C;

7980

best_PSD_results=PSD_results;

7994

best_PSD_results=PSD_results;

7981

best_MMSE_results=MMSE_results;

7995

best_MMSE_results=MMSE_results;

7982

end

7996

end

7983

end

7997

end

7984

end

7998

end

7985

end

7999

end

7986

8000

7987

end

8001

end

7988

end

8002

end

7989

end

8003

end

7990

if do_C2M

8004

if do_C2M

7991

if best_FOM == -inf

8005

if best_FOM == -inf

7992

param.Min_VEO_Test=0;

8006

param.Min_VEO_Test=0;

7993

else

8007

else

7994

break

8008

break

7995

end

8009

end

7996

end

8010

end

7997

end

8011

end

7998

if 0

8012

if 0

7999

fprintf('old loops = %d\n',old_loops);

8013

fprintf('old loops = %d\n',old_loops);

8000

fprintf('new loops = %d\n',new_loops);

8014

fprintf('new loops = %d\n',new_loops);

8001

display(sprintf('\n :loops = %g',pxi))

8015

display(sprintf('\n :loops = %g',pxi))

8002

end

8016

end

8003

8017

8004

%turn this on to review if FOM changes sign more than once in an itick loop

8018

%turn this on to review if FOM changes sign more than once in an itick loop

8005

if 0

8019

if 0

8006

DIR_CHANGE={};

8020

DIR_CHANGE={};

8007

for m=1:length(Gffe_values)

8021

for m=1:length(Gffe_values)

8008

for n=1:length(gdc_values)

8022

for n=1:length(gdc_values)

8009

for k=1:lf_indx

8023

for k=1:lf_indx

8010

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8024

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8011

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8025

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8012

%1 = goes up, -1=goes down

8026

%1 = goes up, -1=goes down

8013

x=sign(diff(FOM_this_mat')');

8027

x=sign(diff(FOM_this_mat')');

8014

%y = change in sign on x. the location of a "2" is where FOM changes direction

8028

%y = change in sign on x. the location of a "2" is where FOM changes direction

8015

y=abs(diff(x'))';

8029

y=abs(diff(x'))';

8016

%the goal is the FOM only changes direction once. so count the occurences of the 2

8030

%the goal is the FOM only changes direction once. so count the occurences of the 2

8017

for j=1:size(FOM_this_mat,1)

8031

for j=1:size(FOM_this_mat,1)

8018

z{j}=find(y(j,:)==2);

8032

z{j}=find(y(j,:)==2);

8019

end

8033

end

8020

zL=cellfun('length',z);

8034

zL=cellfun('length',z);

8021

%return any row where FOM changed direction more than once

8035

%return any row where FOM changed direction more than once

8022

DIR_CHANGE{j,k}=find(zL>1);

8036

DIR_CHANGE{j,k}=find(zL>1);

8023

end

8037

end

8024

end

8038

end

8025

end

8039

end

8026

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8040

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8027

end

8041

end

8028

8042

8029

if ~exist('best_cursor_i', 'var')% take last setting

8043

if ~exist('best_cursor_i', 'var')% take last setting

8030

result.eq_failed=true;

8044

result.eq_failed=true;

8031

display('equalization failed')

8045

display('equalization failed')

8032

best_bmax=param.bmax;

8046

best_bmax=param.bmax;

8033

%AJG021820

8047

%AJG021820

8034

best_bmin=param.bmin;

8048

best_bmin=param.bmin;

8035

best_tail_RSS=0;

8049

best_tail_RSS=0;

8036

best_current_ffegain=0;

8050

best_current_ffegain=0;

8037

best_txffe = txffe;

8051

best_txffe = txffe;

8038

best_sbr = sbr;

8052

best_sbr = sbr;

8039

best_ctle = ctle_index;

8053

best_ctle = ctle_index;

8040

if OP.RxFFE

8054

if OP.RxFFE

8041

best_PSD_results=PSD_results;

8055

best_PSD_results=PSD_results;

8042

best_MMSE_results=MMSE_results;

8056

best_MMSE_results=MMSE_results;

8043

best_RxFFE=C;

8057

best_RxFFE=C;

8044

end

8058

end

8045

best_G_high_pass =g_LP_index;

8059

best_G_high_pass =g_LP_index;

8046

best_FOM = FOM;

8060

best_FOM = FOM;

8047

%if this block is reached, the last encountered EQ parameters are used

8061

%if this block is reached, the last encountered EQ parameters are used

8048

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8062

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8049

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8063

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8050

if isempty(cursor_i)

8064

if isempty(cursor_i)

8051

[~,cursor_i]=max(sbr);

8065

[~,cursor_i]=max(sbr);

8052

end

8066

end

8053

best_cursor_i = cursor_i;

8067

best_cursor_i = cursor_i;

8054

best_itick = itick;

8068

best_itick = itick;

8055

if ~OP.TDMODE

8069

if ~OP.TDMODE

8056

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8070

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8057

best_IR=effective_channel;

8071

best_IR=effective_channel;

8058

end

8072

end

8059

best_sigma_N = sigma_N;

8073

best_sigma_N = sigma_N;

8060

best_h_J = h_J;

8074

best_h_J = h_J;

8061

best_A_p=max(sbr);

8075

best_A_p=max(sbr);

8062

best_ISI=1;

8076

best_ISI=1;

8063

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8077

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8064

best_A_s= sbr( cursor_i);

8078

best_A_s= sbr( cursor_i);

8065

if param.Floating_DFE

8079

if param.Floating_DFE

8066

best_floating_tap_locations=[];

8080

best_floating_tap_locations=[];

8067

best_floating_tap_coef=[];

8081

best_floating_tap_coef=[];

8068

end

8082

end

8069

if do_C2M

8083

if do_C2M

8070

return

8084

return

8071

end

8085

end

8072

% return

8086

% return

8073

else

8087

else

8074

result.eq_failed=false; % RIM 12/30/2023

8088

result.eq_failed=false; % RIM 12/30/2023

8075

end

8089

end

8076

8090

8077

best_cursor = best_sbr(best_cursor_i);

8091

best_cursor = best_sbr(best_cursor_i);

8078

% report during debug

8092

% report during debug

8079

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8093

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8080

%If sbr was zero padded, then PRin needs to do so as well)

8094

%If sbr was zero padded, then PRin needs to do so as well)

8081

if length(PRin)<length(best_sbr)

8095

if length(PRin)<length(best_sbr)

8082

PRin(end+1:length(best_sbr))=0;

8096

PRin(end+1:length(best_sbr))=0;

8083

end

8097

end

8084

f=1e8:1e8:100e9;

8098

f=1e8:1e8:100e9;

8085

8099

8086

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8100

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8087

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8101

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8088

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8102

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8089

% need to include H_RCos in noise and when computing the system ir for thru

8103

% need to include H_RCos in noise and when computing the system ir for thru

8090

% and crosstalk

8104

% and crosstalk

8091

H_r=H_bw.*H_bt.*H_RCos;

8105

H_r=H_bw.*H_bt.*H_RCos;

8092

8106

8093

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8107

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8094

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8108

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8095

8109

8096

switch param.CTLE_type

8110

switch param.CTLE_type

8097

case 'CL93'

8111

case 'CL93'

8098

H_low=1;

8112

H_low=1;

8099

case 'CL120d'

8113

case 'CL120d'

8100

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8114

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8101

case 'CL120e'

8115

case 'CL120e'

8102

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8116

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8103

end

8117

end

8104

ctle_gain=H_low.*ctle_gain1.*H_r;

8118

ctle_gain=H_low.*ctle_gain1.*H_r;

8105

8119

8106

8120

8107

8121

8108

%lsbr=length(sbr);

8122

%lsbr=length(sbr);

8109

%use length of best_sbr in case zero padding was performed

8123

%use length of best_sbr in case zero padding was performed

8110

%check "sbr_required_length" variable

8124

%check "sbr_required_length" variable

8111

lsbr=length(best_sbr);

8125

lsbr=length(best_sbr);

8112

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8126

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8113

8127

8114

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8128

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8115

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8129

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8116

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8130

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8117

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8131

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8118

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8132

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8119

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8133

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8120

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8134

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8121

if param.Floating_DFE

8135

if param.Floating_DFE

8122

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8136

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8123

end

8137

end

8124

% apply max tap value constraint

8138

% apply max tap value constraint

8125

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8139

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8126

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8140

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8127

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8141

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8128

8142

8129

%AJG021820

8143

%AJG021820

8130

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8144

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8131

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8145

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8132

if param.Floating_DFE

8146

if param.Floating_DFE

8133

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8147

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8134

end

8148

end

8135

8149

8136

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8150

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8137

Symbol_Adj = (param.levels-1);% 3A.1.6

8151

Symbol_Adj = (param.levels-1);% 3A.1.6

8138

if OP.DEBUG ~=0

8152

if OP.DEBUG ~=0

8139

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8153

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8140

% display pulse responses in one axis per test case.

8154

% display pulse responses in one axis per test case.

8141

switch upper(OP.TIME_AXIS)

8155

switch upper(OP.TIME_AXIS)

8142

case 'S' % RIM 11-13-2023 added user selectable xaxis

8156

case 'S' % RIM 11-13-2023 added user selectable xaxis

8143

xnorm=1;

8157

xnorm=1;

8144

xaxis_label='seconds';

8158

xaxis_label='seconds';

8145

offset=0;

8159

offset=0;

8146

case 'UI'

8160

case 'UI'

8147

xnorm=param.ui;

8161

xnorm=param.ui;

8148

xaxis_label='UI';

8162

xaxis_label='UI';

8149

offset=t(best_cursor_i)/xnorm;

8163

offset=t(best_cursor_i)/xnorm;

8150

otherwise

8164

otherwise

8151

xnorm=1;

8165

xnorm=1;

8152

xaxis_label='seconds';

8166

xaxis_label='seconds';

8153

offset=0;

8167

offset=0;

8154

end

8168

end

8155

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8169

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8156

fig=findobj('Name', figure_name);

8170

fig=findobj('Name', figure_name);

8157

if isempty(fig), fig=figure('Name', figure_name); end

8171

if isempty(fig), fig=figure('Name', figure_name); end

8158

figure(fig);set(gcf,'Tag','COM');

8172

figure(fig);set(gcf,'Tag','COM');

8159

movegui(fig,'north')

8173

movegui(fig,'north')

8160

%figure(fig.Number);

8174

%figure(fig.Number);

8161

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8175

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8162

if OP.RxFFE

8176

if OP.RxFFE

8163

ax1=subplot(2,1,1);

8177

ax1=subplot(2,1,1);

8164

end

8178

end

8165

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8179

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8166

hold on

8180

hold on

8167

8181

8168

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8182

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8169

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8183

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8170

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8184

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8171

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8185

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8172

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8186

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8173

ylabel('volts')

8187

ylabel('volts')

8174

xlabel(xaxis_label)

8188

xlabel(xaxis_label)

8175

grid on

8189

grid on

8176

legend show

8190

legend show

8177

legend( 'Location', 'best')

8191

legend( 'Location', 'best')

8178

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8192

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8179

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8193

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8180

if param.ndfe_passed ~=0

8194

if param.ndfe_passed ~=0

8181

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8195

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8182

end

8196

end

8183

if param.Floating_DFE

8197

if param.Floating_DFE

8184

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8198

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8185

end

8199

end

8186

if OP.RxFFE

8200

if OP.RxFFE

8187

ax2=subplot(2,1,2);

8201

ax2=subplot(2,1,2);

8188

if param.Floating_RXFFE

8202

if param.Floating_RXFFE

8189

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8203

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8190

,'filled','disp','RxFFE floating FFE taps')

8204

,'filled','disp','RxFFE floating FFE taps')

8191

hold on

8205

hold on

8192

end

8206

end

8193

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8207

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8194

,'filled','disp','RxFFE fixted FFE taps')

8208

,'filled','disp','RxFFE fixted FFE taps')

8195

legend show

8209

legend show

8196

zoom xon

8210

zoom xon

8197

linkaxes([ax1 ax2],'x')

8211

linkaxes([ax1 ax2],'x')

8198

end

8212

end

8199

8213

8200

8214

8201

grid on

8215

grid on

8202

legend show

8216

legend show

8203

legend( 'Location', 'best')

8217

legend( 'Location', 'best')

8204

zoom xon

8218

zoom xon

8205

% set(hax, 'tag', 'EQE');

8219

% set(hax, 'tag', 'EQE');

8206

%

8220

%

8207

figure(110);set(gcf,'Tag','COM');

8221

figure(110);set(gcf,'Tag','COM');

8208

set(gcf, 'Name', 'CTLE selection');

8222

set(gcf, 'Name', 'CTLE selection');

8209

movegui(gcf, 'southeast');

8223

movegui(gcf, 'southeast');

8210

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8224

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8211

hold on

8225

hold on

8212

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8226

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8213

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8227

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8214

fbaud_tick=find(f >= baud_rate, 1);

8228

fbaud_tick=find(f >= baud_rate, 1);

8215

fnq_tick=find(f >= baud_rate/2, 1);

8229

fnq_tick=find(f >= baud_rate/2, 1);

8216

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8230

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8217

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8231

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8218

recolor_plots(gca);

8232

recolor_plots(gca);

8219

title('CTF/w Rx Filter Response')

8233

title('CTF/w Rx Filter Response')

8220

ylabel('dB')

8234

ylabel('dB')

8221

xlabel('Hz')

8235

xlabel('Hz')

8222

legend show

8236

legend show

8223

end

8237

end

8224

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8238

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8225

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8239

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8226

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8240

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8227

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8241

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8228

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8242

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8229

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8243

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8230

end

8244

end

8231

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8245

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8232

eqe_axes = findobj('tag', 'EQE');

8246

eqe_axes = findobj('tag', 'EQE');

8233

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8247

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8234

end

8248

end

8235

if OP.DISPLAY_WINDOW

8249

if OP.DISPLAY_WINDOW

8236

close(hwaitbar);

8250

close(hwaitbar);

8237

else

8251

else

8238

fprintf('\n');

8252

fprintf('\n');

8239

end

8253

end

8240

8254

8241

% % eq_data

8255

% % eq_data

8242

result.cur=cur;

8256

result.cur=cur;

8243

result.txffe = best_txffe;

8257

result.txffe = best_txffe;

8244

result.ctle = best_ctle;

8258

result.ctle = best_ctle;

8245

result.best_G_high_pass=best_G_high_pass;

8259

result.best_G_high_pass=best_G_high_pass;

8246

result.DFE_taps = best_dfetaps; %relative

8260

result.DFE_taps = best_dfetaps; %relative

8247

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8261

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8248

if param.Floating_DFE

8262

if param.Floating_DFE

8249

result.floating_tap_locations=best_floating_tap_locations;

8263

result.floating_tap_locations=best_floating_tap_locations;

8250

result.floating_tap_coef=best_floating_tap_coef;

8264

result.floating_tap_coef=best_floating_tap_coef;

8251

end

8265

end

8252

if param.Floating_RXFFE

8266

if param.Floating_RXFFE

8253

result.floating_tap_locations=best_floating_tap_locations;

8267

result.floating_tap_locations=best_floating_tap_locations;

8254

end

8268

end

8255

result.A_s = best_A_s;

8269

result.A_s = best_A_s;

8256

result.t_s = best_cursor_i;

8270

result.t_s = best_cursor_i;

8257

result.itick = best_itick;

8271

result.itick = best_itick;

8258

result.sigma_N = best_sigma_N;

8272

result.sigma_N = best_sigma_N;

8259

result.h_J = best_h_J;

8273

result.h_J = best_h_J;

8260

result.FOM = best_FOM;

8274

result.FOM = best_FOM;

8261

if ~OP.TDMODE

8275

if ~OP.TDMODE

8262

%If sbr was zero padded, then best_IR needs to do so as well)

8276

%If sbr was zero padded, then best_IR needs to do so as well)

8263

if length(best_IR)<length(best_sbr)

8277

if length(best_IR)<length(best_sbr)

8264

best_IR(end+1:length(best_sbr))=0;

8278

best_IR(end+1:length(best_sbr))=0;

8265

end

8279

end

8266

result.IR = best_IR;

8280

result.IR = best_IR;

8267

end

8281

end

8268

result.t=t;

8282

result.t=t;

8269

result.sbr=best_sbr;

8283

result.sbr=best_sbr;

8270

if OP.RxFFE

8284

if OP.RxFFE

8271

result.RxFFE=best_RxFFE;

8285

result.RxFFE=best_RxFFE;

8272

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8286

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8273

result.PSD_results=best_PSD_results;

8287

result.PSD_results=best_PSD_results;

8274

result.MMSE_results=best_MMSE_results;

8288

result.MMSE_results=best_MMSE_results;

8275

end

8289

end

8276

end

8290

end

8277

8291

8278

8292

8279

8293

8280

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8294

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8281

% updated RIM 12/17/2021

8295

% updated RIM 12/17/2021

8282

result.A_p = max(chdata(1).uneq_pulse_response);

8296

result.A_p = max(chdata(1).uneq_pulse_response);

8283

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8297

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8284

PR=chdata(1).uneq_pulse_response;

8298

PR=chdata(1).uneq_pulse_response;

8285

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8299

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8286

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8300

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8287

if iend >= length(PR)

8301

if iend >= length(PR)

8288

iend = length (PR);

8302

iend = length (PR);

8289

end

8303

end

8290

if ibeg < 1

8304

if ibeg < 1

8291

ibeg = 1;

8305

ibeg = 1;

8292

end

8306

end

8293

PR=PR(ibeg:iend);

8307

PR=PR(ibeg:iend);

8294

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8308

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8295

SRn=PR;

8309

SRn=PR;

8296

for ik=1:floor(length(PR)/param.samples_per_ui)

8310

for ik=1:floor(length(PR)/param.samples_per_ui)

8297

SPR=circshift(PR,param.samples_per_ui*ik);

8311

SPR=circshift(PR,param.samples_per_ui*ik);

8298

SPR(1:ik*param.samples_per_ui)=0;

8312

SPR(1:ik*param.samples_per_ui)=0;

8299

SRn=SRn+ SPR;

8313

SRn=SRn+ SPR;

8300

end

8314

end

8301

codedebug=0;

8315

codedebug=0;

8302

if codedebug

8316

if codedebug

8303

fig=figure('Name', 'step and pulse response for code debug');

8317

fig=figure('Name', 'step and pulse response for code debug');

8304

figure(fig);set(gcf,'Tag','COM');

8318

figure(fig);set(gcf,'Tag','COM');

8305

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8319

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8306

plot(UI,SRn)

8320

plot(UI,SRn)

8307

hold on

8321

hold on

8308

plot(UI,PR)

8322

plot(UI,PR)

8309

xlim([-param.D_p param.N_v])

8323

xlim([-param.D_p param.N_v])

8310

grid on;hold off;

8324

grid on;hold off;

8311

result.step=SRn;

8325

result.step=SRn;

8312

end

8326

end

8313

i20=find(SRn>=0.20*result.A_f,1,'first');

8327

i20=find(SRn>=0.20*result.A_f,1,'first');

8314

i80=find(SRn>=0.80*result.A_f,1,'first');

8328

i80=find(SRn>=0.80*result.A_f,1,'first');

8315

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8329

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8316

result.Pmax_by_Vf=result.A_p/result.A_f;

8330

result.Pmax_by_Vf=result.A_p/result.A_f;

8317

result.ISI =best_ISI;

8331

result.ISI =best_ISI;

8318

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8332

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8319

result.best_current_ffegain=best_current_ffegain;

8333

result.best_current_ffegain=best_current_ffegain;

8320

result.best_bmax=best_bmax;

8334

result.best_bmax=best_bmax;

8321

%AJG021820

8335

%AJG021820

8322

result.best_bmin=best_bmin;

8336

result.best_bmin=best_bmin;

8323

result.tail_RSS=best_tail_RSS;

8337

result.tail_RSS=best_tail_RSS;

8324

function param=parameter_size_adjustment(param,OP)

8338

function param=parameter_size_adjustment(param,OP)

8325

8339

8326

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8340

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8327

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8341

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8328

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8342

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8329

make_length_DCHP={'f_HP'};

8343

make_length_DCHP={'f_HP'};

8330

make_length_ncases={'AC_CM_RMS'};

8344

make_length_ncases={'AC_CM_RMS'};

8331

8345

8332

%ncases used by make_length_ncases fields

8346

%ncases used by make_length_ncases fields

8333

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8347

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8334

8348

8335

%PORTZ_mult used by make_length_WCPORTZ fields

8349

%PORTZ_mult used by make_length_WCPORTZ fields

8336

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8350

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8337

if OP.WC_PORTZ

8351

if OP.WC_PORTZ

8338

PORTZ_mult=[1 1];

8352

PORTZ_mult=[1 1];

8339

else

8353

else

8340

PORTZ_mult=pkg_sel_vec;

8354

PORTZ_mult=pkg_sel_vec;

8341

end

8355

end

8342

8356

8343

%Parameters that have length = 2

8357

%Parameters that have length = 2

8344

for j=1:length(make_length2)

8358

for j=1:length(make_length2)

8345

if numel(param.(make_length2{j}))==1

8359

if numel(param.(make_length2{j}))==1

8346

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8360

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8347

end

8361

end

8348

end

8362

end

8349

8363

8350

%Parameters that have length = ncases

8364

%Parameters that have length = ncases

8351

for j=1:length(make_length_ncases)

8365

for j=1:length(make_length_ncases)

8352

if numel(param.(make_length_ncases{j}))==1

8366

if numel(param.(make_length_ncases{j}))==1

8353

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8367

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8354

end

8368

end

8355

end

8369

end

8356

8370

8357

%Parameters that have length = length(ctle_gdc_values)

8371

%Parameters that have length = length(ctle_gdc_values)

8358

for j=1:length(make_length_GDC)

8372

for j=1:length(make_length_GDC)

8359

if numel(param.(make_length_GDC{j}))==1

8373

if numel(param.(make_length_GDC{j}))==1

8360

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8374

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8361

end

8375

end

8362

end

8376

end

8363

8377

8364

%Parameters that have length = length(g_DC_HP_values)

8378

%Parameters that have length = length(g_DC_HP_values)

8365

for j=1:length(make_length_DCHP)

8379

for j=1:length(make_length_DCHP)

8366

if numel(param.(make_length_DCHP{j}))==1

8380

if numel(param.(make_length_DCHP{j}))==1

8367

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8381

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8368

end

8382

end

8369

end

8383

end

8370

8384

8371

%Parameters that have length associated with PORTZ_mult

8385

%Parameters that have length associated with PORTZ_mult

8372

for j=1:length(make_length_WCPORTZ)

8386

for j=1:length(make_length_WCPORTZ)

8373

if numel(param.(make_length_WCPORTZ{j}))==1

8387

if numel(param.(make_length_WCPORTZ{j}))==1

8374

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8388

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8375

end

8389

end

8376

end

8390

end

8377

function sgm = pdf2sgm(pdf)

8391

function sgm = pdf2sgm(pdf)

8378

avg = sum(pdf.x .* pdf.y);

8392

avg = sum(pdf.x .* pdf.y);

8379

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8393

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8380

% end yasuo patch

8394

% end yasuo patch

8381

8395

8382

8396

8383

%% adding tx packgage

8397

%% adding tx packgage

8384

function cdf=pdf_to_cdf(pdf)

8398

function cdf=pdf_to_cdf(pdf)

8385

8399

8386

%Transform PDF to CDF

8400

%Transform PDF to CDF

8387

%The CDF is natively calculated from negative-to-positive voltage.

8401

%The CDF is natively calculated from negative-to-positive voltage.

8388

%This only gives BER calculation for bottom eye. Need to also

8402

%This only gives BER calculation for bottom eye. Need to also

8389

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8403

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8390

%min of top and bottom CDF values.

8404

%min of top and bottom CDF values.

8391

%If only interested in one side, a simple cumsum on y is all that is needed.

8405

%If only interested in one side, a simple cumsum on y is all that is needed.

8392

8406

8393

cdf.yB=cumsum(pdf.y);

8407

cdf.yB=cumsum(pdf.y);

8394

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8408

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8395

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8409

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8396

cdf.x=pdf.x;

8410

cdf.x=pdf.x;

8397

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8411

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8398

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8412

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8399

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8413

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8400

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8414

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8401

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8415

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8402

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8416

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8403

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8417

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8404

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8418

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8405

%% Added by Bill Kirkland, June 14, 2017

8419

%% Added by Bill Kirkland, June 14, 2017

8406

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8420

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8407

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8421

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8408

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8422

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8409

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8423

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8410

8424

8411

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8425

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8412

hold on

8426

hold on

8413

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8427

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8414

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8428

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8415

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8429

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8416

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8430

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8417

8431

8418

%% Added by Bill Kirkland, June 14, 2017

8432

%% Added by Bill Kirkland, June 14, 2017

8419

% modification allows bathtub curves to cross over and hence one can

8433

% modification allows bathtub curves to cross over and hence one can

8420

% directly read the noise component.

8434

% directly read the noise component.

8421

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8435

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8422

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8436

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8423

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8437

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8424

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8438

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8425

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8439

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8426

8440

8427

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8441

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8428

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8442

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8429

8443

8430

ylabel(hax, 'Probability')

8444

ylabel(hax, 'Probability')

8431

xlabel(hax, 'volts')

8445

xlabel(hax, 'volts')

8432

legend(hax, 'show')

8446

legend(hax, 'show')

8433

% testing code

8447

% testing code

8434

if 0

8448

if 0

8435

figure_name = 'COM curves';

8449

figure_name = 'COM curves';

8436

fig=findobj('Name', figure_name);

8450

fig=findobj('Name', figure_name);

8437

if isempty(fig), fig=figure('Name', figure_name); end

8451

if isempty(fig), fig=figure('Name', figure_name); end

8438

figure(fig);set(gcf,'Tag','COM');

8452

figure(fig);set(gcf,'Tag','COM');

8439

grid on

8453

grid on

8440

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8454

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8441

hold on

8455

hold on

8442

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8456

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8443

ylim([ 1e-6 0.25])

8457

ylim([ 1e-6 0.25])

8444

xlim([0 30])

8458

xlim([0 30])

8445

grid on

8459

grid on

8446

end

8460

end

8447

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8461

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8448

BER=param.specBER;

8462

BER=param.specBER;

8449

delta_dB=param.delta_IL;

8463

delta_dB=param.delta_IL;

8450

8464

8451

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8465

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8452

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8466

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8453

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8467

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8454

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8468

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8455

8469

8456

8470

8457

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8471

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8458

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8472

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8459

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8473

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8460

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8474

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8461

8475

8462

COM=20*log10(max_signal/maxn_tot);

8476

COM=20*log10(max_signal/maxn_tot);

8463

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8477

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8464

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8478

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8465

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8479

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8466

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8480

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8467

8481

8468

pfctr=exp(-0.09054*delta_dB);% less loss

8482

pfctr=exp(-0.09054*delta_dB);% less loss

8469

mfctr=exp(0.09054*delta_dB); % more loss

8483

mfctr=exp(0.09054*delta_dB); % more loss

8470

8484

8471

%less loss

8485

%less loss

8472

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8486

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8473

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8487

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8474

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8488

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8475

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8489

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8476

plus_maxn_tot=norm(plus_maxn);

8490

plus_maxn_tot=norm(plus_maxn);

8477

8491

8478

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8492

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8479

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8493

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8480

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8494

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8481

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8495

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8482

minus_maxn_tot=norm(minus_maxn);

8496

minus_maxn_tot=norm(minus_maxn);

8483

8497

8484

% more loss

8498

% more loss

8485

COMp=20*log10(max_signal*pfctr/maxn_tot);

8499

COMp=20*log10(max_signal*pfctr/maxn_tot);

8486

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8500

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8487

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8501

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8488

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8502

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8489

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8503

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8490

% less loss

8504

% less loss

8491

COMm=20*log10(max_signal*mfctr/maxn_tot);

8505

COMm=20*log10(max_signal*mfctr/maxn_tot);

8492

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8506

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8493

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8507

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8494

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8508

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8495

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8509

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8496

8510

8497

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8511

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8498

8512

8499

8513

8500

if(COM<0)

8514

if(COM<0)

8501

return

8515

return

8502

end

8516

end

8503

8517

8504

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8518

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8505

8519

8506

% pie(COM_per_noise,labels)

8520

% pie(COM_per_noise,labels)

8507

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8521

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8508

% legend('show','Location','bestoutside')

8522

% legend('show','Location','bestoutside')

8509

nullbar= [ 0 0 0 ];

8523

nullbar= [ 0 0 0 ];

8510

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8524

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8511

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8525

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8512

hold on

8526

hold on

8513

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8527

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8514

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8528

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8515

8529

8516

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8530

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8517

% ax=gca;

8531

% ax=gca;

8518

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8532

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8519

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8533

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8520

grid on

8534

grid on

8521

legend(labels,'Location','north')

8535

legend(labels,'Location','north')

8522

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8536

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8523

ylabel('COM (dB)')

8537

ylabel('COM (dB)')

8524

hold off

8538

hold off

8525

8539

8526

8540

8527

8541

8528

8542

8529

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8543

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8530

num_files=length(chdata);

8544

num_files=length(chdata);

8531

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8545

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8532

for i=1:num_files

8546

for i=1:num_files

8533

if param.package_testcase_i==1 && i==1

8547

if param.package_testcase_i==1 && i==1

8534

if OP.TDR && i==1

8548

if OP.TDR && i==1

8535

S.Frequencies=chdata(i).faxis;

8549

S.Frequencies=chdata(i).faxis;

8536

S.Impedance=100;

8550

S.Impedance=100;

8537

if ~OP.SHOW_BRD

8551

if ~OP.SHOW_BRD

8538

Sfield='_orig';

8552

Sfield='_orig';

8539

else

8553

else

8540

Sfield='_raw';

8554

Sfield='_raw';

8541

end

8555

end

8542

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8556

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8543

if ~param.FLAG.S2P

8557

if ~param.FLAG.S2P

8544

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8558

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8545

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8559

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8546

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8560

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8547

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8561

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8548

else

8562

else

8549

S.NumPorts=1;

8563

S.NumPorts=1;

8550

end

8564

end

8551

if OP.TDR_W_TXPKG

8565

if OP.TDR_W_TXPKG

8552

if OP.ERL == 2

8566

if OP.ERL == 2

8553

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8567

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8554

end

8568

end

8555

R_diepad = param.R_diepad;

8569

R_diepad = param.R_diepad;

8556

% RX package length is assumed to be the same for all

8570

% RX package length is assumed to be the same for all

8557

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8571

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8558

% for Rx pkg

8572

% for Rx pkg

8559

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8573

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8560

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8574

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8561

combines4p( s11in, s12in, s21in, s22in, ...

8575

combines4p( s11in, s12in, s21in, s22in, ...

8562

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8576

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8563

% S=sparameters(S.Parameters,S.Frequencies,100);

8577

% S=sparameters(S.Parameters,S.Frequencies,100);

8564

S=SL(S,S.Frequencies,R_diepad(1)*2);

8578

S=SL(S,S.Frequencies,R_diepad(1)*2);

8565

chdata(i).TX_RL=S.Parameters(2,2,:);

8579

chdata(i).TX_RL=S.Parameters(2,2,:);

8566

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8580

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8567

end

8581

end

8568

8582

8569

% need to combine S wiht is page and channel

8583

% need to combine S wiht is page and channel

8570

if param.FLAG.S2P

8584

if param.FLAG.S2P

8571

port_sel=1;

8585

port_sel=1;

8572

else

8586

else

8573

port_sel=[1 2];

8587

port_sel=[1 2];

8574

if OP.AUTO_TFX

8588

if OP.AUTO_TFX

8575

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8589

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8576

pix=find(fir4del==max(fir4del),1);

8590

pix=find(fir4del==max(fir4del),1);

8577

param.tfx(2)=2*tu(pix);

8591

param.tfx(2)=2*tu(pix);

8578

end

8592

end

8579

end

8593

end

8580

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8594

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8581

for ipsl=1:length(port_sel) % do for both port if s4p

8595

for ipsl=1:length(port_sel) % do for both port if s4p

8582

for izt=1:length(param.Z_t) % do for all tdr impedances

8596

for izt=1:length(param.Z_t) % do for all tdr impedances

8583

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8597

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8584

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8598

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8585

% OP.interp_sparam_mag='trend_to_DC';

8599

% OP.interp_sparam_mag='trend_to_DC';

8586

OP.interp_sparam_mag='linear_trend_to_DC';

8600

OP.interp_sparam_mag='linear_trend_to_DC';

8587

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8601

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8588

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8602

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8589

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8603

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8590

if ipsl ==1

8604

if ipsl ==1

8591

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8605

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8592

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8606

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8593

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8607

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8594

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8608

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8595

else

8609

else

8596

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8610

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8597

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8611

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8598

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8612

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8599

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8613

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8600

end

8614

end

8601

if OP.PTDR && i==1

8615

if OP.PTDR && i==1

8602

if ipsl ==1

8616

if ipsl ==1

8603

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8617

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8604

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8618

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8605

else

8619

else

8606

if ~param.FLAG.S2P

8620

if ~param.FLAG.S2P

8607

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8621

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8608

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8622

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8609

else

8623

else

8610

chdata(i).TDR22(izt).ERL=[];

8624

chdata(i).TDR22(izt).ERL=[];

8611

chdata(i).TDR22(izt).ERLRMS=[];

8625

chdata(i).TDR22(izt).ERLRMS=[];

8612

end

8626

end

8613

end

8627

end

8614

else

8628

else

8615

chdata(i).TDR11(izt).ERL=[];

8629

chdata(i).TDR11(izt).ERL=[];

8616

chdata(i).TDR22(izt).ERL=[];

8630

chdata(i).TDR22(izt).ERL=[];

8617

chdata(i).TDR11(izt).ERLRMS=[];

8631

chdata(i).TDR11(izt).ERLRMS=[];

8618

chdata(i).TDR22(izt).ERLRMS=[];

8632

chdata(i).TDR22(izt).ERLRMS=[];

8619

end

8633

end

8620

end

8634

end

8621

end

8635

end

8622

end

8636

end

8623

8637

8624

end

8638

end

8625

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8639

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8626

h=figure(180);set(gcf,'Tag','COM');

8640

h=figure(180);set(gcf,'Tag','COM');

8627

if param.package_testcase_i==1 && i == 1

8641

if param.package_testcase_i==1 && i == 1

8628

if i==1

8642

if i==1

8629

htabgroup = uitabgroup(h);

8643

htabgroup = uitabgroup(h);

8630

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8644

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8631

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8645

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8632

hax1 = axes('Parent', htab1);

8646

hax1 = axes('Parent', htab1);

8633

hax3 = axes('Parent', htab3);

8647

hax3 = axes('Parent', htab3);

8634

if ~param.FLAG.S2P

8648

if ~param.FLAG.S2P

8635

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8649

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8636

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8650

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8637

hax2 = axes('Parent', htab2);

8651

hax2 = axes('Parent', htab2);

8638

hax4 = axes('Parent', htab4);

8652

hax4 = axes('Parent', htab4);

8639

end

8653

end

8640

end

8654

end

8641

set(h,'CurrentAxes',hax1)

8655

set(h,'CurrentAxes',hax1)

8642

hold on

8656

hold on

8643

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8657

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8644

hold off

8658

hold off

8645

legend (hax1, 'off');grid on;zoom xon;

8659

legend (hax1, 'off');grid on;zoom xon;

8646

set(legend (hax1, 'show'), 'interp', 'none');

8660

set(legend (hax1, 'show'), 'interp', 'none');

8647

8661

8648

if ~param.FLAG.S2P

8662

if ~param.FLAG.S2P

8649

set(h,'CurrentAxes',hax2)

8663

set(h,'CurrentAxes',hax2)

8650

hold on

8664

hold on

8651

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8665

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8652

hold off

8666

hold off

8653

legend (hax2, 'off');grid on;zoom xon;

8667

legend (hax2, 'off');grid on;zoom xon;

8654

set(legend (hax2, 'show'), 'interp', 'none');

8668

set(legend (hax2, 'show'), 'interp', 'none');

8655

end

8669

end

8656

8670

8657

set(h,'CurrentAxes',hax3)

8671

set(h,'CurrentAxes',hax3)

8658

hold on

8672

hold on

8659

if OP.PTDR

8673

if OP.PTDR

8660

for izt=1:length(param.Z_t)

8674

for izt=1:length(param.Z_t)

8661

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8675

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8662

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8676

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8663

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8677

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8664

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8678

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8665

end

8679

end

8666

end

8680

end

8667

hold off

8681

hold off

8668

legend (hax3, 'off');grid on;zoom xon;

8682

legend (hax3, 'off');grid on;zoom xon;

8669

set(legend (hax3, 'show'), 'interp', 'none');

8683

set(legend (hax3, 'show'), 'interp', 'none');

8670

if ~param.FLAG.S2P

8684

if ~param.FLAG.S2P

8671

set(h,'CurrentAxes',hax4)

8685

set(h,'CurrentAxes',hax4)

8672

hold on

8686

hold on

8673

if OP.PTDR

8687

if OP.PTDR

8674

for izt=1:length(param.Z_t)

8688

for izt=1:length(param.Z_t)

8675

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8689

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8676

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8690

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8677

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8691

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8678

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8692

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8679

end

8693

end

8680

end

8694

end

8681

hold off

8695

hold off

8682

legend (hax4, 'off');grid on;zoom xon;

8696

legend (hax4, 'off');grid on;zoom xon;

8683

set(legend (hax4, 'show'), 'interp', 'none');

8697

set(legend (hax4, 'show'), 'interp', 'none');

8684

end

8698

end

8685

end

8699

end

8686

end

8700

end

8687

if param.FLAG.S2P, return; end

8701

if param.FLAG.S2P, return; end

8688

end

8702

end

8689

function S =r_parrelell2(zref,f,rpad)

8703

function S =r_parrelell2(zref,f,rpad)

8690

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8704

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8691

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8705

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8692

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8706

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8693

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8707

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8694

% Sm=sparameters(S.Parameters,f,zref);

8708

% Sm=sparameters(S.Parameters,f,zref);

8695

8709

8696

8710

8697

8711

8698

8712

8699

8713

8700

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8714

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8701

8715

8702

%touchstone_file: .sNp touchstone file to read

8716

%touchstone_file: .sNp touchstone file to read

8703

%port_order: port reorder vector

8717

%port_order: port reorder vector

8704

%

8718

%

8705

%sch: sparameter matrix

8719

%sch: sparameter matrix

8706

%schFreqAxis: frequency axis

8720

%schFreqAxis: frequency axis

8707

8721

8708

[file_path,root_name,extension]=fileparts(touchstone_file);

8722

[file_path,root_name,extension]=fileparts(touchstone_file);

8709

fid=fopen(touchstone_file);

8723

fid=fopen(touchstone_file);

8710

8724

8711

%fetch number of ports from extension

8725

%fetch number of ports from extension

8712

num_ports=str2num(char(regexp(extension,'\d*','match')));

8726

num_ports=str2num(char(regexp(extension,'\d*','match')));

8713

8727

8714

%Get option line

8728

%Get option line

8715

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8729

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8716

optcell=textscan(optstr{1}{1},'%s');

8730

optcell=textscan(optstr{1}{1},'%s');

8717

optcell=optcell{1};

8731

optcell=optcell{1};

8718

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8732

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8719

%Some touchstone files need this. can't remember why now. maybe lines

8733

%Some touchstone files need this. can't remember why now. maybe lines

8720

%with whitespace but not empty but not commented

8734

%with whitespace but not empty but not commented

8721

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8735

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8722

optcell=textscan(optstr{1}{1},'%s');

8736

optcell=textscan(optstr{1}{1},'%s');

8723

optcell=optcell{1};

8737

optcell=optcell{1};

8724

end

8738

end

8725

8739

8726

%read the entire file

8740

%read the entire file

8727

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8741

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8728

raw_column_data=raw_read_data{1};

8742

raw_column_data=raw_read_data{1};

8729

fclose(fid);

8743

fclose(fid);

8730

8744

8731

%number of columns for 2D matrix

8745

%number of columns for 2D matrix

8732

columns=num_ports*num_ports*2+1;

8746

columns=num_ports*num_ports*2+1;

8733

8747

8734

%find the frequency lines by searching for the right number of NaN

8748

%find the frequency lines by searching for the right number of NaN

8735

a=sum(isnan(raw_column_data),2);

8749

a=sum(isnan(raw_column_data),2);

8736

if num_ports==3

8750

if num_ports==3

8737

b=find(a==2);

8751

b=find(a==2);

8738

elseif num_ports==1

8752

elseif num_ports==1

8739

b=find(a==6);

8753

b=find(a==6);

8740

else

8754

else

8741

b=find(a==0);

8755

b=find(a==0);

8742

end

8756

end

8743

8757

8744

num_freq=length(b);

8758

num_freq=length(b);

8745

8759

8746

%toss out the NaN and reshape into a 2D matrix

8760

%toss out the NaN and reshape into a 2D matrix

8747

raw_input = raw_column_data.';

8761

raw_input = raw_column_data.';

8748

raw_input = raw_input(~isnan(raw_input));

8762

raw_input = raw_input(~isnan(raw_input));

8749

raw_input = reshape(raw_input,columns,num_freq).';

8763

raw_input = reshape(raw_input,columns,num_freq).';

8750

8764

8751

%get the frequency mult

8765

%get the frequency mult

8752

frequency_mult_text=optcell{2};

8766

frequency_mult_text=optcell{2};

8753

if(strcmpi(frequency_mult_text,'hz'))

8767

if(strcmpi(frequency_mult_text,'hz'))

8754

frequency_mult=1;

8768

frequency_mult=1;

8755

elseif(strcmpi(frequency_mult_text,'khz'))

8769

elseif(strcmpi(frequency_mult_text,'khz'))

8756

frequency_mult=1e3;

8770

frequency_mult=1e3;

8757

elseif(strcmpi(frequency_mult_text,'mhz'))

8771

elseif(strcmpi(frequency_mult_text,'mhz'))

8758

frequency_mult=1e6;

8772

frequency_mult=1e6;

8759

elseif(strcmpi(frequency_mult_text,'ghz'))

8773

elseif(strcmpi(frequency_mult_text,'ghz'))

8760

frequency_mult=1e9;

8774

frequency_mult=1e9;

8761

else

8775

else

8762

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8776

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8763

end

8777

end

8764

8778

8765

%get the RI/MA/DB format

8779

%get the RI/MA/DB format

8766

format=optcell{4};

8780

format=optcell{4};

8767

%get Z0

8781

%get Z0

8768

port_impedance=str2double(optcell(6:end))';

8782

port_impedance=str2double(optcell(6:end))';

8769

8783

8770

8784

8771

%grab frequency

8785

%grab frequency

8772

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8786

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8773

Spar.F=raw_input(:,1);

8787

Spar.F=raw_input(:,1);

8774

Spar.F=transpose(Spar.F(:));

8788

Spar.F=transpose(Spar.F(:));

8775

8789

8776

8790

8777

%transform data to real imaginary

8791

%transform data to real imaginary

8778

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8792

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8779

if(strcmpi(format,'ri'))

8793

if(strcmpi(format,'ri'))

8780

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8794

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8781

elseif(strcmpi(format,'ma'))

8795

elseif(strcmpi(format,'ma'))

8782

mag_data=raw_input(:,2:2:end);

8796

mag_data=raw_input(:,2:2:end);

8783

rad_data=raw_input(:,3:2:end)*pi/180;

8797

rad_data=raw_input(:,3:2:end)*pi/180;

8784

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8798

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8785

elseif(strcmpi(format,'db'))

8799

elseif(strcmpi(format,'db'))

8786

mag_data=10.^(raw_input(:,2:2:end)/20);

8800

mag_data=10.^(raw_input(:,2:2:end)/20);

8787

rad_data=raw_input(:,3:2:end)*pi/180;

8801

rad_data=raw_input(:,3:2:end)*pi/180;

8788

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8802

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8789

else

8803

else

8790

error('Format %s is not supported. Use RI MA or DB',format);

8804

error('Format %s is not supported. Use RI MA or DB',format);

8791

end

8805

end

8792

8806

8793

8807

8794

8808

8795

%transform to 3D

8809

%transform to 3D

8796

%allow for upper/lower matrix specification for touchstone 2.0 support

8810

%allow for upper/lower matrix specification for touchstone 2.0 support

8797

matrix_format=0;

8811

matrix_format=0;

8798

if(matrix_format==0)

8812

if(matrix_format==0)

8799

%full

8813

%full

8800

for j=1:num_ports

8814

for j=1:num_ports

8801

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8815

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8802

end

8816

end

8803

elseif(matrix_format==1)

8817

elseif(matrix_format==1)

8804

%upper

8818

%upper

8805

used_ports=0;

8819

used_ports=0;

8806

for j=1:num_ports

8820

for j=1:num_ports

8807

stated_ports=num_ports-j+1;

8821

stated_ports=num_ports-j+1;

8808

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8822

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8809

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8823

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8810

used_ports=used_ports+stated_ports;

8824

used_ports=used_ports+stated_ports;

8811

end

8825

end

8812

elseif(matrix_format==2)

8826

elseif(matrix_format==2)

8813

%lower

8827

%lower

8814

used_ports=0;

8828

used_ports=0;

8815

for j=1:num_ports

8829

for j=1:num_ports

8816

stated_ports=j;

8830

stated_ports=j;

8817

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8831

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8818

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8832

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8819

used_ports=used_ports+stated_ports;

8833

used_ports=used_ports+stated_ports;

8820

end

8834

end

8821

else

8835

else

8822

error('Matrix format is not supported. Use Full, Lower, or Upper');

8836

error('Matrix format is not supported. Use Full, Lower, or Upper');

8823

end

8837

end

8824

8838

8825

8839

8826

%check for swapping the 2 port matrix (required on 1.x spec)

8840

%check for swapping the 2 port matrix (required on 1.x spec)

8827

two_port_swap=1;

8841

two_port_swap=1;

8828

if(num_ports==2 && two_port_swap==1)

8842

if(num_ports==2 && two_port_swap==1)

8829

temp=pre_out.sp(1,2,:);

8843

temp=pre_out.sp(1,2,:);

8830

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8844

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8831

pre_out.sp(2,1,:)=temp;

8845

pre_out.sp(2,1,:)=temp;

8832

end

8846

end

8833

8847

8834

Spar.S=pre_out.sp;

8848

Spar.S=pre_out.sp;

8835

Spar.Z0=transpose(port_impedance(:));

8849

Spar.Z0=transpose(port_impedance(:));

8836

8850

8837

if length(Spar.Z0)>1

8851

if length(Spar.Z0)>1

8838

error('Each port must have the same reference impedance');

8852

error('Each port must have the same reference impedance');

8839

end

8853

end

8840

if ~isequal(Spar.Z0,50)

8854

if ~isequal(Spar.Z0,50)

8841

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8855

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8842

%Renormalize to 50 ohms

8856

%Renormalize to 50 ohms

8843

rho=(50-Spar.Z0)/(50+Spar.Z0);

8857

rho=(50-Spar.Z0)/(50+Spar.Z0);

8844

p=num_ports;

8858

p=num_ports;

8845

s_old=Spar.S;

8859

s_old=Spar.S;

8846

for k=1:num_freq

8860

for k=1:num_freq

8847

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8861

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8848

end

8862

end

8849

end

8863

end

8850

8864

8851

%These operations sync up with COM style Spar matrix

8865

%These operations sync up with COM style Spar matrix

8852

%1: put frequency as first dimension

8866

%1: put frequency as first dimension

8853

sch=shiftdim(Spar.S,2);

8867

sch=shiftdim(Spar.S,2);

8854

%2: reorder ports according to "ports" input

8868

%2: reorder ports according to "ports" input

8855

sch=sch(:,port_order,port_order);

8869

sch=sch(:,port_order,port_order);

8856

schFreqAxis=Spar.F;

8870

schFreqAxis=Spar.F;

8857

function [chdata, param] = read_PR_files(param, OP, chdata)

8871

function [chdata, param] = read_PR_files(param, OP, chdata)

8858

%% Read in pulse response

8872

%% Read in pulse response

8859

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8873

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8860

num_files=length(chdata);

8874

num_files=length(chdata);

8861

M=param.samples_per_ui;

8875

M=param.samples_per_ui;

8862

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8876

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8863

for i=1:num_files

8877

for i=1:num_files

8864

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8878

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8865

progress = i/num_files;

8879

progress = i/num_files;

8866

if OP.DISPLAY_WINDOW

8880

if OP.DISPLAY_WINDOW

8867

[~,a]=fileparts(chdata(i).filename);

8881

[~,a]=fileparts(chdata(i).filename);

8868

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8882

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8869

else

8883

else

8870

fprintf('%i ',i);

8884

fprintf('%i ',i);

8871

end

8885

end

8872

switch chdata(i).ext

8886

switch chdata(i).ext

8873

case '.csv'

8887

case '.csv'

8874

vt=load(chdata(i).filename);

8888

vt=load(chdata(i).filename);

8875

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8889

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8876

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8890

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8877

dt=vt(2,1)-vt(1,1);

8891

dt=vt(2,1)-vt(1,1);

8878

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8892

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8879

8893

8880

8894

8881

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8895

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8882

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8896

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8883

Vf=step_response(end);

8897

Vf=step_response(end);

8884

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8898

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8885

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8899

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8886

8900

8887

end

8901

end

8888

end

8902

end

8889

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8903

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8890

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8904

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8891

[filepath,name,ext] = fileparts(paramFile);

8905

[filepath,name,ext] = fileparts(paramFile);

8892

if ~isempty(filepath)

8906

if ~isempty(filepath)

8893

filepath=[filepath '\'];

8907

filepath=[filepath '\'];

8894

end

8908

end

8895

matcongfile=[filepath name '.mat'];

8909

matcongfile=[filepath name '.mat'];

8896

try

8910

try

8897

switch upper(ext)

8911

switch upper(ext)

8898

case upper('.mat')

8912

case upper('.mat')

8899

load(matcongfile)

8913

load(matcongfile)

8900

case upper('.csv')

8914

case upper('.csv')

8901

[na1, na2, parameter] = xlsread(paramFile);

8915

[na1, na2, parameter] = xlsread(paramFile);

8902

otherwise

8916

otherwise

8903

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8917

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8904

end

8918

end

8905

8919

8906

catch ME %#ok<NASGU>

8920

catch ME %#ok<NASGU>

8907

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8921

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8908

switch upper(ext)

8922

switch upper(ext)

8909

case upper('.mat')

8923

case upper('.mat')

8910

load(matcongfile)

8924

load(matcongfile)

8911

case upper('.csv')

8925

case upper('.csv')

8912

[na1, na2, parameter] = xlsread(paramFile);

8926

[na1, na2, parameter] = xlsread(paramFile);

8913

otherwise

8927

otherwise

8914

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8928

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8915

end

8929

end

8916

end

8930

end

8917

8931

8918

%% New section to parse .START package data

8932

%% New section to parse .START package data

8919

first_column_data = parameter(:,1);

8933

first_column_data = parameter(:,1);

8920

start_data_rows = find(strcmp(first_column_data,'.START'));

8934

start_data_rows = find(strcmp(first_column_data,'.START'));

8921

if ~isempty(start_data_rows)

8935

if ~isempty(start_data_rows)

8922

end_data_rows = find(strcmp(first_column_data,'.END'));

8936

end_data_rows = find(strcmp(first_column_data,'.END'));

8923

if length(start_data_rows) ~= length(end_data_rows)

8937

if length(start_data_rows) ~= length(end_data_rows)

8924

error('Number of .START and .END must be the same');

8938

error('Number of .START and .END must be the same');

8925

end

8939

end

8926

first_start_row = start_data_rows(1);

8940

first_start_row = start_data_rows(1);

8927

special_parameter = parameter;

8941

special_parameter = parameter;

8928

parameter = parameter(1:first_start_row-1,:);

8942

parameter = parameter(1:first_start_row-1,:);

8929

for j=1:length(start_data_rows)

8943

for j=1:length(start_data_rows)

8930

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8944

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8931

pkg_name = special_parameter{start_data_rows(j),2};

8945

pkg_name = special_parameter{start_data_rows(j),2};

8932

8946

8933

%Read all the parameters that make up a package

8947

%Read all the parameters that make up a package

8934

PKG_param = read_package_parameters(this_block);

8948

PKG_param = read_package_parameters(this_block);

8935

8949

8936

%save the data in a field revealed by pkg_name

8950

%save the data in a field revealed by pkg_name

8937

param.PKG.(pkg_name) = PKG_param;

8951

param.PKG.(pkg_name) = PKG_param;

8938

8952

8939

8953

8940

end

8954

end

8941

end

8955

end

8942

%Allow specification of TX and RX package section through PKG_NAME keyword

8956

%Allow specification of TX and RX package section through PKG_NAME keyword

8943

%the values must match package blocks specified in .START sections

8957

%the values must match package blocks specified in .START sections

8944

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8958

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8945

if isnan(param.PKG_NAME)

8959

if isnan(param.PKG_NAME)

8946

param.PKG_NAME = '';

8960

param.PKG_NAME = '';

8947

end

8961

end

8948

if isempty(param.PKG_NAME)

8962

if isempty(param.PKG_NAME)

8949

param.PKG_NAME = {};

8963

param.PKG_NAME = {};

8950

else

8964

else

8951

param.PKG_NAME = strsplit(param.PKG_NAME);

8965

param.PKG_NAME = strsplit(param.PKG_NAME);

8952

end

8966

end

8953

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8967

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8954

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8968

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8955

end

8969

end

8956

for j=1:length(param.PKG_NAME)

8970

for j=1:length(param.PKG_NAME)

8957

if ~isfield(param.PKG,param.PKG_NAME{j})

8971

if ~isfield(param.PKG,param.PKG_NAME{j})

8958

error('Package Block "%s" not found',param.PKG_NAME{j});

8972

error('Package Block "%s" not found',param.PKG_NAME{j});

8959

end

8973

end

8960

end

8974

end

8961

8975

8962

%%

8976

%%

8963

% just need to define so we can pass

8977

% just need to define so we can pass

8964

param.c=[.4e-12 .4e-12];

8978

param.c=[.4e-12 .4e-12];

8965

param.alen=[ 20 30 550 ];

8979

param.alen=[ 20 30 550 ];

8966

param.az=[100 120 100];

8980

param.az=[100 120 100];

8967

8981

8968

% make control for package/channel reflection control

8982

% make control for package/channel reflection control

8969

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8983

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8970

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8984

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8971

8985

8972

8986

8973

% make compatible with presentation of kappa

8987

% make compatible with presentation of kappa

8974

8988

8975

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8989

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8976

8990

8977

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8991

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8978

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8992

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8979

8993

8980

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8994

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8981

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8995

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8982

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8996

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8983

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8997

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8984

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8998

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8985

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8999

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8986

9000

8987

if OP.dynamic_txffe

9001

if OP.dynamic_txffe

8988

found_pre=1;

9002

found_pre=1;

8989

pre_count=1;

9003

pre_count=1;

8990

while found_pre

9004

while found_pre

8991

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9005

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8992

if found_pre

9006

if found_pre

8993

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9007

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8994

param.(field_name)=p;

9008

param.(field_name)=p;

8995

pre_count=pre_count+1;

9009

pre_count=pre_count+1;

8996

end

9010

end

8997

end

9011

end

8998

found_post=1;

9012

found_post=1;

8999

post_count=1;

9013

post_count=1;

9000

while found_post

9014

while found_post

9001

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9015

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9002

if found_post

9016

if found_post

9003

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9017

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9004

param.(field_name)=p;

9018

param.(field_name)=p;

9005

post_count=post_count+1;

9019

post_count=post_count+1;

9006

end

9020

end

9007

end

9021

end

9008

else

9022

else

9009

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9023

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9010

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9024

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9011

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9025

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9012

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9026

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9013

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9027

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9014

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9028

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9015

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9029

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9016

end

9030

end

9017

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9031

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9018

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9032

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9019

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9033

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9020

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9034

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9021

% support for floating taps

9035

% support for floating taps

9022

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9036

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9023

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9037

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9024

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9038

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9025

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9039

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9026

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9040

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9027

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9041

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9028

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9042

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9029

9043

9030

% support for tail tap power limitations

9044

% support for tail tap power limitations

9031

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9045

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9032

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9046

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9033

%

9047

%

9034

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9048

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9035

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9049

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9036

param.RxFFE_cmx=param.ffe_pre_tap_len;

9050

param.RxFFE_cmx=param.ffe_pre_tap_len;

9037

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9051

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9038

param.RxFFE_cpx=param.ffe_post_tap_len;

9052

param.RxFFE_cpx=param.ffe_post_tap_len;

9039

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9053

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9040

param.RxFFE_stepz=param.ffe_tap_step_size;

9054

param.RxFFE_stepz=param.ffe_tap_step_size;

9041

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9055

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9042

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9056

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9043

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9057

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9044

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9058

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9045

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9059

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9046

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9060

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9047

OP.RxFFE= true;

9061

OP.RxFFE= true;

9048

else

9062

else

9049

OP.RxFFE=false;

9063

OP.RxFFE=false;

9050

end

9064

end

9051

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9065

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9052

9066

9053

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9067

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9054

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9068

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9055

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9069

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9056

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9070

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9057

9071

9058

9072

9059

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9073

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9060

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9074

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9061

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9075

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9062

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9076

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9063

9077

9064

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9078

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9065

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9079

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9066

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9080

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9067

% always read in main ctle values. They would be interpreted different baseed

9081

% always read in main ctle values. They would be interpreted different baseed

9068

% on the clause they apply because of different CTF equations

9082

% on the clause they apply because of different CTF equations

9069

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9083

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9070

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9084

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9071

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9085

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9072

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9086

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9073

% the contex of the poles an zeros are determined by the clause

9087

% the contex of the poles an zeros are determined by the clause

9074

switch param.CTLE_type

9088

switch param.CTLE_type

9075

case 'CL93'

9089

case 'CL93'

9076

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9090

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9077

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9091

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9078

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9092

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9079

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9093

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9080

case 'CL120d'

9094

case 'CL120d'

9081

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9095

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9082

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9096

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9083

case 'CL120e'

9097

case 'CL120e'

9084

% re adjust to get TD_CTLE to work with C:120e equation without

9098

% re adjust to get TD_CTLE to work with C:120e equation without

9085

% changing TD_CTLE code

9099

% changing TD_CTLE code

9086

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9100

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9087

end

9101

end

9088

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9102

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9089

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9103

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9090

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9104

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9091

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9105

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9092

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9106

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9093

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9107

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9094

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9108

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9095

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9109

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9096

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9110

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9097

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9111

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9098

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9112

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9099

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9113

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9100

9114

9101

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9115

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9102

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9116

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9103

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9117

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9104

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9118

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9105

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9119

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9106

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9120

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9107

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9121

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9108

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9122

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9109

% This will keep bmax length 0 if Nb=0

9123

% This will keep bmax length 0 if Nb=0

9110

9124

9111

%AJG021820

9125

%AJG021820

9112

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9126

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9113

if isempty(param.bmax)

9127

if isempty(param.bmax)

9114

param.bmin=param.bmax;

9128

param.bmin=param.bmax;

9115

else

9129

else

9116

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9130

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9117

9131

9118

end

9132

end

9119

if param.ndfe >= 2

9133

if param.ndfe >= 2

9120

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9134

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9121

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9135

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9122

end

9136

end

9123

9137

9124

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9138

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9125

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9139

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9126

%verify gqual and gqual2 input

9140

%verify gqual and gqual2 input

9127

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9141

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9128

if size(param.gqual,1)~=length(param.g2qual)

9142

if size(param.gqual,1)~=length(param.g2qual)

9129

error('gqual and g2qual size mismatch');

9143

error('gqual and g2qual size mismatch');

9130

end

9144

end

9131

if size(param.gqual,2)~=2

9145

if size(param.gqual,2)~=2

9132

error('gqual must be Nx2 matrix');

9146

error('gqual must be Nx2 matrix');

9133

end

9147

end

9134

end

9148

end

9135

9149

9136

9150

9137

% eval if string for all three - can use different for TX and RX

9151

% eval if string for all three - can use different for TX and RX

9138

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9152

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9139

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9153

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9140

% [ahealey] Read values for optional compensating L and "bump" C

9154

% [ahealey] Read values for optional compensating L and "bump" C

9141

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9155

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9142

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9156

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9143

% [ahealey] End of modifications.

9157

% [ahealey] End of modifications.

9144

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9158

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9145

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9159

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9146

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9160

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9147

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9161

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9148

9162

9149

9163

9150

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9164

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9151

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9165

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9152

[ncases, mele]=size(param.z_p_tx_cases);

9166

[ncases, mele]=size(param.z_p_tx_cases);

9153

if mele ==2

9167

if mele ==2

9154

param.flex=2;

9168

param.flex=2;

9155

elseif mele==4

9169

elseif mele==4

9156

param.flex=4;

9170

param.flex=4;

9157

elseif mele==1

9171

elseif mele==1

9158

param.flex=1;

9172

param.flex=1;

9159

else

9173

else

9160

error(sprintf('config file syntax error'))

9174

error(sprintf('config file syntax error'))

9161

end

9175

end

9162

9176

9163

% board parameters

9177

% board parameters

9164

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9178

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9165

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9179

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9166

%

9180

%

9167

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9181

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9168

[ncases1, mele1]=size(param.z_p_next_cases);

9182

[ncases1, mele1]=size(param.z_p_next_cases);

9169

if ncases ~= ncases1 || mele ~= mele1

9183

if ncases ~= ncases1 || mele ~= mele1

9170

error('All TX, NEXT, FEXT, Rx cases must agree');

9184

error('All TX, NEXT, FEXT, Rx cases must agree');

9171

else

9185

else

9172

end

9186

end

9173

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9187

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9174

[ncases1, mele1]=size(param.z_p_fext_cases);

9188

[ncases1, mele1]=size(param.z_p_fext_cases);

9175

if ncases ~= ncases1 || mele ~= mele1

9189

if ncases ~= ncases1 || mele ~= mele1

9176

error('All TX, NEXT, FEXT, Rx cases must agree');

9190

error('All TX, NEXT, FEXT, Rx cases must agree');

9177

else

9191

else

9178

end

9192

end

9179

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9193

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9180

[ncases1, mele1]=size(param.z_p_rx_cases);

9194

[ncases1, mele1]=size(param.z_p_rx_cases);

9181

if ncases ~= ncases1 || mele ~= mele1

9195

if ncases ~= ncases1 || mele ~= mele1

9182

error('All TX, NEXT, FEXT, Rx cases must agree');

9196

error('All TX, NEXT, FEXT, Rx cases must agree');

9183

else

9197

else

9184

end

9198

end

9185

% Table 93A-3 parameters

9199

% Table 93A-3 parameters

9186

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9200

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9187

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9201

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9188

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9202

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9189

[ ncases1, mele1]=size(param.pkg_Z_c);%

9203

[ ncases1, mele1]=size(param.pkg_Z_c);%

9190

if mele ~= mele1

9204

if mele ~= mele1

9191

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9205

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9192

else

9206

else

9193

end

9207

end

9194

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9208

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9195

for ii=1:ncases

9209

for ii=1:ncases

9196

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9210

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9197

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9211

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9198

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9212

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9199

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9213

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9200

end

9214

end

9201

param.z_p_fext_cases = param.z_p_fext_casesx;

9215

param.z_p_fext_cases = param.z_p_fext_casesx;

9202

param.z_p_next_cases= param.z_p_next_casesx;

9216

param.z_p_next_cases= param.z_p_next_casesx;

9203

param.z_p_tx_cases= param.z_p_tx_casesx;

9217

param.z_p_tx_cases= param.z_p_tx_casesx;

9204

param.z_p_rx_cases= param.z_p_rx_casesx;

9218

param.z_p_rx_cases= param.z_p_rx_casesx;

9205

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9219

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9206

end

9220

end

9207

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9221

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9208

9222

9209

% Table 92-12 parameters

9223

% Table 92-12 parameters

9210

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9224

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9211

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9225

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9212

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9226

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9213

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9227

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9214

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9228

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9215

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9229

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9216

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9230

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9217

9231

9218

% Unofficial parameters

9232

% Unofficial parameters

9219

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9233

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9220

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9234

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9221

% Deprecated parameters - affect only frequency domain analysis.

9235

% Deprecated parameters - affect only frequency domain analysis.

9222

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9236

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9223

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9237

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9224

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9238

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9225

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9239

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9226

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9240

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9227

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9241

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9228

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9242

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9229

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9243

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9230

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9244

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9231

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9245

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9232

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9246

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9233

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9247

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9234

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9248

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9235

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9249

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9236

switch param.Gx

9250

switch param.Gx

9237

case 0

9251

case 0

9238

param.Grr=param.Grr; % just use older Grr ir gx not specified

9252

param.Grr=param.Grr; % just use older Grr ir gx not specified

9239

case 1

9253

case 1

9240

param.Grr=2; % use newer Grr

9254

param.Grr=2; % use newer Grr

9241

end

9255

end

9242

9256

9243

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9257

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9244

% Operational control variables

9258

% Operational control variables

9245

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9259

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9246

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9260

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9247

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9261

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9248

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9262

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9249

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9263

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9250

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9264

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9251

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9265

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9252

9266

9253

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9267

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9254

9268

9255

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9269

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9256

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9270

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9257

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9271

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9258

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9272

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9259

9273

9260

%%

9274

%%

9261

9275

9262

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9276

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9263

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9277

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9264

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9278

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9265

param.awgn_mv=param.AC_CM_RMS;

9279

param.awgn_mv=param.AC_CM_RMS;

9266

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9280

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9267

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9281

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9268

9282

9269

9283

9270

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9284

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9271

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9285

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9272

param.Floating_RXFFE=false;

9286

param.Floating_RXFFE=false;

9273

param.Floating_DFE=false;

9287

param.Floating_DFE=false;

9274

if param.N_bg > 0

9288

if param.N_bg > 0

9275

param.Floating_DFE=true;

9289

param.Floating_DFE=true;

9276

end

9290

end

9277

if OP.RxFFE

9291

if OP.RxFFE

9278

param.Floating_DFE=false;

9292

param.Floating_DFE=false;

9279

if param.N_bg > 0

9293

if param.N_bg > 0

9280

param.Floating_RXFFE=true;

9294

param.Floating_RXFFE=true;

9281

end

9295

end

9282

end

9296

end

9283

%% for introducing Tx or Rx skew on p leg or n leg

9297

%% for introducing Tx or Rx skew on p leg or n leg

9284

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9298

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9285

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9299

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9286

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9300

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9287

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9301

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9288

9302

9289

%%

9303

%%

9290

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9304

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9291

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9305

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9292

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9306

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9293

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9307

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9294

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9308

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9295

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9309

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9296

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9310

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9297

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9311

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9298

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9312

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9299

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9313

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9300

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9314

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9301

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9315

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9302

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9316

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9303

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9317

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9304

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9318

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9305

if ~OP.INC_PACKAGE

9319

if ~OP.INC_PACKAGE

9306

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9320

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9307

end

9321

end

9308

9322

9309

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9323

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9310

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9324

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9311

if OP.IDEAL_TX_TERM

9325

if OP.IDEAL_TX_TERM

9312

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9326

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9313

end

9327

end

9314

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9328

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9315

if OP.IDEAL_RX_TERM

9329

if OP.IDEAL_RX_TERM

9316

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9330

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9317

end

9331

end

9318

9332

9319

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9333

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9320

9334

9321

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9335

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9322

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9336

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9323

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9337

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9324

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9338

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9325

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9339

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9326

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9340

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9327

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9341

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9328

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9342

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9329

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9343

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9330

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9344

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9331

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9345

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9332

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9346

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9333

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9347

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9334

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9348

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9335

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9349

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9336

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9350

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9337

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9351

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9338

9352

9339

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9353

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9340

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9354

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9341

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9355

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9342

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9356

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9343

% compatibility

9357

% compatibility

9344

if OP.FORCE_TR

9358

if OP.FORCE_TR

9345

OP.T_r_meas_point=0;

9359

OP.T_r_meas_point=0;

9346

OP.T_r_filter_type=1;

9360

OP.T_r_filter_type=1;

9347

end

9361

end

9348

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9362

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9349

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9363

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9350

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9364

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9351

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9365

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9352

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9366

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9353

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9367

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9354

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9368

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9355

if OP.ERL

9369

if OP.ERL

9356

OP.PTDR=1;

9370

OP.PTDR=1;

9357

else

9371

else

9358

OP.PTDR=0;

9372

OP.PTDR=0;

9359

end % ERL needs to do a TDR

9373

end % ERL needs to do a TDR

9360

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9374

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9361

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9375

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9362

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9376

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9363

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9377

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9364

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9378

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9365

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9379

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9366

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9380

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9367

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9381

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9368

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9382

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9369

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9383

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9370

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9384

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9371

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9385

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9372

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9386

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9373

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9387

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9374

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9388

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9375

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9389

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9376

if strcmpi(OP.PHY,'C2M')

9390

if strcmpi(OP.PHY,'C2M')

9377

OP.EW=true;

9391

OP.EW=true;

9378

else

9392

else

9379

param.T_O=0; % make sure when c2c that sample is at Ts

9393

param.T_O=0; % make sure when c2c that sample is at Ts

9380

end

9394

end

9381

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9395

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9382

OP.PHY='C2Mcom';

9396

OP.PHY='C2Mcom';

9383

end

9397

end

9384

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9398

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9385

switch lower(OP.TDECQ)

9399

switch lower(OP.TDECQ)

9386

case {false 'none' 'vma'}

9400

case {false 'none' 'vma'}

9387

otherwise

9401

otherwise

9388

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9402

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9389

end

9403

end

9390

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9404

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9391

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9405

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9392

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9406

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9393

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9407

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9394

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9408

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9395

% Parameters for error burst probability calculation. Not officially used

9409

% Parameters for error burst probability calculation. Not officially used

9396

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9410

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9397

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9411

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9398

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9412

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9399

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9413

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9400

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9414

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9401

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9415

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9402

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9416

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9403

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9417

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9404

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9418

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9405

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9419

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9406

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9420

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9407

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9421

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9408

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9422

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9409

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9423

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9410

if OP.MLSE && param.ndfe==0

9424

if OP.MLSE && param.ndfe==0

9411

error('At least DFE 1 must be set to use MLSE');

9425

error('At least DFE 1 must be set to use MLSE');

9412

end

9426

end

9413

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9427

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9414

% MNSE parameters

9428

% MNSE parameters

9415

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9429

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9416

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9430

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9417

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9431

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9418

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9432

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9419

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS', 'WIENER-HOPF',

9433

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9420

+9434

% Commit request 4p4_7, healey_3dj_COM_01_240416

9435

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9421

% need to make sure TD mode does not invoke FD operations

9436

% need to make sure TD mode does not invoke FD operations

9422

if OP.TDMODE % need to set GET_FD false of TDMODE

9437

if OP.TDMODE % need to set GET_FD false of TDMODE

9423

OP.GET_FD=false;

9438

OP.GET_FD=false;

9424

OP.ERL_ONLY=0;

9439

OP.ERL_ONLY=0;

9425

OP.ERL=0;

9440

OP.ERL=0;

9426

OP.PTDR=0;

9441

OP.PTDR=0;

9427

OP.TDR=0;

9442

OP.TDR=0;

9428

OP.RX_CALIBRATION=0;

9443

OP.RX_CALIBRATION=0;

9429

end

9444

end

9430

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9445

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9431

save(matcongfile ,'parameter');

9446

save(matcongfile ,'parameter');

9432

end

9447

end

9433

9448

9434

9449

9435

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9450

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9436

if ~isempty(param.PKG_NAME)

9451

if ~isempty(param.PKG_NAME)

9437

if length(param.PKG_NAME) == 1

9452

if length(param.PKG_NAME) == 1

9438

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9453

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9439

end

9454

end

9440

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9455

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9441

tx_rx_fields_matrix = {'pkg_Z_c'};

9456

tx_rx_fields_matrix = {'pkg_Z_c'};

9442

tx_fields = {'z_p_tx_cases' 'z_p_next_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9457

tx_fields = {'z_p_tx_cases' 'z_p_next_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9443

rx_fields = {'z_p_rx_cases' 'a_next'};

9458

rx_fields = {'z_p_rx_cases' 'a_next'};

9444

tx_pkg_name=param.PKG_NAME{1};

9459

tx_pkg_name=param.PKG_NAME{1};

9445

rx_pkg_name=param.PKG_NAME{2};

9460

rx_pkg_name=param.PKG_NAME{2};

9446

tx_pkg_struct=param.PKG.(tx_pkg_name);

9461

tx_pkg_struct=param.PKG.(tx_pkg_name);

9447

rx_pkg_struct=param.PKG.(rx_pkg_name);

9462

rx_pkg_struct=param.PKG.(rx_pkg_name);

9448

9463

9449

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9464

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9450

for j=1:length(tx_rx_fields)

9465

for j=1:length(tx_rx_fields)

9451

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9466

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9452

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9467

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9453

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9468

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9454

end

9469

end

9455

9470

9456

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9471

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9457

for j=1:length(tx_rx_fields_matrix)

9472

for j=1:length(tx_rx_fields_matrix)

9458

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9473

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9459

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9474

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9460

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9475

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9461

end

9476

end

9462

9477

9463

%tx_fields: use only the tx package values

9478

%tx_fields: use only the tx package values

9464

for j=1:length(tx_fields)

9479

for j=1:length(tx_fields)

9465

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9480

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9466

end

9481

end

9467

9482

9468

%rx_fields: use only the rx package values

9483

%rx_fields: use only the rx package values

9469

for j=1:length(rx_fields)

9484

for j=1:length(rx_fields)

9470

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9485

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9471

end

9486

end

9472

9487

9473

end

9488

end

9474

9489

9475

9490

9476

%%

9491

%%

9477

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9492

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9478

%% FUNCTION :: read_sp4_sparams

9493

%% FUNCTION :: read_sp4_sparams

9479

%

9494

%

9480

% Description

9495

% Description

9481

% Read the fid of single-ended 4-port complex S-parameters

9496

% Read the fid of single-ended 4-port complex S-parameters

9482

% in Touchstone format 'file' and convert to the internal

9497

% in Touchstone format 'file' and convert to the internal

9483

% format using the port transform 'ports'

9498

% format using the port transform 'ports'

9484

%

9499

%

9485

% Created by Mike Y. He

9500

% Created by Mike Y. He

9486

% April 22, 2005

9501

% April 22, 2005

9487

%

9502

%

9488

% Reused some code from

9503

% Reused some code from

9489

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9504

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9490

% for touchstone 4-port S-matrix import.

9505

% for touchstone 4-port S-matrix import.

9491

%

9506

%

9492

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9507

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9493

% optimized for quicker parameter matching and parsing. also, separated out

9508

% optimized for quicker parameter matching and parsing. also, separated out

9494

% the plotting algorithms into their own sub-function routines

9509

% the plotting algorithms into their own sub-function routines

9495

%

9510

%

9496

% Modified December 2021 to use read_Nport_touchstone

9511

% Modified December 2021 to use read_Nport_touchstone

9497

% This is faster reader that is capable of reading touchstone with any number of ports

9512

% This is faster reader that is capable of reading touchstone with any number of ports

9498

%

9513

%

9499

% Input Variables (required)

9514

% Input Variables (required)

9500

% infile -- The s4p file to be read and converted

9515

% infile -- The s4p file to be read and converted

9501

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9516

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9502

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9517

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9503

% ports -- Re-order the port layout

9518

% ports -- Re-order the port layout

9504

%

9519

%

9505

% Output/Return Variables

9520

% Output/Return Variables

9506

% data -- structure containing network parameter data points and frequency axis

9521

% data -- structure containing network parameter data points and frequency axis

9507

% sdc -- the differential in/common-mode out s-parameter data matrix

9522

% sdc -- the differential in/common-mode out s-parameter data matrix

9508

% sdd -- the differential in/differential out s-parameter data matrix

9523

% sdd -- the differential in/differential out s-parameter data matrix

9509

%

9524

%

9510

9525

9511

9526

9512

% backwards compatibility settings. can be removed in updated code.

9527

% backwards compatibility settings. can be removed in updated code.

9513

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9528

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9514

if isempty(ports); ports = [1 2]; end % default order normally used.

9529

if isempty(ports); ports = [1 2]; end % default order normally used.

9515

ports = [1 2];

9530

ports = [1 2];

9516

9531

9517

9532

9518

if OP.DISPLAY_WINDOW

9533

if OP.DISPLAY_WINDOW

9519

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9534

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9520

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9535

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9521

end

9536

end

9522

9537

9523

%AJG: fast touchstone read for any number of ports

9538

%AJG: fast touchstone read for any number of ports

9524

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9539

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9525

9540

9526

9541

9527

9542

9528

D=NaN(size(sch));

9543

D=NaN(size(sch));

9529

% calculate differential s parameter matrix from single ended

9544

% calculate differential s parameter matrix from single ended

9530

for i=1:size(sch,1)

9545

for i=1:size(sch,1)

9531

S(:,:) = sch(i,:,:);

9546

S(:,:) = sch(i,:,:);

9532

T = [1 1 ; 1 -1 ];

9547

T = [1 1 ; 1 -1 ];

9533

W = T * (S / T);

9548

W = T * (S / T);

9534

D(i,:,:) = W(:,:);

9549

D(i,:,:) = W(:,:);

9535

end

9550

end

9536

9551

9537

% D matrix should be

9552

% D matrix should be

9538

% Scc11 Scd11 Scc12 Scd21

9553

% Scc11 Scd11 Scc12 Scd21

9539

% Sdc11 Sdd11 Sdc12 Sdd12

9554

% Sdc11 Sdd11 Sdc12 Sdd12

9540

% Scc21 Scd21 Scc22 Scd22

9555

% Scc21 Scd21 Scc22 Scd22

9541

% Sdc21 Sdd21 Sdc22 Sdd22

9556

% Sdc21 Sdd21 Sdc22 Sdd22

9542

9557

9543

% proper values

9558

% proper values

9544

%AJG: matrix can be properly referenced after fixing mapping

9559

%AJG: matrix can be properly referenced after fixing mapping

9545

SDD(:,1,1) = D(:,2,2);

9560

SDD(:,1,1) = D(:,2,2);

9546

SDC(:,1,1)= D(:,2,1);

9561

SDC(:,1,1)= D(:,2,1);

9547

SCC(:,1,1)= D(:,1,1);

9562

SCC(:,1,1)= D(:,1,1);

9548

SCD(:,1,1)= D(:,1,2);

9563

SCD(:,1,1)= D(:,1,2);

9549

9564

9550

9565

9551

9566

9552

% backwards compatibility output variables

9567

% backwards compatibility output variables

9553

data.m = sch;

9568

data.m = sch;

9554

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9569

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9555

data.freq = schFreqAxis;

9570

data.freq = schFreqAxis;

9556

colors = 'rgbk';

9571

colors = 'rgbk';

9557

9572

9558

if (plot_ini_s_params == 1)

9573

if (plot_ini_s_params == 1)

9559

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9574

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9560

for mj=1:4

9575

for mj=1:4

9561

% subplot(2,2,mj);

9576

% subplot(2,2,mj);

9562

for mi=1:4

9577

for mi=1:4

9563

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9578

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9564

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9579

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9565

hold on

9580

hold on

9566

end

9581

end

9567

xlabel('Frequency (Hz)');

9582

xlabel('Frequency (Hz)');

9568

ylabel('Magnitude (dB)');

9583

ylabel('Magnitude (dB)');

9569

legend show

9584

legend show

9570

grid on

9585

grid on

9571

title(sprintf('Output port %d', mj));

9586

title(sprintf('Output port %d', mj));

9572

end

9587

end

9573

end

9588

end

9574

plot_dif_s_params =0;

9589

plot_dif_s_params =0;

9575

if (plot_dif_s_params == 1)

9590

if (plot_dif_s_params == 1)

9576

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9591

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9577

% subplot(2,1,1);

9592

% subplot(2,1,1);

9578

for mj=1:1

9593

for mj=1:1

9579

for mi=1:1

9594

for mi=1:1

9580

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9595

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9581

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9596

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9582

hold on

9597

hold on

9583

end

9598

end

9584

end

9599

end

9585

xlabel('Frequency (Hz)');

9600

xlabel('Frequency (Hz)');

9586

ylabel('Magnitude (dB)');

9601

ylabel('Magnitude (dB)');

9587

legend show

9602

legend show

9588

grid on

9603

grid on

9589

title(infile);

9604

title(infile);

9590

9605

9591

% subplot(2,1,2);

9606

% subplot(2,1,2);

9592

% for mj=1:2

9607

% for mj=1:2

9593

% for mi=1:2

9608

% for mi=1:2

9594

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9609

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9595

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9610

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9596

% hold on

9611

% hold on

9597

% end

9612

% end

9598

% end

9613

% end

9599

% xlabel('Frequency (Hz)');

9614

% xlabel('Frequency (Hz)');

9600

% ylabel('Magnitude (dB)');

9615

% ylabel('Magnitude (dB)');

9601

% legend show

9616

% legend show

9602

% grid on

9617

% grid on

9603

end

9618

end

9604

9619

9605

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9620

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9606

% end read_sp2_sparam

9621

% end read_sp2_sparam

9607

9622

9608

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9623

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9609

%% FUNCTION :: read_sp4_sparams

9624

%% FUNCTION :: read_sp4_sparams

9610

%

9625

%

9611

% Description

9626

% Description

9612

% Read the fid of single-ended 4-port complex S-parameters

9627

% Read the fid of single-ended 4-port complex S-parameters

9613

% in Touchstone format 'file' and convert to the internal

9628

% in Touchstone format 'file' and convert to the internal

9614

% format using the port transform 'ports'

9629

% format using the port transform 'ports'

9615

%

9630

%

9616

% Created by Mike Y. He

9631

% Created by Mike Y. He

9617

% April 22, 2005

9632

% April 22, 2005

9618

%

9633

%

9619

% Reused some code from

9634

% Reused some code from

9620

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9635

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9621

% for touchstone 4-port S-matrix import.

9636

% for touchstone 4-port S-matrix import.

9622

%

9637

%

9623

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9638

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9624

% optimized for quicker parameter matching and parsing. also, separated out

9639

% optimized for quicker parameter matching and parsing. also, separated out

9625

% the plotting algorithms into their own sub-function routines

9640

% the plotting algorithms into their own sub-function routines

9626

%

9641

%

9627

% Modified December 2021 to use read_Nport_touchstone

9642

% Modified December 2021 to use read_Nport_touchstone

9628

% This is faster reader that is capable of reading touchstone with any number of ports

9643

% This is faster reader that is capable of reading touchstone with any number of ports

9629

%

9644

%

9630

% Input Variables (required)

9645

% Input Variables (required)

9631

% infile -- The s4p file to be read and converted

9646

% infile -- The s4p file to be read and converted

9632

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9647

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9633

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9648

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9634

% ports -- Re-order the port layout

9649

% ports -- Re-order the port layout

9635

% OP

9650

% OP

9636

% param

9651

% param

9637

% Output/Return Variables

9652

% Output/Return Variables

9638

% data -- structure containing network parameter data points and frequency axis

9653

% data -- structure containing network parameter data points and frequency axis

9639

% sdd -- the differential in/differential out s-parameter data matrix

9654

% sdd -- the differential in/differential out s-parameter data matrix

9640

% sdc -- the differential in/common-mode out s-parameter data matrix

9655

% sdc -- the differential in/common-mode out s-parameter data matrix

9641

% scc -- the common mode in/common-mode out s-parameter data matrix

9656

% scc -- the common mode in/common-mode out s-parameter data matrix

9642

%

9657

%

9643

%

9658

%

9644

9659

9645

9660

9646

% backwards compatibility settings. can be removed in updated code.

9661

% backwards compatibility settings. can be removed in updated code.

9647

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9662

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9648

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9663

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9649

9664

9650

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9665

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9651

% pair is reversed.

9666

% pair is reversed.

9652

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9667

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9653

9668

9654

if OP.DISPLAY_WINDOW

9669

if OP.DISPLAY_WINDOW

9655

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9670

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9656

end

9671

end

9657

9672

9658

%AJG: fast touchstone read for any number of ports

9673

%AJG: fast touchstone read for any number of ports

9659

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9674

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9660

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9675

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9661

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9676

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9662

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9677

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9663

Sigfct = ...

9678

Sigfct = ...

9664

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9679

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9665

D=NaN(size(sch));

9680

D=NaN(size(sch));

9666

% calculate differential s parameter matrix from single ended

9681

% calculate differential s parameter matrix from single ended

9667

% skew added RIM 12/29/2023

9682

% skew added RIM 12/29/2023

9668

for i=1:size(sch,1)

9683

for i=1:size(sch,1)

9669

f=schFreqAxis(i);

9684

f=schFreqAxis(i);

9670

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9685

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9671

S(:,:) = sch(i,:,:);

9686

S(:,:) = sch(i,:,:);

9672

Snew=sigma_matrix.*S;

9687

Snew=sigma_matrix.*S;

9673

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9688

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9674

W = T * (Snew / T);

9689

W = T * (Snew / T);

9675

D(i,:,:) = W(:,:);

9690

D(i,:,:) = W(:,:);

9676

end

9691

end

9677

9692

9678

% D matrix should be

9693

% D matrix should be

9679

% Scc11 Scd11 Scc12 Scd21

9694

% Scc11 Scd11 Scc12 Scd21

9680

% Sdc11 Sdd11 Sdc12 Sdd12

9695

% Sdc11 Sdd11 Sdc12 Sdd12

9681

% Scc21 Scd21 Scc22 Scd22

9696

% Scc21 Scd21 Scc22 Scd22

9682

% Sdc21 Sdd21 Sdc22 Sdd22

9697

% Sdc21 Sdd21 Sdc22 Sdd22

9683

9698

9684

% proper values

9699

% proper values

9685

SDD(:,1,1) = D(:,2,2);

9700

SDD(:,1,1) = D(:,2,2);

9686

SDD(:,2,2) = D(:,4,4);

9701

SDD(:,2,2) = D(:,4,4);

9687

SDD(:,1,2) = D(:,2,4);

9702

SDD(:,1,2) = D(:,2,4);

9688

SDD(:,2,1) = D(:,4,2);

9703

SDD(:,2,1) = D(:,4,2);

9689

9704

9690

SDC(:,1,1) = D(:,2,1);

9705

SDC(:,1,1) = D(:,2,1);

9691

SDC(:,2,2) = D(:,4,3);

9706

SDC(:,2,2) = D(:,4,3);

9692

SDC(:,1,2) = D(:,2,3);

9707

SDC(:,1,2) = D(:,2,3);

9693

SDC(:,2,1) = D(:,4,1);

9708

SDC(:,2,1) = D(:,4,1);

9694

9709

9695

SCC(:,1,1) = D(:,1,1);

9710

SCC(:,1,1) = D(:,1,1);

9696

SCC(:,2,2) = D(:,3,3);

9711

SCC(:,2,2) = D(:,3,3);

9697

SCC(:,1,2) = D(:,1,3);

9712

SCC(:,1,2) = D(:,1,3);

9698

SCC(:,2,1) = D(:,3,1);

9713

SCC(:,2,1) = D(:,3,1);

9699

9714

9700

% backwards compatibility output variables

9715

% backwards compatibility output variables

9701

data.m = sch;

9716

data.m = sch;

9702

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9717

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9703

data.freq = schFreqAxis;

9718

data.freq = schFreqAxis;

9704

colors = 'rgbk';

9719

colors = 'rgbk';

9705

9720

9706

if (plot_ini_s_params == 1)

9721

if (plot_ini_s_params == 1)

9707

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9722

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9708

for mj=1:4

9723

for mj=1:4

9709

subplot(2,2,mj);

9724

subplot(2,2,mj);

9710

for mi=1:4

9725

for mi=1:4

9711

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9726

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9712

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9727

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9713

hold on

9728

hold on

9714

end

9729

end

9715

xlabel('Frequency (Hz)');

9730

xlabel('Frequency (Hz)');

9716

ylabel('Magnitude (dB)');

9731

ylabel('Magnitude (dB)');

9717

legend show

9732

legend show

9718

grid on

9733

grid on

9719

title(sprintf('Output port %d', mj));

9734

title(sprintf('Output port %d', mj));

9720

end

9735

end

9721

end

9736

end

9722

plot_dif_s_params =0;

9737

plot_dif_s_params =0;

9723

if (plot_dif_s_params == 1)

9738

if (plot_dif_s_params == 1)

9724

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9739

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9725

% subplot(2,1,1);

9740

% subplot(2,1,1);

9726

for mj=1:2

9741

for mj=1:2

9727

for mi=1:2

9742

for mi=1:2

9728

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9743

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9729

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9744

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9730

hold on

9745

hold on

9731

end

9746

end

9732

end

9747

end

9733

xlabel('Frequency (Hz)');

9748

xlabel('Frequency (Hz)');

9734

ylabel('Magnitude (dB)');

9749

ylabel('Magnitude (dB)');

9735

legend show

9750

legend show

9736

grid on

9751

grid on

9737

title(infile);

9752

title(infile);

9738

%

9753

%

9739

% subplot(2,1,2);

9754

% subplot(2,1,2);

9740

% for mj=1:2

9755

% for mj=1:2

9741

% for mi=1:2

9756

% for mi=1:2

9742

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9757

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9743

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9758

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9744

% hold on

9759

% hold on

9745

% end

9760

% end

9746

% end

9761

% end

9747

% xlabel('Frequency (Hz)');

9762

% xlabel('Frequency (Hz)');

9748

% ylabel('Magnitude (dB)');

9763

% ylabel('Magnitude (dB)');

9749

% legend show

9764

% legend show

9750

% grid on

9765

% grid on

9751

end

9766

end

9752

9767

9753

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9768

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9754

% end read_sp4_sparam

9769

% end read_sp4_sparam

9755

function param_struct = read_package_parameters(parameter,param_struct)

9770

function param_struct = read_package_parameters(parameter,param_struct)

9756

9771

9757

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9772

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9758

%This block should eventually replace what is in read_ParamConfigFile

9773

%This block should eventually replace what is in read_ParamConfigFile

9759

%It can be called as: param = read_package_parameters(parameter, param)

9774

%It can be called as: param = read_package_parameters(parameter, param)

9760

9775

9761

if nargin<2

9776

if nargin<2

9762

%param_struct doesn't need to be passed when building a new package structure

9777

%param_struct doesn't need to be passed when building a new package structure

9763

%it is only needed when appending to regular param structure

9778

%it is only needed when appending to regular param structure

9764

param_struct=struct;

9779

param_struct=struct;

9765

end

9780

end

9766

9781

9767

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9782

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9768

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9783

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9769

9784

9770

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9785

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9771

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9786

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9772

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9787

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9773

9788

9774

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9789

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9775

[ncases, mele]=size(param_struct.z_p_tx_cases);

9790

[ncases, mele]=size(param_struct.z_p_tx_cases);

9776

if mele ==2

9791

if mele ==2

9777

param_struct.flex=2;

9792

param_struct.flex=2;

9778

elseif mele==4

9793

elseif mele==4

9779

param_struct.flex=4;

9794

param_struct.flex=4;

9780

elseif mele==1

9795

elseif mele==1

9781

param_struct.flex=1;

9796

param_struct.flex=1;

9782

else

9797

else

9783

error('config file syntax error')

9798

error('config file syntax error')

9784

end

9799

end

9785

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9800

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9786

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9801

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9787

if ncases ~= ncases1 || mele ~= mele1

9802

if ncases ~= ncases1 || mele ~= mele1

9788

error('All TX, NEXT, FEXT, Rx cases must agree');

9803

error('All TX, NEXT, FEXT, Rx cases must agree');

9789

else

9804

else

9790

end

9805

end

9791

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9806

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9792

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9807

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9793

if ncases ~= ncases1 || mele ~= mele1

9808

if ncases ~= ncases1 || mele ~= mele1

9794

error('All TX, NEXT, FEXT, Rx cases must agree');

9809

error('All TX, NEXT, FEXT, Rx cases must agree');

9795

else

9810

else

9796

end

9811

end

9797

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9812

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9798

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9813

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9799

if ncases ~= ncases1 || mele ~= mele1

9814

if ncases ~= ncases1 || mele ~= mele1

9800

error('All TX, NEXT, FEXT, Rx cases must agree');

9815

error('All TX, NEXT, FEXT, Rx cases must agree');

9801

else

9816

else

9802

end

9817

end

9803

% Table 93A-3 parameters

9818

% Table 93A-3 parameters

9804

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9819

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9805

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9820

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9806

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9821

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9807

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9822

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9808

if mele ~= mele1

9823

if mele ~= mele1

9809

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9824

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9810

else

9825

else

9811

end

9826

end

9812

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9827

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9813

for ii=1:ncases

9828

for ii=1:ncases

9814

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9829

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9815

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9830

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9816

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9831

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9817

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9832

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9818

end

9833

end

9819

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9834

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9820

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9835

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9821

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9836

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9822

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9837

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9823

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9838

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9824

end

9839

end

9825

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9840

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9826

%% extract s-parameter and convert to differential mode

9841

%% extract s-parameter and convert to differential mode

9827

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9842

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9828

num_files=length(chdata);

9843

num_files=length(chdata);

9829

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9844

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9830

for i=1:num_files

9845

for i=1:num_files

9831

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9846

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9832

progress = i/num_files;

9847

progress = i/num_files;

9833

if OP.DISPLAY_WINDOW

9848

if OP.DISPLAY_WINDOW

9834

[~,a]=fileparts(chdata(i).filename);

9849

[~,a]=fileparts(chdata(i).filename);

9835

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9850

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9836

else

9851

else

9837

fprintf('%i ',i);

9852

fprintf('%i ',i);

9838

end

9853

end

9839

9854

9840

% Skip reading file if it was already read (multiple test cases)

9855

% Skip reading file if it was already read (multiple test cases)

9841

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9856

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9842

switch lower(chdata(i).ext)

9857

switch lower(chdata(i).ext)

9843

case '.s2p' % for differential return loss

9858

case '.s2p' % for differential return loss

9844

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9859

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9845

chdata(i).fmaxi = length(Sch.freq);

9860

chdata(i).fmaxi = length(Sch.freq);

9846

chdata(i).faxis = Sch.freq;

9861

chdata(i).faxis = Sch.freq;

9847

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9862

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9848

SDDp2p(i)=NaN;

9863

SDDp2p(i)=NaN;

9849

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9864

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9850

chdata(i).sdd11=chdata(i).sdd11_raw;

9865

chdata(i).sdd11=chdata(i).sdd11_raw;

9851

case '.s4p'

9866

case '.s4p'

9852

if length(param.snpPortsOrder) ~= 4

9867

if length(param.snpPortsOrder) ~= 4

9853

error( 'warning:sNpFilePortMismatch', ...

9868

error( 'warning:sNpFilePortMismatch', ...

9854

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9869

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9855

length(param.snpPortsOrder), ...

9870

length(param.snpPortsOrder), ...

9856

chdata(i).ext ...

9871

chdata(i).ext ...

9857

);

9872

);

9858

end

9873

end

9859

% read function returns differnetial mode parameters

9874

% read function returns differnetial mode parameters

9860

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9875

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9861

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9876

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9862

% param.holdsdata(i).Sch= Sch;

9877

% param.holdsdata(i).Sch= Sch;

9863

% param.holdsdata(i).SDDch= SDDch;

9878

% param.holdsdata(i).SDDch= SDDch;

9864

% param.holdsdata(i).SDCch= SDCch;

9879

% param.holdsdata(i).SDCch= SDCch;

9865

else

9880

else

9866

error('If this line is reached, there is a logic error');

9881

error('If this line is reached, there is a logic error');

9867

% Sch=param.holdsdata(i).Sch;

9882

% Sch=param.holdsdata(i).Sch;

9868

% SDDch=param.holdsdata(i).SDDch;

9883

% SDDch=param.holdsdata(i).SDDch;

9869

% SDCch=param.holdsdata(i).SDCch;

9884

% SDCch=param.holdsdata(i).SDCch;

9870

end

9885

end

9871

chdata(i).fmaxi = length(Sch.freq);

9886

chdata(i).fmaxi = length(Sch.freq);

9872

9887

9873

9888

9874

if Sch.freq(chdata(i).fmaxi) < param.fb

9889

if Sch.freq(chdata(i).fmaxi) < param.fb

9875

warning('COM:read_s4p:MaxFreqTooLow', ...

9890

warning('COM:read_s4p:MaxFreqTooLow', ...

9876

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9891

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9877

chdata(i).filename, Sch.freq(end), param.fb);

9892

chdata(i).filename, Sch.freq(end), param.fb);

9878

end

9893

end

9879

if Sch.freq(1) > param.max_start_freq

9894

if Sch.freq(1) > param.max_start_freq

9880

warning('COM:read_s4p:StartFreqTooHigh', ...

9895

warning('COM:read_s4p:StartFreqTooHigh', ...

9881

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9896

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9882

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9897

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9883

end

9898

end

9884

freqstep=diff(Sch.freq);

9899

freqstep=diff(Sch.freq);

9885

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9900

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9886

if max(freqstep)-min(freqstep) > 1

9901

if max(freqstep)-min(freqstep) > 1

9887

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9902

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9888

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9903

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9889

end

9904

end

9890

if max(freqstep) - param.max_freq_step > 1

9905

if max(freqstep) - param.max_freq_step > 1

9891

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9906

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9892

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9907

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9893

end

9908

end

9894

9909

9895

chdata(i).faxis = Sch.freq;

9910

chdata(i).faxis = Sch.freq;

9896

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9911

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9897

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9912

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9898

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9913

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9899

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9914

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9900

% mode conversion

9915

% mode conversion

9901

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9916

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9902

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9917

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9903

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9918

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9904

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9919

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9905

%save original and add board (if required)

9920

%save original and add board (if required)

9906

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9921

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9907

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9922

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9908

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9923

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9909

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9924

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9910

if OP.include_pcb

9925

if OP.include_pcb

9911

% add boards to sdd

9926

% add boards to sdd

9912

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9927

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9913

9928

9914

end

9929

end

9915

%save final return loss (after the boards were included)

9930

%save final return loss (after the boards were included)

9916

chdata(i).sdd11=chdata(i).sdd11_raw;

9931

chdata(i).sdd11=chdata(i).sdd11_raw;

9917

chdata(i).sdd22=chdata(i).sdd22_raw;

9932

chdata(i).sdd22=chdata(i).sdd22_raw;

9918

otherwise

9933

otherwise

9919

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9934

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9920

end

9935

end

9921

9936

9922

%Crosstalk frequency axis must be the same as Thru

9937

%Crosstalk frequency axis must be the same as Thru

9923

if i>1

9938

if i>1

9924

%error on length difference

9939

%error on length difference

9925

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9940

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9926

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9941

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9927

end

9942

end

9928

%error if any value > 1Hz (don't want to check for exact

9943

%error if any value > 1Hz (don't want to check for exact

9929

%equality in case of floating point error)

9944

%equality in case of floating point error)

9930

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9945

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9931

if max(Fdiff)>1

9946

if max(Fdiff)>1

9932

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9947

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9933

end

9948

end

9934

end

9949

end

9935

else

9950

else

9936

SDDch(:,1,2)=chdata(i).sdd12_raw;

9951

SDDch(:,1,2)=chdata(i).sdd12_raw;

9937

SDDch(:,2,1)=chdata(i).sdd21_raw;

9952

SDDch(:,2,1)=chdata(i).sdd21_raw;

9938

SDDch(:,1,1)=chdata(i).sdd11_raw;

9953

SDDch(:,1,1)=chdata(i).sdd11_raw;

9939

SDDch(:,2,2)=chdata(i).sdd22_raw;

9954

SDDch(:,2,2)=chdata(i).sdd22_raw;

9940

end

9955

end

9941

chdata(i).sigma_ACCM_at_tp0=0;

9956

chdata(i).sigma_ACCM_at_tp0=0;

9942

if ~param.FLAG.S2P

9957

if ~param.FLAG.S2P

9943

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9958

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9944

if (OP.RX_CALIBRATION == 1 && i==2)

9959

if (OP.RX_CALIBRATION == 1 && i==2)

9945

chdata(i).sdd21=chdata(i).sdd21_raw;

9960

chdata(i).sdd21=chdata(i).sdd21_raw;

9946

else

9961

else

9947

%updated package construction with single function for both DD and DC

9962

%updated package construction with single function for both DD and DC

9948

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9963

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9949

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9964

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9950

chdata(i).sdd21=chdata(i).sdd21p;

9965

chdata(i).sdd21=chdata(i).sdd21p;

9951

if 1 % for AC CM noise inclusion

9966

if 1 % for AC CM noise inclusion

9952

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9967

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9953

chdata(i).sdc21=chdata(i).sdc21p;

9968

chdata(i).sdc21=chdata(i).sdc21p;

9954

end

9969

end

9955

end

9970

end

9956

else

9971

else

9957

chdata(i).sdd21=chdata(i).sdd21_raw;

9972

chdata(i).sdd21=chdata(i).sdd21_raw;

9958

end

9973

end

9959

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9974

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9960

end

9975

end

9961

end

9976

end

9962

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9977

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9963

9978

9964

function result = readdataSnPx(filename, nport)

9979

function result = readdataSnPx(filename, nport)

9965

%function [freq, cs] = readdataSnPx(filename, nport)

9980

%function [freq, cs] = readdataSnPx(filename, nport)

9966

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9981

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9967

%

9982

%

9968

% Read Touchstone file with frequencies in units of Hertz

9983

% Read Touchstone file with frequencies in units of Hertz

9969

%

9984

%

9970

% Input:

9985

% Input:

9971

% ======

9986

% ======

9972

% filename: Name of the Touchstone/SnP file

9987

% filename: Name of the Touchstone/SnP file

9973

% nport: Number of ports

9988

% nport: Number of ports

9974

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9989

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9975

% Touchstone file)

9990

% Touchstone file)

9976

% nheader: Number of header lines (comment lines plus option line in the

9991

% nheader: Number of header lines (comment lines plus option line in the

9977

% Touchstone file)

9992

% Touchstone file)

9978

%

9993

%

9979

% Output:

9994

% Output:

9980

% =======

9995

% =======

9981

% freq: Vector of frequencies [Hz]

9996

% freq: Vector of frequencies [Hz]

9982

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9997

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9983

% at frequency freq(k)

9998

% at frequency freq(k)

9984

%

9999

%

9985

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10000

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9986

% frequencies appropriately after reading the data.

10001

% frequencies appropriately after reading the data.

9987

%

10002

%

9988

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10003

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9989

% EIA/IBIS Open Forum, 2002.

10004

% EIA/IBIS Open Forum, 2002.

9990

%

10005

%

9991

% Written by Henning Braunisch, September 2004.

10006

% Written by Henning Braunisch, September 2004.

9992

% Updated by Steven Krooswyk, April 2006.

10007

% Updated by Steven Krooswyk, April 2006.

9993

10008

9994

10009

9995

fid = fopen(filename, 'r');

10010

fid = fopen(filename, 'r');

9996

10011

9997

10012

9998

% Skip header lines

10013

% Skip header lines

9999

str = ' ';

10014

str = ' ';

10000

n = 0;

10015

n = 0;

10001

while ~strcmp(str(1),'#')

10016

while ~strcmp(str(1),'#')

10002

str = fgetl(fid);

10017

str = fgetl(fid);

10003

if isempty(str)

10018

if isempty(str)

10004

str=' ' ;

10019

str=' ' ;

10005

if n > 1000

10020

if n > 1000

10006

display('error: could not find config line (#)')

10021

display('error: could not find config line (#)')

10007

break

10022

break

10008

end

10023

end

10009

end

10024

end

10010

n = n + 1;

10025

n = n + 1;

10011

end

10026

end

10012

10027

10013

% parse configuration line

10028

% parse configuration line

10014

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10029

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10015

p = find(A=='S'); %position of 'S'

10030

p = find(A=='S'); %position of 'S'

10016

units = lower(A(2:p-1)); %units before 'S'

10031

units = lower(A(2:p-1)); %units before 'S'

10017

format = A(p+1:p+2); %format after 'S'

10032

format = A(p+1:p+2); %format after 'S'

10018

10033

10019

% skip any more header lines

10034

% skip any more header lines

10020

%while ~str

10035

%while ~str

10021

10036

10022

nk = 0; % frequency counter

10037

nk = 0; % frequency counter

10023

while 1

10038

while 1

10024

10039

10025

[temp, count] = fscanf(fid, '%f', 1);

10040

[temp, count] = fscanf(fid, '%f', 1);

10026

if count == 0

10041

if count == 0

10027

temp2 = fscanf(fid, '%s', 1);

10042

temp2 = fscanf(fid, '%s', 1);

10028

if ~isempty(temp2), fgetl(fid); continue, end;

10043

if ~isempty(temp2), fgetl(fid); continue, end;

10029

break

10044

break

10030

end

10045

end

10031

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10046

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10032

for ni = 1:nport

10047

for ni = 1:nport

10033

for nj = 1:nport

10048

for nj = 1:nport

10034

switch lower(format)

10049

switch lower(format)

10035

case 'ma'

10050

case 'ma'

10036

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10051

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10037

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10052

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10038

case 'ri'

10053

case 'ri'

10039

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10054

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10040

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10055

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10041

case 'db'

10056

case 'db'

10042

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10057

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10043

M = 10^(db/20);

10058

M = 10^(db/20);

10044

%re = M*cos(ang);

10059

%re = M*cos(ang);

10045

%im = M*sin(ang);

10060

%im = M*sin(ang);

10046

re = M*cos(ang * pi / 180);

10061

re = M*cos(ang * pi / 180);

10047

im = M*sin(ang * pi / 180);

10062

im = M*sin(ang * pi / 180);

10048

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10063

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10049

otherwise

10064

otherwise

10050

error('readdataSnP: Unknown data format');

10065

error('readdataSnP: Unknown data format');

10051

end

10066

end

10052

end

10067

end

10053

end

10068

end

10054

end

10069

end

10055

10070

10056

fclose(fid);

10071

fclose(fid);

10057

10072

10058

% If 2-port then swap S_12 and S_21 per Touchstone spec

10073

% If 2-port then swap S_12 and S_21 per Touchstone spec

10059

if nport == 2

10074

if nport == 2

10060

temp = cs(2,1,:);

10075

temp = cs(2,1,:);

10061

cs(2,1,:) = cs(1,2,:);

10076

cs(2,1,:) = cs(1,2,:);

10062

cs(1,2,:) = temp;

10077

cs(1,2,:) = temp;

10063

end

10078

end

10064

10079

10065

% Update freq units to Hz

10080

% Update freq units to Hz

10066

switch lower(units)

10081

switch lower(units)

10067

case 'hz'

10082

case 'hz'

10068

10083

10069

case 'khz'

10084

case 'khz'

10070

freq=freq.*1e3;

10085

freq=freq.*1e3;

10071

case 'mhz'

10086

case 'mhz'

10072

freq=freq.*1e6;

10087

freq=freq.*1e6;

10073

case 'ghz'

10088

case 'ghz'

10074

freq=freq.*1e9;

10089

freq=freq.*1e9;

10075

end

10090

end

10076

10091

10077

% passivity check

10092

% passivity check

10078

result.freq = freq;

10093

result.freq = freq;

10079

result.cs = cs;

10094

result.cs = cs;

10080

10095

10081

function recolor_plots(ax)

10096

function recolor_plots(ax)

10082

10097

10083

if ~verLessThan('matlab', '8.4.0')

10098

if ~verLessThan('matlab', '8.4.0')

10084

return

10099

return

10085

end

10100

end

10086

colors='brgcmk';

10101

colors='brgcmk';

10087

ch=flipud(get(ax, 'children'));

10102

ch=flipud(get(ax, 'children'));

10088

10103

10089

for k=1:length(ch)

10104

for k=1:length(ch)

10090

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10105

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10091

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10106

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10092

end

10107

end

10093

legend (ax, 'off');

10108

legend (ax, 'off');

10094

warning('off', 'MATLAB:legend:PlotEmpty');

10109

warning('off', 'MATLAB:legend:PlotEmpty');

10095

set(legend (ax, 'show'), 'interp', 'none');

10110

set(legend (ax, 'show'), 'interp', 'none');

10096

10111

10097

function result = reduce(var1)

10112

function result = reduce(var1)

10098

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10113

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10099

out = zeros(1,length(var1));

10114

out = zeros(1,length(var1));

10100

out(1,:) = var1(1,1,:);

10115

out(1,:) = var1(1,1,:);

10101

result=out;

10116

result=out;

10102

10117

10103

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10118

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10104

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10119

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10105

% faxis is the frequency array

10120

% faxis is the frequency array

10106

% s21, s11, s22 are the corresponding array of differential parameters

10121

% s21, s11, s22 are the corresponding array of differential parameters

10107

% s21p includes the VFT and Tx filter if include_die=1

10122

% s21p includes the VFT and Tx filter if include_die=1

10108

if nargin<6

10123

if nargin<6

10109

include_die=1;

10124

include_die=1;

10110

end

10125

end

10111

if nargin<5

10126

if nargin<5

10112

mode='dd';

10127

mode='dd';

10113

end

10128

end

10114

10129

10115

s21=chdata.(['s' mode '21_raw']);

10130

s21=chdata.(['s' mode '21_raw']);

10116

s12=chdata.(['s' mode '12_raw']);

10131

s12=chdata.(['s' mode '12_raw']);

10117

s11=chdata.(['s' mode '11_raw']);

10132

s11=chdata.(['s' mode '11_raw']);

10118

s22=chdata.(['s' mode '22_raw']);

10133

s22=chdata.(['s' mode '22_raw']);

10119

faxis=chdata.faxis;

10134

faxis=chdata.faxis;

10120

channel_type=chdata.type;

10135

channel_type=chdata.type;

10121

10136

10122

if strcmpi(mode,'dd')

10137

if strcmpi(mode,'dd')

10123

s11=s11*param.kappa1;

10138

s11=s11*param.kappa1;

10124

s22=s22*param.kappa2;

10139

s22=s22*param.kappa2;

10125

end

10140

end

10126

10141

10127

10142

10128

Z0=param.Z0;

10143

Z0=param.Z0;

10129

%sigma_ACCM_at_tp0 is only used when mode=DC

10144

%sigma_ACCM_at_tp0 is only used when mode=DC

10130

sigma_ACCM_at_tp0=0;

10145

sigma_ACCM_at_tp0=0;

10131

10146

10132

% The following three parameters have possibly different valuesF for TX and

10147

% The following three parameters have possibly different valuesF for TX and

10133

% RX (so can be 2-element vectors).

10148

% RX (so can be 2-element vectors).

10134

R_diepad = param.R_diepad;

10149

R_diepad = param.R_diepad;

10135

10150

10136

%Make TX Package

10151

%Make TX Package

10137

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10152

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10138

10153

10139

%Make RX Package

10154

%Make RX Package

10140

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10155

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10141

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10156

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10142

10157

10143

10158

10144

% p(1 ,1, :)=s11in;

10159

% p(1 ,1, :)=s11in;

10145

% p(2 ,2, :)=s22in;

10160

% p(2 ,2, :)=s22in;

10146

% p(1 ,2, :)=s12in;

10161

% p(1 ,2, :)=s12in;

10147

% p(2 ,1, :)=s21in;

10162

% p(2 ,1, :)=s21in;

10148

%

10163

%

10149

% S=sparameters(p,faxis);

10164

% S=sparameters(p,faxis);

10150

% rfwrite(S,'temp.s4p');

10165

% rfwrite(S,'temp.s4p');

10151

10166

10152

if strcmpi(mode,'dc')

10167

if strcmpi(mode,'dc')

10153

RTX=R_diepad(param.Tx_rd_sel)/2;

10168

RTX=R_diepad(param.Tx_rd_sel)/2;

10154

RRX=R_diepad(param.Rx_rd_sel)/2;

10169

RRX=R_diepad(param.Rx_rd_sel)/2;

10155

Z0gamma=Z0/2;

10170

Z0gamma=Z0/2;

10156

else

10171

else

10157

RTX=R_diepad(param.Tx_rd_sel);

10172

RTX=R_diepad(param.Tx_rd_sel);

10158

RRX=R_diepad(param.Rx_rd_sel);

10173

RRX=R_diepad(param.Rx_rd_sel);

10159

Z0gamma=Z0;

10174

Z0gamma=Z0;

10160

end

10175

end

10161

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10176

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10162

gamma_tx=0;

10177

gamma_tx=0;

10163

else

10178

else

10164

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10179

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10165

end

10180

end

10166

if OP.IDEAL_RX_TERM

10181

if OP.IDEAL_RX_TERM

10167

gamma_rx=0;

10182

gamma_rx=0;

10168

else

10183

else

10169

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10184

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10170

end

10185

end

10171

10186

10172

if OP.INC_PACKAGE==0

10187

if OP.INC_PACKAGE==0

10173

s21p= s21;

10188

s21p= s21;

10174

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10189

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10175

else

10190

else

10176

if OP.RX_CALIBRATION == 1 && channel_number == 2

10191

if OP.RX_CALIBRATION == 1 && channel_number == 2

10177

% for calibration do not include the transmitter package

10192

% for calibration do not include the transmitter package

10178

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10193

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10179

SCH.Frequencies=faxis;

10194

SCH.Frequencies=faxis;

10180

SCH.Parameters(1,1,:)=s11out_rx;

10195

SCH.Parameters(1,1,:)=s11out_rx;

10181

SCH.Parameters(2,2,:)=s22out_rx;

10196

SCH.Parameters(2,2,:)=s22out_rx;

10182

SCH.Parameters(1,2,:)=s12out_rx;

10197

SCH.Parameters(1,2,:)=s12out_rx;

10183

SCH.Parameters(2,1,:)=s21out_rx;

10198

SCH.Parameters(2,1,:)=s21out_rx;

10184

SCH.NumPorts=2;

10199

SCH.NumPorts=2;

10185

SCH.Impedance=100;

10200

SCH.Impedance=100;

10186

%% Equation 93A-18

10201

%% Equation 93A-18

10187

if include_die

10202

if include_die

10188

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10203

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10189

else

10204

else

10190

s21p=s21out_rx; % if no die we do not want a VTF

10205

s21p=s21out_rx; % if no die we do not want a VTF

10191

end

10206

end

10192

else

10207

else

10193

%% Equations 93A-4 to 93A-7

10208

%% Equations 93A-4 to 93A-7

10194

if ~OP.IDEAL_TX_TERM

10209

if ~OP.IDEAL_TX_TERM

10195

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10210

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10196

end

10211

end

10197

H_t=ones(1,length(faxis)); % .3bj compatibility

10212

H_t=ones(1,length(faxis)); % .3bj compatibility

10198

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10213

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10199

% for RITT testing with good termination as in some instruments

10214

% for RITT testing with good termination as in some instruments

10200

% and tx filter when required

10215

% and tx filter when required

10201

if OP.T_r_filter_type==0

10216

if OP.T_r_filter_type==0

10202

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10217

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10203

else

10218

else

10204

tr=OP.transmitter_transition_time;

10219

tr=OP.transmitter_transition_time;

10205

f9=faxis/1e9;

10220

f9=faxis/1e9;

10206

if OP.T_r_meas_point == 1

10221

if OP.T_r_meas_point == 1

10207

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10222

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10208

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10223

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10209

else

10224

else

10210

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10225

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10211

end

10226

end

10212

10227

10213

end

10228

end

10214

end

10229

end

10215

if strcmpi(mode,'dc')

10230

if strcmpi(mode,'dc')

10216

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10231

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10217

end

10232

end

10218

if ~OP.IDEAL_RX_TERM

10233

if ~OP.IDEAL_RX_TERM

10219

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10234

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10220

else

10235

else

10221

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10236

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10222

end

10237

end

10223

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10238

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10224

if include_die

10239

if include_die

10225

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10240

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10226

else

10241

else

10227

s21p=s21; % if no die we do not want a VTF

10242

s21p=s21; % if no die we do not want a VTF

10228

end

10243

end

10229

end

10244

end

10230

10245

10231

if strcmpi(mode,'dc')

10246

if strcmpi(mode,'dc')

10232

% compute AC_CM_RMS at tp0

10247

% compute AC_CM_RMS at tp0

10233

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10248

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10234

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10249

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10235

if channel_number == 1

10250

if channel_number == 1

10236

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10251

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10237

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10252

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10238

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10253

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10239

% S=sparameters(p,faxis);

10254

% S=sparameters(p,faxis);

10240

% rfwrite(S,'temp.s4p');

10255

% rfwrite(S,'temp.s4p');

10241

end

10256

end

10242

end

10257

end

10243

10258

10244

SCH.Frequencies=faxis;

10259

SCH.Frequencies=faxis;

10245

SCH.Parameters(1,1,:)=s11;

10260

SCH.Parameters(1,1,:)=s11;

10246

SCH.Parameters(2,2,:)=s22;

10261

SCH.Parameters(2,2,:)=s22;

10247

SCH.Parameters(1,2,:)=s12;

10262

SCH.Parameters(1,2,:)=s12;

10248

SCH.Parameters(2,1,:)=s21;

10263

SCH.Parameters(2,1,:)=s21;

10249

SCH.NumPorts=2;

10264

SCH.NumPorts=2;

10250

if strcmpi(mode,'dc')

10265

if strcmpi(mode,'dc')

10251

SCH.Impedance=25;

10266

SCH.Impedance=25;

10252

else

10267

else

10253

SCH.Impedance=100;

10268

SCH.Impedance=100;

10254

end

10269

end

10255

10270

10256

end

10271

end

10257

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10272

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10258

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10273

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10259

% Creates a time-domain impulse response from frequency-domain IL data.

10274

% Creates a time-domain impulse response from frequency-domain IL data.

10260

% IL does not need to have DC but a corresponding frequency array

10275

% IL does not need to have DC but a corresponding frequency array

10261

% (freq_array) is required.

10276

% (freq_array) is required.

10262

%

10277

%

10263

% Causality is imposed using the Alternating Projections Method. See also:

10278

% Causality is imposed using the Alternating Projections Method. See also:

10264

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10279

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10265

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10280

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10266

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10281

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10267

10282

10268

ILin=IL;

10283

ILin=IL;

10269

fmax=1/time_step/2;

10284

fmax=1/time_step/2;

10270

freq_step=(freq_array(3)-freq_array(2))/1;

10285

freq_step=(freq_array(3)-freq_array(2))/1;

10271

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10286

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10272

if all(IL==0)

10287

if all(IL==0)

10273

%response with all zeros is problematic. set to all eps and avoid interp function

10288

%response with all zeros is problematic. set to all eps and avoid interp function

10274

IL=ones(1,length(fout))*eps;

10289

IL=ones(1,length(fout))*eps;

10275

else

10290

else

10276

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10291

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10277

IL_nan = find(isnan(IL));

10292

IL_nan = find(isnan(IL));

10278

for in=IL_nan

10293

for in=IL_nan

10279

IL(in)=IL(in-1);

10294

IL(in)=IL(in-1);

10280

end

10295

end

10281

end

10296

end

10282

IL = IL(:);

10297

IL = IL(:);

10283

% add padding for time steps

10298

% add padding for time steps

10284

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10299

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10285

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10300

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10286

impulse_response = real(ifft(IL_symmetric));

10301

impulse_response = real(ifft(IL_symmetric));

10287

L = length(impulse_response);

10302

L = length(impulse_response);

10288

t_base = (0:L-1)/(freq_step*L);

10303

t_base = (0:L-1)/(freq_step*L);

10289

10304

10290

original_impulse_response=impulse_response;

10305

original_impulse_response=impulse_response;

10291

% Correct non-causal effects frequently caused by extrapolation of IL

10306

% Correct non-causal effects frequently caused by extrapolation of IL

10292

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10307

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10293

abs_ir=abs(impulse_response);

10308

abs_ir=abs(impulse_response);

10294

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10309

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10295

start_ind = a(1);

10310

start_ind = a(1);

10296

10311

10297

err=inf;

10312

err=inf;

10298

while ~all(impulse_response==0)

10313

while ~all(impulse_response==0)

10299

impulse_response(1:start_ind)=0;

10314

impulse_response(1:start_ind)=0;

10300

impulse_response(floor(L/2):end)=0;

10315

impulse_response(floor(L/2):end)=0;

10301

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10316

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10302

ir_modified = real(ifft(IL_modified));

10317

ir_modified = real(ifft(IL_modified));

10303

delta = abs(impulse_response-ir_modified);

10318

delta = abs(impulse_response-ir_modified);

10304

10319

10305

err_prev = err;

10320

err_prev = err;

10306

err=max(delta)/max(impulse_response);

10321

err=max(delta)/max(impulse_response);

10307

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10322

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10308

break;

10323

break;

10309

end

10324

end

10310

10325

10311

impulse_response=ir_modified;

10326

impulse_response=ir_modified;

10312

end

10327

end

10313

10328

10314

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10329

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10315

10330

10316

if ~OP.ENFORCE_CAUSALITY

10331

if ~OP.ENFORCE_CAUSALITY

10317

impulse_response = original_impulse_response;

10332

impulse_response = original_impulse_response;

10318

end

10333

end

10319

% truncate final samples smaller than 1e-3 of the peak

10334

% truncate final samples smaller than 1e-3 of the peak

10320

ir_peak = max(abs(impulse_response));

10335

ir_peak = max(abs(impulse_response));

10321

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10336

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10322

10337

10323

voltage = impulse_response(1:ir_last);

10338

voltage = impulse_response(1:ir_last);

10324

t_base = t_base(1:ir_last);

10339

t_base = t_base(1:ir_last);

10325

10340

10326

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10341

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10327

10342

10328

function S =s_for_c2(zref,f,cpad)

10343

function S =s_for_c2(zref,f,cpad)

10329

% S is 2 port s parameters out

10344

% S is 2 port s parameters out

10330

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10345

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10331

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10346

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10332

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10347

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10333

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10348

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10334

S=sparameters(S_Parameters,f,zref);

10349

S=sparameters(S_Parameters,f,zref);

10335

10350

10336

function S =s_for_c4(zref,f,cpad)

10351

function S =s_for_c4(zref,f,cpad)

10337

10352

10338

S2 = s_for_c2(zref,f,cpad);

10353

S2 = s_for_c2(zref,f,cpad);

10339

S4P=s2_to_s4(S2.Parameters);

10354

S4P=s2_to_s4(S2.Parameters);

10340

S=sparameters(S4P,f,zref);

10355

S=sparameters(S4P,f,zref);

10341

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10356

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10342

10357

10343

10358

10344

10359

10345

10360

10346

%%

10361

%%

10347

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10362

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10348

% save commmend string

10363

% save commmend string

10349

% for saving from interactive queries

10364

% for saving from interactive queries

10350

10365

10351

10366

10352

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10367

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10353

for i=1:num_next+num_fext

10368

for i=1:num_next+num_fext

10354

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10369

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10355

end

10370

end

10356

cmd_str= [ cmd_str ')'];

10371

cmd_str= [ cmd_str ')'];

10357

10372

10358

10373

10359

%%%%% require the RF tool box

10374

%%%%% require the RF tool box

10360

%%

10375

%%

10361

function [ h ] = savefigs( param, OP )

10376

function [ h ] = savefigs( param, OP )

10362

10377

10363

%% find the figures

10378

%% find the figures

10364

hw = waitbar(0,'Saving figures...');

10379

hw = waitbar(0,'Saving figures...');

10365

h = findobj(0, 'Type', 'figure');

10380

h = findobj(0, 'Type', 'figure');

10366

for ii=1:length(h)

10381

for ii=1:length(h)

10367

10382

10368

figname= get(h(ii), 'Name'); % use the figure name as file name

10383

figname= get(h(ii), 'Name'); % use the figure name as file name

10369

if isempty(strfind(figname,param.base))

10384

if isempty(strfind(figname,param.base))

10370

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10385

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10371

end

10386

end

10372

if verLessThan('matlab', '8.4.0')

10387

if verLessThan('matlab', '8.4.0')

10373

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10388

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10374

else

10389

else

10375

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10390

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10376

end

10391

end

10377

figname = strrep(figname,':','-');

10392

figname = strrep(figname,':','-');

10378

figname = strrep(figname,' ','_');

10393

figname = strrep(figname,' ','_');

10379

if OP.SAVE_FIGURES==1

10394

if OP.SAVE_FIGURES==1

10380

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10395

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10381

end

10396

end

10382

%% get x y data

10397

%% get x y data

10383

if OP.SAVE_FIGURE_to_CSV==1

10398

if OP.SAVE_FIGURE_to_CSV==1

10384

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10399

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10385

M=[]; %ncol=1;

10400

M=[]; %ncol=1;

10386

for nk=1:length(h_L)

10401

for nk=1:length(h_L)

10387

% get x and data for a line.

10402

% get x and data for a line.

10388

x_data=get(h_L(nk),'xdata')';

10403

x_data=get(h_L(nk),'xdata')';

10389

y_data=get(h_L(nk),'ydata')';

10404

y_data=get(h_L(nk),'ydata')';

10390

% .........>> need to get data in the line structure (legend or label) for headers

10405

% .........>> need to get data in the line structure (legend or label) for headers

10391

M=[M; x_data; y_data]; %#ok<AGROW>

10406

M=[M; x_data; y_data]; %#ok<AGROW>

10392

end

10407

end

10393

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10408

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10394

% clear M y x header h_L

10409

% clear M y x header h_L

10395

end

10410

end

10396

waitbar(ii/length(h),hw)

10411

waitbar(ii/length(h),hw)

10397

10412

10398

end

10413

end

10399

10414

10400

close(hw)

10415

close(hw)

10401

10416

10402

%%

10417

%%

10403

function [ h ] = savefigs_png( param, OP )

10418

function [ h ] = savefigs_png( param, OP )

10404

10419

10405

%% find the figures

10420

%% find the figures

10406

hw = waitbar(0,'Saving figures...');

10421

hw = waitbar(0,'Saving figures...');

10407

h = findobj(0, 'Type', 'figure');

10422

h = findobj(0, 'Type', 'figure');

10408

for ii=1:length(h)

10423

for ii=1:length(h)

10409

10424

10410

figname= get(h(ii), 'Name'); % use the figure name as file name

10425

figname= get(h(ii), 'Name'); % use the figure name as file name

10411

if isempty(strfind(figname,param.base))

10426

if isempty(strfind(figname,param.base))

10412

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10427

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10413

end

10428

end

10414

if verLessThan('matlab', '8.4.0')

10429

if verLessThan('matlab', '8.4.0')

10415

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10430

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10416

else

10431

else

10417

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10432

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10418

end

10433

end

10419

figname = strrep(figname,':','-');

10434

figname = strrep(figname,':','-');

10420

figname = strrep(figname,' ','_');

10435

figname = strrep(figname,' ','_');

10421

if OP.SAVE_FIGURES==1

10436

if OP.SAVE_FIGURES==1

10422

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10437

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10423

end

10438

end

10424

%% get x y data

10439

%% get x y data

10425

if OP.SAVE_FIGURE_to_CSV==1

10440

if OP.SAVE_FIGURE_to_CSV==1

10426

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10441

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10427

M=[]; %ncol=1;

10442

M=[]; %ncol=1;

10428

for nk=1:length(h_L)

10443

for nk=1:length(h_L)

10429

% get x and data for a line.

10444

% get x and data for a line.

10430

x_data=get(h_L(nk),'xdata')';

10445

x_data=get(h_L(nk),'xdata')';

10431

y_data=get(h_L(nk),'ydata')';

10446

y_data=get(h_L(nk),'ydata')';

10432

% .........>> need to get data in the line structure (legend or label) for headers

10447

% .........>> need to get data in the line structure (legend or label) for headers

10433

M=[M; x_data; y_data]; %#ok<AGROW>

10448

M=[M; x_data; y_data]; %#ok<AGROW>

10434

end

10449

end

10435

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10450

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10436

% clear M y x header h_L

10451

% clear M y x header h_L

10437

end

10452

end

10438

waitbar(ii/length(h),hw)

10453

waitbar(ii/length(h),hw)

10439

10454

10440

end

10455

end

10441

10456

10442

close(hw)

10457

close(hw)

10443

10458

10444

%%

10459

%%

10445

function pdf_out = scalePDF(pdf,scale_factor)

10460

function pdf_out = scalePDF(pdf,scale_factor)

10446

pdf_out=pdf;

10461

pdf_out=pdf;

10447

pdf_out.Min=floor(pdf.Min*scale_factor);

10462

pdf_out.Min=floor(pdf.Min*scale_factor);

10448

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10463

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10449

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10464

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10450

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10465

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10451

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10466

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10452

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10467

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10453

function t_params = stot(s_params)

10468

function t_params = stot(s_params)

10454

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10469

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10455

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10470

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10456

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10471

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10457

delta = (s11.*s22-s12.*s21);

10472

delta = (s11.*s22-s12.*s21);

10458

s21(s21==0)=eps;

10473

s21(s21==0)=eps;

10459

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10474

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10460

10475

10461

function csv_string = str2csv(c)

10476

function csv_string = str2csv(c)

10462

% convert a cell array of strings to a csv string

10477

% convert a cell array of strings to a csv string

10463

cell_tmp = cell(2, length(c));

10478

cell_tmp = cell(2, length(c));

10464

cell_tmp(1,:)=c;

10479

cell_tmp(1,:)=c;

10465

cell_tmp(2,:) = {','};

10480

cell_tmp(2,:) = {','};

10466

cell_tmp{2,end} = '';

10481

cell_tmp{2,end} = '';

10467

csv_string=strcat(cell_tmp{:});

10482

csv_string=strcat(cell_tmp{:});

10468

10483

10469

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10484

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10470

f_GHz=f/1e9;

10485

f_GHz=f/1e9;

10471

%% Equation 93A-10 %%

10486

%% Equation 93A-10 %%

10472

gamma_1 = gamma_coeff(2)*(1+1i);

10487

gamma_1 = gamma_coeff(2)*(1+1i);

10473

%% Equation 93A-11 %%

10488

%% Equation 93A-11 %%

10474

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10489

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10475

%% Equation 93A-9 %%

10490

%% Equation 93A-9 %%

10476

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10491

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10477

gamma(f_GHz==0) = gamma_coeff(1);

10492

gamma(f_GHz==0) = gamma_coeff(1);

10478

10493

10479

%% Equation 93A-12 %%

10494

%% Equation 93A-12 %%

10480

if d==0

10495

if d==0

10481

%force matched impedance if length is 0

10496

%force matched impedance if length is 0

10482

%otherwise divide by zero can occur if Z_c=0

10497

%otherwise divide by zero can occur if Z_c=0

10483

rho_rl=0;

10498

rho_rl=0;

10484

else

10499

else

10485

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10500

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10486

end

10501

end

10487

10502

10488

exp_gamma_d = exp(-d*gamma);

10503

exp_gamma_d = exp(-d*gamma);

10489

%% Equations 93A-13 and 93A-14 %%

10504

%% Equations 93A-13 and 93A-14 %%

10490

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10505

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10491

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10506

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10492

s12 = s21;

10507

s12 = s21;

10493

s22 = s11;

10508

s22 = s11;

10494

10509

10495

function s_params = ttos(t_params)

10510

function s_params = ttos(t_params)

10496

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10511

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10497

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10512

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10498

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10513

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10499

delta = t11.*t22-t21.*t12;

10514

delta = t11.*t22-t21.*t12;

10500

t11(t11==0)=eps;

10515

t11(t11==0)=eps;

10501

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10516

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10502

10517

10503

function [out_var,varg_out]=varargin_extractor(varargin)

10518

function [out_var,varg_out]=varargin_extractor(varargin)

10504

10519

10505

if isempty(varargin)

10520

if isempty(varargin)

10506

out_var=[];

10521

out_var=[];

10507

varg_out={};

10522

varg_out={};

10508

else

10523

else

10509

out_var=varargin{1};

10524

out_var=varargin{1};

10510

varg_out=varargin;

10525

varg_out=varargin;

10511

varg_out(1)=[];

10526

varg_out(1)=[];

10512

end

10527

end

10513

10528

10514

10529

10515

function results= vma(PR, M)

10530

function results= vma(PR, M)

10516

% PR=sbr.Data;

10531

% PR=sbr.Data;

10517

% M=32;

10532

% M=32;

10518

% PR is the pulse response

10533

% PR is the pulse response

10519

% M is samples per UI

10534

% M is samples per UI

10520

[ seq, syms, syms_nrz ] = PRBS13Q( );

10535

[ seq, syms, syms_nrz ] = PRBS13Q( );

10521

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10536

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10522

symbols=seq;

10537

symbols=seq;

10523

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10538

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10524

% start end symbols index for 7 3's and 6 0's

10539

% start end symbols index for 7 3's and 6 0's

10525

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10540

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10526

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10541

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10527

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10542

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10528

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10543

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10529

% superposition code

10544

% superposition code

10530

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10545

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10531

Bit_stream_response=filter(PR,1, shifting_vector);

10546

Bit_stream_response=filter(PR,1, shifting_vector);

10532

% find center of 3's and 0's

10547

% find center of 3's and 0's

10533

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10548

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10534

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10549

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10535

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10550

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10536

% hold on

10551

% hold on

10537

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10552

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10538

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10553

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10539

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10554

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10540

VMA= P_3 - P_0;

10555

VMA= P_3 - P_0;

10541

results.P_3=P_3;

10556

results.P_3=P_3;

10542

results.P_0=P_0;

10557

results.P_0=P_0;

10543

results.VMA=VMA;

10558

results.VMA=VMA;

10544

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10559

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10545

10560

10546

%slope of the 2 sample points around vref crossing

10561

%slope of the 2 sample points around vref crossing

10547

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10562

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10548

%x-intercept for the line

10563

%x-intercept for the line

10549

b1=eye_contour(x_in,1)-m1*x_in;

10564

b1=eye_contour(x_in,1)-m1*x_in;

10550

% drawing a horizontal line through vref so slope = 0

10565

% drawing a horizontal line through vref so slope = 0

10551

m2=0;

10566

m2=0;

10552

%special case for horizontal line, b=y

10567

%special case for horizontal line, b=y

10553

b2=vref;

10568

b2=vref;

10554

%the x-value of line intersection = (b2-b1)/(m1-m2)

10569

%the x-value of line intersection = (b2-b1)/(m1-m2)

10555

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10570

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10556

%And usually vref is 0, so it further reduces to -b1/m1

10571

%And usually vref is 0, so it further reduces to -b1/m1

10557

line_intersection=(b2-b1)/(m1-m2);

10572

line_intersection=(b2-b1)/(m1-m2);

10558

10573

10559

10574

10560

10575

10561

10576

10562

10577

10563

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10578

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10564

% helper function to read parameter values from XLS file. Uses names to find values.

10579

% helper function to read parameter values from XLS file. Uses names to find values.

10565

if nargin<3, eval_if_string=0; end

10580

if nargin<3, eval_if_string=0; end

10566

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10581

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10567

if numel(row)*numel(col)==0

10582

if numel(row)*numel(col)==0

10568

if nargin<4

10583

if nargin<4

10569

missingParameter(param_name);

10584

missingParameter(param_name);

10570

else

10585

else

10571

p = default_value;

10586

p = default_value;

10572

end

10587

end

10573

elseif numel(row)*numel(col)>1

10588

elseif numel(row)*numel(col)>1

10574

% if there are several occurrences, use the first, but warn

10589

% if there are several occurrences, use the first, but warn

10575

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10590

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10576

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10591

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10577

error('COM:XLS_parameter:MultipleOccurrence', ...

10592

error('COM:XLS_parameter:MultipleOccurrence', ...

10578

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10593

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10579

p=param_sheet{row(1), col(1)+1};

10594

p=param_sheet{row(1), col(1)+1};

10580

else

10595

else

10581

p=param_sheet{row, col+1};

10596

p=param_sheet{row, col+1};

10582

end

10597

end

10583

if ischar(p) && eval_if_string

10598

if ischar(p) && eval_if_string

10584

p=eval(p);

10599

p=eval(p);

10585

end

10600

end

10586

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10601

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10587

if OP.SAVE_KEYWORD_FILE

10602

if OP.SAVE_KEYWORD_FILE

10588

10603

10589

if nargin<3 || ~exist('default_value','var')

10604

if nargin<3 || ~exist('default_value','var')

10590

default_value=p;

10605

default_value=p;

10591

end

10606

end

10592

if isempty(default_value)

10607

if isempty(default_value)

10593

default_value='-';

10608

default_value='-';

10594

end

10609

end

10595

%%

10610

%%

10596

% Get call-stack info:

10611

% Get call-stack info:

10597

stDebug = dbstack;

10612

stDebug = dbstack;

10598

callerFileName = stDebug(2).file;

10613

callerFileName = stDebug(2).file;

10599

callerLineNumber = stDebug(2).line;

10614

callerLineNumber = stDebug(2).line;

10600

% Open caller file:

10615

% Open caller file:

10601

fCaller = fopen(callerFileName);

10616

fCaller = fopen(callerFileName);

10602

% Iterate through lines to get to desired line number:

10617

% Iterate through lines to get to desired line number:

10603

for iLine = 1 : callerLineNumber

10618

for iLine = 1 : callerLineNumber

10604

% Read current line of text:

10619

% Read current line of text:

10605

currLine = fgetl(fCaller);

10620

currLine = fgetl(fCaller);

10606

end

10621

end

10607

% (currLine) now reflects calling desired code: display this code:

10622

% (currLine) now reflects calling desired code: display this code:

10608

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10623

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10609

% Close caller file:

10624

% Close caller file:

10610

left_side=currLine(1:strfind(currLine,'=')-1);

10625

left_side=currLine(1:strfind(currLine,'=')-1);

10611

cmt_side=currLine(strfind(currLine,'%')+1:end);

10626

cmt_side=currLine(strfind(currLine,'%')+1:end);

10612

if isempty(cmt_side), cmt_side=' ';end

10627

if isempty(cmt_side), cmt_side=' ';end

10613

fclose(fCaller);

10628

fclose(fCaller);

10614

10629

10615

if ~ischar(default_value)

10630

if ~ischar(default_value)

10616

default_str=sprintf('%g ',default_value);

10631

default_str=sprintf('%g ',default_value);

10617

else

10632

else

10618

default_str=default_value;

10633

default_str=default_value;

10619

end

10634

end

10620

if ~isfile('keyworklog.mat')

10635

if ~isfile('keyworklog.mat')

10621

save_p=param_name;

10636

save_p=param_name;

10622

save_d=default_str;

10637

save_d=default_str;

10623

save_r=left_side;

10638

save_r=left_side;

10624

save_c=cmt_side;

10639

save_c=cmt_side;

10625

param_name = {'keyword'};

10640

param_name = {'keyword'};

10626

default_str = {'default'};

10641

default_str = {'default'};

10627

left_side={'matlab variable'};

10642

left_side={'matlab variable'};

10628

cmt_side={'info'};

10643

cmt_side={'info'};

10629

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10644

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10630

param_name=save_p;

10645

param_name=save_p;

10631

default_str=save_d;

10646

default_str=save_d;

10632

left_side=save_r;

10647

left_side=save_r;

10633

cmt_side=save_c;

10648

cmt_side=save_c;

10634

data=load('keyworklog.mat');

10649

data=load('keyworklog.mat');

10635

else

10650

else

10636

load('keyworklog.mat');

10651

load('keyworklog.mat');

10637

end

10652

end

10638

data.left_side = [ data.left_side; left_side];

10653

data.left_side = [ data.left_side; left_side];

10639

data.param_name = [data.param_name; param_name];

10654

data.param_name = [data.param_name; param_name];

10640

data.default_str = [data.default_str; default_str ];

10655

data.default_str = [data.default_str; default_str ];

10641

data.cmt_side = [ data.cmt_side; cmt_side];

10656

data.cmt_side = [ data.cmt_side; cmt_side];

10642

if length(data.default_str)~=length(data.default_str)

10657

if length(data.default_str)~=length(data.default_str)

10643

a=1;

10658

a=1;

10644

end

10659

end

10645

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10660

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10646

save('keyworklog.mat','data');

10661

save('keyworklog.mat','data');

10647

writetable(T,[ 'keywords_' date '.csv' ]);

10662

writetable(T,[ 'keywords_' date '.csv' ]);

10648

end

10663

end

10649

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10664

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10650

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10665

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10651

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10666

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10652

10667

10653

found=1;

10668

found=1;

10654

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10669

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10655

if numel(row)*numel(col)==0

10670

if numel(row)*numel(col)==0

10656

p = 0;

10671

p = 0;

10657

found=0;

10672

found=0;

10658

elseif numel(row)*numel(col)>1

10673

elseif numel(row)*numel(col)>1

10659

% if there are several occurrences, use the first, but warn

10674

% if there are several occurrences, use the first, but warn

10660

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10675

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10661

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10676

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10662

error('COM:XLS_parameter:MultipleOccurrence', ...

10677

error('COM:XLS_parameter:MultipleOccurrence', ...

10663

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10678

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10664

p=param_sheet{row(1), col(1)+1};

10679

p=param_sheet{row(1), col(1)+1};

10665

else

10680

else

10666

p=param_sheet{row, col+1};

10681

p=param_sheet{row, col+1};

10667

end

10682

end

10668

if ischar(p)

10683

if ischar(p)

10669

p=eval(p);

10684

p=eval(p);

10670

end

10685

end

10671

function zzz_list_of_changes

10686

function zzz_list_of_changes

10672

% structures:

10687

% structures:

10673

% chdata(i)

10688

% chdata(i)

10674

% i= 1 --> THRU index

10689

% i= 1 --> THRU index

10675

% i= 2, num_fext+1 --> FEXT channel index

10690

% i= 2, num_fext+1 --> FEXT channel index

10676

% i= num_fext+2, num_next+num_fext+1

10691

% i= num_fext+2, num_next+num_fext+1

10677

% base: name of THRU file

10692

% base: name of THRU file

10678

% A: amplitude

10693

% A: amplitude

10679

% type: 'THRU', 'NEXT', or 'FEXT'

10694

% type: 'THRU', 'NEXT', or 'FEXT'

10680

% ftr: Rise time frequency

10695

% ftr: Rise time frequency

10681

% fmaxi: max number of frequency points

10696

% fmaxi: max number of frequency points

10682

% faxis: frequency array [Hz]

10697

% faxis: frequency array [Hz]

10683

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10698

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10684

% sdd22: differential RL

10699

% sdd22: differential RL

10685

% sdd11: differential RL

10700

% sdd11: differential RL

10686

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10701

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10687

% sdd21f: raw differential IL not filtered use for FD plots

10702

% sdd21f: raw differential IL not filtered use for FD plots

10688

% added output_args.peak_uneq_pulse_mV

10703

% added output_args.peak_uneq_pulse_mV

10689

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10704

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10690

% added: tap c(-2) c(2) and c(3)

10705

% added: tap c(-2) c(2) and c(3)

10691

% added: g_DC_HP and f_HP_PZ

10706

% added: g_DC_HP and f_HP_PZ

10692

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10707

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10693

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10708

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10694

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10709

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10695

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10710

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10696

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10711

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10697

% fixed INCLUDE_CTLE=0 to really remove from computation

10712

% fixed INCLUDE_CTLE=0 to really remove from computation

10698

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10713

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10699

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10714

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10700

% r162 tx and rx package impedance {Zc)

10715

% r162 tx and rx package impedance {Zc)

10701

% r162a Gaussian equation corrected

10716

% r162a Gaussian equation corrected

10702

% r163 cast snr_tx with package test case

10717

% r163 cast snr_tx with package test case

10703

% r164 fix pdf for very low noise and lo pass filter enhancements

10718

% r164 fix pdf for very low noise and lo pass filter enhancements

10704

% r164 add zero gain at nqyist CTLE as in CL12e

10719

% r164 add zero gain at nqyist CTLE as in CL12e

10705

% r165 add simpler congfig command called FORCE_TR (force risetime)

10720

% r165 add simpler congfig command called FORCE_TR (force risetime)

10706

% r200 cm3 and cm4 added cp3 removed

10721

% r200 cm3 and cm4 added cp3 removed

10707

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10722

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10708

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10723

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10709

% r200 improved phase interpolation for return loss time conversion

10724

% r200 improved phase interpolation for return loss time conversion

10710

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10725

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10711

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10726

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10712

% r200c missed on fix for interpolation

10727

% r200c missed on fix for interpolation

10713

% r210 new ERL with time gating function

10728

% r210 new ERL with time gating function

10714

% r224 update ERL with from D3.1

10729

% r224 update ERL with from D3.1

10715

% r226 fix s2p reading problem

10730

% r226 fix s2p reading problem

10716

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10731

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10717

% Fix Rx calibration issue

10732

% Fix Rx calibration issue

10718

% added ERL limit and Nd

10733

% added ERL limit and Nd

10719

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10734

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10720

% INC_PACKAGE=0 not fully supported message

10735

% INC_PACKAGE=0 not fully supported message

10721

% if N=0 use TDR_duration

10736

% if N=0 use TDR_duration

10722

% red display text for fail ERL and COM

10737

% red display text for fail ERL and COM

10723

% r228 fixed ERL pass fail report, default Grr_limit to 1

10738

% r228 fixed ERL pass fail report, default Grr_limit to 1

10724

% r230 add rx ffe

10739

% r230 add rx ffe

10725

% r231 change crosstalk noise to icn like to speed things up

10740

% r231 change crosstalk noise to icn like to speed things up

10726

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10741

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10727

% 1e-5mof-

10742

% 1e-5mof-

10728

% r232 fix default for Rx eq so old spead sheets work

10743

% r232 fix default for Rx eq so old spead sheets work

10729

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10744

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10730

% r235 adding dfe quantization changed to normalized DFE taps reported

10745

% r235 adding dfe quantization changed to normalized DFE taps reported

10731

% r236 adding ffe gain loop and resample after RxFFE

10746

% r236 adding ffe gain loop and resample after RxFFE

10732

% r240 added output for C2M and setting defaults for some FFE eq

10747

% r240 added output for C2M and setting defaults for some FFE eq

10733

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10748

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10734

% r250 adding more complex package

10749

% r250 adding more complex package

10735

% r251 post cursor fix for DFE in force() and ffe backoff

10750

% r251 post cursor fix for DFE in force() and ffe backoff

10736

% r251 remove TDR threshold noise filter

10751

% r251 remove TDR threshold noise filter

10737

% r252 add rx FFE filter to receiver noise filter

10752

% r252 add rx FFE filter to receiver noise filter

10738

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10753

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10739

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10754

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10740

% r254 precursor check fix in optimize_fom % mod fix in force

10755

% r254 precursor check fix in optimize_fom % mod fix in force

10741

% r254 help to align columns in csv file

10756

% r254 help to align columns in csv file

10742

% r254 accept syntax for 2 tline flex package model

10757

% r254 accept syntax for 2 tline flex package model

10743

% r256 speed up optimize FOM

10758

% r256 speed up optimize FOM

10744

% r256 fix problem reading in config file from q/a

10759

% r256 fix problem reading in config file from q/a

10745

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10760

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10746

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10761

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10747

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10762

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10748

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10763

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10749

% r258 CDR switch 'MM' or 'mod-MM'

10764

% r258 CDR switch 'MM' or 'mod-MM'

10750

% r258 correction for asymentirc tx/Rx packages

10765

% r258 correction for asymentirc tx/Rx packages

10751

% r258 revamped display results display window

10766

% r258 revamped display results display window

10752

% r259 fix problem if Min_VEO is set in spreadsheet.

10767

% r259 fix problem if Min_VEO is set in spreadsheet.

10753

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10768

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10754

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10769

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10755

% r259 putting COM_db and IL last in output to terminal

10770

% r259 putting COM_db and IL last in output to terminal

10756

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10771

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10757

% r259 use N_bx for ERL rather than Nb (ndfe))

10772

% r259 use N_bx for ERL rather than Nb (ndfe))

10758

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10773

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10759

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10774

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10760

% r260 used eta_0 PSD equation for sigma_n

10775

% r260 used eta_0 PSD equation for sigma_n

10761

% r260 fix IL graph legend to w/pkg and Tr

10776

% r260 fix IL graph legend to w/pkg and Tr

10762

% r260 define tfx for each port

10777

% r260 define tfx for each port

10763

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10778

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10764

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10779

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10765

% r262 reset on exit default text interpreter to tex

10780

% r262 reset on exit default text interpreter to tex

10766

% r262 localize run timer (John Buck 1/17/19)

10781

% r262 localize run timer (John Buck 1/17/19)

10767

% r262 set db as internal function in force to avoid tool box

10782

% r262 set db as internal function in force to avoid tool box

10768

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10783

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10769

% r263 added to output_args RL structure and report "struct" in csv file

10784

% r263 added to output_args RL structure and report "struct" in csv file

10770

% r264 added EW estimate

10785

% r264 added EW estimate

10771

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10786

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10772

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10787

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10773

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10788

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10774

% r269 changed param.N_bmax to param.N_f

10789

% r269 changed param.N_bmax to param.N_f

10775

% r270 implement JingBo Li's and Howard Heck's floating tap method

10790

% r270 implement JingBo Li's and Howard Heck's floating tap method

10776

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10791

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10777

% r270 added c_0 and c_1 for CA in add_brd

10792

% r270 added c_0 and c_1 for CA in add_brd

10778

% r272 fixed version syntax problem in output_args RL report

10793

% r272 fixed version syntax problem in output_args RL report

10779

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10794

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10780

% r272 removed eye width report if doing a Rx calibration

10795

% r272 removed eye width report if doing a Rx calibration

10781

% r273 better alignment and control for ICN reporting

10796

% r273 better alignment and control for ICN reporting

10782

% r273 fixed PSXTK graph

10797

% r273 fixed PSXTK graph

10783

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10798

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10784

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10799

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10785

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10800

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10786

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10801

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10787

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10802

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10788

% r276 C_1 was instantiated as C_0. This was fixed

10803

% r276 C_1 was instantiated as C_0. This was fixed

10789

% r276 fixed rounding problem in reporting of loss at f_nq

10804

% r276 fixed rounding problem in reporting of loss at f_nq

10790

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10805

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10791

% r277 added nv for deterining steady state voltage for fitting compatibility

10806

% r277 added nv for deterining steady state voltage for fitting compatibility

10792

% r278 added b_min to support asymmetric bmax

10807

% r278 added b_min to support asymmetric bmax

10793

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10808

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10794

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10809

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10795

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10810

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10796

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10811

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10797

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10812

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10798

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10813

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10799

% r292 H_t implemented in s21_pkg

10814

% r292 H_t implemented in s21_pkg

10800

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10815

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10801

% r292 add GDC_MIN to optimize_FOM

10816

% r292 add GDC_MIN to optimize_FOM

10802

% r293 fix if ndfe-0 and ERL only and s2p issue

10817

% r293 fix if ndfe-0 and ERL only and s2p issue

10803

% r293a investigate the Tukey filtering

10818

% r293a investigate the Tukey filtering

10804

% r293a if fix if bmin is missing

10819

% r293a if fix if bmin is missing

10805

% r294 fix problems reading s2p files for ERL computation

10820

% r294 fix problems reading s2p files for ERL computation

10806

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10821

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10807

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10822

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10808

% r294 add gdc and gdc2 range limitations

10823

% r294 add gdc and gdc2 range limitations

10809

% r295 add VEC Pass threshold

10824

% r295 add VEC Pass threshold

10810

% r295 removed close force all. Tagged all figures with "COM"

10825

% r295 removed close force all. Tagged all figures with "COM"

10811

% r295 consolidated print in new function "end_display_control"

10826

% r295 consolidated print in new function "end_display_control"

10812

% r295 report pre/pmax for Txffe

10827

% r295 report pre/pmax for Txffe

10813

% r295 speed up test cases by not re-reading in s4p files

10828

% r295 speed up test cases by not re-reading in s4p files

10814

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10829

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10815

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10830

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10816

% r310 refine VEC and EH for C2M from Adam Gregory in

10831

% r310 refine VEC and EH for C2M from Adam Gregory in

10817

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10832

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10818

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10833

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10819

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10834

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10820

% r311 added RILN

10835

% r311 added RILN

10821

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10836

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10822

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10837

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10823

% r316 remove DC computation for RX Calibration loops

10838

% r316 remove DC computation for RX Calibration loops

10824

% r317 for SAVE_TD to include EQ and unEQ FIR

10839

% r317 for SAVE_TD to include EQ and unEQ FIR

10825

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10840

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10826

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10841

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10827

% r320 fixed RX_CALIBRATION which was broken in r310

10842

% r320 fixed RX_CALIBRATION which was broken in r310

10828

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10843

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10829

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10844

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10830

% r320 removed external feature and replace with TDMODE

10845

% r320 removed external feature and replace with TDMODE

10831

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10846

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10832

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10847

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10833

% r335 fixed typo in when processing the bessel thompson filter option

10848

% r335 fixed typo in when processing the bessel thompson filter option

10834

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10849

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10835

% r335 compute and report CD_CM_RMS

10850

% r335 compute and report CD_CM_RMS

10836

% r335 fixed where output_arg is save i.e. move to end

10851

% r335 fixed where output_arg is save i.e. move to end

10837

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10852

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10838

% r335 change raw IL plot to not include boards

10853

% r335 change raw IL plot to not include boards

10839

% r335 set T_0 to zero if not C2M

10854

% r335 set T_0 to zero if not C2M

10840

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10855

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10841

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10856

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10842

% r335 TD_RILN changes from Hansel Dsilva

10857

% r335 TD_RILN changes from Hansel Dsilva

10843

% r335 Fixed sigma_N for RxFFE

10858

% r335 Fixed sigma_N for RxFFE

10844

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10859

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10845

% r335 added c(2) and C(3) back to read_ParamConfigFile

10860

% r335 added c(2) and C(3) back to read_ParamConfigFile

10846

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10861

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10847

% r335 corrected GDC_MIN per 0.3ck D2.3

10862

% r335 corrected GDC_MIN per 0.3ck D2.3

10848

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10863

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10849

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10864

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10850

% r370 speed up

10865

% r370 speed up

10851

% r370 fix for floating tap missing locations

10866

% r370 fix for floating tap missing locations

10852

% r370 variable Tx FFE taps

10867

% r370 variable Tx FFE taps

10853

% r370 package die load with ladder circuit

10868

% r370 package die load with ladder circuit

10854

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10869

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10855

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10870

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10856

% r380 added capabablity to enable a raised cosine Rx filter0

10871

% r380 added capabablity to enable a raised cosine Rx filter0

10857

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10872

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10858

% r380 added plot for VTF

10873

% r380 added plot for VTF

10859

% r385 added capability for additional Tx FFE per package

10874

% r385 added capability for additional Tx FFE per package

10860

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10875

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10861

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10876

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10862

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10877

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10863

% r389 Improvement by A. Ran for reporting loss at Nq

10878

% r389 Improvement by A. Ran for reporting loss at Nq

10864

% r389 Fixed typo: changed VIM to VMP

10879

% r389 Fixed typo: changed VIM to VMP

10865

% r400 fixed PR with zero pad extension

10880

% r400 fixed PR with zero pad extension

10866

% r400 keyword MLSE and SNRADJ_EQUA for future work

10881

% r400 keyword MLSE and SNRADJ_EQUA for future work

10867

% r400 replaced function db with instances of 20*log10(abs(...))

10882

% r400 replaced function db with instances of 20*log10(abs(...))

10868

% r410 widen voltage distriution for normal_dist doubled max Q

10883

% r410 widen voltage distriution for normal_dist doubled max Q

10869

% r410 improve reading in of config files

10884

% r410 improve reading in of config files

10870

% r410 renormalize s-parameter if not 50 ohm ref

10885

% r410 renormalize s-parameter if not 50 ohm ref

10871

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10886

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10872

% r410 remove RL from output_args bc not need and too much storage allocation

10887

% r410 remove RL from output_args bc not need and too much storage allocation

10873

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10888

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10874

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10889

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10875

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10890

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10876

% r420 updade force to account for pulse responces with short delays in force

10891

% r420 updade force to account for pulse responces with short delays in force

10877

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10892

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10878

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10893

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10879

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10894

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10880

% r420 Wiener-Kofp MMSE optimization for RxFFE

10895

% r420 Wiener-Kofp MMSE optimization for RxFFE

10881

% r430 first pass at healey_3dj_01_2401

10896

% r430 first pass at healey_3dj_01_2401

10882

% r430 RxFFE fixed taps

10897

% r430 RxFFE fixed taps

10883

% r440 RxffE fixed tap index corrections and floating taps

10898

% r440 RxffE fixed tap index corrections and floating taps

10884

% r440 first pass implemenation of MLSE U3

10899

% r440 first pass implemenation of MLSE U3

10885

10900