File Comparison Report

C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_480beta2.m vs. C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_480beta1.m

richardm

09-Dec-2024

Files

Left FileRight File
File namecom_ieee8023_93a_480beta2com_ieee8023_93a_480beta1
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified09-Dec-2024 14:27:1403-Dec-2024 12:35:57

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

% at this point chdata(1).eq_pulse_response has the tx and rx FFE and CTF applied

451

% at this point chdata(1).eq_pulse_response has the tx and rx FFE and CTF applied

452

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

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);

453

OP.WO_TXFFE=0;

453

OP.WO_TXFFE=0;

454

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

454

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

455

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

455

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

456

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

456

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

457

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

457

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

458

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

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);

459

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

459

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

460

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

460

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

461

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

461

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

462

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

462

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

463

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

463

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

464

end

464

end

465

%% Create ISI PDF & Individual Crosstalk PDFs

465

%% Create ISI PDF & Individual Crosstalk PDFs

466

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

466

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

467

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

467

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

468

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

468

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

469

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

469

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

470

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

470

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

471

for i=1:param.number_of_s4p_files

471

for i=1:param.number_of_s4p_files

472

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

472

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

473

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

473

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

474

474

475

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

475

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

476

else

476

else

477

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

477

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

478

end

478

end

479

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

479

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

480

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

480

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

481

subplot(2,1,2);

481

subplot(2,1,2);

482

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

482

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

483

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

483

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

484

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

484

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

485

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

485

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

486

hold on; title('PDF')

486

hold on; title('PDF')

487

recolor_plots(gca);

487

recolor_plots(gca);

488

end

488

end

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 && OP.MLSE == 0

524

if OP.RX_CALIBRATION ==0 && OP.EW == 1 && OP.MLSE == 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);

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

570

else

571

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

571

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

572

[MLSE_results] = MLSE_U1_c_178A(param,fom_result.MMSE_results.blim,A_s,A_ni,PDF,CDF,PSD_results);% align to (178A –39)

572

[MLSE_results] = MLSE_U1_c_178A(param,fom_result.MMSE_results.blim,A_s,A_ni,PDF,CDF,PSD_results);% align to (178A –39)

573

if param.T_O ~=0

573

if param.T_O ~=0

574

eye_opening=EH_T_C2M-EH_B_C2M;

574

eye_opening=EH_T_C2M-EH_B_C2M;

575

A_ni=2*A_s-eye_opening;

575

A_ni=2*A_s-eye_opening;

576

%eq 124E-4

576

%eq 124E-4

577

vec_arg=2*A_s/eye_opening;

577

vec_arg=2*A_s/eye_opening;

578

if vec_arg<eps

578

if vec_arg<eps

579

vec_arg=eps;

579

vec_arg=eps;

580

end

580

end

581

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

581

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

582

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

582

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

583

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

583

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

584

COM=MLSE_results.COM;

584

COM=MLSE_results.COM;

585

VEO_mV=eye_opening*1000;

585

VEO_mV=eye_opening*1000;

586

min_COM = min(min_COM, COM);

586

min_COM = min(min_COM, COM);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

591

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

592

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

592

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

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

595

else

595

else

596

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

596

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

597

vec_arg=(A_s-A_ni)/A_s;

597

vec_arg=(A_s-A_ni)/A_s;

598

if vec_arg<eps

598

if vec_arg<eps

599

vec_arg=eps;

599

vec_arg=eps;

600

end

600

end

601

VEC_dB_orig = -20*log10(vec_arg);

601

VEC_dB_orig = -20*log10(vec_arg);

602

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

602

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

603

COM_orig=20*log10(A_s/A_ni);

603

COM_orig=20*log10(A_s/A_ni);

604

COM=MLSE_results.COM;

604

COM=MLSE_results.COM;

605

min_COM = min(min_COM, COM);

605

min_COM = min(min_COM, COM);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

611

COM_SNR_Struct.VEC_dB=VEC_dB;

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

if OP.MLSE ~= 0

658

if OP.MLSE ~= 0

659

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

659

COM_SNR_Struct.combined_interference_and_noise_pdf=MLSE_results.PDF;

660

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

660

COM_SNR_Struct.combined_interference_and_noise_cdf=MLSE_results.CDF;

661

end

661

end

662

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

662

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

663

end

663

end

664

664

665

%% Msg management

665

%% Msg management

666

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

666

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

667

msg=[];

667

msg=[];

668

end

668

end

669

if OP.DEBUG

669

if OP.DEBUG

670

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

670

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

671

switch param.flex

671

switch param.flex

672

case 4

672

case 4

673

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', ...

673

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', ...

674

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

674

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

675

);

675

);

676

case 2

676

case 2

677

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

677

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

678

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) ...

678

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) ...

679

);

679

);

680

otherwise

680

otherwise

681

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

681

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

682

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

682

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

683

);

683

);

684

684

685

end

685

end

686

else

686

else

687

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

687

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

688

end

688

end

689

689

690

if OP.TDMODE

690

if OP.TDMODE

691

min_ERL=inf;

691

min_ERL=inf;

692

ERL=[inf inf];

692

ERL=[inf inf];

693

end

693

end

694

[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

694

[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

695

695

696

696

697

%% Output Args

697

%% Output Args

698

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

698

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

699

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

699

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

700

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

700

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

701

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

701

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

702

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

702

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

703

rt=toc(t0);

703

rt=toc(t0);

704

output_args.rtmin=rt/60;

704

output_args.rtmin=rt/60;

705

705

706

if OP.BREAD_CRUMBS

706

if OP.BREAD_CRUMBS

707

output_args.OP=OP;

707

output_args.OP=OP;

708

output_args.param=param;

708

output_args.param=param;

709

output_args.chdata=chdata;

709

output_args.chdata=chdata;

710

output_args.fom_result = fom_result;

710

output_args.fom_result = fom_result;

711

output_args.PDF=PDF; % for exploration

711

output_args.PDF=PDF; % for exploration

712

output_args.CDF=CDF; % for exploration

712

output_args.CDF=CDF; % for exploration

713

output_args.MLSE_results=MLSE_results;

713

output_args.MLSE_results=MLSE_results;

714

output_args.PSD_results=PSD_results;

714

output_args.PSD_results=PSD_results;

715

end

715

end

716

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

716

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

717

717

718

%% making csv file

718

%% making csv file

719

if OP.CSV_REPORT ==1

719

if OP.CSV_REPORT ==1

720

Write_CSV(output_args,CSV_FILE);

720

Write_CSV(output_args,CSV_FILE);

721

end

721

end

722

%% making mat file

722

%% making mat file

723

if(OP.DEBUG)

723

if(OP.DEBUG)

724

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

724

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

725

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

725

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

726

end

726

end

727

if 1

727

if 1

728

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

728

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

729

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

729

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

730

end

730

end

731

731

732

if nargout==0

732

if nargout==0

733

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

733

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

734

disp(output_args)

734

disp(output_args)

735

end

735

end

736

736

737

if OP.BREAD_CRUMBS

737

if OP.BREAD_CRUMBS

738

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

738

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

739

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

739

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

740

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

740

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

741

try

741

try

742

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

742

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

743

catch

743

catch

744

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

744

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

745

end

745

end

746

end

746

end

747

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

747

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

748

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

748

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

749

end

749

end

750

750

751

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

751

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

752

end

752

end

753

[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);

753

[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);

754

%%

754

%%

755

755

756

if OP.RX_CALIBRATION ==1

756

if OP.RX_CALIBRATION ==1

757

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

757

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

758

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

758

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

759

end

759

end

760

DO_ONCE=false;

760

DO_ONCE=false;

761

end

761

end

762

762

763

%% Final cleanup

763

%% Final cleanup

764

if OP.DISPLAY_WINDOW

764

if OP.DISPLAY_WINDOW

765

savefigs(param, OP);

765

savefigs(param, OP);

766

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

766

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

767

end

767

end

768

768

769

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

769

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

770

if ~param.f_hp==0

770

if ~param.f_hp==0

771

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

771

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

772

if OP.DISPLAY_WINDOW

772

if OP.DISPLAY_WINDOW

773

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

773

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

774

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

774

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

775

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

775

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

776

end

776

end

777

else

777

else

778

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

778

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

779

if OP.DISPLAY_WINDOW

779

if OP.DISPLAY_WINDOW

780

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

780

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

781

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

781

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

782

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

782

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

783

end

783

end

784

end

784

end

785

end

785

end

786

786

787

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

787

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

788

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

788

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

789

disp(redo_cmd_str);

789

disp(redo_cmd_str);

790

if isdeployed

790

if isdeployed

791

if OP.exit_if_deployed

791

if OP.exit_if_deployed

792

quit

792

quit

793

end

793

end

794

end

794

end

795

%%

795

%%

796

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

796

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

797

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

797

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

798

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

798

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

799

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

799

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

800

800

801

FB=param.fb;

801

FB=param.fb;

802

FZ=param.CTLE_fz(fom_result.ctle);

802

FZ=param.CTLE_fz(fom_result.ctle);

803

FP1=param.CTLE_fp1(fom_result.ctle);

803

FP1=param.CTLE_fp1(fom_result.ctle);

804

FP2=param.CTLE_fp2(fom_result.ctle);

804

FP2=param.CTLE_fp2(fom_result.ctle);

805

GDC=param.ctle_gdc_values(fom_result.ctle);

805

GDC=param.ctle_gdc_values(fom_result.ctle);

806

if ~isempty(param.f_HP)

806

if ~isempty(param.f_HP)

807

FHP=param.f_HP(fom_result.best_G_high_pass);

807

FHP=param.f_HP(fom_result.best_G_high_pass);

808

end

808

end

809

if ~isempty(param.g_DC_HP_values)

809

if ~isempty(param.g_DC_HP_values)

810

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

810

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

811

end

811

end

812

if ~isempty(param.f_HP_Z)

812

if ~isempty(param.f_HP_Z)

813

FHPZ=param.f_HP_Z(fom_result.ctle);

813

FHPZ=param.f_HP_Z(fom_result.ctle);

814

end

814

end

815

if ~isempty(param.f_HP_P)

815

if ~isempty(param.f_HP_P)

816

FHPP=param.f_HP_P(fom_result.ctle);

816

FHPP=param.f_HP_P(fom_result.ctle);

817

end

817

end

818

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

818

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

819

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

819

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

820

%length

820

%length

821

SBR_Len=length(fom_result.sbr);

821

SBR_Len=length(fom_result.sbr);

822

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

822

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

823

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

823

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

824

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

824

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

825

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

825

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

826

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

826

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

827

end

827

end

828

for i=1:param.number_of_s4p_files

828

for i=1:param.number_of_s4p_files

829

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

829

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

830

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

830

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

831

if OP.INCLUDE_CTLE==1

831

if OP.INCLUDE_CTLE==1

832

switch param.CTLE_type

832

switch param.CTLE_type

833

case 'CL93'

833

case 'CL93'

834

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

834

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

835

case 'CL120d'

835

case 'CL120d'

836

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

836

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

837

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

837

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

838

case 'CL120e' % z has been adjusted for gain

838

case 'CL120e' % z has been adjusted for gain

839

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

839

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

840

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

840

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

841

end

841

end

842

else

842

else

843

eq_ir=uneq_ir;

843

eq_ir=uneq_ir;

844

end

844

end

845

chdata(i).eq_imp_response=eq_ir;

845

chdata(i).eq_imp_response=eq_ir;

846

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

846

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

847

847

848

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

848

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

849

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

849

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

850

end

850

end

851

851

852

% Next 4 lines determine a pulse response required quantization,

852

% Next 4 lines determine a pulse response required quantization,

853

% at the CTLE output with Tx_ffe

853

% at the CTLE output with Tx_ffe

854

chdata(i).ctle_pulse = eq_pulse;

854

chdata(i).ctle_pulse = eq_pulse;

855

[~, sample_start] = min(abs(chdata(i).t-fom_result.sampled_best_sbr_precursors_t(1)));

855

[~, sample_start] = min(abs(chdata(i).t-fom_result.sampled_best_sbr_precursors_t(1)));

856

chdata(i).pulse_sampled_w_tx_ffe_ctle = eq_pulse(sample_start:param.samples_per_ui:end);

856

chdata(i).pulse_sampled_w_tx_ffe_ctle = eq_pulse(sample_start:param.samples_per_ui:end);

857

chdata(i).t_sampled_w_tx_ffe_ctle = chdata(i).t(sample_start:param.samples_per_ui:end);

857

chdata(i).t_sampled_w_tx_ffe_ctle = chdata(i).t(sample_start:param.samples_per_ui:end);

858

858

859

% chdata(i).ctle_imp_response

859

% chdata(i).ctle_imp_response

860

if OP.RxFFE

860

if OP.RxFFE

861

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

861

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

862

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

862

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

863

end

863

end

864

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

864

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

865

end

865

end

866

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

866

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

867

end

867

end

868

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

868

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

869

869

870

% display bathtub curves in one axis per test case.

870

% display bathtub curves in one axis per test case.

871

case_number=param.package_testcase_i;

871

case_number=param.package_testcase_i;

872

if ~OP.COM_CONTRIBUTION_CURVES

872

if ~OP.COM_CONTRIBUTION_CURVES

873

figure_name = 'Voltage bathtub curves';

873

figure_name = 'Voltage bathtub curves';

874

fig=findobj('Name', figure_name);

874

fig=findobj('Name', figure_name);

875

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

875

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

876

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

876

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

877

movegui(fig,'south')

877

movegui(fig,'south')

878

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

878

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

879

plot_bathtub_curves( hax ...

879

plot_bathtub_curves( hax ...

880

, COM_SNR_Struct.A_s ...

880

, COM_SNR_Struct.A_s ...

881

, Noise_Struct.sci_pdf ...

881

, Noise_Struct.sci_pdf ...

882

, Noise_Struct.cci_pdf ...

882

, Noise_Struct.cci_pdf ...

883

, Noise_Struct.isi_and_xtalk_pdf ...

883

, Noise_Struct.isi_and_xtalk_pdf ...

884

, Noise_Struct.noise_pdf ...

884

, Noise_Struct.noise_pdf ...

885

, Noise_Struct.jitt_pdf ...

885

, Noise_Struct.jitt_pdf ...

886

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

886

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

887

, param.delta_y ...

887

, param.delta_y ...

888

);

888

);

889

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

889

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

890

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

890

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

891

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

891

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

892

% show BER target line

892

% show BER target line

893

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

893

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

894

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

894

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

895

else

895

else

896

figure_name = 'COM Contributions (Rough Allocations)';

896

figure_name = 'COM Contributions (Rough Allocations)';

897

fig=findobj('Name', figure_name);

897

fig=findobj('Name', figure_name);

898

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

898

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

899

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

899

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

900

movegui(fig,'south')

900

movegui(fig,'south')

901

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

901

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

902

902

903

plot_pie_com( hax ...

903

plot_pie_com( hax ...

904

, COM_SNR_Struct.A_s ...

904

, COM_SNR_Struct.A_s ...

905

, Noise_Struct.sci_pdf ...

905

, Noise_Struct.sci_pdf ...

906

, Noise_Struct.cci_pdf ...

906

, Noise_Struct.cci_pdf ...

907

, Noise_Struct.isi_and_xtalk_pdf ...

907

, Noise_Struct.isi_and_xtalk_pdf ...

908

, Noise_Struct.noise_pdf ...

908

, Noise_Struct.noise_pdf ...

909

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

909

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

910

, param.delta_y, param...

910

, param.delta_y, param...

911

);

911

);

912

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

912

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

913

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

913

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

914

end

914

end

915

915

916

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

916

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

917

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

917

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

918

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

918

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

919

end

919

end

920

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

920

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

921

921

922

if use_BT

922

if use_BT

923

a = bessel( param.BTorder );

923

a = bessel( param.BTorder );

924

acoef=fliplr( a );

924

acoef=fliplr( a );

925

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

925

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

926

else

926

else

927

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

927

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

928

end

928

end

929

929

930

930

931

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

931

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

932

932

933

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

933

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

934

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

934

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

935

%All subsequent lines are field names in chdata

935

%All subsequent lines are field names in chdata

936

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

936

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

937

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

937

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

938

%

938

%

939

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

939

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

940

%#reduce

940

%#reduce

941

%sdd12_raw

941

%sdd12_raw

942

%sdd21_raw

942

%sdd21_raw

943

%sdd22_raw

943

%sdd22_raw

944

%sdd11_raw

944

%sdd11_raw

945

%

945

%

946

946

947

fid=fopen(fields_file,'r');

947

fid=fopen(fields_file,'r');

948

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

948

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

949

949

950

file_data=file_data{1};

950

file_data=file_data{1};

951

fclose(fid);

951

fclose(fid);

952

952

953

%remove blank lines

953

%remove blank lines

954

L=cellfun('length',file_data);

954

L=cellfun('length',file_data);

955

file_data=file_data(L~=0);

955

file_data=file_data(L~=0);

956

956

957

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

957

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

958

type=file_data{1};

958

type=file_data{1};

959

field_names=file_data(2:end);

959

field_names=file_data(2:end);

960

switch lower(type)

960

switch lower(type)

961

case '#reduce'

961

case '#reduce'

962

remove_fields=field_names;

962

remove_fields=field_names;

963

case '#include'

963

case '#include'

964

all_fields=fieldnames(chdata);

964

all_fields=fieldnames(chdata);

965

remove_fields=setdiff(all_fields,field_names);

965

remove_fields=setdiff(all_fields,field_names);

966

otherwise

966

otherwise

967

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

967

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

968

end

968

end

969

969

970

%remove the "remove_fields" from chdata

970

%remove the "remove_fields" from chdata

971

for j=1:length(remove_fields)

971

for j=1:length(remove_fields)

972

this_field=remove_fields{j};

972

this_field=remove_fields{j};

973

if isfield(chdata,this_field)

973

if isfield(chdata,this_field)

974

chdata=rmfield(chdata,this_field);

974

chdata=rmfield(chdata,this_field);

975

end

975

end

976

end

976

end

977

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

977

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

978

978

979

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

979

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

980

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

980

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

981

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

981

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

982

982

983

A_s=COM_SNR_Struct.A_s;

983

A_s=COM_SNR_Struct.A_s;

984

% initialize loop with uncorrelated noise and BER

984

% initialize loop with uncorrelated noise and BER

985

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

985

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

986

986

987

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

987

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

988

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

988

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

989

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

989

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

990

% below target BER).

990

% below target BER).

991

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

991

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

992

% 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.

992

% 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.

993

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

993

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

994

if isempty(x_error_propagation)

994

if isempty(x_error_propagation)

995

p_error_propagation(1) = 1e-20;

995

p_error_propagation(1) = 1e-20;

996

else

996

else

997

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

997

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

998

end

998

end

999

999

1000

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

1000

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

1001

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

1001

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

1002

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

1002

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

1003

if OP.use_simple_EP_model

1003

if OP.use_simple_EP_model

1004

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>

1004

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>

1005

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

1005

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

1006

else

1006

else

1007

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>

1007

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>

1008

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

1008

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

1009

end

1009

end

1010

1010

1011

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

1011

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

1012

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

1012

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

1013

if isempty(x_error_propagation)

1013

if isempty(x_error_propagation)

1014

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

1014

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

1015

else

1015

else

1016

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

1016

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

1017

end

1017

end

1018

end

1018

end

1019

1019

1020

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

1020

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

1021

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

1021

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

1022

% of this event by partial sum of the PDF.

1022

% of this event by partial sum of the PDF.

1023

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

1023

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

1024

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

1024

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

1025

1025

1026

% probability of bursts of different lengths

1026

% probability of bursts of different lengths

1027

p_burst = cumprod(p_error_propagation);

1027

p_burst = cumprod(p_error_propagation);

1028

function H_bw=Butterworth_Filter(param,f,use_BW)

1028

function H_bw=Butterworth_Filter(param,f,use_BW)

1029

1029

1030

if use_BW

1030

if use_BW

1031

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

1031

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

1032

else

1032

else

1033

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

1033

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

1034

end

1034

end

1035

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

1035

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

1036

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

1036

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

1037

CDF_ev=CDF(index);

1037

CDF_ev=CDF(index);

1038

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

1038

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

1039

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

1039

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

1040

if isempty(index)

1040

if isempty(index)

1041

CDF_inv_ev=PDF.x(end);

1041

CDF_inv_ev=PDF.x(end);

1042

else

1042

else

1043

CDF_inv_ev=PDF.x(index);

1043

CDF_inv_ev=PDF.x(index);

1044

end

1044

end

1045

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

1045

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

1046

1046

1047

1047

1048

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

1048

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

1049

Remember_keyword='Legacy';

1049

Remember_keyword='Legacy';

1050

OP.TDMODE=false;

1050

OP.TDMODE=false;

1051

OP.GET_FD=true;

1051

OP.GET_FD=true;

1052

OP.CONFIG2MAT_ONLY=false;

1052

OP.CONFIG2MAT_ONLY=false;

1053

config_file='';

1053

config_file='';

1054

num_fext=[];

1054

num_fext=[];

1055

num_next=[];

1055

num_next=[];

1056

if ~isempty(varargin)

1056

if ~isempty(varargin)

1057

if ~ischar(varargin{1})

1057

if ~ischar(varargin{1})

1058

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

1058

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

1059

end

1059

end

1060

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

1060

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

1061

if isempty(keyword_idx)

1061

if isempty(keyword_idx)

1062

%Legacy Mode

1062

%Legacy Mode

1063

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

1063

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

1064

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

1064

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

1065

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

1065

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

1066

else

1066

else

1067

%Keyword Mode

1067

%Keyword Mode

1068

my_keyword=varargin{1};

1068

my_keyword=varargin{1};

1069

Remember_keyword=my_keyword;

1069

Remember_keyword=my_keyword;

1070

varargin(1)=[];

1070

varargin(1)=[];

1071

switch my_keyword

1071

switch my_keyword

1072

1072

1073

case 'Legacy'

1073

case 'Legacy'

1074

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

1074

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

1075

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

1075

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

1076

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

1076

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

1077

case 'TD'

1077

case 'TD'

1078

OP.TDMODE=true;

1078

OP.TDMODE=true;

1079

OP.GET_FD=false;

1079

OP.GET_FD=false;

1080

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

1080

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

1081

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

1081

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

1082

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

1082

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

1083

case 'Config2Mat'

1083

case 'Config2Mat'

1084

OP.CONFIG2MAT_ONLY=true;

1084

OP.CONFIG2MAT_ONLY=true;

1085

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

1085

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

1086

end

1086

end

1087

end

1087

end

1088

end

1088

end

1089

function chdata=COM_FD_to_TD(chdata,param,OP)

1089

function chdata=COM_FD_to_TD(chdata,param,OP)

1090

1090

1091

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

1091

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

1092

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

1092

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

1093

case_number=param.package_testcase_i;

1093

case_number=param.package_testcase_i;

1094

for i=1:param.number_of_s4p_files

1094

for i=1:param.number_of_s4p_files

1095

% RIM 2-01-2023 moved to FD_Processing

1095

% RIM 2-01-2023 moved to FD_Processing

1096

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1096

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1097

% % Equation 93A-20 %%

1097

% % Equation 93A-20 %%

1098

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

1098

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

1099

% f=chdata(i).faxis;

1099

% f=chdata(i).faxis;

1100

% %

1100

% %

1101

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

1101

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

1102

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

1102

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

1103

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

1103

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

1104

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

1104

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

1105

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

1105

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

1106

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

1106

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

1107

% if OP.DISPLAY_WINDOW

1107

% if OP.DISPLAY_WINDOW

1108

% if i==1

1108

% if i==1

1109

% figure(300+param.package_testcase_i);

1109

% figure(300+param.package_testcase_i);

1110

% subplot(3,1,1)

1110

% subplot(3,1,1)

1111

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

1111

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

1112

% try

1112

% try

1113

% legend('NumColumns',2)

1113

% legend('NumColumns',2)

1114

% legend('location','south')

1114

% legend('location','south')

1115

% catch

1115

% catch

1116

% end

1116

% end

1117

% end

1117

% end

1118

% end

1118

% end

1119

% end

1119

% end

1120

[chdata(i).uneq_imp_response, ...

1120

[chdata(i).uneq_imp_response, ...

1121

chdata(i).t, ...

1121

chdata(i).t, ...

1122

chdata(i).causality_correction_dB, ...

1122

chdata(i).causality_correction_dB, ...

1123

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

1123

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

1124

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

1124

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

1125

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

1125

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

1126

[chdata(i).uneq_CD_imp_response, ...

1126

[chdata(i).uneq_CD_imp_response, ...

1127

chdata(i).t_DC, ...

1127

chdata(i).t_DC, ...

1128

chdata(i).causality_correction_DC_dB, ...

1128

chdata(i).causality_correction_DC_dB, ...

1129

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

1129

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

1130

end

1130

end

1131

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

1131

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

1132

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

1132

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

1133

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

1133

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

1134

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

1134

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

1135

1135

1136

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

1136

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

1137

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

1137

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

1138

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

1138

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

1139

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

1139

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

1140

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

1140

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

1141

rss=-inf;

1141

rss=-inf;

1142

for im=1:param.samples_per_ui

1142

for im=1:param.samples_per_ui

1143

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

1143

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

1144

end

1144

end

1145

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

1145

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

1146

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

1146

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

1147

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

1147

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

1148

end

1148

end

1149

if OP.DEBUG && OP.DISPLAY_WINDOW

1149

if OP.DEBUG && OP.DISPLAY_WINDOW

1150

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1150

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1151

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

1151

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

1152

screen_size=get(0,'ScreenSize');

1152

screen_size=get(0,'ScreenSize');

1153

pos = get(gcf, 'OuterPosition');

1153

pos = get(gcf, 'OuterPosition');

1154

set(gcf, 'OuterPosition', ...

1154

set(gcf, 'OuterPosition', ...

1155

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

1155

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

1156

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

1156

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

1157

%movegui(gcf,'northeast')

1157

%movegui(gcf,'northeast')

1158

1158

1159

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

1159

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

1160

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

1160

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

1161

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

1161

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

1162

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

1162

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

1163

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

1163

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

1164

end

1164

end

1165

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

1165

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

1166

% scale. thru is shown in another plot.

1166

% scale. thru is shown in another plot.

1167

if isequal(chdata(i).type, 'THRU' ) && ~OP.RX_CALIBRATION %|| OP.RX_CALIBRATION % RIM 06-14-2022

1167

if isequal(chdata(i).type, 'THRU' ) && ~OP.RX_CALIBRATION %|| OP.RX_CALIBRATION % RIM 06-14-2022

1168

% set(hp, 'visible', 'off');

1168

% set(hp, 'visible', 'off');

1169

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

1169

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

1170

end

1170

end

1171

title(sprintf('Unequalized Crosstalk and CD Conversion \n Pulse Responses'))

1171

title(sprintf('Unequalized Crosstalk and CD Conversion \n Pulse Responses'))

1172

ylabel('Volts')

1172

ylabel('Volts')

1173

xlabel('seconds')

1173

xlabel('seconds')

1174

1174

1175

recolor_plots(gca);

1175

recolor_plots(gca);

1176

else

1176

else

1177

if param.ndfe~=0

1177

if param.ndfe~=0

1178

fprintf('%s\tUnequalized pulse peak = %.1f mV\n', chdata(i).base, 1000*max(abs(chdata(i).uneq_pulse_response)));

1178

fprintf('%s\tUnequalized pulse peak = %.1f mV\n', chdata(i).base, 1000*max(abs(chdata(i).uneq_pulse_response)));

1179

end

1179

end

1180

end

1180

end

1181

1181

1182

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1182

fprintf('%s\tCausality correction = %.1f dB', chdata(i).base, chdata(i).causality_correction_dB);

1183

if OP.ENFORCE_CAUSALITY

1183

if OP.ENFORCE_CAUSALITY

1184

fprintf('\n');

1184

fprintf('\n');

1185

else

1185

else

1186

fprintf(' (not applied)\n');

1186

fprintf(' (not applied)\n');

1187

end

1187

end

1188

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1188

fprintf('%s\tTruncation ratio = %.1f dB\n', chdata(i).base, chdata(i).truncation_dB);

1189

1189

1190

end

1190

end

1191

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)

1191

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)

1192

1192

1193

1193

1194

debug_plot=0;

1194

debug_plot=0;

1195

1195

1196

1196

1197

samp_UI=param.samples_for_C2M;

1197

samp_UI=param.samples_for_C2M;

1198

half_UI=get_center_of_UI(samp_UI);

1198

half_UI=get_center_of_UI(samp_UI);

1199

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1199

T_O=floor((param.T_O/1000)*param.samples_for_C2M);

1200

start_sample=half_UI-T_O;

1200

start_sample=half_UI-T_O;

1201

end_sample=half_UI+T_O;

1201

end_sample=half_UI+T_O;

1202

1202

1203

1203

1204

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1204

%pdf_range is a placeholder to allow fractional UI calculation for optimize

1205

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1205

%C2M speedup. For regular COM_eye_width calls, pdf_range will be empty

1206

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1206

%which will force pdf_range=1:samp_UI for stanard full UI calculation.

1207

if pdf_range_flag

1207

if pdf_range_flag

1208

pdf_range=[start_sample end_sample];

1208

pdf_range=[start_sample end_sample];

1209

else

1209

else

1210

pdf_range=[];

1210

pdf_range=[];

1211

end

1211

end

1212

1212

1213

%pdf_full is self ISI pdf for each sample point

1213

%pdf_full is self ISI pdf for each sample point

1214

%h_j_full is the v/t calculation for each sample point

1214

%h_j_full is the v/t calculation for each sample point

1215

%the center vector for each should be identical to the standard COM variables

1215

%the center vector for each should be identical to the standard COM variables

1216

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1216

[pdf_full_1,h_j_full,A_s_vec] = get_pdf_full(chdata(1), delta_y, fom_result.t_s, param, OP,pdf_range) ;

1217

1217

1218

1218

1219

1219

1220

if isempty(pdf_range)

1220

if isempty(pdf_range)

1221

pdf_range=1:samp_UI;

1221

pdf_range=1:samp_UI;

1222

else

1222

else

1223

pdf_range=min(pdf_range):max(pdf_range);

1223

pdf_range=min(pdf_range):max(pdf_range);

1224

end

1224

end

1225

1225

1226

%Test doing Level PDFs

1226

%Test doing Level PDFs

1227

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1227

Levels = 2*(0:param.levels-1)/(param.levels-1)-1;

1228

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1228

%A_s_vec=A_s_vec*(param.levels-1)/param.R_LM;

1229

A_s_vec=A_s_vec*(param.levels-1);

1229

A_s_vec=A_s_vec*(param.levels-1);

1230

1230

1231

%add signal vector into pdf

1231

%add signal vector into pdf

1232

for n=1:param.levels

1232

for n=1:param.levels

1233

pdf_full{n}=pdf_full_1;

1233

pdf_full{n}=pdf_full_1;

1234

for j=pdf_range

1234

for j=pdf_range

1235

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1235

pdf_full{n}(j).x=pdf_full{n}(j).x+A_s_vec(j)*Levels(n);

1236

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1236

pdf_full{n}(j).Min=pdf_full{n}(j).x(1)/pdf_full{n}(j).BinSize;

1237

end

1237

end

1238

end

1238

end

1239

1239

1240

1240

1241

% figure;

1241

% figure;

1242

% hold on;

1242

% hold on;

1243

%This loop builds the same PDF/CDF structures from regular COM, but it is

1243

%This loop builds the same PDF/CDF structures from regular COM, but it is

1244

%computed for every sample point

1244

%computed for every sample point

1245

for n=1:param.levels

1245

for n=1:param.levels

1246

for j=pdf_range

1246

for j=pdf_range

1247

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1247

sigma_G_full(j) = norm([param.sigma_RJ*param.sigma_X*norm(h_j_full(:,j)), Struct_Noise.sigma_N, Struct_Noise.sigma_TX]);

1248

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1248

gaussian_noise_pdf_full(j) = normal_dist(sigma_G_full(j), Struct_Noise.ber_q, delta_y);

1249

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1249

gaussian_noise_pdf_full(j) = conv_fct(gaussian_noise_pdf_full(j), Struct_Noise.ne_noise_pdf);

1250

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1250

p_DD_full(j) = get_pdf_from_sampled_signal(param.A_DD*h_j_full(:,j), param.levels, delta_y);

1251

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1251

noise_pdf_full(j)=conv_fct(gaussian_noise_pdf_full(j), p_DD_full(j));

1252

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1252

isi_and_xtalk_pdf_full(j) = conv_fct_MeanNotZero(pdf_full{n}(j), Struct_Noise.cci_pdf);

1253

% change from adam gregory to include crosstalk

1253

% change from adam gregory to include crosstalk

1254

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1254

% combined_interference_and_noise_pdf_full = conv_fct(pdf_full(j), noise_pdf_full(j));

1255

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1255

combined_interference_and_noise_pdf_full{n}(j) = conv_fct_MeanNotZero(isi_and_xtalk_pdf_full(j), noise_pdf_full(j));

1256

1256

1257

%PDF to CDF

1257

%PDF to CDF

1258

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1258

combined_interference_and_noise_cdf_full{n}(j)=pdf_to_cdf(combined_interference_and_noise_pdf_full{n}(j));

1259

1259

1260

end

1260

end

1261

end

1261

end

1262

%hold off;

1262

%hold off;

1263

1263

1264

1264

1265

%For the given BER, find the top & bottom voltage level in the CDF

1265

%For the given BER, find the top & bottom voltage level in the CDF

1266

for n=1:param.levels

1266

for n=1:param.levels

1267

A_ni_bottom{n}=zeros(1,samp_UI);

1267

A_ni_bottom{n}=zeros(1,samp_UI);

1268

A_ni_top{n}=zeros(1,samp_UI);

1268

A_ni_top{n}=zeros(1,samp_UI);

1269

for j=pdf_range

1269

for j=pdf_range

1270

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1270

[A_ni_top{n}(j),A_ni_bottom{n}(j)]=cdf_to_ber_contour(combined_interference_and_noise_cdf_full{n}(j),param.specBER);

1271

end

1271

end

1272

end

1272

end

1273

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1273

%plot(1:samp_UI,cursor_vector-A_ni_top,1:samp_UI,-cursor_vector+A_ni_bottom)

1274

1274

1275

for n=1:param.levels-1

1275

for n=1:param.levels-1

1276

eye_contour{n}(:,1)=A_ni_top{n+1};

1276

eye_contour{n}(:,1)=A_ni_top{n+1};

1277

eye_contour{n}(:,2)=A_ni_bottom{n};

1277

eye_contour{n}(:,2)=A_ni_bottom{n};

1278

end

1278

end

1279

1279

1280

1280

1281

for n=1:param.levels-1

1281

for n=1:param.levels-1

1282

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1282

%eye_contour holds the top eye in the 1st column & bottom eye in the 2nd column

1283

%define vref as middle of top eye height and bottom eye height. Now

1283

%define vref as middle of top eye height and bottom eye height. Now

1284

%that all eyes are created, vref is non-zero except for middle eye

1284

%that all eyes are created, vref is non-zero except for middle eye

1285

EH_top=eye_contour{n}(half_UI,1);

1285

EH_top=eye_contour{n}(half_UI,1);

1286

EH_bot=eye_contour{n}(half_UI,2);

1286

EH_bot=eye_contour{n}(half_UI,2);

1287

EH=EH_top-EH_bot;

1287

EH=EH_top-EH_bot;

1288

vref=EH_top/2+EH_bot/2;

1288

vref=EH_top/2+EH_bot/2;

1289

%This function finds left/right eye width by finding the vref crossings of

1289

%This function finds left/right eye width by finding the vref crossings of

1290

%the top and bottom eye contours

1290

%the top and bottom eye contours

1291

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1291

[Left_EW(n),Right_EW(n)]=find_eye_width(eye_contour{n},half_UI,samp_UI,vref);

1292

end

1292

end

1293

1293

1294

%For reporting to .csv, need eye contour to be a matrix instead of cell

1294

%For reporting to .csv, need eye contour to be a matrix instead of cell

1295

eye_contour_tmp=eye_contour;

1295

eye_contour_tmp=eye_contour;

1296

eye_contour=[];

1296

eye_contour=[];

1297

for n=1:param.levels-1

1297

for n=1:param.levels-1

1298

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1298

eye_contour(:,(n-1)*2+1:n*2)=eye_contour_tmp{n};

1299

end

1299

end

1300

1300

1301

1301

1302

%Find VEC eye height

1302

%Find VEC eye height

1303

out_VT=[];

1303

out_VT=[];

1304

out_VB=[];

1304

out_VB=[];

1305

if param.T_O ~=0

1305

if param.T_O ~=0

1306

1306

1307

switch lower(OP.Histogram_Window_Weight)

1307

switch lower(OP.Histogram_Window_Weight)

1308

case {'gaussian' 'norm' 'normal' 'guassian'}

1308

case {'gaussian' 'norm' 'normal' 'guassian'}

1309

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1309

%build a gaussian window of weights that are multiplied by each pdf in the T_O range

1310

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1310

%Sigma = T_O/QL. Default QL=2.5. This gives a nice descent to near 0 at the edge of the window

1311

QL_sigma=T_O/param.QL;

1311

QL_sigma=T_O/param.QL;

1312

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1312

weights=exp(-1/2 * ([-T_O:T_O]/QL_sigma).^2);

1313

case 'triangle'

1313

case 'triangle'

1314

%triangle window. linear slope from 0 to 1 and back down to 0

1314

%triangle window. linear slope from 0 to 1 and back down to 0

1315

%for the weights

1315

%for the weights

1316

t_slope=1/(T_O);

1316

t_slope=1/(T_O);

1317

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1317

weights=[0:t_slope:1 1-t_slope:-t_slope:0];

1318

case 'rectangle'

1318

case 'rectangle'

1319

%default = rectangle. all weights = 1

1319

%default = rectangle. all weights = 1

1320

weights(1:2*T_O+1)=1;

1320

weights(1:2*T_O+1)=1;

1321

case 'dual_rayleigh'

1321

case 'dual_rayleigh'

1322

QL_sigma=T_O/param.QL;

1322

QL_sigma=T_O/param.QL;

1323

X=-T_O:T_O;

1323

X=-T_O:T_O;

1324

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1324

weights=(X+T_O)/QL_sigma^2.*exp(-1/2 * ((X+T_O)/QL_sigma).^2)...

1325

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1325

-(X-T_O)/QL_sigma^2.*exp(-1/2 * ((X-T_O)/QL_sigma).^2);

1326

weights=weights/max(weights);

1326

weights=weights/max(weights);

1327

otherwise

1327

otherwise

1328

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1328

error('%s not recognized for Histogram_Window_Weight',OP.Histogram_Window_Weight)

1329

end

1329

end

1330

1330

1331

for n=1:param.levels

1331

for n=1:param.levels

1332

out_pdf{n}=[];

1332

out_pdf{n}=[];

1333

for j=start_sample:end_sample

1333

for j=start_sample:end_sample

1334

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1334

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1335

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1335

target_pdf.y=target_pdf.y*weights(j-start_sample+1);

1336

if isempty(out_pdf{n})

1336

if isempty(out_pdf{n})

1337

out_pdf{n}=target_pdf;

1337

out_pdf{n}=target_pdf;

1338

else

1338

else

1339

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1339

out_pdf{n} = combine_pdf_same_voltage_axis(out_pdf{n}, target_pdf);

1340

end

1340

end

1341

end

1341

end

1342

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1342

out_pdf{n}.y=out_pdf{n}.y/sum(out_pdf{n}.y);

1343

end

1343

end

1344

1344

1345

for n=1:param.levels

1345

for n=1:param.levels

1346

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1346

out_cdf{n}=pdf_to_cdf(out_pdf{n});

1347

end

1347

end

1348

1348

1349

for n=1:param.levels

1349

for n=1:param.levels

1350

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1350

[A_ni_top_O(n),A_ni_bottom_O(n)]=cdf_to_ber_contour(out_cdf{n},param.specBER);

1351

end

1351

end

1352

1352

1353

for n=1:param.levels-1

1353

for n=1:param.levels-1

1354

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1354

OUT_VT_L(n,1)=A_ni_top_O(n+1);

1355

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1355

OUT_VT_L(n,2)=A_ni_bottom_O(n);

1356

end

1356

end

1357

1357

1358

%Report the top/bottom eye height of the worst eye

1358

%Report the top/bottom eye height of the worst eye

1359

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1359

EH_VT=OUT_VT_L(:,1)-OUT_VT_L(:,2);

1360

[mineh,min_idx]=min(EH_VT);

1360

[mineh,min_idx]=min(EH_VT);

1361

out_VT=OUT_VT_L(min_idx,1);

1361

out_VT=OUT_VT_L(min_idx,1);

1362

out_VB=OUT_VT_L(min_idx,2);

1362

out_VB=OUT_VT_L(min_idx,2);

1363

1363

1364

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1364

% CDF_Mean=mean(A_s_vec(start_sample:end_sample));

1365

% out_VT=2*CDF_Mean-A_ni_top_O;

1365

% out_VT=2*CDF_Mean-A_ni_top_O;

1366

% out_VB=-1*A_ni_bottom_O;

1366

% out_VB=-1*A_ni_bottom_O;

1367

1367

1368

if debug_plot

1368

if debug_plot

1369

figure;

1369

figure;

1370

hold on;

1370

hold on;

1371

for j=start_sample:end_sample

1371

for j=start_sample:end_sample

1372

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1372

plot(combined_interference_and_noise_pdf_full(j).x,combined_interference_and_noise_pdf_full(j).y);

1373

end

1373

end

1374

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1374

plot(out_pdf.x,out_pdf.y,'color','k','LineWidth',2);

1375

hold off;

1375

hold off;

1376

end

1376

end

1377

end

1377

end

1378

1378

1379

1379

1380

1380

1381

1381

1382

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

1382

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

1383

1383

1384

%This block was originally in main COM function but was moved here for

1384

%This block was originally in main COM function but was moved here for

1385

%cleanup. It returns the combined interference and noise PDF & CDF as well

1385

%cleanup. It returns the combined interference and noise PDF & CDF as well

1386

%as a structure "NS" that contains all the noise parameters that are used

1386

%as a structure "NS" that contains all the noise parameters that are used

1387

%in other places in COM

1387

%in other places in COM

1388

1388

1389

if OP.RX_CALIBRATION

1389

if OP.RX_CALIBRATION

1390

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1390

ctle_gain2 = (10.^(param.ctle_gdc_values(fom_result.ctle)/20) + 1i*chdata(2).faxis/param.CTLE_fz(fom_result.ctle)) ./ ...

1391

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1391

((1+1i*chdata(2).faxis/param.CTLE_fp1(fom_result.ctle)).*(1+1i*chdata(2).faxis/param.CTLE_fp2(fom_result.ctle)));

1392

switch param.CTLE_type

1392

switch param.CTLE_type

1393

case 'CL93'

1393

case 'CL93'

1394

H_low2=1;

1394

H_low2=1;

1395

case 'CL120d' % this clause uses two gain indexes

1395

case 'CL120d' % this clause uses two gain indexes

1396

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));

1396

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));

1397

case 'CL120e' % Z1 has been adjusted

1397

case 'CL120e' % Z1 has been adjusted

1398

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1398

H_low2=(1 + 1i*chdata(2).faxis/f_HP_P(fom_result.ctle))./(1 + 1i*chdata(2).faxis/f_HP_Z(fom_result.ctle));

1399

end

1399

end

1400

H_ctf2=H_low2.*ctle_gain2;

1400

H_ctf2=H_low2.*ctle_gain2;

1401

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1401

[ sigma_ne, NS.sigma_hp] = get_sigma_noise( H_ctf2, param, chdata, sigma_bn );

1402

else

1402

else

1403

sigma_ne=0;

1403

sigma_ne=0;

1404

end

1404

end

1405

1405

1406

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1406

NS.sigma_N = fom_result.sigma_N; % eta zero noise

1407

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

1407

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

1408

if ~OP.SNR_TXwC0

1408

if ~OP.SNR_TXwC0

1409

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1409

% Equation 93A-30 %% h0(ts0)= A_s*R_lm/(L-1)

1410

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1410

NS.sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx and RLM

1411

else

1411

else

1412

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

1412

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

1413

end

1413

end

1414

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1414

NS.sigma_G = norm([param.sigma_RJ*param.sigma_X*norm(fom_result.h_J), NS.sigma_N, NS.sigma_TX]);

1415

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1415

NS.sigma_rjit= param.sigma_RJ*param.sigma_X*norm(fom_result.h_J);

1416

else

1416

else

1417

NS.sigma_TX =PSD_results.S_tn_rms;

1417

NS.sigma_TX =PSD_results.S_tn_rms;

1418

NS.sigma_G = PSD_results.S_G_rms;

1418

NS.sigma_G = PSD_results.S_G_rms;

1419

NS.sigma_rjit=PSD_results.S_rj_rms ;

1419

NS.sigma_rjit=PSD_results.S_rj_rms ;

1420

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1420

NS.sigma_N=PSD_results.S_rn_rms ; % Commit request 4p4_8, healey_3dj_COM_01_240416

1421

end

1421

end

1422

% Equation 93A-41 %%

1422

% Equation 93A-41 %%

1423

1423

1424

1424

1425

% Equation 93A-42 %%

1425

% Equation 93A-42 %%

1426

% number of sigmas needed depends on the required BER.

1426

% number of sigmas needed depends on the required BER.

1427

if param.Noise_Crest_Factor == 0

1427

if param.Noise_Crest_Factor == 0

1428

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1428

NS.ber_q = sqrt(2)*erfcinv(2*param.specBER);

1429

else

1429

else

1430

NS.ber_q=param.Noise_Crest_Factor;

1430

NS.ber_q=param.Noise_Crest_Factor;

1431

end

1431

end

1432

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1432

NS.gaussian_noise_pdf = normal_dist(NS.sigma_G, NS.ber_q, param.delta_y);

1433

% enable overriding the Q factor of the BBN instrument.

1433

% enable overriding the Q factor of the BBN instrument.

1434

if OP.force_BBN_Q_factor

1434

if OP.force_BBN_Q_factor

1435

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1435

NS.ne_noise_pdf = normal_dist(sigma_ne, OP.BBN_Q_factor, param.delta_y);

1436

else

1436

else

1437

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1437

NS.ne_noise_pdf = normal_dist(sigma_ne, NS.ber_q, param.delta_y);

1438

end

1438

end

1439

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1439

NS.gaussian_noise_pdf = conv_fct(NS.gaussian_noise_pdf, NS.ne_noise_pdf);

1440

1440

1441

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1441

% p_DD is computed using the procedure defined in 93A.1.7.1 with h(n)=A_DD*h_J(n)

1442

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1442

NS.p_DD = get_pdf_from_sampled_signal(param.A_DD*fom_result.h_J, param.levels, param.delta_y);

1443

1443

1444

% Equation 93A-43 % only used for reporting bathtub curves

1444

% Equation 93A-43 % only used for reporting bathtub curves

1445

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1445

NS.noise_pdf=conv_fct(NS.gaussian_noise_pdf, NS.p_DD);

1446

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1446

gaussian_rjitt_pdf = normal_dist(NS.sigma_rjit, NS.ber_q, param.delta_y);

1447

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1447

NS.jitt_pdf=conv_fct(gaussian_rjitt_pdf, NS.p_DD);

1448

1448

1449

% Implementation of 93A.1.7.3 combination procedure

1449

% Implementation of 93A.1.7.3 combination procedure

1450

% (effectively Equation 93A-44) %%

1450

% (effectively Equation 93A-44) %%

1451

1451

1452

% Self-Channel Interference is thru residual result

1452

% Self-Channel Interference is thru residual result

1453

NS.sci_pdf = chdata(1).pdfr;

1453

NS.sci_pdf = chdata(1).pdfr;

1454

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1454

sci_mxi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1455

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1455

NS.thru_peak_interference_at_BER=abs(NS.sci_pdf.x(sci_mxi));

1456

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1456

sci_msi=find(cumsum(NS.sci_pdf.y)>=param.specBER, 1, 'first');

1457

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1457

NS.sci_sigma=abs(NS.sci_pdf.x(sci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1458

if OP.RX_CALIBRATION ==0

1458

if OP.RX_CALIBRATION ==0

1459

% Co-Channel Interference PDFs (for information only):

1459

% Co-Channel Interference PDFs (for information only):

1460

% initialize to deltas

1460

% initialize to deltas

1461

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1461

MDNEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1462

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1462

MDFEXT_cci_pdf = d_cpdf(param.delta_y, 0, 1);

1463

% serially convolve FEXT/NEXT PDFs

1463

% serially convolve FEXT/NEXT PDFs

1464

for k=2:param.number_of_s4p_files

1464

for k=2:param.number_of_s4p_files

1465

if isequal(chdata(k).type, 'NEXT')

1465

if isequal(chdata(k).type, 'NEXT')

1466

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1466

MDNEXT_cci_pdf = conv_fct(MDNEXT_cci_pdf, chdata(k).pdfr);

1467

else % ... must be FEXT

1467

else % ... must be FEXT

1468

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1468

MDFEXT_cci_pdf = conv_fct(MDFEXT_cci_pdf, chdata(k).pdfr);

1469

end

1469

end

1470

end

1470

end

1471

1471

1472

% find "peaks" of MDNEXT/MDFEXT for reporting

1472

% find "peaks" of MDNEXT/MDFEXT for reporting

1473

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1473

mdnxi=find(cumsum(MDNEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1474

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1474

NS.MDNEXT_peak_interference=abs(MDNEXT_cci_pdf.x(mdnxi));

1475

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1475

mdfxi=find(cumsum(MDFEXT_cci_pdf.y)>=param.specBER, 1, 'first');

1476

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1476

NS.MDFEXT_peak_interference=abs(MDFEXT_cci_pdf.x(mdfxi));

1477

1477

1478

% Combined crosstalk effect

1478

% Combined crosstalk effect

1479

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1479

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1480

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1480

cci_mxi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1481

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1481

cci_msi=find(cumsum(NS.cci_pdf.y)>=param.specBER, 1, 'first');

1482

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1482

NS.cci_sigma=abs(NS.cci_pdf.x(cci_msi)/(erfcinv(2*param.specBER)*sqrt(2)));

1483

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1483

NS.crosstalk_peak_interference_at_BER=abs(NS.cci_pdf.x(cci_mxi));

1484

% combine cci and sci

1484

% combine cci and sci

1485

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1485

NS.isi_and_xtalk_pdf = conv_fct(NS.sci_pdf, NS.cci_pdf);

1486

else

1486

else

1487

% for calibration there is no cci

1487

% for calibration there is no cci

1488

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1488

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1489

end

1489

end

1490

1490

1491

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1491

mxi=find(cumsum(NS.isi_and_xtalk_pdf.y)>=param.specBER, 1, 'first');

1492

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1492

NS.peak_interference_at_BER=abs(NS.isi_and_xtalk_pdf.x(mxi));

1493

1493

1494

1494

1495

% Equation 93A-45

1495

% Equation 93A-45

1496

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1496

combined_interference_and_noise_pdf = conv_fct(NS.isi_and_xtalk_pdf, NS.noise_pdf);

1497

1497

1498

%%

1498

%%

1499

% Equation 93A-37

1499

% Equation 93A-37

1500

if param.ENOB ~=0

1500

if param.ENOB ~=0

1501

[chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP);

1501

[chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP);

1502

end

1502

end

1503

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1503

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1504

CDF=combined_interference_and_noise_cdf;

1504

CDF=combined_interference_and_noise_cdf;

1505

PDF=combined_interference_and_noise_pdf;

1505

PDF=combined_interference_and_noise_pdf;

1506

1506

1507

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1507

function [hctf] = FD_CTLE(freq, fb, f_z, f_p1, f_p2, kacdc_dB)

1508

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1508

hctf = ( 10.^(kacdc_dB/20) + 1i*freq/f_z ) ./ ( (1+1i*freq/f_p1) .* (1+1i*freq/f_p2)) ;

1509

1509

1510

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

1510

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

1511

%This function calculates various frequency domain metrics

1511

%This function calculates various frequency domain metrics

1512

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1512

%Mainly IL_fit, FOM_ILD, ICN, ICN_Fext, and ICN_Next

1513

db = @(x) 20*log10(abs(x));

1513

db = @(x) 20*log10(abs(x));

1514

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1514

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1515

if OP.WC_PORTZ

1515

if OP.WC_PORTZ

1516

A_thru = param.a_thru(param.Tx_rd_sel);

1516

A_thru = param.a_thru(param.Tx_rd_sel);

1517

A_fext = param.a_fext(param.Tx_rd_sel);

1517

A_fext = param.a_fext(param.Tx_rd_sel);

1518

A_next = param.a_next(param.Tx_rd_sel);

1518

A_next = param.a_next(param.Tx_rd_sel);

1519

else

1519

else

1520

A_thru = param.a_thru(package_testcase);

1520

A_thru = param.a_thru(package_testcase);

1521

A_fext = param.a_fext(package_testcase);

1521

A_fext = param.a_fext(package_testcase);

1522

A_next = param.a_next(package_testcase);

1522

A_next = param.a_next(package_testcase);

1523

end

1523

end

1524

for i=1:param.number_of_s4p_files

1524

for i=1:param.number_of_s4p_files

1525

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

1525

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

1526

chdata(i).A=A_thru;

1526

chdata(i).A=A_thru;

1527

chdata(i).Aicn=A_thru;

1527

chdata(i).Aicn=A_thru;

1528

elseif isequal(chdata(i).type, 'FEXT')

1528

elseif isequal(chdata(i).type, 'FEXT')

1529

chdata(i).A=A_fext;

1529

chdata(i).A=A_fext;

1530

chdata(i).Aicn=param.a_icn_fext;

1530

chdata(i).Aicn=param.a_icn_fext;

1531

elseif isequal(chdata(i).type, 'NEXT')

1531

elseif isequal(chdata(i).type, 'NEXT')

1532

chdata(i).A=A_next;

1532

chdata(i).A=A_next;

1533

chdata(i).Aicn=param.a_icn_next;

1533

chdata(i).Aicn=param.a_icn_next;

1534

end

1534

end

1535

end

1535

end

1536

if OP.TDMODE

1536

if OP.TDMODE

1537

for i=1:param.number_of_s4p_files % freq delta for integration

1537

for i=1:param.number_of_s4p_files % freq delta for integration

1538

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1538

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1539

end

1539

end

1540

end

1540

end

1541

if ~DO_ONCE

1541

if ~DO_ONCE

1542

return;

1542

return;

1543

end

1543

end

1544

%Any new output_args fields set in this function should be initialized here as empty

1544

%Any new output_args fields set in this function should be initialized here as empty

1545

output_args.fitted_IL_dB_at_Fnq = [];

1545

output_args.fitted_IL_dB_at_Fnq = [];

1546

output_args.cable__assembley_loss=[];

1546

output_args.cable__assembley_loss=[];

1547

output_args.loss_with_PCB=[];

1547

output_args.loss_with_PCB=[];

1548

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1548

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1549

output_args.IL_dB_channel_only_at_Fnq=[];

1549

output_args.IL_dB_channel_only_at_Fnq=[];

1550

output_args.VTF_loss_dB_at_Fnq=[];

1550

output_args.VTF_loss_dB_at_Fnq=[];

1551

output_args.IL_db_die_to_die_at_Fnq=[];

1551

output_args.IL_db_die_to_die_at_Fnq=[];

1552

output_args.FOM_TDILN=[];

1552

output_args.FOM_TDILN=[];

1553

output_args.TD_ILN=[];

1553

output_args.TD_ILN=[];

1554

output_args.FOM_RILN=[];

1554

output_args.FOM_RILN=[];

1555

output_args.FOM_ILD=[];

1555

output_args.FOM_ILD=[];

1556

%TD_Mode is just a pass through to set the empty values and return

1556

%TD_Mode is just a pass through to set the empty values and return

1557

if ~OP.GET_FD

1557

if ~OP.GET_FD

1558

return;

1558

return;

1559

end

1559

end

1560

case_number=param.package_testcase_i;

1560

case_number=param.package_testcase_i;

1561

f2=param.f2;

1561

f2=param.f2;

1562

f1=param.f1;

1562

f1=param.f1;

1563

MDFEXT_ICN=0; MDNEXT_ICN=0;

1563

MDFEXT_ICN=0; MDNEXT_ICN=0;

1564

for i=1:param.number_of_s4p_files

1564

for i=1:param.number_of_s4p_files

1565

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1565

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1566

% Equation 93A-20 %%

1566

% Equation 93A-20 %%

1567

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

1567

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

1568

f=chdata(i).faxis;

1568

f=chdata(i).faxis;

1569

%

1569

%

1570

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

1570

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

1571

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

1571

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

1572

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

1572

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

1573

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

1573

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

1574

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

1574

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

1575

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

1575

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

1576

if OP.DISPLAY_WINDOW

1576

if OP.DISPLAY_WINDOW

1577

if i==1

1577

if i==1

1578

figure(300+param.package_testcase_i);

1578

figure(300+param.package_testcase_i);

1579

subplot(3,1,1)

1579

subplot(3,1,1)

1580

hold on

1580

hold on

1581

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

1581

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

1582

try

1582

try

1583

legend('NumColumns',2)

1583

legend('NumColumns',2)

1584

legend('location','south')

1584

legend('location','south')

1585

catch

1585

catch

1586

end

1586

end

1587

end

1587

end

1588

end

1588

end

1589

end

1589

end

1590

end

1590

end

1591

for i=1:param.number_of_s4p_files

1591

for i=1:param.number_of_s4p_files

1592

if i == 2

1592

if i == 2

1593

PSXT(1:length(chdata(i).sdd21f))=0;

1593

PSXT(1:length(chdata(i).sdd21f))=0;

1594

MDFEXT(1:length(chdata(i).sdd21f))=0;

1594

MDFEXT(1:length(chdata(i).sdd21f))=0;

1595

MDNEXT(1:length(chdata(i).sdd21f))=0;

1595

MDNEXT(1:length(chdata(i).sdd21f))=0;

1596

end

1596

end

1597

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1597

a=find(chdata(i).faxis(:)>=f2,1,'first');% RIM 01-12-21

1598

if isempty(a)

1598

if isempty(a)

1599

f2=chdata(i).faxis(end);

1599

f2=chdata(i).faxis(end);

1600

index_f2=length(chdata(i).faxis);

1600

index_f2=length(chdata(i).faxis);

1601

else

1601

else

1602

index_f2=a(1);

1602

index_f2=a(1);

1603

end

1603

end

1604

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1604

b=find(chdata(i).faxis(:)<=f1,1,'last');% RIM 01-12-21

1605

if isempty(b)

1605

if isempty(b)

1606

f1=chdata(i).faxis(1);

1606

f1=chdata(i).faxis(1);

1607

index_f1=1;

1607

index_f1=1;

1608

else

1608

else

1609

index_f1=b(1);

1609

index_f1=b(1);

1610

end

1610

end

1611

% R is the frequency dependent parameter for the sinc function use in the

1611

% R is the frequency dependent parameter for the sinc function use in the

1612

% PWF for ICN

1612

% PWF for ICN

1613

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1613

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(i).faxis;

1614

if(chdata(i).faxis(1)==0)

1614

if(chdata(i).faxis(1)==0)

1615

temp_angle(1)=1e-20;% we don't want to divide by zero

1615

temp_angle(1)=1e-20;% we don't want to divide by zero

1616

end

1616

end

1617

SINC = sin(temp_angle)./temp_angle;

1617

SINC = sin(temp_angle)./temp_angle;

1618

PWF_data=SINC.^2;

1618

PWF_data=SINC.^2;

1619

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1619

PWF_trf=(1+(chdata(i).faxis/chdata(i).ftr).^4).^-1;

1620

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1620

%// bw1=2.613126; bw2=3.4142136; bw3=2.613126;

1621

fr=param.f_r*param.fb;

1621

fr=param.f_r*param.fb;

1622

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1622

PWF_rx=(1+(chdata(i).faxis/fr).^8).^-1;

1623

PWF_highpass=1;

1623

PWF_highpass=1;

1624

% Equation 93A-57 %

1624

% Equation 93A-57 %

1625

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1625

PWF=PWF_data.*PWF_trf.*PWF_rx.*PWF_highpass; % power weight function

1626

% freq delta for integration

1626

% freq delta for integration

1627

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1627

chdata(i).delta_f=chdata(i).faxis(11)-chdata(i).faxis(10);

1628

% from ba spec, this is basically ICN

1628

% from ba spec, this is basically ICN

1629

faxis_GHz = chdata(i).faxis/1e9;

1629

faxis_GHz = chdata(i).faxis/1e9;

1630

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

1630

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

1631

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1631

[ILD_magft chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2));

1632

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1632

% find fitted loss values by interpolation using full data, no indexing - Adee 2022-08-28

1633

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1633

[~, chdata(i).fit_orig] = get_ILN(chdata(i).sdd21f, chdata(i).faxis);

1634

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1634

fit_loss = interp1(chdata(i).faxis, -chdata(i).fit_orig, 1/param.ui/2);

1635

chdata(i).fit_ILatNq = fit_loss;

1635

chdata(i).fit_ILatNq = fit_loss;

1636

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1636

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1637

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1637

IL_interp = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21f)), 1/param.ui/2);

1638

chdata(i).ILatNq = IL_interp;

1638

chdata(i).ILatNq = IL_interp;

1639

if OP.include_pcb

1639

if OP.include_pcb

1640

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1640

cable_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_orig)), 1/param.ui/2);

1641

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1641

loss_with_PCB = interp1(chdata(i).faxis, -20*log10(abs(chdata(i).sdd21_raw)), 1/param.ui/2);

1642

output_args.cable__assembley_loss=cable_loss;

1642

output_args.cable__assembley_loss=cable_loss;

1643

output_args.loss_with_PCB=loss_with_PCB;

1643

output_args.loss_with_PCB=loss_with_PCB;

1644

end

1644

end

1645

Nq_loss=chdata(i).ILatNq;

1645

Nq_loss=chdata(i).ILatNq;

1646

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1646

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1647

% time domain ref RR = complex fit pulse

1647

% time domain ref RR = complex fit pulse

1648

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1648

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1649

[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);

1649

[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);

1650

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1650

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1651

FOM_ILN_complex= TD_ILN.FOM;

1651

FOM_ILN_complex= TD_ILN.FOM;

1652

end

1652

end

1653

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1653

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1654

[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);

1654

[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);

1655

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1655

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1656

FOM_ILN_complex= TD_ILN.FOM;

1656

FOM_ILN_complex= TD_ILN.FOM;

1657

end

1657

end

1658

if OP.COMPUTE_TDILN

1658

if OP.COMPUTE_TDILN

1659

output_args.FOM_TDILN=FOM_TDILN;

1659

output_args.FOM_TDILN=FOM_TDILN;

1660

output_args.TD_ILN=TD_ILN; % struct

1660

output_args.TD_ILN=TD_ILN; % struct

1661

end

1661

end

1662

if OP.COMPUTE_RILN

1662

if OP.COMPUTE_RILN

1663

% Get RIL, RILN, and TD_RILN

1663

% Get RIL, RILN, and TD_RILN

1664

[RIL_struct]= capture_RIL_RILN(chdata);

1664

[RIL_struct]= capture_RIL_RILN(chdata);

1665

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));

1665

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));

1666

output_args.FOM_RILN=FOM_RILN;

1666

output_args.FOM_RILN=FOM_RILN;

1667

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1667

%---start. plotting ILN based on ILD and RILN % Hansel 10/18/2021

1668

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1668

plot_tdomain_debug= 0; % must have OP.COMPUTE_TDILN = 1 to use

1669

if plot_tdomain_debug== 1

1669

if plot_tdomain_debug== 1

1670

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

1670

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

1671

ax_1= subplot(3,1,1);

1671

ax_1= subplot(3,1,1);

1672

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1672

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1673

hold on;

1673

hold on;

1674

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1674

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1675

hold on;

1675

hold on;

1676

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1676

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1677

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1677

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1678

grid on;

1678

grid on;

1679

box on;

1679

box on;

1680

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1680

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1681

xlabel('Time [nsec]');

1681

xlabel('Time [nsec]');

1682

ylabel('Pulse Response [mV]');

1682

ylabel('Pulse Response [mV]');

1683

1683

1684

ax_2= subplot(3,1,2);

1684

ax_2= subplot(3,1,2);

1685

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1685

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1686

hold on;

1686

hold on;

1687

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1687

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1688

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1688

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1689

grid on;

1689

grid on;

1690

box on;

1690

box on;

1691

legend('REF', 'TD\_RILN');

1691

legend('REF', 'TD\_RILN');

1692

xlabel('Time [nsec]');

1692

xlabel('Time [nsec]');

1693

ylabel('Pulse Response [mV]');

1693

ylabel('Pulse Response [mV]');

1694

ax_3= subplot(3,1,3);

1694

ax_3= subplot(3,1,3);

1695

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1695

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1696

hold on;

1696

hold on;

1697

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1697

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1698

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1698

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1699

grid on;

1699

grid on;

1700

box on;

1700

box on;

1701

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1701

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1702

xlabel('Time [nsec]');

1702

xlabel('Time [nsec]');

1703

ylabel('Pulse Response [mV]');

1703

ylabel('Pulse Response [mV]');

1704

1704

1705

linkaxes([ax_1, ax_2, ax_3], 'x');

1705

linkaxes([ax_1, ax_2, ax_3], 'x');

1706

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1706

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1707

end

1707

end

1708

%---end. plotting ILN based on ILD and RILN

1708

%---end. plotting ILN based on ILD and RILN

1709

end

1709

end

1710

% Equation 93A-56 %

1710

% Equation 93A-56 %

1711

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1711

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1712

output_args.FOM_ILD=FOM_ILD;

1712

output_args.FOM_ILD=FOM_ILD;

1713

if OP.DEBUG

1713

if OP.DEBUG

1714

if OP.DISPLAY_WINDOW

1714

if OP.DISPLAY_WINDOW

1715

figure(300+case_number);

1715

figure(300+case_number);

1716

set(gcf,'Tag','COM')

1716

set(gcf,'Tag','COM')

1717

screen_size=get(0,'ScreenSize');

1717

screen_size=get(0,'ScreenSize');

1718

pos = get(gcf, 'OuterPosition');

1718

pos = get(gcf, 'OuterPosition');

1719

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1719

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1720

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

1720

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

1721

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

1721

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

1722

subplot(3,1,1)

1722

subplot(3,1,1)

1723

title('Losses')

1723

title('Losses')

1724

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1724

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1725

hold on

1725

hold on

1726

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1726

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1727

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1727

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1728

ylim(get(gca, 'ylim'));

1728

ylim(get(gca, 'ylim'));

1729

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1729

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1730

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1730

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1731

subplot(3,1,3)

1731

subplot(3,1,3)

1732

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1732

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1733

if OP.PLOT_CM

1733

if OP.PLOT_CM

1734

if case_number ==1

1734

if case_number ==1

1735

h350=figure(350);set(gcf,'Tag','COM')

1735

h350=figure(350);set(gcf,'Tag','COM')

1736

screen_size=get(0,'ScreenSize');

1736

screen_size=get(0,'ScreenSize');

1737

pos = get(gcf, 'OuterPosition');

1737

pos = get(gcf, 'OuterPosition');

1738

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1738

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1739

movegui(gcf,'center');

1739

movegui(gcf,'center');

1740

htabgroup350 = uitabgroup(h350);

1740

htabgroup350 = uitabgroup(h350);

1741

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1741

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1742

hax1 = axes('Parent', htab1);

1742

hax1 = axes('Parent', htab1);

1743

set(h350,'CurrentAxes',hax1)

1743

set(h350,'CurrentAxes',hax1)

1744

hold on

1744

hold on

1745

set(gcf,'Tag','COM')

1745

set(gcf,'Tag','COM')

1746

screen_size=get(0,'ScreenSize');

1746

screen_size=get(0,'ScreenSize');

1747

pos = get(gcf, 'OuterPosition');

1747

pos = get(gcf, 'OuterPosition');

1748

title('IL & CM Losses')

1748

title('IL & CM Losses')

1749

base=strrep(chdata(i).base,'_',' ');

1749

base=strrep(chdata(i).base,'_',' ');

1750

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1750

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1751

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1751

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1752

ylabel('dB')

1752

ylabel('dB')

1753

xlabel('GHz')

1753

xlabel('GHz')

1754

legend show

1754

legend show

1755

legend('Location','eastoutside')

1755

legend('Location','eastoutside')

1756

hold on

1756

hold on

1757

grid on

1757

grid on

1758

if param.number_of_s4p_files > 1

1758

if param.number_of_s4p_files > 1

1759

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1759

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1760

hax2 = axes('Parent', htab2);

1760

hax2 = axes('Parent', htab2);

1761

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1761

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1762

hax3 = axes('Parent', htab3);

1762

hax3 = axes('Parent', htab3);

1763

end

1763

end

1764

1764

1765

end

1765

end

1766

end

1766

end

1767

else

1767

else

1768

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1768

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1769

end

1769

end

1770

end

1770

end

1771

else % NEXT or FEXT

1771

else % NEXT or FEXT

1772

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

1772

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

1773

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1773

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1774

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46 corrected for fb

1774

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46 corrected for fb

1775

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1775

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1776

elseif isequal(chdata(i).type, 'NEXT')

1776

elseif isequal(chdata(i).type, 'NEXT')

1777

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1777

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1778

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47 corrected for fb

1778

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47 corrected for fb

1779

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1779

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1780

end

1780

end

1781

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1781

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1782

ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));% corrected for fb

1782

ICN=sqrt(2*chdata(i).delta_f/param.fb*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));% corrected for fb

1783

output_args.ICN_mV=ICN*1000;

1783

output_args.ICN_mV=ICN*1000;

1784

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1784

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1785

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1785

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1786

if case_number ==1

1786

if case_number ==1

1787

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1787

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1788

% hax2 = axes('Parent', htab2);

1788

% hax2 = axes('Parent', htab2);

1789

set(h350,'CurrentAxes',hax2)

1789

set(h350,'CurrentAxes',hax2)

1790

hold on

1790

hold on

1791

title('CM Losses')

1791

title('CM Losses')

1792

base=strrep(chdata(i).base,'_',' ');

1792

base=strrep(chdata(i).base,'_',' ');

1793

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1793

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1794

legend('Location','eastoutside')

1794

legend('Location','eastoutside')

1795

hold on

1795

hold on

1796

grid on

1796

grid on

1797

set(h350,'CurrentAxes',hax3)

1797

set(h350,'CurrentAxes',hax3)

1798

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1798

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1799

legend('Location','eastoutside')

1799

legend('Location','eastoutside')

1800

hold on

1800

hold on

1801

grid on

1801

grid on

1802

end

1802

end

1803

end

1803

end

1804

end

1804

end

1805

end % for loop

1805

end % for loop

1806

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1806

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1807

if OP.DEBUG && OP.DISPLAY_WINDOW

1807

if OP.DEBUG && OP.DISPLAY_WINDOW

1808

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

1808

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

1809

if param.number_of_s4p_files > 1

1809

if param.number_of_s4p_files > 1

1810

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1810

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1811

subplot(3,1,1)

1811

subplot(3,1,1)

1812

hold on

1812

hold on

1813

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1813

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1814

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1814

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1815

subplot(3,1,2)

1815

subplot(3,1,2)

1816

grid on

1816

grid on

1817

ILtemp=20*log10(abs(chdata(1).sdd21f));

1817

ILtemp=20*log10(abs(chdata(1).sdd21f));

1818

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1818

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1819

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1819

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1820

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1820

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1821

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1821

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1822

hold on

1822

hold on

1823

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1823

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1824

end

1824

end

1825

subplot(3,1,1)

1825

subplot(3,1,1)

1826

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1826

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1827

grid on; legend show

1827

grid on; legend show

1828

subplot(3,1,2)

1828

subplot(3,1,2)

1829

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1829

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1830

ylim([0 80])

1830

ylim([0 80])

1831

xlim([.1 100])

1831

xlim([.1 100])

1832

grid on; %legend show

1832

grid on; %legend show

1833

subplot(3,1,3)

1833

subplot(3,1,3)

1834

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1834

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1835

ylim([-3 3])

1835

ylim([-3 3])

1836

grid on; legend show

1836

grid on; legend show

1837

end

1837

end

1838

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1838

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1839

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1839

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1840

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1840

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1841

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1841

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1842

output_args.VTF_loss_dB_at_Fnq=total_loss;

1842

output_args.VTF_loss_dB_at_Fnq=total_loss;

1843

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1843

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1844

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1844

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1845

function [ V0 ] = FFE( C , cmx,spui, V )

1845

function [ V0 ] = FFE( C , cmx,spui, V )

1846

% C FFE taps

1846

% C FFE taps

1847

% cmx number of precursors taps

1847

% cmx number of precursors taps

1848

% spui samples per ui

1848

% spui samples per ui

1849

% V input signal

1849

% V input signal

1850

%speed ups implemented:

1850

%speed ups implemented:

1851

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1851

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1852

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1852

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1853

1853

1854

V0=0;

1854

V0=0;

1855

if iscolumn(V); V=V.';end

1855

if iscolumn(V); V=V.';end

1856

for i=1:length(C)

1856

for i=1:length(C)

1857

if C(i)~=0

1857

if C(i)~=0

1858

ishift=(i-1-cmx)*spui;

1858

ishift=(i-1-cmx)*spui;

1859

V0=circshift(V',[ishift,0])*C(i)+V0;

1859

V0=circshift(V',[ishift,0])*C(i)+V0;

1860

end

1860

end

1861

end

1861

end

1862

%V0=circshift(V0,[(-cmx)*spui,0]);

1862

%V0=circshift(V0,[(-cmx)*spui,0]);

1863

% disp(max(V0));

1863

% disp(max(V0));

1864

1864

1865

1865

1866

% begin yasuo patch 12/11/2018

1866

% begin yasuo patch 12/11/2018

1867

% calculate sigma (standard deviation) value of PDF

1867

% calculate sigma (standard deviation) value of PDF

1868

function [ V0 ] = FFE_Fast( C,V_shift )

1868

function [ V0 ] = FFE_Fast( C,V_shift )

1869

% C FFE taps

1869

% C FFE taps

1870

% V input signal separated into length(C) columns with circshift already performed

1870

% V input signal separated into length(C) columns with circshift already performed

1871

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1871

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1872

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1872

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1873

% saved by pre-shifting it and remembering it across loops

1873

% saved by pre-shifting it and remembering it across loops

1874

% Another speed up: only multiply by indices of C that are not 0

1874

% Another speed up: only multiply by indices of C that are not 0

1875

1875

1876

V0=0;

1876

V0=0;

1877

for i=1:length(C)

1877

for i=1:length(C)

1878

if C(i)~=0

1878

if C(i)~=0

1879

V0=V_shift(:,i)*C(i)+V0;

1879

V0=V_shift(:,i)*C(i)+V0;

1880

end

1880

end

1881

end

1881

end

1882

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1882

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1883

1883

1884

hisi=h(isi_start:isi_end);

1884

hisi=h(isi_start:isi_end);

1885

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1885

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1886

bank_size = param.N_bf;

1886

bank_size = param.N_bf;

1887

num_groups = param.N_bg;

1887

num_groups = param.N_bg;

1888

1888

1889

1889

1890

%start with one by one Floating Tap

1890

%start with one by one Floating Tap

1891

num_isi=length(hisi);

1891

num_isi=length(hisi);

1892

max_isi=num_isi-bank_size+1;

1892

max_isi=num_isi-bank_size+1;

1893

valid_tap_locations=1:max_isi;

1893

valid_tap_locations=1:max_isi;

1894

all_idx=[];

1894

all_idx=[];

1895

for j=1:num_groups

1895

for j=1:num_groups

1896

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1896

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1897

for k=1:length(valid_tap_locations)

1897

for k=1:length(valid_tap_locations)

1898

this_location=valid_tap_locations(k);

1898

this_location=valid_tap_locations(k);

1899

new_idx = [all_idx this_location:this_location+bank_size-1];

1899

new_idx = [all_idx this_location:this_location+bank_size-1];

1900

new_idx=sort(new_idx);

1900

new_idx=sort(new_idx);

1901

new_idx = new_idx+param.RxFFE_cpx;

1901

new_idx = new_idx+param.RxFFE_cpx;

1902

%calculate FOM for each one

1902

%calculate FOM for each one

1903

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1903

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1904

end

1904

end

1905

%choose the location with best FOM

1905

%choose the location with best FOM

1906

%add it to the "all_idx" list and remove it from valid locations

1906

%add it to the "all_idx" list and remove it from valid locations

1907

[~,best_FOM_idx]=max(best_FOM);

1907

[~,best_FOM_idx]=max(best_FOM);

1908

start_tap = valid_tap_locations(best_FOM_idx);

1908

start_tap = valid_tap_locations(best_FOM_idx);

1909

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1909

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1910

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1910

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1911

remove_range(remove_range>length(valid_tap_locations))=[];

1911

remove_range(remove_range>length(valid_tap_locations))=[];

1912

valid_tap_locations(remove_range)=[];

1912

valid_tap_locations(remove_range)=[];

1913

1913

1914

%Also remove illegal taps from valid locations

1914

%Also remove illegal taps from valid locations

1915

%illegal taps are ones that would overlap with the chosen bank

1915

%illegal taps are ones that would overlap with the chosen bank

1916

bad_tap=start_tap-bank_size+1:start_tap-1;

1916

bad_tap=start_tap-bank_size+1:start_tap-1;

1917

bad_tap(bad_tap<1)=[];

1917

bad_tap(bad_tap<1)=[];

1918

for n=1:length(bad_tap)

1918

for n=1:length(bad_tap)

1919

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1919

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1920

if ~isempty(bad_tap_idx)

1920

if ~isempty(bad_tap_idx)

1921

valid_tap_locations(bad_tap_idx)=[];

1921

valid_tap_locations(bad_tap_idx)=[];

1922

end

1922

end

1923

end

1923

end

1924

end

1924

end

1925

1925

1926

%put idx back in the right location (adding RxFFE_cpx)

1926

%put idx back in the right location (adding RxFFE_cpx)

1927

idx = all_idx+param.RxFFE_cpx;

1927

idx = all_idx+param.RxFFE_cpx;

1928

idx = sort(idx);

1928

idx = sort(idx);

1929

function [ V0 ] = Fract_T_FFE( V , skew_step)

1929

function [ V0 ] = Fract_T_FFE( V , skew_step)

1930

% skew_step sub UI skew assuming param.samples_per_ui

1930

% skew_step sub UI skew assuming param.samples_per_ui

1931

% V input signal

1931

% V input signal

1932

% V0 output signal

1932

% V0 output signal

1933

% Richard Mellitz 8/17/2021

1933

% Richard Mellitz 8/17/2021

1934

V0=0;

1934

V0=0;

1935

if iscolumn(V); V=V.';end

1935

if iscolumn(V); V=V.';end

1936

ishift=skew_step;

1936

ishift=skew_step;

1937

V0=circshift(V',[ishift,0])'+V;

1937

V0=circshift(V',[ishift,0])'+V;

1938

V0=V0/2;

1938

V0=V0/2;

1939

function out=Full_Grid_Matrix(in)

1939

function out=Full_Grid_Matrix(in)

1940

1940

1941

%create a full grid matrix of input variables

1941

%create a full grid matrix of input variables

1942

%used to create the full grid of all txffe cases

1942

%used to create the full grid of all txffe cases

1943

%example:

1943

%example:

1944

%Full_Grid_Matrix({ [1 2] [100 200] })

1944

%Full_Grid_Matrix({ [1 2] [100 200] })

1945

%out =

1945

%out =

1946

% 1 100

1946

% 1 100

1947

% 1 200

1947

% 1 200

1948

% 2 100

1948

% 2 100

1949

% 2 200

1949

% 2 200

1950

%

1950

%

1951

%input can also be mixed between numeric and cell of char

1951

%input can also be mixed between numeric and cell of char

1952

%example:

1952

%example:

1953

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1953

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1954

%out =

1954

%out =

1955

% {[1]} {'A'}

1955

% {[1]} {'A'}

1956

% {[1]} {'B'}

1956

% {[1]} {'B'}

1957

% {[2]} {'A'}

1957

% {[2]} {'A'}

1958

% {[2]} {'B'}

1958

% {[2]} {'B'}

1959

1959

1960

if ~iscell(in)

1960

if ~iscell(in)

1961

error('input must be cell array of individual sweep variables');

1961

error('input must be cell array of individual sweep variables');

1962

end

1962

end

1963

1963

1964

num_columns=length(in);

1964

num_columns=length(in);

1965

num_cases=prod(cellfun('length',in));

1965

num_cases=prod(cellfun('length',in));

1966

1966

1967

cell_output=0;

1967

cell_output=0;

1968

cell_indices=cellfun(@(x) iscell(x),in);

1968

cell_indices=cellfun(@(x) iscell(x),in);

1969

if any(cell_indices)

1969

if any(cell_indices)

1970

cell_output=1;

1970

cell_output=1;

1971

end

1971

end

1972

if cell_output

1972

if cell_output

1973

for k=find(~cell_indices)

1973

for k=find(~cell_indices)

1974

in{k}=num2cell(in{k});

1974

in{k}=num2cell(in{k});

1975

end

1975

end

1976

end

1976

end

1977

1977

1978

if cell_output

1978

if cell_output

1979

out=cell(num_cases,num_columns);

1979

out=cell(num_cases,num_columns);

1980

else

1980

else

1981

out=zeros(num_cases,num_columns);

1981

out=zeros(num_cases,num_columns);

1982

end

1982

end

1983

1983

1984

%num_repetitions controls how many times each element of the column

1984

%num_repetitions controls how many times each element of the column

1985

%repeats. The first column is always just a copy of itself since every

1985

%repeats. The first column is always just a copy of itself since every

1986

%case will vary.

1986

%case will vary.

1987

num_repetitions=1;

1987

num_repetitions=1;

1988

for k=num_columns:-1:1

1988

for k=num_columns:-1:1

1989

this_column=in{k}(:);

1989

this_column=in{k}(:);

1990

%copy the column into a matrix to create the repetitions needed

1990

%copy the column into a matrix to create the repetitions needed

1991

B=repmat(this_column,[1 num_repetitions]);

1991

B=repmat(this_column,[1 num_repetitions]);

1992

%reshape into single column (actual repetitions)

1992

%reshape into single column (actual repetitions)

1993

C=reshape(B',[numel(B) 1]);

1993

C=reshape(B',[numel(B) 1]);

1994

%repeat the single column to build the entire length required

1994

%repeat the single column to build the entire length required

1995

num_repeats=num_cases/length(C);

1995

num_repeats=num_cases/length(C);

1996

D=repmat(C,[num_repeats 1]);

1996

D=repmat(C,[num_repeats 1]);

1997

out(:,k)=D;

1997

out(:,k)=D;

1998

%determine how many repetitions the next column needs

1998

%determine how many repetitions the next column needs

1999

num_repetitions=num_repetitions*length(this_column);

1999

num_repetitions=num_repetitions*length(this_column);

2000

end

2000

end

2001

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

2001

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

2002

% p=cpdf(type, ...)

2002

% p=cpdf(type, ...)

2003

%

2003

%

2004

% CPDF is a probability mass function for discrete distributions or an

2004

% CPDF is a probability mass function for discrete distributions or an

2005

% approxmation of a PDF for continuous distributions.

2005

% approxmation of a PDF for continuous distributions.

2006

%

2006

%

2007

% cpdf is internally normalized so that the sum of probabilities is 1

2007

% cpdf is internally normalized so that the sum of probabilities is 1

2008

% (regardless of bin size).

2008

% (regardless of bin size).

2009

2009

2010

% Internal fields:

2010

% Internal fields:

2011

% Min: *bin number* of minimum value.

2011

% Min: *bin number* of minimum value.

2012

% BinSize: size of PDF bins. Bin center is the representative value.

2012

% BinSize: size of PDF bins. Bin center is the representative value.

2013

% Vec: vector of probabilities per bin.

2013

% Vec: vector of probabilities per bin.

2014

2014

2015

pdf=EmptyPDF;

2015

pdf=EmptyPDF;

2016

2016

2017

rounded_values_div_binsize=round(values/pdf.BinSize);

2017

rounded_values_div_binsize=round(values/pdf.BinSize);

2018

%values=pdf.BinSize*rounded_values_div_binsize;

2018

%values=pdf.BinSize*rounded_values_div_binsize;

2019

2019

2020

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2020

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2021

% if all(values==0)

2021

% if all(values==0)

2022

% return;

2022

% return;

2023

% end

2023

% end

2024

%

2024

%

2025

% %speed up for all values rounded to the same bin

2025

% %speed up for all values rounded to the same bin

2026

% %The output pdf is the same as the

2026

% %The output pdf is the same as the

2027

% %empty pdf, but the x value is non-zero (but still scalar)

2027

% %empty pdf, but the x value is non-zero (but still scalar)

2028

% if all(values==values(1))

2028

% if all(values==values(1))

2029

% pdf.Min=rounded_values_div_binsize(1);

2029

% pdf.Min=rounded_values_div_binsize(1);

2030

% pdf.x=values(1);

2030

% pdf.x=values(1);

2031

% return;

2031

% return;

2032

% end

2032

% end

2033

%

2033

%

2034

% %The code below requires that values is

2034

% %The code below requires that values is

2035

% %sorted. Generally this should be true, but check to be sure

2035

% %sorted. Generally this should be true, but check to be sure

2036

% if ~issorted(values)

2036

% if ~issorted(values)

2037

% [values,si]=sort(values);

2037

% [values,si]=sort(values);

2038

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2038

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2039

% probs=probs(si);

2039

% probs=probs(si);

2040

% end

2040

% end

2041

2041

2042

2042

2043

%pdf.x=values(1):pdf.BinSize:values(end);

2043

%pdf.x=values(1):pdf.BinSize:values(end);

2044

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2044

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2045

pdf.Min=rounded_values_div_binsize(1);

2045

pdf.Min=rounded_values_div_binsize(1);

2046

2046

2047

pdf.y=zeros(size(pdf.x));

2047

pdf.y=zeros(size(pdf.x));

2048

%The rounded values divided by binsize will reveal the bin number if

2048

%The rounded values divided by binsize will reveal the bin number if

2049

%pdf.Min is subtracted from it

2049

%pdf.Min is subtracted from it

2050

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2050

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2051

%Can avoid one addition by inserting the first probability

2051

%Can avoid one addition by inserting the first probability

2052

%actually helps when calling this 2 million times

2052

%actually helps when calling this 2 million times

2053

pdf.y(bin_placement(1))=probs(1);

2053

pdf.y(bin_placement(1))=probs(1);

2054

for k=2:length(values)

2054

for k=2:length(values)

2055

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2055

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2056

end

2056

end

2057

2057

2058

2058

2059

%Have already ensured that sum(pdf.y)=1

2059

%Have already ensured that sum(pdf.y)=1

2060

%pdf.y=pdf.y/sum(pdf.y);

2060

%pdf.y=pdf.y/sum(pdf.y);

2061

2061

2062

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2062

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2063

% error('PDF must be real and nonnegative');

2063

% error('PDF must be real and nonnegative');

2064

% end

2064

% end

2065

2065

2066

% pMax=pdf.Min+length(pdf.y)-1;

2066

% pMax=pdf.Min+length(pdf.y)-1;

2067

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2067

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2068

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2068

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2069

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2069

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2070

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2070

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2071

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2071

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2072

2072

2073

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2073

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2074

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2074

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2075

2075

2076

%% step 0

2076

%% step 0

2077

COM_from_matlab=20*log10(A_s/A_ni);

2077

COM_from_matlab=20*log10(A_s/A_ni);

2078

L=param.levels;

2078

L=param.levels;

2079

DER0=param.specBER;

2079

DER0=param.specBER;

2080

%% step 1 from slide 6/5

2080

%% step 1 from slide 6/5

2081

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2081

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2082

main=A_peak;

2082

main=A_peak;

2083

k_DER=qfuncinv(param.specBER);

2083

k_DER=qfuncinv(param.specBER);

2084

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2084

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2085

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2085

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2086

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2086

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2087

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2087

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2088

if A_s >= A_ni

2088

if A_s >= A_ni

2089

%% step 2 slide 10/8

2089

%% step 2 slide 10/8

2090

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2090

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2091

%% step 2 slide 10/8

2091

%% step 2 slide 10/8

2092

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2092

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2093

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2093

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2094

%% step 3 side 11/9

2094

%% step 3 side 11/9

2095

j=1:200;

2095

j=1:200;

2096

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2096

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2097

DER_MLSE_CDF=0; jj=1;

2097

DER_MLSE_CDF=0; jj=1;

2098

DER_delta = inf;

2098

DER_delta = inf;

2099

while DER_delta > .001

2099

while DER_delta > .001

2100

last_DER_MLSE_CDF=DER_MLSE_CDF;

2100

last_DER_MLSE_CDF=DER_MLSE_CDF;

2101

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;

2101

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;

2102

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2102

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2103

jj=jj+1;

2103

jj=jj+1;

2104

end

2104

end

2105

%% step 4 slide 12/10

2105

%% step 4 slide 12/10

2106

SNR_DFE_eqivalent=SNR_DFE*(...

2106

SNR_DFE_eqivalent=SNR_DFE*(...

2107

(L-1)*sigma_noise/main * qfuncinv(...

2107

(L-1)*sigma_noise/main * qfuncinv(...

2108

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2108

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2109

) ...

2109

) ...

2110

)^2;

2110

)^2;

2111

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2111

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2112

(L-1)/main * CDF_inv_ev(...

2112

(L-1)/main * CDF_inv_ev(...

2113

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2113

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2114

,PDF, CDF ) ...

2114

,PDF, CDF ) ...

2115

)^2;

2115

)^2;

2116

2116

2117

%% step 5 slide 13/11

2117

%% step 5 slide 13/11

2118

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2118

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2119

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2119

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2120

new_com_CDF=COM_from_matlab+delta_com_CDF;

2120

new_com_CDF=COM_from_matlab+delta_com_CDF;

2121

else

2121

else

2122

warning('MLSE not applied because there is more noise than signal')

2122

warning('MLSE not applied because there is more noise than signal')

2123

DER_MLSE=[];

2123

DER_MLSE=[];

2124

DER_MLSE_CDF=[];

2124

DER_MLSE_CDF=[];

2125

SNR_DFE_eqivalent=[];

2125

SNR_DFE_eqivalent=[];

2126

SNR_DFE_eqivalent_CDF=[];

2126

SNR_DFE_eqivalent_CDF=[];

2127

new_com_CDF=COM_from_matlab;

2127

new_com_CDF=COM_from_matlab;

2128

delta_com_CDF=0;

2128

delta_com_CDF=0;

2129

delta_com=0;

2129

delta_com=0;

2130

SNR_DFE=[];

2130

SNR_DFE=[];

2131

end

2131

end

2132

2132

2133

%%

2133

%%

2134

MLSE_results.COM_from_matlab=COM_from_matlab;

2134

MLSE_results.COM_from_matlab=COM_from_matlab;

2135

MLSE_results.SNR_DFE=SNR_DFE;

2135

MLSE_results.SNR_DFE=SNR_DFE;

2136

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2136

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2137

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2137

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2138

MLSE_results.sigma_noise=sigma_noise;

2138

MLSE_results.sigma_noise=sigma_noise;

2139

MLSE_results.SNR_dB=SNR_dB ;

2139

MLSE_results.SNR_dB=SNR_dB ;

2140

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2140

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2141

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2141

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2142

MLSE_results.COM_Gaussian=new_com_CDF;

2142

MLSE_results.COM_Gaussian=new_com_CDF;

2143

MLSE_results.COM_CDF=new_com_CDF;

2143

MLSE_results.COM_CDF=new_com_CDF;

2144

MLSE_results.k_DER=k_DER;

2144

MLSE_results.k_DER=k_DER;

2145

MLSE_results.delta_com_CDF=delta_com_CDF;

2145

MLSE_results.delta_com_CDF=delta_com_CDF;

2146

MLSE_results.delta_com_Gaussian=delta_com;

2146

MLSE_results.delta_com_Gaussian=delta_com;

2147

2147

2148

2148

2149

2149

2150

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2150

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2151

if 1

2151

if 1

2152

num_ui=param.num_ui_RXFF_noise;

2152

num_ui=param.num_ui_RXFF_noise;

2153

M=param.samples_per_ui;

2153

M=param.samples_per_ui;

2154

L=param.levels;

2154

L=param.levels;

2155

sigma_X2=(L^2-1)/(3*(L-1)^2);

2155

sigma_X2=(L^2-1)/(3*(L-1)^2);

2156

f_b=param.fb;

2156

f_b=param.fb;

2157

DER0=param.specBER; % align terminology

2157

DER0=param.specBER; % align terminology

2158

delta_COM_an=param.pass_threshold; % align terminology

2158

delta_COM_an=param.pass_threshold; % align terminology

2159

end

2159

end

2160

% new function to scale CDF at specified DER; healey_3dj_01_2409 slide 8, 12, and 13

2160

% new function to scale CDF at specified DER; healey_3dj_01_2409 slide 8, 12, and 13

2161

% directly compute p_an (PDF) and P_an (CDF);

2161

% directly compute p_an (PDF) and P_an (CDF);

2162

[p_an, P_an, ~] = scaleCDF( PDF,delta_COM_an,DER0, A_s );

2162

[p_an, P_an, ~] = scaleCDF( PDF,delta_COM_an,DER0, A_s );

2163

sigma_an_2_pdf=sum(p_an.y.*p_an.x.^2)-sum(PDF.y.*PDF.x.^2);

2163

sigma_an_2_pdf=sum(p_an.y.*p_an.x.^2)-sum(PDF.y.*PDF.x.^2);

2164

sigma_G_2=PSD_results.S_G_rms^2;

2164

sigma_G_2=PSD_results.S_G_rms^2;

2165

g_an=(sigma_an_2_pdf-PSD_results.S_G_rms^2)/PSD_results.S_rn_rms^2;

2165

g_an=(sigma_an_2_pdf-PSD_results.S_G_rms^2)/PSD_results.S_rn_rms^2;

2166

2166

2167

% g_an be squared since votltage was scalted: healey_3dj_01_2409 slide 12 (178A –X) units are power

2167

% g_an be squared since votltage was scalted: healey_3dj_01_2409 slide 12 (178A –X) units are power

2168

% g_an=g_an^2;

2168

% g_an=g_an^2;

2169

COM_from_matlab=20*log10(A_s/A_ni);

2169

COM_from_matlab=20*log10(A_s/A_ni);

2170

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2170

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2171

if 1 % comparing to healey_3dj_01_2409 slide 8

2171

if 1 % comparing to healey_3dj_01_2409 slide 8

2172

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

2172

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

2173

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2173

semilogy(PDF.x/A_s,CDF,'disp',sprintf('P(y) case %g',param.package_testcase_i))

2174

ylim([1e-7 1e-1])

2174

ylim([1e-7 1e-1])

2175

grid on

2175

grid on

2176

movegui(gcf,[randn randn]*100)

2176

movegui(gcf,[randn randn]*100)

2177

xlabel('-A_ni/A_s')

2177

xlabel('-A_ni/A_s')

2178

ylabel('DER')

2178

ylabel('DER')

2179

hold on

2179

hold on

2180

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2180

semilogy(p_an.x/A_s,P_an,'disp',sprintf('P_a_n(y) case %g',param.package_testcase_i'))

2181

legend show

2181

legend show

2182

% fprintf('checking %.4g dB is the com threshold\n', db(CDF_inv_ev ( param.specBER,p_an,P_an )/CDF_inv_ev ( param.specBER,PDF,CDF ) ))

2182

% fprintf('checking %.4g dB is the com threshold\n', db(CDF_inv_ev ( param.specBER,p_an,P_an )/CDF_inv_ev ( param.specBER,PDF,CDF ) ))

2183

end

2183

end

2184

% PDF=p_an;

2184

% PDF=p_an;

2185

% CDF=P_an;

2185

% CDF=P_an;

2186

S_an=g_an*PSD_results.S_rn.*PSD_results.H_rxffe_2; % healey_3dj_01_2409 slide 12

2186

S_an=g_an*PSD_results.S_rn.*PSD_results.H_rxffe_2; % healey_3dj_01_2409 slide 12

2187

S_ni=PSD_results.S_isi +PSD_results.S_n +S_an; % 178A-40, healey_3dj_01_2409 slide 15

2187

S_ni=PSD_results.S_isi +PSD_results.S_n +S_an; % 178A-40, healey_3dj_01_2409 slide 15

2188

R_ni=ifft(S_ni)*f_b;

2188

R_ni=ifft(S_ni)*f_b;

2189

p_scaled_by_b=scalePDF(p_an,b(1));

2189

p_scaled_by_b=scalePDF(p_an,b(1));

2190

p_j=conv_fct(p_an,p_scaled_by_b);

2190

p_j=conv_fct(p_an,p_scaled_by_b);

2191

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2191

p_scaled_by_1mb=scalePDF(p_an,1-b(1));

2192

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2192

%% %% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2193

p_trunc = p_an;

2193

p_trunc = p_an;

2194

%

2194

%

2195

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2195

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2196

P_j.y=cumsum(p_j.y);

2196

P_j.y=cumsum(p_j.y);

2197

smallest_relative_change=.0001;

2197

smallest_relative_change=.0001;

2198

%% 178A–37

2198

%% 178A–37

2199

rou=R_ni'/R_ni(1);

2199

rou=R_ni'/R_ni(1);

2200

if DER_DFE <= param.DER_CDR

2200

if DER_DFE <= param.DER_CDR

2201

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2201

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2202

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2202

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2203

u_j(2:2:end-1)=-u_j(2:2:end-1);

2203

u_j(2:2:end-1)=-u_j(2:2:end-1);

2204

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2204

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2205

V_j=toeplitz(rou(1:j+1));

2205

V_j=toeplitz(rou(1:j+1));

2206

P_j=cumsum(p_j.y);

2206

P_j=cumsum(p_j.y);

2207

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-P_an)

2207

DER_MLSE_j= ((L-1)/L)^(j-1) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(1/2), p_j, P_j ) ) ; % CDF_ev is (1-P_an)

2208

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2208

% DER_MLSE_j= 2*(3/4)^(j) * ( CDF_ev( A_s *(u_j.'* u_j )^(3/2)/( u_j.'*V_j*u_j)^(0.5), p_j, P_j ) ) ; % CDF_ev is (1-CDF)

2209

DER_MLSE=DER_MLSE+DER_MLSE_j;

2209

DER_MLSE=DER_MLSE+DER_MLSE_j;

2210

p_j=conv_fct(p_j,p_scaled_by_1mb);

2210

p_j=conv_fct(p_j,p_scaled_by_1mb);

2211

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2211

%% %% shakiba_3dj_01_2407(to add MLSE sequence truncation penalty)

2212

if j == param.trunc

2212

if j == param.trunc

2213

u_trunc = u_j(1:j);

2213

u_trunc = u_j(1:j);

2214

V_trunc = V_j(1:j, 1:j);

2214

V_trunc = V_j(1:j, 1:j);

2215

P_trunc = cumsum(p_trunc.y);

2215

P_trunc = cumsum(p_trunc.y);

2216

DER_MLSE_trunc = DER_MLSE_trunc+L*((L-1)/L)^(j-1)*CDF_ev(A_s*(u_trunc'*u_trunc)^(3/2)/(u_trunc'*V_trunc*u_trunc)^(1/2), p_trunc, P_trunc);

2216

DER_MLSE_trunc = DER_MLSE_trunc+L*((L-1)/L)^(j-1)*CDF_ev(A_s*(u_trunc'*u_trunc)^(3/2)/(u_trunc'*V_trunc*u_trunc)^(1/2), p_trunc, P_trunc);

2217

elseif j < param.trunc

2217

elseif j < param.trunc

2218

DER_MLSE_trunc = DER_MLSE;

2218

DER_MLSE_trunc = DER_MLSE;

2219

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2219

p_trunc = conv_fct(p_trunc, p_scaled_by_1mb); % Convolves trunc-1 times

2220

P_trunc = cumsum(p_trunc.y);

2220

P_trunc = cumsum(p_trunc.y);

2221

end

2221

end

2222

j=j+1;

2222

j=j+1;

2223

end

2223

end

2224

%% healey_3dj_01a_2407

2224

%% healey_3dj_01a_2407

2225

if param.Q_budget_adj == 0

2225

if param.Q_budget_adj == 0

2226

Q_budget_adj=0;

2226

Q_budget_adj=0;

2227

else

2227

else

2228

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2228

Q_budget_adj=param.Q_budget_adj(1) -param.Q_budget_adj(2)*COM_from_matlab;

2229

end

2229

end

2230

%% shakiba_3dj_01_2407

2230

%% shakiba_3dj_01_2407

2231

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE ,p_an,P_an ) )- param.Q ;% shakiba_3dj_01_2405

2231

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE ,p_an,P_an ) )- param.Q ;% shakiba_3dj_01_2405

2232

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,p_an,P_an ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2232

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE_trunc,p_an,P_an ) )- Q_budget_adj ;% shakiba_3dj_01_2405

2233

%% shakiba_3dj_01_2407

2233

%% shakiba_3dj_01_2407

2234

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2234

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,p_an,CDF ) )- Q ;% (178A–36)

2235

new_com=COM_from_matlab+delta_com;

2235

new_com=COM_from_matlab+delta_com;

2236

if(delta_com<0)

2236

if(delta_com<0)

2237

delta_com=0;

2237

delta_com=0;

2238

warning('MLSE truncation failed. Try increasing trunc')

2238

warning('MLSE truncation failed. Try increasing trunc')

2239

try

2239

try

2240

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2240

hx=msgbox('MLSE truncation failed. Try increasing N_tc','warning','warn');

2241

set(hx,'Color',[1 0 1]);

2241

set(hx,'Color',[1 0 1]);

2242

movegui(hx,[randn randn]*100)

2242

movegui(hx,[randn randn]*100)

2243

set(hx,'Tag','COM') %

2243

set(hx,'Tag','COM') %

2244

catch

2244

catch

2245

end

2245

end

2246

end

2246

end

2247

else

2247

else

2248

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2248

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2249

DER_MLSE=NaN;

2249

DER_MLSE=NaN;

2250

new_com=COM_from_matlab;

2250

new_com=COM_from_matlab;

2251

delta_com=0;

2251

delta_com=0;

2252

Q=0;

2252

Q=0;

2253

Q_budget_adj=0;

2253

Q_budget_adj=0;

2254

DER_MLSE_trunc=NaN;

2254

DER_MLSE_trunc=NaN;

2255

%% shakiba_3dj_01_2407

2255

%% shakiba_3dj_01_2407

2256

end

2256

end

2257

2257

2258

%%

2258

%%

2259

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2259

[PDF1, CDF1, ~] = scaleCDF( PDF,-delta_com,DER0, A_s ); % create new pdf/cdf estimate for display only

2260

MLSE_results.CDF=CDF1;

2260

MLSE_results.CDF=CDF1;

2261

MLSE_results.PDF=PDF1;

2261

MLSE_results.PDF=PDF1;

2262

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2262

MLSE_results.DER_MLSE_trunc = DER_MLSE_trunc;% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

2263

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2263

MLSE_results.Q_budget_adj=Q_budget_adj; % healey_3dj_01a_2407

2264

MLSE_results.COM_from_matlab=COM_from_matlab;

2264

MLSE_results.COM_from_matlab=COM_from_matlab;

2265

MLSE_results.DER_MLSE=DER_MLSE;

2265

MLSE_results.DER_MLSE=DER_MLSE;

2266

MLSE_results.DER_DFE=DER_DFE;

2266

MLSE_results.DER_DFE=DER_DFE;

2267

MLSE_results.COM=new_com;

2267

MLSE_results.COM=new_com;

2268

MLSE_results.delta_com=delta_com;

2268

MLSE_results.delta_com=delta_com;

2269

MLSE_results.g_an=g_an;

2269

MLSE_results.g_an=g_an;

2270

2270

2271

2271

2272

2272

2273

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2273

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2274

if 1

2274

if 1

2275

num_ui=param.num_ui_RXFF_noise;

2275

num_ui=param.num_ui_RXFF_noise;

2276

M=param.samples_per_ui;

2276

M=param.samples_per_ui;

2277

L=param.levels;

2277

L=param.levels;

2278

sigma_X2=(L^2-1)/(3*(L-1)^2);

2278

sigma_X2=(L^2-1)/(3*(L-1)^2);

2279

fb=param.fb;

2279

fb=param.fb;

2280

R_LM=param.R_LM;

2280

R_LM=param.R_LM;

2281

end

2281

end

2282

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2282

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2283

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2283

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2284

% h=reshape(h,1,[]); % make row vectors

2284

% h=reshape(h,1,[]); % make row vectors

2285

% h=[ h(1:floor(length(h)/M)*M) ];

2285

% h=[ h(1:floor(length(h)/M)*M) ];

2286

% h= [h zeros(1,num_ui*M-length(h)) ];

2286

% h= [h zeros(1,num_ui*M-length(h)) ];

2287

% h=h(1:M:end);% resample

2287

% h=h(1:M:end);% resample

2288

% N=length(h);

2288

% N=length(h);

2289

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2289

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2290

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2290

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2291

2291

2292

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2292

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2293

dh= find(samp_idx == cursor_i)-1;

2293

dh= find(samp_idx == cursor_i)-1;

2294

dw=param.RxFFE_cmx;

2294

dw=param.RxFFE_cmx;

2295

h = reshape(sbr(samp_idx),1,[]); % make row vector

2295

h = reshape(sbr(samp_idx),1,[]); % make row vector

2296

h(end+1:num_ui)=0;

2296

h(end+1:num_ui)=0;

2297

h = h(1:num_ui); % h needs to have num_ui points

2297

h = h(1:num_ui); % h needs to have num_ui points

2298

N=length(h); % used in subsequent expressions

2298

N=length(h); % used in subsequent expressions

2299

2299

2300

if param.N_bg == 0

2300

if param.N_bg == 0

2301

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2301

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2302

bmax=param.bmax;

2302

bmax=param.bmax;

2303

bmin=param.bmin ;

2303

bmin=param.bmin ;

2304

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 ];

2304

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 ];

2305

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 ];

2305

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 ];

2306

idx=[];

2306

idx=[];

2307

else

2307

else

2308

Nfloating_taps=param.N_bf*param.N_bg;

2308

Nfloating_taps=param.N_bf*param.N_bg;

2309

Nmax=param.N_bmax;

2309

Nmax=param.N_bmax;

2310

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2310

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2311

Ng=param.N_bg;

2311

Ng=param.N_bg;

2312

Nf=param.N_bf;

2312

Nf=param.N_bf;

2313

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2313

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2314

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2314

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2315

% hisi=h(dh+2:((dh-dw)+Nw));

2315

% hisi=h(dh+2:((dh-dw)+Nw));

2316

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2316

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2317

% idx=sort(idx);

2317

% idx=sort(idx);

2318

bmax=param.bmax;

2318

bmax=param.bmax;

2319

bmin=param.bmin ;

2319

bmin=param.bmin ;

2320

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 ];

2320

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 ];

2321

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 ];

2321

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 ];

2322

end

2322

end

2323

Nb=param.ndfe; % DFE taps

2323

Nb=param.ndfe; % DFE taps

2324

d=dw+dh; % used for index in algorithms

2324

d=dw+dh; % used for index in algorithms

2325

indx(1:N)=(1:N)-dh-1;

2325

indx(1:N)=(1:N)-dh-1;

2326

S_n=PSD_results.S_n; % total agregate noise PSD

2326

S_n=PSD_results.S_n; % total agregate noise PSD

2327

Rn=ifft(S_n)*fb;

2327

Rn=ifft(S_n)*fb;

2328

%% HH and R

2328

%% HH and R

2329

2329

2330

%Test routine finding rxffe floating taps using best FOM for each bank

2330

%Test routine finding rxffe floating taps using best FOM for each bank

2331

isi_start = dh+2;

2331

isi_start = dh+2;

2332

isi_end = (dh-dw)+Nw;

2332

isi_end = (dh-dw)+Nw;

2333

2333

2334

%check for num_ui too small

2334

%check for num_ui too small

2335

if isi_end > length(h)

2335

if isi_end > length(h)

2336

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2336

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2337

end

2337

end

2338

2338

2339

hc1=[ h zeros(1,Nw-1) ];

2339

hc1=[ h zeros(1,Nw-1) ];

2340

hr1=[ h(1) zeros(1,Nw-1)];

2340

hr1=[ h(1) zeros(1,Nw-1)];

2341

H=toeplitz(hc1,hr1);

2341

H=toeplitz(hc1,hr1);

2342

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2342

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2343

if param.N_bg ~= 0

2343

if param.N_bg ~= 0

2344

switch lower(OP.RXFFE_FLOAT_CTL)

2344

switch lower(OP.RXFFE_FLOAT_CTL)

2345

case 'isi'

2345

case 'isi'

2346

hisi=h(dh+2:((dh-dw)+Nw));

2346

hisi=h(dh+2:((dh-dw)+Nw));

2347

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2347

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2348

idx=sort(idx);

2348

idx=sort(idx);

2349

otherwise

2349

otherwise

2350

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2350

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2351

idx=sort(idx);

2351

idx=sort(idx);

2352

end

2352

end

2353

end

2353

end

2354

[sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx); % bring out blim for

2354

[sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx); % bring out blim for

2355

MMSE_results.sigma_e=sigma_e; %

2355

MMSE_results.sigma_e=sigma_e; %

2356

MMSE_results.FOM=FOM;

2356

MMSE_results.FOM=FOM;

2357

Craw=w/w(dw+1); % returned Rx FFE taps

2357

Craw=w/w(dw+1); % returned Rx FFE taps

2358

% re-align Cmod to floating tap locations

2358

% re-align Cmod to floating tap locations

2359

if param.N_bg ~= 0

2359

if param.N_bg ~= 0

2360

C=Craw;

2360

C=Craw;

2361

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2361

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2362

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2362

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2363

else

2363

else

2364

C=Craw;

2364

C=Craw;

2365

end

2365

end

2366

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2366

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2367

MMSE_results.C=C;

2367

MMSE_results.C=C;

2368

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2368

MMSE_results.blim=blim; % added blim passed out for MLSD for 178A-39

2369

MMSE_results.Nw=Nw;

2369

MMSE_results.Nw=Nw;

2370

2370

2371

2371

2372

2372

2373

2373

2374

2374

2375

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2375

function [sigma_e,FOM,w,idx,Nw,blim] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2376

% added blim passed out for MLSD

2376

% added blim passed out for MLSD

2377

if isempty(idx)

2377

if isempty(idx)

2378

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2378

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2379

bmax=param.bmax;

2379

bmax=param.bmax;

2380

bmin=param.bmin ;

2380

bmin=param.bmin ;

2381

else

2381

else

2382

Nfloating_taps=param.N_bf*param.N_bg;

2382

Nfloating_taps=param.N_bf*param.N_bg;

2383

%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

2383

%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

2384

Nfloating_taps = length(idx);

2384

Nfloating_taps = length(idx);

2385

Nmax=param.N_bmax;

2385

Nmax=param.N_bmax;

2386

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2386

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2387

Ng=param.N_bg;

2387

Ng=param.N_bg;

2388

Nf=param.N_bf;

2388

Nf=param.N_bf;

2389

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2389

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2390

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2390

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2391

end

2391

end

2392

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2392

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2393

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2393

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2394

% hc1=[ h zeros(1,Nw-1) ];

2394

% hc1=[ h zeros(1,Nw-1) ];

2395

% hr1=[ h(1) zeros(1,Nw-1)];

2395

% hr1=[ h(1) zeros(1,Nw-1)];

2396

% H=toeplitz(hc1,hr1);

2396

% H=toeplitz(hc1,hr1);

2397

2397

2398

if param.N_bg ~= 0

2398

if param.N_bg ~= 0

2399

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2399

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2400

end

2400

end

2401

%% HH and R

2401

%% HH and R

2402

HH= H'*H;

2402

HH= H'*H;

2403

if param.N_bg ~= 0

2403

if param.N_bg ~= 0

2404

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2404

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2405

end

2405

end

2406

R=HH+Rnn/sigma_X2;

2406

R=HH+Rnn/sigma_X2;

2407

%% hb and h0

2407

%% hb and h0

2408

Hb= H(d+2:d+Nb+1,:);

2408

Hb= H(d+2:d+Nb+1,:);

2409

h0=H(d+1,:);

2409

h0=H(d+1,:);

2410

% display(floor(h0));

2410

% display(floor(h0));

2411

2411

2412

%% Ib and zb (slide 10)

2412

%% Ib and zb (slide 10)

2413

ib=eye(Nb);

2413

ib=eye(Nb);

2414

zb=zeros(1,Nb);

2414

zb=zeros(1,Nb);

2415

wbl= [ R -Hb' -h0';...

2415

wbl= [ R -Hb' -h0';...

2416

-Hb ib zb'; ...

2416

-Hb ib zb'; ...

2417

h0 zb 0]\[h0'; zb' ;1];

2417

h0 zb 0]\[h0'; zb' ;1];

2418

2418

2419

%% re-adjust Nw to number of used taps

2419

%% re-adjust Nw to number of used taps

2420

if param.N_bg ~= 0

2420

if param.N_bg ~= 0

2421

Nw=Nwft;

2421

Nw=Nwft;

2422

end

2422

end

2423

%% check equalized pulse

2423

%% check equalized pulse

2424

w=wbl(1:Nw);

2424

w=wbl(1:Nw);

2425

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2425

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2426

2426

2427

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2427

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2428

blim = min(bmax(:), max(bmin(:), b));

2428

blim = min(bmax(:), max(bmin(:), b));

2429

if (Nb > 0) && ~isequal(b, blim)

2429

if (Nb > 0) && ~isequal(b, blim)

2430

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2430

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2431

w = wl(1:Nw);

2431

w = wl(1:Nw);

2432

end

2432

end

2433

2433

2434

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2434

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2435

%so need to chop off the extra indices on wmax and wmin

2435

%so need to chop off the extra indices on wmax and wmin

2436

if length(w)<length(wmax)

2436

if length(w)<length(wmax)

2437

wmax=wmax(1:length(w));

2437

wmax=wmax(1:length(w));

2438

wmin=wmin(1:length(w));

2438

wmin=wmin(1:length(w));

2439

end

2439

end

2440

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2440

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2441

if ~isequal(w, wlim)

2441

if ~isequal(w, wlim)

2442

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2442

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2443

if Nb > 0

2443

if Nb > 0

2444

b = Hb*wlim; % Update the feedback coefficients.

2444

b = Hb*wlim; % Update the feedback coefficients.

2445

blim = min(bmax(:), max(bmin(:), b));

2445

blim = min(bmax(:), max(bmin(:), b));

2446

end

2446

end

2447

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2447

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2448

% wl = wl(1:Nw);

2448

% wl = wl(1:Nw);

2449

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2449

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2450

end

2450

end

2451

% w=w(1:Nw) ;

2451

% w=w(1:Nw) ;

2452

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2452

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2453

w=wlim;

2453

w=wlim;

2454

b=blim;

2454

b=blim;

2455

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

2455

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

2456

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2456

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2457

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

2457

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

2458

2458

2459

%not all output_args are filled here but most are

2459

%not all output_args are filled here but most are

2460

2460

2461

switch lower(OP.TDECQ)

2461

switch lower(OP.TDECQ)

2462

case { false 'none' } % should be the default

2462

case { false 'none' } % should be the default

2463

output_args.VMA=[];

2463

output_args.VMA=[];

2464

case 'vma'

2464

case 'vma'

2465

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2465

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2466

output_args.VMA=est_vma.VMA;

2466

output_args.VMA=est_vma.VMA;

2467

otherwise

2467

otherwise

2468

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2468

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2469

end

2469

end

2470

2470

2471

fileset_str=str2csv({chdata.base});

2471

fileset_str=str2csv({chdata.base});

2472

output_args.file_names=sprintf('"%s"', fileset_str);

2472

output_args.file_names=sprintf('"%s"', fileset_str);

2473

% [ahealey] Echo the termination parameters in the output arguments..

2473

% [ahealey] Echo the termination parameters in the output arguments..

2474

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2474

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2475

output_args.(odt_param{:}) = param.(odt_param{:});

2475

output_args.(odt_param{:}) = param.(odt_param{:});

2476

end

2476

end

2477

% [ahealey] End of modifications.

2477

% [ahealey] End of modifications.

2478

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2478

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2479

output_args.(pkg_params{:})= param.(pkg_params{:});

2479

output_args.(pkg_params{:})= param.(pkg_params{:});

2480

end

2480

end

2481

output_args.baud_rate_GHz=param.fb/1e9;

2481

output_args.baud_rate_GHz=param.fb/1e9;

2482

output_args.f_Nyquist_GHz = param.fb/2e9;

2482

output_args.f_Nyquist_GHz = param.fb/2e9;

2483

output_args.BER=param.specBER;

2483

output_args.BER=param.specBER;

2484

output_args.FOM = fom_result.FOM;

2484

output_args.FOM = fom_result.FOM;

2485

output_args.sigma_N=Noise_Struct.sigma_N;

2485

output_args.sigma_N=Noise_Struct.sigma_N;

2486

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2486

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2487

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2487

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2488

output_args.tail_RSS=fom_result.tail_RSS;

2488

output_args.tail_RSS=fom_result.tail_RSS;

2489

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2489

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2490

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2490

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2491

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2491

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2492

try

2492

try

2493

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2493

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2494

catch

2494

catch

2495

output_args.uneq_FIR_peak_time=[];

2495

output_args.uneq_FIR_peak_time=[];

2496

end

2496

end

2497

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2497

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2498

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2498

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2499

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2499

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2500

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2500

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2501

2501

2502

if OP.RX_CALIBRATION== 1

2502

if OP.RX_CALIBRATION== 1

2503

output_args.sigma_bn=sigma_bn;

2503

output_args.sigma_bn=sigma_bn;

2504

else

2504

else

2505

output_args.sigma_bn=[];

2505

output_args.sigma_bn=[];

2506

end

2506

end

2507

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2507

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2508

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2508

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2509

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2509

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2510

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2510

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2511

2511

2512

if OP.RX_CALIBRATION == 0

2512

if OP.RX_CALIBRATION == 0

2513

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2513

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2514

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2514

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2515

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2515

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2516

else

2516

else

2517

output_args.peak_MDXTK_interference_at_BER_mV=[];

2517

output_args.peak_MDXTK_interference_at_BER_mV=[];

2518

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2518

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2519

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2519

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2520

end

2520

end

2521

%output_args.ICN_mV=ICN*1000;

2521

%output_args.ICN_mV=ICN*1000;

2522

% output_args.ICN_test_mV=ICN_test*1000;

2522

% output_args.ICN_test_mV=ICN_test*1000;

2523

xtk=param.num_next+param.num_fext;

2523

xtk=param.num_next+param.num_fext;

2524

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2524

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2525

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2525

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2526

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2526

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2527

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2527

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2528

else

2528

else

2529

output_args.MDNEXT_ICN_92_46_mV=0;

2529

output_args.MDNEXT_ICN_92_46_mV=0;

2530

output_args.MDFEXT_ICN_92_47_mV=0;

2530

output_args.MDFEXT_ICN_92_47_mV=0;

2531

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2531

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2532

end

2532

end

2533

%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

2533

%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

2534

if 1

2534

if 1

2535

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)));

2535

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)));

2536

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2536

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2537

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2537

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2538

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2538

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2539

end

2539

end

2540

2540

2541

2541

2542

switch param.CTLE_type

2542

switch param.CTLE_type

2543

case 'CL93'

2543

case 'CL93'

2544

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2544

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2545

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2545

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2546

output_args.g_DC_HP=[];

2546

output_args.g_DC_HP=[];

2547

output_args.HP_poles_zero=[];

2547

output_args.HP_poles_zero=[];

2548

case 'CL120d'

2548

case 'CL120d'

2549

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2549

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2550

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2550

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2551

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2551

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2552

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2552

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2553

case 'CL120e'

2553

case 'CL120e'

2554

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)];

2554

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)];

2555

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2555

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2556

output_args.g_DC_HP=[];

2556

output_args.g_DC_HP=[];

2557

output_args.HP_poles_zero=[];

2557

output_args.HP_poles_zero=[];

2558

end

2558

end

2559

output_args.TXLE_taps=fom_result.txffe;

2559

output_args.TXLE_taps=fom_result.txffe;

2560

if length(output_args.TXLE_taps) >= 3

2560

if length(output_args.TXLE_taps) >= 3

2561

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2561

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2562

else

2562

else

2563

output_args.Pre2Pmax=[];

2563

output_args.Pre2Pmax=[];

2564

end

2564

end

2565

output_args.DFE_taps=fom_result.DFE_taps;

2565

output_args.DFE_taps=fom_result.DFE_taps;

2566

if param.Floating_DFE || param.Floating_RXFFE

2566

if param.Floating_DFE || param.Floating_RXFFE

2567

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2567

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2568

else

2568

else

2569

output_args.floating_tap_locations=[];

2569

output_args.floating_tap_locations=[];

2570

end

2570

end

2571

2571

2572

if OP.RxFFE

2572

if OP.RxFFE

2573

output_args.RxFFE=fom_result.RxFFE;

2573

output_args.RxFFE=fom_result.RxFFE;

2574

output_args.RxFFEgain=param.current_ffegain;

2574

output_args.RxFFEgain=param.current_ffegain;

2575

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2575

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2576

output_args.RxFFE=[];

2576

output_args.RxFFE=[];

2577

output_args.RxFFEgain=[];

2577

output_args.RxFFEgain=[];

2578

end

2578

end

2579

2579

2580

output_args.itick=fom_result.itick;

2580

output_args.itick=fom_result.itick;

2581

2581

2582

% Calculation of error propagation and burst probability

2582

% Calculation of error propagation and burst probability

2583

if OP.nburst>0

2583

if OP.nburst>0

2584

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2584

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2585

output_args.error_propagation_probability = p_error_propagation;

2585

output_args.error_propagation_probability = p_error_propagation;

2586

output_args.burst_probabilities = p_burst;

2586

output_args.burst_probabilities = p_burst;

2587

else

2587

else

2588

output_args.error_propagation_probability = [];

2588

output_args.error_propagation_probability = [];

2589

output_args.burst_probabilities = [];

2589

output_args.burst_probabilities = [];

2590

end

2590

end

2591

2591

2592

2592

2593

%begin yasuo patch 12/11/2018

2593

%begin yasuo patch 12/11/2018

2594

% collect sigma values to report

2594

% collect sigma values to report

2595

% pdf2sgm() is a function to calculate sigma value from PDF

2595

% pdf2sgm() is a function to calculate sigma value from PDF

2596

% It is added at the end of this file code.

2596

% It is added at the end of this file code.

2597

% I am not sure if an equivalent function already exists.

2597

% I am not sure if an equivalent function already exists.

2598

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2598

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2599

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2599

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2600

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2600

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2601

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2601

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2602

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2602

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2603

output_args.sgm_G = Noise_Struct.sigma_G;

2603

output_args.sgm_G = Noise_Struct.sigma_G;

2604

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2604

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2605

output_args.sgm_N = Noise_Struct.sigma_N;

2605

output_args.sgm_N = Noise_Struct.sigma_N;

2606

output_args.sgm_TX = Noise_Struct.sigma_TX;

2606

output_args.sgm_TX = Noise_Struct.sigma_TX;

2607

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2607

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2608

if OP.RX_CALIBRATION == 0

2608

if OP.RX_CALIBRATION == 0

2609

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2609

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2610

else

2610

else

2611

output_args.sgm_xt=[];

2611

output_args.sgm_xt=[];

2612

end

2612

end

2613

% end yasuo patch

2613

% end yasuo patch

2614

2614

2615

% r259 putting COM, VEO and loss last in report

2615

% r259 putting COM, VEO and loss last in report

2616

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2616

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2617

if param.ENOB ~= 0

2618

output_args.sgm_Q =Noise_Struct.sigma_Q;

2619

output_args.sigma_before_clip = Noise_Struct.sigma_before_clip;

2620

output_args.peak_clip = Noise_Struct.peak_clip;

2621

output_args.P2ptopsigma_clip = Noise_Struct.p2ptosigma_clip;

2622

end

2623

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2617

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2624

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2618

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2625

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

2619

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

2626

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2620

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2627

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2621

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2628

output_args.VEO_window_mUI= param.T_O;

2622

output_args.VEO_window_mUI= param.T_O;

2629

else

2623

else

2630

output_args.EW_UI_est=[];

2624

output_args.EW_UI_est=[];

2631

output_args.eye_contour=[];

2625

output_args.eye_contour=[];

2632

output_args.VEO_window_mUI= [];

2626

output_args.VEO_window_mUI= [];

2633

end

2627

end

2634

2628

2635

if sum(param.AC_CM_RMS) ~= 0

2629

if sum(param.AC_CM_RMS) ~= 0

2636

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2630

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2637

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2631

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2638

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2632

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2639

else

2633

else

2640

output_args.sigma_ACCM_at_tp0_mV=[];

2634

output_args.sigma_ACCM_at_tp0_mV=[];

2641

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2635

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2642

end

2636

end

2643

if OP.MLSE

2637

if OP.MLSE

2644

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2638

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2645

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2639

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2646

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2640

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2647

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2641

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2648

if strcmpi(upper(OP.PHY),'C2M')

2642

if strcmpi(upper(OP.PHY),'C2M')

2649

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2643

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2650

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2644

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2651

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2645

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2652

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2646

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2653

end

2647

end

2654

end

2648

end

2655

%

2649

%

2656

output_args.COM_dB=COM_SNR_Struct.COM;

2650

output_args.COM_dB=COM_SNR_Struct.COM;

2657

% end yasuo patch

2651

% end yasuo patch

2658

% begin yasuo patch 3/18/2019

2652

% begin yasuo patch 3/18/2019

2659

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2653

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2660

% end yasuo patch

2654

% end yasuo patch

2661

function [ seq syms syms_nrz ] = PRBS13Q( )

2655

function [ seq syms syms_nrz ] = PRBS13Q( )

2662

%UNTITLED Summary of this function goes here

2656

%UNTITLED Summary of this function goes here

2663

% Detailed explanation goes here

2657

% Detailed explanation goes here

2664

2658

2665

2659

2666

taps = ([13 12 2 1]);

2660

taps = ([13 12 2 1]);

2667

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2661

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2668

[seq_nrz c] =LFSR(seed,taps);

2662

[seq_nrz c] =LFSR(seed,taps);

2669

seq_nrz=2*(seq_nrz-0.5);

2663

seq_nrz=2*(seq_nrz-0.5);

2670

seq=pam(seq_nrz);

2664

seq=pam(seq_nrz);

2671

% syms=round(2*(seq+1));

2665

% syms=round(2*(seq+1));

2672

syms((round(2*(seq+1))/2==2))=3;

2666

syms((round(2*(seq+1))/2==2))=3;

2673

syms((round(2*(seq+1))/2==1.5))=2;

2667

syms((round(2*(seq+1))/2==1.5))=2;

2674

syms((round(2*(seq+1))/2==.5))=1;

2668

syms((round(2*(seq+1))/2==.5))=1;

2675

syms((round(2*(seq+1))/2==0))=0;

2669

syms((round(2*(seq+1))/2==0))=0;

2676

2670

2677

% syms_nrz=((seq_nrz+1)/2);

2671

% syms_nrz=((seq_nrz+1)/2);

2678

2672

2679

syms_nrz=seq_nrz;

2673

syms_nrz=seq_nrz;

2680

2674

2681

2675

2682

function[seq c]=LFSR(s,t)

2676

function[seq c]=LFSR(s,t)

2683

%s=initial state of LFSR, you can choose any lenght of LFSR

2677

%s=initial state of LFSR, you can choose any lenght of LFSR

2684

%Instruction:==========

2678

%Instruction:==========

2685

%Save LFSR.m in your current directory and type following

2679

%Save LFSR.m in your current directory and type following

2686

%on Command window for simulating 5 bit LFSR with tap [5 2]

2680

%on Command window for simulating 5 bit LFSR with tap [5 2]

2687

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

2681

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

2688

%>>s=[1 1 0 0 1]

2682

%>>s=[1 1 0 0 1]

2689

%>>t=[5 2]

2683

%>>t=[5 2]

2690

%>>[seq c] =LFSR(s,t)

2684

%>>[seq c] =LFSR(s,t)

2691

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

2685

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

2692

%seq = generated sequence

2686

%seq = generated sequence

2693

%c will be matrix containing the states of LFSR raw wise

2687

%c will be matrix containing the states of LFSR raw wise

2694

%

2688

%

2695

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

2689

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

2696

%If any doubt, confusion or feedback please contact me

2690

%If any doubt, confusion or feedback please contact me

2697

% NIKESH BAJAJ

2691

% NIKESH BAJAJ

2698

% bajaj.nikkey@gmail.com (+91-9915522564)

2692

% bajaj.nikkey@gmail.com (+91-9915522564)

2699

% Asst. Professor at Lovely Profesional University

2693

% Asst. Professor at Lovely Profesional University

2700

% Masters from Aligarh Muslim University,INDIA

2694

% Masters from Aligarh Muslim University,INDIA

2701

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

2695

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

2702

n=length(s);

2696

n=length(s);

2703

c(1,:)=s;

2697

c(1,:)=s;

2704

m=length(t);

2698

m=length(t);

2705

for k=1:2^n-2;

2699

for k=1:2^n-2;

2706

b(1)=xor(s(t(1)), s(t(2)));

2700

b(1)=xor(s(t(1)), s(t(2)));

2707

if m>2;

2701

if m>2;

2708

for i=1:m-2;

2702

for i=1:m-2;

2709

b(i+1)=xor(s(t(i+2)), b(i));

2703

b(i+1)=xor(s(t(i+2)), b(i));

2710

end

2704

end

2711

end

2705

end

2712

j=1:n-1;

2706

j=1:n-1;

2713

s(n+1-j)=s(n-j);

2707

s(n+1-j)=s(n-j);

2714

s(1)=b(m-1);

2708

s(1)=b(m-1);

2715

c(k+1,:)=s;

2709

c(k+1,:)=s;

2716

end

2710

end

2717

seq=c(:,n)';

2711

seq=c(:,n)';

2718

2712

2719

function [ dataout ] = pam( data )

2713

function [ dataout ] = pam( data )

2720

% mapping data usng Grey Coding

2714

% mapping data usng Grey Coding

2721

for i=1:2:floor(length(data)/2)*2

2715

for i=1:2:floor(length(data)/2)*2

2722

if data(i:i+1)==[ -1 -1 ]

2716

if data(i:i+1)==[ -1 -1 ]

2723

dataout(ceil(i/2)) = -1;

2717

dataout(ceil(i/2)) = -1;

2724

elseif data(i:i+1)==[ -1 1 ]

2718

elseif data(i:i+1)==[ -1 1 ]

2725

dataout(ceil(i/2)) = -1/3;

2719

dataout(ceil(i/2)) = -1/3;

2726

elseif data(i:i+1)==[ 1 1 ]

2720

elseif data(i:i+1)==[ 1 1 ]

2727

dataout(ceil(i/2)) = 1/3;

2721

dataout(ceil(i/2)) = 1/3;

2728

elseif data(i:i+1)==[ 1 -1 ]

2722

elseif data(i:i+1)==[ 1 -1 ]

2729

dataout(ceil(i/2)) = 1;

2723

dataout(ceil(i/2)) = 1;

2730

end

2724

end

2731

end

2725

end

2732

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2726

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2733

db = @(x) 20*log10(abs(x));

2727

db = @(x) 20*log10(abs(x));

2734

disp('computing TD_RILN...')

2728

disp('computing TD_RILN...')

2735

sdd21=squeeze(sdd21);

2729

sdd21=squeeze(sdd21);

2736

if iscolumn(sdd21)

2730

if iscolumn(sdd21)

2737

sdd21=sdd21.';

2731

sdd21=sdd21.';

2738

end

2732

end

2739

RIL=squeeze(RIL);

2733

RIL=squeeze(RIL);

2740

if iscolumn(RIL)

2734

if iscolumn(RIL)

2741

RIL=RIL.';

2735

RIL=RIL.';

2742

end

2736

end

2743

print_for_codereview=1;

2737

print_for_codereview=1;

2744

if exist('OP','var')

2738

if exist('OP','var')

2745

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2739

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2746

2740

2747

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2741

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2748

H_bw=Butterworth_Filter(param,faxis_f2,1);

2742

H_bw=Butterworth_Filter(param,faxis_f2,1);

2749

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2743

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2750

H_tw=Tukey_Window(faxis_f2,param);

2744

H_tw=Tukey_Window(faxis_f2,param);

2751

H_tw=ones(1,length(faxis_f2) );

2745

H_tw=ones(1,length(faxis_f2) );

2752

[RILN_TD_struct.REF.FIR, ...

2746

[RILN_TD_struct.REF.FIR, ...

2753

RILN_TD_struct.REF.t, ...

2747

RILN_TD_struct.REF.t, ...

2754

RILN_TD_struct.REF.causality_correction_dB, ...

2748

RILN_TD_struct.REF.causality_correction_dB, ...

2755

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2749

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2756

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2750

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2757

[RILN_TD_struct.FIT.FIR, ...

2751

[RILN_TD_struct.FIT.FIR, ...

2758

RILN_TD_struct.FIT.t, ...

2752

RILN_TD_struct.FIT.t, ...

2759

RILN_TD_struct.FIT.causality_correction_dB, ...

2753

RILN_TD_struct.FIT.causality_correction_dB, ...

2760

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2754

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2761

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2755

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2762

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2756

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2763

NrangeUI=1000;

2757

NrangeUI=1000;

2764

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2758

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2765

range=ipeak:range_end;

2759

range=ipeak:range_end;

2766

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2760

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2767

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2761

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2768

RILN_TD_struct.FOM=-inf;

2762

RILN_TD_struct.FOM=-inf;

2769

RILN_TD_struct.FOM_PDF=-inf;

2763

RILN_TD_struct.FOM_PDF=-inf;

2770

rms_fom=-inf;

2764

rms_fom=-inf;

2771

for im=1:param.samples_per_ui

2765

for im=1:param.samples_per_ui

2772

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2766

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2773

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2767

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2774

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2768

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2775

cdf=pdf; cdf.y=cumsum(pdf.y);

2769

cdf=pdf; cdf.y=cumsum(pdf.y);

2776

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2770

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2777

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2771

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2778

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2772

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2779

if print_for_codereview % remove once all checked out

2773

if print_for_codereview % remove once all checked out

2780

h=figure(191);set(gcf,'Tag','COM');

2774

h=figure(191);set(gcf,'Tag','COM');

2781

semilogy(-cdf.x,cdf.y);

2775

semilogy(-cdf.x,cdf.y);

2782

% xlim ([0,-cdf.x(1)])

2776

% xlim ([0,-cdf.x(1)])

2783

ylim([param.specBER 1]);title ('CDF of RILN')

2777

ylim([param.specBER 1]);title ('CDF of RILN')

2784

hold on

2778

hold on

2785

end

2779

end

2786

if rms>rms_fom

2780

if rms>rms_fom

2787

rms_fom=rms;

2781

rms_fom=rms;

2788

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2782

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2789

RILN_TD_struct.PDF=pdf;

2783

RILN_TD_struct.PDF=pdf;

2790

end

2784

end

2791

end

2785

end

2792

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2786

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2793

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2787

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2794

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2788

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2795

if print_for_codereview % remove once all checked out

2789

if print_for_codereview % remove once all checked out

2796

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

2790

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

2797

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2791

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2798

hold on

2792

hold on

2799

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2793

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2800

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2794

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2801

hold off

2795

hold off

2802

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)

2796

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)

2803

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

2797

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

2804

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2798

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2805

hold on

2799

hold on

2806

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2800

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2807

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2801

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2808

grid on

2802

grid on

2809

legend('show')

2803

legend('show')

2810

end

2804

end

2811

end

2805

end

2812

function is_illegal=RXFFE_Illegal(C,param,last_index)

2806

function is_illegal=RXFFE_Illegal(C,param,last_index)

2813

2807

2814

%check if RXFFE taps are illegal

2808

%check if RXFFE taps are illegal

2815

%C = RXFFE taps

2809

%C = RXFFE taps

2816

%param = COM param struct

2810

%param = COM param struct

2817

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2811

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2818

% in the Backoff region are not considered in the legality check.

2812

% in the Backoff region are not considered in the legality check.

2819

2813

2820

%If last index is omitted, set it to length(C)

2814

%If last index is omitted, set it to length(C)

2821

if nargin<3

2815

if nargin<3

2822

last_index=length(C);

2816

last_index=length(C);

2823

end

2817

end

2824

2818

2825

is_illegal=0;

2819

is_illegal=0;

2826

2820

2827

%Check cursor tap

2821

%Check cursor tap

2828

Ccur_i=param.RxFFE_cmx+1;

2822

Ccur_i=param.RxFFE_cmx+1;

2829

if C(Ccur_i) < param.ffe_main_cursor_min

2823

if C(Ccur_i) < param.ffe_main_cursor_min

2830

is_illegal=1;

2824

is_illegal=1;

2831

return;

2825

return;

2832

end

2826

end

2833

2827

2834

%Check postcursors

2828

%Check postcursors

2835

if param.ffe_post_tap_len ~=0

2829

if param.ffe_post_tap_len ~=0

2836

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2830

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2837

is_illegal=1;

2831

is_illegal=1;

2838

return;

2832

return;

2839

end

2833

end

2840

if (param.ffe_post_tap_len > 1)

2834

if (param.ffe_post_tap_len > 1)

2841

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2835

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2842

is_illegal=1;

2836

is_illegal=1;

2843

return;

2837

return;

2844

end

2838

end

2845

end

2839

end

2846

end

2840

end

2847

2841

2848

%Check precursors

2842

%Check precursors

2849

if param.ffe_pre_tap_len ~=0

2843

if param.ffe_pre_tap_len ~=0

2850

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2844

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2851

is_illegal=1;

2845

is_illegal=1;

2852

return;

2846

return;

2853

end

2847

end

2854

if (param.ffe_pre_tap_len > 1)

2848

if (param.ffe_pre_tap_len > 1)

2855

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2849

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2856

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2850

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2857

is_illegal=1;

2851

is_illegal=1;

2858

return;

2852

return;

2859

end % 11.22.2018 Yasou Hadaka

2853

end % 11.22.2018 Yasou Hadaka

2860

end

2854

end

2861

end

2855

end

2862

function S =R_series2(zref,f,R)

2856

function S =R_series2(zref,f,R)

2863

r=ones(1,length(f))*R;

2857

r=ones(1,length(f))*R;

2864

S.Parameters(1,1,:) = r./(r + 2*zref);

2858

S.Parameters(1,1,:) = r./(r + 2*zref);

2865

S.Parameters(2,2,:) = r./(r + 2*zref);

2859

S.Parameters(2,2,:) = r./(r + 2*zref);

2866

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2860

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2867

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2861

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2868

% Sm=sparameters(S.Parameters,f,zref);

2862

% Sm=sparameters(S.Parameters,f,zref);

2869

2863

2870

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2864

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2871

2865

2872

if use_RC

2866

if use_RC

2873

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2867

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2874

else

2868

else

2875

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

2869

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

2876

end

2870

end

2877

function SLD=SL(S,f,R)

2871

function SLD=SL(S,f,R)

2878

% source load impact return loss add to S21

2872

% source load impact return loss add to S21

2879

% S and SLD are the same structure

2873

% S and SLD are the same structure

2880

% S.Parameters

2874

% S.Parameters

2881

% S.Impedance

2875

% S.Impedance

2882

% S.NumPorts

2876

% S.NumPorts

2883

% S.Frequencies

2877

% S.Frequencies

2884

SLD=S; % assign the fields

2878

SLD=S; % assign the fields

2885

zref=100;

2879

zref=100;

2886

if R==0

2880

if R==0

2887

warndlg('Termination should not be set to zero');

2881

warndlg('Termination should not be set to zero');

2888

SLD=S;

2882

SLD=S;

2889

return

2883

return

2890

end

2884

end

2891

2885

2892

if R > zref

2886

if R > zref

2893

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2887

spr =R_series2(zref,f,(R-zref)); % make series sparameter

2894

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2888

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

2895

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2889

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2896

combines4p( ...

2890

combines4p( ...

2897

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2891

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2898

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2892

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2899

);

2893

);

2900

elseif R < zref

2894

elseif R < zref

2901

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2895

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

2902

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2896

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

2903

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2897

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

2904

combines4p( ...

2898

combines4p( ...

2905

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2899

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

2906

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2900

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

2907

);

2901

);

2908

else

2902

else

2909

SLD=S;

2903

SLD=S;

2910

end

2904

end

2911

2905

2912

%%

2906

%%

2913

2907

2914

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2908

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

2915

p1=param.CTLE_fp1(1);

2909

p1=param.CTLE_fp1(1);

2916

z1=param.CTLE_fz(1);

2910

z1=param.CTLE_fz(1);

2917

p2=param.CTLE_fp2(1);

2911

p2=param.CTLE_fp2(1);

2918

zlf=param.f_HP(1);

2912

zlf=param.f_HP(1);

2919

plf=param.f_HP(1);

2913

plf=param.f_HP(1);

2920

f_b=param.fb;

2914

f_b=param.fb;

2921

f_r=param.f_r;

2915

f_r=param.f_r;

2922

eta_0=param.eta_0;

2916

eta_0=param.eta_0;

2923

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));

2917

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));

2924

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2918

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

2925

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2919

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

2926

if 0

2920

if 0

2927

figure

2921

figure

2928

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2922

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

2929

% see if it looks correct

2923

% see if it looks correct

2930

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2924

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

2931

ylabel('dB');

2925

ylabel('dB');

2932

xlabel('GHz');

2926

xlabel('GHz');

2933

title( 'H_ctf with H_r')

2927

title( 'H_ctf with H_r')

2934

grid on

2928

grid on

2935

ylim([-30 0])

2929

ylim([-30 0])

2936

end

2930

end

2937

2931

2938

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

2932

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

2939

2933

2940

%Fill TDR data

2934

%Fill TDR data

2941

if package_testcase_i == 1

2935

if package_testcase_i == 1

2942

if OP.TDR

2936

if OP.TDR

2943

output_args.Z11est=chdata(1).TDR11.avgZport;

2937

output_args.Z11est=chdata(1).TDR11.avgZport;

2944

if ~param.FLAG.S2P

2938

if ~param.FLAG.S2P

2945

output_args.Z22est=chdata(1).TDR22.avgZport;

2939

output_args.Z22est=chdata(1).TDR22.avgZport;

2946

else

2940

else

2947

output_args.Z22est=[];

2941

output_args.Z22est=[];

2948

end

2942

end

2949

if OP.AUTO_TFX

2943

if OP.AUTO_TFX

2950

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2944

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

2951

else

2945

else

2952

output_args.tfx_estimate=[];

2946

output_args.tfx_estimate=[];

2953

end

2947

end

2954

else

2948

else

2955

output_args.Z11est=[];

2949

output_args.Z11est=[];

2956

output_args.Z22est=[];

2950

output_args.Z22est=[];

2957

output_args.tfx_estimate=[];

2951

output_args.tfx_estimate=[];

2958

end

2952

end

2959

end

2953

end

2960

2954

2961

% Process ERL

2955

% Process ERL

2962

if package_testcase_i == 1

2956

if package_testcase_i == 1

2963

if OP.ERL

2957

if OP.ERL

2964

output_args.ERL11=chdata(1).TDR11.ERL;

2958

output_args.ERL11=chdata(1).TDR11.ERL;

2965

if ~param.FLAG.S2P

2959

if ~param.FLAG.S2P

2966

output_args.ERL22=chdata(1).TDR22.ERL;

2960

output_args.ERL22=chdata(1).TDR22.ERL;

2967

else

2961

else

2968

output_args.ERL22=[];

2962

output_args.ERL22=[];

2969

end

2963

end

2970

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2964

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

2971

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2965

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

2972

else

2966

else

2973

output_args.ERL11=[];

2967

output_args.ERL11=[];

2974

output_args.ERL22=[];

2968

output_args.ERL22=[];

2975

end

2969

end

2976

end

2970

end

2977

if OP.ERL

2971

if OP.ERL

2978

if OP.TDR_W_TXPKG

2972

if OP.TDR_W_TXPKG

2979

min_ERL=output_args.ERL22;

2973

min_ERL=output_args.ERL22;

2980

ERL= [ nan output_args.ERL22 ];

2974

ERL= [ nan output_args.ERL22 ];

2981

else

2975

else

2982

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2976

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

2983

min_ERL=output_args.ERL11;

2977

min_ERL=output_args.ERL11;

2984

ERL= [ output_args.ERL11 nan ];

2978

ERL= [ output_args.ERL11 nan ];

2985

else

2979

else

2986

min_ERL=min(output_args.ERL11,output_args.ERL22);

2980

min_ERL=min(output_args.ERL11,output_args.ERL22);

2987

ERL= [ output_args.ERL11 output_args.ERL22 ];

2981

ERL= [ output_args.ERL11 output_args.ERL22 ];

2988

end

2982

end

2989

end

2983

end

2990

output_args.ERL=min_ERL;

2984

output_args.ERL=min_ERL;

2991

else

2985

else

2992

min_ERL=[];

2986

min_ERL=[];

2993

ERL= [];

2987

ERL= [];

2994

output_args.ERL=[];

2988

output_args.ERL=[];

2995

end

2989

end

2996

if OP.ERL_ONLY

2990

if OP.ERL_ONLY

2997

if OP.BREAD_CRUMBS

2991

if OP.BREAD_CRUMBS

2998

output_args.OP=OP;

2992

output_args.OP=OP;

2999

output_args.param=param;

2993

output_args.param=param;

3000

output_args.chdata=chdata;

2994

output_args.chdata=chdata;

3001

%This seems to be the intent of setting fom_result.ran=0. Add it

2995

%This seems to be the intent of setting fom_result.ran=0. Add it

3002

%to output_args so there is a fom_result field.

2996

%to output_args so there is a fom_result field.

3003

fom_result.ran=0;

2997

fom_result.ran=0;

3004

output_args.fom_result=fom_result;

2998

output_args.fom_result=fom_result;

3005

end

2999

end

3006

output_args.Z_t=param.Z_t;

3000

output_args.Z_t=param.Z_t;

3007

fileset_str=str2csv({chdata(1).base});

3001

fileset_str=str2csv({chdata(1).base});

3008

output_args.file_names=sprintf('"%s"', fileset_str);

3002

output_args.file_names=sprintf('"%s"', fileset_str);

3009

if OP.DISPLAY_WINDOW

3003

if OP.DISPLAY_WINDOW

3010

savefigs(param, OP);

3004

savefigs(param, OP);

3011

end

3005

end

3012

end

3006

end

3013

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3007

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3014

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3008

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3015

p1_ctle = -2*pi*f_p1;

3009

p1_ctle = -2*pi*f_p1;

3016

p2_ctle = -2*pi*f_p2;

3010

p2_ctle = -2*pi*f_p2;

3017

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3011

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3018

k_ctle = -p2_ctle;

3012

k_ctle = -p2_ctle;

3019

bilinear_fs = 2*fb*oversampling;

3013

bilinear_fs = 2*fb*oversampling;

3020

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3014

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3021

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3015

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3022

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3016

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3023

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3017

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3024

% allow for different pole zeros RIM 9-29-2015

3018

% allow for different pole zeros RIM 9-29-2015

3025

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3019

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3026

B_filt =k_ctle*kd*poly([zd, -1]);

3020

B_filt =k_ctle*kd*poly([zd, -1]);

3027

A_filt=poly([p1d, p2d]);

3021

A_filt=poly([p1d, p2d]);

3028

impulse_response=filter(B_filt,A_filt,ir_in);

3022

impulse_response=filter(B_filt,A_filt,ir_in);

3029

3023

3030

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3024

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3031

Over_sample=2;

3025

Over_sample=2;

3032

num_files=length(chdata);

3026

num_files=length(chdata);

3033

for i=1:num_files

3027

for i=1:num_files

3034

V=chdata(i).uneq_pulse_response;

3028

V=chdata(i).uneq_pulse_response;

3035

T=chdata(i).t;

3029

T=chdata(i).t;

3036

dt=T(2)-T(1);

3030

dt=T(2)-T(1);

3037

f=0:1/max(T):1/dt;

3031

f=0:1/max(T):1/dt;

3038

chdata(i).faxis=f;

3032

chdata(i).faxis=f;

3039

f75=find(f >= param.fb*.75,1,'first');

3033

f75=find(f >= param.fb*.75,1,'first');

3040

fnq=find(f >= param.fb*.5,1,'first');

3034

fnq=find(f >= param.fb*.5,1,'first');

3041

chdata(i).fmaxi = length(f);

3035

chdata(i).fmaxi = length(f);

3042

chdata(i).faxis = f;

3036

chdata(i).faxis = f;

3043

UI=param.ui; % unit interval

3037

UI=param.ui; % unit interval

3044

M=param.samples_per_ui; % sample per UI

3038

M=param.samples_per_ui; % sample per UI

3045

N_v=param.N_v; % number of UI for Vf determination

3039

N_v=param.N_v; % number of UI for Vf determination

3046

3040

3047

% filters

3041

% filters

3048

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

3042

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

3049

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

3043

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

3050

H_ftr=H_bw.*H_bt;

3044

H_ftr=H_bw.*H_bt;

3051

H_ftr=H_ftr(:);

3045

H_ftr=H_ftr(:);

3052

% fd of PR

3046

% fd of PR

3053

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3047

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3054

prr = prr(:);

3048

prr = prr(:);

3055

if f(1)==0, prr(1)=1; end %remove NaN

3049

if f(1)==0, prr(1)=1; end %remove NaN

3056

fd=fft(V);

3050

fd=fft(V);

3057

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3051

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3058

3052

3059

%% get Vf

3053

%% get Vf

3060

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3054

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3061

step_response=filter(V,1, shifting_vector);

3055

step_response=filter(V,1, shifting_vector);

3062

Vf=step_response(end);

3056

Vf=step_response(end);

3063

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3057

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3064

%%

3058

%%

3065

% 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

3059

% 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

3066

% figure

3060

% figure

3067

% plot(f(1:f75),ILest)

3061

% plot(f(1:f75),ILest)

3068

3062

3069

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

3063

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

3070

% set same variables as get_s4p_files

3064

% set same variables as get_s4p_files

3071

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3065

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3072

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3066

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3073

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3067

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3074

zero_vector=zeros(length(IL_conv),1);

3068

zero_vector=zeros(length(IL_conv),1);

3075

for j=1:length(IL_fields)

3069

for j=1:length(IL_fields)

3076

chdata(i).(IL_fields{j})=IL_conv;

3070

chdata(i).(IL_fields{j})=IL_conv;

3077

end

3071

end

3078

for j=1:length(Zero_fields)

3072

for j=1:length(Zero_fields)

3079

chdata(i).(Zero_fields{j})=zero_vector;

3073

chdata(i).(Zero_fields{j})=zero_vector;

3080

end

3074

end

3081

3075

3082

if i==1

3076

if i==1

3083

SDDch(:,1,2)=chdata.sdd12_raw;

3077

SDDch(:,1,2)=chdata.sdd12_raw;

3084

SDDch(:,2,1)=chdata.sdd21_raw;

3078

SDDch(:,2,1)=chdata.sdd21_raw;

3085

SDDch(:,1,1)=chdata.sdd11_raw;

3079

SDDch(:,1,1)=chdata.sdd11_raw;

3086

SDDch(:,2,2)=chdata.sdd22_raw;

3080

SDDch(:,2,2)=chdata.sdd22_raw;

3087

SDDp2p= zeros(length(IL_conv),1);

3081

SDDp2p= zeros(length(IL_conv),1);

3088

end

3082

end

3089

chdata(i).TX_RL=[];

3083

chdata(i).TX_RL=[];

3090

chdata(i).TDR11=[];

3084

chdata(i).TDR11=[];

3091

chdata(i).PDTR11=[];

3085

chdata(i).PDTR11=[];

3092

chdata(i).TDR22=[];

3086

chdata(i).TDR22=[];

3093

chdata(i).PDTR22=[];

3087

chdata(i).PDTR22=[];

3094

end

3088

end

3095

3089

3096

3090

3097

function H_tw=Tukey_Window(f,param,fr,fb)

3091

function H_tw=Tukey_Window(f,param,fr,fb)

3098

% RIM 05/26/2022 added optional fr and fb

3092

% RIM 05/26/2022 added optional fr and fb

3099

% fr is the start of the raised cosine window

3093

% fr is the start of the raised cosine window

3100

% fb is the end of the raised cosine window

3094

% fb is the end of the raised cosine window

3101

if ~exist('fr','var') && ~exist('fb','var')

3095

if ~exist('fr','var') && ~exist('fb','var')

3102

fb=param.fb;

3096

fb=param.fb;

3103

fr=param.f_r*param.fb;

3097

fr=param.f_r*param.fb;

3104

end

3098

end

3105

fperiod=2*(fb-fr);

3099

fperiod=2*(fb-fr);

3106

H_tw = [ ones(1,length(f(f<fr))) ...

3100

H_tw = [ ones(1,length(f(f<fr))) ...

3107

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3101

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3108

zeros(1,length(f(f>fb)) )];

3102

zeros(1,length(f(f>fb)) )];

3109

H_tw=H_tw(1:length(f));

3103

H_tw=H_tw(1:length(f));

3110

if 0

3104

if 0

3111

plot(f/1e9,H_tw)

3105

plot(f/1e9,H_tw)

3112

end

3106

end

3113

3107

3114

3108

3115

3109

3116

%% moved output control to functions

3110

%% moved output control to functions

3117

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3111

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3118

% Author: Richard Mellitz

3112

% Author: Richard Mellitz

3119

% Date: 7/29/2022

3113

% Date: 7/29/2022

3120

% generate FD tx ffe system function

3114

% generate FD tx ffe system function

3121

% varagins...

3115

% varagins...

3122

% param - stucture

3116

% param - stucture

3123

% param.fb baud rate

3117

% param.fb baud rate

3124

% param.Tx_FFE Tx FFE coef

3118

% param.Tx_FFE Tx FFE coef

3125

% f - freq array

3119

% f - freq array

3126

% Use_Tx_FFE = flag to use or not

3120

% Use_Tx_FFE = flag to use or not

3127

% H_TxFFE is system function for Tx_FFE

3121

% H_TxFFE is system function for Tx_FFE

3128

db = @(x) 20*log10(abs(x));

3122

db = @(x) 20*log10(abs(x));

3129

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

3123

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

3130

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

3124

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

3131

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

3125

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

3132

if isempty(Use_Tx_FFE)

3126

if isempty(Use_Tx_FFE)

3133

Use_Tx_FFE=0;

3127

Use_Tx_FFE=0;

3134

end

3128

end

3135

if isempty(param)

3129

if isempty(param)

3136

param.fb=106.25e9;

3130

param.fb=106.25e9;

3137

Tx_FFE=[1 ];

3131

Tx_FFE=[1 ];

3138

else

3132

else

3139

if ~isfield(param, 'Pkg_TXFFE_preset')

3133

if ~isfield(param, 'Pkg_TXFFE_preset')

3140

Tx_FFE=[ 1 ];

3134

Tx_FFE=[ 1 ];

3141

else

3135

else

3142

Tx_FFE=param.Pkg_TXFFE_preset;

3136

Tx_FFE=param.Pkg_TXFFE_preset;

3143

end

3137

end

3144

end

3138

end

3145

if isempty(f)

3139

if isempty(f)

3146

f=0:10e6:param.fb;

3140

f=0:10e6:param.fb;

3147

end

3141

end

3148

3142

3149

3143

3150

if Use_Tx_FFE ~=0

3144

if Use_Tx_FFE ~=0

3151

[mcur,icur] = max(Tx_FFE);

3145

[mcur,icur] = max(Tx_FFE);

3152

H_TxFFE=zeros(1,length(f));

3146

H_TxFFE=zeros(1,length(f));

3153

for ii=1:length(Tx_FFE)

3147

for ii=1:length(Tx_FFE)

3154

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3148

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3155

end

3149

end

3156

else

3150

else

3157

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

3151

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

3158

end

3152

end

3159

% figure (1102320)

3153

% figure (1102320)

3160

% plot(f/1e9,db(H_TxFFE))

3154

% plot(f/1e9,db(H_TxFFE))

3161

% hold on

3155

% hold on

3162

function Write_CSV(output_args,csv_file)

3156

function Write_CSV(output_args,csv_file)

3163

3157

3164

items = fieldnames(output_args);

3158

items = fieldnames(output_args);

3165

item_value_strings = cell(size(items));

3159

item_value_strings = cell(size(items));

3166

for field_id=1:length(items)

3160

for field_id=1:length(items)

3167

field_name=items{field_id};

3161

field_name=items{field_id};

3168

field_value=output_args.(field_name);

3162

field_value=output_args.(field_name);

3169

if isstruct(output_args.(field_name))

3163

if isstruct(output_args.(field_name))

3170

field_value='struct';

3164

field_value='struct';

3171

end

3165

end

3172

if ischar(field_value)

3166

if ischar(field_value)

3173

item_value_strings{field_id}=field_value;

3167

item_value_strings{field_id}=field_value;

3174

elseif isempty(field_value)

3168

elseif isempty(field_value)

3175

item_value_strings{field_id}='';

3169

item_value_strings{field_id}='';

3176

elseif numel(field_value)==1

3170

elseif numel(field_value)==1

3177

item_value_strings{field_id}=num2str(field_value);

3171

item_value_strings{field_id}=num2str(field_value);

3178

else

3172

else

3179

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3173

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3180

end

3174

end

3181

end

3175

end

3182

3176

3183

header_string = str2csv(items);

3177

header_string = str2csv(items);

3184

data_string = str2csv(item_value_strings);

3178

data_string = str2csv(item_value_strings);

3185

fid = fopen(csv_file,'w');

3179

fid = fopen(csv_file,'w');

3186

fprintf(fid,'%s\n', header_string);

3180

fprintf(fid,'%s\n', header_string);

3187

fprintf(fid,'%s\n', data_string);

3181

fprintf(fid,'%s\n', data_string);

3188

fclose(fid);

3182

fclose(fid);

3189

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3183

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3190

%% Used in Clause 92 for adding board trace between TP0 and TP2

3184

%% Used in Clause 92 for adding board trace between TP0 and TP2

3191

3185

3192

switch chdata.type

3186

switch chdata.type

3193

case 'THRU'

3187

case 'THRU'

3194

z_bp_tx = param.z_bp_tx;

3188

z_bp_tx = param.z_bp_tx;

3195

z_bp_rx = param.z_bp_rx;

3189

z_bp_rx = param.z_bp_rx;

3196

case 'NEXT'

3190

case 'NEXT'

3197

z_bp_tx = param.z_bp_rx;

3191

z_bp_tx = param.z_bp_rx;

3198

z_bp_rx = param.z_bp_next;

3192

z_bp_rx = param.z_bp_next;

3199

case 'FEXT'

3193

case 'FEXT'

3200

z_bp_tx = param.z_bp_fext;

3194

z_bp_tx = param.z_bp_fext;

3201

z_bp_rx = param.z_bp_rx;

3195

z_bp_rx = param.z_bp_rx;

3202

end

3196

end

3203

% Same cap on each tx and rx three is a data stratue for bifrucation but

3197

% Same cap on each tx and rx three is a data stratue for bifrucation but

3204

% logic no implemented here RIM 06/28/2019

3198

% logic no implemented here RIM 06/28/2019

3205

zref=param.Z0;

3199

zref=param.Z0;

3206

c1=param.C_0;

3200

c1=param.C_0;

3207

c2=param.C_1;

3201

c2=param.C_1;

3208

f=chdata.faxis;

3202

f=chdata.faxis;

3209

f(f<eps)=eps;

3203

f(f<eps)=eps;

3210

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3204

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3211

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3205

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3212

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3206

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3213

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3207

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3214

[ 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);

3208

[ 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);

3215

% add Tx caps

3209

% add Tx caps

3216

[s11tx, s12tx, s21tx, s22tx ]= ...

3210

[s11tx, s12tx, s21tx, s22tx ]= ...

3217

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3211

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3218

[s11tx, s12tx, s21tx, s22tx ]= ...

3212

[s11tx, s12tx, s21tx, s22tx ]= ...

3219

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3213

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3220

3214

3221

3215

3222

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3216

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3223

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3217

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3224

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3218

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3225

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3219

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3226

[ 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);

3220

[ 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);

3227

% add Rx caps

3221

% add Rx caps

3228

[s11rx, s12rx, s21rx, s22rx ]= ...

3222

[s11rx, s12rx, s21rx, s22rx ]= ...

3229

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3223

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3230

[s11rx, s12rx, s21rx, s22rx ]= ...

3224

[s11rx, s12rx, s21rx, s22rx ]= ...

3231

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3225

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3232

3226

3233

3227

3234

switch OP.include_pcb

3228

switch OP.include_pcb

3235

case 1

3229

case 1

3236

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3230

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3237

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3231

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3238

case 2

3232

case 2

3239

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3233

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3240

end

3234

end

3241

3235

3242

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3236

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3243

% Used in Clause 92 for adding board trace between TP0 and TP2

3237

% Used in Clause 92 for adding board trace between TP0 and TP2

3244

switch chdata.type

3238

switch chdata.type

3245

case 'THRU'

3239

case 'THRU'

3246

z_bp_tx = param.z_bp_tx;

3240

z_bp_tx = param.z_bp_tx;

3247

case 'NEXT'

3241

case 'NEXT'

3248

z_bp_tx = param.z_bp_next;

3242

z_bp_tx = param.z_bp_next;

3249

case 'FEXT'

3243

case 'FEXT'

3250

z_bp_tx = param.z_bp_fext;

3244

z_bp_tx = param.z_bp_fext;

3251

end

3245

end

3252

3246

3253

[ 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);

3247

[ 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);

3254

[ 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);

3248

[ 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);

3255

3249

3256

switch OP.include_pcb

3250

switch OP.include_pcb

3257

case 1

3251

case 1

3258

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3252

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3259

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3253

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3260

case 2

3254

case 2

3261

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3255

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3262

end

3256

end

3263

3257

3264

function [chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP)

3258

function [chdata,NS,combined_interference_and_noise_pdf] = adjust_Rx_noise_for_quantization(combined_interference_and_noise_pdf,NS, chdata,fom_result,param,OP)

3265

% expected input

3259

% expected input

3266

% chdata(1).eq_pulse_response --- includes packages, Hf, and Hr, Ht, and Hffe(from tx)

3260

% chdata(1).eq_pulse_response --- includes packages, Hf, and Hr, Ht, and Hffe(from tx)

3267

% align the first sample point to to ts in chdata(1).eq_pulse_response

3261

% align the first sample point to to ts in chdata(1).eq_pulse_response

3268

% align to termiolgy used in MMSE and optimize_FOM

3262

% align to termiolgy used in MMSE and optimize_FOM

3269

3263

3270

%

3264

%

3271

sig_after_ctle_pdf = get_pdf_from_sampled_signal(chdata(1).pulse_sampled_w_tx_ffe_ctle, param.levels, param.delta_y);

3265

sig_after_ctle_pdf = get_pdf_from_sampled_signal(chdata(1).pulse_sampled_w_tx_ffe_ctle, param.levels, param.delta_y);

3272

sig_after_ctle_pdf = conv_fct(sig_after_ctle_pdf, combined_interference_and_noise_pdf);

3273

sig_after_ctle_cdf = cumsum(sig_after_ctle_pdf.y);

3266

sig_after_ctle_cdf = cumsum(sig_after_ctle_pdf.y);

3274

adc_clip = -CDF_inv_ev(2*param.specBER, sig_after_ctle_pdf, sig_after_ctle_cdf);

3267

adc_clip = -CDF_inv_ev(2*param.specBER, sig_after_ctle_pdf, sig_after_ctle_cdf);

3275

ctle_pulse_sigma = sqrt(sum((sig_after_ctle_pdf.x.^2).*sig_after_ctle_pdf.y));

3268

ctle_pulse_sigma = sqrt(sum((sig_after_ctle_pdf.x.^2).*sig_after_ctle_pdf.y));

3276

adc_lsb = 2*adc_clip/(2^param.ENOB-1);

3269

adc_lsb = 2*adc_clip/(2^param.ENOB-1);

3277

NS.sigma_Q = adc_lsb/sqrt(12);

3270

NS.signa_Q = adc_lsb/sqrt(12);

3278

NS.sigma_before_clip = ctle_pulse_sigma;

3271

NS.signa_before_clip = ctle_pulse_sigma;

3279

NS.peak_clip = adc_clip;

3272

NS.peak_clip = adc_clip;

3280

NS.p2ptosigma_clip = 2*adc_clip/ctle_pulse_sigma;

3273

NS.p2ptosigna_clip = 2*adc_clip/ctle_pulse_sigma;

3281

quantizaiton_noise_pdf = combined_interference_and_noise_pdf; % This is to copy the fields of the structure

3274

quantizaion_noise_pdf = combined_interference_and_noise_pdf; % This is to copy the fields of the structure

3282

[~,adc_ind_right] = min(abs(quantizaiton_noise_pdf.x-adc_lsb/2));

3275

[~,adc_ind_right] = min(abs(quantizaion_noise_pdf.x-adc_lsb/2));

3283

[~,adc_ind_left] = min(abs(quantizaiton_noise_pdf.x+adc_lsb/2));

3276

[~,adc_ind_left] = min(abs(quantizaion_noise_pdf.x+adc_lsb/2));

3284

% adc_ind_right= find ( min(abs(quantizaiton_noise_pdf.x-adc_lsb/2)) == abs(quantizaiton_noise_pdf.x-adc_lsb/2) );

3285

% adc_ind_left= find ( min(abs(quantizaiton_noise_pdf.x+adc_lsb/2)) == abs(quantizaiton_noise_pdf.x+adc_lsb/2) );

3286

quantizaiton_noise_pdf.y = zeros(size(quantizaiton_noise_pdf.x));

3277

quantizaion_noise_pdf.y = zeros(size(quantizaion_noise_pdf.x));

3287

quantizaiton_noise_pdf.y(adc_ind_left:adc_ind_right) = 1/(adc_ind_right-adc_ind_left+1);

3278

quantizaion_noise_pdf.y(adc_ind_left:adc_ind_right) = 1/(adc_ind_right-adc_ind_left+1);

3288

% Calculate quantization noise PDF after RxFFE

3279

% Calculate quantization noise PDF after RxFFE

3289

h_rxffe = fom_result.RxFFE(find(fom_result.RxFFE ~= 0));

3280

h_rxffe = fom_result.RxFFE(find(fom_result.RxFFE ~= 0));

3290

for irxffe = 1:length(h_rxffe)

3281

for irxffe = 1:length(h_rxffe)

3291

if irxffe ~= param.ffe_pre_tap_len

3282

if irxffe ~= param.ffe_pre_tap_len

3292

quantizaiton_noise_pdf_scale = scalePDF(quantizaiton_noise_pdf, abs(h_rxffe(irxffe)));

3283

quantizaion_noise_pdf_scale = scalePDF(quantizaion_noise_pdf, abs(h_rxffe(irxffe)));

3293

quantizaiton_noise_pdf = conv_fct(quantizaiton_noise_pdf, quantizaiton_noise_pdf_scale);

3284

quantizaion_noise_pdf = conv_fct(quantizaion_noise_pdf, quantizaion_noise_pdf_scale);

3294

end

3285

end

3295

end

3286

end

3296

combined_interference_and_noise_pdf = conv_fct(combined_interference_and_noise_pdf, quantizaiton_noise_pdf);

3287

combined_interference_and_noise_pdf = conv_fct(combined_interference_and_noise_pdf, quantizaion_noise_pdf);

3297

NS.quantizaiton_noise_pdf = quantizaiton_noise_pdf ;

3288

NS.guantizaion_noise_pdf = quantizaion_noise_pdf ;

3298

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3289

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3299

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3290

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3300

% applying a bank of DFE at desired location

3291

% applying a bank of DFE at desired location

3301

% hisi: waveform with cursor values;

3292

% hisi: waveform with cursor values;

3302

% idx: starting index of the bank;

3293

% idx: starting index of the bank;

3303

% tap_bk: number of taps in bank;

3294

% tap_bk: number of taps in bank;

3304

% bmaxg: maxmum coefficient in bank;

3295

% bmaxg: maxmum coefficient in bank;

3305

3296

3306

if nargin<6

3297

if nargin<6

3307

dfe_delta=0;

3298

dfe_delta=0;

3308

end

3299

end

3309

3300

3310

rng=idx:idx+tap_bk-1;

3301

rng=idx:idx+tap_bk-1;

3311

flt_curval=hisi(rng);

3302

flt_curval=hisi(rng);

3312

3303

3313

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3304

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3314

3305

3315

if dfe_delta~=0

3306

if dfe_delta~=0

3316

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3307

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3317

dfe_delta.*sign(flt_curval)*curval;

3308

dfe_delta.*sign(flt_curval)*curval;

3318

else

3309

else

3319

flt_curval_q=hisi(rng);

3310

flt_curval_q=hisi(rng);

3320

end

3311

end

3321

3312

3322

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3313

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3323

hisi(rng)= hisi(rng) - curval*tap_coef;

3314

hisi(rng)= hisi(rng) - curval*tap_coef;

3324

hisi_ref(rng)=0;

3315

hisi_ref(rng)=0;

3325

3316

3326

%AJG021820

3317

%AJG021820

3327

function [ a] = bessel( n )

3318

function [ a] = bessel( n )

3328

% bessel polynomial

3319

% bessel polynomial

3329

for ii= 0:n

3320

for ii= 0:n

3330

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3321

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3331

end

3322

end

3332

3323

3333

3324

3334

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3325

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3335

% History:

3326

% History:

3336

% 1. 14th October, 2021 (Intial release)

3327

% 1. 14th October, 2021 (Intial release)

3337

3328

3338

% Definition:

3329

% Definition:

3339

% This function captures the channel delay through the time domain using causality enforcement.

3330

% This function captures the channel delay through the time domain using causality enforcement.

3340

% Following are the steps being followed.

3331

% Following are the steps being followed.

3341

% Step 1. Cascade negative frequencies

3332

% Step 1. Cascade negative frequencies

3342

% Step 2. Extract magnitude

3333

% Step 2. Extract magnitude

3343

% Step 3. IFFT of the magnitude

3334

% Step 3. IFFT of the magnitude

3344

% Step 4. Multiply by the sign(t)

3335

% Step 4. Multiply by the sign(t)

3345

% Step 5. Calculate the phase of the 1j*causal_phase

3336

% Step 5. Calculate the phase of the 1j*causal_phase

3346

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3337

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3347

% Step 7. f-domain to t-domain pulse response

3338

% Step 7. f-domain to t-domain pulse response

3348

% Step 8. Calculate the delay

3339

% Step 8. Calculate the delay

3349

3340

3350

% Author:

3341

% Author:

3351

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3342

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3352

3343

3353

% Reference:

3344

% Reference:

3354

% 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.

3345

% 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.

3355

3346

3356

% Input:

3347

% Input:

3357

% freq %frequency in hertz (odd number points)

3348

% freq %frequency in hertz (odd number points)

3358

% sdd21 %insertion loss in complex (odd number points)

3349

% sdd21 %insertion loss in complex (odd number points)

3359

% param %COM native structure passed

3350

% param %COM native structure passed

3360

% OP %COM native structure passed

3351

% OP %COM native structure passed

3361

3352

3362

% Output:

3353

% Output:

3363

% delay_sec %channel delay in seconds

3354

% delay_sec %channel delay in seconds

3364

% delay_idx %channel delay index

3355

% delay_idx %channel delay index

3365

3356

3366

if iscolumn(sdd21)

3357

if iscolumn(sdd21)

3367

sdd21= sdd21.';

3358

sdd21= sdd21.';

3368

end

3359

end

3369

if iscolumn(freq)

3360

if iscolumn(freq)

3370

freq= freq.';

3361

freq= freq.';

3371

end

3362

end

3372

3363

3373

%---start. Step 1. Cascade negative frequencies

3364

%---start. Step 1. Cascade negative frequencies

3374

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3365

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3375

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3366

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3376

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3367

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3377

%---end. Step 1. Cascade negative frequencies

3368

%---end. Step 1. Cascade negative frequencies

3378

3369

3379

%---start. Step 2. Extract magnitude

3370

%---start. Step 2. Extract magnitude

3380

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3371

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3381

%---end. Step 2. Extract magnitude

3372

%---end. Step 2. Extract magnitude

3382

3373

3383

%---start. Step 3. IFFT of the magnitude

3374

%---start. Step 3. IFFT of the magnitude

3384

sdd21_mag_time = ifft(sdd21_mag_conj);

3375

sdd21_mag_time = ifft(sdd21_mag_conj);

3385

%---end. Step 3. IFFT of the magnitude

3376

%---end. Step 3. IFFT of the magnitude

3386

3377

3387

%---start. Step 4. Multiply by the sign(t)

3378

%---start. Step 4. Multiply by the sign(t)

3388

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3379

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3389

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3380

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3390

%---end. Step 4. Multiply by the sign(t)

3381

%---end. Step 4. Multiply by the sign(t)

3391

3382

3392

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3383

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3393

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3384

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3394

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3385

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3395

3386

3396

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3387

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3397

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3388

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3398

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3389

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3399

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3390

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3400

3391

3401

%---start. Step 7. f-domain to t-domain pulse response

3392

%---start. Step 7. f-domain to t-domain pulse response

3402

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3393

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3403

%--------- Extrapolation has been already done by the COM tool

3394

%--------- Extrapolation has been already done by the COM tool

3404

freq_array= freq;

3395

freq_array= freq;

3405

time_step= param.sample_dt;

3396

time_step= param.sample_dt;

3406

fmax=1/time_step/2;

3397

fmax=1/time_step/2;

3407

freq_step=(freq_array(3)-freq_array(2))/1;

3398

freq_step=(freq_array(3)-freq_array(2))/1;

3408

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3399

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3409

3400

3410

ILin=sdd21;

3401

ILin=sdd21;

3411

IL=interp_Sparam(ILin,freq_array,fout, ...

3402

IL=interp_Sparam(ILin,freq_array,fout, ...

3412

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3403

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3413

IL_nan = find(isnan(IL));

3404

IL_nan = find(isnan(IL));

3414

for in=IL_nan

3405

for in=IL_nan

3415

IL(in)=IL(in-1);

3406

IL(in)=IL(in-1);

3416

end

3407

end

3417

IL = IL(:);

3408

IL = IL(:);

3418

% add padding for time steps

3409

% add padding for time steps

3419

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3410

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3420

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3411

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3421

clear IL IL_nan IL_symmetric

3412

clear IL IL_nan IL_symmetric

3422

3413

3423

ILin=sdd21_causality_enforced;

3414

ILin=sdd21_causality_enforced;

3424

IL=interp_Sparam(ILin,freq_array,fout, ...

3415

IL=interp_Sparam(ILin,freq_array,fout, ...

3425

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3416

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3426

IL_nan = find(isnan(IL));

3417

IL_nan = find(isnan(IL));

3427

for in=IL_nan

3418

for in=IL_nan

3428

IL(in)=IL(in-1);

3419

IL(in)=IL(in-1);

3429

end

3420

end

3430

IL = IL(:);

3421

IL = IL(:);

3431

% add padding for time steps

3422

% add padding for time steps

3432

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3423

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3433

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3424

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3434

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3425

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3435

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3426

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3436

clear IL IL_nan IL_symmetric

3427

clear IL IL_nan IL_symmetric

3437

3428

3438

clear time_step fmax freq_step freq_array

3429

clear time_step fmax freq_step freq_array

3439

3430

3440

freq_step=(fout(3)-fout(2))/1;

3431

freq_step=(fout(3)-fout(2))/1;

3441

L= length(sdd21_PR);

3432

L= length(sdd21_PR);

3442

t_base = (0:L-1)/(freq_step*L);

3433

t_base = (0:L-1)/(freq_step*L);

3443

clear fout freq_step L

3434

clear fout freq_step L

3444

%---end. Step 7. f-domain to t-domain pulse response

3435

%---end. Step 7. f-domain to t-domain pulse response

3445

3436

3446

%---start. Step 8. Calculate the delay

3437

%---start. Step 8. Calculate the delay

3447

%------start. Remove the last 5% of the waveform for noise due to IFFT

3438

%------start. Remove the last 5% of the waveform for noise due to IFFT

3448

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3439

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3449

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3440

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3450

%------end. Remove the last 5% of the waveform for noise due to IFFT

3441

%------end. Remove the last 5% of the waveform for noise due to IFFT

3451

3442

3452

%---start. calculate the difference in index between the peaks

3443

%---start. calculate the difference in index between the peaks

3453

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3444

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3454

[~, peak_y_idx] = max(sdd21_PR_reduced);

3445

[~, peak_y_idx] = max(sdd21_PR_reduced);

3455

peak_idx_difference = peak_x_idx - peak_y_idx;

3446

peak_idx_difference = peak_x_idx - peak_y_idx;

3456

%---end. calculate the difference in index between the peaks

3447

%---end. calculate the difference in index between the peaks

3457

3448

3458

if peak_idx_difference~=0

3449

if peak_idx_difference~=0

3459

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

3450

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

3460

error_value = length(sdd21_causality_enforced_PR_reduced);

3451

error_value = length(sdd21_causality_enforced_PR_reduced);

3461

error_idx = 0;

3452

error_idx = 0;

3462

% i= 1;

3453

% i= 1;

3463

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3454

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3464

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3455

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3465

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3456

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3466

if (error_value > current_error)

3457

if (error_value > current_error)

3467

error_idx = shift_value;

3458

error_idx = shift_value;

3468

error_value = current_error;

3459

error_value = current_error;

3469

end

3460

end

3470

% error_idx_H(i)= error_idx;

3461

% error_idx_H(i)= error_idx;

3471

% i= i+ 1;

3462

% i= i+ 1;

3472

end

3463

end

3473

%plot(error_idx_H);

3464

%plot(error_idx_H);

3474

3465

3475

if error_idx==0

3466

if error_idx==0

3476

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3467

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3477

end

3468

end

3478

3469

3479

delay_idx = error_idx;

3470

delay_idx = error_idx;

3480

else

3471

else

3481

delay_idx= 1;

3472

delay_idx= 1;

3482

end

3473

end

3483

3474

3484

delay_sec= t_base(abs(delay_idx));

3475

delay_sec= t_base(abs(delay_idx));

3485

3476

3486

3477

3487

function [return_struct]= capture_RIL_RILN(chdata)

3478

function [return_struct]= capture_RIL_RILN(chdata)

3488

% History:

3479

% History:

3489

% 1. 12th April, 2019 (Intial release)

3480

% 1. 12th April, 2019 (Intial release)

3490

%

3481

%

3491

% 2. 11th October, 2021

3482

% 2. 11th October, 2021

3492

% - Details:

3483

% - Details:

3493

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3484

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3494

% 2] Revised the selection criteria for the solution of the quadratic

3485

% 2] Revised the selection criteria for the solution of the quadratic

3495

% equation in finding the reflection coefficient (rho).

3486

% equation in finding the reflection coefficient (rho).

3496

% - Impact:

3487

% - Impact:

3497

% => Zero impact in |RIL|, while impact on angle(RIL).

3488

% => Zero impact in |RIL|, while impact on angle(RIL).

3498

% - Previous:

3489

% - Previous:

3499

% %---start. For passive networks the reflection coefficient should be less than one

3490

% %---start. For passive networks the reflection coefficient should be less than one

3500

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3491

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3501

% rho_port2= solution_1;

3492

% rho_port2= solution_1;

3502

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3493

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3503

% rho_port2= solution_2;

3494

% rho_port2= solution_2;

3504

% else

3495

% else

3505

% rho_port2= solution_1;

3496

% rho_port2= solution_1;

3506

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3497

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3507

% end

3498

% end

3508

% %---end. For passive networks the reflection coefficient should be less than one

3499

% %---end. For passive networks the reflection coefficient should be less than one

3509

%

3500

%

3510

% 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) ) );

3501

% 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) ) );

3511

% - Change:

3502

% - Change:

3512

% %---start. Given the real part of the impedance is to be positive

3503

% %---start. Given the real part of the impedance is to be positive

3513

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3504

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3514

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3505

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3515

%

3506

%

3516

% rho_port2= zeros(length(solution_1), 1);

3507

% rho_port2= zeros(length(solution_1), 1);

3517

% for solution_idx= 1:length(solution_1)

3508

% for solution_idx= 1:length(solution_1)

3518

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3509

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3519

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3510

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3520

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3511

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3521

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3512

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3522

% else

3513

% else

3523

% error('An odd case has occured. Please contact the tool developer.');

3514

% error('An odd case has occured. Please contact the tool developer.');

3524

% end

3515

% end

3525

% end

3516

% end

3526

% %---end. Given the real part of the impedance is to be positive

3517

% %---end. Given the real part of the impedance is to be positive

3527

% 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) ) );

3518

% 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) ) );

3528

3519

3529

% Definition:

3520

% Definition:

3530

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3521

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3531

3522

3532

% Author:

3523

% Author:

3533

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3524

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3534

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3525

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3535

3526

3536

% 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.

3527

% 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.

3537

3528

3538

% Reference:

3529

% Reference:

3539

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3530

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3540

% 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.

3531

% 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.

3541

3532

3542

% Input:

3533

% Input:

3543

% 1] SCH: S-matrix structure

3534

% 1] SCH: S-matrix structure

3544

% SCH.Frequencies= faxis;

3535

% SCH.Frequencies= faxis;

3545

% SCH.Parameters(1,1,:)= sdd11;

3536

% SCH.Parameters(1,1,:)= sdd11;

3546

% SCH.Parameters(2,2,:)= sdd22;

3537

% SCH.Parameters(2,2,:)= sdd22;

3547

% SCH.Parameters(1,2,:)= sdd12;

3538

% SCH.Parameters(1,2,:)= sdd12;

3548

% SCH.Parameters(2,1,:)= sdd21;

3539

% SCH.Parameters(2,1,:)= sdd21;

3549

% SCH.NumPorts= 2;

3540

% SCH.NumPorts= 2;

3550

% SCH.Impedance= 100;

3541

% SCH.Impedance= 100;

3551

3542

3552

% Output: Struct returned has the following,

3543

% Output: Struct returned has the following,

3553

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3544

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3554

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3545

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3555

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3546

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3556

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3547

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3557

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3548

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3558

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3549

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3559

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3550

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3560

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3551

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3561

% return_struct.freq %Frequency axis

3552

% return_struct.freq %Frequency axis

3562

3553

3563

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3554

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3564

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3555

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3565

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3556

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3566

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3557

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3567

SCH.Frequencies=chdata(1).faxis;

3558

SCH.Frequencies=chdata(1).faxis;

3568

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3559

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3569

SCH.NumPorts= 2;

3560

SCH.NumPorts= 2;

3570

3561

3571

%---start. allowed is only a 2-port network having a transmitter and receiver

3562

%---start. allowed is only a 2-port network having a transmitter and receiver

3572

if size(SCH.Parameters, 1)~=2

3563

if size(SCH.Parameters, 1)~=2

3573

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3564

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3574

error('Allowed is only a 2-port network having a transmitter and receiver.');

3565

error('Allowed is only a 2-port network having a transmitter and receiver.');

3575

end

3566

end

3576

%---end. allowed is only a 2-port network having a transmitter and receiver

3567

%---end. allowed is only a 2-port network having a transmitter and receiver

3577

3568

3578

%---start. do not include the DC point given sinusoidals at DC are not

3569

%---start. do not include the DC point given sinusoidals at DC are not

3579

%defined

3570

%defined

3580

if SCH.Frequencies(1)==0

3571

if SCH.Frequencies(1)==0

3581

idx_start= 2;

3572

idx_start= 2;

3582

else

3573

else

3583

idx_start= 1;

3574

idx_start= 1;

3584

end

3575

end

3585

%---end. do not include the DC point given sinusoidals at DC are not

3576

%---end. do not include the DC point given sinusoidals at DC are not

3586

%defined

3577

%defined

3587

3578

3588

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3579

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3589

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3580

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3590

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3581

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3591

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3582

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3592

3583

3593

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3584

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3594

b= 1+ Sdd22.*conj(Sdd22)+...

3585

b= 1+ Sdd22.*conj(Sdd22)+...

3595

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3586

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3596

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3587

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3597

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3588

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3598

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3589

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3599

Sdd11.*conj(Sdd11);

3590

Sdd11.*conj(Sdd11);

3600

c= -conj(Sdd22)-...

3591

c= -conj(Sdd22)-...

3601

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3592

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3602

Sdd11.*conj(Sdd11).*conj(Sdd22);

3593

Sdd11.*conj(Sdd11).*conj(Sdd22);

3603

3594

3604

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3595

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3605

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3596

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3606

3597

3607

clear a b c

3598

clear a b c

3608

3599

3609

%---start. Given the real part of the impedance is to be positive

3600

%---start. Given the real part of the impedance is to be positive

3610

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3601

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3611

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3602

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3612

3603

3613

rho_port2= zeros(length(solution_1), 1);

3604

rho_port2= zeros(length(solution_1), 1);

3614

for solution_idx= 1:length(solution_1)

3605

for solution_idx= 1:length(solution_1)

3615

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3606

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3616

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3607

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3617

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3608

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3618

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3609

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3619

else

3610

else

3620

error('An odd case has occured. Please contact the tool developer.');

3611

error('An odd case has occured. Please contact the tool developer.');

3621

end

3612

end

3622

end

3613

end

3623

%---end. Given the real part of the impedance is to be positive

3614

%---end. Given the real part of the impedance is to be positive

3624

3615

3625

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3616

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3626

3617

3627

%---start. calculate the equivalent port impedance

3618

%---start. calculate the equivalent port impedance

3628

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3619

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3629

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3620

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3630

%---end. calculate the equivalent port impedance

3621

%---end. calculate the equivalent port impedance

3631

3622

3632

3623

3633

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3624

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3634

% %to zero reflections.

3625

% %to zero reflections.

3635

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) ) );

3626

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) ) );

3636

%---end. The reflectionless insertion loss is the insertion loss corresponding

3627

%---end. The reflectionless insertion loss is the insertion loss corresponding

3637

%to zero reflections.

3628

%to zero reflections.

3638

3629

3639

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3630

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3640

RILN= RIL- Sdd21;

3631

RILN= RIL- Sdd21;

3641

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3632

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3642

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3633

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3643

3634

3644

%---start. preparing returns struct

3635

%---start. preparing returns struct

3645

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3636

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3646

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3637

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3647

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3638

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3648

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3639

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3649

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3640

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3650

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3641

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3651

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3642

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3652

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3643

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3653

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3644

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3654

%---end. preparing returns struct

3645

%---end. preparing returns struct

3655

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3646

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3656

3647

3657

3648

3658

%For the given BER, find the top & bottom voltage level in the CDF

3649

%For the given BER, find the top & bottom voltage level in the CDF

3659

3650

3660

%for the top, just find the first index at the spec BER

3651

%for the top, just find the first index at the spec BER

3661

nidx=find(cdf.y>specBER, 1, 'first');

3652

nidx=find(cdf.y>specBER, 1, 'first');

3662

noise_bottom = cdf.x(nidx);

3653

noise_bottom = cdf.x(nidx);

3663

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3654

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3664

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3655

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3665

%the true index without flipping

3656

%the true index without flipping

3666

nidx=length(cdf.y)-nidx+1;

3657

nidx=length(cdf.y)-nidx+1;

3667

noise_top = cdf.x(nidx);

3658

noise_top = cdf.x(nidx);

3668

function p=comb_fct(p1, p2)

3659

function p=comb_fct(p1, p2)

3669

if p1.BinSize ~= p2.BinSize

3660

if p1.BinSize ~= p2.BinSize

3670

error('bin size must be equal')

3661

error('bin size must be equal')

3671

end

3662

end

3672

3663

3673

p=p1;

3664

p=p1;

3674

p.BinSize=p1.BinSize;

3665

p.BinSize=p1.BinSize;

3675

%p.Min=p1.Min+p2.Min;

3666

%p.Min=p1.Min+p2.Min;

3676

p.Min=min(p1.Min,p2.Min);

3667

p.Min=min(p1.Min,p2.Min);

3677

difsz=abs(p1.Min-p2.Min);

3668

difsz=abs(p1.Min-p2.Min);

3678

lp1=length(p1.y);

3669

lp1=length(p1.y);

3679

lp2=length(p2.y);

3670

lp2=length(p2.y);

3680

if p1.Min == p.Min

3671

if p1.Min == p.Min

3681

p2.y(difsz+1:lp2+difsz)=p2.y;

3672

p2.y(difsz+1:lp2+difsz)=p2.y;

3682

p2.y(1:difsz)=0;

3673

p2.y(1:difsz)=0;

3683

p2.y(lp2+difsz+1:lp1)=0;

3674

p2.y(lp2+difsz+1:lp1)=0;

3684

elseif p2.Min == p.Min

3675

elseif p2.Min == p.Min

3685

p1.y(difsz+1:lp1+difsz)=p1.y;

3676

p1.y(difsz+1:lp1+difsz)=p1.y;

3686

p1.y(1:difsz)=0;

3677

p1.y(1:difsz)=0;

3687

p1.y(lp1+difsz+1:lp2)=0;

3678

p1.y(lp1+difsz+1:lp2)=0;

3688

end

3679

end

3689

% p.y=conv(p1.y, p2.y);

3680

% p.y=conv(p1.y, p2.y);

3690

p.y=(p1.y+p2.y);

3681

p.y=(p1.y+p2.y);

3691

% p.y=p.y/sum(p.y);

3682

% p.y=p.y/sum(p.y);

3692

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3683

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3693

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3684

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3694

3685

3695

3686

3696

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3687

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3697

3688

3698

if pdf1.BinSize ~= pdf2.BinSize

3689

if pdf1.BinSize ~= pdf2.BinSize

3699

error('bin size must be equal')

3690

error('bin size must be equal')

3700

end

3691

end

3701

3692

3702

x1=pdf1.x;

3693

x1=pdf1.x;

3703

y1=pdf1.y;

3694

y1=pdf1.y;

3704

x2=pdf2.x;

3695

x2=pdf2.x;

3705

y2=pdf2.y;

3696

y2=pdf2.y;

3706

%find the pdf with a larger min, force it to have the same min, and insert

3697

%find the pdf with a larger min, force it to have the same min, and insert

3707

%probability = 0

3698

%probability = 0

3708

min1=pdf1.x(1);

3699

min1=pdf1.x(1);

3709

min2=pdf2.x(1);

3700

min2=pdf2.x(1);

3710

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3701

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3711

if min1<min2

3702

if min1<min2

3712

x2=[pdf1.x(1:shift_amount) pdf2.x];

3703

x2=[pdf1.x(1:shift_amount) pdf2.x];

3713

y2=[zeros(1,shift_amount) pdf2.y];

3704

y2=[zeros(1,shift_amount) pdf2.y];

3714

else

3705

else

3715

x1=[pdf2.x(1:shift_amount) pdf1.x];

3706

x1=[pdf2.x(1:shift_amount) pdf1.x];

3716

y1=[zeros(1,shift_amount) pdf1.y];

3707

y1=[zeros(1,shift_amount) pdf1.y];

3717

end

3708

end

3718

%find the pdf with smaller max, force it to have the same max, and insert

3709

%find the pdf with smaller max, force it to have the same max, and insert

3719

%probability=0

3710

%probability=0

3720

L1=length(x1);

3711

L1=length(x1);

3721

L2=length(x2);

3712

L2=length(x2);

3722

Ldiff=abs(L1-L2);

3713

Ldiff=abs(L1-L2);

3723

if L1>L2

3714

if L1>L2

3724

out_x=x1;

3715

out_x=x1;

3725

y2=[y2 zeros(1,Ldiff)];

3716

y2=[y2 zeros(1,Ldiff)];

3726

else

3717

else

3727

out_x=x2;

3718

out_x=x2;

3728

y1=[y1 zeros(1,Ldiff)];

3719

y1=[y1 zeros(1,Ldiff)];

3729

end

3720

end

3730

%now the 2 pdfs have the same voltage axis, add probabilities together

3721

%now the 2 pdfs have the same voltage axis, add probabilities together

3731

%renormalization is not handled here, so the output pdf will not have sum=1

3722

%renormalization is not handled here, so the output pdf will not have sum=1

3732

%It is the responsibility of the calling function to handle renormalization

3723

%It is the responsibility of the calling function to handle renormalization

3733

%if needed

3724

%if needed

3734

out_y=y1+y2;

3725

out_y=y1+y2;

3735

out_pdf.x=out_x;

3726

out_pdf.x=out_x;

3736

out_pdf.y=out_y;

3727

out_pdf.y=out_y;

3737

out_pdf.BinSize=pdf1.BinSize;

3728

out_pdf.BinSize=pdf1.BinSize;

3738

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3729

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3739

3730

3740

%original method:

3731

%original method:

3741

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3732

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3742

% for i=1:length(s11in1)

3733

% for i=1:length(s11in1)

3743

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3734

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3744

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3735

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3745

% end

3736

% end

3746

% t1=stot(s1);

3737

% t1=stot(s1);

3747

% t2=stot(s2);

3738

% t2=stot(s2);

3748

% for i=1:length(s11in1)

3739

% for i=1:length(s11in1)

3749

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3740

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3750

% end

3741

% end

3751

% s3=ttos(t3);

3742

% s3=ttos(t3);

3752

% s11out=s3(1,1,:);

3743

% s11out=s3(1,1,:);

3753

% s11out=transpose(s11out(:));

3744

% s11out=transpose(s11out(:));

3754

% s12out=s3(1,2,:);

3745

% s12out=s3(1,2,:);

3755

% s12out=transpose(s12out(:));

3746

% s12out=transpose(s12out(:));

3756

% s21out=s3(2,1,:);

3747

% s21out=s3(2,1,:);

3757

% s21out=transpose(s21out(:));

3748

% s21out=transpose(s21out(:));

3758

% s22out=s3(2,2,:);

3749

% s22out=s3(2,2,:);

3759

% s22out=transpose(s22out(:));

3750

% s22out=transpose(s22out(:));

3760

3751

3761

3752

3762

%vectorized method:

3753

%vectorized method:

3763

s1(1,1,:)=s11in1;

3754

s1(1,1,:)=s11in1;

3764

s1(1,2,:)=s12in1;

3755

s1(1,2,:)=s12in1;

3765

s1(2,1,:)=s21in1;

3756

s1(2,1,:)=s21in1;

3766

s1(2,2,:)=s22in1;

3757

s1(2,2,:)=s22in1;

3767

s2(1,1,:)=s11in2;

3758

s2(1,1,:)=s11in2;

3768

s2(1,2,:)=s12in2;

3759

s2(1,2,:)=s12in2;

3769

s2(2,1,:)=s21in2;

3760

s2(2,1,:)=s21in2;

3770

s2(2,2,:)=s22in2;

3761

s2(2,2,:)=s22in2;

3771

3762

3772

3763

3773

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3764

N = (1-s1(2,2,:).*s2(1,1,:)) ;

3774

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3765

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

3775

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3766

s12out = s1(1,2,:).*s2(1,2,:)./N ;

3776

s21out = s2(2,1,:).*s1(2,1,:)./N;

3767

s21out = s2(2,1,:).*s1(2,1,:)./N;

3777

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3768

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

3778

3769

3779

s11out=transpose(squeeze(s11out));

3770

s11out=transpose(squeeze(s11out));

3780

s12out=transpose(squeeze(s12out));

3771

s12out=transpose(squeeze(s12out));

3781

s21out=transpose(squeeze(s21out));

3772

s21out=transpose(squeeze(s21out));

3782

s22out=transpose(squeeze(s22out));

3773

s22out=transpose(squeeze(s22out));

3783

function p=conv_fct(p1, p2)

3774

function p=conv_fct(p1, p2)

3784

if p1.BinSize ~= p2.BinSize

3775

if p1.BinSize ~= p2.BinSize

3785

error('bin size must be equal')

3776

error('bin size must be equal')

3786

end

3777

end

3787

3778

3788

p=p1;

3779

p=p1;

3789

%p.BinSize=p1.BinSize;

3780

%p.BinSize=p1.BinSize;

3790

%p.Min=p1.Min+p2.Min;

3781

%p.Min=p1.Min+p2.Min;

3791

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3782

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3792

p.y=conv2(p1.y, p2.y);

3783

p.y=conv2(p1.y, p2.y);

3793

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3784

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3794

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3785

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3795

pMax=p.Min+length(p.y)-1;

3786

pMax=p.Min+length(p.y)-1;

3796

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3787

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3797

3788

3798

3789

3799

3790

3800

3791

3801

function p=conv_fct_MeanNotZero(p1, p2)

3792

function p=conv_fct_MeanNotZero(p1, p2)

3802

3793

3803

if p1.BinSize ~= p2.BinSize

3794

if p1.BinSize ~= p2.BinSize

3804

error('bin size must be equal')

3795

error('bin size must be equal')

3805

end

3796

end

3806

3797

3807

p=p1;

3798

p=p1;

3808

%p.BinSize=p1.BinSize;

3799

%p.BinSize=p1.BinSize;

3809

%p.Min=p1.Min+p2.Min;

3800

%p.Min=p1.Min+p2.Min;

3810

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3801

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

3811

p.y=conv2(p1.y, p2.y);

3802

p.y=conv2(p1.y, p2.y);

3812

3803

3813

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3804

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

3814

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3805

%But it is faster to pre-multiply BinSize instead of multiplying the entire

3815

%vector by BinSize

3806

%vector by BinSize

3816

pMax=p.Min+length(p.y)-1;

3807

pMax=p.Min+length(p.y)-1;

3817

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3808

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

3818

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3809

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

3819

3810

3820

%IN:

3811

%IN:

3821

%sbr = pulse response

3812

%sbr = pulse response

3822

%param = COM "param" struct

3813

%param = COM "param" struct

3823

%OP = COM "OP" struct

3814

%OP = COM "OP" struct

3824

%peak_search_range= a limited range to search for the peak (for speed up)

3815

%peak_search_range= a limited range to search for the peak (for speed up)

3825

% it is usually +/- 20 UI

3816

% it is usually +/- 20 UI

3826

%

3817

%

3827

%OUT:

3818

%OUT:

3828

%cursor_i = sampling location

3819

%cursor_i = sampling location

3829

%no_zero_crossing = flag that reveals if sampling is not possible.

3820

%no_zero_crossing = flag that reveals if sampling is not possible.

3830

% When this function is called in optimize_fom, it signals to quit the current case

3821

% When this function is called in optimize_fom, it signals to quit the current case

3831

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3822

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

3832

% time consuming, so saving the peak in one spot is advantageous

3823

% time consuming, so saving the peak in one spot is advantageous

3833

%zxi = zero crossing index (returned because RXFFE uses it)

3824

%zxi = zero crossing index (returned because RXFFE uses it)

3834

3825

3835

no_zero_crossing=0;

3826

no_zero_crossing=0;

3836

%need to set cursor_i to empty in case no_zero_crossing flag is set

3827

%need to set cursor_i to empty in case no_zero_crossing flag is set

3837

cursor_i=[];

3828

cursor_i=[];

3838

3829

3839

%get peak of pulse and peak index

3830

%get peak of pulse and peak index

3840

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3831

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

3841

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3832

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

3842

3833

3843

3834

3844

% initial guess at cursor location (t_s) - based on approximate zero crossing

3835

% initial guess at cursor location (t_s) - based on approximate zero crossing

3845

%limit search space for speed up

3836

%limit search space for speed up

3846

search_start=sbr_peak_i-4*param.samples_per_ui;

3837

search_start=sbr_peak_i-4*param.samples_per_ui;

3847

if search_start<1

3838

if search_start<1

3848

search_start=1;

3839

search_start=1;

3849

end

3840

end

3850

%Find zero crossings

3841

%Find zero crossings

3851

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3842

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

3852

3843

3853

%Note: the original implementation of zxi:

3844

%Note: the original implementation of zxi:

3854

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3845

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

3855

% zxi = zxi(zxi<sbr_peak_i);

3846

% zxi = zxi(zxi<sbr_peak_i);

3856

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3847

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

3857

% The changes to limit search space and remember max(sbr) give 10x speed up

3848

% The changes to limit search space and remember max(sbr) give 10x speed up

3858

% A test case of 25k runs, reduced from 1.2s to 0.1s

3849

% A test case of 25k runs, reduced from 1.2s to 0.1s

3859

3850

3860

3851

3861

if isempty(zxi)

3852

if isempty(zxi)

3862

%if no zero crossing, the calling program must respond (since sample point will be empty)

3853

%if no zero crossing, the calling program must respond (since sample point will be empty)

3863

no_zero_crossing=1;

3854

no_zero_crossing=1;

3864

return;

3855

return;

3865

elseif length(zxi)>1

3856

elseif length(zxi)>1

3866

%only need the last zero crossing

3857

%only need the last zero crossing

3867

zxi=zxi(end);

3858

zxi=zxi(end);

3868

end

3859

end

3869

if param.ndfe==0

3860

if param.ndfe==0

3870

max_dfe1=0;

3861

max_dfe1=0;

3871

else

3862

else

3872

max_dfe1=param.bmax(1);

3863

max_dfe1=param.bmax(1);

3873

end

3864

end

3874

% adjust cursor_i to Solve equation 93A-25 %%

3865

% adjust cursor_i to Solve equation 93A-25 %%

3875

% Muller-Mueller criterion with DFE

3866

% Muller-Mueller criterion with DFE

3876

mm_range = zxi+(0:2*param.samples_per_ui);

3867

mm_range = zxi+(0:2*param.samples_per_ui);

3877

switch OP.CDR

3868

switch OP.CDR

3878

case 'Mod-MM'

3869

case 'Mod-MM'

3879

mm_metric = ...

3870

mm_metric = ...

3880

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3871

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

3881

otherwise % MM

3872

otherwise % MM

3882

%MM is generally: first precursor = 0

3873

%MM is generally: first precursor = 0

3883

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3874

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

3884

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3875

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

3885

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3876

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

3886

%first precursor = first postcursor - max_dfe

3877

%first precursor = first postcursor - max_dfe

3887

mm_metric = ...

3878

mm_metric = ...

3888

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3879

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

3889

end

3880

end

3890

[~, mm_cursor_offset] = min(mm_metric);

3881

[~, mm_cursor_offset] = min(mm_metric);

3891

3882

3892

%cursor_i = the sample location

3883

%cursor_i = the sample location

3893

cursor_i = zxi+mm_cursor_offset-1;

3884

cursor_i = zxi+mm_cursor_offset-1;

3894

function pdf=d_cpdf( binsize, values, probs)

3885

function pdf=d_cpdf( binsize, values, probs)

3895

% p=cpdf(type, ...)

3886

% p=cpdf(type, ...)

3896

%

3887

%

3897

% CPDF is a probability mass function for discrete distributions or an

3888

% CPDF is a probability mass function for discrete distributions or an

3898

% approxmation of a PDF for continuous distributions.

3889

% approxmation of a PDF for continuous distributions.

3899

%

3890

%

3900

% cpdf is internally normalized so that the sum of probabilities is 1

3891

% cpdf is internally normalized so that the sum of probabilities is 1

3901

% (regardless of bin size).

3892

% (regardless of bin size).

3902

3893

3903

% Internal fields:

3894

% Internal fields:

3904

% Min: *bin number* of minimum value.

3895

% Min: *bin number* of minimum value.

3905

% BinSize: size of PDF bins. Bin center is the representative value.

3896

% BinSize: size of PDF bins. Bin center is the representative value.

3906

% Vec: vector of probabilities per bin.

3897

% Vec: vector of probabilities per bin.

3907

3898

3908

%speed up for initializing empty pdf

3899

%speed up for initializing empty pdf

3909

if all(values==0)

3900

if all(values==0)

3910

pdf.BinSize=binsize;

3901

pdf.BinSize=binsize;

3911

pdf.Min=0;

3902

pdf.Min=0;

3912

pdf.y=1;

3903

pdf.y=1;

3913

pdf.x=0;

3904

pdf.x=0;

3914

return;

3905

return;

3915

end

3906

end

3916

3907

3917

if ~issorted(values)

3908

if ~issorted(values)

3918

[values,si]=sort(values);

3909

[values,si]=sort(values);

3919

probs=probs(si);

3910

probs=probs(si);

3920

end

3911

end

3921

values=binsize*round(values/binsize);

3912

values=binsize*round(values/binsize);

3922

t=(values(1):binsize:values(end));

3913

t=(values(1):binsize:values(end));

3923

pdf.Min=values(1)/binsize;

3914

pdf.Min=values(1)/binsize;

3924

pdf.y=zeros(size(t));

3915

pdf.y=zeros(size(t));

3925

for k=1:length(values)

3916

for k=1:length(values)

3926

if k==1

3917

if k==1

3927

bin=1;

3918

bin=1;

3928

elseif k==length(values)

3919

elseif k==length(values)

3929

bin=length(t);

3920

bin=length(t);

3930

else

3921

else

3931

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3922

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

3932

end

3923

end

3933

pdf.y(bin) = pdf.y(bin)+probs(k);

3924

pdf.y(bin) = pdf.y(bin)+probs(k);

3934

end

3925

end

3935

3926

3936

pdf.BinSize=binsize;

3927

pdf.BinSize=binsize;

3937

pdf.y=pdf.y/sum(pdf.y);

3928

pdf.y=pdf.y/sum(pdf.y);

3938

if any(~isreal(pdf.y)) || any(pdf.y<0)

3929

if any(~isreal(pdf.y)) || any(pdf.y<0)

3939

error('PDF must be real and nonnegative');

3930

error('PDF must be real and nonnegative');

3940

end

3931

end

3941

support=find(pdf.y);

3932

support=find(pdf.y);

3942

pdf.y=pdf.y(support(1):support(end));

3933

pdf.y=pdf.y(support(1):support(end));

3943

pdf.Min=pdf.Min+(support(1)-1);

3934

pdf.Min=pdf.Min+(support(1)-1);

3944

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3935

pdf.x=(pdf.Min:-pdf.Min)*binsize;

3945

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3936

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

3946

3937

3947

if isrow(input)

3938

if isrow(input)

3948

max_threshold=max_threshold(:).';

3939

max_threshold=max_threshold(:).';

3949

min_threshold=min_threshold(:).';

3940

min_threshold=min_threshold(:).';

3950

else

3941

else

3951

max_threshold=max_threshold(:);

3942

max_threshold=max_threshold(:);

3952

min_threshold=min_threshold(:);

3943

min_threshold=min_threshold(:);

3953

end

3944

end

3954

3945

3955

clip_output=input;

3946

clip_output=input;

3956

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3947

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

3957

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3948

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

3958

3949

3959

3950

3960

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3951

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

3961

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

3952

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

3962

if mele ==2

3953

if mele ==2

3963

param.flex=2;

3954

param.flex=2;

3964

elseif mele==4

3955

elseif mele==4

3965

param.flex=4;

3956

param.flex=4;

3966

elseif mele==1

3957

elseif mele==1

3967

param.flex=1;

3958

param.flex=1;

3968

else

3959

else

3969

error(springf('config file syntax error'))

3960

error(springf('config file syntax error'))

3970

end

3961

end

3971

3962

3972

3963

3973

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3964

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

3974

% display bathtub curves in one axis per test case.

3965

% display bathtub curves in one axis per test case.

3975

% h=findall(0, 'Name', 'COM results');

3966

% h=findall(0, 'Name', 'COM results');

3976

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

3967

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

3977

msgtext = cell(1, length(OP.pkg_len_select));

3968

msgtext = cell(1, length(OP.pkg_len_select));

3978

msgcolor = 'g';

3969

msgcolor = 'g';

3979

else

3970

else

3980

msgtext=get(findobj(h, 'type', 'text'), 'string');

3971

msgtext=get(findobj(h, 'type', 'text'), 'string');

3981

msgcolor = get(h, 'color');

3972

msgcolor = get(h, 'color');

3982

close(h); % will be recreated

3973

close(h); % will be recreated

3983

end

3974

end

3984

msgctr=size(msgtext,1)+1;

3975

msgctr=size(msgtext,1)+1;

3985

if ~OP.ERL_ONLY

3976

if ~OP.ERL_ONLY

3986

switch OP.PHY

3977

switch OP.PHY

3987

case 'C2M'

3978

case 'C2M'

3988

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3979

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

3989

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3980

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

3990

msg, VEO_mV);

3981

msg, VEO_mV);

3991

else

3982

else

3992

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3983

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

3993

msg, VEO_mV);

3984

msg, VEO_mV);

3994

msgcolor = 'r';

3985

msgcolor = 'r';

3995

end

3986

end

3996

3987

3997

if VEC_dB <= param.VEC_pass_threshold

3988

if VEC_dB <= param.VEC_pass_threshold

3998

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3989

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

3999

(msg), VEC_dB);

3990

(msg), VEC_dB);

4000

else

3991

else

4001

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

3992

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4002

(msg), VEC_dB);

3993

(msg), VEC_dB);

4003

msgcolor = 'r';

3994

msgcolor = 'r';

4004

end

3995

end

4005

case 'C2C'

3996

case 'C2C'

4006

if COM >= param.pass_threshold

3997

if COM >= param.pass_threshold

4007

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

3998

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4008

% msg, COM);

3999

% msg, COM);

4009

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4000

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4010

msg, COM);

4001

msg, COM);

4011

else

4002

else

4012

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4003

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4013

% msg, COM);

4004

% msg, COM);

4014

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4005

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4015

msg, COM);

4006

msg, COM);

4016

msgcolor = 'r';

4007

msgcolor = 'r';

4017

end

4008

end

4018

% begin yasuo patch 3/18/2019

4009

% begin yasuo patch 3/18/2019

4019

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4010

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4020

% end yasuo patch

4011

% end yasuo patch

4021

case 'C2Mcom'

4012

case 'C2Mcom'

4022

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4013

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4023

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4014

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4024

msg, VEO_mV);

4015

msg, VEO_mV);

4025

else

4016

else

4026

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4017

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4027

msg, VEO_mV);

4018

msg, VEO_mV);

4028

msgcolor = 'r';

4019

msgcolor = 'r';

4029

end

4020

end

4030

4021

4031

if VEC_dB <= param.VEC_pass_threshold

4022

if VEC_dB <= param.VEC_pass_threshold

4032

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4023

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4033

(msg), VEC_dB);

4024

(msg), VEC_dB);

4034

else

4025

else

4035

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4026

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4036

(msg), VEC_dB);

4027

(msg), VEC_dB);

4037

msgcolor = 'r';

4028

msgcolor = 'r';

4038

end

4029

end

4039

if COM >= param.pass_threshold

4030

if COM >= param.pass_threshold

4040

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4031

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4041

% msg, COM);

4032

% msg, COM);

4042

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4033

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4043

msg, COM);

4034

msg, COM);

4044

else

4035

else

4045

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4036

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4046

% msg, COM);

4037

% msg, COM);

4047

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4038

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4048

msg, COM);

4039

msg, COM);

4049

msgcolor = 'r';

4040

msgcolor = 'r';

4050

end

4041

end

4051

% begin yasuo patch 3/18/2019

4042

% begin yasuo patch 3/18/2019

4052

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4043

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4053

% end yasuo patch

4044

% end yasuo patch

4054

end

4045

end

4055

end

4046

end

4056

if OP.ERL

4047

if OP.ERL

4057

if ~isempty(ERL)

4048

if ~isempty(ERL)

4058

if min_ERL >= param.ERL_pass_threshold

4049

if min_ERL >= param.ERL_pass_threshold

4059

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4050

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4060

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4051

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4061

else

4052

else

4062

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4053

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4063

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4054

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4064

msgcolor = 'r';

4055

msgcolor = 'r';

4065

end

4056

end

4066

end

4057

end

4067

end

4058

end

4068

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4059

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4069

set(h, 'color', msgcolor, 'tag', 'COM');

4060

set(h, 'color', msgcolor, 'tag', 'COM');

4070

movegui(h, 'center');

4061

movegui(h, 'center');

4071

else % no windows

4062

else % no windows

4072

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4063

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4073

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4064

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4074

if ~OP.ERL_ONLY

4065

if ~OP.ERL_ONLY

4075

switch OP.PHY

4066

switch OP.PHY

4076

case 'C2C'

4067

case 'C2C'

4077

if COM >= param.pass_threshold

4068

if COM >= param.pass_threshold

4078

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4069

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4079

else

4070

else

4080

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4071

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4081

end

4072

end

4082

% begin yasuo patch 3/18/2019

4073

% begin yasuo patch 3/18/2019

4083

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4074

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4084

% end yasuo patch

4075

% end yasuo patch

4085

case 'C2Mcom'

4076

case 'C2Mcom'

4086

if VEC_dB <= param.VEC_pass_threshold

4077

if VEC_dB <= param.VEC_pass_threshold

4087

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4078

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4088

else

4079

else

4089

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4080

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4090

end

4081

end

4091

4082

4092

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4083

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4093

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4084

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4094

else

4085

else

4095

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4086

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4096

end

4087

end

4097

if COM >= param.pass_threshold

4088

if COM >= param.pass_threshold

4098

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4089

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4099

else

4090

else

4100

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4091

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4101

end

4092

end

4102

% begin yasuo patch 3/18/2019

4093

% begin yasuo patch 3/18/2019

4103

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4094

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4104

% end yasuo patch

4095

% end yasuo patch

4105

case 'C2M'

4096

case 'C2M'

4106

if VEC_dB <= param.VEC_pass_threshold

4097

if VEC_dB <= param.VEC_pass_threshold

4107

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4098

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4108

else

4099

else

4109

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4100

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4110

end

4101

end

4111

4102

4112

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4103

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4113

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4104

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4114

else

4105

else

4115

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4106

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4116

end

4107

end

4117

end

4108

end

4118

end

4109

end

4119

if OP.ERL

4110

if OP.ERL

4120

if ~isempty(ERL)

4111

if ~isempty(ERL)

4121

if min_ERL >= param.ERL_pass_threshold

4112

if min_ERL >= param.ERL_pass_threshold

4122

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4113

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4123

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4114

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4124

else

4115

else

4125

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4116

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4126

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4117

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4127

end

4118

end

4128

end

4119

end

4129

end

4120

end

4130

end

4121

end

4131

4122

4132

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4123

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4133

4124

4134

%Left eye Width (Top Eye)

4125

%Left eye Width (Top Eye)

4135

left_top=eye_contour(half_UI:-1:1,1);

4126

left_top=eye_contour(half_UI:-1:1,1);

4136

%vref_crossing is the first point less than vref (usually first point < 0)

4127

%vref_crossing is the first point less than vref (usually first point < 0)

4137

vref_crossing=find(left_top<vref,1,'first');

4128

vref_crossing=find(left_top<vref,1,'first');

4138

if isempty(vref_crossing)

4129

if isempty(vref_crossing)

4139

%this case handles completely open eye

4130

%this case handles completely open eye

4140

L1=half_UI;

4131

L1=half_UI;

4141

elseif vref_crossing==1

4132

elseif vref_crossing==1

4142

%this case handles completely closed eye

4133

%this case handles completely closed eye

4143

L1=0;

4134

L1=0;

4144

else

4135

else

4145

%this case handles the normal eye

4136

%this case handles the normal eye

4146

%INT is a linear interpolation between the 2 points on either side of

4137

%INT is a linear interpolation between the 2 points on either side of

4147

%vref to determine where the vref crossing occurred. In systems with

4138

%vref to determine where the vref crossing occurred. In systems with

4148

%a small number of samples_per_UI, interpolation improves accuracy over

4139

%a small number of samples_per_UI, interpolation improves accuracy over

4149

%just using the integer sample point

4140

%just using the integer sample point

4150

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4141

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4151

L1=half_UI-INT;

4142

L1=half_UI-INT;

4152

end

4143

end

4153

%Left eye Width (Bottom Eye)

4144

%Left eye Width (Bottom Eye)

4154

left_bot=eye_contour(half_UI:-1:1,2);

4145

left_bot=eye_contour(half_UI:-1:1,2);

4155

vref_crossing=find(left_bot>vref,1,'first');

4146

vref_crossing=find(left_bot>vref,1,'first');

4156

if isempty(vref_crossing)

4147

if isempty(vref_crossing)

4157

L0=half_UI;

4148

L0=half_UI;

4158

elseif vref_crossing==1

4149

elseif vref_crossing==1

4159

L0=0;

4150

L0=0;

4160

else

4151

else

4161

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4152

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4162

L0=half_UI-INT;

4153

L0=half_UI-INT;

4163

end

4154

end

4164

%Right eye Width (Top Eye)

4155

%Right eye Width (Top Eye)

4165

right_top=eye_contour(half_UI:end,1);

4156

right_top=eye_contour(half_UI:end,1);

4166

vref_crossing=find(right_top<vref,1,'first');

4157

vref_crossing=find(right_top<vref,1,'first');

4167

if isempty(vref_crossing)

4158

if isempty(vref_crossing)

4168

R1=samples_per_UI-half_UI;

4159

R1=samples_per_UI-half_UI;

4169

elseif vref_crossing==1

4160

elseif vref_crossing==1

4170

R1=0;

4161

R1=0;

4171

else

4162

else

4172

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4163

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4173

R1=INT-half_UI;

4164

R1=INT-half_UI;

4174

end

4165

end

4175

%Right eye Width (Bottom Eye)

4166

%Right eye Width (Bottom Eye)

4176

right_bot=eye_contour(half_UI:end,2);

4167

right_bot=eye_contour(half_UI:end,2);

4177

vref_crossing=find(right_bot>vref,1,'first');

4168

vref_crossing=find(right_bot>vref,1,'first');

4178

if isempty(vref_crossing)

4169

if isempty(vref_crossing)

4179

R0=samples_per_UI-half_UI;

4170

R0=samples_per_UI-half_UI;

4180

elseif vref_crossing==1

4171

elseif vref_crossing==1

4181

R0=0;

4172

R0=0;

4182

else

4173

else

4183

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4174

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4184

R0=INT-half_UI;

4175

R0=INT-half_UI;

4185

end

4176

end

4186

4177

4187

%L1 = top left eye width

4178

%L1 = top left eye width

4188

%L0 = bottom left eye width

4179

%L0 = bottom left eye width

4189

%Left eye width is the minimum

4180

%Left eye width is the minimum

4190

%R1 = top right eye width

4181

%R1 = top right eye width

4191

%R0 = bottom right eye width

4182

%R0 = bottom right eye width

4192

%Right eye width is the minimum

4183

%Right eye width is the minimum

4193

Left_EW=min([L1 L0]);

4184

Left_EW=min([L1 L0]);

4194

Right_EW=min([R1 R0]);

4185

Right_EW=min([R1 R0]);

4195

4186

4196

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4187

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4197

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4188

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4198

% find the location of the DFE bank

4189

% find the location of the DFE bank

4199

% hisi: waveform with cursor values;

4190

% hisi: waveform with cursor values;

4200

% idx_st: starting index;

4191

% idx_st: starting index;

4201

% idx_en: ending index ;

4192

% idx_en: ending index ;

4202

% tap_bk: number of taps per bank;

4193

% tap_bk: number of taps per bank;

4203

% bmaxg: maximum coefficient;

4194

% bmaxg: maximum coefficient;

4204

4195

4205

hisi=hisi(:);

4196

hisi=hisi(:);

4206

len=idx_en-idx_st+1;

4197

len=idx_en-idx_st+1;

4207

h0=abs(hisi(idx_st:idx_en));

4198

h0=abs(hisi(idx_st:idx_en));

4208

h1=max(0,h0-bmaxg*curval);

4199

h1=max(0,h0-bmaxg*curval);

4209

4200

4210

%if cursor value is negative, force h1 to all zeros

4201

%if cursor value is negative, force h1 to all zeros

4211

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4202

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4212

%this makes the weakest isi the most desirable to choose so everything breaks

4203

%this makes the weakest isi the most desirable to choose so everything breaks

4213

if curval<0

4204

if curval<0

4214

h1=zeros(size(h0));

4205

h1=zeros(size(h0));

4215

end

4206

end

4216

4207

4217

h0n=zeros(len-tap_bk+1,1);

4208

h0n=zeros(len-tap_bk+1,1);

4218

h1n=h0n;

4209

h1n=h0n;

4219

4210

4220

for ii=1:tap_bk

4211

for ii=1:tap_bk

4221

h0tmp=h0(ii:ii+len-tap_bk);

4212

h0tmp=h0(ii:ii+len-tap_bk);

4222

h0n=h0n+h0tmp.^2;

4213

h0n=h0n+h0tmp.^2;

4223

h1tmp=h1(ii:ii+len-tap_bk);

4214

h1tmp=h1(ii:ii+len-tap_bk);

4224

h1n=h1n+h1tmp.^2;

4215

h1n=h1n+h1tmp.^2;

4225

end

4216

end

4226

4217

4227

ndiff=h0n-h1n;

4218

ndiff=h0n-h1n;

4228

4219

4229

min_energy = -Inf;

4220

min_energy = -Inf;

4230

4221

4231

idx=zeros(1,tap_bk*N_bg);

4222

idx=zeros(1,tap_bk*N_bg);

4232

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4223

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4233

set_next_bank=0;

4224

set_next_bank=0;

4234

%Loop through each group

4225

%Loop through each group

4235

for k=1:N_bg

4226

for k=1:N_bg

4236

%Sort to choose the strongest

4227

%Sort to choose the strongest

4237

[~,val_sort]=sort(ndiff,'descend');

4228

[~,val_sort]=sort(ndiff,'descend');

4238

if k==1

4229

if k==1

4239

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4230

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4240

if isequal(sort(val_sort(ordered_set)),ordered_set)

4231

if isequal(sort(val_sort(ordered_set)),ordered_set)

4241

idx=1:N_bg*tap_bk;

4232

idx=1:N_bg*tap_bk;

4242

break;

4233

break;

4243

end

4234

end

4244

end

4235

end

4245

if set_next_bank>0

4236

if set_next_bank>0

4246

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4237

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4247

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4238

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4248

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4239

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4249

set_next_bank=0;

4240

set_next_bank=0;

4250

ndiff(new_bank)=min_energy;

4241

ndiff(new_bank)=min_energy;

4251

bad_start=new_bank(1)-tap_bk+1;

4242

bad_start=new_bank(1)-tap_bk+1;

4252

bad_end=new_bank(1)-1;

4243

bad_end=new_bank(1)-1;

4253

if bad_end<=0

4244

if bad_end<=0

4254

badV=[];

4245

badV=[];

4255

elseif bad_start>0

4246

elseif bad_start>0

4256

badV=bad_start:bad_end;

4247

badV=bad_start:bad_end;

4257

else

4248

else

4258

badV=1:bad_end;

4249

badV=1:bad_end;

4259

end

4250

end

4260

if ~isempty(badV)

4251

if ~isempty(badV)

4261

ndiff(badV)=min_energy;

4252

ndiff(badV)=min_energy;

4262

end

4253

end

4263

continue;

4254

continue;

4264

end

4255

end

4265

%potential bank = the strongest tap group

4256

%potential bank = the strongest tap group

4266

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4257

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4267

if k==N_bg

4258

if k==N_bg

4268

%Last group: just choose the strongest

4259

%Last group: just choose the strongest

4269

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4260

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4270

break;

4261

break;

4271

end

4262

end

4272

4263

4273

do_it_again=1;

4264

do_it_again=1;

4274

first_time=1;

4265

first_time=1;

4275

num_loops=0;

4266

num_loops=0;

4276

while do_it_again

4267

while do_it_again

4277

do_it_again=0;

4268

do_it_again=0;

4278

if num_loops>length(ndiff)

4269

if num_loops>length(ndiff)

4279

break;

4270

break;

4280

end

4271

end

4281

%note badV: taps smaller and less than 1 group away

4272

%note badV: taps smaller and less than 1 group away

4282

bad_start=new_bank(1)-tap_bk+1;

4273

bad_start=new_bank(1)-tap_bk+1;

4283

bad_end=new_bank(1)-1;

4274

bad_end=new_bank(1)-1;

4284

if bad_end<=0

4275

if bad_end<=0

4285

badV=[];

4276

badV=[];

4286

elseif bad_start>0

4277

elseif bad_start>0

4287

badV=bad_start:bad_end;

4278

badV=bad_start:bad_end;

4288

else

4279

else

4289

badV=1:bad_end;

4280

badV=1:bad_end;

4290

end

4281

end

4291

for j=length(badV):-1:1

4282

for j=length(badV):-1:1

4292

if any(badV(j)-idx==0)

4283

if any(badV(j)-idx==0)

4293

badV(j)=[];

4284

badV(j)=[];

4294

end

4285

end

4295

end

4286

end

4296

%note goodV: the tap exactly 1 tap_bk smaller

4287

%note goodV: the tap exactly 1 tap_bk smaller

4297

goodV=new_bank(1)-tap_bk;

4288

goodV=new_bank(1)-tap_bk;

4298

if ~isempty(badV)

4289

if ~isempty(badV)

4299

if ~first_time

4290

if ~first_time

4300

[~,val_sort]=sort(ndiff,'descend');

4291

[~,val_sort]=sort(ndiff,'descend');

4301

end

4292

end

4302

first_time=0;

4293

first_time=0;

4303

checkV=[badV new_bank];

4294

checkV=[badV new_bank];

4304

4295

4305

badV_pos=zeros(1,length(badV));

4296

badV_pos=zeros(1,length(badV));

4306

for j=1:length(badV)

4297

for j=1:length(badV)

4307

badV_pos(j)=find(badV(j)==val_sort);

4298

badV_pos(j)=find(badV(j)==val_sort);

4308

end

4299

end

4309

4300

4310

%loop through the sorted list to find the first tap outside the group and not a member of badV

4301

%loop through the sorted list to find the first tap outside the group and not a member of badV

4311

found_goodV=0;

4302

found_goodV=0;

4312

for ii=1:length(val_sort)

4303

for ii=1:length(val_sort)

4313

if val_sort(ii)==goodV

4304

if val_sort(ii)==goodV

4314

found_goodV=1;

4305

found_goodV=1;

4315

break;

4306

break;

4316

end

4307

end

4317

if all(val_sort(ii)-checkV~=0)

4308

if all(val_sort(ii)-checkV~=0)

4318

break;

4309

break;

4319

end

4310

end

4320

end

4311

end

4321

4312

4322

if ~found_goodV && min(badV_pos)<ii

4313

if ~found_goodV && min(badV_pos)<ii

4323

%if goodV wasn't found and bad taps occur before non group members are found

4314

%if goodV wasn't found and bad taps occur before non group members are found

4324

%throw out the strongest tap and take the next strongest

4315

%throw out the strongest tap and take the next strongest

4325

do_it_again=1;

4316

do_it_again=1;

4326

ndiff(new_bank(1))=min_energy;

4317

ndiff(new_bank(1))=min_energy;

4327

%speed up: new max_val is always val_sort(2)

4318

%speed up: new max_val is always val_sort(2)

4328

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4319

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4329

end

4320

end

4330

if found_goodV

4321

if found_goodV

4331

%if goodV was found, set the next bank to goodV

4322

%if goodV was found, set the next bank to goodV

4332

set_next_bank=goodV;

4323

set_next_bank=goodV;

4333

end

4324

end

4334

end

4325

end

4335

num_loops=num_loops+1;

4326

num_loops=num_loops+1;

4336

end

4327

end

4337

%at the end, the floating taps are set to idx

4328

%at the end, the floating taps are set to idx

4338

%and ndiff has illegal values set to zero

4329

%and ndiff has illegal values set to zero

4339

ndiff(new_bank)=min_energy;

4330

ndiff(new_bank)=min_energy;

4340

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4331

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4341

if ~isempty(badV)

4332

if ~isempty(badV)

4342

ndiff(badV)=min_energy;

4333

ndiff(badV)=min_energy;

4343

end

4334

end

4344

end

4335

end

4345

4336

4346

4337

4347

idx=idx+idx_st-1;

4338

idx=idx+idx_st-1;

4348

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4339

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4349

4340

4350

% hisi = postcursor isi

4341

% hisi = postcursor isi

4351

% N_b = number of fixed dfe taps (before floating taps begin)

4342

% N_b = number of fixed dfe taps (before floating taps begin)

4352

% N_bf = number of floating taps per group

4343

% N_bf = number of floating taps per group

4353

% N_bg = nubmber of groups

4344

% N_bg = nubmber of groups

4354

% N_bmax = max tap number that can be used for floating tap

4345

% N_bmax = max tap number that can be used for floating tap

4355

% bmaxg = max tap strength for floating taps

4346

% bmaxg = max tap strength for floating taps

4356

% curval = value of the cursor

4347

% curval = value of the cursor

4357

4348

4358

4349

4359

if nargin<8, dfe_delta=0;end

4350

if nargin<8, dfe_delta=0;end

4360

4351

4361

4352

4362

tap_coef=zeros(1,length(hisi));

4353

tap_coef=zeros(1,length(hisi));

4363

b=zeros(1,length(hisi));

4354

b=zeros(1,length(hisi));

4364

4355

4365

4356

4366

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4357

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4367

4358

4368

%Apply DFE to all taps

4359

%Apply DFE to all taps

4369

flt_curval=hisi(tap_loc);

4360

flt_curval=hisi(tap_loc);

4370

if dfe_delta~=0

4361

if dfe_delta~=0

4371

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4362

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4372

dfe_delta.*sign(flt_curval)*curval;

4363

dfe_delta.*sign(flt_curval)*curval;

4373

else

4364

else

4374

flt_curval_q=hisi(tap_loc);

4365

flt_curval_q=hisi(tap_loc);

4375

end

4366

end

4376

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4367

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4377

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4368

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4378

tap_coef(tap_loc)=applied_coef;

4369

tap_coef(tap_loc)=applied_coef;

4379

4370

4380

4371

4381

4372

4382

tap_loc=sort(tap_loc,'ascend');

4373

tap_loc=sort(tap_loc,'ascend');

4383

b(tap_loc)=bmaxg;

4374

b(tap_loc)=bmaxg;

4384

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4375

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4385

% Richard Mellitz: 04/23/2019

4376

% Richard Mellitz: 04/23/2019

4386

% hisi is the isi 1 ui/sample

4377

% hisi is the isi 1 ui/sample

4387

% N_b number of fixed dfe taps

4378

% N_b number of fixed dfe taps

4388

% N_bf number of floating taps per group

4379

% N_bf number of floating taps per group

4389

% N_bg number of floating tap groups. 1 2 or 3 right now

4380

% N_bg number of floating tap groups. 1 2 or 3 right now

4390

% N_bmax number of ui for the max reach of the floating taps

4381

% N_bmax number of ui for the max reach of the floating taps

4391

% bmaxg limit for the floating taps

4382

% bmaxg limit for the floating taps

4392

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4383

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4393

%

4384

%

4394

%

4385

%

4395

% function to remove isi or add noise above bmaxg

4386

% function to remove isi or add noise above bmaxg

4396

if ~exist('COOP','var'), COOP=0;end

4387

if ~exist('COOP','var'), COOP=0;end

4397

if iscolumn(hisi); hisi=hisi.';end

4388

if iscolumn(hisi); hisi=hisi.';end

4398

hsis_in=hisi;

4389

hsis_in=hisi;

4399

% find all the reduction group taken N_bf at a time

4390

% find all the reduction group taken N_bf at a time

4400

% we are looking for the group when when remove yield the miminim isi, h, power

4391

% we are looking for the group when when remove yield the miminim isi, h, power

4401

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4392

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4402

% add on switch and loop for each potential group

4393

% add on switch and loop for each potential group

4403

switch N_bg

4394

switch N_bg

4404

case 0

4395

case 0

4405

bmax=0;

4396

bmax=0;

4406

return

4397

return

4407

case 1

4398

case 1

4408

end1=N_bmax-N_bf;

4399

end1=N_bmax-N_bf;

4409

end2=N_b+1;

4400

end2=N_b+1;

4410

end3=N_b+1;

4401

end3=N_b+1;

4411

case 2

4402

case 2

4412

end1=N_bmax-N_bf;

4403

end1=N_bmax-N_bf;

4413

end2=N_bmax-N_bf;

4404

end2=N_bmax-N_bf;

4414

end3=N_b+1;

4405

end3=N_b+1;

4415

case 3

4406

case 3

4416

end1=N_bmax-N_bf;

4407

end1=N_bmax-N_bf;

4417

end2=N_bmax-N_bf;

4408

end2=N_bmax-N_bf;

4418

end3=N_bmax-N_bf;

4409

end3=N_bmax-N_bf;

4419

end

4410

end

4420

if COOP

4411

if COOP

4421

for ig1= N_b+1:end1 % now remove the 2nd group

4412

for ig1= N_b+1:end1 % now remove the 2nd group

4422

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4413

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4423

% loop for 2rd group

4414

% loop for 2rd group

4424

for ig2= N_b+1: end2

4415

for ig2= N_b+1: end2

4425

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4416

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4426

if N_bg < 2; hcap2 =hcap; end

4417

if N_bg < 2; hcap2 =hcap; end

4427

for ig3= N_b+1: end3

4418

for ig3= N_b+1: end3

4428

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4419

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4429

if N_bg < 3 ; hcap3=hcap2 ; end

4420

if N_bg < 3 ; hcap3=hcap2 ; end

4430

sigma=norm( hcap3 );

4421

sigma=norm( hcap3 );

4431

if sigma < best_sigma

4422

if sigma < best_sigma

4432

best_sigma=sigma;

4423

best_sigma=sigma;

4433

best_ig1=ig1;

4424

best_ig1=ig1;

4434

best_ig2=ig2;

4425

best_ig2=ig2;

4435

best_ig3=ig3;

4426

best_ig3=ig3;

4436

best_hcap=hcap3;

4427

best_hcap=hcap3;

4437

end

4428

end

4438

end

4429

end

4439

end

4430

end

4440

end

4431

end

4441

else % sequentail

4432

else % sequentail

4442

for ig1= N_b+1:end1 % now remove the 1st group

4433

for ig1= N_b+1:end1 % now remove the 1st group

4443

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4434

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4444

sigma=norm( hcap );

4435

sigma=norm( hcap );

4445

if sigma < best_sigma

4436

if sigma < best_sigma

4446

best_sigma=sigma;

4437

best_sigma=sigma;

4447

best_ig1=ig1;

4438

best_ig1=ig1;

4448

best_hcap=hcap;

4439

best_hcap=hcap;

4449

end

4440

end

4450

end

4441

end

4451

% loop for 2rd group

4442

% loop for 2rd group

4452

hisi=best_hcap;

4443

hisi=best_hcap;

4453

for ig2= N_b+1: end2

4444

for ig2= N_b+1: end2

4454

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4445

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4455

sigma=norm( hcap );

4446

sigma=norm( hcap );

4456

if sigma < best_sigma

4447

if sigma < best_sigma

4457

best_sigma=sigma;

4448

best_sigma=sigma;

4458

best_ig2=ig2;

4449

best_ig2=ig2;

4459

best_hcap=hcap;

4450

best_hcap=hcap;

4460

end

4451

end

4461

end

4452

end

4462

hisi=best_hcap;

4453

hisi=best_hcap;

4463

% loop for 3rd group

4454

% loop for 3rd group

4464

for ig3= N_b+1: end3

4455

for ig3= N_b+1: end3

4465

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4456

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4466

sigma=norm( hcap );

4457

sigma=norm( hcap );

4467

if sigma < best_sigma

4458

if sigma < best_sigma

4468

best_sigma=sigma;

4459

best_sigma=sigma;

4469

best_ig3=ig3;

4460

best_ig3=ig3;

4470

best_hcap=hcap;

4461

best_hcap=hcap;

4471

end

4462

end

4472

end

4463

end

4473

4464

4474

end

4465

end

4475

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4466

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4476

switch N_bg

4467

switch N_bg

4477

case 1

4468

case 1

4478

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4469

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4479

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4470

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4480

case 2

4471

case 2

4481

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4472

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4482

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4473

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4483

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4474

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4484

case 3

4475

case 3

4485

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4476

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4486

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4477

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4487

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4478

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4488

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4479

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4489

end

4480

end

4490

floating_tap_locations=sort(floating_tap_locations);

4481

floating_tap_locations=sort(floating_tap_locations);

4491

if 0 % for code debug

4482

if 0 % for code debug

4492

close force all

4483

close force all

4493

stem(best_hcap,'disp','hcap')

4484

stem(best_hcap,'disp','hcap')

4494

hold on

4485

hold on

4495

stem(bmax,'-k','disp','bmax')

4486

stem(bmax,'-k','disp','bmax')

4496

stem(hisi,'disp','hisi')

4487

stem(hisi,'disp','hisi')

4497

hold off

4488

hold off

4498

end

4489

end

4499

4490

4500

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4491

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4501

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4492

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4502

% Vfilter is vector forced filtered sbr

4493

% Vfilter is vector forced filtered sbr

4503

% Cmod is the ffe tap co-efficient vector

4494

% Cmod is the ffe tap co-efficient vector

4504

% if C is passed, just process V with C else compute C

4495

% if C is passed, just process V with C else compute C

4505

% cmx=param.rx_cmx; number of pre cursor taps

4496

% cmx=param.rx_cmx; number of pre cursor taps

4506

% cpx=param.rx_cps; number of post cursor taps

4497

% cpx=param.rx_cps; number of post cursor taps

4507

% V=sbr; pass pulse response

4498

% V=sbr; pass pulse response

4508

% ix the sample point in the passed pulse response

4499

% ix the sample point in the passed pulse response

4509

% the sample point is recomputed by optimize_fom

4500

% the sample point is recomputed by optimize_fom

4510

% idx - return floating tap location (RIM 9-19-2023)

4501

% idx - return floating tap location (RIM 9-19-2023)

4511

% OP not used for now

4502

% OP not used for now

4512

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4503

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4513

% this allows significant speed up in optimize_fom since FFE is time consuming

4504

% this allows significant speed up in optimize_fom since FFE is time consuming

4514

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4505

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4515

% Vfiltered to be calculated

4506

% Vfiltered to be calculated

4516

% test with load('SBR_FIR_resp.mydata','-mat')

4507

% test with load('SBR_FIR_resp.mydata','-mat')

4517

idx=[];

4508

idx=[];

4518

if nargin<4

4509

if nargin<4

4519

ix=find(V==max(V),1,'first');

4510

ix=find(V==max(V),1,'first');

4520

end

4511

end

4521

if nargin<5

4512

if nargin<5

4522

C=[];

4513

C=[];

4523

end

4514

end

4524

if nargin<6

4515

if nargin<6

4525

return_V=1;

4516

return_V=1;

4526

end

4517

end

4527

cmx=param.RxFFE_cmx;

4518

cmx=param.RxFFE_cmx;

4528

cpx=param.RxFFE_cpx;

4519

cpx=param.RxFFE_cpx;

4529

% do this early on so we can reuse the old code

4520

% do this early on so we can reuse the old code

4530

if param.N_bg ~=0 % must be floating taps

4521

if param.N_bg ~=0 % must be floating taps

4531

cpx=param.N_bmax; % N_f in spreadsheet

4522

cpx=param.N_bmax; % N_f in spreadsheet

4532

end

4523

end

4533

num_taps=cmx+cpx+1;

4524

num_taps=cmx+cpx+1;

4534

cstep=param.RxFFE_stepz;

4525

cstep=param.RxFFE_stepz;

4535

ndfe=param.ndfe;

4526

ndfe=param.ndfe;

4536

spui=param.samples_per_ui;

4527

spui=param.samples_per_ui;

4537

param.current_ffegain=0;

4528

param.current_ffegain=0;

4538

if return_V && ~isempty(C)

4529

if return_V && ~isempty(C)

4539

% RIM 2-3-23 when we just want to EQ not find EQ

4530

% RIM 2-3-23 when we just want to EQ not find EQ

4540

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4531

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4541

Cmod=C;

4532

Cmod=C;

4542

return

4533

return

4543

end

4534

end

4544

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4535

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4545

if ix < length(V)

4536

if ix < length(V)

4546

if isrow(V)

4537

if isrow(V)

4547

if mod(ix,spui) == 0

4538

if mod(ix,spui) == 0

4548

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4539

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4549

else

4540

else

4550

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4541

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4551

end

4542

end

4552

4543

4553

else

4544

else

4554

if mod(ix,spui) == 0

4545

if mod(ix,spui) == 0

4555

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4546

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4556

else

4547

else

4557

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4548

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4558

end

4549

end

4559

end

4550

end

4560

else

4551

else

4561

if isrow(V)

4552

if isrow(V)

4562

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4553

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4563

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4554

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4564

else

4555

else

4565

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4556

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4566

end

4557

end

4567

else

4558

else

4568

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4559

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4569

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4560

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4570

else

4561

else

4571

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4562

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4572

end

4563

end

4573

end

4564

end

4574

end

4565

end

4575

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4566

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4576

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4567

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4577

4568

4578

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4569

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4579

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4570

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4580

% Upen Kareti suggested fix for indexing 11/04/18

4571

% Upen Kareti suggested fix for indexing 11/04/18

4581

if ix < length(V)

4572

if ix < length(V)

4582

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4573

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4583

else

4574

else

4584

ivs=find(vsampled == max(vsampled),1,'first');

4575

ivs=find(vsampled == max(vsampled),1,'first');

4585

end

4576

end

4586

4577

4587

4578

4588

%% create VV matrix of shifted UI spaced sample of the pulse response

4579

%% create VV matrix of shifted UI spaced sample of the pulse response

4589

% only consider the VV matrix that correstonds to the FFE taps

4580

% only consider the VV matrix that correstonds to the FFE taps

4590

VV=zeros(num_taps,num_taps);

4581

VV=zeros(num_taps,num_taps);

4591

for i=1:num_taps

4582

for i=1:num_taps

4592

start_idx=ivs+i-1;

4583

start_idx=ivs+i-1;

4593

end_idx=start_idx-num_taps+1;

4584

end_idx=start_idx-num_taps+1;

4594

VV(:,i)=vsampled(start_idx:-1:end_idx);

4585

VV(:,i)=vsampled(start_idx:-1:end_idx);

4595

end

4586

end

4596

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4587

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4597

%% Apply RXFFE

4588

%% Apply RXFFE

4598

if isempty(C)

4589

if isempty(C)

4599

switch upper(OP.FFE_OPT_METHOD)

4590

switch upper(OP.FFE_OPT_METHOD)

4600

case 'WIENER-HOPF'

4591

case 'WIENER-HOPF'

4601

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4592

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4602

Cmod=C(1:num_taps);

4593

Cmod=C(1:num_taps);

4603

otherwise

4594

otherwise

4604

% cmx+1 is the cursor or sample point

4595

% cmx+1 is the cursor or sample point

4605

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4596

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4606

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4597

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4607

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4598

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4608

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4599

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4609

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4600

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4610

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4601

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4611

end

4602

end

4612

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4603

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4613

if diff(size(VV))==0

4604

if diff(size(VV))==0

4614

%For square matrix, can solve C using simple inv(VV')*FV'

4605

%For square matrix, can solve C using simple inv(VV')*FV'

4615

C=VV'\FV';

4606

C=VV'\FV';

4616

else

4607

else

4617

%otherwise use the general solution with psuedo inverse

4608

%otherwise use the general solution with psuedo inverse

4618

%note: this is the same as doing pinv(VV') but pinv is far slower

4609

%note: this is the same as doing pinv(VV') but pinv is far slower

4619

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4610

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4620

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4611

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4621

end

4612

end

4622

4613

4623

Cmod=C(1:num_taps);

4614

Cmod=C(1:num_taps);

4624

end

4615

end

4625

4616

4626

4617

4627

% added for 4.2 find floating taps with either ISI or taps

4618

% added for 4.2 find floating taps with either ISI or taps

4628

switch lower(OP.RXFFE_FLOAT_CTL)

4619

switch lower(OP.RXFFE_FLOAT_CTL)

4629

case 'taps'

4620

case 'taps'

4630

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4621

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4631

otherwise

4622

otherwise

4632

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4623

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4633

end

4624

end

4634

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4625

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4635

case 'unity cursor'

4626

case 'unity cursor'

4636

Cmod=Cmod/Cmod(cmx+1);

4627

Cmod=Cmod/Cmod(cmx+1);

4637

otherwise

4628

otherwise

4638

Cmod=C;

4629

Cmod=C;

4639

end

4630

end

4640

if cstep ~= 0

4631

if cstep ~= 0

4641

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4632

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4642

end

4633

end

4643

4634

4644

if ~isempty(idx)

4635

if ~isempty(idx)

4645

idx=sort(idx);

4636

idx=sort(idx);

4646

C1=Cmod;

4637

C1=Cmod;

4647

% C1(param.N_tail_start:end)=0;

4638

% C1(param.N_tail_start:end)=0;

4648

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4639

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4649

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4640

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4650

Cmod=C1;

4641

Cmod=C1;

4651

else

4642

else

4652

% Cmod=C;

4643

% Cmod=C;

4653

end

4644

end

4654

4645

4655

% now when ussing RxFFE floating taps need to tag stems correctly and

4646

% now when ussing RxFFE floating taps need to tag stems correctly and

4656

% make sure DFEfloating tap code does not get exectuted

4647

% make sure DFEfloating tap code does not get exectuted

4657

4648

4658

%

4649

%

4659

else

4650

else

4660

Cmod=C;%just us the FFE taps, C, passed for filtering

4651

Cmod=C;%just us the FFE taps, C, passed for filtering

4661

end

4652

end

4662

%%

4653

%%

4663

%% filter the pulse response with the solved FFE

4654

%% filter the pulse response with the solved FFE

4664

% (now option to avoid this and just return Cmod for speed up)

4655

% (now option to avoid this and just return Cmod for speed up)

4665

if return_V

4656

if return_V

4666

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4657

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4667

else

4658

else

4668

Vfiltered=[];

4659

Vfiltered=[];

4669

end

4660

end

4670

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4661

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4671

% used for FD IL fitting

4662

% used for FD IL fitting

4672

% sdd21 us a complex insertion loss

4663

% sdd21 us a complex insertion loss

4673

db = @(x) 20*log10(abs(x));

4664

db = @(x) 20*log10(abs(x));

4674

sdd21=squeeze(sdd21);

4665

sdd21=squeeze(sdd21);

4675

if iscolumn(sdd21)

4666

if iscolumn(sdd21)

4676

sdd21=sdd21.';

4667

sdd21=sdd21.';

4677

end

4668

end

4678

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)) ];

4669

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)) ];

4679

warning('off','MATLAB:nearlySingularMatrix');

4670

warning('off','MATLAB:nearlySingularMatrix');

4680

LGw=transpose(abs(sdd21).*db(sdd21));

4671

LGw=transpose(abs(sdd21).*db(sdd21));

4681

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4672

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4682

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4673

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4683

ILN = db(sdd21)-efit;

4674

ILN = db(sdd21)-efit;

4684

4675

4685

4676

4686

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4677

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4687

% Complex IL fitting

4678

% Complex IL fitting

4688

% sdd21 us a complex insertion loss

4679

% sdd21 us a complex insertion loss

4689

% efit and ILN are in db

4680

% efit and ILN are in db

4690

% faxix_f2 needs to be at least to fb

4681

% faxix_f2 needs to be at least to fb

4691

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4682

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4692

% still need to settle on voltage scaling.

4683

% still need to settle on voltage scaling.

4693

% maybe db(peak/Rss

4684

% maybe db(peak/Rss

4694

4685

4695

OP.interp_sparam_mag= 'trend_to_DC';

4686

OP.interp_sparam_mag= 'trend_to_DC';

4696

OP.interp_sparam_phase= 'interp_to_DC';

4687

OP.interp_sparam_phase= 'interp_to_DC';

4697

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4688

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4698

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4689

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4699

4690

4700

print_for_codereview=0;

4691

print_for_codereview=0;

4701

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

4692

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

4702

A_T=1;

4693

A_T=1;

4703

end

4694

end

4704

4695

4705

db = @(x) 20*log10(abs(x));

4696

db = @(x) 20*log10(abs(x));

4706

sdd21=squeeze(sdd21);

4697

sdd21=squeeze(sdd21);

4707

if iscolumn(sdd21)

4698

if iscolumn(sdd21)

4708

sdd21=sdd21.';

4699

sdd21=sdd21.';

4709

end

4700

end

4710

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) ];

4701

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) ];

4711

warning('off','MATLAB:nearlySingularMatrix');

4702

warning('off','MATLAB:nearlySingularMatrix');

4712

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4703

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4713

LGw=transpose(sdd21.*unwraplog);

4704

LGw=transpose(sdd21.*unwraplog);

4714

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4705

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4715

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4706

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4716

FIT=transpose(exp(transpose(efit_C)));

4707

FIT=transpose(exp(transpose(efit_C)));

4717

efit=db(abs(FIT));

4708

efit=db(abs(FIT));

4718

ILN = db(sdd21)-efit;

4709

ILN = db(sdd21)-efit;

4719

% time domain

4710

% time domain

4720

fprintf('computing TD_ILN (dB) ...')

4711

fprintf('computing TD_ILN (dB) ...')

4721

if exist('OP','var')

4712

if exist('OP','var')

4722

% OP.fraction_of_F_range_start_extrap_from=.95;

4713

% OP.fraction_of_F_range_start_extrap_from=.95;

4723

OP.impulse_response_truncation_threshold =1e-7;

4714

OP.impulse_response_truncation_threshold =1e-7;

4724

4715

4725

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4716

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4726

H_bw=Butterworth_Filter(param,faxis_f2,1);

4717

H_bw=Butterworth_Filter(param,faxis_f2,1);

4727

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4718

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4728

H_tw=Tukey_Window(faxis_f2,param);

4719

H_tw=Tukey_Window(faxis_f2,param);

4729

H_tw=ones(1,length(faxis_f2) );

4720

H_tw=ones(1,length(faxis_f2) );

4730

4721

4731

[TD_ILN.REF.FIR, ...

4722

[TD_ILN.REF.FIR, ...

4732

TD_ILN.REF.t, ...

4723

TD_ILN.REF.t, ...

4733

TD_ILN.REF.causality_correction_dB, ...

4724

TD_ILN.REF.causality_correction_dB, ...

4734

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4725

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4735

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4726

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4736

4727

4737

[TD_ILN.FIT.FIR, ...

4728

[TD_ILN.FIT.FIR, ...

4738

TD_ILN.FIT.t, ...

4729

TD_ILN.FIT.t, ...

4739

TD_ILN.FIT.causality_correction_dB, ...

4730

TD_ILN.FIT.causality_correction_dB, ...

4740

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4731

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4741

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4732

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4742

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4733

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4743

% NrangeUI=1000;

4734

% NrangeUI=1000;

4744

% 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);

4735

% 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);

4745

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4736

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4746

range=ipeak:range_end;

4737

range=ipeak:range_end;

4747

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4738

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4748

TD_ILN.t=TD_ILN.FIT.t(range);

4739

TD_ILN.t=TD_ILN.FIT.t(range);

4749

TD_ILN.FOM=-inf;

4740

TD_ILN.FOM=-inf;

4750

TD_ILN.FOM_PDF=-inf;

4741

TD_ILN.FOM_PDF=-inf;

4751

rms_fom=-inf;

4742

rms_fom=-inf;

4752

for im=1:param.samples_per_ui

4743

for im=1:param.samples_per_ui

4753

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4744

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4754

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4745

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4755

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4746

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4756

cdf=pdf; cdf.y=cumsum(pdf.y);

4747

cdf=pdf; cdf.y=cumsum(pdf.y);

4757

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4748

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4758

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4749

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4759

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4750

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4760

if print_for_codereview % remove once all checked out

4751

if print_for_codereview % remove once all checked out

4761

h=figure(190);set(gcf,'Tag','COM');

4752

h=figure(190);set(gcf,'Tag','COM');

4762

semilogy(-cdf.x,cdf.y);

4753

semilogy(-cdf.x,cdf.y);

4763

% xlim ([0,-cdf.x(1)])

4754

% xlim ([0,-cdf.x(1)])

4764

ylim([param.specBER 1]);title ('CDF of ILN')

4755

ylim([param.specBER 1]);title ('CDF of ILN')

4765

hold on

4756

hold on

4766

end

4757

end

4767

if rms>rms_fom

4758

if rms>rms_fom

4768

rms_fom=rms;

4759

rms_fom=rms;

4769

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4760

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

4770

TD_ILN.PDF=pdf;

4761

TD_ILN.PDF=pdf;

4771

end

4762

end

4772

end

4763

end

4773

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4764

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

4774

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4765

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

4775

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4766

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

4776

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4767

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

4777

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4768

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

4778

if print_for_codereview % remove once all checked out

4769

if print_for_codereview % remove once all checked out

4779

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

4770

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

4780

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4771

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

4781

hold on

4772

hold on

4782

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4773

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

4783

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4774

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

4784

hold off

4775

hold off

4785

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)

4776

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)

4786

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

4777

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

4787

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4778

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

4788

hold on

4779

hold on

4789

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4780

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

4790

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4781

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

4791

grid on

4782

grid on

4792

legend('show')

4783

legend('show')

4793

end

4784

end

4794

end

4785

end

4795

% display('got to end of get_ILN_cmp_td')

4786

% display('got to end of get_ILN_cmp_td')

4796

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4787

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

4797

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4788

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

4798

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4789

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

4799

if 1 % force indent for doc

4790

if 1 % force indent for doc

4800

num_ui=param.num_ui_RXFF_noise;

4791

num_ui=param.num_ui_RXFF_noise;

4801

M=param.samples_per_ui;

4792

M=param.samples_per_ui;

4802

L=param.levels;

4793

L=param.levels;

4803

f_b=param.fb;

4794

f_b=param.fb;

4804

SNR_TX=param.SNR_TX;

4795

SNR_TX=param.SNR_TX;

4805

dw=param.RxFFE_cmx;

4796

dw=param.RxFFE_cmx;

4806

bmax=param.bmax;

4797

bmax=param.bmax;

4807

bmin=param.bmin ;

4798

bmin=param.bmin ;

4808

Nb=param.ndfe;

4799

Nb=param.ndfe;

4809

sigma_X2=(L^2-1)/(3*(L-1)^2);

4800

sigma_X2=(L^2-1)/(3*(L-1)^2);

4810

eta_0=param.eta_0; %V^2/GHz

4801

eta_0=param.eta_0; %V^2/GHz

4811

T_b=1/f_b;

4802

T_b=1/f_b;

4812

delta_f = f_b/num_ui; % Units are Hz.

4803

delta_f = f_b/num_ui; % Units are Hz.

4813

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4804

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

4814

result.fvec=fvec;

4805

result.fvec=fvec;

4815

end

4806

end

4816

if OP.COMPUTE_COM

4807

if OP.COMPUTE_COM

4817

%% H_rxffe eq 178A-28 d1.0

4808

%% H_rxffe eq 178A-28 d1.0

4818

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4809

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

4819

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4810

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

4820

H_rxffe=0;

4811

H_rxffe=0;

4821

for nn=1:length(result.w)

4812

for nn=1:length(result.w)

4822

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4813

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

4823

end

4814

end

4824

H_rxffe_2_of_f=abs(H_rxffe).^2;

4815

H_rxffe_2_of_f=abs(H_rxffe).^2;

4825

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4816

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

4826

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))];

4817

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))];

4827

else

4818

else

4828

H_rxffe_2=1;

4819

H_rxffe_2=1;

4829

end

4820

end

4830

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

4821

result.H_rxffe_2=H_rxffe_2;% pass as output for compuation in healey_3dj_01_2409 slide 12

4831

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4822

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

4832

% --->this is the point in the code may fork where we add extra rx noise

4823

% --->this is the point in the code may fork where we add extra rx noise

4833

%% compute S_rn ( eq 178A-15 d0.2 )

4824

%% compute S_rn ( eq 178A-15 d0.2 )

4834

if ~OP.COMPUTE_COM

4825

if ~OP.COMPUTE_COM

4835

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4826

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

4836

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

4827

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

4837

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4828

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

4838

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4829

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

4839

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4830

S_rn = sum(reshape(rxn_psd, num_ui, M).');

4840

S_rn=S_rn(1:num_ui/2+1);

4831

S_rn=S_rn(1:num_ui/2+1);

4841

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4832

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

4842

result.S_rn=S_rn;

4833

result.S_rn=S_rn;

4843

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4834

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4844

else

4835

else

4845

result.S_rn=result.S_rn.*H_rxffe_2;

4836

result.S_rn=result.S_rn.*H_rxffe_2;

4846

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4837

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

4847

end

4838

end

4848

4839

4849

else % find noise for item that set have tx ffe for each loop

4840

else % find noise for item that set have tx ffe for each loop

4850

%% S_xn from eq 178A-16

4841

%% S_xn from eq 178A-16

4851

%% Crosstalk power spectral density

4842

%% Crosstalk power spectral density

4852

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4843

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

4853

result.S_xn=0;

4844

result.S_xn=0;

4854

if length(chdata)~=1

4845

if length(chdata)~=1

4855

for xchan=2:length(chdata)

4846

for xchan=2:length(chdata)

4856

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4847

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

4857

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4848

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

4858

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4849

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

4859

% enable less UI for computation speed improvement

4850

% enable less UI for computation speed improvement

4860

%%

4851

%%

4861

if num_ui*M > length(pulse_ctle)

4852

if num_ui*M > length(pulse_ctle)

4862

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4853

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

4863

else

4854

else

4864

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4855

hk(xchan).k=hk(xchan).k(1:num_ui*M);

4865

end

4856

end

4866

for i1=1:M

4857

for i1=1:M

4867

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4858

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

4868

end

4859

end

4869

iphase(xchan)=find(hxn==max(hxn));

4860

iphase(xchan)=find(hxn==max(hxn));

4870

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4861

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

4871

result.hk(xchan).hrn= hk(xchan).hrn;

4862

result.hk(xchan).hrn= hk(xchan).hrn;

4872

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4863

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

4873

result.S_xn=hk(xchan).S_xn+result.S_xn;

4864

result.S_xn=hk(xchan).S_xn+result.S_xn;

4874

end

4865

end

4875

result.S_xn=result.S_xn;

4866

result.S_xn=result.S_xn;

4876

result.hk=hk;

4867

result.hk=hk;

4877

result.iphase=iphase;

4868

result.iphase=iphase;

4878

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4869

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4879

else % if no crosstalk, perserve structure and return 0 for S_xn

4870

else % if no crosstalk, perserve structure and return 0 for S_xn

4880

result.S_xn=0;

4871

result.S_xn=0;

4881

result.hk=[];

4872

result.hk=[];

4882

result.iphase=1;

4873

result.iphase=1;

4883

result.S_xn_rms = 0;

4874

result.S_xn_rms = 0;

4884

end

4875

end

4885

else % adjust for H_rxffe when computing COM

4876

else % adjust for H_rxffe when computing COM

4886

result.S_xn=result.S_xn.*H_rxffe_2;

4877

result.S_xn=result.S_xn.*H_rxffe_2;

4887

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4878

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

4888

end

4879

end

4889

%% S_tn from eq 178A-17

4880

%% S_tn from eq 178A-17

4890

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4881

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

4891

%% Transmitter noise power spectral density

4882

%% Transmitter noise power spectral density

4892

if ~OP.COMPUTE_COM

4883

if ~OP.COMPUTE_COM

4893

if ~OP.TDMODE

4884

if ~OP.TDMODE

4894

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4885

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

4895

else % only use when the input was a pulse response not s-parameters

4886

else % only use when the input was a pulse response not s-parameters

4896

if isfield(chdata(1),'ctle_pulse_response')

4887

if isfield(chdata(1),'ctle_pulse_response')

4897

htn=chdata(1).ctle_pulse_response;

4888

htn=chdata(1).ctle_pulse_response;

4898

else

4889

else

4899

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4890

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

4900

end

4891

end

4901

end

4892

end

4902

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4893

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

4903

htn=reshape(htn,1,[]); % make row vectors

4894

htn=reshape(htn,1,[]); % make row vectors

4904

htn=[ htn(1:floor(length(htn)/M)*M) ];

4895

htn=[ htn(1:floor(length(htn)/M)*M) ];

4905

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4896

htn= [htn zeros(1,num_ui*M-length(htn)) ];

4906

htn=htn(1:M:end);% resample

4897

htn=htn(1:M:end);% resample

4907

if num_ui>length(htn)

4898

if num_ui>length(htn)

4908

hext=[htn zeros(1,num_ui-length(htn))];

4899

hext=[htn zeros(1,num_ui-length(htn))];

4909

else

4900

else

4910

hext=htn(1:num_ui);

4901

hext=htn(1:num_ui);

4911

end

4902

end

4912

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4903

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

4913

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4904

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4914

else

4905

else

4915

result.S_tn=result.S_tn.*H_rxffe_2;

4906

result.S_tn=result.S_tn.*H_rxffe_2;

4916

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4907

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

4917

end

4908

end

4918

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4909

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

4919

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4910

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

4920

%% Power spectral density of noise due to jitter

4911

%% Power spectral density of noise due to jitter

4921

%% Eq. 93A-28 %%

4912

%% Eq. 93A-28 %%

4922

if ~OP.COMPUTE_COM

4913

if ~OP.COMPUTE_COM

4923

sampling_offset = mod(cursor_i, M);

4914

sampling_offset = mod(cursor_i, M);

4924

%ensure we can take early sample

4915

%ensure we can take early sample

4925

if sampling_offset<=1

4916

if sampling_offset<=1

4926

sampling_offset=sampling_offset+M;

4917

sampling_offset=sampling_offset+M;

4927

end

4918

end

4928

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4919

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

4929

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4920

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

4930

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4921

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

4931

else

4922

else

4932

cursors_early_sample = h(sampling_offset-1:M:end);

4923

cursors_early_sample = h(sampling_offset-1:M:end);

4933

cursors_late_sample = h(sampling_offset+1:M:end);

4924

cursors_late_sample = h(sampling_offset+1:M:end);

4934

end

4925

end

4935

% ensure lengths are equal

4926

% ensure lengths are equal

4936

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4927

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

4937

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4928

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

4938

h_J=reshape(h_J,1,[]); % make row vectors

4929

h_J=reshape(h_J,1,[]); % make row vectors

4939

if num_ui>length(h_J)

4930

if num_ui>length(h_J)

4940

h_J=[h_J zeros(1,num_ui-length(h_J))];

4931

h_J=[h_J zeros(1,num_ui-length(h_J))];

4941

else

4932

else

4942

h_J=h_J(1:num_ui);

4933

h_J=h_J(1:num_ui);

4943

end

4934

end

4944

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4935

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4945

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4936

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4946

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4937

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

4947

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4938

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4948

else

4939

else

4949

result.S_jn=result.S_jn.*H_rxffe_2;

4940

result.S_jn=result.S_jn.*H_rxffe_2;

4950

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4941

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

4951

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4942

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

4952

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4943

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

4953

end

4944

end

4954

% result.S_qn

4945

% result.S_qn

4955

if(param.ENOB ~=0)

4946

if(param.ENOB ~=0)

4956

if OP.INCLUDE_CTLE == 1

4947

if OP.INCLUDE_CTLE == 1

4957

eq_ir = TD_CTLE(chdata(1).uneq_imp_response, param.fb, param.CTLE_fz(1), param.CTLE_fp1(1), param.CTLE_fp2(1), G_DC, param.samples_per_ui);

4948

eq_ir = TD_CTLE(chdata(1).uneq_imp_response, param.fb, param.CTLE_fz(1), param.CTLE_fp1(1), param.CTLE_fp2(1), G_DC, param.samples_per_ui);

4958

eq_ir = TD_CTLE(eq_ir, param.fb, param.f_HP(1), param.f_HP(1), 100e100 , G_DC2, param.samples_per_ui);

4949

eq_ir = TD_CTLE(eq_ir, param.fb, param.f_HP(1), param.f_HP(1), 100e100 , G_DC2, param.samples_per_ui);

4959

else

4950

else

4960

eq_ir = chdata(1).uneq_imp_response;

4951

eq_ir = chdata(1).uneq_imp_response;

4961

end

4952

end

4962

ctle_pulse = filter(ones(1, param.samples_per_ui), 1, eq_ir);

4953

ctle_pulse = filter(ones(1, param.samples_per_ui), 1, eq_ir);

4963

ind_max = find(ctle_pulse == max(ctle_pulse));

4954

ind_max = find(ctle_pulse == max(ctle_pulse));

4964

adc_clip = sum(abs([ctle_pulse(ind_max-param.samples_per_ui:-param.samples_per_ui:1); ctle_pulse(ind_max:param.samples_per_ui:end)]));

4955

adc_clip = sum(abs([ctle_pulse(ind_max-param.samples_per_ui:-param.samples_per_ui:1); ctle_pulse(ind_max:param.samples_per_ui:end)]));

4965

adc_lsb = 2*adc_clip/(2^param.ENOB-1);

4956

adc_lsb = 2*adc_clip/(2^param.ENOB-1);

4966

sigma_Q = adc_lsb/sqrt(12);

4957

sigma_Q = adc_lsb/sqrt(12);

4967

S_qn = sigma_Q^2/(length(result.S_rn)*delta_f)*ones(size(result.S_rn));

4958

S_qn = sigma_Q^2/(length(result.S_rn)*delta_f)*ones(size(result.S_rn));

4968

result.S_qn = S_qn;

4959

result.S_qn = S_qn;

4969

result.qn_rms = sqrt(sum(result.S_qn)* delta_f);

4960

result.qn_rms = sqrt(sum(result.S_qn)* delta_f);

4970

else

4961

else

4971

result.S_qn=0;

4962

result.S_qn=0;

4972

result.S_qn_rms = 0;

4963

result.S_qn_rms = 0;

4973

% result.S_n

4964

% result.S_n

4974

end

4965

end

4975

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn+ result.S_qn;

4966

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn+ result.S_qn;

4976

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4967

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

4977

4968

4978

%%

4969

%%

4979

%% Hisi to be included in MLSE rho eq 178a-28

4970

%% Hisi to be included in MLSE rho eq 178a-28

4980

if OP.COMPUTE_COM

4971

if OP.COMPUTE_COM

4981

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4972

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

4982

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4973

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

4983

% hisi=h(sampling_offset:M:end);

4974

% hisi=h(sampling_offset:M:end);

4984

% hisi=hisi(:).';

4975

% hisi=hisi(:).';

4985

% if num_ui>length(hisi)

4976

% if num_ui>length(hisi)

4986

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4977

% hisi=[hisi zeros(1,num_ui-length(hisi))];

4987

% else

4978

% else

4988

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

4979

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

4989

% end

4980

% end

4990

% cursor_n=find(hisi==max(hisi),1','first');

4981

% cursor_n=find(hisi==max(hisi),1','first');

4991

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

4982

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

4992

cursor_n=find(samp_idx == cursor_i);

4983

cursor_n=find(samp_idx == cursor_i);

4993

hisi=h(samp_idx);

4984

hisi=h(samp_idx);

4994

hisi(end+1:num_ui)=0;

4985

hisi(end+1:num_ui)=0;

4995

hisi=reshape(hisi(1:num_ui),1,[]);

4986

hisi=reshape(hisi(1:num_ui),1,[]);

4996

%% Eq 178a-29

4987

%% Eq 178a-29

4997

for ii=1:length(hisi)

4988

for ii=1:length(hisi)

4998

if ii==cursor_n % cursor

4989

if ii==cursor_n % cursor

4999

cursor=hisi(ii);

4990

cursor=hisi(ii);

5000

hisi(ii)= 0;

4991

hisi(ii)= 0;

5001

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

4992

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5002

ib_indx=ii-cursor_n;

4993

ib_indx=ii-cursor_n;

5003

if hisi(ii) >= bmax(ib_indx)*cursor

4994

if hisi(ii) >= bmax(ib_indx)*cursor

5004

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

4995

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5005

elseif hisi(ii) <= bmin(ib_indx)*cursor

4996

elseif hisi(ii) <= bmin(ib_indx)*cursor

5006

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

4997

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5007

else

4998

else

5008

hisi(ii)=0;

4999

hisi(ii)=0;

5009

end

5000

end

5010

end

5001

end

5011

end

5002

end

5012

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5003

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5013

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5004

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5014

%%

5005

%%

5015

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5006

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5016

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5007

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5017

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5008

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5018

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5009

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5019

end

5010

end

5020

end

5011

end

5021

function result=get_PulseR(ir,param,cb_step,ZT)

5012

function result=get_PulseR(ir,param,cb_step,ZT)

5022

%ir = impulse response

5013

%ir = impulse response

5023

%t_base=time array with equal time steps

5014

%t_base=time array with equal time steps

5024

%samp_UI = number of samples per UI for ir

5015

%samp_UI = number of samples per UI for ir

5025

5016

5026

% t for debug

5017

% t for debug

5027

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5018

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5028

5019

5029

if cb_step

5020

if cb_step

5030

Ag=1;

5021

Ag=1;

5031

dt=1/param.fb/param.samples_per_ui;

5022

dt=1/param.fb/param.samples_per_ui;

5032

edge_time=param.TR_TDR*1e-9;

5023

edge_time=param.TR_TDR*1e-9;

5033

fedge=1/edge_time;

5024

fedge=1/edge_time;

5034

tedge=0:dt:edge_time*2;

5025

tedge=0:dt:edge_time*2;

5035

%

5026

%

5036

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5027

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5037

drive_pulse=[edge ones(1,param.samples_per_ui)];

5028

drive_pulse=[edge ones(1,param.samples_per_ui)];

5038

%pulse=filter(UI_ones,1,ir);

5029

%pulse=filter(UI_ones,1,ir);

5039

% t for debug

5030

% t for debug

5040

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5031

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5041

5032

5042

pulse=filter(drive_pulse,1,ir);

5033

pulse=filter(drive_pulse,1,ir);

5043

else

5034

else

5044

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5035

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5045

end

5036

end

5046

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5037

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5047

result.PDR=PDR_response;

5038

result.PDR=PDR_response;

5048

result.pulse=pulse;

5039

result.pulse=pulse;

5049

5040

5050

5041

5051

5042

5052

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5043

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5053

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

5044

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

5054

if ~iscolumn(H), H=H.';end

5045

if ~iscolumn(H), H=H.';end

5055

if ~iscolumn(H_r), H_r=H_r.';end

5046

if ~iscolumn(H_r), H_r=H_r.';end

5056

H=H(:).*H_r;

5047

H=H(:).*H_r;

5057

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5048

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5058

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5049

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5059

5050

5060

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5051

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5061

% Complex reflection and re-reflection noise using the concept of zero'ing

5052

% Complex reflection and re-reflection noise using the concept of zero'ing

5062

% out of reflections

5053

% out of reflections

5063

% sdd21 us a complex insertion loss

5054

% sdd21 us a complex insertion loss

5064

% RIL_struct is the output of capture_RIL_RILN()

5055

% RIL_struct is the output of capture_RIL_RILN()

5065

% faxix_f2 needs to be at least to fb

5056

% faxix_f2 needs to be at least to fb

5066

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5057

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5067

% still need to settle on voltage scaling.

5058

% still need to settle on voltage scaling.

5068

% maybe db(peak/Rss

5059

% maybe db(peak/Rss

5069

db = @(x) 20*log10(abs(x));

5060

db = @(x) 20*log10(abs(x));

5070

fprintf('computing TD_RILN (dB) ...');

5061

fprintf('computing TD_RILN (dB) ...');

5071

5062

5072

OP.interp_sparam_mag= 'trend_to_DC';

5063

OP.interp_sparam_mag= 'trend_to_DC';

5073

OP.interp_sparam_phase= 'interp_to_DC';

5064

OP.interp_sparam_phase= 'interp_to_DC';

5074

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5065

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5075

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5066

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5076

5067

5077

sdd21=squeeze(sdd21);

5068

sdd21=squeeze(sdd21);

5078

if iscolumn(sdd21)

5069

if iscolumn(sdd21)

5079

sdd21=sdd21.';

5070

sdd21=sdd21.';

5080

end

5071

end

5081

RIL=squeeze(RIL_struct.RIL);

5072

RIL=squeeze(RIL_struct.RIL);

5082

if iscolumn(RIL)

5073

if iscolumn(RIL)

5083

RIL=RIL.';

5074

RIL=RIL.';

5084

end

5075

end

5085

rho_port1=squeeze(RIL_struct.rho_port1);

5076

rho_port1=squeeze(RIL_struct.rho_port1);

5086

if iscolumn(rho_port1)

5077

if iscolumn(rho_port1)

5087

rho_port1=rho_port1.';

5078

rho_port1=rho_port1.';

5088

end

5079

end

5089

rho_port2=squeeze(RIL_struct.rho_port2);

5080

rho_port2=squeeze(RIL_struct.rho_port2);

5090

if iscolumn(rho_port2)

5081

if iscolumn(rho_port2)

5091

rho_port2=rho_port2.';

5082

rho_port2=rho_port2.';

5092

end

5083

end

5093

RIL_f=squeeze(RIL_struct.freq);

5084

RIL_f=squeeze(RIL_struct.freq);

5094

if iscolumn(RIL_f)

5085

if iscolumn(RIL_f)

5095

RIL_f=RIL_f.';

5086

RIL_f=RIL_f.';

5096

end

5087

end

5097

5088

5098

%---start. Calculate the reflection and re-reflection noise

5089

%---start. Calculate the reflection and re-reflection noise

5099

number_of_echos= 1e3;

5090

number_of_echos= 1e3;

5100

fmin= 1e9;%<-------------

5091

fmin= 1e9;%<-------------

5101

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5092

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5102

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5093

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5103

for m= 1:number_of_echos

5094

for m= 1:number_of_echos

5104

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);

5095

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);

5105

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);

5096

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);

5106

end

5097

end

5107

5098

5108

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5099

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5109

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5100

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5110

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5101

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5111

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5102

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5112

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5103

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5113

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5104

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5114

5105

5115

% clear RIL RIL_f rho_port1 rho_port2

5106

% clear RIL RIL_f rho_port1 rho_port2

5116

% clear fmin m

5107

% clear fmin m

5117

%---end. Calculate the reflection and re-reflection noise

5108

%---end. Calculate the reflection and re-reflection noise

5118

5109

5119

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) ];

5110

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) ];

5120

warning('off','MATLAB:nearlySingularMatrix');

5111

warning('off','MATLAB:nearlySingularMatrix');

5121

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5112

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5122

LGw=transpose(sdd21.*unwraplog);

5113

LGw=transpose(sdd21.*unwraplog);

5123

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5114

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5124

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5115

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5125

FIT=transpose(exp(transpose(efit_C)));

5116

FIT=transpose(exp(transpose(efit_C)));

5126

efit=db(abs(FIT));

5117

efit=db(abs(FIT));

5127

ILN = db(sdd21)-efit;

5118

ILN = db(sdd21)-efit;

5128

5119

5129

5120

5130

OP.impulse_response_truncation_threshold =1e-7;

5121

OP.impulse_response_truncation_threshold =1e-7;

5131

5122

5132

print_for_codereview=0;

5123

print_for_codereview=0;

5133

if exist('OP','var')

5124

if exist('OP','var')

5134

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5125

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5135

H_bw=Butterworth_Filter(param,faxis_f2,1);

5126

H_bw=Butterworth_Filter(param,faxis_f2,1);

5136

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5127

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5137

H_tw=Tukey_Window(faxis_f2,param);

5128

H_tw=Tukey_Window(faxis_f2,param);

5138

H_tw=ones(1,length(faxis_f2) );

5129

H_tw=ones(1,length(faxis_f2) );

5139

[RILN_TD_struct.REF.FIR, ...

5130

[RILN_TD_struct.REF.FIR, ...

5140

RILN_TD_struct.REF.t, ...

5131

RILN_TD_struct.REF.t, ...

5141

RILN_TD_struct.REF.causality_correction_dB, ...

5132

RILN_TD_struct.REF.causality_correction_dB, ...

5142

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5133

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5143

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5134

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5144

5135

5145

5136

5146

[RILN_TD_struct.FIT.FIR, ...

5137

[RILN_TD_struct.FIT.FIR, ...

5147

RILN_TD_struct.FIT.t, ...

5138

RILN_TD_struct.FIT.t, ...

5148

RILN_TD_struct.FIT.causality_correction_dB, ...

5139

RILN_TD_struct.FIT.causality_correction_dB, ...

5149

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5140

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5150

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5141

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5151

5142

5152

5143

5153

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5144

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5154

H_bw=Butterworth_Filter(param,RIL_f,1);

5145

H_bw=Butterworth_Filter(param,RIL_f,1);

5155

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5146

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5156

H_tw=Tukey_Window(RIL_f,param);

5147

H_tw=Tukey_Window(RIL_f,param);

5157

H_tw=ones(1,length(RIL_f) );

5148

H_tw=ones(1,length(RIL_f) );

5158

[RILN_TD_struct.RIL.FIR, ...

5149

[RILN_TD_struct.RIL.FIR, ...

5159

RILN_TD_struct.RIL.t, ...

5150

RILN_TD_struct.RIL.t, ...

5160

RILN_TD_struct.RIL.causality_correction_dB, ...

5151

RILN_TD_struct.RIL.causality_correction_dB, ...

5161

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5152

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5162

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5153

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5163

5154

5164

5155

5165

%---start. Calculate the channel delay

5156

%---start. Calculate the channel delay

5166

try

5157

try

5167

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5158

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5168

catch

5159

catch

5169

end

5160

end

5170

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5161

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5171

clear delay_sec delay_idx

5162

clear delay_sec delay_idx

5172

%---end. Calculate the channel delay

5163

%---end. Calculate the channel delay

5173

5164

5174

5165

5175

5166

5176

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5167

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5177

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5168

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5178

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5169

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5179

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5170

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5180

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5171

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5181

[RILN_TD_struct.REF_noise.FIR, ...

5172

[RILN_TD_struct.REF_noise.FIR, ...

5182

RILN_TD_struct.REF_noise.t, ...

5173

RILN_TD_struct.REF_noise.t, ...

5183

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5174

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5184

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) ;

5175

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) ;

5185

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5176

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5186

5177

5187

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5178

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5188

% NrangeUI=1000;

5179

% NrangeUI=1000;

5189

% 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);

5180

% 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);

5190

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5181

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5191

range=ipeak:range_end;

5182

range=ipeak:range_end;

5192

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5183

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5193

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5184

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5194

RILN_TD_struct.FOM=-inf;

5185

RILN_TD_struct.FOM=-inf;

5195

RILN_TD_struct.FOM_PDF=-inf;

5186

RILN_TD_struct.FOM_PDF=-inf;

5196

rms_fom=-inf;

5187

rms_fom=-inf;

5197

for im=1:param.samples_per_ui

5188

for im=1:param.samples_per_ui

5198

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5189

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5199

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5190

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5200

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5191

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5201

cdf=pdf; cdf.y=cumsum(pdf.y);

5192

cdf=pdf; cdf.y=cumsum(pdf.y);

5202

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5193

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5203

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5194

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5204

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5195

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5205

if print_for_codereview % remove once all checked out

5196

if print_for_codereview % remove once all checked out

5206

h=figure(190);set(gcf,'Tag','COM');

5197

h=figure(190);set(gcf,'Tag','COM');

5207

semilogy(-cdf.x,cdf.y);

5198

semilogy(-cdf.x,cdf.y);

5208

% xlim ([0,-cdf.x(1)])

5199

% xlim ([0,-cdf.x(1)])

5209

ylim([param.specBER 1]);title ('CDF of ILN')

5200

ylim([param.specBER 1]);title ('CDF of ILN')

5210

hold on

5201

hold on

5211

end

5202

end

5212

if rms>rms_fom

5203

if rms>rms_fom

5213

rms_fom=rms;

5204

rms_fom=rms;

5214

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5205

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5215

RILN_TD_struct.PDF=pdf;

5206

RILN_TD_struct.PDF=pdf;

5216

end

5207

end

5217

end

5208

end

5218

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5209

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5219

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5210

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5220

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5211

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5221

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5212

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5222

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5213

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5223

if print_for_codereview % remove once all checked out

5214

if print_for_codereview % remove once all checked out

5224

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

5215

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

5225

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5216

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5226

hold on

5217

hold on

5227

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5218

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5228

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5219

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5229

yyaxis right

5220

yyaxis right

5230

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5221

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5231

hold off

5222

hold off

5232

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)

5223

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)

5233

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

5224

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

5234

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5225

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5235

hold on

5226

hold on

5236

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5227

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5237

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5228

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5238

grid on

5229

grid on

5239

legend('show')

5230

legend('show')

5240

end

5231

end

5241

end

5232

end

5242

function result=get_StepR(ir,param,cb_step,ZT)

5233

function result=get_StepR(ir,param,cb_step,ZT)

5243

%ir = impulse response

5234

%ir = impulse response

5244

%t_base=time array with equal time steps

5235

%t_base=time array with equal time steps

5245

%samp_UI = number of samples per UI for ir

5236

%samp_UI = number of samples per UI for ir

5246

% result.SBR

5237

% result.SBR

5247

% t for debug

5238

% t for debug

5248

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5239

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5249

5240

5250

if cb_step

5241

if cb_step

5251

Ag=1;

5242

Ag=1;

5252

dt=1/param.fb/param.samples_per_ui;

5243

dt=1/param.fb/param.samples_per_ui;

5253

edge_time=param.TR_TDR*1e-9;

5244

edge_time=param.TR_TDR*1e-9;

5254

fedge=1/edge_time;

5245

fedge=1/edge_time;

5255

tedge=0:dt:edge_time*2;

5246

tedge=0:dt:edge_time*2;

5256

%

5247

%

5257

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5248

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5258

drive_pulse=[edge ones(1,param.samples_per_ui)];

5249

drive_pulse=[edge ones(1,param.samples_per_ui)];

5259

%pulse=filter(UI_ones,1,ir);

5250

%pulse=filter(UI_ones,1,ir);

5260

5251

5261

pulse=filter(drive_pulse,1,ir);

5252

pulse=filter(drive_pulse,1,ir);

5262

else

5253

else

5263

pulse=cumsum(ir);

5254

pulse=cumsum(ir);

5264

end

5255

end

5265

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5256

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5266

result.ZSR=TDR_response;

5257

result.ZSR=TDR_response;

5267

result.pulse=pulse;

5258

result.pulse=pulse;

5268

5259

5269

5260

5270

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5261

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5271

% sdd is differential s-parameters structure (2 port assumed)

5262

% sdd is differential s-parameters structure (2 port assumed)

5272

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5263

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5273

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5264

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5274

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5265

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5275

% TDR_results.t starting at t=0

5266

% TDR_results.t starting at t=0

5276

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5267

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5277

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5268

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5278

% TDR_results.f frequency for filter and s parameters

5269

% TDR_results.f frequency for filter and s parameters

5279

% TDR_results.ptdr_RL reflection waveform from the pulse

5270

% TDR_results.ptdr_RL reflection waveform from the pulse

5280

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5271

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5281

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5272

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5282

% TDR_results.ERL reported effective return loss

5273

% TDR_results.ERL reported effective return loss

5283

%

5274

%

5284

db = @(x) 20*log10(abs(x));

5275

db = @(x) 20*log10(abs(x));

5285

rms =@(x) norm(x)/sqrt(length(x));

5276

rms =@(x) norm(x)/sqrt(length(x));

5286

if isfield(OP,'TDR_duration')

5277

if isfield(OP,'TDR_duration')

5287

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5278

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5288

else

5279

else

5289

TDR_duration=5;

5280

TDR_duration=5;

5290

end

5281

end

5291

if ~isfield(OP,'DISPLAY_WINDOW')

5282

if ~isfield(OP,'DISPLAY_WINDOW')

5292

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5283

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5293

end

5284

end

5294

f=sdd.Frequencies;

5285

f=sdd.Frequencies;

5295

TDR_results.f=f;

5286

TDR_results.f=f;

5296

% OP.Zt_adj=2;

5287

% OP.Zt_adj=2;

5297

if param.FLAG.S2P == 0

5288

if param.FLAG.S2P == 0

5298

5289

5299

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5290

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5300

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);

5291

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);

5301

5292

5302

if param.RL_sel==1, other_port=2;end

5293

if param.RL_sel==1, other_port=2;end

5303

if param.RL_sel==2, other_port=1;end

5294

if param.RL_sel==2, other_port=1;end

5304

for i = 1:length(sdd.Frequencies)

5295

for i = 1:length(sdd.Frequencies)

5305

if size(sdd.Parameters,2) ==1 % for s2p files

5296

if size(sdd.Parameters,2) ==1 % for s2p files

5306

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) );

5297

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) );

5307

else

5298

else

5308

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) );

5299

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) );

5309

end

5300

end

5310

end

5301

end

5311

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5302

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5312

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5303

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5313

% Z_t=ZT;

5304

% Z_t=ZT;

5314

% zref=sdd.Impedance/2;

5305

% zref=sdd.Impedance/2;

5315

% if Z_t > zref

5306

% if Z_t > zref

5316

% radjust= (zref-Z_t);

5307

% radjust= (zref-Z_t);

5317

% S11adjust= radjust./(radjust + 2*zref);

5308

% S11adjust= radjust./(radjust + 2*zref);

5318

% RL=RL +S11adjust;

5309

% RL=RL +S11adjust;

5319

% elseif Z_t < zref

5310

% elseif Z_t < zref

5320

% rpad=-Z_t*zref/(Z_t-zref);

5311

% rpad=-Z_t*zref/(Z_t-zref);

5321

% S11adjust=zref/(rpad*(zref/rpad + 2));

5312

% S11adjust=zref/(rpad*(zref/rpad + 2));

5322

% RL=RL + S11adjust;

5313

% RL=RL + S11adjust;

5323

% else

5314

% else

5324

% RL=RL;

5315

% RL=RL;

5325

% end

5316

% end

5326

else

5317

else

5327

for i = 1:length(sdd.Frequencies)

5318

for i = 1:length(sdd.Frequencies)

5328

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5319

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5329

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5320

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5330

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5321

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5331

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5322

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5332

end

5323

end

5333

end

5324

end

5334

5325

5335

% end

5326

% end

5336

RL=squeeze(RL);

5327

RL=squeeze(RL);

5337

f9=f/1e9;

5328

f9=f/1e9;

5338

tr=param.TR_TDR;

5329

tr=param.TR_TDR;

5339

TDR_results.delay=500e-12 ;

5330

TDR_results.delay=500e-12 ;

5340

% determine max time from thue

5331

% determine max time from thue

5341

% if sdd.NumPorts==1

5332

% if sdd.NumPorts==1

5342

% try

5333

% try

5343

% maxtime=OP.N*param.ui;

5334

% maxtime=OP.N*param.ui;

5344

% catch

5335

% catch

5345

% maxtime=2e-9;

5336

% maxtime=2e-9;

5346

% end

5337

% end

5347

% pix=1;

5338

% pix=1;

5348

% else

5339

% else

5349

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5340

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5350

% pix=find(fir4del==max(fir4del),1);

5341

% pix=find(fir4del==max(fir4del),1);

5351

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5342

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5352

% if maxtime > tu(end); maxtime=tu(end);end

5343

% if maxtime > tu(end); maxtime=tu(end);end

5353

% endS

5344

% endS

5354

5345

5355

try

5346

try

5356

maxtime=OP.N*param.ui;

5347

maxtime=OP.N*param.ui;

5357

catch

5348

catch

5358

maxtime=2e-9;

5349

maxtime=2e-9;

5359

end

5350

end

5360

if OP.N==0

5351

if OP.N==0

5361

if sdd.NumPorts==1

5352

if sdd.NumPorts==1

5362

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5353

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5363

else

5354

else

5364

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5355

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5365

pix=find(fir4del==max(fir4del),1);

5356

pix=find(fir4del==max(fir4del),1);

5366

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5357

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5367

if maxtime > tu(end); maxtime=tu(end);end

5358

if maxtime > tu(end); maxtime=tu(end);end

5368

end

5359

end

5369

end

5360

end

5370

5361

5371

5362

5372

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5363

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5373

% (makes gausian edge somewhat causal)

5364

% (makes gausian edge somewhat causal)

5374

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);

5365

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);

5375

if ~isfield(OP,'cb_Guassian')

5366

if ~isfield(OP,'cb_Guassian')

5376

Use_gaussian=1;

5367

Use_gaussian=1;

5377

else

5368

else

5378

Use_gaussian=OP.cb_Guassian;

5369

Use_gaussian=OP.cb_Guassian;

5379

end

5370

end

5380

if Use_gaussian

5371

if Use_gaussian

5381

if iscolumn(H_t), H_t=H_t.'; end

5372

if iscolumn(H_t), H_t=H_t.'; end

5382

RLf=RL(:).'.*H_t;

5373

RLf=RL(:).'.*H_t;

5383

else % add extra 3x tr delay for causality

5374

else % add extra 3x tr delay for causality

5384

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5375

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5385

end

5376

end

5386

5377

5387

%Bessesl-Thomson turned off here (3rd input=0)

5378

%Bessesl-Thomson turned off here (3rd input=0)

5388

OP.TDR_Bessel_Thomson=0;

5379

OP.TDR_Bessel_Thomson=0;

5389

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5380

H_bt=Bessel_Thomson_Filter(param,f,OP.TDR_Bessel_Thomson);

5390

5381

5391

if isfield(OP,'TDR_Butterworth')

5382

if isfield(OP,'TDR_Butterworth')

5392

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5383

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5393

else

5384

else

5394

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

5385

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

5395

end

5386

end

5396

5387

5397

5388

5398

if param.Tukey_Window ~= 0

5389

if param.Tukey_Window ~= 0

5399

H_tw= Tukey_Window(f,param);

5390

H_tw= Tukey_Window(f,param);

5400

else

5391

else

5401

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

5392

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

5402

end

5393

end

5403

5394

5404

5395

5405

if iscolumn(H_tw), H_tw=H_tw.';end

5396

if iscolumn(H_tw), H_tw=H_tw.';end

5406

if iscolumn(H_bt), H_bt=H_bt.';end

5397

if iscolumn(H_bt), H_bt=H_bt.';end

5407

if iscolumn(H_bw), H_bw=H_bw.';end

5398

if iscolumn(H_bw), H_bw=H_bw.';end

5408

if iscolumn(RLf), RLf=RLf.';end

5399

if iscolumn(RLf), RLf=RLf.';end

5409

5400

5410

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5401

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5411

RLf=RLf.*TDR_results.Rx_filter;

5402

RLf=RLf.*TDR_results.Rx_filter;

5412

TDR_results.tx_filter=H_t;

5403

TDR_results.tx_filter=H_t;

5413

5404

5414

5405

5415

[IR, t, causality_correction_dB, truncation_dB] = ...

5406

[IR, t, causality_correction_dB, truncation_dB] = ...

5416

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5407

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5417

5408

5418

5409

5419

%

5410

%

5420

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5411

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5421

tfx=param.tfx(np); % use fixture delay for port (np)

5412

tfx=param.tfx(np); % use fixture delay for port (np)

5422

5413

5423

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5414

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5424

5415

5425

t = t-TDR_results.delay;

5416

t = t-TDR_results.delay;

5426

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5417

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5427

if isempty(tend), tend=length(t); end

5418

if isempty(tend), tend=length(t); end

5428

IR=IR(1:tend);

5419

IR=IR(1:tend);

5429

t=t(1:tend);

5420

t=t(1:tend);

5430

if isempty(tend), tend=length(t); end

5421

if isempty(tend), tend=length(t); end

5431

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5422

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5432

if isempty(tstart), tstart=1;end

5423

if isempty(tstart), tstart=1;end

5433

if isempty(tend) || tstart >= tend

5424

if isempty(tend) || tstart >= tend

5434

if isempty(tend) || tstart >= tend

5425

if isempty(tend) || tstart >= tend

5435

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5426

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5436

end

5427

end

5437

tend=length(t);

5428

tend=length(t);

5438

tstart=1;

5429

tstart=1;

5439

end

5430

end

5440

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5431

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5441

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5432

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5442

TDR_results.tdr= ch.ZSR;

5433

TDR_results.tdr= ch.ZSR;

5443

TDR_results.t = t(tstart:tend);

5434

TDR_results.t = t(tstart:tend);

5444

5435

5445

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5436

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5446

if OP.TDR || OP.PTDR % determin average impededance with

5437

if OP.TDR || OP.PTDR % determin average impededance with

5447

try

5438

try

5448

tfstart=find(t>=3*tr*1e-9,1);

5439

tfstart=find(t>=3*tr*1e-9,1);

5449

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5440

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5450

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5441

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5451

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5442

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5452

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5443

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5453

catch

5444

catch

5454

TDR_results.avgZport=0;

5445

TDR_results.avgZport=0;

5455

fit=zeros(1,1);

5446

fit=zeros(1,1);

5456

p=[0 0 0 0 ];

5447

p=[0 0 0 0 ];

5457

end

5448

end

5458

TDR_results.RL=RL;

5449

TDR_results.RL=RL;

5459

end

5450

end

5460

if OP.PTDR

5451

if OP.PTDR

5461

% param.N_bx=param.ndfe;

5452

% param.N_bx=param.ndfe;

5462

RL_equiv=-inf;

5453

RL_equiv=-inf;

5463

L=param.levels;

5454

L=param.levels;

5464

BinSize=OP.BinSize;

5455

BinSize=OP.BinSize;

5465

% param.specBER=1e-5;

5456

% param.specBER=1e-5;

5466

if OP.DISPLAY_WINDOW

5457

if OP.DISPLAY_WINDOW

5467

hwaitbar=waitbar(0);

5458

hwaitbar=waitbar(0);

5468

else

5459

else

5469

fprintf('Worst ERL searching');

5460

fprintf('Worst ERL searching');

5470

end

5461

end

5471

% adjust PTDR for NDFE

5462

% adjust PTDR for NDFE

5472

% ---------------------- 2.7 code

5463

% ---------------------- 2.7 code

5473

% ntx=find(TDR_results.t >= tfx,1,'first');

5464

% ntx=find(TDR_results.t >= tfx,1,'first');

5474

% % gatestartt=TDR_results.t(ntx);

5465

% % gatestartt=TDR_results.t(ntx);

5475

% % gatestartV=PTDR.pulse(ntx);

5466

% % gatestartV=PTDR.pulse(ntx);

5476

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5467

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5477

% tk=param.ui*1*(param.N_bx+1)+tfx;

5468

% tk=param.ui*1*(param.N_bx+1)+tfx;

5478

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

5469

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

5479

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5470

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5480

% time filter.

5471

% time filter.

5481

% ntx=find(TDR_results.t >= tfx,1,'first');

5472

% ntx=find(TDR_results.t >= tfx,1,'first');

5482

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5473

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5483

% gatestartt=TDR_results.t(ntx);

5474

% gatestartt=TDR_results.t(ntx);

5484

% gatestartV=PTDR.pulse(ntx);

5475

% gatestartV=PTDR.pulse(ntx);

5485

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5476

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5486

% tk=param.ui*1*(param.N_bx+1)+tfx;

5477

% tk=param.ui*1*(param.N_bx+1)+tfx;

5487

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5478

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5488

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5479

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5489

% [ahealey] End of modifications.

5480

% [ahealey] End of modifications.

5490

if isempty(ndfex), ndfex=length(TDR_results.t); end

5481

if isempty(ndfex), ndfex=length(TDR_results.t); end

5491

PTDR.pulse_orig=PTDR.pulse;

5482

PTDR.pulse_orig=PTDR.pulse;

5492

5483

5493

switch param.Grr

5484

switch param.Grr

5494

case 0 % pre .3cd release

5485

case 0 % pre .3cd release

5495

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5486

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5496

case 1 % .3cd release

5487

case 1 % .3cd release

5497

fctrx(1:length(PTDR.pulse_orig))=1;

5488

fctrx(1:length(PTDR.pulse_orig))=1;

5498

case 2 % .3ck working

5489

case 2 % .3ck working

5499

fctrx(1:length(PTDR.pulse_orig))=1;

5490

fctrx(1:length(PTDR.pulse_orig))=1;

5500

end

5491

end

5501

Gloss(1:length(TDR_results.t))=1;

5492

Gloss(1:length(TDR_results.t))=1;

5502

Grr(1:length(TDR_results.t))=1;

5493

Grr(1:length(TDR_results.t))=1;

5503

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5494

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5504

5495

5505

for ii=ntx:ndfex

5496

for ii=ntx:ndfex

5506

% adjust for near end loss

5497

% adjust for near end loss

5507

if param.N_bx>0 && param.beta_x~=0;

5498

if param.N_bx>0 && param.beta_x~=0;

5508

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5499

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5509

else

5500

else

5510

Gloss(ii)=1;

5501

Gloss(ii)=1;

5511

end

5502

end

5512

% ---------------------- 2.7 code

5503

% ---------------------- 2.7 code

5513

% x=(TDR_results.t(ii)-tfx)/param.ui;

5504

% x=(TDR_results.t(ii)-tfx)/param.ui;

5514

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

5505

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

5515

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5506

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5516

% rise time filter.

5507

% rise time filter.

5517

% x=(TDR_results.t(ii)-tfx)/param.ui;

5508

% x=(TDR_results.t(ii)-tfx)/param.ui;

5518

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5509

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5519

% determine how much of the return loss to use base on expected

5510

% determine how much of the return loss to use base on expected

5520

% missing reflections

5511

% missing reflections

5521

switch param.Grr

5512

switch param.Grr

5522

case 0 % pre .3cd release

5513

case 0 % pre .3cd release

5523

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5514

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5524

case 1 % .3cd release

5515

case 1 % .3cd release

5525

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5516

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5526

case 2 % .3ck working

5517

case 2 % .3ck working

5527

Grr(ii)= param.rho_x ;

5518

Grr(ii)= param.rho_x ;

5528

end

5519

end

5529

fctrx(ii)=Gloss(ii).*Grr(ii);

5520

fctrx(ii)=Gloss(ii).*Grr(ii);

5530

end

5521

end

5531

5522

5532

if isrow(fctrx), fctrx=fctrx(:);end

5523

if isrow(fctrx), fctrx=fctrx(:);end

5533

PTDR.pulse=PTDR.pulse.*fctrx;

5524

PTDR.pulse=PTDR.pulse.*fctrx;

5534

if 0

5525

if 0

5535

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5526

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5536

s1=subplot(2,1,1);

5527

s1=subplot(2,1,1);

5537

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5528

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5538

hold on

5529

hold on

5539

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5530

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5540

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5531

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5541

grid on

5532

grid on

5542

ylim([ 0 1.2])

5533

ylim([ 0 1.2])

5543

s2=subplot(2,1,2);

5534

s2=subplot(2,1,2);

5544

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5535

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5545

grid on

5536

grid on

5546

linkaxes([s1,s2],'x')

5537

linkaxes([s1,s2],'x')

5547

xlabel 'UI'

5538

xlabel 'UI'

5548

xlim ([ 1 200])

5539

xlim ([ 1 200])

5549

end

5540

end

5550

5541

5551

FAST_NOISE_CONV=0;

5542

FAST_NOISE_CONV=0;

5552

ERLRMS=rms(PTDR.pulse);

5543

ERLRMS=rms(PTDR.pulse);

5553

for ki=1:param.samples_per_ui

5544

for ki=1:param.samples_per_ui

5554

progress = ki/param.samples_per_ui;

5545

progress = ki/param.samples_per_ui;

5555

if OP.DISPLAY_WINDOW

5546

if OP.DISPLAY_WINDOW

5556

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5547

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5557

else

5548

else

5558

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5549

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5559

end

5550

end

5560

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5551

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5561

if OP.RL_norm_test

5552

if OP.RL_norm_test

5562

rl_fom=(norm(tps));

5553

rl_fom=(norm(tps));

5563

else

5554

else

5564

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5555

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5565

cdf_test=cumsum(testpdf.y);

5556

cdf_test=cumsum(testpdf.y);

5566

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5557

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5567

rl_fom=rl_test;

5558

rl_fom=rl_test;

5568

end

5559

end

5569

if rl_fom > RL_equiv

5560

if rl_fom > RL_equiv

5570

RL_equiv=rl_fom;

5561

RL_equiv=rl_fom;

5571

best_ki=ki;

5562

best_ki=ki;

5572

end

5563

end

5573

if ~OP.RL_norm_test

5564

if ~OP.RL_norm_test

5574

best_erl=rl_test;

5565

best_erl=rl_test;

5575

best_pdf=testpdf;

5566

best_pdf=testpdf;

5576

best_cdf=cdf_test;

5567

best_cdf=cdf_test;

5577

end

5568

end

5578

5569

5579

end

5570

end

5580

if OP.RL_norm_test

5571

if OP.RL_norm_test

5581

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5572

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5582

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5573

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5583

cdf_test=cumsum(testpdf.y);

5574

cdf_test=cumsum(testpdf.y);

5584

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5575

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5585

end

5576

end

5586

5577

5587

fprintf('\n');

5578

fprintf('\n');

5588

try

5579

try

5589

close(hwaitbar)

5580

close(hwaitbar)

5590

catch

5581

catch

5591

end

5582

end

5592

if ~exist('best_ki','var'),best_ki=1;end

5583

if ~exist('best_ki','var'),best_ki=1;end

5593

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5584

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5594

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5585

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5595

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5586

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5596

TDR_results.ERL=-db(best_erl);

5587

TDR_results.ERL=-db(best_erl);

5597

TDR_results.ERLRMS=-db(ERLRMS);

5588

TDR_results.ERLRMS=-db(ERLRMS);

5598

5589

5599

end

5590

end

5600

5591

5601

5592

5602

% end get TDR

5593

% end get TDR

5603

%%

5594

%%

5604

5595

5605

5596

5606

5597

5607

5598

5608

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5599

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5609

% filename parsing and acquisition

5600

% filename parsing and acquisition

5610

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

5601

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

5611

%----------put files names into chdata structure ---------

5602

%----------put files names into chdata structure ---------

5612

% The thru file has the index of 1

5603

% The thru file has the index of 1

5613

% crosstalk file are indexed from 2

5604

% crosstalk file are indexed from 2

5614

% nxi is incremented each time a file is read in so that nxi will end

5605

% nxi is incremented each time a file is read in so that nxi will end

5615

filepath=[]; % path name for file

5606

filepath=[]; % path name for file

5616

nxi=0; % file index

5607

nxi=0; % file index

5617

% get the THRU file

5608

% get the THRU file

5618

if size(file_list,2) ~= 0

5609

if size(file_list,2) ~= 0

5619

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5610

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5620

[filepath, basename, fileext]=fileparts(file_list{1});

5611

[filepath, basename, fileext]=fileparts(file_list{1});

5621

5612

5622

else

5613

else

5623

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5614

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5624

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5615

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5625

movegui(h,'northeast')

5616

movegui(h,'northeast')

5626

end

5617

end

5627

dir=fullfile(filepath, '*.csv');

5618

dir=fullfile(filepath, '*.csv');

5628

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5619

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5629

if filepath == 0

5620

if filepath == 0

5630

error('No Thru file')

5621

error('No Thru file')

5631

end

5622

end

5632

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5623

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5633

end

5624

end

5634

nxi=nxi+1;

5625

nxi=nxi+1;

5635

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5626

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5636

chdata(nxi).ext = fileext;

5627

chdata(nxi).ext = fileext;

5637

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5628

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5638

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5629

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5639

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5630

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5640

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5631

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5641

chdata(nxi).type='THRU';

5632

chdata(nxi).type='THRU';

5642

chdata(nxi).ftr=param.fb*param.f_v;

5633

chdata(nxi).ftr=param.fb*param.f_v;

5643

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5634

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5644

5635

5645

% now get FEXT file names into chdata structure

5636

% now get FEXT file names into chdata structure

5646

kxi=nxi;

5637

kxi=nxi;

5647

for nxi=kxi+1:num_fext+kxi

5638

for nxi=kxi+1:num_fext+kxi

5648

lastfilepath=filepath;

5639

lastfilepath=filepath;

5649

if size(file_list,2) ~= 0

5640

if size(file_list,2) ~= 0

5650

[filepath, basename, fileext]=fileparts(file_list{nxi});

5641

[filepath, basename, fileext]=fileparts(file_list{nxi});

5651

else

5642

else

5652

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5643

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5653

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5644

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5654

movegui(h,'northeast')

5645

movegui(h,'northeast')

5655

end

5646

end

5656

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

5647

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

5657

dir=fullfile(filepath, '*.csv');

5648

dir=fullfile(filepath, '*.csv');

5658

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5649

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5659

if filepath==0

5650

if filepath==0

5660

error('Not enough NEXT files')

5651

error('Not enough NEXT files')

5661

end

5652

end

5662

else

5653

else

5663

dir=fullfile(filepath, '*.csv');

5654

dir=fullfile(filepath, '*.csv');

5664

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5655

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5665

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5656

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5666

else

5657

else

5667

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5658

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5668

end

5659

end

5669

if filepath==0

5660

if filepath==0

5670

error('Not enough NEXT files')

5661

error('Not enough NEXT files')

5671

end

5662

end

5672

end

5663

end

5673

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5664

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5674

end

5665

end

5675

if isempty( filepath), filepath=lastfilepath; end

5666

if isempty( filepath), filepath=lastfilepath; end

5676

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5667

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5677

chdata(nxi).ext = fileext;

5668

chdata(nxi).ext = fileext;

5678

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5669

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5679

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5670

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5680

% chdata(nxi).A=param.a_fext;

5671

% chdata(nxi).A=param.a_fext;

5681

chdata(nxi).ftr=param.fb*param.f_f;

5672

chdata(nxi).ftr=param.fb*param.f_f;

5682

chdata(nxi).type='FEXT';

5673

chdata(nxi).type='FEXT';

5683

end

5674

end

5684

% now get NEXT file names into chdata structure

5675

% now get NEXT file names into chdata structure

5685

kxi=num_fext+kxi;

5676

kxi=num_fext+kxi;

5686

for nxi=kxi+1:num_next+kxi

5677

for nxi=kxi+1:num_next+kxi

5687

lastfilepath=filepath;

5678

lastfilepath=filepath;

5688

if size(file_list,2) ~= 0

5679

if size(file_list,2) ~= 0

5689

[filepath, basename, fileext]=fileparts(file_list{nxi});

5680

[filepath, basename, fileext]=fileparts(file_list{nxi});

5690

else

5681

else

5691

dir=fullfile(filepath, '*.csv');

5682

dir=fullfile(filepath, '*.csv');

5692

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5683

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5693

if filepath==0

5684

if filepath==0

5694

error('Not enough NEXT files')

5685

error('Not enough NEXT files')

5695

end

5686

end

5696

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5687

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5697

end

5688

end

5698

if isempty( filepath), filepath=lastfilepath; end

5689

if isempty( filepath), filepath=lastfilepath; end

5699

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5690

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5700

chdata(nxi).ext = fileext;

5691

chdata(nxi).ext = fileext;

5701

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5692

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5702

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5693

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5703

% chdata(nxi).A=param.A_next;

5694

% chdata(nxi).A=param.A_next;

5704

chdata(nxi).ftr=param.fb*param.f_n;

5695

chdata(nxi).ftr=param.fb*param.f_n;

5705

chdata(nxi).type='NEXT';

5696

chdata(nxi).type='NEXT';

5706

end

5697

end

5707

function half_UI=get_center_of_UI(samples_per_UI)

5698

function half_UI=get_center_of_UI(samples_per_UI)

5708

5699

5709

%half_UI reveals which value to use for the center of the UI. For eye

5700

%half_UI reveals which value to use for the center of the UI. For eye

5710

%width calculations, it is necessary to place the cursor in the center of the

5701

%width calculations, it is necessary to place the cursor in the center of the

5711

%UI window to ensure a 0 crossing on both left/right inside the window.

5702

%UI window to ensure a 0 crossing on both left/right inside the window.

5712

%This function was written in order to support even and odd samples_per_UI

5703

%This function was written in order to support even and odd samples_per_UI

5713

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5704

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5714

5705

5715

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5706

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5716

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5707

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5717

%the center of the UI is sample closest to 0.5

5708

%the center of the UI is sample closest to 0.5

5718

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5709

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5719

function results= get_cm_noise(M,PR,L,BER,OP)

5710

function results= get_cm_noise(M,PR,L,BER,OP)

5720

5711

5721

if ~exist('OP')

5712

if ~exist('OP')

5722

OP.DC_norm_test=0;

5713

OP.DC_norm_test=0;

5723

OP.DISPLAY_WINDOW=1;

5714

OP.DISPLAY_WINDOW=1;

5724

end

5715

end

5725

param.BinSize=1e-5;

5716

param.BinSize=1e-5;

5726

PR_test=-inf;

5717

PR_test=-inf;

5727

PR_fom_best=-inf;

5718

PR_fom_best=-inf;

5728

% hwaitbar=waitbar(0);

5719

% hwaitbar=waitbar(0);

5729

for ki=1:M

5720

for ki=1:M

5730

progress = ki/M;

5721

progress = ki/M;

5731

% if OP.DISPLAY_WINDOW

5722

% if OP.DISPLAY_WINDOW

5732

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5723

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5733

% else

5724

% else

5734

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5725

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5735

% end

5726

% end

5736

tps=PR(ki:M:end);

5727

tps=PR(ki:M:end);

5737

if OP.DC_norm_test

5728

if OP.DC_norm_test

5738

PR_fom=(norm(tps));

5729

PR_fom=(norm(tps));

5739

else

5730

else

5740

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5731

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5741

cdf_test=cumsum(testpdf.y);

5732

cdf_test=cumsum(testpdf.y);

5742

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5733

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5743

PR_fom=PRn_test;

5734

PR_fom=PRn_test;

5744

end

5735

end

5745

if PR_fom > PR_fom_best

5736

if PR_fom > PR_fom_best

5746

PR_fom_best=PR_fom;

5737

PR_fom_best=PR_fom;

5747

best_ki=ki;

5738

best_ki=ki;

5748

end

5739

end

5749

if ~OP.DC_norm_test

5740

if ~OP.DC_norm_test

5750

results.DCn=PR_fom_best;

5741

results.DCn=PR_fom_best;

5751

results.DCn_pdf=testpdf;

5742

results.DCn_pdf=testpdf;

5752

results.DCn_cdf=cdf_test;

5743

results.DCn_cdf=cdf_test;

5753

else

5744

else

5754

results.DCn=PR_fom_best;

5745

results.DCn=PR_fom_best;

5755

end

5746

end

5756

results.DCn_p2p=max(PR)-min(PR);

5747

results.DCn_p2p=max(PR)-min(PR);

5757

end

5748

end

5758

5749

5759

5750

5760

5751

5761

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5752

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5762

SBR=chdata.eq_pulse_response(:)'; % row vector

5753

SBR=chdata.eq_pulse_response(:)'; % row vector

5763

type=chdata.type;

5754

type=chdata.type;

5764

samp_UI=param.samples_per_ui;

5755

samp_UI=param.samples_per_ui;

5765

residual_response = SBR;

5756

residual_response = SBR;

5766

5757

5767

if isequal(type, 'THRU')

5758

if isequal(type, 'THRU')

5768

% for thru pulse response:

5759

% for thru pulse response:

5769

% remove the cursor and the DFE postcursors (up to their limit), since

5760

% remove the cursor and the DFE postcursors (up to their limit), since

5770

% we only care about the residuals.

5761

% we only care about the residuals.

5771

5762

5772

if ~param.Floating_DFE

5763

if ~param.Floating_DFE

5773

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5764

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5774

else

5765

else

5775

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5766

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5776

end

5767

end

5777

if param.dfe_delta ~= 0

5768

if param.dfe_delta ~= 0

5778

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);

5769

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);

5779

else

5770

else

5780

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5771

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5781

end

5772

end

5782

5773

5783

%AJG021820

5774

%AJG021820

5784

if ~param.Floating_DFE

5775

if ~param.Floating_DFE

5785

bmax_vec=residual_response(t_s)*[1,param.bmax];

5776

bmax_vec=residual_response(t_s)*[1,param.bmax];

5786

bmin_vec=residual_response(t_s)*[1,param.bmin];

5777

bmin_vec=residual_response(t_s)*[1,param.bmin];

5787

else

5778

else

5788

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5779

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

5789

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5780

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

5790

end

5781

end

5791

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5782

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5792

5783

5793

5784

5794

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5785

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

5795

dfetaps=effective_cancelled_cursors/SBR(t_s);

5786

dfetaps=effective_cancelled_cursors/SBR(t_s);

5796

5787

5797

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5788

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5798

% really needed for COM, but helps debugging. May be factored out in future revisions.

5789

% really needed for COM, but helps debugging. May be factored out in future revisions.

5799

start_cancel = t_s-param.samples_per_ui/2;

5790

start_cancel = t_s-param.samples_per_ui/2;

5800

if ~param.Floating_DFE

5791

if ~param.Floating_DFE

5801

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5792

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

5802

else

5793

else

5803

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5794

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

5804

end

5795

end

5805

residual_response(start_cancel:end_cancel) = ...

5796

residual_response(start_cancel:end_cancel) = ...

5806

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5797

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5807

%else

5798

%else

5808

% for crosstalk pulse responses, nothing is cancelled, and all phases

5799

% for crosstalk pulse responses, nothing is cancelled, and all phases

5809

% are equally important.

5800

% are equally important.

5810

end

5801

end

5811

5802

5812

nui=round(length(residual_response)/param.samples_per_ui);

5803

nui=round(length(residual_response)/param.samples_per_ui);

5813

5804

5814

vs=zeros(nui-2, param.samples_per_ui);

5805

vs=zeros(nui-2, param.samples_per_ui);

5815

for i=1:param.samples_per_ui

5806

for i=1:param.samples_per_ui

5816

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5807

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

5817

end

5808

end

5818

5809

5819

if OP.DISPLAY_WINDOW,

5810

if OP.DISPLAY_WINDOW,

5820

hwaitbar=waitbar(0);

5811

hwaitbar=waitbar(0);

5821

end

5812

end

5822

5813

5823

% determine which pdf to use

5814

% determine which pdf to use

5824

if isequal(type, 'THRU')

5815

if isequal(type, 'THRU')

5825

% one phase is interesting for thru

5816

% one phase is interesting for thru

5826

phases = mod(t_s,param.samples_per_ui);

5817

phases = mod(t_s,param.samples_per_ui);

5827

if phases==0, phases = param.samples_per_ui; end

5818

if phases==0, phases = param.samples_per_ui; end

5828

else

5819

else

5829

phases=1:samp_UI;

5820

phases=1:samp_UI;

5830

end

5821

end

5831

5822

5832

mxV = zeros(size(phases));

5823

mxV = zeros(size(phases));

5833

% we already found the phase in the PSD process for MMSE

5824

% we already found the phase in the PSD process for MMSE

5834

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

5825

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

5835

if isequal(type, 'THRU')

5826

if isequal(type, 'THRU')

5836

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5827

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

5837

else

5828

else

5838

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5829

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

5839

end

5830

end

5840

else

5831

else

5841

for k=phases

5832

for k=phases

5842

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5833

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

5843

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5834

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

5844

progress = k/length(phases);

5835

progress = k/length(phases);

5845

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5836

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

5846

end

5837

end

5847

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5838

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

5848

pdf=pdf_samples(pxi);

5839

pdf=pdf_samples(pxi);

5849

end

5840

end

5850

5841

5851

5842

5852

5843

5853

if OP.DISPLAY_WINDOW

5844

if OP.DISPLAY_WINDOW

5854

close(hwaitbar);

5845

close(hwaitbar);

5855

end

5846

end

5856

5847

5857

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5848

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

5858

% Create PDF from interference vector using successive delta-set convolutions.

5849

% Create PDF from interference vector using successive delta-set convolutions.

5859

% input_vector = list of values of samples

5850

% input_vector = list of values of samples

5860

% return

5851

% return

5861

% pdf.x

5852

% pdf.x

5862

% pdf.y

5853

% pdf.y

5863

% pdf.vec

5854

% pdf.vec

5864

% pdf.bin

5855

% pdf.bin

5865

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

5856

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

5866

FAST_NOISE_CONV=0;

5857

FAST_NOISE_CONV=0;

5867

end

5858

end

5868

if max(input_vector) > BinSize

5859

if max(input_vector) > BinSize

5869

input_vector=input_vector(abs(input_vector)>BinSize);

5860

input_vector=input_vector(abs(input_vector)>BinSize);

5870

end

5861

end

5871

% for i = 1:length(input_vector)

5862

% for i = 1:length(input_vector)

5872

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5863

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

5873

%end

5864

%end

5874

5865

5875

input_vector(abs(input_vector)<BinSize) = 0;

5866

input_vector(abs(input_vector)<BinSize) = 0;

5876

b=sign(input_vector);

5867

b=sign(input_vector);

5877

[input_vector,index]=sort(abs(input_vector),'descend');

5868

[input_vector,index]=sort(abs(input_vector),'descend');

5878

input_vector=input_vector.*b(index);

5869

input_vector=input_vector.*b(index);

5879

if FAST_NOISE_CONV

5870

if FAST_NOISE_CONV

5880

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5871

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

5881

res_pdf= normal_dist(sig_res,5,BinSize);

5872

res_pdf= normal_dist(sig_res,5,BinSize);

5882

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5873

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

5883

end

5874

end

5884

%% Equation 93A-39 %%

5875

%% Equation 93A-39 %%

5885

values = 2*(0:L-1)/(L-1)-1;

5876

values = 2*(0:L-1)/(L-1)-1;

5886

prob = ones(1,L)/L;

5877

prob = ones(1,L)/L;

5887

5878

5888

%% Initialize pdf to delta at 0

5879

%% Initialize pdf to delta at 0

5889

pdf=d_cpdf(BinSize, 0, 1);

5880

pdf=d_cpdf(BinSize, 0, 1);

5890

empty_pdf=pdf;

5881

empty_pdf=pdf;

5891

for k = 1:length(input_vector)

5882

for k = 1:length(input_vector)

5892

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5883

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

5893

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5884

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

5894

pdf=conv_fct(pdf, pdfn);

5885

pdf=conv_fct(pdf, pdfn);

5895

end

5886

end

5896

if FAST_NOISE_CONV

5887

if FAST_NOISE_CONV

5897

% pdf=conv_fct(pdf,res_pdf);

5888

% pdf=conv_fct(pdf,res_pdf);

5898

pdf=conv_fct_TEST(pdf,res_pdf);

5889

pdf=conv_fct_TEST(pdf,res_pdf);

5899

end

5890

end

5900

5891

5901

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5892

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

5902

t_s_orig=t_s;

5893

t_s_orig=t_s;

5903

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5894

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

5904

type=chdata.type;

5895

type=chdata.type;

5905

5896

5906

pulse_orig=chdata.eq_pulse_response(:)';

5897

pulse_orig=chdata.eq_pulse_response(:)';

5907

%build arbitrary time axis with step size = 1/samples per ui

5898

%build arbitrary time axis with step size = 1/samples per ui

5908

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5899

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

5909

%force t_s at time =0 (makes the other things below easy)

5900

%force t_s at time =0 (makes the other things below easy)

5910

original_sample_time=old_time(t_s_orig);

5901

original_sample_time=old_time(t_s_orig);

5911

old_time=old_time-original_sample_time;

5902

old_time=old_time-original_sample_time;

5912

%build new time axis that forces time=0 to be in the axis

5903

%build new time axis that forces time=0 to be in the axis

5913

%unless the new/old samples per UI are integer ratios, time 0 will not be

5904

%unless the new/old samples per UI are integer ratios, time 0 will not be

5914

%there by default

5905

%there by default

5915

samp_UI=param.samples_for_C2M;

5906

samp_UI=param.samples_for_C2M;

5916

new_timea=[0:-1/samp_UI:min(old_time)];

5907

new_timea=[0:-1/samp_UI:min(old_time)];

5917

new_timeb=[0:1/samp_UI:max(old_time)];

5908

new_timeb=[0:1/samp_UI:max(old_time)];

5918

new_time=[fliplr(new_timea) new_timeb(2:end)];

5909

new_time=[fliplr(new_timea) new_timeb(2:end)];

5919

SBR=interp1(old_time,pulse_orig,new_time);

5910

SBR=interp1(old_time,pulse_orig,new_time);

5920

%new sample time is simply the point where new_time = 0

5911

%new sample time is simply the point where new_time = 0

5921

[tmp,t_s]=min(abs(new_time));

5912

[tmp,t_s]=min(abs(new_time));

5922

5913

5923

residual_response = SBR;

5914

residual_response = SBR;

5924

5915

5925

half_UI=get_center_of_UI(samp_UI);

5916

half_UI=get_center_of_UI(samp_UI);

5926

5917

5927

if isequal(type, 'THRU')

5918

if isequal(type, 'THRU')

5928

% for thru pulse response:

5919

% for thru pulse response:

5929

% remove the cursor and the DFE postcursors (up to their limit), since

5920

% remove the cursor and the DFE postcursors (up to their limit), since

5930

% we only care about the residuals.

5921

% we only care about the residuals.

5931

5922

5932

%AJG021820

5923

%AJG021820

5933

if ~param.Floating_DFE

5924

if ~param.Floating_DFE

5934

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5925

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

5935

else

5926

else

5936

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5927

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

5937

end

5928

end

5938

if param.dfe_delta ~= 0

5929

if param.dfe_delta ~= 0

5939

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);

5930

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);

5940

else

5931

else

5941

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5932

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5942

end

5933

end

5943

5934

5944

if ~param.Floating_DFE

5935

if ~param.Floating_DFE

5945

bmax_vec=residual_response(t_s)*[param.bmax];

5936

bmax_vec=residual_response(t_s)*[param.bmax];

5946

bmin_vec=residual_response(t_s)*[param.bmin];

5937

bmin_vec=residual_response(t_s)*[param.bmin];

5947

else

5938

else

5948

bmax_vec=residual_response(t_s)*[param.use_bmax];

5939

bmax_vec=residual_response(t_s)*[param.use_bmax];

5949

bmin_vec=residual_response(t_s)*[param.use_bmin];

5940

bmin_vec=residual_response(t_s)*[param.use_bmin];

5950

end

5941

end

5951

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5942

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

5952

5943

5953

5944

5954

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5945

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

5955

dfetaps=effective_cancelled_cursors/SBR(t_s);

5946

dfetaps=effective_cancelled_cursors/SBR(t_s);

5956

5947

5957

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5948

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

5958

% really needed for COM, but helps debugging. May be factored out in future revisions.

5949

% really needed for COM, but helps debugging. May be factored out in future revisions.

5959

5950

5960

%avoid dividing samp_UI by 2 in case it is not even

5951

%avoid dividing samp_UI by 2 in case it is not even

5961

start_cancel=t_s-half_UI+1+samp_UI;

5952

start_cancel=t_s-half_UI+1+samp_UI;

5962

%AJG021820

5953

%AJG021820

5963

if ~param.Floating_DFE

5954

if ~param.Floating_DFE

5964

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5955

end_cancel=start_cancel+param.ndfe*samp_UI-1;

5965

else

5956

else

5966

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5957

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

5967

end

5958

end

5968

residual_response(start_cancel:end_cancel) = ...

5959

residual_response(start_cancel:end_cancel) = ...

5969

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5960

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

5970

%else

5961

%else

5971

% for crosstalk pulse responses, nothing is cancelled, and all phases

5962

% for crosstalk pulse responses, nothing is cancelled, and all phases

5972

% are equally important.

5963

% are equally important.

5973

5964

5974

%remove entire cursor UI

5965

%remove entire cursor UI

5975

uiv_start=start_cancel-samp_UI;

5966

uiv_start=start_cancel-samp_UI;

5976

uiv_end=uiv_start+samp_UI-1;

5967

uiv_end=uiv_start+samp_UI-1;

5977

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5968

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

5978

residual_response(uiv_start:uiv_end)=0;

5969

residual_response(uiv_start:uiv_end)=0;

5979

end

5970

end

5980

5971

5981

nui=round(length(residual_response)/samp_UI);

5972

nui=round(length(residual_response)/samp_UI);

5982

5973

5983

5974

5984

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5975

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5985

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5976

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

5986

%response without DFE included. (Can't include DFE for jitter calc)

5977

%response without DFE included. (Can't include DFE for jitter calc)

5987

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5978

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

5988

5979

5989

% if OP.DISPLAY_WINDOW,

5980

% if OP.DISPLAY_WINDOW,

5990

% hwaitbar=waitbar(0);

5981

% hwaitbar=waitbar(0);

5991

% end

5982

% end

5992

5983

5993

% determine which pdf to use

5984

% determine which pdf to use

5994

if isequal(type, 'THRU')

5985

if isequal(type, 'THRU')

5995

% one phase is interesting for thru

5986

% one phase is interesting for thru

5996

phases = mod(t_s,samp_UI);

5987

phases = mod(t_s,samp_UI);

5997

if phases==0, phases = samp_UI; end

5988

if phases==0, phases = samp_UI; end

5998

else

5989

else

5999

phases=1:samp_UI;

5990

phases=1:samp_UI;

6000

end

5991

end

6001

5992

6002

mxV = zeros(size(phases));

5993

mxV = zeros(size(phases));

6003

5994

6004

%phases reveals the raw position in the UI window of the cursor.

5995

%phases reveals the raw position in the UI window of the cursor.

6005

%shift_amount is the amount to shift so that it aligns with half_UI

5996

%shift_amount is the amount to shift so that it aligns with half_UI

6006

shift_amount=half_UI-phases;

5997

shift_amount=half_UI-phases;

6007

%vs_shift puts the cursor at the center

5998

%vs_shift puts the cursor at the center

6008

vs_shift=circshift(vs,[0 shift_amount]);

5999

vs_shift=circshift(vs,[0 shift_amount]);

6009

L=size(vs_raw,1);

6000

L=size(vs_raw,1);

6010

%allow partial UI computation through pdf_range

6001

%allow partial UI computation through pdf_range

6011

%if pdf_range is empty, do full UI

6002

%if pdf_range is empty, do full UI

6012

if isempty(pdf_range)

6003

if isempty(pdf_range)

6013

pdf_range=1:samp_UI;

6004

pdf_range=1:samp_UI;

6014

else

6005

else

6015

pdf_range=min(pdf_range):max(pdf_range);

6006

pdf_range=min(pdf_range):max(pdf_range);

6016

end

6007

end

6017

h_j_full=zeros(L,samp_UI);

6008

h_j_full=zeros(L,samp_UI);

6018

for k=pdf_range

6009

for k=pdf_range

6019

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6010

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6020

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6011

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6021

%progress = k/length(phases);

6012

%progress = k/length(phases);

6022

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6013

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6023

6014

6024

%build the circshift of h_j_full into the loop to support a reduced

6015

%build the circshift of h_j_full into the loop to support a reduced

6025

%range of sampling points. circshift at the end only works if doing the

6016

%range of sampling points. circshift at the end only works if doing the

6026

%full range of sampling points. And shifting before the loop will

6017

%full range of sampling points. And shifting before the loop will

6027

%yield the wrong answer at the edges of the UI

6018

%yield the wrong answer at the edges of the UI

6028

hk=k-shift_amount;

6019

hk=k-shift_amount;

6029

if hk<1

6020

if hk<1

6030

hk=hk+samp_UI;

6021

hk=hk+samp_UI;

6031

elseif hk>samp_UI

6022

elseif hk>samp_UI

6032

hk=hk-samp_UI;

6023

hk=hk-samp_UI;

6033

end

6024

end

6034

if hk==1

6025

if hk==1

6035

%when hk=1, the early UI is the last column

6026

%when hk=1, the early UI is the last column

6036

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6027

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6037

elseif hk==samp_UI

6028

elseif hk==samp_UI

6038

%when hk=samp_UI, the late UI is the first column

6029

%when hk=samp_UI, the late UI is the first column

6039

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6030

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6040

else

6031

else

6041

%for all other cases, do the normal late=+1, early = -1

6032

%for all other cases, do the normal late=+1, early = -1

6042

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6033

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6043

end

6034

end

6044

end

6035

end

6045

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6036

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6046

% filename parsing and acquisition

6037

% filename parsing and acquisition

6047

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

6038

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

6048

%----------put files names into chdata structure ---------

6039

%----------put files names into chdata structure ---------

6049

% The thru file has the index of 1

6040

% The thru file has the index of 1

6050

% crosstalk file are indexed from 2

6041

% crosstalk file are indexed from 2

6051

% nxi is incremented each time a file is read in so that nxi will end

6042

% nxi is incremented each time a file is read in so that nxi will end

6052

filepath=[]; % path name for file

6043

filepath=[]; % path name for file

6053

nxi=0; % file index

6044

nxi=0; % file index

6054

% get the THRU file

6045

% get the THRU file

6055

if size(file_list,2) ~= 0

6046

if size(file_list,2) ~= 0

6056

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6047

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6057

[filepath, basename, fileext]=fileparts(file_list{1});

6048

[filepath, basename, fileext]=fileparts(file_list{1});

6058

6049

6059

else

6050

else

6060

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6051

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6061

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6052

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6062

movegui(h,'northeast')

6053

movegui(h,'northeast')

6063

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

6054

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

6064

end

6055

end

6065

if OP.ERL == 2

6056

if OP.ERL == 2

6066

dir=fullfile(filepath, '*.s2p');

6057

dir=fullfile(filepath, '*.s2p');

6067

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6058

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6068

if filepath == 0

6059

if filepath == 0

6069

error('No RL measurement file')

6060

error('No RL measurement file')

6070

end

6061

end

6071

else

6062

else

6072

dir=fullfile(filepath, '*.s4p');

6063

dir=fullfile(filepath, '*.s4p');

6073

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6064

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6074

if filepath == 0

6065

if filepath == 0

6075

error('No Thru file')

6066

error('No Thru file')

6076

end

6067

end

6077

end

6068

end

6078

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6069

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6079

end

6070

end

6080

nxi=nxi+1;

6071

nxi=nxi+1;

6081

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6072

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6082

chdata(nxi).ext = fileext;

6073

chdata(nxi).ext = fileext;

6083

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6074

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6084

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6075

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6085

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6076

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6086

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6077

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6087

chdata(nxi).type='THRU';

6078

chdata(nxi).type='THRU';

6088

chdata(nxi).ftr=param.fb*param.f_v;

6079

chdata(nxi).ftr=param.fb*param.f_v;

6089

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6080

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6090

6081

6091

% now get FEXT file names into chdata structure

6082

% now get FEXT file names into chdata structure

6092

kxi=nxi;

6083

kxi=nxi;

6093

for nxi=kxi+1:num_fext+kxi

6084

for nxi=kxi+1:num_fext+kxi

6094

lastfilepath=filepath;

6085

lastfilepath=filepath;

6095

if size(file_list,2) ~= 0

6086

if size(file_list,2) ~= 0

6096

[filepath, basename, fileext]=fileparts(file_list{nxi});

6087

[filepath, basename, fileext]=fileparts(file_list{nxi});

6097

else

6088

else

6098

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6089

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6099

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6090

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6100

movegui(h,'northeast')

6091

movegui(h,'northeast')

6101

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

6092

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

6102

end

6093

end

6103

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

6094

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

6104

dir=fullfile(filepath, '*.s4p');

6095

dir=fullfile(filepath, '*.s4p');

6105

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6096

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6106

if filepath==0

6097

if filepath==0

6107

error('Not enough NEXT files')

6098

error('Not enough NEXT files')

6108

end

6099

end

6109

else

6100

else

6110

dir=fullfile(filepath, '*.s4p');

6101

dir=fullfile(filepath, '*.s4p');

6111

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6102

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6112

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6103

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6113

else

6104

else

6114

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6105

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6115

end

6106

end

6116

if filepath==0

6107

if filepath==0

6117

error('Not enough NEXT files')

6108

error('Not enough NEXT files')

6118

end

6109

end

6119

end

6110

end

6120

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6111

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6121

end

6112

end

6122

if isempty( filepath), filepath=lastfilepath; end

6113

if isempty( filepath), filepath=lastfilepath; end

6123

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6114

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6124

chdata(nxi).ext = fileext;

6115

chdata(nxi).ext = fileext;

6125

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6116

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6126

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6117

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6127

% chdata(nxi).A=param.a_fext;

6118

% chdata(nxi).A=param.a_fext;

6128

chdata(nxi).ftr=param.fb*param.f_f;

6119

chdata(nxi).ftr=param.fb*param.f_f;

6129

chdata(nxi).type='FEXT';

6120

chdata(nxi).type='FEXT';

6130

end

6121

end

6131

% now get NEXT file names into chdata structure

6122

% now get NEXT file names into chdata structure

6132

kxi=num_fext+kxi;

6123

kxi=num_fext+kxi;

6133

for nxi=kxi+1:num_next+kxi

6124

for nxi=kxi+1:num_next+kxi

6134

lastfilepath=filepath;

6125

lastfilepath=filepath;

6135

if size(file_list,2) ~= 0

6126

if size(file_list,2) ~= 0

6136

[filepath, basename, fileext]=fileparts(file_list{nxi});

6127

[filepath, basename, fileext]=fileparts(file_list{nxi});

6137

else

6128

else

6138

dir=fullfile(filepath, '*.s4p');

6129

dir=fullfile(filepath, '*.s4p');

6139

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6130

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6140

if filepath==0

6131

if filepath==0

6141

error('Not enough NEXT files')

6132

error('Not enough NEXT files')

6142

end

6133

end

6143

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6134

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6144

end

6135

end

6145

if isempty( filepath), filepath=lastfilepath; end

6136

if isempty( filepath), filepath=lastfilepath; end

6146

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6137

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6147

chdata(nxi).ext = fileext;

6138

chdata(nxi).ext = fileext;

6148

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6139

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6149

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6140

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6150

% chdata(nxi).A=param.A_next;

6141

% chdata(nxi).A=param.A_next;

6151

chdata(nxi).ftr=param.fb*param.f_n;

6142

chdata(nxi).ftr=param.fb*param.f_n;

6152

chdata(nxi).type='NEXT';

6143

chdata(nxi).type='NEXT';

6153

end

6144

end

6154

6145

6155

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6146

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6156

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6147

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6157

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6148

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6158

% H_r - receiver filter, Butterworth

6149

% H_r - receiver filter, Butterworth

6159

% H_ctf - total gain of CTLE and low freq filtering

6150

% H_ctf - total gain of CTLE and low freq filtering

6160

% H_dc - the common mode channel gain

6151

% H_dc - the common mode channel gain

6161

% param.eta_0 -input referred Rx noise

6152

% param.eta_0 -input referred Rx noise

6162

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6153

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6163

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6154

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6164

%% Equation 93A-35 - independent of FFE setting %%

6155

%% Equation 93A-35 - independent of FFE setting %%

6165

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

6156

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

6166

if sum(param.AC_CM_RMS) ~= 0

6157

if sum(param.AC_CM_RMS) ~= 0

6167

sigma_ACCM=0;

6158

sigma_ACCM=0;

6168

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6159

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6169

for i=1:length(chdata)

6160

for i=1:length(chdata)

6170

H_dc=abs(squeeze(chdata(i).sdc21));

6161

H_dc=abs(squeeze(chdata(i).sdc21));

6171

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) );

6162

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) );

6172

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6163

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6173

end

6164

end

6174

sigma_N=norm([sigma_N1,sigma_ACCM]);

6165

sigma_N=norm([sigma_N1,sigma_ACCM]);

6175

else

6166

else

6176

sigma_N=sigma_N1;

6167

sigma_N=sigma_N1;

6177

end

6168

end

6178

%%

6169

%%

6179

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6170

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6180

% for Rx calibratrion only

6171

% for Rx calibratrion only

6181

% the FEXT channel for calibration basically a DC connection unlike normal

6172

% the FEXT channel for calibration basically a DC connection unlike normal

6182

% FEXT channels which are nearly open at DC channels

6173

% FEXT channels which are nearly open at DC channels

6183

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

6174

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

6184

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6175

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6185

if size(chdata,2) >= 2

6176

if size(chdata,2) >= 2

6186

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6177

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6187

else

6178

else

6188

Hnoise_channel=1;

6179

Hnoise_channel=1;

6189

end

6180

end

6190

f=chdata(2).faxis;

6181

f=chdata(2).faxis;

6191

f_hp=param.f_hp;

6182

f_hp=param.f_hp;

6192

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6183

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6193

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6184

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6194

else

6185

else

6195

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

6186

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

6196

end

6187

end

6197

%% Equation 93A-47 or 162-12

6188

%% Equation 93A-47 or 162-12

6198

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6189

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6199

6190

6200

%% Equation 93A-48 or 162-14%%

6191

%% Equation 93A-48 or 162-14%%

6201

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6192

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6202

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6193

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6203

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6194

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6204

% Modified not to double count crosstalk: John Ewen 13/12/2018

6195

% Modified not to double count crosstalk: John Ewen 13/12/2018

6205

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6196

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6206

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6197

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6207

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6198

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6208

f=chdata(1).faxis;

6199

f=chdata(1).faxis;

6209

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6200

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6210

if(f(1)==0)

6201

if(f(1)==0)

6211

temp_angle(1)=1e-20;% we don't want to divide by zero

6202

temp_angle(1)=1e-20;% we don't want to divide by zero

6212

end

6203

end

6213

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

6204

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

6214

if max(upsampled_txffe) > 0

6205

if max(upsampled_txffe) > 0

6215

PWF_tx=zeros(1,length(f));

6206

PWF_tx=zeros(1,length(f));

6216

[mcur,icur] = max(upsampled_txffe);

6207

[mcur,icur] = max(upsampled_txffe);

6217

if exist('phase_memory','var') && ~isempty(phase_memory)

6208

if exist('phase_memory','var') && ~isempty(phase_memory)

6218

pre_calc=1;

6209

pre_calc=1;

6219

else

6210

else

6220

pre_calc=0;

6211

pre_calc=0;

6221

end

6212

end

6222

for ii=1:length(upsampled_txffe)

6213

for ii=1:length(upsampled_txffe)

6223

if upsampled_txffe(ii)==0

6214

if upsampled_txffe(ii)==0

6224

%speed up: skip cases when txffe=0

6215

%speed up: skip cases when txffe=0

6225

continue;

6216

continue;

6226

end

6217

end

6227

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6218

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6228

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6219

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6229

% that is needed

6220

% that is needed

6230

if ii==icur

6221

if ii==icur

6231

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6222

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6232

PWF_tx = PWF_tx + upsampled_txffe(ii);

6223

PWF_tx = PWF_tx + upsampled_txffe(ii);

6233

else

6224

else

6234

if pre_calc

6225

if pre_calc

6235

%speed up: avoid vector exp calculation by externally pre-calculating it

6226

%speed up: avoid vector exp calculation by externally pre-calculating it

6236

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6227

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6237

else

6228

else

6238

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6229

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6239

end

6230

end

6240

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6231

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6241

PWF_tx = PWF_tx + transpose(term_ii(:));

6232

PWF_tx = PWF_tx + transpose(term_ii(:));

6242

end

6233

end

6243

% /Adee

6234

% /Adee

6244

end

6235

end

6245

end

6236

end

6246

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

6237

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

6247

if exist('C','var')

6238

if exist('C','var')

6248

PWF_rx=zeros(1,length(f));

6239

PWF_rx=zeros(1,length(f));

6249

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6240

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6250

if C(ii+param.RxFFE_cmx+1)==0

6241

if C(ii+param.RxFFE_cmx+1)==0

6251

%speed up: skip cases when rxffe=0

6242

%speed up: skip cases when rxffe=0

6252

continue;

6243

continue;

6253

end

6244

end

6254

if ii+1==0

6245

if ii+1==0

6255

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6246

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6256

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6247

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6257

else

6248

else

6258

if pre_calc

6249

if pre_calc

6259

%speed up: avoid vector exp calculation by externally pre-calculating it

6250

%speed up: avoid vector exp calculation by externally pre-calculating it

6260

%The latter columns of phase_memory hold RXFFE shift vectors

6251

%The latter columns of phase_memory hold RXFFE shift vectors

6261

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6252

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6262

term_ii=transpose(term_ii);

6253

term_ii=transpose(term_ii);

6263

else

6254

else

6264

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6255

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6265

end

6256

end

6266

PWF_rx=PWF_rx+term_ii;

6257

PWF_rx=PWF_rx+term_ii;

6267

end

6258

end

6268

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6259

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6269

end

6260

end

6270

end

6261

end

6271

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6262

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6272

for ii=2:size(chdata,2)

6263

for ii=2:size(chdata,2)

6273

SINC = sin(temp_angle)./temp_angle;

6264

SINC = sin(temp_angle)./temp_angle;

6274

PWF_data=SINC.^2;

6265

PWF_data=SINC.^2;

6275

PWF=PWF_data.*PWF_rx; % power weight function

6266

PWF=PWF_data.*PWF_rx; % power weight function

6276

PWFnext=abs(PWF);

6267

PWFnext=abs(PWF);

6277

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6268

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6278

PWFfext=abs(PWF);

6269

PWFfext=abs(PWF);

6279

if isequal(chdata(ii).type, 'FEXT')

6270

if isequal(chdata(ii).type, 'FEXT')

6280

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6271

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6281

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

6272

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

6282

elseif isequal(chdata(ii).type, 'NEXT')

6273

elseif isequal(chdata(ii).type, 'NEXT')

6283

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6274

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6284

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

6275

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

6285

end

6276

end

6286

end

6277

end

6287

if nargout == 1 && isequal(type,'NEXT')

6278

if nargout == 1 && isequal(type,'NEXT')

6288

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

6279

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

6289

elseif nargout == 1 && isequal(type,'FEXT')

6280

elseif nargout == 1 && isequal(type,'FEXT')

6290

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

6281

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

6291

elseif nargout == 3

6282

elseif nargout == 3

6292

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6283

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6293

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

6284

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

6294

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

6285

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

6295

end

6286

end

6296

6287

6297

function out=hrem(h,index,N_bf,bmaxg)

6288

function out=hrem(h,index,N_bf,bmaxg)

6298

6289

6299

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) ];

6290

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) ];

6300

% faster than single line function

6291

% faster than single line function

6301

% hrem =@(h,index,N_bf,bmaxg) ...

6292

% hrem =@(h,index,N_bf,bmaxg) ...

6302

% [ h(1:index-1) ...

6293

% [ h(1:index-1) ...

6303

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6294

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6304

% h(index+N_bf:end) ]...

6295

% h(index+N_bf:end) ]...

6305

% ;

6296

% ;

6306

6297

6307

%% floating DFE taps

6298

%% floating DFE taps

6308

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6299

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6309

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6300

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6310

% Sout = interp_Sparam(Sin,fin,fout)

6301

% Sout = interp_Sparam(Sin,fin,fout)

6311

%

6302

%

6312

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6303

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6313

% fout.

6304

% fout.

6314

6305

6315

if ( fin(end)<fout(end) )

6306

if ( fin(end)<fout(end) )

6316

% warning('Channel high frequencies extrapolation might be inaccurate!');

6307

% warning('Channel high frequencies extrapolation might be inaccurate!');

6317

end

6308

end

6318

6309

6319

H_mag = abs(Sin);

6310

H_mag = abs(Sin);

6320

H_mag(H_mag<eps)=eps; % handle ill cases...

6311

H_mag(H_mag<eps)=eps; % handle ill cases...

6321

H_ph = unwrap(angle(Sin));

6312

H_ph = unwrap(angle(Sin));

6322

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6313

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6323

% user ignore that.

6314

% user ignore that.

6324

if mean(diff(H_ph))>0

6315

if mean(diff(H_ph))>0

6325

if OP.DEBUG

6316

if OP.DEBUG

6326

warning('Anti-causal response found. Finer frequency step is required for this channel');

6317

warning('Anti-causal response found. Finer frequency step is required for this channel');

6327

else

6318

else

6328

error('Anti-causal response found. Finer frequency step is required for this channel');

6319

error('Anti-causal response found. Finer frequency step is required for this channel');

6329

end

6320

end

6330

end

6321

end

6331

6322

6332

%opt_interp_Sparam_mag='linear_trend_to_DC';

6323

%opt_interp_Sparam_mag='linear_trend_to_DC';

6333

switch opt_interp_Sparam_mag

6324

switch opt_interp_Sparam_mag

6334

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6325

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6335

if -iscolumn(H_mag), H_mag=H_mag.';end

6326

if -iscolumn(H_mag), H_mag=H_mag.';end

6336

if -iscolumn(fin), fin=fin.';end

6327

if -iscolumn(fin), fin=fin.';end

6337

fin_x=fin;

6328

fin_x=fin;

6338

H_mag_x=H_mag(:);

6329

H_mag_x=H_mag(:);

6339

if fin(1)>0

6330

if fin(1)>0

6340

p=polyfit(fin(1:10), H_mag(1:10), 1);

6331

p=polyfit(fin(1:10), H_mag(1:10), 1);

6341

dc_trend_val=polyval(p, 0);

6332

dc_trend_val=polyval(p, 0);

6342

fin_x=[0, fin_x];

6333

fin_x=[0, fin_x];

6343

H_mag_x = [dc_trend_val; H_mag_x];

6334

H_mag_x = [dc_trend_val; H_mag_x];

6344

end

6335

end

6345

if fin(end)<fout(end)

6336

if fin(end)<fout(end)

6346

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6337

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6347

mid_freq_ind=round(length(fin)/2);

6338

mid_freq_ind=round(length(fin)/2);

6348

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6339

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6349

warning(warn_state);

6340

warning(warn_state);

6350

hf_trend_val=polyval(p, fout(end));

6341

hf_trend_val=polyval(p, fout(end));

6351

if hf_trend_val>H_mag(end)

6342

if hf_trend_val>H_mag(end)

6352

hf_trend_val=H_mag(end);

6343

hf_trend_val=H_mag(end);

6353

hf_logtrend_val = H_mag(end);

6344

hf_logtrend_val = H_mag(end);

6354

elseif hf_trend_val<eps

6345

elseif hf_trend_val<eps

6355

hf_trend_val=eps;

6346

hf_trend_val=eps;

6356

hf_logtrend_val = realmin;

6347

hf_logtrend_val = realmin;

6357

end

6348

end

6358

fin_x=[fin_x, fout(end)];

6349

fin_x=[fin_x, fout(end)];

6359

H_mag_x = [H_mag_x; hf_trend_val];

6350

H_mag_x = [H_mag_x; hf_trend_val];

6360

end

6351

end

6361

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6352

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6362

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6353

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6363

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6354

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6364

indx = find(fout > fin(end),1,'first');

6355

indx = find(fout > fin(end),1,'first');

6365

H_mag_i(indx:end) = H_logmag_i(indx:end);

6356

H_mag_i(indx:end) = H_logmag_i(indx:end);

6366

end

6357

end

6367

case 'trend_to_DC'

6358

case 'trend_to_DC'

6368

% extrapolate to trend value at DC.

6359

% extrapolate to trend value at DC.

6369

if -iscolumn(H_mag), H_mag=H_mag.';end

6360

if -iscolumn(H_mag), H_mag=H_mag.';end

6370

if -iscolumn(fin), fin=fin.';end

6361

if -iscolumn(fin), fin=fin.';end

6371

fin_x=fin;

6362

fin_x=fin;

6372

H_mag_x=H_mag;

6363

H_mag_x=H_mag;

6373

if fin(1)>0

6364

if fin(1)>0

6374

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6365

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6375

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6366

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6376

dc_trend_val=10^polyval(p, 0);

6367

dc_trend_val=10^polyval(p, 0);

6377

fin_x=[0, fin_x];

6368

fin_x=[0, fin_x];

6378

H_mag_x = [dc_trend_val H_mag_x];

6369

H_mag_x = [dc_trend_val H_mag_x];

6379

end

6370

end

6380

if fin(end)<fout(end)

6371

if fin(end)<fout(end)

6381

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6372

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6382

mid_freq_ind=round(length(fin)/2);

6373

mid_freq_ind=round(length(fin)/2);

6383

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6374

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6384

warning(warn_state);

6375

warning(warn_state);

6385

hf_trend_val=10^polyval(p, fout(end));

6376

hf_trend_val=10^polyval(p, fout(end));

6386

if hf_trend_val>H_mag(end)

6377

if hf_trend_val>H_mag(end)

6387

hf_trend_val=H_mag(end);

6378

hf_trend_val=H_mag(end);

6388

end

6379

end

6389

fin_x=[fin_x, fout(end)];

6380

fin_x=[fin_x, fout(end)];

6390

H_mag_x = [H_mag_x hf_trend_val];

6381

H_mag_x = [H_mag_x hf_trend_val];

6391

end

6382

end

6392

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6383

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6393

case 'extrap_to_DC_or_zero'

6384

case 'extrap_to_DC_or_zero'

6394

% same as extrap_to_DC but detect AC-coupled channels and

6385

% same as extrap_to_DC but detect AC-coupled channels and

6395

% extrapolate them to 0.

6386

% extrapolate them to 0.

6396

if fin(1)>0 && 20*log10(H_mag(1))<-20

6387

if fin(1)>0 && 20*log10(H_mag(1))<-20

6397

% assume AC coupling, with 0 at DC

6388

% assume AC coupling, with 0 at DC

6398

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6389

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6399

else

6390

else

6400

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6391

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6401

end

6392

end

6402

H_mag_i(fout>fin(end)) = H_mag(end);

6393

H_mag_i(fout>fin(end)) = H_mag(end);

6403

case 'extrap_to_DC'

6394

case 'extrap_to_DC'

6404

% first extrapolate down to DC, then use highest available frequency

6395

% first extrapolate down to DC, then use highest available frequency

6405

% for higher frequencies

6396

% for higher frequencies

6406

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6397

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6407

H_mag_i(fout>fin(end)) = H_mag(end);

6398

H_mag_i(fout>fin(end)) = H_mag(end);

6408

case 'old'

6399

case 'old'

6409

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6400

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6410

otherwise

6401

otherwise

6411

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6402

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6412

end

6403

end

6413

6404

6414

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6405

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6415

6406

6416

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6407

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6417

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6408

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6418

switch opt_interp_Sparam_phase

6409

switch opt_interp_Sparam_phase

6419

case 'old'

6410

case 'old'

6420

H_ph_i = H_ph_i-H_ph_i(1);

6411

H_ph_i = H_ph_i-H_ph_i(1);

6421

case 'zero_DC'

6412

case 'zero_DC'

6422

H_ph_i(1) = 0;

6413

H_ph_i(1) = 0;

6423

case 'interp_to_DC'

6414

case 'interp_to_DC'

6424

if fin(1) ~= 0

6415

if fin(1) ~= 0

6425

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6416

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6426

end

6417

end

6427

case 'extrap_cubic_to_dc_linear_to_inf'

6418

case 'extrap_cubic_to_dc_linear_to_inf'

6428

if fin(1) ~= 0

6419

if fin(1) ~= 0

6429

% estimate low frequency group delay

6420

% estimate low frequency group delay

6430

group_delay = -diff(H_ph(:))./diff(fin(:));

6421

group_delay = -diff(H_ph(:))./diff(fin(:));

6431

low_freq_gd = group_delay(1:50);

6422

low_freq_gd = group_delay(1:50);

6432

% calculate trend, throwing away outliers

6423

% calculate trend, throwing away outliers

6433

m = median(low_freq_gd); sigma = std(low_freq_gd);

6424

m = median(low_freq_gd); sigma = std(low_freq_gd);

6434

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6425

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6435

% correct outliers in first 10 phase samples

6426

% correct outliers in first 10 phase samples

6436

for k=10:-1:1

6427

for k=10:-1:1

6437

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6428

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6438

end

6429

end

6439

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6430

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6440

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6431

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6441

% modification - trend to inf

6432

% modification - trend to inf

6442

if (1)

6433

if (1)

6443

high_freq_gd = group_delay(end-50:end);

6434

high_freq_gd = group_delay(end-50:end);

6444

% calculate trend, throwing away outliers

6435

% calculate trend, throwing away outliers

6445

m = median(high_freq_gd); sigma = std(high_freq_gd);

6436

m = median(high_freq_gd); sigma = std(high_freq_gd);

6446

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6437

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6447

hf_extrap_range = find(fout>fin(end));

6438

hf_extrap_range = find(fout>fin(end));

6448

last_data_sample = hf_extrap_range(1)-1;

6439

last_data_sample = hf_extrap_range(1)-1;

6449

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6440

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6450

% for k=hf_range

6441

% for k=hf_range

6451

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6442

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6452

% end

6443

% end

6453

end

6444

end

6454

6445

6455

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6446

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6456

H_ph_i=H_ph_cubic;

6447

H_ph_i=H_ph_cubic;

6457

H_ph_i(indx:end) = H_ph_linear(indx:end);

6448

H_ph_i(indx:end) = H_ph_linear(indx:end);

6458

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6449

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6459

end

6450

end

6460

case 'interp_and_shift_to_DC'

6451

case 'interp_and_shift_to_DC'

6461

if fin(1) ~= 0

6452

if fin(1) ~= 0

6462

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6453

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6463

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6454

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6464

end

6455

end

6465

case 'trend_and_shift_to_DC'

6456

case 'trend_and_shift_to_DC'

6466

% estimate low frequency group delay

6457

% estimate low frequency group delay

6467

group_delay = -diff(H_ph(:))./diff(fin(:));

6458

group_delay = -diff(H_ph(:))./diff(fin(:));

6468

low_freq_gd = group_delay(1:50);

6459

low_freq_gd = group_delay(1:50);

6469

% calculate trend, throwing away outliers

6460

% calculate trend, throwing away outliers

6470

m = median(low_freq_gd); sigma = std(low_freq_gd);

6461

m = median(low_freq_gd); sigma = std(low_freq_gd);

6471

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6462

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6472

fin_x=fin;

6463

fin_x=fin;

6473

H_ph_x=H_ph(:);

6464

H_ph_x=H_ph(:);

6474

if fin(1) ~= 0

6465

if fin(1) ~= 0

6475

% correct outliers in first 10 phase samples

6466

% correct outliers in first 10 phase samples

6476

for k=10:-1:1

6467

for k=10:-1:1

6477

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6468

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6478

end

6469

end

6479

6470

6480

% shift all phase data so that DC extrapolation to 0 follows trend

6471

% shift all phase data so that DC extrapolation to 0 follows trend

6481

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6472

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6482

fin_x=[0, fin_x];

6473

fin_x=[0, fin_x];

6483

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6474

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6484

end

6475

end

6485

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6476

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6486

% the last two samples, so noise can create an inverted slope and

6477

% the last two samples, so noise can create an inverted slope and

6487

% non-causal response).

6478

% non-causal response).

6488

if fout(end)>fin(end)

6479

if fout(end)>fin(end)

6489

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6480

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6490

% p=polyfit(fin_x', H_ph_x, 1);

6481

% p=polyfit(fin_x', H_ph_x, 1);

6491

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6482

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6492

% hf_phase_trend=polyval(p,max(fout));

6483

% hf_phase_trend=polyval(p,max(fout));

6493

fin_x=[fin_x, fout(end)];

6484

fin_x=[fin_x, fout(end)];

6494

H_ph_x=[H_ph_x; hf_phase_trend];

6485

H_ph_x=[H_ph_x; hf_phase_trend];

6495

end

6486

end

6496

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6487

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6497

6488

6498

otherwise

6489

otherwise

6499

error('COM:Extrap:InvalidOption', ...

6490

error('COM:Extrap:InvalidOption', ...

6500

'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"');

6491

'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"');

6501

end

6492

end

6502

H_i = H_mag_i.*exp(1j*H_ph_i);

6493

H_i = H_mag_i.*exp(1j*H_ph_i);

6503

Sout=H_i;

6494

Sout=H_i;

6504

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6495

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6505

6496

6506

%This function makes the TX or RX package. The type input must be

6497

%This function makes the TX or RX package. The type input must be

6507

%'TX' or 'RX'

6498

%'TX' or 'RX'

6508

%If the mode argument is omitted, mode='dd' is assumed. Currently

6499

%If the mode argument is omitted, mode='dd' is assumed. Currently

6509

%mode='dc' is only used when making the TX package for AC CM noise

6500

%mode='dc' is only used when making the TX package for AC CM noise

6510

%inclusion. The Rx package for 'dc' mode is still generated using

6501

%inclusion. The Rx package for 'dc' mode is still generated using

6511

%the same parameters as 'dd' mode

6502

%the same parameters as 'dd' mode

6512

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6503

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6513

%

6504

%

6514

%One instance of package block looks like this (if no elements are set to 0):

6505

%One instance of package block looks like this (if no elements are set to 0):

6515

%-------------Lcomp----------Tline---------------

6506

%-------------Lcomp----------Tline---------------

6516

% | | |

6507

% | | |

6517

% Cpad Cbump Cball

6508

% Cpad Cbump Cball

6518

% | | |

6509

% | | |

6519

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

6510

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

6520

6511

6521

if nargin<6

6512

if nargin<6

6522

%optional input "include_die"=0 allows die parameters to be forced to 0

6513

%optional input "include_die"=0 allows die parameters to be forced to 0

6523

%this includes Cpad, Lcomp, and Cbump

6514

%this includes Cpad, Lcomp, and Cbump

6524

include_die=1;

6515

include_die=1;

6525

end

6516

end

6526

if nargin<5

6517

if nargin<5

6527

mode='dd';

6518

mode='dd';

6528

end

6519

end

6529

6520

6530

6521

6531

if ~isempty(param.PKG_NAME)

6522

if ~isempty(param.PKG_NAME)

6532

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6523

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6533

%so they are swapped in depending on if Tx or Rx is set for type

6524

%so they are swapped in depending on if Tx or Rx is set for type

6534

%Note that param is not returned from this function, so the swap does not persist

6525

%Note that param is not returned from this function, so the swap does not persist

6535

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6526

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6536

if strcmpi(type,'tx')

6527

if strcmpi(type,'tx')

6537

pkg_name = param.PKG_NAME{1};

6528

pkg_name = param.PKG_NAME{1};

6538

elseif strcmpi(type,'rx')

6529

elseif strcmpi(type,'rx')

6539

pkg_name = param.PKG_NAME{2};

6530

pkg_name = param.PKG_NAME{2};

6540

else

6531

else

6541

error('Pkg type must be Tx or Rx');

6532

error('Pkg type must be Tx or Rx');

6542

end

6533

end

6543

pkg_parameter_struct = param.PKG.(pkg_name);

6534

pkg_parameter_struct = param.PKG.(pkg_name);

6544

6535

6545

6536

6546

for j=1:length(swap_fields)

6537

for j=1:length(swap_fields)

6547

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6538

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6548

end

6539

end

6549

6540

6550

end

6541

end

6551

6542

6552

C_diepad = param.C_diepad;

6543

C_diepad = param.C_diepad;

6553

C_pkg_board = param.C_pkg_board;

6544

C_pkg_board = param.C_pkg_board;

6554

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6545

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6555

L_comp = param.L_comp;

6546

L_comp = param.L_comp;

6556

C_bump = param.C_bump;

6547

C_bump = param.C_bump;

6557

if ~include_die

6548

if ~include_die

6558

%best to multiply by 0. that way vectors maintain original size

6549

%best to multiply by 0. that way vectors maintain original size

6559

C_diepad=C_diepad*0;

6550

C_diepad=C_diepad*0;

6560

L_comp=L_comp*0;

6551

L_comp=L_comp*0;

6561

C_bump=C_bump*0;

6552

C_bump=C_bump*0;

6562

end

6553

end

6563

% [ahealey] End of modifications.

6554

% [ahealey] End of modifications.

6564

% generate TX package according to channel type.

6555

% generate TX package according to channel type.

6565

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

6556

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

6566

6557

6567

%Syntax update for C_diepad and L_comp

6558

%Syntax update for C_diepad and L_comp

6568

%Allow a chain of values to be entered as a matrix:

6559

%Allow a chain of values to be entered as a matrix:

6569

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6560

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6570

if isvector(C_diepad)

6561

if isvector(C_diepad)

6571

Cd_Tx=C_diepad(1);

6562

Cd_Tx=C_diepad(1);

6572

Cd_Rx=C_diepad(2);

6563

Cd_Rx=C_diepad(2);

6573

L_comp_Tx=L_comp(1);

6564

L_comp_Tx=L_comp(1);

6574

L_comp_Rx=L_comp(2);

6565

L_comp_Rx=L_comp(2);

6575

num_blocks=mele;

6566

num_blocks=mele;

6576

else

6567

else

6577

Cd_Tx=C_diepad(1,:);

6568

Cd_Tx=C_diepad(1,:);

6578

Cd_Rx=C_diepad(2,:);

6569

Cd_Rx=C_diepad(2,:);

6579

L_comp_Tx=L_comp(1,:);

6570

L_comp_Tx=L_comp(1,:);

6580

L_comp_Rx=L_comp(2,:);

6571

L_comp_Rx=L_comp(2,:);

6581

num_blocks=mele+length(Cd_Tx)-1;

6572

num_blocks=mele+length(Cd_Tx)-1;

6582

end

6573

end

6583

extra_LC=length(Cd_Tx)-1;

6574

extra_LC=length(Cd_Tx)-1;

6584

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6575

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6585

insert_zeros=zeros([1 extra_LC]);

6576

insert_zeros=zeros([1 extra_LC]);

6586

6577

6587

%Updated technique of building Tx/Rx packages

6578

%Updated technique of building Tx/Rx packages

6588

%each index corresponds to the package segment

6579

%each index corresponds to the package segment

6589

switch type

6580

switch type

6590

case 'TX'

6581

case 'TX'

6591

switch mele

6582

switch mele

6592

case 1

6583

case 1

6593

Cpad=Cd_Tx;

6584

Cpad=Cd_Tx;

6594

Lcomp=L_comp_Tx;

6585

Lcomp=L_comp_Tx;

6595

Cbump=C_bump(1);

6586

Cbump=C_bump(1);

6596

Cball=C_pkg_board(1);

6587

Cball=C_pkg_board(1);

6597

Zpkg=param.pkg_Z_c(1);

6588

Zpkg=param.pkg_Z_c(1);

6598

case 4

6589

case 4

6599

Cpad=[Cd_Tx 0 0 0];

6590

Cpad=[Cd_Tx 0 0 0];

6600

Lcomp=[L_comp_Tx 0 0 0];

6591

Lcomp=[L_comp_Tx 0 0 0];

6601

Cbump=[C_bump(1) 0 0 0];

6592

Cbump=[C_bump(1) 0 0 0];

6602

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6593

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6603

Zpkg=param.pkg_Z_c(1,:);

6594

Zpkg=param.pkg_Z_c(1,:);

6604

otherwise

6595

otherwise

6605

error('package syntax error')

6596

error('package syntax error')

6606

end

6597

end

6607

switch upper(channel_type)

6598

switch upper(channel_type)

6608

case 'THRU'

6599

case 'THRU'

6609

Len=param.Pkg_len_TX;

6600

Len=param.Pkg_len_TX;

6610

case 'NEXT'

6601

case 'NEXT'

6611

Len=param.Pkg_len_NEXT;

6602

Len=param.Pkg_len_NEXT;

6612

case 'FEXT'

6603

case 'FEXT'

6613

Len=param.Pkg_len_FEXT;

6604

Len=param.Pkg_len_FEXT;

6614

end

6605

end

6615

case 'RX'

6606

case 'RX'

6616

switch mele

6607

switch mele

6617

case 1

6608

case 1

6618

Cpad=Cd_Rx;

6609

Cpad=Cd_Rx;

6619

Lcomp=L_comp_Rx;

6610

Lcomp=L_comp_Rx;

6620

Cbump=C_bump(2);

6611

Cbump=C_bump(2);

6621

Cball=C_pkg_board(2);

6612

Cball=C_pkg_board(2);

6622

Zpkg=param.pkg_Z_c(2);

6613

Zpkg=param.pkg_Z_c(2);

6623

case 4

6614

case 4

6624

Cpad=[Cd_Rx 0 0 0];

6615

Cpad=[Cd_Rx 0 0 0];

6625

Lcomp=[L_comp_Rx 0 0 0];

6616

Lcomp=[L_comp_Rx 0 0 0];

6626

Cbump=[C_bump(2) 0 0 0];

6617

Cbump=[C_bump(2) 0 0 0];

6627

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6618

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6628

Zpkg=param.pkg_Z_c(2,:);

6619

Zpkg=param.pkg_Z_c(2,:);

6629

otherwise

6620

otherwise

6630

error('package syntax error')

6621

error('package syntax error')

6631

end

6622

end

6632

switch upper(channel_type)

6623

switch upper(channel_type)

6633

case 'THRU'

6624

case 'THRU'

6634

Len=param.Pkg_len_RX;

6625

Len=param.Pkg_len_RX;

6635

case 'NEXT'

6626

case 'NEXT'

6636

Len=param.Pkg_len_RX;

6627

Len=param.Pkg_len_RX;

6637

case 'FEXT'

6628

case 'FEXT'

6638

Len=param.Pkg_len_RX;

6629

Len=param.Pkg_len_RX;

6639

end

6630

end

6640

end

6631

end

6641

6632

6642

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6633

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6643

Cball=[insert_zeros Cball];

6634

Cball=[insert_zeros Cball];

6644

Cbump=[insert_zeros Cbump];

6635

Cbump=[insert_zeros Cbump];

6645

Len=[insert_zeros Len];

6636

Len=[insert_zeros Len];

6646

Zpkg=[insert_zeros Zpkg];

6637

Zpkg=[insert_zeros Zpkg];

6647

6638

6648

% debug_string='';

6639

% debug_string='';

6649

% for j=1:length(Zpkg)

6640

% for j=1:length(Zpkg)

6650

% if Cpad(j)~=0

6641

% if Cpad(j)~=0

6651

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6642

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6652

% end

6643

% end

6653

% if Lcomp(j)~=0

6644

% if Lcomp(j)~=0

6654

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6645

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6655

% end

6646

% end

6656

% if Cbump(j)~=0

6647

% if Cbump(j)~=0

6657

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6648

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6658

% end

6649

% end

6659

% if Len(j)~=0

6650

% if Len(j)~=0

6660

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6651

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6661

% end

6652

% end

6662

% if Cball(j)~=0

6653

% if Cball(j)~=0

6663

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6654

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6664

% end

6655

% end

6665

% end

6656

% end

6666

% if length(debug_string)>2

6657

% if length(debug_string)>2

6667

% debug_string=debug_string(3:end);

6658

% debug_string=debug_string(3:end);

6668

% end

6659

% end

6669

6660

6670

% tx package

6661

% tx package

6671

pkg_param=param;

6662

pkg_param=param;

6672

if strcmpi(mode,'dc')

6663

if strcmpi(mode,'dc')

6673

% change tx package to CC mode

6664

% change tx package to CC mode

6674

pkg_param.Z0=pkg_param.Z0/2;

6665

pkg_param.Z0=pkg_param.Z0/2;

6675

Cpad=Cpad*2;

6666

Cpad=Cpad*2;

6676

Cball=Cball*2;

6667

Cball=Cball*2;

6677

Zpkg=Zpkg*2;

6668

Zpkg=Zpkg*2;

6678

Lcomp=Lcomp/2;

6669

Lcomp=Lcomp/2;

6679

Cbump=Cbump*2;

6670

Cbump=Cbump*2;

6680

end

6671

end

6681

switch num_blocks

6672

switch num_blocks

6682

case 1

6673

case 1

6683

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6674

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6684

otherwise

6675

otherwise

6685

for j=1:num_blocks

6676

for j=1:num_blocks

6686

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6677

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6687

if j==1

6678

if j==1

6688

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6679

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6689

else

6680

else

6690

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6681

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6691

end

6682

end

6692

end

6683

end

6693

end

6684

end

6694

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6685

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6695

f(f<eps)=eps;

6686

f(f<eps)=eps;

6696

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6687

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6697

%% Equation 93A-8

6688

%% Equation 93A-8

6698

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6689

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6699

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6690

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6700

6691

6701

% [ahealey] Add compensating L and shunt C (bump) when requested.

6692

% [ahealey] Add compensating L and shunt C (bump) when requested.

6702

s12pad = s21pad;

6693

s12pad = s21pad;

6703

s22pad = s11pad;

6694

s22pad = s11pad;

6704

if nargin > 6

6695

if nargin > 6

6705

lcomp = varargin{1};

6696

lcomp = varargin{1};

6706

if lcomp>0

6697

if lcomp>0

6707

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6698

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6708

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6699

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6709

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6700

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6710

s11pad, s12pad, s21pad, s22pad, ...

6701

s11pad, s12pad, s21pad, s22pad, ...

6711

s11comp, s21comp, s21comp, s11comp);

6702

s11comp, s21comp, s21comp, s11comp);

6712

end

6703

end

6713

end

6704

end

6714

if nargin > 7

6705

if nargin > 7

6715

cbump = varargin{2};

6706

cbump = varargin{2};

6716

if cbump>0

6707

if cbump>0

6717

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6708

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6718

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6709

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6719

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6710

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6720

s11pad, s12pad, s21pad, s22pad, ...

6711

s11pad, s12pad, s21pad, s22pad, ...

6721

s11bump, s21bump, s21bump, s11bump);

6712

s11bump, s21bump, s21bump, s11bump);

6722

end

6713

end

6723

end

6714

end

6724

% [ahealey] End of modifications.

6715

% [ahealey] End of modifications.

6725

6716

6726

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6717

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6727

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6718

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6728

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6719

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6729

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6720

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6730

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6721

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6731

s11pad, s12pad, s21pad, s22pad, ...

6722

s11pad, s12pad, s21pad, s22pad, ...

6732

S11, S21, S21, S11);

6723

S11, S21, S21, S11);

6733

% [ahealey] End of modifications.

6724

% [ahealey] End of modifications.

6734

6725

6735

%% Equation 93A-8

6726

%% Equation 93A-8

6736

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6727

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6737

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6728

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6738

[ s11out, s12out, s21out, s22out ]= ...

6729

[ s11out, s12out, s21out, s22out ]= ...

6739

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6730

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6740

6731

6741

function missingParameter (parameterName)

6732

function missingParameter (parameterName)

6742

error( 'error:badParameterInformation', ...

6733

error( 'error:badParameterInformation', ...

6743

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6734

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6744

6735

6745

function pdf = normal_dist(sigma,nsigma,binsize)

6736

function pdf = normal_dist(sigma,nsigma,binsize)

6746

pdf.BinSize=binsize;

6737

pdf.BinSize=binsize;

6747

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6738

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6748

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6739

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6749

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6740

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6750

pdf.y=pdf.y/sum(pdf.y);

6741

pdf.y=pdf.y/sum(pdf.y);

6751

6742

6752

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6743

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6753

%% input

6744

%% input

6754

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6745

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6755

% baud_rate - baud rate in seconds

6746

% baud_rate - baud rate in seconds

6756

% param.samples_per_ui = samples per UI of IR

6747

% param.samples_per_ui = samples per UI of IR

6757

% param.max_ctle - maximum ac to dc gain in dB

6748

% param.max_ctle - maximum ac to dc gain in dB

6758

% param.tx_ffe(1) - maximum pre cursor (positive value)

6749

% param.tx_ffe(1) - maximum pre cursor (positive value)

6759

% param.tx_ffe(2) - maximum post cursor (positive value)

6750

% param.tx_ffe(2) - maximum post cursor (positive value)

6760

% param.tx_ffe_step - sweep step size for tx pre and post taps

6751

% param.tx_ffe_step - sweep step size for tx pre and post taps

6761

% param.ndfe - number of reference dfe taps

6752

% param.ndfe - number of reference dfe taps

6762

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6753

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6763

% output

6754

% output

6764

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6755

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6765

% result.eq.ctle - index of CTLE parameters in table

6756

% result.eq.ctle - index of CTLE parameters in table

6766

% result.IR - impulse response

6757

% result.IR - impulse response

6767

% result.avail_signal - maximum signal after equalization

6758

% result.avail_signal - maximum signal after equalization

6768

% result.avail_sig_index - index in result.IR of max signal

6759

% result.avail_sig_index - index in result.IR of max signal

6769

% result.best_FOM - best raw ISI

6760

% result.best_FOM - best raw ISI

6770

6761

6771

min_number_of_UI_in_response=40;

6762

min_number_of_UI_in_response=40;

6772

baud_rate=1/param.ui;

6763

baud_rate=1/param.ui;

6773

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

6764

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

6774

f=chdata(1).faxis;

6765

f=chdata(1).faxis;

6775

6766

6776

%Read user input of ts_sample_adj_range

6767

%Read user input of ts_sample_adj_range

6777

%if one value was entered, go from 0 to that value

6768

%if one value was entered, go from 0 to that value

6778

%if 2 values were entered, go from the 1st value to the 2nd value

6769

%if 2 values were entered, go from the 1st value to the 2nd value

6779

if length(param.ts_sample_adj_range)==1

6770

if length(param.ts_sample_adj_range)==1

6780

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6771

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6781

param.ts_sample_adj_range(1)=0;

6772

param.ts_sample_adj_range(1)=0;

6782

end

6773

end

6783

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6774

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6784

6775

6785

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

6776

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

6786

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

6777

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

6787

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6778

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

6788

% need to include H_RCos in noise and when computing the system ir for thru

6779

% need to include H_RCos in noise and when computing the system ir for thru

6789

% and crosstalk

6780

% and crosstalk

6790

H_r=H_bw.*H_bt.*H_RCos;

6781

H_r=H_bw.*H_bt.*H_RCos;

6791

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6782

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

6792

% Get f vector from 0 to Fs/2-delta_f.

6783

% Get f vector from 0 to Fs/2-delta_f.

6793

N_fft_by2 = 512;

6784

N_fft_by2 = 512;

6794

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6785

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

6795

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6786

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

6796

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6787

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

6797

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6788

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

6798

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6789

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

6799

%%

6790

%%

6800

6791

6801

% system noise H_sy PSD

6792

% system noise H_sy PSD

6802

if OP.USE_ETA0_PSD

6793

if OP.USE_ETA0_PSD

6803

fspike=1e9;

6794

fspike=1e9;

6804

% requires communication tool box if used

6795

% requires communication tool box if used

6805

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6796

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

6806

else

6797

else

6807

H_sy=ones(1,length(chdata(1).faxis));

6798

H_sy=ones(1,length(chdata(1).faxis));

6808

end

6799

end

6809

6800

6810

%Build txffe values dynamically

6801

%Build txffe values dynamically

6811

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6802

%any param field that is "tx_ffe_cm<X>_values" is a precursor

6812

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6803

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

6813

%where <X> is any integer

6804

%where <X> is any integer

6814

param_fields=fieldnames(param);

6805

param_fields=fieldnames(param);

6815

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6806

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

6816

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6807

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

6817

num_taps=num_pre+num_post;

6808

num_taps=num_pre+num_post;

6818

cur=num_pre+1;

6809

cur=num_pre+1;

6819

%txffe_cell combines all the txffe values into a single cell array

6810

%txffe_cell combines all the txffe values into a single cell array

6820

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6811

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

6821

txffe_cell=cell(1,num_taps);

6812

txffe_cell=cell(1,num_taps);

6822

for k=num_pre:-1:1

6813

for k=num_pre:-1:1

6823

idx=num_pre-k+1;

6814

idx=num_pre-k+1;

6824

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6815

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

6825

txffe_cell{idx}=param.(this_tx_field);

6816

txffe_cell{idx}=param.(this_tx_field);

6826

end

6817

end

6827

for k=1:num_post

6818

for k=1:num_post

6828

idx=k+num_pre;

6819

idx=k+num_pre;

6829

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6820

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

6830

txffe_cell{idx}=param.(this_tx_field);

6821

txffe_cell{idx}=param.(this_tx_field);

6831

end

6822

end

6832

%total number of txffe runs is the product of the lengths of each tap

6823

%total number of txffe runs is the product of the lengths of each tap

6833

txffe_lengths=cellfun('length',txffe_cell);

6824

txffe_lengths=cellfun('length',txffe_cell);

6834

if isempty(txffe_cell)

6825

if isempty(txffe_cell)

6835

num_txffe_runs=1;

6826

num_txffe_runs=1;

6836

else

6827

else

6837

num_txffe_runs=prod(txffe_lengths);

6828

num_txffe_runs=prod(txffe_lengths);

6838

end

6829

end

6839

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6830

%txffe_sweep_indices are used in the LOCAL_SEARCH block

6840

%any tap with length=1 can be ignored

6831

%any tap with length=1 can be ignored

6841

%Also is statistically likely that taps with greater number of values

6832

%Also is statistically likely that taps with greater number of values

6842

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6833

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

6843

txffe_sweep_indices=find(txffe_lengths>1);

6834

txffe_sweep_indices=find(txffe_lengths>1);

6844

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6835

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

6845

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6836

txffe_sweep_indices=txffe_sweep_indices(length_sort);

6846

num_txffe_sweep_indices=length(txffe_sweep_indices);

6837

num_txffe_sweep_indices=length(txffe_sweep_indices);

6847

6838

6848

gdc_values = param.ctle_gdc_values;

6839

gdc_values = param.ctle_gdc_values;

6849

Gffe_values = param.cursor_gain;

6840

Gffe_values = param.cursor_gain;

6850

switch param.CTLE_type

6841

switch param.CTLE_type

6851

case 'CL93'

6842

case 'CL93'

6852

case 'CL120d'

6843

case 'CL120d'

6853

g_DC_HP_values =param.g_DC_HP_values;

6844

g_DC_HP_values =param.g_DC_HP_values;

6854

case 'CL120e'

6845

case 'CL120e'

6855

f_HP_Z=param.f_HP_Z;

6846

f_HP_Z=param.f_HP_Z;

6856

f_HP_P=param.f_HP_P;

6847

f_HP_P=param.f_HP_P;

6857

6848

6858

end

6849

end

6859

best_ctle = [];

6850

best_ctle = [];

6860

best_FOM = -inf;

6851

best_FOM = -inf;

6861

best_txffe = [];

6852

best_txffe = [];

6862

delta_sbr = [];

6853

delta_sbr = [];

6863

PSD_results=[];

6854

PSD_results=[];

6864

MMSE_results=[];

6855

MMSE_results=[];

6865

best_bmax=param.bmax;

6856

best_bmax=param.bmax;

6866

%AJG021820

6857

%AJG021820

6867

best_bmin=param.bmin;

6858

best_bmin=param.bmin;

6868

h_J=[];

6859

h_J=[];

6869

pxi=0;

6860

pxi=0;

6870

if OP.DISPLAY_WINDOW

6861

if OP.DISPLAY_WINDOW

6871

hwaitbar=waitbar(0);

6862

hwaitbar=waitbar(0);

6872

else

6863

else

6873

fprintf('FOM search ');

6864

fprintf('FOM search ');

6874

end

6865

end

6875

FOM=0;

6866

FOM=0;

6876

if ~OP.RxFFE

6867

if ~OP.RxFFE

6877

Gffe_values=0;

6868

Gffe_values=0;

6878

end

6869

end

6879

param.ndfe_passed=param.ndfe;

6870

param.ndfe_passed=param.ndfe;

6880

old_loops=0;

6871

old_loops=0;

6881

new_loops=0;

6872

new_loops=0;

6882

6873

6883

%GDC Qual construction

6874

%GDC Qual construction

6884

gqual= param.gqual;

6875

gqual= param.gqual;

6885

g2qual=param.g2qual;

6876

g2qual=param.g2qual;

6886

if ~strcmp(param.CTLE_type,'CL120d')

6877

if ~strcmp(param.CTLE_type,'CL120d')

6887

qual=ones(1,length(gdc_values));

6878

qual=ones(1,length(gdc_values));

6888

else

6879

else

6889

if isempty(gqual) && isempty(g2qual)

6880

if isempty(gqual) && isempty(g2qual)

6890

qual=ones(length(g_DC_HP_values),length(gdc_values));

6881

qual=ones(length(g_DC_HP_values),length(gdc_values));

6891

else

6882

else

6892

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6883

qual=zeros(length(g_DC_HP_values),length(gdc_values));

6893

6884

6894

%prepare gqual and g2qual

6885

%prepare gqual and g2qual

6895

[g2qual,si]=sort(g2qual,'descend');

6886

[g2qual,si]=sort(g2qual,'descend');

6896

gqual=gqual(si,:);

6887

gqual=gqual(si,:);

6897

tmp=g2qual;

6888

tmp=g2qual;

6898

g2qual=zeros(length(tmp),2);

6889

g2qual=zeros(length(tmp),2);

6899

for kk=1:length(tmp)

6890

for kk=1:length(tmp)

6900

if kk==1

6891

if kk==1

6901

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6892

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

6902

else

6893

else

6903

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6894

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

6904

end

6895

end

6905

gqual(kk,:)=sort(gqual(kk,:),'descend');

6896

gqual(kk,:)=sort(gqual(kk,:),'descend');

6906

end

6897

end

6907

6898

6908

%Qual Construction

6899

%Qual Construction

6909

for jj=1:length(g_DC_HP_values)

6900

for jj=1:length(g_DC_HP_values)

6910

for ii=1:length(gdc_values)

6901

for ii=1:length(gdc_values)

6911

for kk=1:size(gqual,1)

6902

for kk=1:size(gqual,1)

6912

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6903

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

6913

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6904

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

6914

qual(jj,ii)=1;

6905

qual(jj,ii)=1;

6915

break;

6906

break;

6916

end

6907

end

6917

end

6908

end

6918

end

6909

end

6919

end

6910

end

6920

end

6911

end

6921

end

6912

end

6922

end

6913

end

6923

6914

6924

progress_interval=0.025;

6915

progress_interval=0.025;

6925

if do_C2M

6916

if do_C2M

6926

loop_count=[1 2];

6917

loop_count=[1 2];

6927

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6918

T_O=floor((param.T_O/1000)*param.samples_per_ui);

6928

T_O=max(0,T_O);

6919

T_O=max(0,T_O);

6929

else

6920

else

6930

loop_count=1;

6921

loop_count=1;

6931

T_O=0;

6922

T_O=0;

6932

end

6923

end

6933

switch param.CTLE_type

6924

switch param.CTLE_type

6934

case 'CL93'

6925

case 'CL93'

6935

lf_indx=1;

6926

lf_indx=1;

6936

case 'CL120d'

6927

case 'CL120d'

6937

lf_indx=length(g_DC_HP_values);

6928

lf_indx=length(g_DC_HP_values);

6938

case 'CL120e'

6929

case 'CL120e'

6939

lf_indx=1;

6930

lf_indx=1;

6940

end

6931

end

6941

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6932

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

6942

if OP.Optimize_loop_speed_up == 1

6933

if OP.Optimize_loop_speed_up == 1

6943

OP.BinSize = 1e-4;

6934

OP.BinSize = 1e-4;

6944

OP.impulse_response_truncation_threshold = 1e-3;

6935

OP.impulse_response_truncation_threshold = 1e-3;

6945

end

6936

end

6946

6937

6947

%Used to speed up FFE by only performing circshift when necessary

6938

%Used to speed up FFE by only performing circshift when necessary

6948

pulse_struc(1).pulse_ctle_circshift=[];

6939

pulse_struc(1).pulse_ctle_circshift=[];

6949

ctle_response_updated=1;

6940

ctle_response_updated=1;

6950

6941

6951

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6942

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

6952

calc_exp_phase=0;

6943

calc_exp_phase=0;

6953

6944

6954

%calculate cur index and pre/post indices outside of the loop

6945

%calculate cur index and pre/post indices outside of the loop

6955

cur_start=cur;

6946

cur_start=cur;

6956

precursor_indices=[];

6947

precursor_indices=[];

6957

postcursor_indices=[];

6948

postcursor_indices=[];

6958

auto_count_trigger=0;

6949

auto_count_trigger=0;

6959

for kv=1:num_taps

6950

for kv=1:num_taps

6960

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6951

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

6961

%precursor values fill the beginning of the vector. Any empty precursor means

6952

%precursor values fill the beginning of the vector. Any empty precursor means

6962

%cursor position must be subtracted by 1

6953

%cursor position must be subtracted by 1

6963

if kv<cur_start

6954

if kv<cur_start

6964

cur=cur-1;

6955

cur=cur-1;

6965

end

6956

end

6966

else

6957

else

6967

%non empty value: add to precursor or postcursor indices depending on position

6958

%non empty value: add to precursor or postcursor indices depending on position

6968

%in the vector

6959

%in the vector

6969

if kv<cur_start

6960

if kv<cur_start

6970

auto_count_trigger=1;

6961

auto_count_trigger=1;

6971

precursor_indices=[precursor_indices kv];

6962

precursor_indices=[precursor_indices kv];

6972

else

6963

else

6973

auto_count_trigger=0;

6964

auto_count_trigger=0;

6974

postcursor_indices=[postcursor_indices kv];

6965

postcursor_indices=[postcursor_indices kv];

6975

end

6966

end

6976

end

6967

end

6977

end

6968

end

6978

if ~isempty(postcursor_indices)

6969

if ~isempty(postcursor_indices)

6979

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6970

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

6980

end

6971

end

6981

6972

6982

%Calculate the full grid matrix of all txffe combinations

6973

%Calculate the full grid matrix of all txffe combinations

6983

if isempty(txffe_cell)

6974

if isempty(txffe_cell)

6984

TXFFE_grid=0;

6975

TXFFE_grid=0;

6985

FULL_tx_index_vector=1;

6976

FULL_tx_index_vector=1;

6986

else

6977

else

6987

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6978

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

6988

%Also calculate the full grid matrix for the index used in each txffe combination

6979

%Also calculate the full grid matrix for the index used in each txffe combination

6989

%(the index is used in the LOCAL SEARCH block)

6980

%(the index is used in the LOCAL SEARCH block)

6990

for k=1:num_taps

6981

for k=1:num_taps

6991

txffe_index_cell{k}=1:txffe_lengths(k);

6982

txffe_index_cell{k}=1:txffe_lengths(k);

6992

end

6983

end

6993

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

6984

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

6994

end

6985

end

6995

6986

6996

%pre-calculate cursor to save time

6987

%pre-calculate cursor to save time

6997

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

6988

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

6998

6989

6999

%pre-calculate full txffe for each iteration to save time

6990

%pre-calculate full txffe for each iteration to save time

7000

precursor_matrix=TXFFE_grid(:,precursor_indices);

6991

precursor_matrix=TXFFE_grid(:,precursor_indices);

7001

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

6992

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7002

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

6993

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7003

6994

7004

if OP.TDMODE

6995

if OP.TDMODE

7005

uneq_field='uneq_pulse_response';

6996

uneq_field='uneq_pulse_response';

7006

ctle_field='ctle_pulse_response';

6997

ctle_field='ctle_pulse_response';

7007

else

6998

else

7008

uneq_field='uneq_imp_response';

6999

uneq_field='uneq_imp_response';

7009

ctle_field='ctle_imp_response';

7000

ctle_field='ctle_imp_response';

7010

end

7001

end

7011

7002

7012

%Speed up search for max(sbr)

7003

%Speed up search for max(sbr)

7013

if OP.TDMODE

7004

if OP.TDMODE

7014

[~,init_max]=max(chdata(1).uneq_pulse_response);

7005

[~,init_max]=max(chdata(1).uneq_pulse_response);

7015

else

7006

else

7016

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7007

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7017

end

7008

end

7018

UI_max_window=20;

7009

UI_max_window=20;

7019

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7010

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7020

if start_max_idx<1

7011

if start_max_idx<1

7021

start_max_idx=1;

7012

start_max_idx=1;

7022

end

7013

end

7023

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7014

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7024

if end_max_idx>length(chdata(1).(uneq_field))

7015

if end_max_idx>length(chdata(1).(uneq_field))

7025

end_max_idx=length(chdata(1).(uneq_field));

7016

end_max_idx=length(chdata(1).(uneq_field));

7026

end

7017

end

7027

7018

7028

itick_skips=0;

7019

itick_skips=0;

7029

itick_cases=0;

7020

itick_cases=0;

7030

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7021

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7031

for i=loop_count

7022

for i=loop_count

7032

7023

7033

for Gffe_index=1:length(Gffe_values)

7024

for Gffe_index=1:length(Gffe_values)

7034

param.current_ffegain=Gffe_values(Gffe_index);

7025

param.current_ffegain=Gffe_values(Gffe_index);

7035

for ctle_index=1:length(gdc_values)

7026

for ctle_index=1:length(gdc_values)

7036

g_dc = gdc_values(ctle_index);

7027

g_dc = gdc_values(ctle_index);

7037

kacdc = 10^(g_dc/20);

7028

kacdc = 10^(g_dc/20);

7038

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7029

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7039

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7030

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7040

CTLE_fz = param.CTLE_fz(ctle_index);

7031

CTLE_fz = param.CTLE_fz(ctle_index);

7041

switch param.CTLE_type

7032

switch param.CTLE_type

7042

case 'CL93'

7033

case 'CL93'

7043

%

7034

%

7044

case 'CL120d'

7035

case 'CL120d'

7045

%

7036

%

7046

case 'CL120e'

7037

case 'CL120e'

7047

HP_Z = param.f_HP_Z(ctle_index);

7038

HP_Z = param.f_HP_Z(ctle_index);

7048

HP_P = param.f_HP_P(ctle_index);

7039

HP_P = param.f_HP_P(ctle_index);

7049

end

7040

end

7050

%% HF Boost

7041

%% HF Boost

7051

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7042

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7052

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7043

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7053

%% Mid Frequency Boost

7044

%% Mid Frequency Boost

7054

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7045

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7055

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7046

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7056

for g_LP_index=1:lf_indx

7047

for g_LP_index=1:lf_indx

7057

7048

7058

%GDC Qual Check

7049

%GDC Qual Check

7059

if qual(g_LP_index,ctle_index)==0

7050

if qual(g_LP_index,ctle_index)==0

7060

pxi=pxi+num_txffe_runs;

7051

pxi=pxi+num_txffe_runs;

7061

continue;

7052

continue;

7062

end

7053

end

7063

7054

7064

switch param.CTLE_type

7055

switch param.CTLE_type

7065

case 'CL93'

7056

case 'CL93'

7066

H_low=1;

7057

H_low=1;

7067

kacde_DC_low=1;

7058

kacde_DC_low=1;

7068

case 'CL120d'

7059

case 'CL120d'

7069

g_DC_low = g_DC_HP_values(g_LP_index);

7060

g_DC_low = g_DC_HP_values(g_LP_index);

7070

f_HP=param.f_HP(g_LP_index);

7061

f_HP=param.f_HP(g_LP_index);

7071

kacde_DC_low = 10^(g_DC_low/20);

7062

kacde_DC_low = 10^(g_DC_low/20);

7072

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7063

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7073

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7064

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7074

case 'CL120e' % z1 has been adusted on read in

7065

case 'CL120e' % z1 has been adusted on read in

7075

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7066

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7076

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7067

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7077

end

7068

end

7078

H_ctf=H_low.*ctle_gain;

7069

H_ctf=H_low.*ctle_gain;

7079

switch upper(OP.FFE_OPT_METHOD)

7070

switch upper(OP.FFE_OPT_METHOD)

7080

case 'WIENER-HOPF'

7071

case 'WIENER-HOPF'

7081

%% Bill Kirkland

7072

%% Bill Kirkland

7082

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7073

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7083

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7074

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7084

% use Fourier Transform pair for correlation as we have to

7075

% use Fourier Transform pair for correlation as we have to

7085

% take ifft of H_r anyways.

7076

% take ifft of H_r anyways.

7086

% onesided and two sided responses - tricky, tricky, tricky

7077

% onesided and two sided responses - tricky, tricky, tricky

7087

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7078

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7088

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7079

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7089

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7080

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7090

7081

7091

if OP.Do_White_Noise

7082

if OP.Do_White_Noise

7092

Noise_XC = Noise_XC(1);

7083

Noise_XC = Noise_XC(1);

7093

end

7084

end

7094

otherwise

7085

otherwise

7095

Noise_XC=[];

7086

Noise_XC=[];

7096

end

7087

end

7097

7088

7098

7089

7099

7090

7100

if OP.INCLUDE_CTLE==1

7091

if OP.INCLUDE_CTLE==1

7101

for k=1:param.num_s4p_files

7092

for k=1:param.num_s4p_files

7102

ir_peak = max(abs(chdata(k).(uneq_field)));

7093

ir_peak = max(abs(chdata(k).(uneq_field)));

7103

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7094

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7104

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7095

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7105

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7096

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7106

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7097

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7107

switch param.CTLE_type

7098

switch param.CTLE_type

7108

case 'CL93'

7099

case 'CL93'

7109

case 'CL120d'

7100

case 'CL120d'

7110

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7101

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7111

case 'CL120e' % z1 has been adusted on read in

7102

case 'CL120e' % z1 has been adusted on read in

7112

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7103

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7113

end

7104

end

7114

end

7105

end

7115

%set the flag to show ctle response was updated

7106

%set the flag to show ctle response was updated

7116

ctle_response_updated=1;

7107

ctle_response_updated=1;

7117

else

7108

else

7118

for k=1:param.num_s4p_files

7109

for k=1:param.num_s4p_files

7119

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7110

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7120

end

7111

end

7121

end

7112

end

7122

for k=1:param.num_s4p_files

7113

for k=1:param.num_s4p_files

7123

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7114

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7124

end

7115

end

7125

%% Equation 93A-22 %%

7116

%% Equation 93A-22 %%

7126

% figure(1000)

7117

% figure(1000)

7127

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7118

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7128

% hold on

7119

% hold on

7129

if OP.RX_CALIBRATION

7120

if OP.RX_CALIBRATION

7130

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7121

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7131

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7122

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7132

switch param.CTLE_type

7123

switch param.CTLE_type

7133

case 'CL93'

7124

case 'CL93'

7134

H_low2=1;

7125

H_low2=1;

7135

case 'CL120d'

7126

case 'CL120d'

7136

g_DC_low = g_DC_HP_values(g_LP_index);

7127

g_DC_low = g_DC_HP_values(g_LP_index);

7137

f_HP=param.f_HP(g_LP_index);

7128

f_HP=param.f_HP(g_LP_index);

7138

kacde_DC_low = 10^(g_DC_low/20);

7129

kacde_DC_low = 10^(g_DC_low/20);

7139

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7130

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7140

case 'CL120e' % z1 has been adusted on read in

7131

case 'CL120e' % z1 has been adusted on read in

7141

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7132

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7142

end

7133

end

7143

H_ctf2=H_low2.*ctle_gain2;

7134

H_ctf2=H_low2.*ctle_gain2;

7144

end

7135

end

7145

% RIM 11-30-2020 moved to a subfunction

7136

% RIM 11-30-2020 moved to a subfunction

7146

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7137

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7147

if OP.RX_CALIBRATION

7138

if OP.RX_CALIBRATION

7148

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7139

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7149

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

7140

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

7150

else

7141

else

7151

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7142

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7152

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7143

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7153

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7144

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7154

sigma_ne=0;

7145

sigma_ne=0;

7155

end

7146

end

7156

7147

7157

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7148

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7158

pxi=pxi+num_txffe_runs;

7149

pxi=pxi+num_txffe_runs;

7159

continue; % change per 0.3k draft 2.3

7150

continue; % change per 0.3k draft 2.3

7160

end

7151

end

7161

%%

7152

%%

7162

PSD_results=[];

7153

PSD_results=[];

7163

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

7154

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

7164

OP.WO_TXFFE=1;

7155

OP.WO_TXFFE=1;

7165

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7156

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7166

end

7157

end

7167

%TXFFE Loop

7158

%TXFFE Loop

7168

%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

7159

%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

7169

for TK=1:size(TXFFE_grid,1)

7160

for TK=1:size(TXFFE_grid,1)

7170

7161

7171

pxi=pxi+1;

7162

pxi=pxi+1;

7172

progress = pxi/runs;

7163

progress = pxi/runs;

7173

if OP.DISPLAY_WINDOW

7164

if OP.DISPLAY_WINDOW

7174

if ~mod(pxi,floor(runs*progress_interval))

7165

if ~mod(pxi,floor(runs*progress_interval))

7175

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7166

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7176

end

7167

end

7177

else

7168

else

7178

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7169

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7179

end

7170

end

7180

7171

7181

%get the cursor for this iteration

7172

%get the cursor for this iteration

7182

txffe_cur=txffe_cursor_vector(TK);

7173

txffe_cur=txffe_cursor_vector(TK);

7183

7174

7184

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7175

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7185

if txffe_cur<param.tx_ffe_c0_min

7176

if txffe_cur<param.tx_ffe_c0_min

7186

continue;

7177

continue;

7187

end

7178

end

7188

old_loops=old_loops+1;

7179

old_loops=old_loops+1;

7189

7180

7190

%get the index used for each tap on this iteration

7181

%get the index used for each tap on this iteration

7191

%this is needed for the LOCAL SEARCH block

7182

%this is needed for the LOCAL SEARCH block

7192

tx_index_vector=FULL_tx_index_vector(TK,:);

7183

tx_index_vector=FULL_tx_index_vector(TK,:);

7193

7184

7194

%Original LOCAL SEARCH Block:

7185

%Original LOCAL SEARCH Block:

7195

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7186

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7196

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7187

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7197

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7188

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7198

% % skip configurations more than

7189

% % skip configurations more than

7199

% % 2 steps away from current "best" point on any grid direction

7190

% % 2 steps away from current "best" point on any grid direction

7200

% % Matt Brown 11/19/2021 for cp2 and cp3

7191

% % Matt Brown 11/19/2021 for cp2 and cp3

7201

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7192

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7202

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7193

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7203

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7194

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7204

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7195

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7205

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7196

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7206

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7197

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7207

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7198

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7208

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7199

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7209

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7200

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7210

%

7201

%

7211

% continue;

7202

% continue;

7212

% end

7203

% end

7213

7204

7214

%Modular LOCAL_SEARCH block:

7205

%Modular LOCAL_SEARCH block:

7215

% speedup "local search" heuristic - Adee Ran 03-17-2020

7206

% speedup "local search" heuristic - Adee Ran 03-17-2020

7216

% skip configurations more than 2 steps away from current "best" point on any grid direction

7207

% skip configurations more than 2 steps away from current "best" point on any grid direction

7217

skip_it=0;

7208

skip_it=0;

7218

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7209

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7219

%instead of looping across all taps, only loop across

7210

%instead of looping across all taps, only loop across

7220

%those with length>1 (txffe_sweep_indices).

7211

%those with length>1 (txffe_sweep_indices).

7221

%It saves time since this block is encountered so often

7212

%It saves time since this block is encountered so often

7222

for kj=1:num_txffe_sweep_indices

7213

for kj=1:num_txffe_sweep_indices

7223

kv=txffe_sweep_indices(kj);

7214

kv=txffe_sweep_indices(kj);

7224

if kv==1

7215

if kv==1

7225

previous_loop_val=g_LP_index;

7216

previous_loop_val=g_LP_index;

7226

else

7217

else

7227

previous_loop_val=tx_index_vector(kv-1);

7218

previous_loop_val=tx_index_vector(kv-1);

7228

end

7219

end

7229

if previous_loop_val>1

7220

if previous_loop_val>1

7230

best_index_this_tap=best_txffe_index(kv);

7221

best_index_this_tap=best_txffe_index(kv);

7231

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7222

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7232

skip_it=1;

7223

skip_it=1;

7233

break;

7224

break;

7234

end

7225

end

7235

end

7226

end

7236

end

7227

end

7237

7228

7238

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7229

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7239

skip_it=1;

7230

skip_it=1;

7240

end

7231

end

7241

end

7232

end

7242

if skip_it

7233

if skip_it

7243

continue;

7234

continue;

7244

end

7235

end

7245

%End Modular LOCAL SEARCH block

7236

%End Modular LOCAL SEARCH block

7246

7237

7247

new_loops=new_loops+1;

7238

new_loops=new_loops+1;

7248

7239

7249

%fetch txffe for this iteration

7240

%fetch txffe for this iteration

7250

txffe=txffe_matrix(TK,:);

7241

txffe=txffe_matrix(TK,:);

7251

7242

7252

%The phase shift exponentials used in get_xtlk_noise are independent of

7243

%The phase shift exponentials used in get_xtlk_noise are independent of

7253

%everything except number of taps and cursor position

7244

%everything except number of taps and cursor position

7254

%So it can be calculated 1 time here to avoid thousands of re-calcs

7245

%So it can be calculated 1 time here to avoid thousands of re-calcs

7255

if ~calc_exp_phase

7246

if ~calc_exp_phase

7256

calc_exp_phase=1;

7247

calc_exp_phase=1;

7257

for k=1:length(txffe)

7248

for k=1:length(txffe)

7258

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7249

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7259

end

7250

end

7260

if OP.RxFFE

7251

if OP.RxFFE

7261

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7252

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7262

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7253

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7263

end

7254

end

7264

phase_memory=[phase_memory phase_memoryRXFFE];

7255

phase_memory=[phase_memory phase_memoryRXFFE];

7265

end

7256

end

7266

end

7257

end

7267

7258

7268

%% Unequalized Pulse Reponse & circshift for FFE

7259

%% Unequalized Pulse Reponse & circshift for FFE

7269

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7260

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7270

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7261

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7271

if ctle_response_updated

7262

if ctle_response_updated

7272

ctle_response_updated=0;

7263

ctle_response_updated=0;

7273

num_pre=cur-1;

7264

num_pre=cur-1;

7274

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7265

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7275

%Calculating here reduces number of convolutions by thousands

7266

%Calculating here reduces number of convolutions by thousands

7276

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

7267

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

7277

ich=1;

7268

ich=1;

7278

else

7269

else

7279

ich=param.num_s4p_files;

7270

ich=param.num_s4p_files;

7280

end

7271

end

7281

for ii=1:ich

7272

for ii=1:ich

7282

if OP.TDMODE

7273

if OP.TDMODE

7283

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7274

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7284

else

7275

else

7285

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7276

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7286

%"conv2" is faster than filter. Just need to chop off extra points at the end

7277

%"conv2" is faster than filter. Just need to chop off extra points at the end

7287

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7278

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7288

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7279

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7289

end

7280

end

7290

for k=1:length(txffe)

7281

for k=1:length(txffe)

7291

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7282

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7292

end

7283

end

7293

end

7284

end

7294

end

7285

end

7295

7286

7296

%% Apply TXFFE to pre-shifted pulse response

7287

%% Apply TXFFE to pre-shifted pulse response

7297

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7288

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7298

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7289

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7299

sbr_from_txffe=sbr;

7290

sbr_from_txffe=sbr;

7300

for ii=1:ich

7291

for ii=1:ich

7301

% this is sbr when ii=1; to be used in get_PSDs

7292

% this is sbr when ii=1; to be used in get_PSDs

7302

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

7293

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

7303

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7294

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7304

else

7295

else

7305

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7296

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7306

end

7297

end

7307

end

7298

end

7308

7299

7309

%% Find Sample Location

7300

%% Find Sample Location

7310

% If RXFFE is included, the sample location will be found again below

7301

% If RXFFE is included, the sample location will be found again below

7311

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7302

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7312

if param.ts_anchor==0

7303

if param.ts_anchor==0

7313

%keep MM

7304

%keep MM

7314

elseif param.ts_anchor==1

7305

elseif param.ts_anchor==1

7315

%peak sample

7306

%peak sample

7316

cursor_i=sbr_peak_i;

7307

cursor_i=sbr_peak_i;

7317

no_zero_crossing=0;

7308

no_zero_crossing=0;

7318

elseif param.ts_anchor==2

7309

elseif param.ts_anchor==2

7319

%max DV

7310

%max DV

7320

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7311

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7321

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7312

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7322

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7313

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7323

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7314

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7324

no_zero_crossing=0;

7315

no_zero_crossing=0;

7325

else

7316

else

7326

error('ts_anchor parameter must be 0, 1, or 2');

7317

error('ts_anchor parameter must be 0, 1, or 2');

7327

end

7318

end

7328

if no_zero_crossing

7319

if no_zero_crossing

7329

continue;

7320

continue;

7330

end

7321

end

7331

raw_cursor_i=cursor_i;

7322

raw_cursor_i=cursor_i;

7332

7323

7333

%%%%%%%%%%

7324

%%%%%%%%%%

7334

%%%%%%%%%%

7325

%%%%%%%%%%

7335

%%%%%%%%%%

7326

%%%%%%%%%%

7336

%NEW ITICK LOOP (not indenting everything yet)

7327

%NEW ITICK LOOP (not indenting everything yet)

7337

[~,si]=sort(abs(full_sample_range));

7328

[~,si]=sort(abs(full_sample_range));

7338

best_positive_itick_FOM=-inf;

7329

best_positive_itick_FOM=-inf;

7339

best_negative_itick_FOM=-inf;

7330

best_negative_itick_FOM=-inf;

7340

best_positive_itick_in_loop=[];

7331

best_positive_itick_in_loop=[];

7341

best_negative_itick_in_loop=[];

7332

best_negative_itick_in_loop=[];

7342

best_itick_FOM=-inf;

7333

best_itick_FOM=-inf;

7343

best_itick_in_cluster=[];

7334

best_itick_in_cluster=[];

7344

best_cluster=[];

7335

best_cluster=[];

7345

7336

7346

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7337

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7347

%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)

7338

%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)

7348

% Commit request4p4_7 healey_3dj_COM_01_240416

7339

% Commit request4p4_7 healey_3dj_COM_01_240416

7349

%box_search=0;

7340

%box_search=0;

7350

%middle_search=1;% should set 0 so all Ts sample points are used

7341

%middle_search=1;% should set 0 so all Ts sample points are used

7351

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7342

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7352

case 'full-sweep'

7343

case 'full-sweep'

7353

box_search=0;

7344

box_search=0;

7354

middle_search=0;

7345

middle_search=0;

7355

case 'middle'

7346

case 'middle'

7356

box_search=0;

7347

box_search=0;

7357

middle_search=1;

7348

middle_search=1;

7358

otherwise

7349

otherwise

7359

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7350

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7360

end

7351

end

7361

if box_search

7352

if box_search

7362

box_size=5;

7353

box_size=5;

7363

box_mid=floor(box_size/2);

7354

box_mid=floor(box_size/2);

7364

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7355

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7365

CL=length(cluster);

7356

CL=length(cluster);

7366

loop_range=1:CL+box_mid*2;

7357

loop_range=1:CL+box_mid*2;

7367

elseif middle_search

7358

elseif middle_search

7368

loop_range=si;

7359

loop_range=si;

7369

else

7360

else

7370

loop_range=1:length(full_sample_range);

7361

loop_range=1:length(full_sample_range);

7371

end

7362

end

7372

7363

7373

for itickn=loop_range

7364

for itickn=loop_range

7374

if box_search

7365

if box_search

7375

if itickn<=CL

7366

if itickn<=CL

7376

itick=cluster(itickn);

7367

itick=cluster(itickn);

7377

else

7368

else

7378

if itickn==CL+1

7369

if itickn==CL+1

7379

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7370

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7380

end

7371

end

7381

if isempty(best_cluster)

7372

if isempty(best_cluster)

7382

continue;

7373

continue;

7383

end

7374

end

7384

itick=best_cluster(itickn-CL);

7375

itick=best_cluster(itickn-CL);

7385

end

7376

end

7386

else

7377

else

7387

itick=full_sample_range(itickn);

7378

itick=full_sample_range(itickn);

7388

end

7379

end

7389

7380

7390

itick_cases=itick_cases+1;

7381

itick_cases=itick_cases+1;

7391

7382

7392

sbr=sbr_from_txffe;

7383

sbr=sbr_from_txffe;

7393

cursor_i = raw_cursor_i+itick;

7384

cursor_i = raw_cursor_i+itick;

7394

7385

7395

%Local Search for +/- itick sweep

7386

%Local Search for +/- itick sweep

7396

if middle_search && param.LOCAL_SEARCH>0

7387

if middle_search && param.LOCAL_SEARCH>0

7397

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7388

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7398

itick_skips=itick_skips+1;

7389

itick_skips=itick_skips+1;

7399

continue;

7390

continue;

7400

end

7391

end

7401

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7392

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7402

itick_skips=itick_skips+1;

7393

itick_skips=itick_skips+1;

7403

continue;

7394

continue;

7404

end

7395

end

7405

end

7396

end

7406

7397

7407

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7398

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7408

if min_number_of_UI_in_response < triple_transit_time

7399

if min_number_of_UI_in_response < triple_transit_time

7409

min_number_of_UI_in_response = triple_transit_time;

7400

min_number_of_UI_in_response = triple_transit_time;

7410

end

7401

end

7411

7402

7412

cursor = sbr(cursor_i);

7403

cursor = sbr(cursor_i);

7413

7404

7414

%% RXFFE

7405

%% RXFFE

7415

if OP.RxFFE

7406

if OP.RxFFE

7416

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7407

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7417

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7408

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7418

%if isrow(sbr), sbr=sbr';end

7409

%if isrow(sbr), sbr=sbr';end

7419

7410

7420

%AJG: do not return sbr here (run time improvement)

7411

%AJG: do not return sbr here (run time improvement)

7421

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7412

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7422

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7413

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7423

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7414

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7424

% sbr at this point include the current setting

7415

% sbr at this point include the current setting

7425

% under consideration of txffe h21 ctf and fr

7416

% under consideration of txffe h21 ctf and fr

7426

switch upper(OP.FFE_OPT_METHOD)

7417

switch upper(OP.FFE_OPT_METHOD)

7427

case 'MMSE'

7418

case 'MMSE'

7428

OP.WO_TXFFE=0;

7419

OP.WO_TXFFE=0;

7429

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7420

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7430

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn+ PSD_results.S_qn ;

7421

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn+ PSD_results.S_qn ;

7431

if 0 % for debug

7422

if 0 % for debug

7432

figure(1010132)

7423

figure(1010132)

7433

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7424

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7434

hold on

7425

hold on

7435

if(PSD_results.S_xn~=0)

7426

if(PSD_results.S_xn~=0)

7436

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7427

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7437

end

7428

end

7438

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7429

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7439

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7430

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7440

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7431

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7441

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_qn*1000/100) ,'disp','Sqn')

7432

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_qn*1000/100) ,'disp','Sqn')

7442

xlim([0 0.5])

7433

xlim([0 0.5])

7443

% ylim([-190 -160])

7434

% ylim([-190 -160])

7444

set(gcf,'defaulttextinterpreter','none')

7435

set(gcf,'defaulttextinterpreter','none')

7445

xlabel('Normalized Frequency')

7436

xlabel('Normalized Frequency')

7446

ylabel('PSD dBm/Hz')

7437

ylabel('PSD dBm/Hz')

7447

hold on

7438

hold on

7448

grid on

7439

grid on

7449

legend show

7440

legend show

7450

title('PSD')

7441

title('PSD')

7451

end

7442

end

7452

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7443

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7453

% floating_tap_locations=MMSE_results.MLSE_results;

7444

% floating_tap_locations=MMSE_results.MLSE_results;

7454

C=MMSE_results.C;

7445

C=MMSE_results.C;

7455

FOM=MMSE_results.FOM;

7446

FOM=MMSE_results.FOM;

7456

floating_tap_locations=MMSE_results.floating_tap_locations;

7447

floating_tap_locations=MMSE_results.floating_tap_locations;

7457

otherwise

7448

otherwise

7458

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7449

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7459

end

7450

end

7460

%Now there is a stand alone function for determining if RXFFE taps are illegal

7451

%Now there is a stand alone function for determining if RXFFE taps are illegal

7461

%This is because the "force" function will also do a legality check when "backoff" is enabled

7452

%This is because the "force" function will also do a legality check when "backoff" is enabled

7462

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

7453

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

7463

if RXFFE_Illegal(C,param)

7454

if RXFFE_Illegal(C,param)

7464

continue;

7455

continue;

7465

end

7456

end

7466

end

7457

end

7467

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7458

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7468

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7459

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7469

if isrow(sbr), sbr=sbr';end

7460

if isrow(sbr), sbr=sbr';end

7470

7461

7471

%% second guess at cursor location (t_s) - based on approximate zero crossing

7462

%% second guess at cursor location (t_s) - based on approximate zero crossing

7472

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7463

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7473

%UPDATE: NOT RESAMPLING AFTER RXFFE

7464

%UPDATE: NOT RESAMPLING AFTER RXFFE

7474

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7465

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7475

% if no_zero_crossing

7466

% if no_zero_crossing

7476

% continue;

7467

% continue;

7477

% end

7468

% end

7478

7469

7479

cursor = sbr(cursor_i);

7470

cursor = sbr(cursor_i);

7480

end

7471

end

7481

A_p=sbr(sbr_peak_i);

7472

A_p=sbr(sbr_peak_i);

7482

%% 93A.1.6 step c defines A_s %%

7473

%% 93A.1.6 step c defines A_s %%

7483

A_s = param.R_LM*cursor/(param.levels-1);

7474

A_s = param.R_LM*cursor/(param.levels-1);

7484

if isempty(delta_sbr)

7475

if isempty(delta_sbr)

7485

delta_sbr = sbr;

7476

delta_sbr = sbr;

7486

end

7477

end

7487

sbr=sbr(:);

7478

sbr=sbr(:);

7488

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7479

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7489

7480

7490

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7481

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7491

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7482

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7492

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)))*...

7483

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)))*...

7493

param.ui/param.samples_per_ui;

7484

param.ui/param.samples_per_ui;

7494

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7485

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7495

precursors = precursors(end:-1:1);

7486

precursors = precursors(end:-1:1);

7496

7487

7497

% % Error message if the sbr is not long enough for the specified range of Nb

7488

% % Error message if the sbr is not long enough for the specified range of Nb

7498

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7489

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7499

% close(hwaitbar);

7490

% close(hwaitbar);

7500

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7491

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7501

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7492

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7502

% end

7493

% end

7503

7494

7504

7495

7505

7496

7506

%% skip this case if FOM has no chance of beating old FOM

7497

%% skip this case if FOM has no chance of beating old FOM

7507

%this is also done below but with excess_dfe_cursors included.

7498

%this is also done below but with excess_dfe_cursors included.

7508

%excess_dfe_cursors requires the floating DFE computation which is

7499

%excess_dfe_cursors requires the floating DFE computation which is

7509

%time consuming, so checking here can have significant run time improvements

7500

%time consuming, so checking here can have significant run time improvements

7510

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7501

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7511

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

7502

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

7512

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7503

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7513

continue

7504

continue

7514

end

7505

end

7515

end

7506

end

7516

7507

7517

%% Equation 93A-27, when 1<=n<=N_b

7508

%% Equation 93A-27, when 1<=n<=N_b

7518

%required length = cursor + all DFE UI + 1 additional UI

7509

%required length = cursor + all DFE UI + 1 additional UI

7519

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7510

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7520

if length(sbr)<sbr_required_length

7511

if length(sbr)<sbr_required_length

7521

sbr(end+1:sbr_required_length)=0;

7512

sbr(end+1:sbr_required_length)=0;

7522

end

7513

end

7523

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7514

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7524

if param.dfe_delta ~= 0

7515

if param.dfe_delta ~= 0

7525

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7516

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7526

7517

7527

else

7518

else

7528

dfecursors_q=dfecursors;

7519

dfecursors_q=dfecursors;

7529

end

7520

end

7530

if param.Floating_DFE

7521

if param.Floating_DFE

7531

%% floating taps

7522

%% floating taps

7532

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7523

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7533

7524

7534

[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 );

7525

[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 );

7535

7526

7536

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7527

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7537

param.use_bmax=newbmax;

7528

param.use_bmax=newbmax;

7538

%AJG021820

7529

%AJG021820

7539

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7530

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7540

else

7531

else

7541

param.use_bmax=param.bmax;

7532

param.use_bmax=param.bmax;

7542

%AJG021820

7533

%AJG021820

7543

param.use_bmin=param.bmin;

7534

param.use_bmin=param.bmin;

7544

end

7535

end

7545

7536

7546

%AJG021820

7537

%AJG021820

7547

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7538

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7548

if do_C2M

7539

if do_C2M

7549

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);

7540

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);

7550

% readjust SBR

7541

% readjust SBR

7551

if 0

7542

if 0

7552

%PR_DFE_center not currently used, so this is in "if 0" statement

7543

%PR_DFE_center not currently used, so this is in "if 0" statement

7553

PR_DFE_center=sbr;

7544

PR_DFE_center=sbr;

7554

for n=1:param.ndfe

7545

for n=1:param.ndfe

7555

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7546

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7556

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7547

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7557

% dper=sbr(i_sample)- actual_dfecursors(n);

7548

% dper=sbr(i_sample)- actual_dfecursors(n);

7558

% PR_DFE_center(i_sample)=dper;

7549

% PR_DFE_center(i_sample)=dper;

7559

% end

7550

% end

7560

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7551

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7561

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7552

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7562

end

7553

end

7563

end

7554

end

7564

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7555

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7565

else

7556

else

7566

excess_dfe_cursors=dfecursors-actual_dfecursors;

7557

excess_dfe_cursors=dfecursors-actual_dfecursors;

7567

end

7558

end

7568

dfetaps=actual_dfecursors/sbr(cursor_i);

7559

dfetaps=actual_dfecursors/sbr(cursor_i);

7569

7560

7570

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7561

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7571

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7562

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7572

if tail_RSS ~= 0

7563

if tail_RSS ~= 0

7573

if tail_RSS >= param.B_float_RSS_MAX

7564

if tail_RSS >= param.B_float_RSS_MAX

7574

param.use_bmax(param.N_tail_start:end)= ...

7565

param.use_bmax(param.N_tail_start:end)= ...

7575

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7566

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7576

%AJG021820

7567

%AJG021820

7577

param.use_bmin(param.N_tail_start:end)= ...

7568

param.use_bmin(param.N_tail_start:end)= ...

7578

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7569

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7579

end

7570

end

7580

end

7571

end

7581

7572

7582

%AJG021820

7573

%AJG021820

7583

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7574

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7584

if do_C2M

7575

if do_C2M

7585

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7576

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7586

else

7577

else

7587

excess_dfe_cursors=dfecursors-actual_dfecursors;

7578

excess_dfe_cursors=dfecursors-actual_dfecursors;

7588

end

7579

end

7589

dfetaps=actual_dfecursors/sbr(cursor_i);

7580

dfetaps=actual_dfecursors/sbr(cursor_i);

7590

7581

7591

else

7582

else

7592

tail_RSS=0;

7583

tail_RSS=0;

7593

end

7584

end

7594

%% Eq. 93A-28 %%

7585

%% Eq. 93A-28 %%

7595

sampling_offset = mod(cursor_i, param.samples_per_ui);

7586

sampling_offset = mod(cursor_i, param.samples_per_ui);

7596

%ensure we can take early sample

7587

%ensure we can take early sample

7597

if sampling_offset<=1

7588

if sampling_offset<=1

7598

sampling_offset=sampling_offset+param.samples_per_ui;

7589

sampling_offset=sampling_offset+param.samples_per_ui;

7599

end

7590

end

7600

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7591

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7601

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7592

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7602

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7593

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7603

else

7594

else

7604

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7595

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7605

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7596

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7606

end

7597

end

7607

% ensure lengths are equal

7598

% ensure lengths are equal

7608

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7599

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7609

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7600

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7610

if ~OP.SNR_TXwC0

7601

if ~OP.SNR_TXwC0

7611

%% Equation 93A-30 %%

7602

%% Equation 93A-30 %%

7612

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7603

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7613

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7604

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7614

else

7605

else

7615

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7606

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7616

end

7607

end

7617

%% Equation 93A-31 %%

7608

%% Equation 93A-31 %%

7618

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7609

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7619

ISI_N=param.sigma_X*norm( far_cursors);

7610

ISI_N=param.sigma_X*norm( far_cursors);

7620

%% break if FOM has no chance of beating old e

7611

%% break if FOM has no chance of beating old e

7621

OP.exe_mode=1;

7612

OP.exe_mode=1;

7622

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

7613

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

7623

switch OP.EXE_MODE

7614

switch OP.EXE_MODE

7624

case 0

7615

case 0

7625

case 1

7616

case 1

7626

if (20*log10(A_s/sigma_ISI) < best_FOM)

7617

if (20*log10(A_s/sigma_ISI) < best_FOM)

7627

continue

7618

continue

7628

end

7619

end

7629

case 2

7620

case 2

7630

if (20*log10(A_s/sigma_ISI) < best_FOM)

7621

if (20*log10(A_s/sigma_ISI) < best_FOM)

7631

break

7622

break

7632

end

7623

end

7633

end

7624

end

7634

end

7625

end

7635

%% Equation 93A-32 %%

7626

%% Equation 93A-32 %%

7636

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7627

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7637

7628

7638

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7629

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7639

if OP.RX_CALIBRATION

7630

if OP.RX_CALIBRATION

7640

sigma_XT=0;

7631

sigma_XT=0;

7641

else

7632

else

7642

if ~OP.RxFFE

7633

if ~OP.RxFFE

7643

[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

7634

[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

7644

%% Equation 93A-36 denominator (actually its sqrt)

7635

%% Equation 93A-36 denominator (actually its sqrt)

7645

else % John Ewen: 13/12/20018

7636

else % John Ewen: 13/12/20018

7646

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7637

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7647

[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

7638

[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

7648

else % use results from get_PSDs RIM 3/28/2024

7639

else % use results from get_PSDs RIM 3/28/2024

7649

sigma_XT=PSD_results.S_xn_rms;

7640

sigma_XT=PSD_results.S_xn_rms;

7650

end

7641

end

7651

end

7642

end

7652

end

7643

end

7653

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

7644

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

7654

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7645

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7655

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7646

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7656

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7647

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7657

f=chdata(1).faxis;

7648

f=chdata(1).faxis;

7658

H_Rx_FFE=zeros(1,length(f));

7649

H_Rx_FFE=zeros(1,length(f));

7659

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7650

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7660

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7651

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7661

if C(ii+param.RxFFE_cmx+1)==0

7652

if C(ii+param.RxFFE_cmx+1)==0

7662

%speed up: skip cases when rxffe=0

7653

%speed up: skip cases when rxffe=0

7663

continue;

7654

continue;

7664

end

7655

end

7665

if ii+1==0

7656

if ii+1==0

7666

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7657

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7667

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7658

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7668

else

7659

else

7669

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7660

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7670

end

7661

end

7671

end

7662

end

7672

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

7663

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

7673

end

7664

end

7674

end

7665

end

7675

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7666

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7676

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

7667

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

7677

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7668

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7678

else

7669

else

7679

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7670

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7680

end

7671

end

7681

if do_C2M

7672

if do_C2M

7682

if param.Noise_Crest_Factor == 0

7673

if param.Noise_Crest_Factor == 0

7683

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7674

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7684

else

7675

else

7685

ber_q=param.Noise_Crest_Factor;

7676

ber_q=param.Noise_Crest_Factor;

7686

end

7677

end

7687

if OP.force_pdf_bin_size

7678

if OP.force_pdf_bin_size

7688

delta_y = OP.BinSize;

7679

delta_y = OP.BinSize;

7689

else

7680

else

7690

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

7681

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

7691

end

7682

end

7692

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7683

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7693

cci_pdf = normal_dist(0, ber_q, delta_y);

7684

cci_pdf = normal_dist(0, ber_q, delta_y);

7694

chdata(1).eq_pulse_response=sbr;

7685

chdata(1).eq_pulse_response=sbr;

7695

tmp_result.t_s= cursor_i;

7686

tmp_result.t_s= cursor_i;

7696

tmp_result.A_s=A_s;

7687

tmp_result.A_s=A_s;

7697

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7688

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7698

if EH_1st <= param.Min_VEO_Test/1000 -.001

7689

if EH_1st <= param.Min_VEO_Test/1000 -.001

7699

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7690

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7700

continue

7691

continue

7701

else

7692

else

7702

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7693

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7703

end

7694

end

7704

Struct_Noise.sigma_N=sigma_N;

7695

Struct_Noise.sigma_N=sigma_N;

7705

Struct_Noise.sigma_TX=sigma_TX;

7696

Struct_Noise.sigma_TX=sigma_TX;

7706

Struct_Noise.cci_pdf=cci_pdf;

7697

Struct_Noise.cci_pdf=cci_pdf;

7707

Struct_Noise.ber_q=ber_q;

7698

Struct_Noise.ber_q=ber_q;

7708

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7699

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7709

[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);

7700

[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);

7710

EH=EH_T_C2M-EH_B_C2M;

7701

EH=EH_T_C2M-EH_B_C2M;

7711

N_i=(A_s*2-EH)/2;

7702

N_i=(A_s*2-EH)/2;

7712

if EH <= param.Min_VEO_Test/1000

7703

if EH <= param.Min_VEO_Test/1000

7713

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7704

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7714

continue

7705

continue

7715

else

7706

else

7716

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7707

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7717

end

7708

end

7718

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7709

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7719

FOM =20*log10(A_s/N_i);

7710

FOM =20*log10(A_s/N_i);

7720

end

7711

end

7721

else

7712

else

7722

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7713

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7723

FOM = 20*log10(A_s/total_noise_rms);

7714

FOM = 20*log10(A_s/total_noise_rms);

7724

end

7715

end

7725

% if strfind(param.CTLE_type,'CL120e')

7716

% if strfind(param.CTLE_type,'CL120e')

7726

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7717

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7727

end

7718

end

7728

if 0 % for loop analysis

7719

if 0 % for loop analysis

7729

result.FOM_array(new_loops)=FOM;

7720

result.FOM_array(new_loops)=FOM;

7730

end

7721

end

7731

7722

7732

if FOM>best_itick_FOM

7723

if FOM>best_itick_FOM

7733

best_itick_FOM=FOM;

7724

best_itick_FOM=FOM;

7734

best_itick_in_cluster=itick;

7725

best_itick_in_cluster=itick;

7735

end

7726

end

7736

7727

7737

if itick>=0 && FOM>best_positive_itick_FOM

7728

if itick>=0 && FOM>best_positive_itick_FOM

7738

best_positive_itick_FOM=FOM;

7729

best_positive_itick_FOM=FOM;

7739

best_positive_itick_in_loop=itick;

7730

best_positive_itick_in_loop=itick;

7740

end

7731

end

7741

if itick<=0 && FOM>best_negative_itick_FOM

7732

if itick<=0 && FOM>best_negative_itick_FOM

7742

best_negative_itick_FOM=FOM;

7733

best_negative_itick_FOM=FOM;

7743

best_negative_itick_in_loop=itick;

7734

best_negative_itick_in_loop=itick;

7744

end

7735

end

7745

7736

7746

itick_index=find(itick==full_sample_range);

7737

itick_index=find(itick==full_sample_range);

7747

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7738

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7748

7739

7749

if (FOM > best_FOM)

7740

if (FOM > best_FOM)

7750

best_current_ffegain=param.current_ffegain;

7741

best_current_ffegain=param.current_ffegain;

7751

best_txffe = txffe;

7742

best_txffe = txffe;

7752

%along with best_txffe, save the indices of the best_txffe

7743

%along with best_txffe, save the indices of the best_txffe

7753

%(saves time in LOCAL SEARCH block)

7744

%(saves time in LOCAL SEARCH block)

7754

best_txffe_index=tx_index_vector;

7745

best_txffe_index=tx_index_vector;

7755

best_sbr = sbr;

7746

best_sbr = sbr;

7756

best_ctle = ctle_index;

7747

best_ctle = ctle_index;

7757

best_G_high_pass =g_LP_index;

7748

best_G_high_pass =g_LP_index;

7758

best_FOM = FOM;

7749

best_FOM = FOM;

7759

best_cursor_i = cursor_i;

7750

best_cursor_i = cursor_i;

7760

best_itick = itick;

7751

best_itick = itick;

7761

if ~OP.TDMODE

7752

if ~OP.TDMODE

7762

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7753

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7763

best_IR=effective_channel;

7754

best_IR=effective_channel;

7764

end

7755

end

7765

best_sigma_N = sigma_N;

7756

best_sigma_N = sigma_N;

7766

best_h_J = h_J;

7757

best_h_J = h_J;

7767

best_A_s=A_s;

7758

best_A_s=A_s;

7768

best_A_p=A_p;

7759

best_A_p=A_p;

7769

best_ISI=ISI_N;

7760

best_ISI=ISI_N;

7770

best_bmax=param.use_bmax;

7761

best_bmax=param.use_bmax;

7771

%AJG021820

7762

%AJG021820

7772

best_bmin=param.use_bmin;

7763

best_bmin=param.use_bmin;

7773

best_tail_RSS=tail_RSS;

7764

best_tail_RSS=tail_RSS;

7774

best_dfetaps=dfetaps;

7765

best_dfetaps=dfetaps;

7775

if param.Floating_DFE

7766

if param.Floating_DFE

7776

best_floating_tap_locations=floating_tap_locations;

7767

best_floating_tap_locations=floating_tap_locations;

7777

best_floating_tap_coef=floating_tap_coef;

7768

best_floating_tap_coef=floating_tap_coef;

7778

end

7769

end

7779

if param.Floating_RXFFE

7770

if param.Floating_RXFFE

7780

best_floating_tap_locations=floating_tap_locations;

7771

best_floating_tap_locations=floating_tap_locations;

7781

% best_floating_tap_coef=floating_tap_coef;

7772

% best_floating_tap_coef=floating_tap_coef;

7782

end

7773

end

7783

if OP.RxFFE

7774

if OP.RxFFE

7784

best_RxFFE=C;

7775

best_RxFFE=C;

7785

best_PSD_results=PSD_results;

7776

best_PSD_results=PSD_results;

7786

best_MMSE_results=MMSE_results;

7777

best_MMSE_results=MMSE_results;

7787

end

7778

end

7788

end

7779

end

7789

end

7780

end

7790

end

7781

end

7791

7782

7792

end

7783

end

7793

end

7784

end

7794

end

7785

end

7795

if do_C2M

7786

if do_C2M

7796

if best_FOM == -inf

7787

if best_FOM == -inf

7797

param.Min_VEO_Test=0;

7788

param.Min_VEO_Test=0;

7798

else

7789

else

7799

break

7790

break

7800

end

7791

end

7801

end

7792

end

7802

end

7793

end

7803

if 0

7794

if 0

7804

fprintf('old loops = %d\n',old_loops);

7795

fprintf('old loops = %d\n',old_loops);

7805

fprintf('new loops = %d\n',new_loops);

7796

fprintf('new loops = %d\n',new_loops);

7806

display(sprintf('\n :loops = %g',pxi))

7797

display(sprintf('\n :loops = %g',pxi))

7807

end

7798

end

7808

7799

7809

%turn this on to review if FOM changes sign more than once in an itick loop

7800

%turn this on to review if FOM changes sign more than once in an itick loop

7810

if 0

7801

if 0

7811

DIR_CHANGE={};

7802

DIR_CHANGE={};

7812

for m=1:length(Gffe_values)

7803

for m=1:length(Gffe_values)

7813

for n=1:length(gdc_values)

7804

for n=1:length(gdc_values)

7814

for k=1:lf_indx

7805

for k=1:lf_indx

7815

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7806

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

7816

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7807

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

7817

%1 = goes up, -1=goes down

7808

%1 = goes up, -1=goes down

7818

x=sign(diff(FOM_this_mat')');

7809

x=sign(diff(FOM_this_mat')');

7819

%y = change in sign on x. the location of a "2" is where FOM changes direction

7810

%y = change in sign on x. the location of a "2" is where FOM changes direction

7820

y=abs(diff(x'))';

7811

y=abs(diff(x'))';

7821

%the goal is the FOM only changes direction once. so count the occurences of the 2

7812

%the goal is the FOM only changes direction once. so count the occurences of the 2

7822

for j=1:size(FOM_this_mat,1)

7813

for j=1:size(FOM_this_mat,1)

7823

z{j}=find(y(j,:)==2);

7814

z{j}=find(y(j,:)==2);

7824

end

7815

end

7825

zL=cellfun('length',z);

7816

zL=cellfun('length',z);

7826

%return any row where FOM changed direction more than once

7817

%return any row where FOM changed direction more than once

7827

DIR_CHANGE{j,k}=find(zL>1);

7818

DIR_CHANGE{j,k}=find(zL>1);

7828

end

7819

end

7829

end

7820

end

7830

end

7821

end

7831

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7822

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

7832

end

7823

end

7833

7824

7834

if ~exist('best_cursor_i', 'var')% take last setting

7825

if ~exist('best_cursor_i', 'var')% take last setting

7835

result.eq_failed=true;

7826

result.eq_failed=true;

7836

display('equalization failed')

7827

display('equalization failed')

7837

best_bmax=param.bmax;

7828

best_bmax=param.bmax;

7838

%AJG021820

7829

%AJG021820

7839

best_bmin=param.bmin;

7830

best_bmin=param.bmin;

7840

best_tail_RSS=0;

7831

best_tail_RSS=0;

7841

best_current_ffegain=0;

7832

best_current_ffegain=0;

7842

best_txffe = txffe;

7833

best_txffe = txffe;

7843

best_sbr = sbr;

7834

best_sbr = sbr;

7844

best_ctle = ctle_index;

7835

best_ctle = ctle_index;

7845

if OP.RxFFE

7836

if OP.RxFFE

7846

best_PSD_results=PSD_results;

7837

best_PSD_results=PSD_results;

7847

best_MMSE_results=MMSE_results;

7838

best_MMSE_results=MMSE_results;

7848

best_RxFFE=C;

7839

best_RxFFE=C;

7849

end

7840

end

7850

best_G_high_pass =g_LP_index;

7841

best_G_high_pass =g_LP_index;

7851

best_FOM = FOM;

7842

best_FOM = FOM;

7852

%if this block is reached, the last encountered EQ parameters are used

7843

%if this block is reached, the last encountered EQ parameters are used

7853

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7844

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

7854

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7845

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

7855

if isempty(cursor_i)

7846

if isempty(cursor_i)

7856

[~,cursor_i]=max(sbr);

7847

[~,cursor_i]=max(sbr);

7857

end

7848

end

7858

best_cursor_i = cursor_i;

7849

best_cursor_i = cursor_i;

7859

best_itick = itick;

7850

best_itick = itick;

7860

if ~OP.TDMODE

7851

if ~OP.TDMODE

7861

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7852

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7862

best_IR=effective_channel;

7853

best_IR=effective_channel;

7863

end

7854

end

7864

best_sigma_N = sigma_N;

7855

best_sigma_N = sigma_N;

7865

best_h_J = h_J;

7856

best_h_J = h_J;

7866

best_A_p=max(sbr);

7857

best_A_p=max(sbr);

7867

best_ISI=1;

7858

best_ISI=1;

7868

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) ;

7859

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) ;

7869

best_A_s= sbr( cursor_i);

7860

best_A_s= sbr( cursor_i);

7870

if param.Floating_DFE

7861

if param.Floating_DFE

7871

best_floating_tap_locations=[];

7862

best_floating_tap_locations=[];

7872

best_floating_tap_coef=[];

7863

best_floating_tap_coef=[];

7873

end

7864

end

7874

if do_C2M

7865

if do_C2M

7875

return

7866

return

7876

end

7867

end

7877

% return

7868

% return

7878

else

7869

else

7879

result.eq_failed=false; % RIM 12/30/2023

7870

result.eq_failed=false; % RIM 12/30/2023

7880

end

7871

end

7881

7872

7882

best_cursor = best_sbr(best_cursor_i);

7873

best_cursor = best_sbr(best_cursor_i);

7883

% report during debug

7874

% report during debug

7884

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

7875

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

7885

%If sbr was zero padded, then PRin needs to do so as well)

7876

%If sbr was zero padded, then PRin needs to do so as well)

7886

if length(PRin)<length(best_sbr)

7877

if length(PRin)<length(best_sbr)

7887

PRin(end+1:length(best_sbr))=0;

7878

PRin(end+1:length(best_sbr))=0;

7888

end

7879

end

7889

f=1e8:1e8:100e9;

7880

f=1e8:1e8:100e9;

7890

7881

7891

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

7882

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

7892

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

7883

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

7893

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7884

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7894

% need to include H_RCos in noise and when computing the system ir for thru

7885

% need to include H_RCos in noise and when computing the system ir for thru

7895

% and crosstalk

7886

% and crosstalk

7896

H_r=H_bw.*H_bt.*H_RCos;

7887

H_r=H_bw.*H_bt.*H_RCos;

7897

7888

7898

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7889

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

7899

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7890

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

7900

7891

7901

switch param.CTLE_type

7892

switch param.CTLE_type

7902

case 'CL93'

7893

case 'CL93'

7903

H_low=1;

7894

H_low=1;

7904

case 'CL120d'

7895

case 'CL120d'

7905

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));

7896

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));

7906

case 'CL120e'

7897

case 'CL120e'

7907

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7898

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

7908

end

7899

end

7909

ctle_gain=H_low.*ctle_gain1.*H_r;

7900

ctle_gain=H_low.*ctle_gain1.*H_r;

7910

7901

7911

7902

7912

7903

7913

%lsbr=length(sbr);

7904

%lsbr=length(sbr);

7914

%use length of best_sbr in case zero padding was performed

7905

%use length of best_sbr in case zero padding was performed

7915

%check "sbr_required_length" variable

7906

%check "sbr_required_length" variable

7916

lsbr=length(best_sbr);

7907

lsbr=length(best_sbr);

7917

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7908

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

7918

7909

7919

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7910

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

7920

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7911

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

7921

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7912

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

7922

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7913

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

7923

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7914

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

7924

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7915

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

7925

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7916

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

7926

if param.Floating_DFE

7917

if param.Floating_DFE

7927

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7918

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

7928

end

7919

end

7929

% apply max tap value constraint

7920

% apply max tap value constraint

7930

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7921

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

7931

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7922

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

7932

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7923

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

7933

7924

7934

%AJG021820

7925

%AJG021820

7935

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7926

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

7936

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7927

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

7937

if param.Floating_DFE

7928

if param.Floating_DFE

7938

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7929

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

7939

end

7930

end

7940

7931

7941

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7932

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

7942

Symbol_Adj = (param.levels-1);% 3A.1.6

7933

Symbol_Adj = (param.levels-1);% 3A.1.6

7943

if OP.DEBUG ~=0

7934

if OP.DEBUG ~=0

7944

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7935

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

7945

% display pulse responses in one axis per test case.

7936

% display pulse responses in one axis per test case.

7946

switch upper(OP.TIME_AXIS)

7937

switch upper(OP.TIME_AXIS)

7947

case 'S' % RIM 11-13-2023 added user selectable xaxis

7938

case 'S' % RIM 11-13-2023 added user selectable xaxis

7948

xnorm=1;

7939

xnorm=1;

7949

xaxis_label='seconds';

7940

xaxis_label='seconds';

7950

offset=0;

7941

offset=0;

7951

case 'UI'

7942

case 'UI'

7952

xnorm=param.ui;

7943

xnorm=param.ui;

7953

xaxis_label='UI';

7944

xaxis_label='UI';

7954

offset=t(best_cursor_i)/xnorm;

7945

offset=t(best_cursor_i)/xnorm;

7955

otherwise

7946

otherwise

7956

xnorm=1;

7947

xnorm=1;

7957

xaxis_label='seconds';

7948

xaxis_label='seconds';

7958

offset=0;

7949

offset=0;

7959

end

7950

end

7960

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7951

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

7961

fig=findobj('Name', figure_name);

7952

fig=findobj('Name', figure_name);

7962

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

7953

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

7963

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

7954

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

7964

movegui(fig,'north')

7955

movegui(fig,'north')

7965

%figure(fig.Number);

7956

%figure(fig.Number);

7966

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7957

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

7967

if OP.RxFFE

7958

if OP.RxFFE

7968

ax1=subplot(2,1,1);

7959

ax1=subplot(2,1,1);

7969

end

7960

end

7970

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7961

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

7971

hold on

7962

hold on

7972

7963

7973

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7964

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

7974

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7965

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

7975

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7966

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

7976

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7967

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

7977

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7968

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

7978

ylabel('volts')

7969

ylabel('volts')

7979

xlabel(xaxis_label)

7970

xlabel(xaxis_label)

7980

grid on

7971

grid on

7981

legend show

7972

legend show

7982

legend( 'Location', 'best')

7973

legend( 'Location', 'best')

7983

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7974

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

7984

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7975

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

7985

if param.ndfe_passed ~=0

7976

if param.ndfe_passed ~=0

7986

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');

7977

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');

7987

end

7978

end

7988

if param.Floating_DFE

7979

if param.Floating_DFE

7989

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');

7980

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');

7990

end

7981

end

7991

if OP.RxFFE

7982

if OP.RxFFE

7992

ax2=subplot(2,1,2);

7983

ax2=subplot(2,1,2);

7993

if param.Floating_RXFFE

7984

if param.Floating_RXFFE

7994

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

7985

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

7995

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

7986

stem((t(best_cursor_i+(best_floating_tap_locations-param.RxFFE_cmx-1)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

7996

,'filled','disp','RxFFE floating FFE taps')

7987

,'filled','disp','RxFFE floating FFE taps')

7997

hold on

7988

hold on

7998

end

7989

end

7999

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)...

7990

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)...

8000

,'filled','disp','RxFFE fixted FFE taps')

7991

,'filled','disp','RxFFE fixted FFE taps')

8001

legend show

7992

legend show

8002

zoom xon

7993

zoom xon

8003

linkaxes([ax1 ax2],'x')

7994

linkaxes([ax1 ax2],'x')

8004

end

7995

end

8005

7996

8006

7997

8007

grid on

7998

grid on

8008

legend show

7999

legend show

8009

legend( 'Location', 'best')

8000

legend( 'Location', 'best')

8010

zoom xon

8001

zoom xon

8011

% set(hax, 'tag', 'EQE');

8002

% set(hax, 'tag', 'EQE');

8012

%

8003

%

8013

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

8004

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

8014

set(gcf, 'Name', 'CTLE selection');

8005

set(gcf, 'Name', 'CTLE selection');

8015

movegui(gcf, 'southeast');

8006

movegui(gcf, 'southeast');

8016

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8007

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8017

hold on

8008

hold on

8018

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8009

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8019

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8010

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8020

fbaud_tick=find(f >= baud_rate, 1);

8011

fbaud_tick=find(f >= baud_rate, 1);

8021

fnq_tick=find(f >= baud_rate/2, 1);

8012

fnq_tick=find(f >= baud_rate/2, 1);

8022

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8013

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8023

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8014

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8024

recolor_plots(gca);

8015

recolor_plots(gca);

8025

title('CTF/w Rx Filter Response')

8016

title('CTF/w Rx Filter Response')

8026

ylabel('dB')

8017

ylabel('dB')

8027

xlabel('Hz')

8018

xlabel('Hz')

8028

legend show

8019

legend show

8029

end

8020

end

8030

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8021

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8031

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8022

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8032

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8023

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8033

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8024

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8034

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8025

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8035

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8026

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8036

end

8027

end

8037

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

8028

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

8038

eqe_axes = findobj('tag', 'EQE');

8029

eqe_axes = findobj('tag', 'EQE');

8039

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8030

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8040

end

8031

end

8041

if OP.DISPLAY_WINDOW

8032

if OP.DISPLAY_WINDOW

8042

close(hwaitbar);

8033

close(hwaitbar);

8043

else

8034

else

8044

fprintf('\n');

8035

fprintf('\n');

8045

end

8036

end

8046

8037

8047

% % eq_data

8038

% % eq_data

8048

result.cur=cur;

8039

result.cur=cur;

8049

result.txffe = best_txffe;

8040

result.txffe = best_txffe;

8050

result.ctle = best_ctle;

8041

result.ctle = best_ctle;

8051

result.best_G_high_pass=best_G_high_pass;

8042

result.best_G_high_pass=best_G_high_pass;

8052

result.DFE_taps = best_dfetaps; %relative

8043

result.DFE_taps = best_dfetaps; %relative

8053

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8044

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8054

if param.Floating_DFE

8045

if param.Floating_DFE

8055

result.floating_tap_locations=best_floating_tap_locations;

8046

result.floating_tap_locations=best_floating_tap_locations;

8056

result.floating_tap_coef=best_floating_tap_coef;

8047

result.floating_tap_coef=best_floating_tap_coef;

8057

end

8048

end

8058

if param.Floating_RXFFE

8049

if param.Floating_RXFFE

8059

result.floating_tap_locations=best_floating_tap_locations;

8050

result.floating_tap_locations=best_floating_tap_locations;

8060

end

8051

end

8061

result.A_s = best_A_s;

8052

result.A_s = best_A_s;

8062

result.t_s = best_cursor_i;

8053

result.t_s = best_cursor_i;

8063

result.itick = best_itick;

8054

result.itick = best_itick;

8064

result.sigma_N = best_sigma_N;

8055

result.sigma_N = best_sigma_N;

8065

result.h_J = best_h_J;

8056

result.h_J = best_h_J;

8066

result.FOM = best_FOM;

8057

result.FOM = best_FOM;

8067

if ~OP.TDMODE

8058

if ~OP.TDMODE

8068

%If sbr was zero padded, then best_IR needs to do so as well)

8059

%If sbr was zero padded, then best_IR needs to do so as well)

8069

if length(best_IR)<length(best_sbr)

8060

if length(best_IR)<length(best_sbr)

8070

best_IR(end+1:length(best_sbr))=0;

8061

best_IR(end+1:length(best_sbr))=0;

8071

end

8062

end

8072

result.IR = best_IR;

8063

result.IR = best_IR;

8073

end

8064

end

8074

result.t=t;

8065

result.t=t;

8075

result.sbr=best_sbr;

8066

result.sbr=best_sbr;

8076

if OP.RxFFE

8067

if OP.RxFFE

8077

result.RxFFE=best_RxFFE;

8068

result.RxFFE=best_RxFFE;

8078

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8069

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8079

result.PSD_results=best_PSD_results;

8070

result.PSD_results=best_PSD_results;

8080

result.MMSE_results=best_MMSE_results;

8071

result.MMSE_results=best_MMSE_results;

8081

end

8072

end

8082

end

8073

end

8083

8074

8084

8075

8085

8076

8086

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8077

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8087

% updated RIM 12/17/2021

8078

% updated RIM 12/17/2021

8088

result.A_p = max(chdata(1).uneq_pulse_response);

8079

result.A_p = max(chdata(1).uneq_pulse_response);

8089

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8080

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8090

PR=chdata(1).uneq_pulse_response;

8081

PR=chdata(1).uneq_pulse_response;

8091

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8082

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8092

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8083

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8093

if iend >= length(PR)

8084

if iend >= length(PR)

8094

iend = length (PR);

8085

iend = length (PR);

8095

end

8086

end

8096

if ibeg < 1

8087

if ibeg < 1

8097

ibeg = 1;

8088

ibeg = 1;

8098

end

8089

end

8099

PR=PR(ibeg:iend);

8090

PR=PR(ibeg:iend);

8100

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8091

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8101

SRn=PR;

8092

SRn=PR;

8102

for ik=1:floor(length(PR)/param.samples_per_ui)

8093

for ik=1:floor(length(PR)/param.samples_per_ui)

8103

SPR=circshift(PR,param.samples_per_ui*ik);

8094

SPR=circshift(PR,param.samples_per_ui*ik);

8104

SPR(1:ik*param.samples_per_ui)=0;

8095

SPR(1:ik*param.samples_per_ui)=0;

8105

SRn=SRn+ SPR;

8096

SRn=SRn+ SPR;

8106

end

8097

end

8107

codedebug=0;

8098

codedebug=0;

8108

if codedebug

8099

if codedebug

8109

fig=figure('Name', 'step and pulse response for code debug');

8100

fig=figure('Name', 'step and pulse response for code debug');

8110

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

8101

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

8111

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8102

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8112

plot(UI,SRn)

8103

plot(UI,SRn)

8113

hold on

8104

hold on

8114

plot(UI,PR)

8105

plot(UI,PR)

8115

xlim([-param.D_p param.N_v])

8106

xlim([-param.D_p param.N_v])

8116

grid on;hold off;

8107

grid on;hold off;

8117

result.step=SRn;

8108

result.step=SRn;

8118

end

8109

end

8119

i20=find(SRn>=0.20*result.A_f,1,'first');

8110

i20=find(SRn>=0.20*result.A_f,1,'first');

8120

i80=find(SRn>=0.80*result.A_f,1,'first');

8111

i80=find(SRn>=0.80*result.A_f,1,'first');

8121

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8112

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8122

result.Pmax_by_Vf=result.A_p/result.A_f;

8113

result.Pmax_by_Vf=result.A_p/result.A_f;

8123

result.ISI =best_ISI;

8114

result.ISI =best_ISI;

8124

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8115

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8125

result.best_current_ffegain=best_current_ffegain;

8116

result.best_current_ffegain=best_current_ffegain;

8126

result.best_bmax=best_bmax;

8117

result.best_bmax=best_bmax;

8127

%AJG021820

8118

%AJG021820

8128

result.best_bmin=best_bmin;

8119

result.best_bmin=best_bmin;

8129

result.tail_RSS=best_tail_RSS;

8120

result.tail_RSS=best_tail_RSS;

8130

result.sampled_best_sbr_precursors_t=sampled_best_sbr_precursors_t;

8121

result.sampled_best_sbr_precursors_t=sampled_best_sbr_precursors_t;

8131

result.sampled_best_sbr_postcursors_t=sampled_best_sbr_postcursors_t;

8122

result.sampled_best_sbr_postcursors_t=sampled_best_sbr_postcursors_t;

8132

function param=parameter_size_adjustment(param,OP)

8123

function param=parameter_size_adjustment(param,OP)

8133

8124

8134

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'};

8125

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'};

8135

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8126

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8136

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8127

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8137

make_length_DCHP={'f_HP'};

8128

make_length_DCHP={'f_HP'};

8138

make_length_ncases={'AC_CM_RMS'};

8129

make_length_ncases={'AC_CM_RMS'};

8139

8130

8140

%ncases used by make_length_ncases fields

8131

%ncases used by make_length_ncases fields

8141

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8132

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8142

8133

8143

%PORTZ_mult used by make_length_WCPORTZ fields

8134

%PORTZ_mult used by make_length_WCPORTZ fields

8144

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8135

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8145

if OP.WC_PORTZ

8136

if OP.WC_PORTZ

8146

PORTZ_mult=[1 1];

8137

PORTZ_mult=[1 1];

8147

else

8138

else

8148

PORTZ_mult=pkg_sel_vec;

8139

PORTZ_mult=pkg_sel_vec;

8149

end

8140

end

8150

8141

8151

%Parameters that have length = 2

8142

%Parameters that have length = 2

8152

for j=1:length(make_length2)

8143

for j=1:length(make_length2)

8153

if numel(param.(make_length2{j}))==1

8144

if numel(param.(make_length2{j}))==1

8154

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8145

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8155

end

8146

end

8156

end

8147

end

8157

8148

8158

%Parameters that have length = ncases

8149

%Parameters that have length = ncases

8159

for j=1:length(make_length_ncases)

8150

for j=1:length(make_length_ncases)

8160

if numel(param.(make_length_ncases{j}))==1

8151

if numel(param.(make_length_ncases{j}))==1

8161

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8152

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8162

end

8153

end

8163

end

8154

end

8164

8155

8165

%Parameters that have length = length(ctle_gdc_values)

8156

%Parameters that have length = length(ctle_gdc_values)

8166

for j=1:length(make_length_GDC)

8157

for j=1:length(make_length_GDC)

8167

if numel(param.(make_length_GDC{j}))==1

8158

if numel(param.(make_length_GDC{j}))==1

8168

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8159

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8169

end

8160

end

8170

end

8161

end

8171

8162

8172

%Parameters that have length = length(g_DC_HP_values)

8163

%Parameters that have length = length(g_DC_HP_values)

8173

for j=1:length(make_length_DCHP)

8164

for j=1:length(make_length_DCHP)

8174

if numel(param.(make_length_DCHP{j}))==1

8165

if numel(param.(make_length_DCHP{j}))==1

8175

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8166

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8176

end

8167

end

8177

end

8168

end

8178

8169

8179

%Parameters that have length associated with PORTZ_mult

8170

%Parameters that have length associated with PORTZ_mult

8180

for j=1:length(make_length_WCPORTZ)

8171

for j=1:length(make_length_WCPORTZ)

8181

if numel(param.(make_length_WCPORTZ{j}))==1

8172

if numel(param.(make_length_WCPORTZ{j}))==1

8182

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8173

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8183

end

8174

end

8184

end

8175

end

8185

function sgm = pdf2sgm(pdf)

8176

function sgm = pdf2sgm(pdf)

8186

avg = sum(pdf.x .* pdf.y);

8177

avg = sum(pdf.x .* pdf.y);

8187

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8178

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8188

% end yasuo patch

8179

% end yasuo patch

8189

8180

8190

8181

8191

%% adding tx packgage

8182

%% adding tx packgage

8192

function cdf=pdf_to_cdf(pdf)

8183

function cdf=pdf_to_cdf(pdf)

8193

8184

8194

%Transform PDF to CDF

8185

%Transform PDF to CDF

8195

%The CDF is natively calculated from negative-to-positive voltage.

8186

%The CDF is natively calculated from negative-to-positive voltage.

8196

%This only gives BER calculation for bottom eye. Need to also

8187

%This only gives BER calculation for bottom eye. Need to also

8197

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8188

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8198

%min of top and bottom CDF values.

8189

%min of top and bottom CDF values.

8199

%If only interested in one side, a simple cumsum on y is all that is needed.

8190

%If only interested in one side, a simple cumsum on y is all that is needed.

8200

8191

8201

cdf.yB=cumsum(pdf.y);

8192

cdf.yB=cumsum(pdf.y);

8202

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8193

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8203

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8194

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8204

cdf.x=pdf.x;

8195

cdf.x=pdf.x;

8205

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)

8196

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)

8206

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8197

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8207

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8198

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8208

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8199

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8209

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8200

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8210

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8201

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8211

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8202

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8212

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8203

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8213

%% Added by Bill Kirkland, June 14, 2017

8204

%% Added by Bill Kirkland, June 14, 2017

8214

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8205

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8215

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8206

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8216

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8207

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8217

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8208

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8218

8209

8219

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8210

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8220

hold on

8211

hold on

8221

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8212

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8222

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8213

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8223

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)

8214

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)

8224

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8215

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8225

8216

8226

%% Added by Bill Kirkland, June 14, 2017

8217

%% Added by Bill Kirkland, June 14, 2017

8227

% modification allows bathtub curves to cross over and hence one can

8218

% modification allows bathtub curves to cross over and hence one can

8228

% directly read the noise component.

8219

% directly read the noise component.

8229

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8220

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8230

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8221

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8231

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8222

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8232

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8223

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8233

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8224

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8234

8225

8235

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8226

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8236

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

8227

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

8237

8228

8238

ylabel(hax, 'Probability')

8229

ylabel(hax, 'Probability')

8239

xlabel(hax, 'volts')

8230

xlabel(hax, 'volts')

8240

legend(hax, 'show')

8231

legend(hax, 'show')

8241

% testing code

8232

% testing code

8242

if 0

8233

if 0

8243

figure_name = 'COM curves';

8234

figure_name = 'COM curves';

8244

fig=findobj('Name', figure_name);

8235

fig=findobj('Name', figure_name);

8245

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

8236

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

8246

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

8237

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

8247

grid on

8238

grid on

8248

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8239

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8249

hold on

8240

hold on

8250

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8241

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8251

ylim([ 1e-6 0.25])

8242

ylim([ 1e-6 0.25])

8252

xlim([0 30])

8243

xlim([0 30])

8253

grid on

8244

grid on

8254

end

8245

end

8255

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)

8246

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)

8256

BER=param.specBER;

8247

BER=param.specBER;

8257

delta_dB=param.delta_IL;

8248

delta_dB=param.delta_IL;

8258

8249

8259

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8250

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8260

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8251

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8261

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8252

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8262

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8253

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8263

8254

8264

8255

8265

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8256

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8266

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8257

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8267

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8258

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8268

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8259

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8269

8260

8270

COM=20*log10(max_signal/maxn_tot);

8261

COM=20*log10(max_signal/maxn_tot);

8271

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8262

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8272

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8263

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8273

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8264

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8274

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8265

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8275

8266

8276

pfctr=exp(-0.09054*delta_dB);% less loss

8267

pfctr=exp(-0.09054*delta_dB);% less loss

8277

mfctr=exp(0.09054*delta_dB); % more loss

8268

mfctr=exp(0.09054*delta_dB); % more loss

8278

8269

8279

%less loss

8270

%less loss

8280

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8271

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8281

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8272

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8282

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8273

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8283

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8274

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8284

plus_maxn_tot=norm(plus_maxn);

8275

plus_maxn_tot=norm(plus_maxn);

8285

8276

8286

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8277

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8287

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8278

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8288

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8279

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8289

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8280

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8290

minus_maxn_tot=norm(minus_maxn);

8281

minus_maxn_tot=norm(minus_maxn);

8291

8282

8292

% more loss

8283

% more loss

8293

COMp=20*log10(max_signal*pfctr/maxn_tot);

8284

COMp=20*log10(max_signal*pfctr/maxn_tot);

8294

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8285

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8295

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8286

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8296

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8287

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8297

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8288

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8298

% less loss

8289

% less loss

8299

COMm=20*log10(max_signal*mfctr/maxn_tot);

8290

COMm=20*log10(max_signal*mfctr/maxn_tot);

8300

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8291

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8301

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8292

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8302

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8293

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8303

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8294

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8304

8295

8305

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8296

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8306

8297

8307

8298

8308

if(COM<0)

8299

if(COM<0)

8309

return

8300

return

8310

end

8301

end

8311

8302

8312

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8303

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8313

8304

8314

% pie(COM_per_noise,labels)

8305

% pie(COM_per_noise,labels)

8315

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8306

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8316

% legend('show','Location','bestoutside')

8307

% legend('show','Location','bestoutside')

8317

nullbar= [ 0 0 0 ];

8308

nullbar= [ 0 0 0 ];

8318

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8309

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8319

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8310

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8320

hold on

8311

hold on

8321

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8312

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8322

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8313

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8323

8314

8324

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8315

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8325

% ax=gca;

8316

% ax=gca;

8326

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8317

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8327

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8318

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8328

grid on

8319

grid on

8329

legend(labels,'Location','north')

8320

legend(labels,'Location','north')

8330

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8321

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8331

ylabel('COM (dB)')

8322

ylabel('COM (dB)')

8332

hold off

8323

hold off

8333

8324

8334

8325

8335

8326

8336

8327

8337

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

8328

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

8338

num_files=length(chdata);

8329

num_files=length(chdata);

8339

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8330

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8340

for i=1:num_files

8331

for i=1:num_files

8341

if param.package_testcase_i==1 && i==1

8332

if param.package_testcase_i==1 && i==1

8342

if OP.TDR && i==1

8333

if OP.TDR && i==1

8343

S.Frequencies=chdata(i).faxis;

8334

S.Frequencies=chdata(i).faxis;

8344

S.Impedance=100;

8335

S.Impedance=100;

8345

if ~OP.SHOW_BRD

8336

if ~OP.SHOW_BRD

8346

Sfield='_orig';

8337

Sfield='_orig';

8347

else

8338

else

8348

Sfield='_raw';

8339

Sfield='_raw';

8349

end

8340

end

8350

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8341

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8351

if ~param.FLAG.S2P

8342

if ~param.FLAG.S2P

8352

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8343

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8353

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8344

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8354

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8345

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8355

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8346

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8356

else

8347

else

8357

S.NumPorts=1;

8348

S.NumPorts=1;

8358

end

8349

end

8359

if OP.TDR_W_TXPKG

8350

if OP.TDR_W_TXPKG

8360

if OP.ERL == 2

8351

if OP.ERL == 2

8361

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8352

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8362

end

8353

end

8363

R_diepad = param.R_diepad;

8354

R_diepad = param.R_diepad;

8364

% RX package length is assumed to be the same for all

8355

% RX package length is assumed to be the same for all

8365

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8356

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8366

% for Rx pkg

8357

% for Rx pkg

8367

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8358

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8368

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8359

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8369

combines4p( s11in, s12in, s21in, s22in, ...

8360

combines4p( s11in, s12in, s21in, s22in, ...

8370

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8361

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8371

% S=sparameters(S.Parameters,S.Frequencies,100);

8362

% S=sparameters(S.Parameters,S.Frequencies,100);

8372

S=SL(S,S.Frequencies,R_diepad(1)*2);

8363

S=SL(S,S.Frequencies,R_diepad(1)*2);

8373

chdata(i).TX_RL=S.Parameters(2,2,:);

8364

chdata(i).TX_RL=S.Parameters(2,2,:);

8374

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8365

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8375

end

8366

end

8376

8367

8377

% need to combine S wiht is page and channel

8368

% need to combine S wiht is page and channel

8378

if param.FLAG.S2P

8369

if param.FLAG.S2P

8379

port_sel=1;

8370

port_sel=1;

8380

else

8371

else

8381

port_sel=[1 2];

8372

port_sel=[1 2];

8382

if OP.AUTO_TFX

8373

if OP.AUTO_TFX

8383

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8374

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8384

pix=find(fir4del==max(fir4del),1);

8375

pix=find(fir4del==max(fir4del),1);

8385

param.tfx(2)=2*tu(pix);

8376

param.tfx(2)=2*tu(pix);

8386

end

8377

end

8387

end

8378

end

8388

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8379

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8389

for ipsl=1:length(port_sel) % do for both port if s4p

8380

for ipsl=1:length(port_sel) % do for both port if s4p

8390

for izt=1:length(param.Z_t) % do for all tdr impedances

8381

for izt=1:length(param.Z_t) % do for all tdr impedances

8391

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8382

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8392

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8383

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8393

% OP.interp_sparam_mag='trend_to_DC';

8384

% OP.interp_sparam_mag='trend_to_DC';

8394

OP.interp_sparam_mag='linear_trend_to_DC';

8385

OP.interp_sparam_mag='linear_trend_to_DC';

8395

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8386

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8396

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8387

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8397

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8388

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8398

if ipsl ==1

8389

if ipsl ==1

8399

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8390

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8400

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8391

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8401

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8392

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8402

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8393

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8403

else

8394

else

8404

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8395

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8405

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8396

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8406

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8397

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8407

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8398

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8408

end

8399

end

8409

if OP.PTDR && i==1

8400

if OP.PTDR && i==1

8410

if ipsl ==1

8401

if ipsl ==1

8411

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8402

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8412

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8403

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8413

else

8404

else

8414

if ~param.FLAG.S2P

8405

if ~param.FLAG.S2P

8415

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8406

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8416

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8407

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8417

else

8408

else

8418

chdata(i).TDR22(izt).ERL=[];

8409

chdata(i).TDR22(izt).ERL=[];

8419

chdata(i).TDR22(izt).ERLRMS=[];

8410

chdata(i).TDR22(izt).ERLRMS=[];

8420

end

8411

end

8421

end

8412

end

8422

else

8413

else

8423

chdata(i).TDR11(izt).ERL=[];

8414

chdata(i).TDR11(izt).ERL=[];

8424

chdata(i).TDR22(izt).ERL=[];

8415

chdata(i).TDR22(izt).ERL=[];

8425

chdata(i).TDR11(izt).ERLRMS=[];

8416

chdata(i).TDR11(izt).ERLRMS=[];

8426

chdata(i).TDR22(izt).ERLRMS=[];

8417

chdata(i).TDR22(izt).ERLRMS=[];

8427

end

8418

end

8428

end

8419

end

8429

end

8420

end

8430

end

8421

end

8431

8422

8432

end

8423

end

8433

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8424

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8434

h=figure(180);set(gcf,'Tag','COM');

8425

h=figure(180);set(gcf,'Tag','COM');

8435

if param.package_testcase_i==1 && i == 1

8426

if param.package_testcase_i==1 && i == 1

8436

if i==1

8427

if i==1

8437

htabgroup = uitabgroup(h);

8428

htabgroup = uitabgroup(h);

8438

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8429

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8439

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8430

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8440

hax1 = axes('Parent', htab1);

8431

hax1 = axes('Parent', htab1);

8441

hax3 = axes('Parent', htab3);

8432

hax3 = axes('Parent', htab3);

8442

if ~param.FLAG.S2P

8433

if ~param.FLAG.S2P

8443

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8434

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8444

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8435

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8445

hax2 = axes('Parent', htab2);

8436

hax2 = axes('Parent', htab2);

8446

hax4 = axes('Parent', htab4);

8437

hax4 = axes('Parent', htab4);

8447

end

8438

end

8448

end

8439

end

8449

set(h,'CurrentAxes',hax1)

8440

set(h,'CurrentAxes',hax1)

8450

hold on

8441

hold on

8451

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8442

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8452

hold off

8443

hold off

8453

legend (hax1, 'off');grid on;zoom xon;

8444

legend (hax1, 'off');grid on;zoom xon;

8454

set(legend (hax1, 'show'), 'interp', 'none');

8445

set(legend (hax1, 'show'), 'interp', 'none');

8455

8446

8456

if ~param.FLAG.S2P

8447

if ~param.FLAG.S2P

8457

set(h,'CurrentAxes',hax2)

8448

set(h,'CurrentAxes',hax2)

8458

hold on

8449

hold on

8459

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8450

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8460

hold off

8451

hold off

8461

legend (hax2, 'off');grid on;zoom xon;

8452

legend (hax2, 'off');grid on;zoom xon;

8462

set(legend (hax2, 'show'), 'interp', 'none');

8453

set(legend (hax2, 'show'), 'interp', 'none');

8463

end

8454

end

8464

8455

8465

set(h,'CurrentAxes',hax3)

8456

set(h,'CurrentAxes',hax3)

8466

hold on

8457

hold on

8467

if OP.PTDR

8458

if OP.PTDR

8468

for izt=1:length(param.Z_t)

8459

for izt=1:length(param.Z_t)

8469

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8460

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8470

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8461

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8471

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8462

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8472

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8463

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8473

end

8464

end

8474

end

8465

end

8475

hold off

8466

hold off

8476

legend (hax3, 'off');grid on;zoom xon;

8467

legend (hax3, 'off');grid on;zoom xon;

8477

set(legend (hax3, 'show'), 'interp', 'none');

8468

set(legend (hax3, 'show'), 'interp', 'none');

8478

if ~param.FLAG.S2P

8469

if ~param.FLAG.S2P

8479

set(h,'CurrentAxes',hax4)

8470

set(h,'CurrentAxes',hax4)

8480

hold on

8471

hold on

8481

if OP.PTDR

8472

if OP.PTDR

8482

for izt=1:length(param.Z_t)

8473

for izt=1:length(param.Z_t)

8483

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8474

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8484

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8475

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8485

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8476

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8486

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8477

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8487

end

8478

end

8488

end

8479

end

8489

hold off

8480

hold off

8490

legend (hax4, 'off');grid on;zoom xon;

8481

legend (hax4, 'off');grid on;zoom xon;

8491

set(legend (hax4, 'show'), 'interp', 'none');

8482

set(legend (hax4, 'show'), 'interp', 'none');

8492

end

8483

end

8493

end

8484

end

8494

end

8485

end

8495

if param.FLAG.S2P, return; end

8486

if param.FLAG.S2P, return; end

8496

end

8487

end

8497

function S =r_parrelell2(zref,f,rpad)

8488

function S =r_parrelell2(zref,f,rpad)

8498

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8489

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8499

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8490

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8500

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8491

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8501

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8492

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8502

% Sm=sparameters(S.Parameters,f,zref);

8493

% Sm=sparameters(S.Parameters,f,zref);

8503

8494

8504

8495

8505

8496

8506

8497

8507

8498

8508

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8499

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8509

8500

8510

%touchstone_file: .sNp touchstone file to read

8501

%touchstone_file: .sNp touchstone file to read

8511

%port_order: port reorder vector

8502

%port_order: port reorder vector

8512

%

8503

%

8513

%sch: sparameter matrix

8504

%sch: sparameter matrix

8514

%schFreqAxis: frequency axis

8505

%schFreqAxis: frequency axis

8515

8506

8516

[file_path,root_name,extension]=fileparts(touchstone_file);

8507

[file_path,root_name,extension]=fileparts(touchstone_file);

8517

fid=fopen(touchstone_file);

8508

fid=fopen(touchstone_file);

8518

8509

8519

%fetch number of ports from extension

8510

%fetch number of ports from extension

8520

num_ports=str2num(char(regexp(extension,'\d*','match')));

8511

num_ports=str2num(char(regexp(extension,'\d*','match')));

8521

8512

8522

%Get option line

8513

%Get option line

8523

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8514

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8524

optcell=textscan(optstr{1}{1},'%s');

8515

optcell=textscan(optstr{1}{1},'%s');

8525

optcell=optcell{1};

8516

optcell=optcell{1};

8526

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8517

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8527

%Some touchstone files need this. can't remember why now. maybe lines

8518

%Some touchstone files need this. can't remember why now. maybe lines

8528

%with whitespace but not empty but not commented

8519

%with whitespace but not empty but not commented

8529

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8520

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8530

optcell=textscan(optstr{1}{1},'%s');

8521

optcell=textscan(optstr{1}{1},'%s');

8531

optcell=optcell{1};

8522

optcell=optcell{1};

8532

end

8523

end

8533

8524

8534

%read the entire file

8525

%read the entire file

8535

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8526

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8536

raw_column_data=raw_read_data{1};

8527

raw_column_data=raw_read_data{1};

8537

fclose(fid);

8528

fclose(fid);

8538

8529

8539

%number of columns for 2D matrix

8530

%number of columns for 2D matrix

8540

columns=num_ports*num_ports*2+1;

8531

columns=num_ports*num_ports*2+1;

8541

8532

8542

%find the frequency lines by searching for the right number of NaN

8533

%find the frequency lines by searching for the right number of NaN

8543

a=sum(isnan(raw_column_data),2);

8534

a=sum(isnan(raw_column_data),2);

8544

if num_ports==3

8535

if num_ports==3

8545

b=find(a==2);

8536

b=find(a==2);

8546

elseif num_ports==1

8537

elseif num_ports==1

8547

b=find(a==6);

8538

b=find(a==6);

8548

else

8539

else

8549

b=find(a==0);

8540

b=find(a==0);

8550

end

8541

end

8551

8542

8552

num_freq=length(b);

8543

num_freq=length(b);

8553

8544

8554

%toss out the NaN and reshape into a 2D matrix

8545

%toss out the NaN and reshape into a 2D matrix

8555

raw_input = raw_column_data.';

8546

raw_input = raw_column_data.';

8556

raw_input = raw_input(~isnan(raw_input));

8547

raw_input = raw_input(~isnan(raw_input));

8557

raw_input = reshape(raw_input,columns,num_freq).';

8548

raw_input = reshape(raw_input,columns,num_freq).';

8558

8549

8559

%get the frequency mult

8550

%get the frequency mult

8560

frequency_mult_text=optcell{2};

8551

frequency_mult_text=optcell{2};

8561

if(strcmpi(frequency_mult_text,'hz'))

8552

if(strcmpi(frequency_mult_text,'hz'))

8562

frequency_mult=1;

8553

frequency_mult=1;

8563

elseif(strcmpi(frequency_mult_text,'khz'))

8554

elseif(strcmpi(frequency_mult_text,'khz'))

8564

frequency_mult=1e3;

8555

frequency_mult=1e3;

8565

elseif(strcmpi(frequency_mult_text,'mhz'))

8556

elseif(strcmpi(frequency_mult_text,'mhz'))

8566

frequency_mult=1e6;

8557

frequency_mult=1e6;

8567

elseif(strcmpi(frequency_mult_text,'ghz'))

8558

elseif(strcmpi(frequency_mult_text,'ghz'))

8568

frequency_mult=1e9;

8559

frequency_mult=1e9;

8569

else

8560

else

8570

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8561

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8571

end

8562

end

8572

8563

8573

%get the RI/MA/DB format

8564

%get the RI/MA/DB format

8574

format=optcell{4};

8565

format=optcell{4};

8575

%get Z0

8566

%get Z0

8576

port_impedance=str2double(optcell(6:end))';

8567

port_impedance=str2double(optcell(6:end))';

8577

8568

8578

8569

8579

%grab frequency

8570

%grab frequency

8580

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8571

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8581

Spar.F=raw_input(:,1);

8572

Spar.F=raw_input(:,1);

8582

Spar.F=transpose(Spar.F(:));

8573

Spar.F=transpose(Spar.F(:));

8583

8574

8584

8575

8585

%transform data to real imaginary

8576

%transform data to real imaginary

8586

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8577

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8587

if(strcmpi(format,'ri'))

8578

if(strcmpi(format,'ri'))

8588

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8579

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8589

elseif(strcmpi(format,'ma'))

8580

elseif(strcmpi(format,'ma'))

8590

mag_data=raw_input(:,2:2:end);

8581

mag_data=raw_input(:,2:2:end);

8591

rad_data=raw_input(:,3:2:end)*pi/180;

8582

rad_data=raw_input(:,3:2:end)*pi/180;

8592

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8583

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8593

elseif(strcmpi(format,'db'))

8584

elseif(strcmpi(format,'db'))

8594

mag_data=10.^(raw_input(:,2:2:end)/20);

8585

mag_data=10.^(raw_input(:,2:2:end)/20);

8595

rad_data=raw_input(:,3:2:end)*pi/180;

8586

rad_data=raw_input(:,3:2:end)*pi/180;

8596

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8587

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8597

else

8588

else

8598

error('Format %s is not supported. Use RI MA or DB',format);

8589

error('Format %s is not supported. Use RI MA or DB',format);

8599

end

8590

end

8600

8591

8601

8592

8602

8593

8603

%transform to 3D

8594

%transform to 3D

8604

%allow for upper/lower matrix specification for touchstone 2.0 support

8595

%allow for upper/lower matrix specification for touchstone 2.0 support

8605

matrix_format=0;

8596

matrix_format=0;

8606

if(matrix_format==0)

8597

if(matrix_format==0)

8607

%full

8598

%full

8608

for j=1:num_ports

8599

for j=1:num_ports

8609

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8600

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8610

end

8601

end

8611

elseif(matrix_format==1)

8602

elseif(matrix_format==1)

8612

%upper

8603

%upper

8613

used_ports=0;

8604

used_ports=0;

8614

for j=1:num_ports

8605

for j=1:num_ports

8615

stated_ports=num_ports-j+1;

8606

stated_ports=num_ports-j+1;

8616

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8607

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8617

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8608

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8618

used_ports=used_ports+stated_ports;

8609

used_ports=used_ports+stated_ports;

8619

end

8610

end

8620

elseif(matrix_format==2)

8611

elseif(matrix_format==2)

8621

%lower

8612

%lower

8622

used_ports=0;

8613

used_ports=0;

8623

for j=1:num_ports

8614

for j=1:num_ports

8624

stated_ports=j;

8615

stated_ports=j;

8625

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8616

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8626

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8617

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8627

used_ports=used_ports+stated_ports;

8618

used_ports=used_ports+stated_ports;

8628

end

8619

end

8629

else

8620

else

8630

error('Matrix format is not supported. Use Full, Lower, or Upper');

8621

error('Matrix format is not supported. Use Full, Lower, or Upper');

8631

end

8622

end

8632

8623

8633

8624

8634

%check for swapping the 2 port matrix (required on 1.x spec)

8625

%check for swapping the 2 port matrix (required on 1.x spec)

8635

two_port_swap=1;

8626

two_port_swap=1;

8636

if(num_ports==2 && two_port_swap==1)

8627

if(num_ports==2 && two_port_swap==1)

8637

temp=pre_out.sp(1,2,:);

8628

temp=pre_out.sp(1,2,:);

8638

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8629

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8639

pre_out.sp(2,1,:)=temp;

8630

pre_out.sp(2,1,:)=temp;

8640

end

8631

end

8641

8632

8642

Spar.S=pre_out.sp;

8633

Spar.S=pre_out.sp;

8643

Spar.Z0=transpose(port_impedance(:));

8634

Spar.Z0=transpose(port_impedance(:));

8644

8635

8645

if length(Spar.Z0)>1

8636

if length(Spar.Z0)>1

8646

error('Each port must have the same reference impedance');

8637

error('Each port must have the same reference impedance');

8647

end

8638

end

8648

if ~isequal(Spar.Z0,50)

8639

if ~isequal(Spar.Z0,50)

8649

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8640

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8650

%Renormalize to 50 ohms

8641

%Renormalize to 50 ohms

8651

rho=(50-Spar.Z0)/(50+Spar.Z0);

8642

rho=(50-Spar.Z0)/(50+Spar.Z0);

8652

p=num_ports;

8643

p=num_ports;

8653

s_old=Spar.S;

8644

s_old=Spar.S;

8654

for k=1:num_freq

8645

for k=1:num_freq

8655

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8646

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8656

end

8647

end

8657

end

8648

end

8658

8649

8659

%These operations sync up with COM style Spar matrix

8650

%These operations sync up with COM style Spar matrix

8660

%1: put frequency as first dimension

8651

%1: put frequency as first dimension

8661

sch=shiftdim(Spar.S,2);

8652

sch=shiftdim(Spar.S,2);

8662

%2: reorder ports according to "ports" input

8653

%2: reorder ports according to "ports" input

8663

sch=sch(:,port_order,port_order);

8654

sch=sch(:,port_order,port_order);

8664

schFreqAxis=Spar.F;

8655

schFreqAxis=Spar.F;

8665

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

8656

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

8666

%% Read in pulse response

8657

%% Read in pulse response

8667

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8658

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8668

num_files=length(chdata);

8659

num_files=length(chdata);

8669

M=param.samples_per_ui;

8660

M=param.samples_per_ui;

8670

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8661

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8671

for i=1:num_files

8662

for i=1:num_files

8672

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8663

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8673

progress = i/num_files;

8664

progress = i/num_files;

8674

if OP.DISPLAY_WINDOW

8665

if OP.DISPLAY_WINDOW

8675

[~,a]=fileparts(chdata(i).filename);

8666

[~,a]=fileparts(chdata(i).filename);

8676

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8667

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8677

else

8668

else

8678

fprintf('%i ',i);

8669

fprintf('%i ',i);

8679

end

8670

end

8680

switch chdata(i).ext

8671

switch chdata(i).ext

8681

case '.csv'

8672

case '.csv'

8682

vt=load(chdata(i).filename);

8673

vt=load(chdata(i).filename);

8683

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8674

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8684

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8675

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8685

dt=vt(2,1)-vt(1,1);

8676

dt=vt(2,1)-vt(1,1);

8686

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8677

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8687

8678

8688

8679

8689

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8680

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8690

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8681

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8691

Vf=step_response(end);

8682

Vf=step_response(end);

8692

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8683

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8693

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8684

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8694

8685

8695

end

8686

end

8696

end

8687

end

8697

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8688

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8698

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8689

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8699

[filepath,name,ext] = fileparts(paramFile);

8690

[filepath,name,ext] = fileparts(paramFile);

8700

if ~isempty(filepath)

8691

if ~isempty(filepath)

8701

filepath=[filepath '\'];

8692

filepath=[filepath '\'];

8702

end

8693

end

8703

matcongfile=[filepath name '.mat'];

8694

matcongfile=[filepath name '.mat'];

8704

try

8695

try

8705

switch upper(ext)

8696

switch upper(ext)

8706

case upper('.mat')

8697

case upper('.mat')

8707

load(matcongfile)

8698

load(matcongfile)

8708

case upper('.csv')

8699

case upper('.csv')

8709

[na1, na2, parameter] = xlsread(paramFile);

8700

[na1, na2, parameter] = xlsread(paramFile);

8710

otherwise

8701

otherwise

8711

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8702

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8712

end

8703

end

8713

8704

8714

catch ME %#ok<NASGU>

8705

catch ME %#ok<NASGU>

8715

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8706

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8716

switch upper(ext)

8707

switch upper(ext)

8717

case upper('.mat')

8708

case upper('.mat')

8718

load(matcongfile)

8709

load(matcongfile)

8719

case upper('.csv')

8710

case upper('.csv')

8720

[na1, na2, parameter] = xlsread(paramFile);

8711

[na1, na2, parameter] = xlsread(paramFile);

8721

otherwise

8712

otherwise

8722

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8713

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8723

end

8714

end

8724

end

8715

end

8725

8716

8726

%% New section to parse .START package data

8717

%% New section to parse .START package data

8727

first_column_data = parameter(:,1);

8718

first_column_data = parameter(:,1);

8728

start_data_rows = find(strcmp(first_column_data,'.START'));

8719

start_data_rows = find(strcmp(first_column_data,'.START'));

8729

if ~isempty(start_data_rows)

8720

if ~isempty(start_data_rows)

8730

end_data_rows = find(strcmp(first_column_data,'.END'));

8721

end_data_rows = find(strcmp(first_column_data,'.END'));

8731

if length(start_data_rows) ~= length(end_data_rows)

8722

if length(start_data_rows) ~= length(end_data_rows)

8732

error('Number of .START and .END must be the same');

8723

error('Number of .START and .END must be the same');

8733

end

8724

end

8734

first_start_row = start_data_rows(1);

8725

first_start_row = start_data_rows(1);

8735

special_parameter = parameter;

8726

special_parameter = parameter;

8736

parameter = parameter(1:first_start_row-1,:);

8727

parameter = parameter(1:first_start_row-1,:);

8737

for j=1:length(start_data_rows)

8728

for j=1:length(start_data_rows)

8738

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8729

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8739

pkg_name = special_parameter{start_data_rows(j),2};

8730

pkg_name = special_parameter{start_data_rows(j),2};

8740

8731

8741

%Read all the parameters that make up a package

8732

%Read all the parameters that make up a package

8742

PKG_param = read_package_parameters(this_block);

8733

PKG_param = read_package_parameters(this_block);

8743

8734

8744

%save the data in a field revealed by pkg_name

8735

%save the data in a field revealed by pkg_name

8745

param.PKG.(pkg_name) = PKG_param;

8736

param.PKG.(pkg_name) = PKG_param;

8746

8737

8747

8738

8748

end

8739

end

8749

end

8740

end

8750

%Allow specification of TX and RX package section through PKG_NAME keyword

8741

%Allow specification of TX and RX package section through PKG_NAME keyword

8751

%the values must match package blocks specified in .START sections

8742

%the values must match package blocks specified in .START sections

8752

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8743

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8753

if isnan(param.PKG_NAME)

8744

if isnan(param.PKG_NAME)

8754

param.PKG_NAME = '';

8745

param.PKG_NAME = '';

8755

end

8746

end

8756

if isempty(param.PKG_NAME)

8747

if isempty(param.PKG_NAME)

8757

param.PKG_NAME = {};

8748

param.PKG_NAME = {};

8758

else

8749

else

8759

param.PKG_NAME = strsplit(param.PKG_NAME);

8750

param.PKG_NAME = strsplit(param.PKG_NAME);

8760

end

8751

end

8761

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8752

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8762

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8753

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8763

end

8754

end

8764

for j=1:length(param.PKG_NAME)

8755

for j=1:length(param.PKG_NAME)

8765

if ~isfield(param.PKG,param.PKG_NAME{j})

8756

if ~isfield(param.PKG,param.PKG_NAME{j})

8766

error('Package Block "%s" not found',param.PKG_NAME{j});

8757

error('Package Block "%s" not found',param.PKG_NAME{j});

8767

end

8758

end

8768

end

8759

end

8769

8760

8770

%%

8761

%%

8771

% just need to define so we can pass

8762

% just need to define so we can pass

8772

param.c=[.4e-12 .4e-12];

8763

param.c=[.4e-12 .4e-12];

8773

param.alen=[ 20 30 550 ];

8764

param.alen=[ 20 30 550 ];

8774

param.az=[100 120 100];

8765

param.az=[100 120 100];

8775

8766

8776

% make control for package/channel reflection control

8767

% make control for package/channel reflection control

8777

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8768

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8778

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8769

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8779

8770

8780

% make compatible with presentation of kappa

8771

% make compatible with presentation of kappa

8781

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8772

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8782

8773

8783

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8774

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8784

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8775

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8785

8776

8786

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8777

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8787

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

8778

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

8788

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8779

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8789

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8780

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8790

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8781

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8791

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

8782

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

8792

8783

8793

if OP.dynamic_txffe

8784

if OP.dynamic_txffe

8794

found_pre=1;

8785

found_pre=1;

8795

pre_count=1;

8786

pre_count=1;

8796

while found_pre

8787

while found_pre

8797

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8788

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

8798

if found_pre

8789

if found_pre

8799

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8790

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

8800

param.(field_name)=p;

8791

param.(field_name)=p;

8801

pre_count=pre_count+1;

8792

pre_count=pre_count+1;

8802

end

8793

end

8803

end

8794

end

8804

found_post=1;

8795

found_post=1;

8805

post_count=1;

8796

post_count=1;

8806

while found_post

8797

while found_post

8807

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8798

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

8808

if found_post

8799

if found_post

8809

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8800

field_name=sprintf('tx_ffe_cp%d_values',post_count);

8810

param.(field_name)=p;

8801

param.(field_name)=p;

8811

post_count=post_count+1;

8802

post_count=post_count+1;

8812

end

8803

end

8813

end

8804

end

8814

else

8805

else

8815

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

8806

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

8816

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

8807

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

8817

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

8808

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

8818

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

8809

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

8819

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

8810

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

8820

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

8811

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

8821

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

8812

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

8822

end

8813

end

8823

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8814

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

8824

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8815

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

8825

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8816

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

8826

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

8817

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

8827

% support for floating taps

8818

% support for floating taps

8828

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8819

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

8829

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8820

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

8830

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8821

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

8831

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8822

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

8832

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8823

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

8833

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8824

if param.N_bg == 0, param.N_bmax=param.ndfe; end

8834

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8825

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

8835

8826

8836

% support for tail tap power limitations

8827

% support for tail tap power limitations

8837

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8828

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

8838

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8829

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

8839

%

8830

%

8840

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8831

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

8841

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8832

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

8842

param.RxFFE_cmx=param.ffe_pre_tap_len;

8833

param.RxFFE_cmx=param.ffe_pre_tap_len;

8843

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8834

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

8844

param.RxFFE_cpx=param.ffe_post_tap_len;

8835

param.RxFFE_cpx=param.ffe_post_tap_len;

8845

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8836

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

8846

param.RxFFE_stepz=param.ffe_tap_step_size;

8837

param.RxFFE_stepz=param.ffe_tap_step_size;

8847

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8838

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

8848

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8839

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

8849

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8840

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

8850

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8841

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

8851

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

8842

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

8852

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8843

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

8853

OP.RxFFE= true;

8844

OP.RxFFE= true;

8854

else

8845

else

8855

OP.RxFFE=false;

8846

OP.RxFFE=false;

8856

end

8847

end

8857

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8848

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

8858

8849

8859

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8850

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

8860

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8851

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

8861

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

8852

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

8862

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

8853

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

8863

8854

8864

8855

8865

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8856

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

8866

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8857

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

8867

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)

8858

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)

8868

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

8859

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

8869

8860

8870

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)

8861

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)

8871

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

8862

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

8872

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8863

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

8873

% always read in main ctle values. They would be interpreted different baseed

8864

% always read in main ctle values. They would be interpreted different baseed

8874

% on the clause they apply because of different CTF equations

8865

% on the clause they apply because of different CTF equations

8875

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8866

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

8876

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8867

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8877

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8868

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8878

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8869

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8879

% the contex of the poles an zeros are determined by the clause

8870

% the contex of the poles an zeros are determined by the clause

8880

switch param.CTLE_type

8871

switch param.CTLE_type

8881

case 'CL93'

8872

case 'CL93'

8882

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

8873

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

8883

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8874

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

8884

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8875

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

8885

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8876

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

8886

case 'CL120d'

8877

case 'CL120d'

8887

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8878

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

8888

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8879

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

8889

case 'CL120e'

8880

case 'CL120e'

8890

% re adjust to get TD_CTLE to work with C:120e equation without

8881

% re adjust to get TD_CTLE to work with C:120e equation without

8891

% changing TD_CTLE code

8882

% changing TD_CTLE code

8892

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8883

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

8893

end

8884

end

8894

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8885

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

8895

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8886

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

8896

%% addd default to support multiple packages

8887

%% addd default to support multiple packages

8897

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

8888

param.a_thru = xls_parameter(parameter, 'A_v', true, 0.5); % Victim differential peak source output voltage (half of peak to peak)

8898

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8889

param.a_fext = xls_parameter(parameter, 'A_fe', true,0.5); % FEXT aggressor differential peak source output voltage (half of peak to peak)

8899

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8890

param.a_next = xls_parameter(parameter, 'A_ne', true,0.5); % NEXT aggressor differential peak source output voltage (half of peak to peak)

8900

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

8891

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

8901

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

8892

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

8902

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8893

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

8903

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8894

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

8904

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8895

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

8905

param.ENOB = xls_parameter(parameter, 'ENOB',true,0); % adc number of bits if 0 do not apply quantization

8896

param.ENOB = xls_parameter(parameter, 'ENOB',true,0); % adc number of bits if 0 do not apply quantization

8906

param.adc_clip_rate= xls_parameter(parameter, 'adc_clip_rate',true,2*param.specBER); % adc clipping probability

8897

param.adc_clip_rate= xls_parameter(parameter, 'adc_clip_rate',true,2*param.specBER); % adc clipping probability

8907

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8898

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

8908

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8899

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

8909

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

8900

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

8910

8901

8911

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8902

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

8912

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

8903

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

8913

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

8904

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

8914

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8905

% shakiba_3dj_01_2407 (to add MLSE sequence truncation penalty)

8915

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8906

param.trunc = xls_parameter(parameter, 'trunc', true, 128); % MLSE sequence truncation length

8916

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8907

param.trunc = xls_parameter(parameter, 'N_tc', true, param.trunc); % MLSE sequence truncation length

8917

8908

8918

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8909

% healey_3dj_01a_2407 adjust MLSE for COM_DFE

8919

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8910

param.Q_budget_adj = xls_parameter(parameter, 'Q_budget_adj', true, 0); % MLSE sequence truncation length

8920

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8911

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

8921

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8912

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

8922

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8913

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

8923

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8914

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

8924

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)

8915

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)

8925

% This will keep bmax length 0 if Nb=0

8916

% This will keep bmax length 0 if Nb=0

8926

8917

8927

%AJG021820

8918

%AJG021820

8928

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8919

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

8929

if isempty(param.bmax)

8920

if isempty(param.bmax)

8930

param.bmin=param.bmax;

8921

param.bmin=param.bmax;

8931

else

8922

else

8932

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.

8923

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.

8933

8924

8934

end

8925

end

8935

if param.ndfe >= 2

8926

if param.ndfe >= 2

8936

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

8927

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

8937

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)

8928

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)

8938

end

8929

end

8939

8930

8940

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)

8931

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)

8941

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

8932

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

8942

%verify gqual and gqual2 input

8933

%verify gqual and gqual2 input

8943

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8934

if ~isempty(param.gqual) || ~isempty(param.g2qual)

8944

if size(param.gqual,1)~=length(param.g2qual)

8935

if size(param.gqual,1)~=length(param.g2qual)

8945

error('gqual and g2qual size mismatch');

8936

error('gqual and g2qual size mismatch');

8946

end

8937

end

8947

if size(param.gqual,2)~=2

8938

if size(param.gqual,2)~=2

8948

error('gqual must be Nx2 matrix');

8939

error('gqual must be Nx2 matrix');

8949

end

8940

end

8950

end

8941

end

8951

8942

8952

8943

8953

% eval if string for all three - can use different for TX and RX

8944

% eval if string for all three - can use different for TX and RX

8954

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

8945

param.C_pkg_board = xls_parameter(parameter, 'C_p', true,0)*1e-9; % C_p in nF (single sided)

8955

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

8946

param.C_diepad = xls_parameter(parameter, 'C_d', true,0)*1e-9; % C_d in nF (single sided)

8956

% [ahealey] Read values for optional compensating L and "bump" C

8947

% [ahealey] Read values for optional compensating L and "bump" C

8957

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8948

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

8958

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8949

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

8959

% [ahealey] End of modification

8950

% [ahealey] End of modification

8960

% added default to support multiple packages

8951

% added default to support multiple packages

8961

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8952

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

8962

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

8953

param.R_diepad = xls_parameter(parameter, 'R_d', true, [50,50]); % Die source termination resistance (single sided)

8963

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8954

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

8964

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8955

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

8965

8956

8966

8957

8967

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8958

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

8968

% added default to support multiple packages

8959

% added default to support multiple packages

8969

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of victim transmitter package trace lengths in mm, one per case

8960

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of victim transmitter package trace lengths in mm, one per case

8970

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

8961

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

8971

if mele ==2

8962

if mele ==2

8972

param.flex=2;

8963

param.flex=2;

8973

elseif mele==4

8964

elseif mele==4

8974

param.flex=4;

8965

param.flex=4;

8975

elseif mele==1

8966

elseif mele==1

8976

param.flex=1;

8967

param.flex=1;

8977

else

8968

else

8978

error(sprintf('config file syntax error'))

8969

error(sprintf('config file syntax error'))

8979

end

8970

end

8980

8971

8981

% board parameters

8972

% board parameters

8982

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

8973

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

8983

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

8974

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

8984

% added default to support multiple packages

8975

% added default to support multiple packages

8985

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of NEXT transmitter package trace lengths in mm, one per case

8976

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of NEXT transmitter package trace lengths in mm, one per case

8986

[ncases1, mele1]=size(param.z_p_next_cases);

8977

[ncases1, mele1]=size(param.z_p_next_cases);

8987

if ncases ~= ncases1 || mele ~= mele1

8978

if ncases ~= ncases1 || mele ~= mele1

8988

error('All TX, NEXT, FEXT, Rx cases must agree');

8979

error('All TX, NEXT, FEXT, Rx cases must agree');

8989

else

8980

else

8990

end

8981

end

8991

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT transmitter package trace lengths in mm, one per case

8982

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT transmitter package trace lengths in mm, one per case

8992

[ncases1, mele1]=size(param.z_p_fext_cases);

8983

[ncases1, mele1]=size(param.z_p_fext_cases);

8993

if ncases ~= ncases1 || mele ~= mele1

8984

if ncases ~= ncases1 || mele ~= mele1

8994

error('All TX, NEXT, FEXT, Rx cases must agree');

8985

error('All TX, NEXT, FEXT, Rx cases must agree');

8995

else

8986

else

8996

end

8987

end

8997

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT receiver package trace lengths in mm, one per case

8988

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true,'[ 8 24 30 45 ; 1 1 1 1; 1 1 1 1 ; 0.5 0.5 0.5 0.5 ]').'; % List of FEXT receiver package trace lengths in mm, one per case

8998

[ncases1, mele1]=size(param.z_p_rx_cases);

8989

[ncases1, mele1]=size(param.z_p_rx_cases);

8999

if ncases ~= ncases1 || mele ~= mele1

8990

if ncases ~= ncases1 || mele ~= mele1

9000

error('All TX, NEXT, FEXT, Rx cases must agree');

8991

error('All TX, NEXT, FEXT, Rx cases must agree');

9001

else

8992

else

9002

end

8993

end

9003

% Table 93A-3 parameters

8994

% Table 93A-3 parameters

9004

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.

8995

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.

9005

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

8996

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9006

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, '[92 92 ; 70 70; 80 80; 100 100]').';% Package model transmission line characteristic impedance [ Tx , Rx ]

8997

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, '[92 92 ; 70 70; 80 80; 100 100]').';% Package model transmission line characteristic impedance [ Tx , Rx ]

9007

[ ncases1, mele1]=size(param.pkg_Z_c);%

8998

[ ncases1, mele1]=size(param.pkg_Z_c);%

9008

if mele ~= mele1

8999

if mele ~= mele1

9009

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9000

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9010

else

9001

else

9011

end

9002

end

9012

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9003

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9013

for ii=1:ncases

9004

for ii=1:ncases

9014

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9005

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9015

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9006

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9016

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9007

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9017

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9008

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9018

end

9009

end

9019

param.z_p_fext_cases = param.z_p_fext_casesx;

9010

param.z_p_fext_cases = param.z_p_fext_casesx;

9020

param.z_p_next_cases= param.z_p_next_casesx;

9011

param.z_p_next_cases= param.z_p_next_casesx;

9021

param.z_p_tx_cases= param.z_p_tx_casesx;

9012

param.z_p_tx_cases= param.z_p_tx_casesx;

9022

param.z_p_rx_cases= param.z_p_rx_casesx;

9013

param.z_p_rx_cases= param.z_p_rx_casesx;

9023

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9014

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9024

end

9015

end

9025

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9016

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9026

9017

9027

% Table 92-12 parameters

9018

% Table 92-12 parameters

9028

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.

9019

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.

9029

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9020

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9030

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9021

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9031

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9022

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9032

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9023

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9033

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9024

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9034

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9025

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9035

9026

9036

% Unofficial parameters

9027

% Unofficial parameters

9037

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9028

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9038

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9029

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9039

% Deprecated parameters - affect only frequency domain analysis.

9030

% Deprecated parameters - affect only frequency domain analysis.

9040

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

9031

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

9041

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

9032

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

9042

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

9033

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

9043

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

9034

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

9044

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

9035

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

9045

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9036

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9046

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9037

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9047

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9038

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9048

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9039

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9049

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9040

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9050

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9041

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9051

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9042

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9052

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9043

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9053

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9044

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9054

switch param.Gx

9045

switch param.Gx

9055

case 0

9046

case 0

9056

param.Grr=param.Grr; % just use older Grr ir gx not specified

9047

param.Grr=param.Grr; % just use older Grr ir gx not specified

9057

case 1

9048

case 1

9058

param.Grr=2; % use newer Grr

9049

param.Grr=2; % use newer Grr

9059

end

9050

end

9060

9051

9061

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

9052

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

9062

% Operational control variables

9053

% Operational control variables

9063

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9054

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9064

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9055

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9065

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

9056

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

9066

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

9057

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

9067

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9058

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9068

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.

9059

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.

9069

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.

9060

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.

9070

9061

9071

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9062

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9072

9063

9073

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)

9064

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)

9074

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9065

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9075

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9066

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9076

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

9067

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

9077

9068

9078

%%

9069

%%

9079

9070

9080

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9071

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9081

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9072

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9082

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9073

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9083

param.awgn_mv=param.AC_CM_RMS;

9074

param.awgn_mv=param.AC_CM_RMS;

9084

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9075

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9085

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

9076

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

9086

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9077

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

9087

9078

9088

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9079

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9089

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9080

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9090

param.Floating_RXFFE=false;

9081

param.Floating_RXFFE=false;

9091

param.Floating_DFE=false;

9082

param.Floating_DFE=false;

9092

if param.N_bg > 0

9083

if param.N_bg > 0

9093

param.Floating_DFE=true;

9084

param.Floating_DFE=true;

9094

end

9085

end

9095

if OP.RxFFE

9086

if OP.RxFFE

9096

param.Floating_DFE=false;

9087

param.Floating_DFE=false;

9097

if param.N_bg > 0

9088

if param.N_bg > 0

9098

param.Floating_RXFFE=true;

9089

param.Floating_RXFFE=true;

9099

end

9090

end

9100

end

9091

end

9101

%% for introducing Tx or Rx skew on p leg or n leg

9092

%% for introducing Tx or Rx skew on p leg or n leg

9102

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9093

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9103

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9094

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9104

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9095

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9105

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9096

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9106

9097

9107

%%

9098

%%

9108

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9099

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9109

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9100

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9110

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9101

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9111

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9102

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9112

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9103

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9113

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9104

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9114

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9105

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9115

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9106

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9116

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9107

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9117

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

9108

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

9118

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9109

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9119

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9110

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9120

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9111

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9121

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

9112

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

9122

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

9113

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

9123

if ~OP.INC_PACKAGE

9114

if ~OP.INC_PACKAGE

9124

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');

9115

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');

9125

end

9116

end

9126

9117

9127

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9118

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9128

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9119

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9129

if OP.IDEAL_TX_TERM

9120

if OP.IDEAL_TX_TERM

9130

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9121

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9131

end

9122

end

9132

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9123

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9133

if OP.IDEAL_RX_TERM

9124

if OP.IDEAL_RX_TERM

9134

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9125

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9135

end

9126

end

9136

9127

9137

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.

9128

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.

9138

9129

9139

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9130

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9140

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9131

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9141

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9132

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9142

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

9133

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

9143

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9134

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9144

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

9135

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

9145

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9136

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9146

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

9137

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

9147

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

9138

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

9148

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

9139

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

9149

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9140

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9150

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9141

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9151

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

9142

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

9152

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.

9143

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.

9153

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9144

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9154

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9145

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9155

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9146

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9156

9147

9157

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9148

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9158

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9149

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9159

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.

9150

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.

9160

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9151

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9161

% compatibility

9152

% compatibility

9162

if OP.FORCE_TR

9153

if OP.FORCE_TR

9163

OP.T_r_meas_point=0;

9154

OP.T_r_meas_point=0;

9164

OP.T_r_filter_type=1;

9155

OP.T_r_filter_type=1;

9165

end

9156

end

9166

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9157

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9167

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.

9158

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.

9168

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9159

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9169

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9160

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9170

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.

9161

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.

9171

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9162

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9172

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9163

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9173

if OP.ERL

9164

if OP.ERL

9174

OP.PTDR=1;

9165

OP.PTDR=1;

9175

else

9166

else

9176

OP.PTDR=0;

9167

OP.PTDR=0;

9177

end % ERL needs to do a TDR

9168

end % ERL needs to do a TDR

9178

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9169

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9179

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9170

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9180

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9171

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9181

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9172

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9182

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9173

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9183

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9174

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9184

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9175

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9185

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9176

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9186

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.

9177

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.

9187

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9178

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9188

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9179

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9189

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.

9180

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.

9190

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9181

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9191

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9182

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9192

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9183

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9193

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9184

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9194

if strcmpi(OP.PHY,'C2M')

9185

if strcmpi(OP.PHY,'C2M')

9195

OP.EW=true;

9186

OP.EW=true;

9196

else

9187

else

9197

param.T_O=0; % make sure when c2c that sample is at Ts

9188

param.T_O=0; % make sure when c2c that sample is at Ts

9198

end

9189

end

9199

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9190

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9200

OP.PHY='C2Mcom';

9191

OP.PHY='C2Mcom';

9201

end

9192

end

9202

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9193

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9203

switch lower(OP.TDECQ)

9194

switch lower(OP.TDECQ)

9204

case {false 'none' 'vma'}

9195

case {false 'none' 'vma'}

9205

otherwise

9196

otherwise

9206

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9197

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9207

end

9198

end

9208

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9199

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9209

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9200

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9210

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9201

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9211

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9202

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9212

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

9203

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

9213

% Parameters for error burst probability calculation. Not officially used

9204

% Parameters for error burst probability calculation. Not officially used

9214

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9205

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9215

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9206

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9216

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9207

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9217

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.

9208

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.

9218

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.

9209

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.

9219

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9210

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9220

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.

9211

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.

9221

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9212

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9222

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9213

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9223

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9214

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9224

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9215

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9225

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9216

OP.MLSD = xls_parameter(parameter, 'MLSD', false, 0); % not 0 or missing means use MLSD

9226

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9217

OP.MLSE = xls_parameter(parameter, 'MLSE', false, OP.MLSD ); % MSLD Synonym support

9227

if OP.MLSE ~=0

9218

if OP.MLSE ~=0

9228

if param.T_O ~= 0

9219

if param.T_O ~= 0

9229

error('MLSD nnot presently no supported for VEC')

9220

error('MLSD nnot presently no supported for VEC')

9230

end

9221

end

9231

if OP.COM_CONTRIBUTION_CURVES ~=0

9222

if OP.COM_CONTRIBUTION_CURVES ~=0

9232

warning('COM_CONTRIBUTION_CURVES not functional yet with MLSE')

9223

warning("COM_CONTRIBUTION_CURVES not functional yet with MLSE")

9233

OP.COM_CONTRIBUTION_CURVES=0;

9224

OP.COM_CONTRIBUTION_CURVES=0;

9234

end

9225

end

9235

end

9226

end

9236

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9227

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9237

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9228

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9238

if OP.MLSE && param.ndfe==0

9229

if OP.MLSE && param.ndfe==0

9239

error('At least DFE 1 must be set to use MLSE');

9230

error('At least DFE 1 must be set to use MLSE');

9240

end

9231

end

9241

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9232

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9242

% MNSE parameters

9233

% MNSE parameters

9243

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9234

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9244

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9235

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9245

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9236

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9246

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9237

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9247

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9238

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9248

% Commit request 4p4_7, healey_3dj_COM_01_240416

9239

% Commit request 4p4_7, healey_3dj_COM_01_240416

9249

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9240

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9250

% need to make sure TD mode does not invoke FD operations

9241

% need to make sure TD mode does not invoke FD operations

9251

if OP.TDMODE % need to set GET_FD false of TDMODE

9242

if OP.TDMODE % need to set GET_FD false of TDMODE

9252

OP.GET_FD=false;

9243

OP.GET_FD=false;

9253

OP.ERL_ONLY=0;

9244

OP.ERL_ONLY=0;

9254

OP.ERL=0;

9245

OP.ERL=0;

9255

OP.PTDR=0;

9246

OP.PTDR=0;

9256

OP.TDR=0;

9247

OP.TDR=0;

9257

OP.RX_CALIBRATION=0;

9248

OP.RX_CALIBRATION=0;

9258

end

9249

end

9259

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9250

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9260

save(matcongfile ,'parameter');

9251

save(matcongfile ,'parameter');

9261

end

9252

end

9262

9253

9263

9254

9264

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9255

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9265

if ~isempty(param.PKG_NAME)

9256

if ~isempty(param.PKG_NAME)

9266

if length(param.PKG_NAME) == 1

9257

if length(param.PKG_NAME) == 1

9267

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9258

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9268

end

9259

end

9269

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9260

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9270

tx_rx_fields_matrix = {'pkg_Z_c'};

9261

tx_rx_fields_matrix = {'pkg_Z_c'};

9271

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9262

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9272

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9263

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9273

tx_pkg_name=param.PKG_NAME{1};

9264

tx_pkg_name=param.PKG_NAME{1};

9274

rx_pkg_name=param.PKG_NAME{2};

9265

rx_pkg_name=param.PKG_NAME{2};

9275

tx_pkg_struct=param.PKG.(tx_pkg_name);

9266

tx_pkg_struct=param.PKG.(tx_pkg_name);

9276

rx_pkg_struct=param.PKG.(rx_pkg_name);

9267

rx_pkg_struct=param.PKG.(rx_pkg_name);

9277

9268

9278

%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

9269

%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

9279

for j=1:length(tx_rx_fields)

9270

for j=1:length(tx_rx_fields)

9280

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9271

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9281

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9272

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9282

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9273

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9283

end

9274

end

9284

9275

9285

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9276

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9286

for j=1:length(tx_rx_fields_matrix)

9277

for j=1:length(tx_rx_fields_matrix)

9287

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9278

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9288

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9279

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9289

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9280

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9290

end

9281

end

9291

9282

9292

%tx_fields: use only the tx package values

9283

%tx_fields: use only the tx package values

9293

for j=1:length(tx_fields)

9284

for j=1:length(tx_fields)

9294

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9285

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9295

end

9286

end

9296

9287

9297

%rx_fields: use only the rx package values

9288

%rx_fields: use only the rx package values

9298

for j=1:length(rx_fields)

9289

for j=1:length(rx_fields)

9299

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9290

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9300

end

9291

end

9301

9292

9302

end

9293

end

9303

9294

9304

9295

9305

%%

9296

%%

9306

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9297

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9307

%% FUNCTION :: read_sp4_sparams

9298

%% FUNCTION :: read_sp4_sparams

9308

%

9299

%

9309

% Description

9300

% Description

9310

% Read the fid of single-ended 4-port complex S-parameters

9301

% Read the fid of single-ended 4-port complex S-parameters

9311

% in Touchstone format 'file' and convert to the internal

9302

% in Touchstone format 'file' and convert to the internal

9312

% format using the port transform 'ports'

9303

% format using the port transform 'ports'

9313

%

9304

%

9314

% Created by Mike Y. He

9305

% Created by Mike Y. He

9315

% April 22, 2005

9306

% April 22, 2005

9316

%

9307

%

9317

% Reused some code from

9308

% Reused some code from

9318

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9309

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9319

% for touchstone 4-port S-matrix import.

9310

% for touchstone 4-port S-matrix import.

9320

%

9311

%

9321

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9312

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9322

% optimized for quicker parameter matching and parsing. also, separated out

9313

% optimized for quicker parameter matching and parsing. also, separated out

9323

% the plotting algorithms into their own sub-function routines

9314

% the plotting algorithms into their own sub-function routines

9324

%

9315

%

9325

% Modified December 2021 to use read_Nport_touchstone

9316

% Modified December 2021 to use read_Nport_touchstone

9326

% This is faster reader that is capable of reading touchstone with any number of ports

9317

% This is faster reader that is capable of reading touchstone with any number of ports

9327

%

9318

%

9328

% Input Variables (required)

9319

% Input Variables (required)

9329

% infile -- The s4p file to be read and converted

9320

% infile -- The s4p file to be read and converted

9330

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9321

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9331

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9322

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9332

% ports -- Re-order the port layout

9323

% ports -- Re-order the port layout

9333

%

9324

%

9334

% Output/Return Variables

9325

% Output/Return Variables

9335

% data -- structure containing network parameter data points and frequency axis

9326

% data -- structure containing network parameter data points and frequency axis

9336

% sdc -- the differential in/common-mode out s-parameter data matrix

9327

% sdc -- the differential in/common-mode out s-parameter data matrix

9337

% sdd -- the differential in/differential out s-parameter data matrix

9328

% sdd -- the differential in/differential out s-parameter data matrix

9338

%

9329

%

9339

9330

9340

9331

9341

% backwards compatibility settings. can be removed in updated code.

9332

% backwards compatibility settings. can be removed in updated code.

9342

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9333

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9343

if isempty(ports); ports = [1 2]; end % default order normally used.

9334

if isempty(ports); ports = [1 2]; end % default order normally used.

9344

ports = [1 2];

9335

ports = [1 2];

9345

9336

9346

9337

9347

if OP.DISPLAY_WINDOW

9338

if OP.DISPLAY_WINDOW

9348

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

9339

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

9349

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9340

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9350

end

9341

end

9351

9342

9352

%AJG: fast touchstone read for any number of ports

9343

%AJG: fast touchstone read for any number of ports

9353

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9344

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9354

9345

9355

9346

9356

9347

9357

D=NaN(size(sch));

9348

D=NaN(size(sch));

9358

% calculate differential s parameter matrix from single ended

9349

% calculate differential s parameter matrix from single ended

9359

for i=1:size(sch,1)

9350

for i=1:size(sch,1)

9360

S(:,:) = sch(i,:,:);

9351

S(:,:) = sch(i,:,:);

9361

T = [1 1 ; 1 -1 ];

9352

T = [1 1 ; 1 -1 ];

9362

W = T * (S / T);

9353

W = T * (S / T);

9363

D(i,:,:) = W(:,:);

9354

D(i,:,:) = W(:,:);

9364

end

9355

end

9365

9356

9366

% D matrix should be

9357

% D matrix should be

9367

% Scc11 Scd11 Scc12 Scd21

9358

% Scc11 Scd11 Scc12 Scd21

9368

% Sdc11 Sdd11 Sdc12 Sdd12

9359

% Sdc11 Sdd11 Sdc12 Sdd12

9369

% Scc21 Scd21 Scc22 Scd22

9360

% Scc21 Scd21 Scc22 Scd22

9370

% Sdc21 Sdd21 Sdc22 Sdd22

9361

% Sdc21 Sdd21 Sdc22 Sdd22

9371

9362

9372

% proper values

9363

% proper values

9373

%AJG: matrix can be properly referenced after fixing mapping

9364

%AJG: matrix can be properly referenced after fixing mapping

9374

SDD(:,1,1) = D(:,2,2);

9365

SDD(:,1,1) = D(:,2,2);

9375

SDC(:,1,1)= D(:,2,1);

9366

SDC(:,1,1)= D(:,2,1);

9376

SCC(:,1,1)= D(:,1,1);

9367

SCC(:,1,1)= D(:,1,1);

9377

SCD(:,1,1)= D(:,1,2);

9368

SCD(:,1,1)= D(:,1,2);

9378

9369

9379

9370

9380

9371

9381

% backwards compatibility output variables

9372

% backwards compatibility output variables

9382

data.m = sch;

9373

data.m = sch;

9383

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9374

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9384

data.freq = schFreqAxis;

9375

data.freq = schFreqAxis;

9385

colors = 'rgbk';

9376

colors = 'rgbk';

9386

9377

9387

if (plot_ini_s_params == 1)

9378

if (plot_ini_s_params == 1)

9388

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9379

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9389

for mj=1:4

9380

for mj=1:4

9390

% subplot(2,2,mj);

9381

% subplot(2,2,mj);

9391

for mi=1:4

9382

for mi=1:4

9392

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9383

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9393

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9384

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9394

hold on

9385

hold on

9395

end

9386

end

9396

xlabel('Frequency (Hz)');

9387

xlabel('Frequency (Hz)');

9397

ylabel('Magnitude (dB)');

9388

ylabel('Magnitude (dB)');

9398

legend show

9389

legend show

9399

grid on

9390

grid on

9400

title(sprintf('Output port %d', mj));

9391

title(sprintf('Output port %d', mj));

9401

end

9392

end

9402

end

9393

end

9403

plot_dif_s_params =0;

9394

plot_dif_s_params =0;

9404

if (plot_dif_s_params == 1)

9395

if (plot_dif_s_params == 1)

9405

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9396

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9406

% subplot(2,1,1);

9397

% subplot(2,1,1);

9407

for mj=1:1

9398

for mj=1:1

9408

for mi=1:1

9399

for mi=1:1

9409

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9400

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9410

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9401

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9411

hold on

9402

hold on

9412

end

9403

end

9413

end

9404

end

9414

xlabel('Frequency (Hz)');

9405

xlabel('Frequency (Hz)');

9415

ylabel('Magnitude (dB)');

9406

ylabel('Magnitude (dB)');

9416

legend show

9407

legend show

9417

grid on

9408

grid on

9418

title(infile);

9409

title(infile);

9419

9410

9420

% subplot(2,1,2);

9411

% subplot(2,1,2);

9421

% for mj=1:2

9412

% for mj=1:2

9422

% for mi=1:2

9413

% for mi=1:2

9423

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9414

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9424

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9415

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9425

% hold on

9416

% hold on

9426

% end

9417

% end

9427

% end

9418

% end

9428

% xlabel('Frequency (Hz)');

9419

% xlabel('Frequency (Hz)');

9429

% ylabel('Magnitude (dB)');

9420

% ylabel('Magnitude (dB)');

9430

% legend show

9421

% legend show

9431

% grid on

9422

% grid on

9432

end

9423

end

9433

9424

9434

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9425

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9435

% end read_sp2_sparam

9426

% end read_sp2_sparam

9436

9427

9437

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9428

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9438

%% FUNCTION :: read_sp4_sparams

9429

%% FUNCTION :: read_sp4_sparams

9439

%

9430

%

9440

% Description

9431

% Description

9441

% Read the fid of single-ended 4-port complex S-parameters

9432

% Read the fid of single-ended 4-port complex S-parameters

9442

% in Touchstone format 'file' and convert to the internal

9433

% in Touchstone format 'file' and convert to the internal

9443

% format using the port transform 'ports'

9434

% format using the port transform 'ports'

9444

%

9435

%

9445

% Created by Mike Y. He

9436

% Created by Mike Y. He

9446

% April 22, 2005

9437

% April 22, 2005

9447

%

9438

%

9448

% Reused some code from

9439

% Reused some code from

9449

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9440

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9450

% for touchstone 4-port S-matrix import.

9441

% for touchstone 4-port S-matrix import.

9451

%

9442

%

9452

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9443

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9453

% optimized for quicker parameter matching and parsing. also, separated out

9444

% optimized for quicker parameter matching and parsing. also, separated out

9454

% the plotting algorithms into their own sub-function routines

9445

% the plotting algorithms into their own sub-function routines

9455

%

9446

%

9456

% Modified December 2021 to use read_Nport_touchstone

9447

% Modified December 2021 to use read_Nport_touchstone

9457

% This is faster reader that is capable of reading touchstone with any number of ports

9448

% This is faster reader that is capable of reading touchstone with any number of ports

9458

%

9449

%

9459

% Input Variables (required)

9450

% Input Variables (required)

9460

% infile -- The s4p file to be read and converted

9451

% infile -- The s4p file to be read and converted

9461

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9452

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9462

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9453

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9463

% ports -- Re-order the port layout

9454

% ports -- Re-order the port layout

9464

% OP

9455

% OP

9465

% param

9456

% param

9466

% Output/Return Variables

9457

% Output/Return Variables

9467

% data -- structure containing network parameter data points and frequency axis

9458

% data -- structure containing network parameter data points and frequency axis

9468

% sdd -- the differential in/differential out s-parameter data matrix

9459

% sdd -- the differential in/differential out s-parameter data matrix

9469

% sdc -- the differential in/common-mode out s-parameter data matrix

9460

% sdc -- the differential in/common-mode out s-parameter data matrix

9470

% scc -- the common mode in/common-mode out s-parameter data matrix

9461

% scc -- the common mode in/common-mode out s-parameter data matrix

9471

%

9462

%

9472

%

9463

%

9473

9464

9474

9465

9475

% backwards compatibility settings. can be removed in updated code.

9466

% backwards compatibility settings. can be removed in updated code.

9476

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9467

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9477

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9468

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9478

9469

9479

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9470

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9480

% pair is reversed.

9471

% pair is reversed.

9481

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9472

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9482

9473

9483

if OP.DISPLAY_WINDOW

9474

if OP.DISPLAY_WINDOW

9484

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9475

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9485

end

9476

end

9486

9477

9487

%AJG: fast touchstone read for any number of ports

9478

%AJG: fast touchstone read for any number of ports

9488

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9479

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9489

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9480

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9490

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9481

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9491

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9482

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9492

Sigfct = ...

9483

Sigfct = ...

9493

@(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]);

9484

@(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]);

9494

D=NaN(size(sch));

9485

D=NaN(size(sch));

9495

% calculate differential s parameter matrix from single ended

9486

% calculate differential s parameter matrix from single ended

9496

% skew added RIM 12/29/2023

9487

% skew added RIM 12/29/2023

9497

for i=1:size(sch,1)

9488

for i=1:size(sch,1)

9498

f=schFreqAxis(i);

9489

f=schFreqAxis(i);

9499

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) );

9490

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) );

9500

S(:,:) = sch(i,:,:);

9491

S(:,:) = sch(i,:,:);

9501

Snew=sigma_matrix.*S;

9492

Snew=sigma_matrix.*S;

9502

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9493

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9503

W = T * (Snew / T);

9494

W = T * (Snew / T);

9504

D(i,:,:) = W(:,:);

9495

D(i,:,:) = W(:,:);

9505

end

9496

end

9506

9497

9507

% D matrix should be

9498

% D matrix should be

9508

% Scc11 Scd11 Scc12 Scd21

9499

% Scc11 Scd11 Scc12 Scd21

9509

% Sdc11 Sdd11 Sdc12 Sdd12

9500

% Sdc11 Sdd11 Sdc12 Sdd12

9510

% Scc21 Scd21 Scc22 Scd22

9501

% Scc21 Scd21 Scc22 Scd22

9511

% Sdc21 Sdd21 Sdc22 Sdd22

9502

% Sdc21 Sdd21 Sdc22 Sdd22

9512

9503

9513

% proper values

9504

% proper values

9514

SDD(:,1,1) = D(:,2,2);

9505

SDD(:,1,1) = D(:,2,2);

9515

SDD(:,2,2) = D(:,4,4);

9506

SDD(:,2,2) = D(:,4,4);

9516

SDD(:,1,2) = D(:,2,4);

9507

SDD(:,1,2) = D(:,2,4);

9517

SDD(:,2,1) = D(:,4,2);

9508

SDD(:,2,1) = D(:,4,2);

9518

9509

9519

SDC(:,1,1) = D(:,2,1);

9510

SDC(:,1,1) = D(:,2,1);

9520

SDC(:,2,2) = D(:,4,3);

9511

SDC(:,2,2) = D(:,4,3);

9521

SDC(:,1,2) = D(:,2,3);

9512

SDC(:,1,2) = D(:,2,3);

9522

SDC(:,2,1) = D(:,4,1);

9513

SDC(:,2,1) = D(:,4,1);

9523

9514

9524

SCC(:,1,1) = D(:,1,1);

9515

SCC(:,1,1) = D(:,1,1);

9525

SCC(:,2,2) = D(:,3,3);

9516

SCC(:,2,2) = D(:,3,3);

9526

SCC(:,1,2) = D(:,1,3);

9517

SCC(:,1,2) = D(:,1,3);

9527

SCC(:,2,1) = D(:,3,1);

9518

SCC(:,2,1) = D(:,3,1);

9528

9519

9529

% backwards compatibility output variables

9520

% backwards compatibility output variables

9530

data.m = sch;

9521

data.m = sch;

9531

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9522

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9532

data.freq = schFreqAxis;

9523

data.freq = schFreqAxis;

9533

colors = 'rgbk';

9524

colors = 'rgbk';

9534

9525

9535

if (plot_ini_s_params == 1)

9526

if (plot_ini_s_params == 1)

9536

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9527

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9537

for mj=1:4

9528

for mj=1:4

9538

subplot(2,2,mj);

9529

subplot(2,2,mj);

9539

for mi=1:4

9530

for mi=1:4

9540

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9531

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9541

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9532

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9542

hold on

9533

hold on

9543

end

9534

end

9544

xlabel('Frequency (Hz)');

9535

xlabel('Frequency (Hz)');

9545

ylabel('Magnitude (dB)');

9536

ylabel('Magnitude (dB)');

9546

legend show

9537

legend show

9547

grid on

9538

grid on

9548

title(sprintf('Output port %d', mj));

9539

title(sprintf('Output port %d', mj));

9549

end

9540

end

9550

end

9541

end

9551

plot_dif_s_params =0;

9542

plot_dif_s_params =0;

9552

if (plot_dif_s_params == 1)

9543

if (plot_dif_s_params == 1)

9553

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9544

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9554

% subplot(2,1,1);

9545

% subplot(2,1,1);

9555

for mj=1:2

9546

for mj=1:2

9556

for mi=1:2

9547

for mi=1:2

9557

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9548

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9558

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9549

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9559

hold on

9550

hold on

9560

end

9551

end

9561

end

9552

end

9562

xlabel('Frequency (Hz)');

9553

xlabel('Frequency (Hz)');

9563

ylabel('Magnitude (dB)');

9554

ylabel('Magnitude (dB)');

9564

legend show

9555

legend show

9565

grid on

9556

grid on

9566

title(infile);

9557

title(infile);

9567

%

9558

%

9568

% subplot(2,1,2);

9559

% subplot(2,1,2);

9569

% for mj=1:2

9560

% for mj=1:2

9570

% for mi=1:2

9561

% for mi=1:2

9571

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9562

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9572

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9563

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9573

% hold on

9564

% hold on

9574

% end

9565

% end

9575

% end

9566

% end

9576

% xlabel('Frequency (Hz)');

9567

% xlabel('Frequency (Hz)');

9577

% ylabel('Magnitude (dB)');

9568

% ylabel('Magnitude (dB)');

9578

% legend show

9569

% legend show

9579

% grid on

9570

% grid on

9580

end

9571

end

9581

9572

9582

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9573

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9583

% end read_sp4_sparam

9574

% end read_sp4_sparam

9584

function param_struct = read_package_parameters(parameter,param_struct)

9575

function param_struct = read_package_parameters(parameter,param_struct)

9585

9576

9586

%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

9577

%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

9587

%This block should eventually replace what is in read_ParamConfigFile

9578

%This block should eventually replace what is in read_ParamConfigFile

9588

%It can be called as: param = read_package_parameters(parameter, param)

9579

%It can be called as: param = read_package_parameters(parameter, param)

9589

9580

9590

if nargin<2

9581

if nargin<2

9591

%param_struct doesn't need to be passed when building a new package structure

9582

%param_struct doesn't need to be passed when building a new package structure

9592

%it is only needed when appending to regular param structure

9583

%it is only needed when appending to regular param structure

9593

param_struct=struct;

9584

param_struct=struct;

9594

end

9585

end

9595

9586

9596

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9587

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9597

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9588

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9598

9589

9599

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9590

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9600

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9591

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9601

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9592

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9602

9593

9603

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

9594

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

9604

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

9595

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

9605

if mele ==2

9596

if mele ==2

9606

param_struct.flex=2;

9597

param_struct.flex=2;

9607

elseif mele==4

9598

elseif mele==4

9608

param_struct.flex=4;

9599

param_struct.flex=4;

9609

elseif mele==1

9600

elseif mele==1

9610

param_struct.flex=1;

9601

param_struct.flex=1;

9611

else

9602

else

9612

error('config file syntax error')

9603

error('config file syntax error')

9613

end

9604

end

9614

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

9605

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

9615

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9606

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9616

if ncases ~= ncases1 || mele ~= mele1

9607

if ncases ~= ncases1 || mele ~= mele1

9617

error('All TX, NEXT, FEXT, Rx cases must agree');

9608

error('All TX, NEXT, FEXT, Rx cases must agree');

9618

else

9609

else

9619

end

9610

end

9620

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

9611

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

9621

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9612

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9622

if ncases ~= ncases1 || mele ~= mele1

9613

if ncases ~= ncases1 || mele ~= mele1

9623

error('All TX, NEXT, FEXT, Rx cases must agree');

9614

error('All TX, NEXT, FEXT, Rx cases must agree');

9624

else

9615

else

9625

end

9616

end

9626

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

9617

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

9627

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9618

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9628

if ncases ~= ncases1 || mele ~= mele1

9619

if ncases ~= ncases1 || mele ~= mele1

9629

error('All TX, NEXT, FEXT, Rx cases must agree');

9620

error('All TX, NEXT, FEXT, Rx cases must agree');

9630

else

9621

else

9631

end

9622

end

9632

% Table 93A-3 parameters

9623

% Table 93A-3 parameters

9633

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.

9624

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.

9634

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9625

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9635

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9626

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9636

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9627

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9637

if mele ~= mele1

9628

if mele ~= mele1

9638

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9629

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9639

else

9630

else

9640

end

9631

end

9641

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9632

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9642

for ii=1:ncases

9633

for ii=1:ncases

9643

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9634

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9644

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9635

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9645

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9636

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9646

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9637

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9647

end

9638

end

9648

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9639

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9649

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9640

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9650

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9641

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9651

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9642

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9652

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9643

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9653

end

9644

end

9654

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

9645

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

9655

%% extract s-parameter and convert to differential mode

9646

%% extract s-parameter and convert to differential mode

9656

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9647

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9657

num_files=length(chdata);

9648

num_files=length(chdata);

9658

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9649

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9659

for i=1:num_files

9650

for i=1:num_files

9660

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9651

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9661

progress = i/num_files;

9652

progress = i/num_files;

9662

if OP.DISPLAY_WINDOW

9653

if OP.DISPLAY_WINDOW

9663

[~,a]=fileparts(chdata(i).filename);

9654

[~,a]=fileparts(chdata(i).filename);

9664

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9655

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9665

else

9656

else

9666

fprintf('%i ',i);

9657

fprintf('%i ',i);

9667

end

9658

end

9668

9659

9669

% Skip reading file if it was already read (multiple test cases)

9660

% Skip reading file if it was already read (multiple test cases)

9670

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9661

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9671

switch lower(chdata(i).ext)

9662

switch lower(chdata(i).ext)

9672

case '.s2p' % for differential return loss

9663

case '.s2p' % for differential return loss

9673

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9664

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9674

chdata(i).fmaxi = length(Sch.freq);

9665

chdata(i).fmaxi = length(Sch.freq);

9675

chdata(i).faxis = Sch.freq;

9666

chdata(i).faxis = Sch.freq;

9676

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9667

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9677

SDDp2p(i)=NaN;

9668

SDDp2p(i)=NaN;

9678

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9669

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9679

chdata(i).sdd11=chdata(i).sdd11_raw;

9670

chdata(i).sdd11=chdata(i).sdd11_raw;

9680

case '.s4p'

9671

case '.s4p'

9681

if length(param.snpPortsOrder) ~= 4

9672

if length(param.snpPortsOrder) ~= 4

9682

error( 'warning:sNpFilePortMismatch', ...

9673

error( 'warning:sNpFilePortMismatch', ...

9683

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9674

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9684

length(param.snpPortsOrder), ...

9675

length(param.snpPortsOrder), ...

9685

chdata(i).ext ...

9676

chdata(i).ext ...

9686

);

9677

);

9687

end

9678

end

9688

% read function returns differnetial mode parameters

9679

% read function returns differnetial mode parameters

9689

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9680

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9690

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9681

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9691

% param.holdsdata(i).Sch= Sch;

9682

% param.holdsdata(i).Sch= Sch;

9692

% param.holdsdata(i).SDDch= SDDch;

9683

% param.holdsdata(i).SDDch= SDDch;

9693

% param.holdsdata(i).SDCch= SDCch;

9684

% param.holdsdata(i).SDCch= SDCch;

9694

else

9685

else

9695

error('If this line is reached, there is a logic error');

9686

error('If this line is reached, there is a logic error');

9696

% Sch=param.holdsdata(i).Sch;

9687

% Sch=param.holdsdata(i).Sch;

9697

% SDDch=param.holdsdata(i).SDDch;

9688

% SDDch=param.holdsdata(i).SDDch;

9698

% SDCch=param.holdsdata(i).SDCch;

9689

% SDCch=param.holdsdata(i).SDCch;

9699

end

9690

end

9700

chdata(i).fmaxi = length(Sch.freq);

9691

chdata(i).fmaxi = length(Sch.freq);

9701

9692

9702

9693

9703

if Sch.freq(chdata(i).fmaxi) < param.fb

9694

if Sch.freq(chdata(i).fmaxi) < param.fb

9704

warning('COM:read_s4p:MaxFreqTooLow', ...

9695

warning('COM:read_s4p:MaxFreqTooLow', ...

9705

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9696

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9706

chdata(i).filename, Sch.freq(end), param.fb);

9697

chdata(i).filename, Sch.freq(end), param.fb);

9707

end

9698

end

9708

if Sch.freq(1) > param.max_start_freq

9699

if Sch.freq(1) > param.max_start_freq

9709

warning('COM:read_s4p:StartFreqTooHigh', ...

9700

warning('COM:read_s4p:StartFreqTooHigh', ...

9710

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9701

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9711

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9702

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9712

end

9703

end

9713

freqstep=diff(Sch.freq);

9704

freqstep=diff(Sch.freq);

9714

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9705

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9715

if max(freqstep)-min(freqstep) > 1

9706

if max(freqstep)-min(freqstep) > 1

9716

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9707

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9717

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9708

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9718

end

9709

end

9719

if max(freqstep) - param.max_freq_step > 1

9710

if max(freqstep) - param.max_freq_step > 1

9720

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9711

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9721

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9712

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9722

end

9713

end

9723

9714

9724

chdata(i).faxis = Sch.freq;

9715

chdata(i).faxis = Sch.freq;

9725

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9716

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9726

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9717

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9727

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9718

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9728

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9719

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9729

% mode conversion

9720

% mode conversion

9730

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9721

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9731

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9722

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9732

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9723

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9733

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9724

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9734

%save original and add board (if required)

9725

%save original and add board (if required)

9735

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9726

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9736

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9727

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9737

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9728

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9738

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9729

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9739

if OP.include_pcb

9730

if OP.include_pcb

9740

% add boards to sdd

9731

% add boards to sdd

9741

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9732

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9742

9733

9743

end

9734

end

9744

%save final return loss (after the boards were included)

9735

%save final return loss (after the boards were included)

9745

chdata(i).sdd11=chdata(i).sdd11_raw;

9736

chdata(i).sdd11=chdata(i).sdd11_raw;

9746

chdata(i).sdd22=chdata(i).sdd22_raw;

9737

chdata(i).sdd22=chdata(i).sdd22_raw;

9747

otherwise

9738

otherwise

9748

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9739

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9749

end

9740

end

9750

9741

9751

%Crosstalk frequency axis must be the same as Thru

9742

%Crosstalk frequency axis must be the same as Thru

9752

if i>1

9743

if i>1

9753

%error on length difference

9744

%error on length difference

9754

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9745

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9755

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9746

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9756

end

9747

end

9757

%error if any value > 1Hz (don't want to check for exact

9748

%error if any value > 1Hz (don't want to check for exact

9758

%equality in case of floating point error)

9749

%equality in case of floating point error)

9759

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9750

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9760

if max(Fdiff)>1

9751

if max(Fdiff)>1

9761

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9752

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9762

end

9753

end

9763

end

9754

end

9764

else

9755

else

9765

SDDch(:,1,2)=chdata(i).sdd12_raw;

9756

SDDch(:,1,2)=chdata(i).sdd12_raw;

9766

SDDch(:,2,1)=chdata(i).sdd21_raw;

9757

SDDch(:,2,1)=chdata(i).sdd21_raw;

9767

SDDch(:,1,1)=chdata(i).sdd11_raw;

9758

SDDch(:,1,1)=chdata(i).sdd11_raw;

9768

SDDch(:,2,2)=chdata(i).sdd22_raw;

9759

SDDch(:,2,2)=chdata(i).sdd22_raw;

9769

end

9760

end

9770

chdata(i).sigma_ACCM_at_tp0=0;

9761

chdata(i).sigma_ACCM_at_tp0=0;

9771

if ~param.FLAG.S2P

9762

if ~param.FLAG.S2P

9772

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9763

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9773

if (OP.RX_CALIBRATION == 1 && i==2)

9764

if (OP.RX_CALIBRATION == 1 && i==2)

9774

chdata(i).sdd21=chdata(i).sdd21_raw;

9765

chdata(i).sdd21=chdata(i).sdd21_raw;

9775

else

9766

else

9776

%updated package construction with single function for both DD and DC

9767

%updated package construction with single function for both DD and DC

9777

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9768

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9778

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9769

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9779

chdata(i).sdd21=chdata(i).sdd21p;

9770

chdata(i).sdd21=chdata(i).sdd21p;

9780

if 1 % for AC CM noise inclusion

9771

if 1 % for AC CM noise inclusion

9781

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9772

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9782

chdata(i).sdc21=chdata(i).sdc21p;

9773

chdata(i).sdc21=chdata(i).sdc21p;

9783

end

9774

end

9784

end

9775

end

9785

else

9776

else

9786

chdata(i).sdd21=chdata(i).sdd21_raw;

9777

chdata(i).sdd21=chdata(i).sdd21_raw;

9787

end

9778

end

9788

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9779

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9789

end

9780

end

9790

end

9781

end

9791

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

9782

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

9792

9783

9793

function result = readdataSnPx(filename, nport)

9784

function result = readdataSnPx(filename, nport)

9794

%function [freq, cs] = readdataSnPx(filename, nport)

9785

%function [freq, cs] = readdataSnPx(filename, nport)

9795

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9786

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9796

%

9787

%

9797

% Read Touchstone file with frequencies in units of Hertz

9788

% Read Touchstone file with frequencies in units of Hertz

9798

%

9789

%

9799

% Input:

9790

% Input:

9800

% ======

9791

% ======

9801

% filename: Name of the Touchstone/SnP file

9792

% filename: Name of the Touchstone/SnP file

9802

% nport: Number of ports

9793

% nport: Number of ports

9803

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9794

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9804

% Touchstone file)

9795

% Touchstone file)

9805

% nheader: Number of header lines (comment lines plus option line in the

9796

% nheader: Number of header lines (comment lines plus option line in the

9806

% Touchstone file)

9797

% Touchstone file)

9807

%

9798

%

9808

% Output:

9799

% Output:

9809

% =======

9800

% =======

9810

% freq: Vector of frequencies [Hz]

9801

% freq: Vector of frequencies [Hz]

9811

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9802

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9812

% at frequency freq(k)

9803

% at frequency freq(k)

9813

%

9804

%

9814

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9805

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

9815

% frequencies appropriately after reading the data.

9806

% frequencies appropriately after reading the data.

9816

%

9807

%

9817

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9808

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

9818

% EIA/IBIS Open Forum, 2002.

9809

% EIA/IBIS Open Forum, 2002.

9819

%

9810

%

9820

% Written by Henning Braunisch, September 2004.

9811

% Written by Henning Braunisch, September 2004.

9821

% Updated by Steven Krooswyk, April 2006.

9812

% Updated by Steven Krooswyk, April 2006.

9822

9813

9823

9814

9824

fid = fopen(filename, 'r');

9815

fid = fopen(filename, 'r');

9825

9816

9826

9817

9827

% Skip header lines

9818

% Skip header lines

9828

str = ' ';

9819

str = ' ';

9829

n = 0;

9820

n = 0;

9830

while ~strcmp(str(1),'#')

9821

while ~strcmp(str(1),'#')

9831

str = fgetl(fid);

9822

str = fgetl(fid);

9832

if isempty(str)

9823

if isempty(str)

9833

str=' ' ;

9824

str=' ' ;

9834

if n > 1000

9825

if n > 1000

9835

display('error: could not find config line (#)')

9826

display('error: could not find config line (#)')

9836

break

9827

break

9837

end

9828

end

9838

end

9829

end

9839

n = n + 1;

9830

n = n + 1;

9840

end

9831

end

9841

9832

9842

% parse configuration line

9833

% parse configuration line

9843

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9834

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

9844

p = find(A=='S'); %position of 'S'

9835

p = find(A=='S'); %position of 'S'

9845

units = lower(A(2:p-1)); %units before 'S'

9836

units = lower(A(2:p-1)); %units before 'S'

9846

format = A(p+1:p+2); %format after 'S'

9837

format = A(p+1:p+2); %format after 'S'

9847

9838

9848

% skip any more header lines

9839

% skip any more header lines

9849

%while ~str

9840

%while ~str

9850

9841

9851

nk = 0; % frequency counter

9842

nk = 0; % frequency counter

9852

while 1

9843

while 1

9853

9844

9854

[temp, count] = fscanf(fid, '%f', 1);

9845

[temp, count] = fscanf(fid, '%f', 1);

9855

if count == 0

9846

if count == 0

9856

temp2 = fscanf(fid, '%s', 1);

9847

temp2 = fscanf(fid, '%s', 1);

9857

if ~isempty(temp2), fgetl(fid); continue, end;

9848

if ~isempty(temp2), fgetl(fid); continue, end;

9858

break

9849

break

9859

end

9850

end

9860

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9851

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

9861

for ni = 1:nport

9852

for ni = 1:nport

9862

for nj = 1:nport

9853

for nj = 1:nport

9863

switch lower(format)

9854

switch lower(format)

9864

case 'ma'

9855

case 'ma'

9865

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9856

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9866

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9857

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

9867

case 'ri'

9858

case 'ri'

9868

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9859

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

9869

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9860

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9870

case 'db'

9861

case 'db'

9871

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9862

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

9872

M = 10^(db/20);

9863

M = 10^(db/20);

9873

%re = M*cos(ang);

9864

%re = M*cos(ang);

9874

%im = M*sin(ang);

9865

%im = M*sin(ang);

9875

re = M*cos(ang * pi / 180);

9866

re = M*cos(ang * pi / 180);

9876

im = M*sin(ang * pi / 180);

9867

im = M*sin(ang * pi / 180);

9877

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9868

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

9878

otherwise

9869

otherwise

9879

error('readdataSnP: Unknown data format');

9870

error('readdataSnP: Unknown data format');

9880

end

9871

end

9881

end

9872

end

9882

end

9873

end

9883

end

9874

end

9884

9875

9885

fclose(fid);

9876

fclose(fid);

9886

9877

9887

% If 2-port then swap S_12 and S_21 per Touchstone spec

9878

% If 2-port then swap S_12 and S_21 per Touchstone spec

9888

if nport == 2

9879

if nport == 2

9889

temp = cs(2,1,:);

9880

temp = cs(2,1,:);

9890

cs(2,1,:) = cs(1,2,:);

9881

cs(2,1,:) = cs(1,2,:);

9891

cs(1,2,:) = temp;

9882

cs(1,2,:) = temp;

9892

end

9883

end

9893

9884

9894

% Update freq units to Hz

9885

% Update freq units to Hz

9895

switch lower(units)

9886

switch lower(units)

9896

case 'hz'

9887

case 'hz'

9897

9888

9898

case 'khz'

9889

case 'khz'

9899

freq=freq.*1e3;

9890

freq=freq.*1e3;

9900

case 'mhz'

9891

case 'mhz'

9901

freq=freq.*1e6;

9892

freq=freq.*1e6;

9902

case 'ghz'

9893

case 'ghz'

9903

freq=freq.*1e9;

9894

freq=freq.*1e9;

9904

end

9895

end

9905

9896

9906

% passivity check

9897

% passivity check

9907

result.freq = freq;

9898

result.freq = freq;

9908

result.cs = cs;

9899

result.cs = cs;

9909

9900

9910

function recolor_plots(ax)

9901

function recolor_plots(ax)

9911

9902

9912

if ~verLessThan('matlab', '8.4.0')

9903

if ~verLessThan('matlab', '8.4.0')

9913

return

9904

return

9914

end

9905

end

9915

colors='brgcmk';

9906

colors='brgcmk';

9916

ch=flipud(get(ax, 'children'));

9907

ch=flipud(get(ax, 'children'));

9917

9908

9918

for k=1:length(ch)

9909

for k=1:length(ch)

9919

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9910

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

9920

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9911

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

9921

end

9912

end

9922

legend (ax, 'off');

9913

legend (ax, 'off');

9923

warning('off', 'MATLAB:legend:PlotEmpty');

9914

warning('off', 'MATLAB:legend:PlotEmpty');

9924

set(legend (ax, 'show'), 'interp', 'none');

9915

set(legend (ax, 'show'), 'interp', 'none');

9925

9916

9926

function result = reduce(var1)

9917

function result = reduce(var1)

9927

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9918

% --- Reduce 1x1xn array to 1xn (aka squeeze)

9928

out = zeros(1,length(var1));

9919

out = zeros(1,length(var1));

9929

out(1,:) = var1(1,1,:);

9920

out(1,:) = var1(1,1,:);

9930

result=out;

9921

result=out;

9931

9922

9932

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9923

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

9933

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9924

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

9934

% faxis is the frequency array

9925

% faxis is the frequency array

9935

% s21, s11, s22 are the corresponding array of differential parameters

9926

% s21, s11, s22 are the corresponding array of differential parameters

9936

% s21p includes the VFT and Tx filter if include_die=1

9927

% s21p includes the VFT and Tx filter if include_die=1

9937

if nargin<6

9928

if nargin<6

9938

include_die=1;

9929

include_die=1;

9939

end

9930

end

9940

if nargin<5

9931

if nargin<5

9941

mode='dd';

9932

mode='dd';

9942

end

9933

end

9943

9934

9944

s21=chdata.(['s' mode '21_raw']);

9935

s21=chdata.(['s' mode '21_raw']);

9945

s12=chdata.(['s' mode '12_raw']);

9936

s12=chdata.(['s' mode '12_raw']);

9946

s11=chdata.(['s' mode '11_raw']);

9937

s11=chdata.(['s' mode '11_raw']);

9947

s22=chdata.(['s' mode '22_raw']);

9938

s22=chdata.(['s' mode '22_raw']);

9948

faxis=chdata.faxis;

9939

faxis=chdata.faxis;

9949

channel_type=chdata.type;

9940

channel_type=chdata.type;

9950

9941

9951

if strcmpi(mode,'dd')

9942

if strcmpi(mode,'dd')

9952

s11=s11*param.kappa1;

9943

s11=s11*param.kappa1;

9953

s22=s22*param.kappa2;

9944

s22=s22*param.kappa2;

9954

end

9945

end

9955

9946

9956

9947

9957

Z0=param.Z0;

9948

Z0=param.Z0;

9958

%sigma_ACCM_at_tp0 is only used when mode=DC

9949

%sigma_ACCM_at_tp0 is only used when mode=DC

9959

sigma_ACCM_at_tp0=0;

9950

sigma_ACCM_at_tp0=0;

9960

9951

9961

% The following three parameters have possibly different valuesF for TX and

9952

% The following three parameters have possibly different valuesF for TX and

9962

% RX (so can be 2-element vectors).

9953

% RX (so can be 2-element vectors).

9963

R_diepad = param.R_diepad;

9954

R_diepad = param.R_diepad;

9964

9955

9965

%Make TX Package

9956

%Make TX Package

9966

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9957

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

9967

9958

9968

%Make RX Package

9959

%Make RX Package

9969

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9960

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

9970

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9961

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

9971

9962

9972

9963

9973

% p(1 ,1, :)=s11in;

9964

% p(1 ,1, :)=s11in;

9974

% p(2 ,2, :)=s22in;

9965

% p(2 ,2, :)=s22in;

9975

% p(1 ,2, :)=s12in;

9966

% p(1 ,2, :)=s12in;

9976

% p(2 ,1, :)=s21in;

9967

% p(2 ,1, :)=s21in;

9977

%

9968

%

9978

% S=sparameters(p,faxis);

9969

% S=sparameters(p,faxis);

9979

% rfwrite(S,'temp.s4p');

9970

% rfwrite(S,'temp.s4p');

9980

9971

9981

if strcmpi(mode,'dc')

9972

if strcmpi(mode,'dc')

9982

RTX=R_diepad(param.Tx_rd_sel)/2;

9973

RTX=R_diepad(param.Tx_rd_sel)/2;

9983

RRX=R_diepad(param.Rx_rd_sel)/2;

9974

RRX=R_diepad(param.Rx_rd_sel)/2;

9984

Z0gamma=Z0/2;

9975

Z0gamma=Z0/2;

9985

else

9976

else

9986

RTX=R_diepad(param.Tx_rd_sel);

9977

RTX=R_diepad(param.Tx_rd_sel);

9987

RRX=R_diepad(param.Rx_rd_sel);

9978

RRX=R_diepad(param.Rx_rd_sel);

9988

Z0gamma=Z0;

9979

Z0gamma=Z0;

9989

end

9980

end

9990

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9981

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

9991

gamma_tx=0;

9982

gamma_tx=0;

9992

else

9983

else

9993

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9984

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

9994

end

9985

end

9995

if OP.IDEAL_RX_TERM

9986

if OP.IDEAL_RX_TERM

9996

gamma_rx=0;

9987

gamma_rx=0;

9997

else

9988

else

9998

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9989

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

9999

end

9990

end

10000

9991

10001

if OP.INC_PACKAGE==0

9992

if OP.INC_PACKAGE==0

10002

s21p= s21;

9993

s21p= s21;

10003

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

9994

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10004

else

9995

else

10005

if OP.RX_CALIBRATION == 1 && channel_number == 2

9996

if OP.RX_CALIBRATION == 1 && channel_number == 2

10006

% for calibration do not include the transmitter package

9997

% for calibration do not include the transmitter package

10007

[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

9998

[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

10008

SCH.Frequencies=faxis;

9999

SCH.Frequencies=faxis;

10009

SCH.Parameters(1,1,:)=s11out_rx;

10000

SCH.Parameters(1,1,:)=s11out_rx;

10010

SCH.Parameters(2,2,:)=s22out_rx;

10001

SCH.Parameters(2,2,:)=s22out_rx;

10011

SCH.Parameters(1,2,:)=s12out_rx;

10002

SCH.Parameters(1,2,:)=s12out_rx;

10012

SCH.Parameters(2,1,:)=s21out_rx;

10003

SCH.Parameters(2,1,:)=s21out_rx;

10013

SCH.NumPorts=2;

10004

SCH.NumPorts=2;

10014

SCH.Impedance=100;

10005

SCH.Impedance=100;

10015

%% Equation 93A-18

10006

%% Equation 93A-18

10016

if include_die

10007

if include_die

10017

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);

10008

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);

10018

else

10009

else

10019

s21p=s21out_rx; % if no die we do not want a VTF

10010

s21p=s21out_rx; % if no die we do not want a VTF

10020

end

10011

end

10021

else

10012

else

10022

%% Equations 93A-4 to 93A-7

10013

%% Equations 93A-4 to 93A-7

10023

if ~OP.IDEAL_TX_TERM

10014

if ~OP.IDEAL_TX_TERM

10024

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10015

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10025

end

10016

end

10026

H_t=ones(1,length(faxis)); % .3bj compatibility

10017

H_t=ones(1,length(faxis)); % .3bj compatibility

10027

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10018

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10028

% for RITT testing with good termination as in some instruments

10019

% for RITT testing with good termination as in some instruments

10029

% and tx filter when required

10020

% and tx filter when required

10030

if OP.T_r_filter_type==0

10021

if OP.T_r_filter_type==0

10031

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10022

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10032

else

10023

else

10033

tr=OP.transmitter_transition_time;

10024

tr=OP.transmitter_transition_time;

10034

f9=faxis/1e9;

10025

f9=faxis/1e9;

10035

if OP.T_r_meas_point == 1

10026

if OP.T_r_meas_point == 1

10036

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10027

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10037

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);

10028

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);

10038

else

10029

else

10039

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10030

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10040

end

10031

end

10041

10032

10042

end

10033

end

10043

end

10034

end

10044

if strcmpi(mode,'dc')

10035

if strcmpi(mode,'dc')

10045

% 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?

10036

% 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?

10046

end

10037

end

10047

if ~OP.IDEAL_RX_TERM

10038

if ~OP.IDEAL_RX_TERM

10048

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10039

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10049

else

10040

else

10050

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10041

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10051

end

10042

end

10052

%% 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 )

10043

%% 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 )

10053

if include_die

10044

if include_die

10054

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);

10045

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);

10055

else

10046

else

10056

s21p=s21; % if no die we do not want a VTF

10047

s21p=s21; % if no die we do not want a VTF

10057

end

10048

end

10058

end

10049

end

10059

10050

10060

if strcmpi(mode,'dc')

10051

if strcmpi(mode,'dc')

10061

% compute AC_CM_RMS at tp0

10052

% compute AC_CM_RMS at tp0

10062

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10053

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10063

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10054

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10064

if channel_number == 1

10055

if channel_number == 1

10065

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10056

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10066

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10057

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10067

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)) ;

10058

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)) ;

10068

% S=sparameters(p,faxis);

10059

% S=sparameters(p,faxis);

10069

% rfwrite(S,'temp.s4p');

10060

% rfwrite(S,'temp.s4p');

10070

end

10061

end

10071

end

10062

end

10072

10063

10073

SCH.Frequencies=faxis;

10064

SCH.Frequencies=faxis;

10074

SCH.Parameters(1,1,:)=s11;

10065

SCH.Parameters(1,1,:)=s11;

10075

SCH.Parameters(2,2,:)=s22;

10066

SCH.Parameters(2,2,:)=s22;

10076

SCH.Parameters(1,2,:)=s12;

10067

SCH.Parameters(1,2,:)=s12;

10077

SCH.Parameters(2,1,:)=s21;

10068

SCH.Parameters(2,1,:)=s21;

10078

SCH.NumPorts=2;

10069

SCH.NumPorts=2;

10079

if strcmpi(mode,'dc')

10070

if strcmpi(mode,'dc')

10080

SCH.Impedance=25;

10071

SCH.Impedance=25;

10081

else

10072

else

10082

SCH.Impedance=100;

10073

SCH.Impedance=100;

10083

end

10074

end

10084

10075

10085

end

10076

end

10086

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10077

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10087

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10078

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10088

% Creates a time-domain impulse response from frequency-domain IL data.

10079

% Creates a time-domain impulse response from frequency-domain IL data.

10089

% IL does not need to have DC but a corresponding frequency array

10080

% IL does not need to have DC but a corresponding frequency array

10090

% (freq_array) is required.

10081

% (freq_array) is required.

10091

%

10082

%

10092

% Causality is imposed using the Alternating Projections Method. See also:

10083

% Causality is imposed using the Alternating Projections Method. See also:

10093

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10084

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10094

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10085

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10095

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10086

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10096

10087

10097

ILin=IL;

10088

ILin=IL;

10098

fmax=1/time_step/2;

10089

fmax=1/time_step/2;

10099

freq_step=(freq_array(3)-freq_array(2))/1;

10090

freq_step=(freq_array(3)-freq_array(2))/1;

10100

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10091

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10101

if all(IL==0)

10092

if all(IL==0)

10102

%response with all zeros is problematic. set to all eps and avoid interp function

10093

%response with all zeros is problematic. set to all eps and avoid interp function

10103

IL=ones(1,length(fout))*eps;

10094

IL=ones(1,length(fout))*eps;

10104

else

10095

else

10105

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10096

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10106

IL_nan = find(isnan(IL));

10097

IL_nan = find(isnan(IL));

10107

for in=IL_nan

10098

for in=IL_nan

10108

IL(in)=IL(in-1);

10099

IL(in)=IL(in-1);

10109

end

10100

end

10110

end

10101

end

10111

IL = IL(:);

10102

IL = IL(:);

10112

% add padding for time steps

10103

% add padding for time steps

10113

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10104

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10114

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10105

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10115

impulse_response = real(ifft(IL_symmetric));

10106

impulse_response = real(ifft(IL_symmetric));

10116

L = length(impulse_response);

10107

L = length(impulse_response);

10117

t_base = (0:L-1)/(freq_step*L);

10108

t_base = (0:L-1)/(freq_step*L);

10118

10109

10119

original_impulse_response=impulse_response;

10110

original_impulse_response=impulse_response;

10120

% Correct non-causal effects frequently caused by extrapolation of IL

10111

% Correct non-causal effects frequently caused by extrapolation of IL

10121

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10112

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10122

abs_ir=abs(impulse_response);

10113

abs_ir=abs(impulse_response);

10123

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10114

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10124

start_ind = a(1);

10115

start_ind = a(1);

10125

10116

10126

err=inf;

10117

err=inf;

10127

while ~all(impulse_response==0)

10118

while ~all(impulse_response==0)

10128

impulse_response(1:start_ind)=0;

10119

impulse_response(1:start_ind)=0;

10129

impulse_response(floor(L/2):end)=0;

10120

impulse_response(floor(L/2):end)=0;

10130

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10121

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10131

ir_modified = real(ifft(IL_modified));

10122

ir_modified = real(ifft(IL_modified));

10132

delta = abs(impulse_response-ir_modified);

10123

delta = abs(impulse_response-ir_modified);

10133

10124

10134

err_prev = err;

10125

err_prev = err;

10135

err=max(delta)/max(impulse_response);

10126

err=max(delta)/max(impulse_response);

10136

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10127

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10137

break;

10128

break;

10138

end

10129

end

10139

10130

10140

impulse_response=ir_modified;

10131

impulse_response=ir_modified;

10141

end

10132

end

10142

10133

10143

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10134

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10144

10135

10145

if ~OP.ENFORCE_CAUSALITY

10136

if ~OP.ENFORCE_CAUSALITY

10146

impulse_response = original_impulse_response;

10137

impulse_response = original_impulse_response;

10147

end

10138

end

10148

% truncate final samples smaller than 1e-3 of the peak

10139

% truncate final samples smaller than 1e-3 of the peak

10149

ir_peak = max(abs(impulse_response));

10140

ir_peak = max(abs(impulse_response));

10150

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10141

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10151

10142

10152

voltage = impulse_response(1:ir_last);

10143

voltage = impulse_response(1:ir_last);

10153

t_base = t_base(1:ir_last);

10144

t_base = t_base(1:ir_last);

10154

10145

10155

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10146

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10156

10147

10157

function S =s_for_c2(zref,f,cpad)

10148

function S =s_for_c2(zref,f,cpad)

10158

% S is 2 port s parameters out

10149

% S is 2 port s parameters out

10159

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10150

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10160

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10151

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10161

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10152

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10162

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10153

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10163

S=sparameters(S_Parameters,f,zref);

10154

S=sparameters(S_Parameters,f,zref);

10164

10155

10165

function S =s_for_c4(zref,f,cpad)

10156

function S =s_for_c4(zref,f,cpad)

10166

10157

10167

S2 = s_for_c2(zref,f,cpad);

10158

S2 = s_for_c2(zref,f,cpad);

10168

S4P=s2_to_s4(S2.Parameters);

10159

S4P=s2_to_s4(S2.Parameters);

10169

S=sparameters(S4P,f,zref);

10160

S=sparameters(S4P,f,zref);

10170

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10161

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10171

10162

10172

10163

10173

10164

10174

10165

10175

%%

10166

%%

10176

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10167

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10177

% save commmend string

10168

% save commmend string

10178

% for saving from interactive queries

10169

% for saving from interactive queries

10179

10170

10180

10171

10181

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10172

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10182

for i=1:num_next+num_fext

10173

for i=1:num_next+num_fext

10183

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10174

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10184

end

10175

end

10185

cmd_str= [ cmd_str ')'];

10176

cmd_str= [ cmd_str ')'];

10186

10177

10187

10178

10188

%%%%% require the RF tool box

10179

%%%%% require the RF tool box

10189

%%

10180

%%

10190

function [ h ] = savefigs( param, OP )

10181

function [ h ] = savefigs( param, OP )

10191

10182

10192

%% find the figures

10183

%% find the figures

10193

hw = waitbar(0,'Saving figures...');

10184

hw = waitbar(0,'Saving figures...');

10194

h = findobj(0, 'Type', 'figure');

10185

h = findobj(0, 'Type', 'figure');

10195

for ii=1:length(h)

10186

for ii=1:length(h)

10196

10187

10197

figname= get(h(ii), 'Name'); % use the figure name as file name

10188

figname= get(h(ii), 'Name'); % use the figure name as file name

10198

if isempty(strfind(figname,param.base))

10189

if isempty(strfind(figname,param.base))

10199

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10190

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10200

end

10191

end

10201

if verLessThan('matlab', '8.4.0')

10192

if verLessThan('matlab', '8.4.0')

10202

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10193

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10203

else

10194

else

10204

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10195

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10205

end

10196

end

10206

figname = strrep(figname,':','-');

10197

figname = strrep(figname,':','-');

10207

figname = strrep(figname,' ','_');

10198

figname = strrep(figname,' ','_');

10208

if OP.SAVE_FIGURES==1

10199

if OP.SAVE_FIGURES==1

10209

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10200

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10210

end

10201

end

10211

%% get x y data

10202

%% get x y data

10212

if OP.SAVE_FIGURE_to_CSV==1

10203

if OP.SAVE_FIGURE_to_CSV==1

10213

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10204

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10214

M=[]; %ncol=1;

10205

M=[]; %ncol=1;

10215

for nk=1:length(h_L)

10206

for nk=1:length(h_L)

10216

% get x and data for a line.

10207

% get x and data for a line.

10217

x_data=get(h_L(nk),'xdata')';

10208

x_data=get(h_L(nk),'xdata')';

10218

y_data=get(h_L(nk),'ydata')';

10209

y_data=get(h_L(nk),'ydata')';

10219

% .........>> need to get data in the line structure (legend or label) for headers

10210

% .........>> need to get data in the line structure (legend or label) for headers

10220

M=[M; x_data; y_data]; %#ok<AGROW>

10211

M=[M; x_data; y_data]; %#ok<AGROW>

10221

end

10212

end

10222

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10213

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10223

% clear M y x header h_L

10214

% clear M y x header h_L

10224

end

10215

end

10225

waitbar(ii/length(h),hw)

10216

waitbar(ii/length(h),hw)

10226

10217

10227

end

10218

end

10228

10219

10229

close(hw)

10220

close(hw)

10230

10221

10231

%%

10222

%%

10232

function [ h ] = savefigs_png( param, OP )

10223

function [ h ] = savefigs_png( param, OP )

10233

10224

10234

%% find the figures

10225

%% find the figures

10235

hw = waitbar(0,'Saving figures...');

10226

hw = waitbar(0,'Saving figures...');

10236

h = findobj(0, 'Type', 'figure');

10227

h = findobj(0, 'Type', 'figure');

10237

for ii=1:length(h)

10228

for ii=1:length(h)

10238

10229

10239

figname= get(h(ii), 'Name'); % use the figure name as file name

10230

figname= get(h(ii), 'Name'); % use the figure name as file name

10240

if isempty(strfind(figname,param.base))

10231

if isempty(strfind(figname,param.base))

10241

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10232

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10242

end

10233

end

10243

if verLessThan('matlab', '8.4.0')

10234

if verLessThan('matlab', '8.4.0')

10244

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10235

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10245

else

10236

else

10246

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10237

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10247

end

10238

end

10248

figname = strrep(figname,':','-');

10239

figname = strrep(figname,':','-');

10249

figname = strrep(figname,' ','_');

10240

figname = strrep(figname,' ','_');

10250

if OP.SAVE_FIGURES==1

10241

if OP.SAVE_FIGURES==1

10251

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10242

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10252

end

10243

end

10253

%% get x y data

10244

%% get x y data

10254

if OP.SAVE_FIGURE_to_CSV==1

10245

if OP.SAVE_FIGURE_to_CSV==1

10255

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10246

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10256

M=[]; %ncol=1;

10247

M=[]; %ncol=1;

10257

for nk=1:length(h_L)

10248

for nk=1:length(h_L)

10258

% get x and data for a line.

10249

% get x and data for a line.

10259

x_data=get(h_L(nk),'xdata')';

10250

x_data=get(h_L(nk),'xdata')';

10260

y_data=get(h_L(nk),'ydata')';

10251

y_data=get(h_L(nk),'ydata')';

10261

% .........>> need to get data in the line structure (legend or label) for headers

10252

% .........>> need to get data in the line structure (legend or label) for headers

10262

M=[M; x_data; y_data]; %#ok<AGROW>

10253

M=[M; x_data; y_data]; %#ok<AGROW>

10263

end

10254

end

10264

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10255

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10265

% clear M y x header h_L

10256

% clear M y x header h_L

10266

end

10257

end

10267

waitbar(ii/length(h),hw)

10258

waitbar(ii/length(h),hw)

10268

10259

10269

end

10260

end

10270

10261

10271

close(hw)

10262

close(hw)

10272

10263

10273

%%

10264

%%

10274

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10265

function [pdf_out, cdf_out, scale_factor] = scaleCDF(pdf,delta_com,DER0,A_s)

10275

% scale CDF at DER0 to delta_com

10266

% scale CDF at DER0 to delta_com

10276

pdf_out=pdf;

10267

pdf_out=pdf;

10277

P=cumsum(pdf.y);

10268

P=cumsum(pdf.y);

10278

ider0=find(P>=DER0,1,'first');

10269

ider0=find(P>=DER0,1,'first');

10279

anias=pdf.x(ider0)/A_s; % ani/as

10270

anias=pdf.x(ider0)/A_s; % ani/as

10280

new_db = 20*log10(-1/anias)-delta_com;

10271

new_db = 20*log10(-1/anias)-delta_com;

10281

new_value = -1*1/10^(new_db/20);

10272

new_value = -1*1/10^(new_db/20);

10282

scale_factor=1/10^(-delta_com/20);

10273

scale_factor=1/10^(-delta_com/20);

10283

pdf_out=scalePDF(pdf,scale_factor);

10274

pdf_out=scalePDF(pdf,scale_factor);

10284

cdf_out=cumsum(pdf_out.y);

10275

cdf_out=cumsum(pdf_out.y);

10285

function pdf_out = scalePDF(pdf,scale_factor)

10276

function pdf_out = scalePDF(pdf,scale_factor)

10286

pdf_out=pdf;

10277

pdf_out=pdf;

10287

pdf_out.Min=floor(pdf.Min*scale_factor);

10278

pdf_out.Min=floor(pdf.Min*scale_factor);

10288

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10279

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10289

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10280

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10290

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10281

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10291

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10282

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10292

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10283

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10293

function t_params = stot(s_params)

10284

function t_params = stot(s_params)

10294

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10285

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10295

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10286

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10296

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10287

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10297

delta = (s11.*s22-s12.*s21);

10288

delta = (s11.*s22-s12.*s21);

10298

s21(s21==0)=eps;

10289

s21(s21==0)=eps;

10299

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10290

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10300

10291

10301

function csv_string = str2csv(c)

10292

function csv_string = str2csv(c)

10302

% convert a cell array of strings to a csv string

10293

% convert a cell array of strings to a csv string

10303

cell_tmp = cell(2, length(c));

10294

cell_tmp = cell(2, length(c));

10304

cell_tmp(1,:)=c;

10295

cell_tmp(1,:)=c;

10305

cell_tmp(2,:) = {','};

10296

cell_tmp(2,:) = {','};

10306

cell_tmp{2,end} = '';

10297

cell_tmp{2,end} = '';

10307

csv_string=strcat(cell_tmp{:});

10298

csv_string=strcat(cell_tmp{:});

10308

10299

10309

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10300

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10310

f_GHz=f/1e9;

10301

f_GHz=f/1e9;

10311

%% Equation 93A-10 %%

10302

%% Equation 93A-10 %%

10312

gamma_1 = gamma_coeff(2)*(1+1i);

10303

gamma_1 = gamma_coeff(2)*(1+1i);

10313

%% Equation 93A-11 %%

10304

%% Equation 93A-11 %%

10314

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10305

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10315

%% Equation 93A-9 %%

10306

%% Equation 93A-9 %%

10316

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10307

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10317

gamma(f_GHz==0) = gamma_coeff(1);

10308

gamma(f_GHz==0) = gamma_coeff(1);

10318

10309

10319

%% Equation 93A-12 %%

10310

%% Equation 93A-12 %%

10320

if d==0

10311

if d==0

10321

%force matched impedance if length is 0

10312

%force matched impedance if length is 0

10322

%otherwise divide by zero can occur if Z_c=0

10313

%otherwise divide by zero can occur if Z_c=0

10323

rho_rl=0;

10314

rho_rl=0;

10324

else

10315

else

10325

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10316

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10326

end

10317

end

10327

10318

10328

exp_gamma_d = exp(-d*gamma);

10319

exp_gamma_d = exp(-d*gamma);

10329

%% Equations 93A-13 and 93A-14 %%

10320

%% Equations 93A-13 and 93A-14 %%

10330

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10321

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10331

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10322

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10332

s12 = s21;

10323

s12 = s21;

10333

s22 = s11;

10324

s22 = s11;

10334

10325

10335

function s_params = ttos(t_params)

10326

function s_params = ttos(t_params)

10336

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10327

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10337

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10328

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10338

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10329

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10339

delta = t11.*t22-t21.*t12;

10330

delta = t11.*t22-t21.*t12;

10340

t11(t11==0)=eps;

10331

t11(t11==0)=eps;

10341

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10332

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10342

10333

10343

function [out_var,varg_out]=varargin_extractor(varargin)

10334

function [out_var,varg_out]=varargin_extractor(varargin)

10344

10335

10345

if isempty(varargin)

10336

if isempty(varargin)

10346

out_var=[];

10337

out_var=[];

10347

varg_out={};

10338

varg_out={};

10348

else

10339

else

10349

out_var=varargin{1};

10340

out_var=varargin{1};

10350

varg_out=varargin;

10341

varg_out=varargin;

10351

varg_out(1)=[];

10342

varg_out(1)=[];

10352

end

10343

end

10353

10344

10354

10345

10355

function results= vma(PR, M)

10346

function results= vma(PR, M)

10356

% PR=sbr.Data;

10347

% PR=sbr.Data;

10357

% M=32;

10348

% M=32;

10358

% PR is the pulse response

10349

% PR is the pulse response

10359

% M is samples per UI

10350

% M is samples per UI

10360

[ seq, syms, syms_nrz ] = PRBS13Q( );

10351

[ seq, syms, syms_nrz ] = PRBS13Q( );

10361

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10352

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10362

symbols=seq;

10353

symbols=seq;

10363

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10354

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10364

% start end symbols index for 7 3's and 6 0's

10355

% start end symbols index for 7 3's and 6 0's

10365

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10356

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10366

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10357

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10367

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10358

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10368

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10359

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10369

% superposition code

10360

% superposition code

10370

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10361

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10371

Bit_stream_response=filter(PR,1, shifting_vector);

10362

Bit_stream_response=filter(PR,1, shifting_vector);

10372

% find center of 3's and 0's

10363

% find center of 3's and 0's

10373

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10364

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10374

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10365

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10375

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10366

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10376

% hold on

10367

% hold on

10377

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10368

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10378

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10369

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10379

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10370

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10380

VMA= P_3 - P_0;

10371

VMA= P_3 - P_0;

10381

results.P_3=P_3;

10372

results.P_3=P_3;

10382

results.P_0=P_0;

10373

results.P_0=P_0;

10383

results.VMA=VMA;

10374

results.VMA=VMA;

10384

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10375

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10385

10376

10386

%slope of the 2 sample points around vref crossing

10377

%slope of the 2 sample points around vref crossing

10387

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10378

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10388

%x-intercept for the line

10379

%x-intercept for the line

10389

b1=eye_contour(x_in,1)-m1*x_in;

10380

b1=eye_contour(x_in,1)-m1*x_in;

10390

% drawing a horizontal line through vref so slope = 0

10381

% drawing a horizontal line through vref so slope = 0

10391

m2=0;

10382

m2=0;

10392

%special case for horizontal line, b=y

10383

%special case for horizontal line, b=y

10393

b2=vref;

10384

b2=vref;

10394

%the x-value of line intersection = (b2-b1)/(m1-m2)

10385

%the x-value of line intersection = (b2-b1)/(m1-m2)

10395

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10386

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10396

%And usually vref is 0, so it further reduces to -b1/m1

10387

%And usually vref is 0, so it further reduces to -b1/m1

10397

line_intersection=(b2-b1)/(m1-m2);

10388

line_intersection=(b2-b1)/(m1-m2);

10398

10389

10399

10390

10400

10391

10401

10392

10402

10393

10403

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10394

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10404

% helper function to read parameter values from XLS file. Uses names to find values.

10395

% helper function to read parameter values from XLS file. Uses names to find values.

10405

if nargin<3, eval_if_string=0; end

10396

if nargin<3, eval_if_string=0; end

10406

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10397

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10407

if numel(row)*numel(col)==0

10398

if numel(row)*numel(col)==0

10408

if nargin<4

10399

if nargin<4

10409

missingParameter(param_name);

10400

missingParameter(param_name);

10410

else

10401

else

10411

p = default_value;

10402

p = default_value;

10412

end

10403

end

10413

elseif numel(row)*numel(col)>1

10404

elseif numel(row)*numel(col)>1

10414

% if there are several occurrences, use the first, but warn

10405

% if there are several occurrences, use the first, but warn

10415

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10406

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10416

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10407

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10417

error('COM:XLS_parameter:MultipleOccurrence', ...

10408

error('COM:XLS_parameter:MultipleOccurrence', ...

10418

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10409

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10419

p=param_sheet{row(1), col(1)+1};

10410

p=param_sheet{row(1), col(1)+1};

10420

else

10411

else

10421

p=param_sheet{row, col+1};

10412

p=param_sheet{row, col+1};

10422

end

10413

end

10423

if ischar(p) && eval_if_string

10414

if ischar(p) && eval_if_string

10424

p=eval(p);

10415

p=eval(p);

10425

end

10416

end

10426

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10417

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10427

if OP.SAVE_KEYWORD_FILE

10418

if OP.SAVE_KEYWORD_FILE

10428

10419

10429

if nargin<3 || ~exist('default_value','var')

10420

if nargin<3 || ~exist('default_value','var')

10430

default_value=p;

10421

default_value=p;

10431

end

10422

end

10432

if isempty(default_value)

10423

if isempty(default_value)

10433

default_value='-';

10424

default_value='-';

10434

end

10425

end

10435

%%

10426

%%

10436

% Get call-stack info:

10427

% Get call-stack info:

10437

stDebug = dbstack;

10428

stDebug = dbstack;

10438

callerFileName = stDebug(2).file;

10429

callerFileName = stDebug(2).file;

10439

callerLineNumber = stDebug(2).line;

10430

callerLineNumber = stDebug(2).line;

10440

% Open caller file:

10431

% Open caller file:

10441

fCaller = fopen(callerFileName);

10432

fCaller = fopen(callerFileName);

10442

% Iterate through lines to get to desired line number:

10433

% Iterate through lines to get to desired line number:

10443

for iLine = 1 : callerLineNumber

10434

for iLine = 1 : callerLineNumber

10444

% Read current line of text:

10435

% Read current line of text:

10445

currLine = fgetl(fCaller);

10436

currLine = fgetl(fCaller);

10446

end

10437

end

10447

% (currLine) now reflects calling desired code: display this code:

10438

% (currLine) now reflects calling desired code: display this code:

10448

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10439

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10449

% Close caller file:

10440

% Close caller file:

10450

left_side=currLine(1:strfind(currLine,'=')-1);

10441

left_side=currLine(1:strfind(currLine,'=')-1);

10451

cmt_side=currLine(strfind(currLine,'%')+1:end);

10442

cmt_side=currLine(strfind(currLine,'%')+1:end);

10452

if isempty(cmt_side), cmt_side=' ';end

10443

if isempty(cmt_side), cmt_side=' ';end

10453

fclose(fCaller);

10444

fclose(fCaller);

10454

10445

10455

if ~ischar(default_value)

10446

if ~ischar(default_value)

10456

default_str=sprintf('%g ',default_value);

10447

default_str=sprintf('%g ',default_value);

10457

else

10448

else

10458

default_str=default_value;

10449

default_str=default_value;

10459

end

10450

end

10460

if ~isfile('keyworklog.mat')

10451

if ~isfile('keyworklog.mat')

10461

save_p=param_name;

10452

save_p=param_name;

10462

save_d=default_str;

10453

save_d=default_str;

10463

save_r=left_side;

10454

save_r=left_side;

10464

save_c=cmt_side;

10455

save_c=cmt_side;

10465

param_name = {'keyword'};

10456

param_name = {'keyword'};

10466

default_str = {'default'};

10457

default_str = {'default'};

10467

left_side={'matlab variable'};

10458

left_side={'matlab variable'};

10468

cmt_side={'info'};

10459

cmt_side={'info'};

10469

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10460

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10470

param_name=save_p;

10461

param_name=save_p;

10471

default_str=save_d;

10462

default_str=save_d;

10472

left_side=save_r;

10463

left_side=save_r;

10473

cmt_side=save_c;

10464

cmt_side=save_c;

10474

data=load('keyworklog.mat');

10465

data=load('keyworklog.mat');

10475

else

10466

else

10476

load('keyworklog.mat');

10467

load('keyworklog.mat');

10477

end

10468

end

10478

data.left_side = [ data.left_side; left_side];

10469

data.left_side = [ data.left_side; left_side];

10479

data.param_name = [data.param_name; param_name];

10470

data.param_name = [data.param_name; param_name];

10480

data.default_str = [data.default_str; default_str ];

10471

data.default_str = [data.default_str; default_str ];

10481

data.cmt_side = [ data.cmt_side; cmt_side];

10472

data.cmt_side = [ data.cmt_side; cmt_side];

10482

if length(data.default_str)~=length(data.default_str)

10473

if length(data.default_str)~=length(data.default_str)

10483

a=1;

10474

a=1;

10484

end

10475

end

10485

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10476

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10486

save('keyworklog.mat','data');

10477

save('keyworklog.mat','data');

10487

writetable(T,[ 'keywords_' date '.csv' ]);

10478

writetable(T,[ 'keywords_' date '.csv' ]);

10488

end

10479

end

10489

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10480

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10490

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10481

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10491

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10482

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10492

10483

10493

found=1;

10484

found=1;

10494

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10485

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10495

if numel(row)*numel(col)==0

10486

if numel(row)*numel(col)==0

10496

p = 0;

10487

p = 0;

10497

found=0;

10488

found=0;

10498

elseif numel(row)*numel(col)>1

10489

elseif numel(row)*numel(col)>1

10499

% if there are several occurrences, use the first, but warn

10490

% if there are several occurrences, use the first, but warn

10500

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10491

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10501

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10492

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10502

error('COM:XLS_parameter:MultipleOccurrence', ...

10493

error('COM:XLS_parameter:MultipleOccurrence', ...

10503

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10494

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10504

p=param_sheet{row(1), col(1)+1};

10495

p=param_sheet{row(1), col(1)+1};

10505

else

10496

else

10506

p=param_sheet{row, col+1};

10497

p=param_sheet{row, col+1};

10507

end

10498

end

10508

if ischar(p)

10499

if ischar(p)

10509

p=eval(p);

10500

p=eval(p);

10510

end

10501

end

10511

function zzz_list_of_changes

10502

function zzz_list_of_changes

10512

% structures:

10503

% structures:

10513

% chdata(i)

10504

% chdata(i)

10514

% i= 1 --> THRU index

10505

% i= 1 --> THRU index

10515

% i= 2, num_fext+1 --> FEXT channel index

10506

% i= 2, num_fext+1 --> FEXT channel index

10516

% i= num_fext+2, num_next+num_fext+1

10507

% i= num_fext+2, num_next+num_fext+1

10517

% base: name of THRU file

10508

% base: name of THRU file

10518

% A: amplitude

10509

% A: amplitude

10519

% type: 'THRU', 'NEXT', or 'FEXT'

10510

% type: 'THRU', 'NEXT', or 'FEXT'

10520

% ftr: Rise time frequency

10511

% ftr: Rise time frequency

10521

% fmaxi: max number of frequency points

10512

% fmaxi: max number of frequency points

10522

% faxis: frequency array [Hz]

10513

% faxis: frequency array [Hz]

10523

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10514

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10524

% sdd22: differential RL

10515

% sdd22: differential RL

10525

% sdd11: differential RL

10516

% sdd11: differential RL

10526

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10517

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10527

% sdd21f: raw differential IL not filtered use for FD plots

10518

% sdd21f: raw differential IL not filtered use for FD plots

10528

% added output_args.peak_uneq_pulse_mV

10519

% added output_args.peak_uneq_pulse_mV

10529

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10520

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10530

% added: tap c(-2) c(2) and c(3)

10521

% added: tap c(-2) c(2) and c(3)

10531

% added: g_DC_HP and f_HP_PZ

10522

% added: g_DC_HP and f_HP_PZ

10532

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10523

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10533

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10524

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10534

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10525

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10535

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10526

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10536

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10527

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10537

% fixed INCLUDE_CTLE=0 to really remove from computation

10528

% fixed INCLUDE_CTLE=0 to really remove from computation

10538

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10529

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10539

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10530

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10540

% r162 tx and rx package impedance {Zc)

10531

% r162 tx and rx package impedance {Zc)

10541

% r162a Gaussian equation corrected

10532

% r162a Gaussian equation corrected

10542

% r163 cast snr_tx with package test case

10533

% r163 cast snr_tx with package test case

10543

% r164 fix pdf for very low noise and lo pass filter enhancements

10534

% r164 fix pdf for very low noise and lo pass filter enhancements

10544

% r164 add zero gain at nqyist CTLE as in CL12e

10535

% r164 add zero gain at nqyist CTLE as in CL12e

10545

% r165 add simpler congfig command called FORCE_TR (force risetime)

10536

% r165 add simpler congfig command called FORCE_TR (force risetime)

10546

% r200 cm3 and cm4 added cp3 removed

10537

% r200 cm3 and cm4 added cp3 removed

10547

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10538

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10548

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10539

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10549

% r200 improved phase interpolation for return loss time conversion

10540

% r200 improved phase interpolation for return loss time conversion

10550

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10541

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10551

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10542

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10552

% r200c missed on fix for interpolation

10543

% r200c missed on fix for interpolation

10553

% r210 new ERL with time gating function

10544

% r210 new ERL with time gating function

10554

% r224 update ERL with from D3.1

10545

% r224 update ERL with from D3.1

10555

% r226 fix s2p reading problem

10546

% r226 fix s2p reading problem

10556

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10547

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10557

% Fix Rx calibration issue

10548

% Fix Rx calibration issue

10558

% added ERL limit and Nd

10549

% added ERL limit and Nd

10559

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10550

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10560

% INC_PACKAGE=0 not fully supported message

10551

% INC_PACKAGE=0 not fully supported message

10561

% if N=0 use TDR_duration

10552

% if N=0 use TDR_duration

10562

% red display text for fail ERL and COM

10553

% red display text for fail ERL and COM

10563

% r228 fixed ERL pass fail report, default Grr_limit to 1

10554

% r228 fixed ERL pass fail report, default Grr_limit to 1

10564

% r230 add rx ffe

10555

% r230 add rx ffe

10565

% r231 change crosstalk noise to icn like to speed things up

10556

% r231 change crosstalk noise to icn like to speed things up

10566

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10557

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10567

% 1e-5mof-

10558

% 1e-5mof-

10568

% r232 fix default for Rx eq so old spead sheets work

10559

% r232 fix default for Rx eq so old spead sheets work

10569

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10560

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10570

% r235 adding dfe quantization changed to normalized DFE taps reported

10561

% r235 adding dfe quantization changed to normalized DFE taps reported

10571

% r236 adding ffe gain loop and resample after RxFFE

10562

% r236 adding ffe gain loop and resample after RxFFE

10572

% r240 added output for C2M and setting defaults for some FFE eq

10563

% r240 added output for C2M and setting defaults for some FFE eq

10573

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10564

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10574

% r250 adding more complex package

10565

% r250 adding more complex package

10575

% r251 post cursor fix for DFE in force() and ffe backoff

10566

% r251 post cursor fix for DFE in force() and ffe backoff

10576

% r251 remove TDR threshold noise filter

10567

% r251 remove TDR threshold noise filter

10577

% r252 add rx FFE filter to receiver noise filter

10568

% r252 add rx FFE filter to receiver noise filter

10578

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10569

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10579

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10570

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10580

% r254 precursor check fix in optimize_fom % mod fix in force

10571

% r254 precursor check fix in optimize_fom % mod fix in force

10581

% r254 help to align columns in csv file

10572

% r254 help to align columns in csv file

10582

% r254 accept syntax for 2 tline flex package model

10573

% r254 accept syntax for 2 tline flex package model

10583

% r256 speed up optimize FOM

10574

% r256 speed up optimize FOM

10584

% r256 fix problem reading in config file from q/a

10575

% r256 fix problem reading in config file from q/a

10585

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10576

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10586

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10577

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10587

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10578

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10588

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10579

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10589

% r258 CDR switch 'MM' or 'mod-MM'

10580

% r258 CDR switch 'MM' or 'mod-MM'

10590

% r258 correction for asymentirc tx/Rx packages

10581

% r258 correction for asymentirc tx/Rx packages

10591

% r258 revamped display results display window

10582

% r258 revamped display results display window

10592

% r259 fix problem if Min_VEO is set in spreadsheet.

10583

% r259 fix problem if Min_VEO is set in spreadsheet.

10593

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10584

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10594

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10585

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10595

% r259 putting COM_db and IL last in output to terminal

10586

% r259 putting COM_db and IL last in output to terminal

10596

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10587

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10597

% r259 use N_bx for ERL rather than Nb (ndfe))

10588

% r259 use N_bx for ERL rather than Nb (ndfe))

10598

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10589

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10599

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10590

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10600

% r260 used eta_0 PSD equation for sigma_n

10591

% r260 used eta_0 PSD equation for sigma_n

10601

% r260 fix IL graph legend to w/pkg and Tr

10592

% r260 fix IL graph legend to w/pkg and Tr

10602

% r260 define tfx for each port

10593

% r260 define tfx for each port

10603

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10594

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10604

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10595

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10605

% r262 reset on exit default text interpreter to tex

10596

% r262 reset on exit default text interpreter to tex

10606

% r262 localize run timer (John Buck 1/17/19)

10597

% r262 localize run timer (John Buck 1/17/19)

10607

% r262 set db as internal function in force to avoid tool box

10598

% r262 set db as internal function in force to avoid tool box

10608

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10599

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10609

% r263 added to output_args RL structure and report "struct" in csv file

10600

% r263 added to output_args RL structure and report "struct" in csv file

10610

% r264 added EW estimate

10601

% r264 added EW estimate

10611

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10602

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10612

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10603

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10613

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10604

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10614

% r269 changed param.N_bmax to param.N_f

10605

% r269 changed param.N_bmax to param.N_f

10615

% r270 implement JingBo Li's and Howard Heck's floating tap method

10606

% r270 implement JingBo Li's and Howard Heck's floating tap method

10616

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10607

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10617

% r270 added c_0 and c_1 for CA in add_brd

10608

% r270 added c_0 and c_1 for CA in add_brd

10618

% r272 fixed version syntax problem in output_args RL report

10609

% r272 fixed version syntax problem in output_args RL report

10619

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10610

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10620

% r272 removed eye width report if doing a Rx calibration

10611

% r272 removed eye width report if doing a Rx calibration

10621

% r273 better alignment and control for ICN reporting

10612

% r273 better alignment and control for ICN reporting

10622

% r273 fixed PSXTK graph

10613

% r273 fixed PSXTK graph

10623

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10614

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10624

% 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)

10615

% 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)

10625

% 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

10616

% 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

10626

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10617

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10627

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10618

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10628

% r276 C_1 was instantiated as C_0. This was fixed

10619

% r276 C_1 was instantiated as C_0. This was fixed

10629

% r276 fixed rounding problem in reporting of loss at f_nq

10620

% r276 fixed rounding problem in reporting of loss at f_nq

10630

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10621

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10631

% r277 added nv for deterining steady state voltage for fitting compatibility

10622

% r277 added nv for deterining steady state voltage for fitting compatibility

10632

% r278 added b_min to support asymmetric bmax

10623

% r278 added b_min to support asymmetric bmax

10633

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10624

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10634

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10625

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10635

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10626

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10636

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10627

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10637

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10628

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10638

% 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

10629

% 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

10639

% r292 H_t implemented in s21_pkg

10630

% r292 H_t implemented in s21_pkg

10640

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10631

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10641

% r292 add GDC_MIN to optimize_FOM

10632

% r292 add GDC_MIN to optimize_FOM

10642

% r293 fix if ndfe-0 and ERL only and s2p issue

10633

% r293 fix if ndfe-0 and ERL only and s2p issue

10643

% r293a investigate the Tukey filtering

10634

% r293a investigate the Tukey filtering

10644

% r293a if fix if bmin is missing

10635

% r293a if fix if bmin is missing

10645

% r294 fix problems reading s2p files for ERL computation

10636

% r294 fix problems reading s2p files for ERL computation

10646

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10637

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10647

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10638

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10648

% r294 add gdc and gdc2 range limitations

10639

% r294 add gdc and gdc2 range limitations

10649

% r295 add VEC Pass threshold

10640

% r295 add VEC Pass threshold

10650

% r295 removed close force all. Tagged all figures with "COM"

10641

% r295 removed close force all. Tagged all figures with "COM"

10651

% r295 consolidated print in new function "end_display_control"

10642

% r295 consolidated print in new function "end_display_control"

10652

% r295 report pre/pmax for Txffe

10643

% r295 report pre/pmax for Txffe

10653

% r295 speed up test cases by not re-reading in s4p files

10644

% r295 speed up test cases by not re-reading in s4p files

10654

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10645

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10655

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10646

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10656

% r310 refine VEC and EH for C2M from Adam Gregory in

10647

% r310 refine VEC and EH for C2M from Adam Gregory in

10657

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10648

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10658

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10649

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10659

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10650

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10660

% r311 added RILN

10651

% r311 added RILN

10661

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10652

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10662

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10653

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10663

% r316 remove DC computation for RX Calibration loops

10654

% r316 remove DC computation for RX Calibration loops

10664

% r317 for SAVE_TD to include EQ and unEQ FIR

10655

% r317 for SAVE_TD to include EQ and unEQ FIR

10665

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10656

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10666

% 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

10657

% 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

10667

% r320 fixed RX_CALIBRATION which was broken in r310

10658

% r320 fixed RX_CALIBRATION which was broken in r310

10668

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10659

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10669

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10660

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10670

% r320 removed external feature and replace with TDMODE

10661

% r320 removed external feature and replace with TDMODE

10671

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10662

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10672

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10663

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10673

% r335 fixed typo in when processing the bessel thompson filter option

10664

% r335 fixed typo in when processing the bessel thompson filter option

10674

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10665

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10675

% r335 compute and report CD_CM_RMS

10666

% r335 compute and report CD_CM_RMS

10676

% r335 fixed where output_arg is save i.e. move to end

10667

% r335 fixed where output_arg is save i.e. move to end

10677

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10668

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10678

% r335 change raw IL plot to not include boards

10669

% r335 change raw IL plot to not include boards

10679

% r335 set T_0 to zero if not C2M

10670

% r335 set T_0 to zero if not C2M

10680

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10671

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10681

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10672

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10682

% r335 TD_RILN changes from Hansel Dsilva

10673

% r335 TD_RILN changes from Hansel Dsilva

10683

% r335 Fixed sigma_N for RxFFE

10674

% r335 Fixed sigma_N for RxFFE

10684

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10675

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10685

% r335 added c(2) and C(3) back to read_ParamConfigFile

10676

% r335 added c(2) and C(3) back to read_ParamConfigFile

10686

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10677

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10687

% r335 corrected GDC_MIN per 0.3ck D2.3

10678

% r335 corrected GDC_MIN per 0.3ck D2.3

10688

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10679

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10689

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10680

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10690

% r370 speed up

10681

% r370 speed up

10691

% r370 fix for floating tap missing locations

10682

% r370 fix for floating tap missing locations

10692

% r370 variable Tx FFE taps

10683

% r370 variable Tx FFE taps

10693

% r370 package die load with ladder circuit

10684

% r370 package die load with ladder circuit

10694

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10685

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10695

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10686

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10696

% r380 added capabablity to enable a raised cosine Rx filter0

10687

% r380 added capabablity to enable a raised cosine Rx filter0

10697

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10688

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10698

% r380 added plot for VTF

10689

% r380 added plot for VTF

10699

% r385 added capability for additional Tx FFE per package

10690

% r385 added capability for additional Tx FFE per package

10700

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10691

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10701

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10692

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10702

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10693

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10703

% r389 Improvement by A. Ran for reporting loss at Nq

10694

% r389 Improvement by A. Ran for reporting loss at Nq

10704

% r389 Fixed typo: changed VIM to VMP

10695

% r389 Fixed typo: changed VIM to VMP

10705

% r400 fixed PR with zero pad extension

10696

% r400 fixed PR with zero pad extension

10706

% r400 keyword MLSE and SNRADJ_EQUA for future work

10697

% r400 keyword MLSE and SNRADJ_EQUA for future work

10707

% r400 replaced function db with instances of 20*log10(abs(...))

10698

% r400 replaced function db with instances of 20*log10(abs(...))

10708

% r410 widen voltage distriution for normal_dist doubled max Q

10699

% r410 widen voltage distriution for normal_dist doubled max Q

10709

% r410 improve reading in of config files

10700

% r410 improve reading in of config files

10710

% r410 renormalize s-parameter if not 50 ohm ref

10701

% r410 renormalize s-parameter if not 50 ohm ref

10711

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10702

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10712

% r410 remove RL from output_args bc not need and too much storage allocation

10703

% r410 remove RL from output_args bc not need and too much storage allocation

10713

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10704

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10714

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10705

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10715

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10706

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10716

% r420 updade force to account for pulse responces with short delays in force

10707

% r420 updade force to account for pulse responces with short delays in force

10717

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10708

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10718

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10709

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10719

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10710

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10720

% r420 Wiener-Kofp MMSE optimization for RxFFE

10711

% r420 Wiener-Kofp MMSE optimization for RxFFE

10721

% r430 first pass at healey_3dj_01_2401

10712

% r430 first pass at healey_3dj_01_2401

10722

% r430 RxFFE fixed taps

10713

% r430 RxFFE fixed taps

10723

% r440 RxffE fixed tap index corrections and floating taps

10714

% r440 RxffE fixed tap index corrections and floating taps

10724

% r440 first pass implemenation of MLSE U3

10715

% r440 first pass implemenation of MLSE U3

10725

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10716

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10726

% r450 incude Hisi in PSD in get_PSDs

10717

% r450 incude Hisi in PSD in get_PSDs

10727

% r460 is working out reporting bug from RxFFE and package A,B invocations

10718

% r460 is working out reporting bug from RxFFE and package A,B invocations

10728

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10719

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10729

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10720

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10730

% r470 beta1 added MLSE truncation inclusion using N_tc

10721

% r470 beta1 added MLSE truncation inclusion using N_tc

10731

% r470 beta1 add MLSE Q_budget_adj

10722

% r470 beta1 add MLSE Q_budget_adj

10732

% r470 added parameter defaults to support multiple packages

10723

% r470 added parameter defaults to support multiple packages

10733

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10724

% r470 beta2 added MLSD proposal from healey_3dj_01_2409

10734

% r470 remOved support for MLSE_Q

10725

% r470 remOved support for MLSE_Q

10735

% r480 beta1 added new keyword ENOB for quantization. if 0 or missing ignored

10726

% r480 beta1 added new keyword ENOB for quantization. if 0 or missing ignored

10736

% r480 beta1 added function adjust_Rx_noise_for_quantization

10727

% r480 beta1 added function adjust_Rx_noise_for_quantization

10737

% r480 beta2 fixed typo's and updated from shakiba_3dj_COM_02_241001 to shakiba_3dj_COM_01_241029

10728

% r480 beta1 corrected ICN

10738

10729