File Comparison Report

C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_460.m vs. C:\Users\richardm\OneDrive - Samtec\COM\COM\src\com_ieee8023_93a_450.m

richardm

01-Jul-2024

Files

Left FileRight File
File namecom_ieee8023_93a_460com_ieee8023_93a_450
File pathC:\Users\richardm\OneDrive - Samtec\COM\COM\srcC:\Users\richardm\OneDrive - Samtec\COM\COM\src
Last modified01-Jul-2024 09:38:0402-May-2024 14:31:33

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

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

451

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

453

OP.WO_TXFFE=0;

452

OP.WO_TXFFE=0;

454

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

453

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

455

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

454

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

456

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

455

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

457

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

456

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

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

457

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

459

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

458

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

460

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

459

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

461

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

460

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

462

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

461

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

463

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

462

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

464

end

463

end

465

%% Create ISI PDF & Individual Crosstalk PDFs

464

%% Create ISI PDF & Individual Crosstalk PDFs

466

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

465

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

467

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

466

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

468

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

467

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

469

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

468

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

470

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

469

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

471

for i=1:param.number_of_s4p_files

470

for i=1:param.number_of_s4p_files

472

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

471

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

473

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

472

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

474

473

475

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

474

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

476

else

475

else

477

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

476

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

478

end

477

end

479

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

478

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

480

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

479

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

481

subplot(2,1,2);

480

subplot(2,1,2);

482

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

481

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

483

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

482

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

484

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

483

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

485

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

484

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

486

hold on; title('PDF')

485

hold on; title('PDF')

487

recolor_plots(gca);

486

recolor_plots(gca);

488

end

487

end

489

488

490

chdata(i).pdfr=pdf;

489

chdata(i).pdfr=pdf;

491

% reporting

490

% reporting

492

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

491

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

493

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

492

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

494

493

495

end

494

end

496

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

495

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

497

496

498

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

499

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

498

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

500

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

499

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

501

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

500

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

502

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

501

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

503

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

504

combined_interference_and_noise_pdf=PDF;

503

combined_interference_and_noise_pdf=PDF;

505

combined_interference_and_noise_cdf=CDF;

504

combined_interference_and_noise_cdf=CDF;

506

505

507

506

508

%% Calculate COM and other associated outputs

507

%% Calculate COM and other associated outputs

509

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

508

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

510

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

509

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

511

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

510

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

512

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

511

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

513

% 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

514

% that satisfies the relationship P(y0) = DER_0

513

% that satisfies the relationship P(y0) = DER_0

515

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

516

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

517

516

518

% begin yasuo patch 3/18/2019

517

% begin yasuo patch 3/18/2019

519

% estimate DER at threshold COM

518

% estimate DER at threshold COM

520

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

521

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

520

threshold_DER=combined_interference_and_noise_cdf(threshold_ix);

522

threshold_DER_max = max(threshold_DER_max, threshold_DER);

521

threshold_DER_max = max(threshold_DER_max, threshold_DER);

523

% end yasuo patch

522

% end yasuo patch

524

523

525

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

524

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

526

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

527

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

526

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

528

if OP.DISPLAY_WINDOW && OP.DEBUG

527

if OP.DISPLAY_WINDOW && OP.DEBUG

529

figure_name = 'Eye at DER0 estimate';

528

figure_name = 'Eye at DER0 estimate';

530

fig=findobj('Name', figure_name);

529

fig=findobj('Name', figure_name);

531

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

530

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

532

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

531

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

533

movegui(fig,'southwest')

532

movegui(fig,'southwest')

534

plot(eye_contour)

533

plot(eye_contour)

535

xlabel('UI %')

534

xlabel('UI %')

536

ylabel('V')

535

ylabel('V')

537

end

536

end

538

537

539

else

538

else

540

EW_UI=0;

539

EW_UI=0;

541

eye_contour=[];

540

eye_contour=[];

542

end

541

end

543

if OP.MLSE==0

542

if OP.MLSE==0

544

if param.T_O ~=0

543

if param.T_O ~=0

545

eye_opening=EH_T_C2M-EH_B_C2M;

544

eye_opening=EH_T_C2M-EH_B_C2M;

546

A_ni=2*A_s-eye_opening;

545

A_ni=2*A_s-eye_opening;

547

%eq 124E-4

546

%eq 124E-4

548

vec_arg=2*A_s/eye_opening;

547

vec_arg=2*A_s/eye_opening;

549

if vec_arg<eps

548

if vec_arg<eps

550

vec_arg=eps;

549

vec_arg=eps;

551

end

550

end

552

VEC_dB = 20*log10(vec_arg);

551

VEC_dB = 20*log10(vec_arg);

553

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

552

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

554

VEO_mV=eye_opening*1000;

553

VEO_mV=eye_opening*1000;

555

min_COM = min(min_COM, COM);

554

min_COM = min(min_COM, COM);

556

min_VEO_mV = min(min_VEO_mV,VEO_mV);

555

min_VEO_mV = min(min_VEO_mV,VEO_mV);

557

max_VEC_dB = max(max_VEC_dB, VEC_dB);

556

max_VEC_dB = max(max_VEC_dB, VEC_dB);

558

else

557

else

559

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

558

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

560

vec_arg=(A_s-A_ni)/A_s;

559

vec_arg=(A_s-A_ni)/A_s;

561

if vec_arg<eps

560

if vec_arg<eps

562

vec_arg=eps;

561

vec_arg=eps;

563

end

562

end

564

VEC_dB = -20*log10(vec_arg);

563

VEC_dB = -20*log10(vec_arg);

565

COM=20*log10(A_s/A_ni);

564

COM=20*log10(A_s/A_ni);

566

min_COM = min(min_COM, COM);

565

min_COM = min(min_COM, COM);

567

min_VEO_mV = min(min_VEO_mV,VEO_mV);

566

min_VEO_mV = min(min_VEO_mV,VEO_mV);

568

max_VEC_dB = max(max_VEC_dB, VEC_dB);

567

max_VEC_dB = max(max_VEC_dB, VEC_dB);

569

end

568

end

570

MLSE_results=struct;

569

MLSE_results=struct;

+570

else % MLSE case added U3 option

571

if OP.MLSE==1

572

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

573

elseif OP.MLSE==2

574

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

575

elseif OP.MLSE==3

576

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

571

else

577

else

572

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

578

warning('unsuported MLSE option')

+579

end

573

if param.T_O ~=0

580

if param.T_O ~=0

574

eye_opening=EH_T_C2M-EH_B_C2M;

581

eye_opening=EH_T_C2M-EH_B_C2M;

575

A_ni=2*A_s-eye_opening;

582

A_ni=2*A_s-eye_opening;

576

%eq 124E-4

583

%eq 124E-4

577

vec_arg=2*A_s/eye_opening;

584

vec_arg=2*A_s/eye_opening;

578

if vec_arg<eps

585

if vec_arg<eps

579

vec_arg=eps;

586

vec_arg=eps;

580

end

587

end

581

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

588

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

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;

589

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

583

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

590

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

584

COM=MLSE_results.COM;

591

COM=MLSE_results.COM_CDF;

585

VEO_mV=eye_opening*1000;

592

VEO_mV=eye_opening*1000;

586

min_COM = min(min_COM, COM);

593

min_COM = min(min_COM, COM);

587

min_VEO_mV = min(min_VEO_mV,VEO_mV);

594

min_VEO_mV = min(min_VEO_mV,VEO_mV);

588

max_VEC_dB = max(max_VEC_dB, VEC_dB);

595

max_VEC_dB = max(max_VEC_dB, VEC_dB);

589

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

596

output_args.delta_COM=MLSE_results.delta_com_CDF;

590

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

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

597

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

593

COM_SNR_Struct.VEC_dB_orig=VEC_dB_orig;

594

COM_SNR_Struct.VEC_dB=VEC_dB;

595

else

598

else

596

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

599

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

597

vec_arg=(A_s-A_ni)/A_s;

600

vec_arg=(A_s-A_ni)/A_s;

598

if vec_arg<eps

601

if vec_arg<eps

599

vec_arg=eps;

602

vec_arg=eps;

600

end

603

end

601

VEC_dB_orig = -20*log10(vec_arg);

604

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;

605

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

603

COM_orig=20*log10(A_s/A_ni);

606

COM_orig=20*log10(A_s/A_ni);

604

COM=MLSE_results.COM;

607

COM=MLSE_results.COM_CDF;

605

min_COM = min(min_COM, COM);

608

min_COM = min(min_COM, COM);

606

min_VEO_mV = min(min_VEO_mV,VEO_mV);

609

min_VEO_mV = min(min_VEO_mV,VEO_mV);

607

max_VEC_dB = max(max_VEC_dB, VEC_dB);

610

max_VEC_dB = max(max_VEC_dB, VEC_dB);

608

COM_SNR_Struct.delta_COM=MLSE_results.delta_com;

611

output_args.delta_COM=MLSE_results.delta_com_CDF;

609

COM_SNR_Struct.DER_DFE=MLSE_results.DER_DFE;

610

COM_SNR_Struct.DER_MLSE=MLSE_results.DER_MLSE;

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

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

658

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

659

end

659

end

660

660

661

%% Msg management

661

%% Msg management

662

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

662

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

663

msg=[];

663

msg=[];

664

end

664

end

665

if OP.DEBUG

665

if OP.DEBUG

666

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

666

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

667

switch param.flex

667

switch param.flex

668

case 4

668

case 4

669

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

669

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

670

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

670

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

671

);

671

);

672

case 2

672

case 2

673

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

673

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

674

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

674

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

675

);

675

);

676

otherwise

676

otherwise

677

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

677

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

678

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

678

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

679

);

679

);

680

680

681

end

681

end

682

else

682

else

683

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

683

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

684

end

684

end

685

685

686

if OP.TDMODE

686

if OP.TDMODE

687

min_ERL=inf;

687

min_ERL=inf;

688

ERL=[inf inf];

688

ERL=[inf inf];

689

end

689

end

690

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

690

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

691

691

692

692

693

%% Output Args

693

%% Output Args

694

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

694

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

695

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

695

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

696

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

696

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

697

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

697

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

698

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

698

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

699

rt=toc(t0);

699

rt=toc(t0);

700

output_args.rtmin=rt/60;

700

output_args.rtmin=rt/60;

701

701

702

if OP.BREAD_CRUMBS

702

if OP.BREAD_CRUMBS

703

output_args.OP=OP;

703

output_args.OP=OP;

704

output_args.param=param;

704

output_args.param=param;

705

output_args.chdata=chdata;

705

output_args.chdata=chdata;

706

output_args.fom_result = fom_result;

706

output_args.fom_result = fom_result;

707

output_args.PDF=PDF; % for exploration

707

output_args.PDF=PDF; % for exploration

708

output_args.CDF=CDF; % for exploration

708

output_args.CDF=CDF; % for exploration

709

output_args.MLSE_results=MLSE_results;

709

output_args.MLSE_results=MLSE_results;

710

output_args.PSD_results=PSD_results;

710

output_args.PSD_results=PSD_results;

711

end

711

end

712

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

712

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

713

713

714

%% making csv file

714

%% making csv file

715

if OP.CSV_REPORT ==1

715

if OP.CSV_REPORT ==1

716

Write_CSV(output_args,CSV_FILE);

716

Write_CSV(output_args,CSV_FILE);

717

end

717

end

718

%% making mat file

718

%% making mat file

719

if(OP.DEBUG)

719

if(OP.DEBUG)

720

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

720

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

721

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

721

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

722

end

722

end

723

if 1

723

if 1

724

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

724

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

725

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

725

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

726

end

726

end

727

727

728

if nargout==0

728

if nargout==0

729

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

729

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

730

disp(output_args)

730

disp(output_args)

731

end

731

end

732

732

733

if OP.BREAD_CRUMBS

733

if OP.BREAD_CRUMBS

734

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

734

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

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

735

if ~isempty(OP.BREAD_CRUMBS_FIELDS)

736

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

736

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

737

try

737

try

738

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

738

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

739

catch

739

catch

740

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

740

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

741

end

741

end

742

end

742

end

743

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

743

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

744

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

744

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

745

end

745

end

746

746

747

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

747

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

748

end

748

end

749

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

749

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

750

%%

750

%%

751

751

752

if OP.RX_CALIBRATION ==1

752

if OP.RX_CALIBRATION ==1

753

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

753

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

754

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

754

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

755

end

755

end

756

DO_ONCE=false;

756

DO_ONCE=false;

757

end

757

end

758

758

759

%% Final cleanup

759

%% Final cleanup

760

if OP.DISPLAY_WINDOW

760

if OP.DISPLAY_WINDOW

761

savefigs(param, OP);

761

savefigs(param, OP);

762

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

762

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

763

end

763

end

764

764

765

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

765

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

766

if ~param.f_hp==0

766

if ~param.f_hp==0

767

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

767

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

768

if OP.DISPLAY_WINDOW

768

if OP.DISPLAY_WINDOW

769

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

769

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

770

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

770

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

771

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

771

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

772

end

772

end

773

else

773

else

774

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

774

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

775

if OP.DISPLAY_WINDOW

775

if OP.DISPLAY_WINDOW

776

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

776

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

777

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

777

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

778

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

778

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

779

end

779

end

780

end

780

end

781

end

781

end

782

782

783

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

783

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

784

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

784

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

785

disp(redo_cmd_str);

785

disp(redo_cmd_str);

786

if isdeployed

786

if isdeployed

787

if OP.exit_if_deployed

787

if OP.exit_if_deployed

788

quit

788

quit

789

end

789

end

790

end

790

end

791

%%

791

%%

792

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

792

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

793

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

793

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

794

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

794

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

795

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

795

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

796

796

797

FB=param.fb;

797

FB=param.fb;

798

FZ=param.CTLE_fz(fom_result.ctle);

798

FZ=param.CTLE_fz(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

799

FP1=param.CTLE_fp1(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

800

FP2=param.CTLE_fp2(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

801

GDC=param.ctle_gdc_values(fom_result.ctle);

802

if ~isempty(param.f_HP)

802

if ~isempty(param.f_HP)

803

FHP=param.f_HP(fom_result.best_G_high_pass);

803

FHP=param.f_HP(fom_result.best_G_high_pass);

804

end

804

end

805

if ~isempty(param.g_DC_HP_values)

805

if ~isempty(param.g_DC_HP_values)

806

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

806

GDCHP=param.g_DC_HP_values(fom_result.best_G_high_pass);

807

end

807

end

808

if ~isempty(param.f_HP_Z)

808

if ~isempty(param.f_HP_Z)

809

FHPZ=param.f_HP_Z(fom_result.ctle);

809

FHPZ=param.f_HP_Z(fom_result.ctle);

810

end

810

end

811

if ~isempty(param.f_HP_P)

811

if ~isempty(param.f_HP_P)

812

FHPP=param.f_HP_P(fom_result.ctle);

812

FHPP=param.f_HP_P(fom_result.ctle);

813

end

813

end

814

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

814

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

815

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

815

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

816

%length

816

%length

817

SBR_Len=length(fom_result.sbr);

817

SBR_Len=length(fom_result.sbr);

818

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

818

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

819

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

819

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

820

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

820

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

821

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

821

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

822

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

822

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

823

end

823

end

824

for i=1:param.number_of_s4p_files

824

for i=1:param.number_of_s4p_files

825

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

825

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

826

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

826

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

827

if OP.INCLUDE_CTLE==1

827

if OP.INCLUDE_CTLE==1

828

switch param.CTLE_type

828

switch param.CTLE_type

829

case 'CL93'

829

case 'CL93'

830

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

830

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

831

case 'CL120d'

831

case 'CL120d'

832

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

832

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

833

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

833

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

834

case 'CL120e' % z has been adjusted for gain

834

case 'CL120e' % z has been adjusted for gain

835

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

835

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

836

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

836

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

837

end

837

end

838

else

838

else

839

eq_ir=uneq_ir;

839

eq_ir=uneq_ir;

840

end

840

end

841

chdata(i).eq_imp_response=eq_ir;

841

chdata(i).eq_imp_response=eq_ir;

842

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

842

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

843

843

844

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

844

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

845

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

845

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

846

end

846

end

847

% chdata(i).ctle_imp_response

847

% chdata(i).ctle_imp_response

848

if OP.RxFFE

848

if OP.RxFFE

849

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

849

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

850

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

850

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

851

end

851

end

852

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

852

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

853

end

853

end

854

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

854

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

855

end

855

end

856

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

856

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

857

857

858

% display bathtub curves in one axis per test case.

858

% display bathtub curves in one axis per test case.

859

case_number=param.package_testcase_i;

859

case_number=param.package_testcase_i;

860

if ~OP.COM_CONTRIBUTION_CURVES

860

if ~OP.COM_CONTRIBUTION_CURVES

861

figure_name = 'Voltage bathtub curves';

861

figure_name = 'Voltage bathtub curves';

862

fig=findobj('Name', figure_name);

862

fig=findobj('Name', figure_name);

863

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

863

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

864

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

864

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

865

movegui(fig,'south')

865

movegui(fig,'south')

866

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

866

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

867

plot_bathtub_curves( hax ...

867

plot_bathtub_curves( hax ...

868

, COM_SNR_Struct.A_s ...

868

, COM_SNR_Struct.A_s ...

869

, Noise_Struct.sci_pdf ...

869

, Noise_Struct.sci_pdf ...

870

, Noise_Struct.cci_pdf ...

870

, Noise_Struct.cci_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

871

, Noise_Struct.isi_and_xtalk_pdf ...

872

, Noise_Struct.noise_pdf ...

872

, Noise_Struct.noise_pdf ...

873

, Noise_Struct.jitt_pdf ...

873

, Noise_Struct.jitt_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

874

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

875

, param.delta_y ...

875

, param.delta_y ...

876

);

876

);

877

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

877

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

878

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

878

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

879

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

879

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

880

% show BER target line

880

% show BER target line

881

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

881

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

882

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

882

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

883

else

883

else

884

figure_name = 'COM Contributions (Rough Allocations)';

884

figure_name = 'COM Contributions (Rough Allocations)';

885

fig=findobj('Name', figure_name);

885

fig=findobj('Name', figure_name);

886

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

886

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

887

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

887

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

888

movegui(fig,'south')

888

movegui(fig,'south')

889

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

889

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

890

890

891

plot_pie_com( hax ...

891

plot_pie_com( hax ...

892

, COM_SNR_Struct.A_s ...

892

, COM_SNR_Struct.A_s ...

893

, Noise_Struct.sci_pdf ...

893

, Noise_Struct.sci_pdf ...

894

, Noise_Struct.cci_pdf ...

894

, Noise_Struct.cci_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

895

, Noise_Struct.isi_and_xtalk_pdf ...

896

, Noise_Struct.noise_pdf ...

896

, Noise_Struct.noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

897

, COM_SNR_Struct.combined_interference_and_noise_pdf ...

898

, param.delta_y, param...

898

, param.delta_y, param...

899

);

899

);

900

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

900

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

901

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

901

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

902

end

902

end

903

903

904

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

904

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

905

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

905

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

906

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

906

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

907

end

907

end

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

908

function H_bt=Bessel_Thomson_Filter(param,f,use_BT)

909

909

910

if use_BT

910

if use_BT

911

a = bessel( param.BTorder );

911

a = bessel( param.BTorder );

912

acoef=fliplr( a );

912

acoef=fliplr( a );

913

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

913

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

914

else

914

else

915

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

915

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

916

end

916

end

917

917

918

918

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

919

function chdata=Bread_Crumb_Chdata_Reduction(chdata,fields_file)

920

920

921

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

921

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

922

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

922

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

923

%All subsequent lines are field names in chdata

923

%All subsequent lines are field names in chdata

924

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

924

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

925

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

925

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

926

%

926

%

927

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

927

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

928

%#reduce

928

%#reduce

929

%sdd12_raw

929

%sdd12_raw

930

%sdd21_raw

930

%sdd21_raw

931

%sdd22_raw

931

%sdd22_raw

932

%sdd11_raw

932

%sdd11_raw

933

%

933

%

934

934

935

fid=fopen(fields_file,'r');

935

fid=fopen(fields_file,'r');

936

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

936

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

937

937

938

file_data=file_data{1};

938

file_data=file_data{1};

939

fclose(fid);

939

fclose(fid);

940

940

941

%remove blank lines

941

%remove blank lines

942

L=cellfun('length',file_data);

942

L=cellfun('length',file_data);

943

file_data=file_data(L~=0);

943

file_data=file_data(L~=0);

944

944

945

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

945

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

946

type=file_data{1};

946

type=file_data{1};

947

field_names=file_data(2:end);

947

field_names=file_data(2:end);

948

switch lower(type)

948

switch lower(type)

949

case '#reduce'

949

case '#reduce'

950

remove_fields=field_names;

950

remove_fields=field_names;

951

case '#include'

951

case '#include'

952

all_fields=fieldnames(chdata);

952

all_fields=fieldnames(chdata);

953

remove_fields=setdiff(all_fields,field_names);

953

remove_fields=setdiff(all_fields,field_names);

954

otherwise

954

otherwise

955

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

955

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

956

end

956

end

957

957

958

%remove the "remove_fields" from chdata

958

%remove the "remove_fields" from chdata

959

for j=1:length(remove_fields)

959

for j=1:length(remove_fields)

960

this_field=remove_fields{j};

960

this_field=remove_fields{j};

961

if isfield(chdata,this_field)

961

if isfield(chdata,this_field)

962

chdata=rmfield(chdata,this_field);

962

chdata=rmfield(chdata,this_field);

963

end

963

end

964

end

964

end

965

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

965

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

966

966

967

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

967

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

968

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

968

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

969

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

969

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

970

970

971

A_s=COM_SNR_Struct.A_s;

971

A_s=COM_SNR_Struct.A_s;

972

% initialize loop with uncorrelated noise and BER

972

% initialize loop with uncorrelated noise and BER

973

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

973

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

974

974

975

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

975

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

976

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

976

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

977

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

977

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

978

% below target BER).

978

% below target BER).

979

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

979

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

980

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

980

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

981

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

981

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

982

if isempty(x_error_propagation)

982

if isempty(x_error_propagation)

983

p_error_propagation(1) = 1e-20;

983

p_error_propagation(1) = 1e-20;

984

else

984

else

985

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

985

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

986

end

986

end

987

987

988

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

988

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

989

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

989

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

990

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

990

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

991

if OP.use_simple_EP_model

991

if OP.use_simple_EP_model

992

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

992

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

993

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

993

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

994

else

994

else

995

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

995

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

996

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

996

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

997

end

997

end

998

998

999

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

999

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

1000

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

1000

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

1001

if isempty(x_error_propagation)

1001

if isempty(x_error_propagation)

1002

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

1002

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

1003

else

1003

else

1004

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

1004

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

1005

end

1005

end

1006

end

1006

end

1007

1007

1008

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

1008

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

1009

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

1009

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

1010

% of this event by partial sum of the PDF.

1010

% of this event by partial sum of the PDF.

1011

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

1011

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

1012

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

1012

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

1013

1013

1014

% probability of bursts of different lengths

1014

% probability of bursts of different lengths

1015

p_burst = cumprod(p_error_propagation);

1015

p_burst = cumprod(p_error_propagation);

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1016

function H_bw=Butterworth_Filter(param,f,use_BW)

1017

1017

1018

if use_BW

1018

if use_BW

1019

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

1019

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

1020

else

1020

else

1021

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

1021

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

1022

end

1022

end

1023

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

1023

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

1024

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

1024

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

1025

CDF_ev=CDF(index);

1025

CDF_ev=CDF(index);

1026

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

1026

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

1027

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

1027

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

1028

if isempty(index)

1028

if isempty(index)

1029

CDF_inv_ev=PDF.x(end);

1029

CDF_inv_ev=PDF.x(end);

1030

else

1030

else

1031

CDF_inv_ev=PDF.x(index);

1031

CDF_inv_ev=PDF.x(index);

1032

end

1032

end

1033

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

1033

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

1034

1034

1035

1035

1036

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

1036

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

1037

Remember_keyword='Legacy';

1037

Remember_keyword='Legacy';

1038

OP.TDMODE=false;

1038

OP.TDMODE=false;

1039

OP.GET_FD=true;

1039

OP.GET_FD=true;

1040

OP.CONFIG2MAT_ONLY=false;

1040

OP.CONFIG2MAT_ONLY=false;

1041

config_file='';

1041

config_file='';

1042

num_fext=[];

1042

num_fext=[];

1043

num_next=[];

1043

num_next=[];

1044

if ~isempty(varargin)

1044

if ~isempty(varargin)

1045

if ~ischar(varargin{1})

1045

if ~ischar(varargin{1})

1046

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

1046

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

1047

end

1047

end

1048

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

1048

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

1049

if isempty(keyword_idx)

1049

if isempty(keyword_idx)

1050

%Legacy Mode

1050

%Legacy Mode

1051

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

1051

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

1052

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

1052

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

1053

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

1053

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

1054

else

1054

else

1055

%Keyword Mode

1055

%Keyword Mode

1056

my_keyword=varargin{1};

1056

my_keyword=varargin{1};

1057

Remember_keyword=my_keyword;

1057

Remember_keyword=my_keyword;

1058

varargin(1)=[];

1058

varargin(1)=[];

1059

switch my_keyword

1059

switch my_keyword

1060

1060

1061

case 'Legacy'

1061

case 'Legacy'

1062

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

1062

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

1063

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

1063

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

1064

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

1064

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

1065

case 'TD'

1065

case 'TD'

1066

OP.TDMODE=true;

1066

OP.TDMODE=true;

1067

OP.GET_FD=false;

1067

OP.GET_FD=false;

1068

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

1068

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

1069

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

1069

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

1070

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

1070

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

1071

case 'Config2Mat'

1071

case 'Config2Mat'

1072

OP.CONFIG2MAT_ONLY=true;

1072

OP.CONFIG2MAT_ONLY=true;

1073

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

1073

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

1074

end

1074

end

1075

end

1075

end

1076

end

1076

end

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1077

function chdata=COM_FD_to_TD(chdata,param,OP)

1078

1078

1079

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

1079

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

1080

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

1080

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

1081

case_number=param.package_testcase_i;

1081

case_number=param.package_testcase_i;

1082

for i=1:param.number_of_s4p_files

1082

for i=1:param.number_of_s4p_files

1083

% RIM 2-01-2023 moved to FD_Processing

1083

% RIM 2-01-2023 moved to FD_Processing

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1084

% if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1085

% % Equation 93A-20 %%

1085

% % Equation 93A-20 %%

1086

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

1086

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

1087

% f=chdata(i).faxis;

1087

% f=chdata(i).faxis;

1088

% %

1088

% %

1089

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

1089

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

1090

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

1090

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

1091

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

1091

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

1092

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

1092

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

1093

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

1093

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

1094

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

1094

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

1095

% if OP.DISPLAY_WINDOW

1095

% if OP.DISPLAY_WINDOW

1096

% if i==1

1096

% if i==1

1097

% figure(300+param.package_testcase_i);

1097

% figure(300+param.package_testcase_i);

1098

% subplot(3,1,1)

1098

% subplot(3,1,1)

1099

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

1099

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

1100

% try

1100

% try

1101

% legend('NumColumns',2)

1101

% legend('NumColumns',2)

1102

% legend('location','south')

1102

% legend('location','south')

1103

% catch

1103

% catch

1104

% end

1104

% end

1105

% end

1105

% end

1106

% end

1106

% end

1107

% end

1107

% end

1108

[chdata(i).uneq_imp_response, ...

1108

[chdata(i).uneq_imp_response, ...

1109

chdata(i).t, ...

1109

chdata(i).t, ...

1110

chdata(i).causality_correction_dB, ...

1110

chdata(i).causality_correction_dB, ...

1111

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

1111

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

1112

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

1112

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

1113

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

1113

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

1114

[chdata(i).uneq_CD_imp_response, ...

1114

[chdata(i).uneq_CD_imp_response, ...

1115

chdata(i).t_DC, ...

1115

chdata(i).t_DC, ...

1116

chdata(i).causality_correction_DC_dB, ...

1116

chdata(i).causality_correction_DC_dB, ...

1117

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

1117

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

1118

end

1118

end

1119

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

1119

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

1120

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

1120

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

1121

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

1121

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

1122

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

1122

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

1123

1123

1124

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

1124

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

1125

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

1125

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

1126

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

1126

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

1127

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

1127

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

1128

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

1128

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

1129

rss=-inf;

1129

rss=-inf;

1130

for im=1:param.samples_per_ui

1130

for im=1:param.samples_per_ui

1131

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

1131

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

1132

end

1132

end

1133

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

1133

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

1134

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

1134

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

1135

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

1135

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

1136

end

1136

end

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1137

if OP.DEBUG && OP.DISPLAY_WINDOW

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1138

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

1139

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

1139

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

1140

screen_size=get(0,'ScreenSize');

1140

screen_size=get(0,'ScreenSize');

1141

pos = get(gcf, 'OuterPosition');

1141

pos = get(gcf, 'OuterPosition');

1142

set(gcf, 'OuterPosition', ...

1142

set(gcf, 'OuterPosition', ...

1143

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

1143

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

1144

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

1144

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

1145

%movegui(gcf,'northeast')

1145

%movegui(gcf,'northeast')

1146

1146

1147

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

1147

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

1148

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

1148

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

1149

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

1149

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

1150

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

1150

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

1151

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

1151

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

1152

end

1152

end

1153

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

1153

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

1154

% scale. thru is shown in another plot.

1154

% scale. thru is shown in another plot.

1155

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

1155

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

1156

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

1156

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

1157

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

1157

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

1158

end

1158

end

1159

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

1159

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

1160

ylabel('Volts')

1160

ylabel('Volts')

1161

xlabel('seconds')

1161

xlabel('seconds')

1162

1162

1163

recolor_plots(gca);

1163

recolor_plots(gca);

1164

else

1164

else

1165

if param.ndfe~=0

1165

if param.ndfe~=0

1166

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

1166

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

1167

end

1167

end

1168

end

1168

end

1169

1169

1170

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

1170

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

1171

if OP.ENFORCE_CAUSALITY

1171

if OP.ENFORCE_CAUSALITY

1172

fprintf('\n');

1172

fprintf('\n');

1173

else

1173

else

1174

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

1174

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

1175

end

1175

end

1176

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

1176

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

1177

1177

1178

end

1178

end

1179

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1179

function [Left_EW,Right_EW,eye_contour,out_VT,out_VB]=COM_eye_width(chdata,delta_y,fom_result,param,OP,Struct_Noise,pdf_range_flag)

1180

1180

1181

1181

1182

debug_plot=0;

1182

debug_plot=0;

1183

1183

1184

1184

1185

samp_UI=param.samples_for_C2M;

1185

samp_UI=param.samples_for_C2M;

1186

half_UI=get_center_of_UI(samp_UI);

1186

half_UI=get_center_of_UI(samp_UI);

1187

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

1187

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

1188

start_sample=half_UI-T_O;

1188

start_sample=half_UI-T_O;

1189

end_sample=half_UI+T_O;

1189

end_sample=half_UI+T_O;

1190

1190

1191

1191

1192

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

1192

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

1193

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

1193

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

1194

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

1194

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

1195

if pdf_range_flag

1195

if pdf_range_flag

1196

pdf_range=[start_sample end_sample];

1196

pdf_range=[start_sample end_sample];

1197

else

1197

else

1198

pdf_range=[];

1198

pdf_range=[];

1199

end

1199

end

1200

1200

1201

%pdf_full is self ISI pdf for each sample point

1201

%pdf_full is self ISI pdf for each sample point

1202

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

1202

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

1203

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

1203

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

1204

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

1204

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

1205

1205

1206

1206

1207

1207

1208

if isempty(pdf_range)

1208

if isempty(pdf_range)

1209

pdf_range=1:samp_UI;

1209

pdf_range=1:samp_UI;

1210

else

1210

else

1211

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

1211

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

1212

end

1212

end

1213

1213

1214

%Test doing Level PDFs

1214

%Test doing Level PDFs

1215

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

1215

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

1216

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

1216

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

1217

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

1217

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

1218

1218

1219

%add signal vector into pdf

1219

%add signal vector into pdf

1220

for n=1:param.levels

1220

for n=1:param.levels

1221

pdf_full{n}=pdf_full_1;

1221

pdf_full{n}=pdf_full_1;

1222

for j=pdf_range

1222

for j=pdf_range

1223

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

1223

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

1224

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

1224

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

1225

end

1225

end

1226

end

1226

end

1227

1227

1228

1228

1229

% figure;

1229

% figure;

1230

% hold on;

1230

% hold on;

1231

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

1231

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

1232

%computed for every sample point

1232

%computed for every sample point

1233

for n=1:param.levels

1233

for n=1:param.levels

1234

for j=pdf_range

1234

for j=pdf_range

1235

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

1235

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

1236

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

1236

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

1237

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

1237

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

1238

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

1238

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

1239

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

1239

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

1240

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

1240

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

1241

% change from adam gregory to include crosstalk

1241

% change from adam gregory to include crosstalk

1242

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

1242

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

1243

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

1243

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

1244

1244

1245

%PDF to CDF

1245

%PDF to CDF

1246

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

1246

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

1247

1247

1248

end

1248

end

1249

end

1249

end

1250

%hold off;

1250

%hold off;

1251

1251

1252

1252

1253

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

1253

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

1254

for n=1:param.levels

1254

for n=1:param.levels

1255

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

1255

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

1256

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

1256

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

1257

for j=pdf_range

1257

for j=pdf_range

1258

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

1258

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

1259

end

1259

end

1260

end

1260

end

1261

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

1261

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

1262

1262

1263

for n=1:param.levels-1

1263

for n=1:param.levels-1

1264

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

1264

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

1265

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

1265

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

1266

end

1266

end

1267

1267

1268

1268

1269

for n=1:param.levels-1

1269

for n=1:param.levels-1

1270

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

1270

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

1271

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

1271

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

1272

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

1272

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

1273

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

1273

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

1274

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

1274

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

1275

EH=EH_top-EH_bot;

1275

EH=EH_top-EH_bot;

1276

vref=EH_top/2+EH_bot/2;

1276

vref=EH_top/2+EH_bot/2;

1277

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

1277

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

1278

%the top and bottom eye contours

1278

%the top and bottom eye contours

1279

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

1279

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

1280

end

1280

end

1281

1281

1282

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

1282

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

1283

eye_contour_tmp=eye_contour;

1283

eye_contour_tmp=eye_contour;

1284

eye_contour=[];

1284

eye_contour=[];

1285

for n=1:param.levels-1

1285

for n=1:param.levels-1

1286

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

1286

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

1287

end

1287

end

1288

1288

1289

1289

1290

%Find VEC eye height

1290

%Find VEC eye height

1291

out_VT=[];

1291

out_VT=[];

1292

out_VB=[];

1292

out_VB=[];

1293

if param.T_O ~=0

1293

if param.T_O ~=0

1294

1294

1295

switch lower(OP.Histogram_Window_Weight)

1295

switch lower(OP.Histogram_Window_Weight)

1296

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

1296

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

1297

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

1297

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

1298

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

1298

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

1299

QL_sigma=T_O/param.QL;

1299

QL_sigma=T_O/param.QL;

1300

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

1300

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

1301

case 'triangle'

1301

case 'triangle'

1302

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

1302

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

1303

%for the weights

1303

%for the weights

1304

t_slope=1/(T_O);

1304

t_slope=1/(T_O);

1305

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

1305

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

1306

case 'rectangle'

1306

case 'rectangle'

1307

%default = rectangle. all weights = 1

1307

%default = rectangle. all weights = 1

1308

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

1308

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

1309

case 'dual_rayleigh'

1309

case 'dual_rayleigh'

1310

QL_sigma=T_O/param.QL;

1310

QL_sigma=T_O/param.QL;

1311

X=-T_O:T_O;

1311

X=-T_O:T_O;

1312

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

1312

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

1313

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

1313

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

1314

weights=weights/max(weights);

1314

weights=weights/max(weights);

1315

otherwise

1315

otherwise

1316

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

1316

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

1317

end

1317

end

1318

1318

1319

for n=1:param.levels

1319

for n=1:param.levels

1320

out_pdf{n}=[];

1320

out_pdf{n}=[];

1321

for j=start_sample:end_sample

1321

for j=start_sample:end_sample

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1322

target_pdf=combined_interference_and_noise_pdf_full{n}(j);

1323

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

1323

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

1324

if isempty(out_pdf{n})

1324

if isempty(out_pdf{n})

1325

out_pdf{n}=target_pdf;

1325

out_pdf{n}=target_pdf;

1326

else

1326

else

1327

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

1327

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

1328

end

1328

end

1329

end

1329

end

1330

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

1330

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

1331

end

1331

end

1332

1332

1333

for n=1:param.levels

1333

for n=1:param.levels

1334

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

1334

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

1335

end

1335

end

1336

1336

1337

for n=1:param.levels

1337

for n=1:param.levels

1338

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

1338

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

1339

end

1339

end

1340

1340

1341

for n=1:param.levels-1

1341

for n=1:param.levels-1

1342

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

1342

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

1343

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

1343

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

1344

end

1344

end

1345

1345

1346

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

1346

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

1347

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

1347

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

1348

[mineh,min_idx]=min(EH_VT);

1348

[mineh,min_idx]=min(EH_VT);

1349

out_VT=OUT_VT_L(min_idx,1);

1349

out_VT=OUT_VT_L(min_idx,1);

1350

out_VB=OUT_VT_L(min_idx,2);

1350

out_VB=OUT_VT_L(min_idx,2);

1351

1351

1352

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

1352

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

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1353

% out_VT=2*CDF_Mean-A_ni_top_O;

1354

% out_VB=-1*A_ni_bottom_O;

1354

% out_VB=-1*A_ni_bottom_O;

1355

1355

1356

if debug_plot

1356

if debug_plot

1357

figure;

1357

figure;

1358

hold on;

1358

hold on;

1359

for j=start_sample:end_sample

1359

for j=start_sample:end_sample

1360

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

1360

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

1361

end

1361

end

1362

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

1362

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

1363

hold off;

1363

hold off;

1364

end

1364

end

1365

end

1365

end

1366

1366

1367

1367

1368

1368

1369

1369

1370

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

1370

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

1371

1371

1372

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

1372

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

1373

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

1373

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

1374

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

1374

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

1375

%in other places in COM

1375

%in other places in COM

1376

1376

1377

if OP.RX_CALIBRATION

1377

if OP.RX_CALIBRATION

1378

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

1378

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

1379

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

1379

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

1380

switch param.CTLE_type

1380

switch param.CTLE_type

1381

case 'CL93'

1381

case 'CL93'

1382

H_low2=1;

1382

H_low2=1;

1383

case 'CL120d' % this clause uses two gain indexes

1383

case 'CL120d' % this clause uses two gain indexes

1384

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1384

H_low2=(10.^(param.g_DC_HP_values(fom_result.best_G_high_pass)/20) + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass))./(1 + 1i*chdata(2).faxis/param.f_HP(fom_result.best_G_high_pass));

1385

case 'CL120e' % Z1 has been adjusted

1385

case 'CL120e' % Z1 has been adjusted

1386

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

1386

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

1387

end

1387

end

1388

H_ctf2=H_low2.*ctle_gain2;

1388

H_ctf2=H_low2.*ctle_gain2;

1389

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

1389

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

1390

else

1390

else

1391

sigma_ne=0;

1391

sigma_ne=0;

1392

end

1392

end

1393

1393

1394

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

1394

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

1395

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

1395

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

1396

if ~OP.SNR_TXwC0

1396

if ~OP.SNR_TXwC0

1397

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

1397

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

1398

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

1398

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

1399

else

1399

else

1400

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1400

NS.sigma_TX = (param.levels-1)*A_s/fom_result.txffe(fom_result.cur) /param.R_LM*10^(-param.SNR_TX/20); % SNR_Tx from Adee

1401

end

1401

end

1402

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

1402

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

1403

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

1403

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

1404

else

1404

else

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1405

NS.sigma_TX =PSD_results.S_tn_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1406

NS.sigma_G = PSD_results.S_G_rms;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1407

NS.sigma_rjit=PSD_results.S_rj_rms ;

1408

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

1408

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

1409

end

1409

end

1410

% Equation 93A-41 %%

1410

% Equation 93A-41 %%

1411

1411

1412

1412

1413

% Equation 93A-42 %%

1413

% Equation 93A-42 %%

1414

% number of sigmas needed depends on the required BER.

1414

% number of sigmas needed depends on the required BER.

1415

if param.Noise_Crest_Factor == 0

1415

if param.Noise_Crest_Factor == 0

1416

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

1416

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

1417

else

1417

else

1418

NS.ber_q=param.Noise_Crest_Factor;

1418

NS.ber_q=param.Noise_Crest_Factor;

1419

end

1419

end

1420

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

1420

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

1421

% enable overriding the Q factor of the BBN instrument.

1421

% enable overriding the Q factor of the BBN instrument.

1422

if OP.force_BBN_Q_factor

1422

if OP.force_BBN_Q_factor

1423

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

1423

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

1424

else

1424

else

1425

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

1425

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

1426

end

1426

end

1427

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

1427

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

1428

1428

1429

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

1429

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

1430

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

1430

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

1431

1431

1432

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

1432

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

1433

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

1433

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

1434

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

1434

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

1435

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

1435

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

1436

1436

1437

% Implementation of 93A.1.7.3 combination procedure

1437

% Implementation of 93A.1.7.3 combination procedure

1438

% (effectively Equation 93A-44) %%

1438

% (effectively Equation 93A-44) %%

1439

1439

1440

% Self-Channel Interference is thru residual result

1440

% Self-Channel Interference is thru residual result

1441

NS.sci_pdf = chdata(1).pdfr;

1441

NS.sci_pdf = chdata(1).pdfr;

1442

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

1442

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

1443

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

1443

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

1444

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

1444

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

1445

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

1445

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

1446

if OP.RX_CALIBRATION ==0

1446

if OP.RX_CALIBRATION ==0

1447

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

1447

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

1448

% initialize to deltas

1448

% initialize to deltas

1449

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

1449

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

1450

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

1450

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

1451

% serially convolve FEXT/NEXT PDFs

1451

% serially convolve FEXT/NEXT PDFs

1452

for k=2:param.number_of_s4p_files

1452

for k=2:param.number_of_s4p_files

1453

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

1453

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

1454

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

1454

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

1455

else % ... must be FEXT

1455

else % ... must be FEXT

1456

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

1456

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

1457

end

1457

end

1458

end

1458

end

1459

1459

1460

% find "peaks" of MDNEXT/MDFEXT for reporting

1460

% find "peaks" of MDNEXT/MDFEXT for reporting

1461

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

1461

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

1462

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

1462

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

1463

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

1463

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

1464

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

1464

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

1465

1465

1466

% Combined crosstalk effect

1466

% Combined crosstalk effect

1467

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1467

NS.cci_pdf = conv_fct(MDFEXT_cci_pdf, MDNEXT_cci_pdf);

1468

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

1468

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

1469

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

1469

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

1470

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

1470

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

1471

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

1471

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

1472

% combine cci and sci

1472

% combine cci and sci

1473

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

1473

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

1474

else

1474

else

1475

% for calibration there is no cci

1475

% for calibration there is no cci

1476

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1476

NS.isi_and_xtalk_pdf=NS.sci_pdf;

1477

end

1477

end

1478

1478

1479

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

1479

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

1480

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

1480

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

1481

1481

1482

1482

1483

% Equation 93A-45

1483

% Equation 93A-45

1484

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

1484

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

1485

PDF=combined_interference_and_noise_pdf;

1485

PDF=combined_interference_and_noise_pdf;

1486

1486

1487

% Equation 93A-37

1487

% Equation 93A-37

1488

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1488

combined_interference_and_noise_cdf=cumsum(combined_interference_and_noise_pdf.y);

1489

CDF=combined_interference_and_noise_cdf;

1489

CDF=combined_interference_and_noise_cdf;

1490

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

1490

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

1491

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

1491

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

1492

1492

1493

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

1493

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

1494

%This function calculates various frequency domain metrics

1494

%This function calculates various frequency domain metrics

1495

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

1495

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

1496

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

1496

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

1497

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1497

package_testcase=OP.pkg_len_select(param.package_testcase_i);

1498

if OP.WC_PORTZ

1498

if OP.WC_PORTZ

1499

A_thru = param.a_thru(param.Tx_rd_sel);

1499

A_thru = param.a_thru(param.Tx_rd_sel);

1500

A_fext = param.a_fext(param.Tx_rd_sel);

1500

A_fext = param.a_fext(param.Tx_rd_sel);

1501

A_next = param.a_next(param.Tx_rd_sel);

1501

A_next = param.a_next(param.Tx_rd_sel);

1502

else

1502

else

1503

A_thru = param.a_thru(package_testcase);

1503

A_thru = param.a_thru(package_testcase);

1504

A_fext = param.a_fext(package_testcase);

1504

A_fext = param.a_fext(package_testcase);

1505

A_next = param.a_next(package_testcase);

1505

A_next = param.a_next(package_testcase);

1506

end

1506

end

1507

for i=1:param.number_of_s4p_files

1507

for i=1:param.number_of_s4p_files

1508

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

1508

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

1509

chdata(i).A=A_thru;

1509

chdata(i).A=A_thru;

1510

chdata(i).Aicn=A_thru;

1510

chdata(i).Aicn=A_thru;

1511

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

1511

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

1512

chdata(i).A=A_fext;

1512

chdata(i).A=A_fext;

1513

chdata(i).Aicn=param.a_icn_fext;

1513

chdata(i).Aicn=param.a_icn_fext;

1514

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

1514

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

1515

chdata(i).A=A_next;

1515

chdata(i).A=A_next;

1516

chdata(i).Aicn=param.a_icn_next;

1516

chdata(i).Aicn=param.a_icn_next;

1517

end

1517

end

1518

end

1518

end

1519

if OP.TDMODE

1519

if OP.TDMODE

1520

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

1520

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

1521

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

1521

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

1522

end

1522

end

1523

end

1523

end

1524

if ~DO_ONCE

1524

if ~DO_ONCE

1525

return;

1525

return;

1526

end

1526

end

1527

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

1527

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

1528

output_args.fitted_IL_dB_at_Fnq = [];

1528

output_args.fitted_IL_dB_at_Fnq = [];

1529

output_args.cable__assembley_loss=[];

1529

output_args.cable__assembley_loss=[];

1530

output_args.loss_with_PCB=[];

1530

output_args.loss_with_PCB=[];

1531

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1531

output_args.VIP_to_VMP_IL_dB_at_Fnq=[];

1532

output_args.IL_dB_channel_only_at_Fnq=[];

1532

output_args.IL_dB_channel_only_at_Fnq=[];

1533

output_args.VTF_loss_dB_at_Fnq=[];

1533

output_args.VTF_loss_dB_at_Fnq=[];

1534

output_args.IL_db_die_to_die_at_Fnq=[];

1534

output_args.IL_db_die_to_die_at_Fnq=[];

1535

output_args.FOM_TDILN=[];

1535

output_args.FOM_TDILN=[];

1536

output_args.TD_ILN=[];

1536

output_args.TD_ILN=[];

1537

output_args.FOM_RILN=[];

1537

output_args.FOM_RILN=[];

1538

output_args.FOM_ILD=[];

1538

output_args.FOM_ILD=[];

1539

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

1539

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

1540

if ~OP.GET_FD

1540

if ~OP.GET_FD

1541

return;

1541

return;

1542

end

1542

end

1543

case_number=param.package_testcase_i;

1543

case_number=param.package_testcase_i;

1544

f2=param.f2;

1544

f2=param.f2;

1545

f1=param.f1;

1545

f1=param.f1;

1546

MDFEXT_ICN=0; MDNEXT_ICN=0;

1546

MDFEXT_ICN=0; MDNEXT_ICN=0;

1547

for i=1:param.number_of_s4p_files

1547

for i=1:param.number_of_s4p_files

1548

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1548

if OP.INCLUDE_FILTER % apply RX filtRaised_Cosine_Filterer

1549

% Equation 93A-20 %%

1549

% Equation 93A-20 %%

1550

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

1550

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

1551

f=chdata(i).faxis;

1551

f=chdata(i).faxis;

1552

%

1552

%

1553

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

1553

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

1554

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

1554

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

1555

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

1555

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

1556

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

1556

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

1557

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

1557

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

1558

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

1558

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

1559

if OP.DISPLAY_WINDOW

1559

if OP.DISPLAY_WINDOW

1560

if i==1

1560

if i==1

1561

figure(300+param.package_testcase_i);

1561

figure(300+param.package_testcase_i);

1562

subplot(3,1,1)

1562

subplot(3,1,1)

1563

hold on

1563

hold on

1564

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

1564

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

1565

try

1565

try

1566

legend('NumColumns',2)

1566

legend('NumColumns',2)

1567

legend('location','south')

1567

legend('location','south')

1568

catch

1568

catch

1569

end

1569

end

1570

end

1570

end

1571

end

1571

end

1572

end

1572

end

1573

end

1573

end

1574

for i=1:param.number_of_s4p_files

1574

for i=1:param.number_of_s4p_files

1575

if i == 2

1575

if i == 2

1576

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

1576

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

1577

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

1577

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

1578

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

1578

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

1579

end

1579

end

1580

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

1580

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

1581

if isempty(a)

1581

if isempty(a)

1582

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

1582

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

1583

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

1583

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

1584

else

1584

else

1585

index_f2=a(1);

1585

index_f2=a(1);

1586

end

1586

end

1587

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

1587

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

1588

if isempty(b)

1588

if isempty(b)

1589

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

1589

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

1590

index_f1=1;

1590

index_f1=1;

1591

else

1591

else

1592

index_f1=b(1);

1592

index_f1=b(1);

1593

end

1593

end

1594

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

1594

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

1595

% PWF for ICN

1595

% PWF for ICN

1596

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

1596

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

1597

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

1597

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

1598

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

1598

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

1599

end

1599

end

1600

SINC = sin(temp_angle)./temp_angle;

1600

SINC = sin(temp_angle)./temp_angle;

1601

PWF_data=SINC.^2;

1601

PWF_data=SINC.^2;

1602

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

1602

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

1603

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

1603

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

1604

fr=param.f_r*param.fb;

1604

fr=param.f_r*param.fb;

1605

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

1605

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

1606

PWF_highpass=1;

1606

PWF_highpass=1;

1607

% Equation 93A-57 %

1607

% Equation 93A-57 %

1608

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

1608

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

1609

% freq delta for integration

1609

% freq delta for integration

1610

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

1610

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

1611

% from ba spec, this is basically ICN

1611

% from ba spec, this is basically ICN

1612

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

1612

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

1613

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

1613

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

1614

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

1614

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

1615

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

1615

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

1616

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

1616

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

1617

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

1617

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

1618

chdata(i).fit_ILatNq = fit_loss;

1618

chdata(i).fit_ILatNq = fit_loss;

1619

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1619

output_args.fitted_IL_dB_at_Fnq = fit_loss;

1620

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

1620

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

1621

chdata(i).ILatNq = IL_interp;

1621

chdata(i).ILatNq = IL_interp;

1622

if OP.include_pcb

1622

if OP.include_pcb

1623

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

1623

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

1624

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

1624

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

1625

output_args.cable__assembley_loss=cable_loss;

1625

output_args.cable__assembley_loss=cable_loss;

1626

output_args.loss_with_PCB=loss_with_PCB;

1626

output_args.loss_with_PCB=loss_with_PCB;

1627

end

1627

end

1628

Nq_loss=chdata(i).ILatNq;

1628

Nq_loss=chdata(i).ILatNq;

1629

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1629

output_args.IL_dB_channel_only_at_Fnq=Nq_loss;

1630

% time domain ref RR = complex fit pulse

1630

% time domain ref RR = complex fit pulse

1631

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1631

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1632

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1632

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

1633

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1633

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1634

FOM_ILN_complex= TD_ILN.FOM;

1634

FOM_ILN_complex= TD_ILN.FOM;

1635

end

1635

end

1636

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1636

if OP.COMPUTE_TDILN || OP.COMPUTE_RILN

1637

[ILD chdata(i).fit, TD_ILN ] = get_ILN_cmp_td(chdata(i).sdd21f(index_f1:index_f2), chdata(i).faxis(index_f1:index_f2),OP,param,chdata(i).A);

1637

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

1638

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1638

FOM_TDILN = TD_ILN.SNR_ISI_FOM_PDF;

1639

FOM_ILN_complex= TD_ILN.FOM;

1639

FOM_ILN_complex= TD_ILN.FOM;

1640

end

1640

end

1641

if OP.COMPUTE_TDILN

1641

if OP.COMPUTE_TDILN

1642

output_args.FOM_TDILN=FOM_TDILN;

1642

output_args.FOM_TDILN=FOM_TDILN;

1643

output_args.TD_ILN=TD_ILN; % struct

1643

output_args.TD_ILN=TD_ILN; % struct

1644

end

1644

end

1645

if OP.COMPUTE_RILN

1645

if OP.COMPUTE_RILN

1646

% Get RIL, RILN, and TD_RILN

1646

% Get RIL, RILN, and TD_RILN

1647

[RIL_struct]= capture_RIL_RILN(chdata);

1647

[RIL_struct]= capture_RIL_RILN(chdata);

1648

FOM_RILN=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2-1).*RIL_struct.RILN_dB(index_f1:index_f2-1)'.^2));

1648

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

1649

output_args.FOM_RILN=FOM_RILN;

1649

output_args.FOM_RILN=FOM_RILN;

1650

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

1650

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

1651

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

1651

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

1652

if plot_tdomain_debug== 1

1652

if plot_tdomain_debug== 1

1653

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

1653

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

1654

ax_1= subplot(3,1,1);

1654

ax_1= subplot(3,1,1);

1655

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

1655

plot(TD_ILN.REF.t*1e9, TD_ILN.REF.PR*1e3,'disp','ref');

1656

hold on;

1656

hold on;

1657

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1657

plot(TD_ILN.FIT.t*1e9, TD_ILN.FIT.PR*1e3,'disp','fit');

1658

hold on;

1658

hold on;

1659

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1659

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k','disp','ref - fit (IL noise)');

1660

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1660

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1661

grid on;

1661

grid on;

1662

box on;

1662

box on;

1663

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1663

legend('REF', 'FIT', 'TD\_ILN: ref - fit (IL noise)');

1664

xlabel('Time [nsec]');

1664

xlabel('Time [nsec]');

1665

ylabel('Pulse Response [mV]');

1665

ylabel('Pulse Response [mV]');

1666

1666

1667

ax_2= subplot(3,1,2);

1667

ax_2= subplot(3,1,2);

1668

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1668

plot(TD_RILN.REF.t*1e9, TD_RILN.REF.PR*1e3);

1669

hold on;

1669

hold on;

1670

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1670

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1671

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1671

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1672

grid on;

1672

grid on;

1673

box on;

1673

box on;

1674

legend('REF', 'TD\_RILN');

1674

legend('REF', 'TD\_RILN');

1675

xlabel('Time [nsec]');

1675

xlabel('Time [nsec]');

1676

ylabel('Pulse Response [mV]');

1676

ylabel('Pulse Response [mV]');

1677

ax_3= subplot(3,1,3);

1677

ax_3= subplot(3,1,3);

1678

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1678

plot(TD_ILN.t*1e9, TD_ILN.ILN*1e3, 'k');

1679

hold on;

1679

hold on;

1680

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1680

plot(TD_RILN.t*1e9, TD_RILN.ILN*1e3, 'r');

1681

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1681

ylim([min(TD_RILN.ILN) max(TD_RILN.ILN)]*1e3);

1682

grid on;

1682

grid on;

1683

box on;

1683

box on;

1684

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1684

legend( 'TD\_ILN: ref - fit (IL noise)', 'TD\_RILN');

1685

xlabel('Time [nsec]');

1685

xlabel('Time [nsec]');

1686

ylabel('Pulse Response [mV]');

1686

ylabel('Pulse Response [mV]');

1687

1687

1688

linkaxes([ax_1, ax_2, ax_3], 'x');

1688

linkaxes([ax_1, ax_2, ax_3], 'x');

1689

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1689

ax_1.XLim = [0 max(TD_RILN.t)*1e9 ];

1690

end

1690

end

1691

%---end. plotting ILN based on ILD and RILN

1691

%---end. plotting ILN based on ILD and RILN

1692

end

1692

end

1693

% Equation 93A-56 %

1693

% Equation 93A-56 %

1694

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1694

FOM_ILD=sqrt(chdata(i).delta_f/(param.f2-param.f1)*sum( PWF(index_f1:index_f2).*ILD_magft.^2));

1695

output_args.FOM_ILD=FOM_ILD;

1695

output_args.FOM_ILD=FOM_ILD;

1696

if OP.DEBUG

1696

if OP.DEBUG

1697

if OP.DISPLAY_WINDOW

1697

if OP.DISPLAY_WINDOW

1698

figure(300+case_number);

1698

figure(300+case_number);

1699

set(gcf,'Tag','COM')

1699

set(gcf,'Tag','COM')

1700

screen_size=get(0,'ScreenSize');

1700

screen_size=get(0,'ScreenSize');

1701

pos = get(gcf, 'OuterPosition');

1701

pos = get(gcf, 'OuterPosition');

1702

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1702

set(gcf, 'Name', [sprintf('%.3gdB IL Channel: ',Nq_loss) 'Raw frequency-domain data'], 'OuterPosition', ...

1703

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1703

screen_size([3 4 3 4]).*[0 1 0 0] + pos([3 4 3 4]).*[0 -2 1 2] ...IL fit

1704

- (case_number-1)*[0 20 0 0]);

1704

- (case_number-1)*[0 20 0 0]);

1705

subplot(3,1,1)

1705

subplot(3,1,1)

1706

title('Losses')

1706

title('Losses')

1707

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1707

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp','IL passed s-params')

1708

hold on

1708

hold on

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1709

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p_nodie))), 'm-', 'Disp','IL die to die (w pkg/brds)')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1710

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21p))), 'b-', 'Disp','IL dB VIP to VMP')

1711

ylim(get(gca, 'ylim'));

1711

ylim(get(gca, 'ylim'));

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1712

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd11))),'c','Disp','RL11')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1713

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd22))),'m','Disp','RL22')

1714

subplot(3,1,3)

1714

subplot(3,1,3)

1715

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1715

plot(faxis_GHz(index_f1:index_f2), ILD_magft,'Disp','ILD')

1716

if OP.PLOT_CM

1716

if OP.PLOT_CM

1717

if case_number ==1

1717

if case_number ==1

1718

h350=figure(350);set(gcf,'Tag','COM')

1718

h350=figure(350);set(gcf,'Tag','COM')

1719

screen_size=get(0,'ScreenSize');

1719

screen_size=get(0,'ScreenSize');

1720

pos = get(gcf, 'OuterPosition');

1720

pos = get(gcf, 'OuterPosition');

1721

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1721

set(gcf, 'OuterPosition',screen_size([3 4 3 4]).*[1 1 0 0] + pos([3 4 3 4]).*[-2 -2 2 1])

1722

movegui(gcf,'center');

1722

movegui(gcf,'center');

1723

htabgroup350 = uitabgroup(h350);

1723

htabgroup350 = uitabgroup(h350);

1724

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1724

htab1 = uitab(htabgroup350, 'Title', 'CM Through Losses');

1725

hax1 = axes('Parent', htab1);

1725

hax1 = axes('Parent', htab1);

1726

set(h350,'CurrentAxes',hax1)

1726

set(h350,'CurrentAxes',hax1)

1727

hold on

1727

hold on

1728

set(gcf,'Tag','COM')

1728

set(gcf,'Tag','COM')

1729

screen_size=get(0,'ScreenSize');

1729

screen_size=get(0,'ScreenSize');

1730

pos = get(gcf, 'OuterPosition');

1730

pos = get(gcf, 'OuterPosition');

1731

title('IL & CM Losses')

1731

title('IL & CM Losses')

1732

base=strrep(chdata(i).base,'_',' ');

1732

base=strrep(chdata(i).base,'_',' ');

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1733

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21f))), 'b', 'LineWidth', 3, 'Disp', [ 'sdd21(IL) TP0-TP5 ' base])

1734

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1734

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base])

1735

ylabel('dB')

1735

ylabel('dB')

1736

xlabel('GHz')

1736

xlabel('GHz')

1737

legend show

1737

legend show

1738

legend('Location','eastoutside')

1738

legend('Location','eastoutside')

1739

hold on

1739

hold on

1740

grid on

1740

grid on

1741

if param.number_of_s4p_files > 1

1741

if param.number_of_s4p_files > 1

1742

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1742

htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1743

hax2 = axes('Parent', htab2);

1743

hax2 = axes('Parent', htab2);

1744

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1744

htab3 = uitab(htabgroup350, 'Title', 'Crosstalk Losses');

1745

hax3 = axes('Parent', htab3);

1745

hax3 = axes('Parent', htab3);

1746

end

1746

end

1747

1747

1748

end

1748

end

1749

end

1749

end

1750

else

1750

else

1751

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1751

display(['Insertion Loss at Nyquist = ', num2str(chdata(i).ILatNq)])

1752

end

1752

end

1753

end

1753

end

1754

else % NEXT or FEXT

1754

else % NEXT or FEXT

1755

if isequal(chdata(i).type, 'FEXT')

1755

if isequal(chdata(i).type, 'FEXT')

1756

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1756

MDFEXT=sqrt(abs(chdata(i).sdd21f).^2+MDFEXT.^2); % power sum xtk

1757

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1757

MDFEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDFEXT(index_f1:index_f2)).^2)); %eq 46

1758

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1758

output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

1759

elseif isequal(chdata(i).type, 'NEXT')

1759

elseif isequal(chdata(i).type, 'NEXT')

1760

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1760

MDNEXT=sqrt(abs(chdata(i).sdd21f).^2+MDNEXT.^2); % power sum xtk

1761

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1761

MDNEXT_ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( chdata(i).Aicn^2*PWF(index_f1:index_f2).*abs(MDNEXT(index_f1:index_f2)).^2)); %eq 47

1762

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1762

output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

1763

end

1763

end

1764

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1764

PSXT=sqrt((abs(chdata(i).sdd21f)*chdata(i).Aicn).^2+PSXT.^2); % power sum xtk

1765

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1765

ICN=sqrt(2*chdata(i).delta_f/param.f2*sum( PWF(index_f1:index_f2).*abs(PSXT(index_f1:index_f2)).^2));

1766

output_args.ICN_mV=ICN*1000;

1766

output_args.ICN_mV=ICN*1000;

1767

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1767

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1768

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1768

if OP.PLOT_CM && OP.DISPLAY_WINDOW

1769

if case_number ==1

1769

if case_number ==1

1770

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1770

% htab2 = uitab(htabgroup350, 'Title', 'CM Crosstalk Losses');

1771

% hax2 = axes('Parent', htab2);

1771

% hax2 = axes('Parent', htab2);

1772

set(h350,'CurrentAxes',hax2)

1772

set(h350,'CurrentAxes',hax2)

1773

hold on

1773

hold on

1774

title('CM Losses')

1774

title('CM Losses')

1775

base=strrep(chdata(i).base,'_',' ');

1775

base=strrep(chdata(i).base,'_',' ');

1776

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1776

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdc21_raw))), 'LineWidth', 2, 'Disp',[ 'sdc21 TP0-TP5 ' base ])

1777

legend('Location','eastoutside')

1777

legend('Location','eastoutside')

1778

hold on

1778

hold on

1779

grid on

1779

grid on

1780

set(h350,'CurrentAxes',hax3)

1780

set(h350,'CurrentAxes',hax3)

1781

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1781

plot(faxis_GHz, 20*log10(abs(squeeze(chdata(i).sdd21_raw))), 'LineWidth', 2, 'Disp',[ 'sdd21 TP0-TP5 ' base ])

1782

legend('Location','eastoutside')

1782

legend('Location','eastoutside')

1783

hold on

1783

hold on

1784

grid on

1784

grid on

1785

end

1785

end

1786

end

1786

end

1787

end

1787

end

1788

end % for loop

1788

end % for loop

1789

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1789

ICN_test=norm([MDFEXT_ICN MDNEXT_ICN]);

1790

if OP.DEBUG && OP.DISPLAY_WINDOW

1790

if OP.DEBUG && OP.DISPLAY_WINDOW

1791

figure(300+case_number);set(gcf,'Tag','COM');

1791

figure(300+case_number);set(gcf,'Tag','COM');

1792

if param.number_of_s4p_files > 1

1792

if param.number_of_s4p_files > 1

1793

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1793

scale=1/chdata(2).Aicn; %chdata(i).sdd21f not scalled

1794

subplot(3,1,1)

1794

subplot(3,1,1)

1795

hold on

1795

hold on

1796

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1796

plot(faxis_GHz, 20*log10(abs(PSXT*scale)),'r','Disp','PSXTK')

1797

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1797

icrxi=find(chdata(i).faxis >=param.fb/2,1,'first');

1798

subplot(3,1,2)

1798

subplot(3,1,2)

1799

grid on

1799

grid on

1800

ILtemp=20*log10(abs(chdata(1).sdd21f));

1800

ILtemp=20*log10(abs(chdata(1).sdd21f));

1801

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1801

IL4ICR=interp1(chdata(1).faxis,ILtemp,chdata(i).faxis);

1802

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1802

scale=1/chdata(2).Aicn; % chdata(i).sdd21f not scalled

1803

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1803

ICR=-20*log10(abs(PSXT*scale))+IL4ICR;

1804

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1804

semilogx(faxis_GHz, ICR,'Disp', 'ICR')

1805

hold on

1805

hold on

1806

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1806

stem(faxis_GHz(icrxi), ICR(icrxi),'g', 'disp', 'f_{Baud}/2')

1807

end

1807

end

1808

subplot(3,1,1)

1808

subplot(3,1,1)

1809

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1809

title([param.base ' Losses']); ylabel('dB'); xlabel('GHz')

1810

grid on; legend show

1810

grid on; legend show

1811

subplot(3,1,2)

1811

subplot(3,1,2)

1812

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1812

title([param.base ' ICR']); ylabel('dB'); xlabel('GHz')

1813

ylim([0 80])

1813

ylim([0 80])

1814

xlim([.1 100])

1814

xlim([.1 100])

1815

grid on; %legend show

1815

grid on; %legend show

1816

subplot(3,1,3)

1816

subplot(3,1,3)

1817

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1817

title([param.base ' ILD']); ylabel('dB'); xlabel('GHz')

1818

ylim([-3 3])

1818

ylim([-3 3])

1819

grid on; legend show

1819

grid on; legend show

1820

end

1820

end

1821

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1821

% find loss values by interpolation using full data, no indexing - Adee 2022-08-28

1822

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1822

total_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21)), 1/param.ui/2);

1823

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1823

d2d_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p_nodie)), 1/param.ui/2);

1824

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1824

VIP_VMP_loss = interp1(chdata(i).faxis, -20*log10(abs(chdata(1).sdd21p)), 1/param.ui/2);

1825

output_args.VTF_loss_dB_at_Fnq=total_loss;

1825

output_args.VTF_loss_dB_at_Fnq=total_loss;

1826

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1826

output_args.IL_db_die_to_die_at_Fnq=d2d_loss;

1827

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1827

output_args.VIP_to_VMP_IL_dB_at_Fnq=VIP_VMP_loss;

1828

function [ V0 ] = FFE( C , cmx,spui, V )

1828

function [ V0 ] = FFE( C , cmx,spui, V )

1829

% C FFE taps

1829

% C FFE taps

1830

% cmx number of precursors taps

1830

% cmx number of precursors taps

1831

% spui samples per ui

1831

% spui samples per ui

1832

% V input signal

1832

% V input signal

1833

%speed ups implemented:

1833

%speed ups implemented:

1834

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1834

%1) ignore C(i)=0. No need to circshift and then multiply by 0

1835

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1835

%2) change ishift to shift an extra -cmx. This avoids extra circshift at the end

1836

1836

1837

V0=0;

1837

V0=0;

1838

if iscolumn(V); V=V.';end

1838

if iscolumn(V); V=V.';end

1839

for i=1:length(C)

1839

for i=1:length(C)

1840

if C(i)~=0

1840

if C(i)~=0

1841

ishift=(i-1-cmx)*spui;

1841

ishift=(i-1-cmx)*spui;

1842

V0=circshift(V',[ishift,0])*C(i)+V0;

1842

V0=circshift(V',[ishift,0])*C(i)+V0;

1843

end

1843

end

1844

end

1844

end

1845

%V0=circshift(V0,[(-cmx)*spui,0]);

1845

%V0=circshift(V0,[(-cmx)*spui,0]);

1846

% disp(max(V0));

1846

% disp(max(V0));

1847

1847

1848

1848

1849

% begin yasuo patch 12/11/2018

1849

% begin yasuo patch 12/11/2018

1850

% calculate sigma (standard deviation) value of PDF

1850

% calculate sigma (standard deviation) value of PDF

1851

function [ V0 ] = FFE_Fast( C,V_shift )

1851

function [ V0 ] = FFE_Fast( C,V_shift )

1852

% C FFE taps

1852

% C FFE taps

1853

% V input signal separated into length(C) columns with circshift already performed

1853

% V input signal separated into length(C) columns with circshift already performed

1854

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1854

% This function is only to speed up FFE in optimize_fom. Since the signal that is being

1855

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1855

% shifted is the same for all loops of TXFFE taps, a lot of time can be

1856

% saved by pre-shifting it and remembering it across loops

1856

% saved by pre-shifting it and remembering it across loops

1857

% Another speed up: only multiply by indices of C that are not 0

1857

% Another speed up: only multiply by indices of C that are not 0

1858

1858

1859

V0=0;

1859

V0=0;

1860

for i=1:length(C)

1860

for i=1:length(C)

1861

if C(i)~=0

1861

if C(i)~=0

1862

V0=V_shift(:,i)*C(i)+V0;

1862

V0=V_shift(:,i)*C(i)+V0;

1863

end

1863

end

1864

end

1864

end

1865

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1865

function idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end)

1866

1866

1867

hisi=h(isi_start:isi_end);

1867

hisi=h(isi_start:isi_end);

1868

hisi=hisi(param.RxFFE_cpx+1:param.N_bmax);

1868

hisi=hisi(param.N_tail_start:param.N_bmax);

1869

bank_size = param.N_bf;

1869

bank_size = param.N_bf;

1870

num_groups = param.N_bg;

1870

num_groups = param.N_bg;

1871

1871

1872

1872

1873

%start with one by one Floating Tap

1873

%start with one by one Floating Tap

1874

num_isi=length(hisi);

1874

num_isi=length(hisi);

1875

max_isi=num_isi-bank_size+1;

1875

max_isi=num_isi-bank_size+1;

1876

valid_tap_locations=1:max_isi;

1876

valid_tap_locations=1:max_isi;

1877

all_idx=[];

1877

all_idx=[];

1878

for j=1:num_groups

1878

for j=1:num_groups

1879

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1879

best_FOM=ones(1,length(valid_tap_locations))*-Inf;

1880

for k=1:length(valid_tap_locations)

1880

for k=1:length(valid_tap_locations)

1881

this_location=valid_tap_locations(k);

1881

this_location=valid_tap_locations(k);

1882

new_idx = [all_idx this_location:this_location+bank_size-1];

1882

new_idx = [all_idx this_location:this_location+bank_size-1];

1883

new_idx=sort(new_idx);

1883

new_idx=sort(new_idx);

1884

new_idx = new_idx+param.RxFFE_cpx;

1884

new_idx = new_idx+param.N_tail_start-1;

1885

%calculate FOM for each one

1885

%calculate FOM for each one

1886

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1886

[~,best_FOM(k),~,~] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,new_idx);

1887

end

1887

end

1888

%choose the location with best FOM

1888

%choose the location with best FOM

1889

%add it to the "all_idx" list and remove it from valid locations

1889

%add it to the "all_idx" list and remove it from valid locations

1890

[~,best_FOM_idx]=max(best_FOM);

1890

[~,best_FOM_idx]=max(best_FOM);

1891

start_tap = valid_tap_locations(best_FOM_idx);

1891

start_tap = valid_tap_locations(best_FOM_idx);

1892

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1892

all_idx=[all_idx start_tap:start_tap+bank_size-1];

1893

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1893

remove_range=best_FOM_idx:best_FOM_idx+bank_size-1;

1894

remove_range(remove_range>length(valid_tap_locations))=[];

1894

remove_range(remove_range>length(valid_tap_locations))=[];

1895

valid_tap_locations(remove_range)=[];

1895

valid_tap_locations(remove_range)=[];

1896

1896

1897

%Also remove illegal taps from valid locations

1897

%Also remove illegal taps from valid locations

1898

%illegal taps are ones that would overlap with the chosen bank

1898

%illegal taps are ones that would overlap with the chosen bank

1899

bad_tap=start_tap-bank_size+1:start_tap-1;

1899

bad_tap=start_tap-bank_size+1:start_tap-1;

1900

bad_tap(bad_tap<1)=[];

1900

bad_tap(bad_tap<1)=[];

1901

for n=1:length(bad_tap)

1901

for n=1:length(bad_tap)

1902

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1902

bad_tap_idx=find(valid_tap_locations==bad_tap(n));

1903

if ~isempty(bad_tap_idx)

1903

if ~isempty(bad_tap_idx)

1904

valid_tap_locations(bad_tap_idx)=[];

1904

valid_tap_locations(bad_tap_idx)=[];

1905

end

1905

end

1906

end

1906

end

1907

end

1907

end

1908

1908

1909

%put idx back in the right location (adding RxFFE_cpx)

1909

%put idx back in the right location (adding N_tail_start)

1910

idx = all_idx+param.RxFFE_cpx;

1910

idx = all_idx+param.N_tail_start-1;

1911

idx = sort(idx);

1911

idx = sort(idx);

1912

function [ V0 ] = Fract_T_FFE( V , skew_step)

1912

function [ V0 ] = Fract_T_FFE( V , skew_step)

1913

% skew_step sub UI skew assuming param.samples_per_ui

1913

% skew_step sub UI skew assuming param.samples_per_ui

1914

% V input signal

1914

% V input signal

1915

% V0 output signal

1915

% V0 output signal

1916

% Richard Mellitz 8/17/2021

1916

% Richard Mellitz 8/17/2021

1917

V0=0;

1917

V0=0;

1918

if iscolumn(V); V=V.';end

1918

if iscolumn(V); V=V.';end

1919

ishift=skew_step;

1919

ishift=skew_step;

1920

V0=circshift(V',[ishift,0])'+V;

1920

V0=circshift(V',[ishift,0])'+V;

1921

V0=V0/2;

1921

V0=V0/2;

1922

function out=Full_Grid_Matrix(in)

1922

function out=Full_Grid_Matrix(in)

1923

1923

1924

%create a full grid matrix of input variables

1924

%create a full grid matrix of input variables

1925

%used to create the full grid of all txffe cases

1925

%used to create the full grid of all txffe cases

1926

%example:

1926

%example:

1927

%Full_Grid_Matrix({ [1 2] [100 200] })

1927

%Full_Grid_Matrix({ [1 2] [100 200] })

1928

%out =

1928

%out =

1929

% 1 100

1929

% 1 100

1930

% 1 200

1930

% 1 200

1931

% 2 100

1931

% 2 100

1932

% 2 200

1932

% 2 200

1933

%

1933

%

1934

%input can also be mixed between numeric and cell of char

1934

%input can also be mixed between numeric and cell of char

1935

%example:

1935

%example:

1936

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1936

%Full_Grid_Matrix({ [1 2] {'A' 'B'} })

1937

%out =

1937

%out =

1938

% {[1]} {'A'}

1938

% {[1]} {'A'}

1939

% {[1]} {'B'}

1939

% {[1]} {'B'}

1940

% {[2]} {'A'}

1940

% {[2]} {'A'}

1941

% {[2]} {'B'}

1941

% {[2]} {'B'}

1942

1942

1943

if ~iscell(in)

1943

if ~iscell(in)

1944

error('input must be cell array of individual sweep variables');

1944

error('input must be cell array of individual sweep variables');

1945

end

1945

end

1946

1946

1947

num_columns=length(in);

1947

num_columns=length(in);

1948

num_cases=prod(cellfun('length',in));

1948

num_cases=prod(cellfun('length',in));

1949

1949

1950

cell_output=0;

1950

cell_output=0;

1951

cell_indices=cellfun(@(x) iscell(x),in);

1951

cell_indices=cellfun(@(x) iscell(x),in);

1952

if any(cell_indices)

1952

if any(cell_indices)

1953

cell_output=1;

1953

cell_output=1;

1954

end

1954

end

1955

if cell_output

1955

if cell_output

1956

for k=find(~cell_indices)

1956

for k=find(~cell_indices)

1957

in{k}=num2cell(in{k});

1957

in{k}=num2cell(in{k});

1958

end

1958

end

1959

end

1959

end

1960

1960

1961

if cell_output

1961

if cell_output

1962

out=cell(num_cases,num_columns);

1962

out=cell(num_cases,num_columns);

1963

else

1963

else

1964

out=zeros(num_cases,num_columns);

1964

out=zeros(num_cases,num_columns);

1965

end

1965

end

1966

1966

1967

%num_repetitions controls how many times each element of the column

1967

%num_repetitions controls how many times each element of the column

1968

%repeats. The first column is always just a copy of itself since every

1968

%repeats. The first column is always just a copy of itself since every

1969

%case will vary.

1969

%case will vary.

1970

num_repetitions=1;

1970

num_repetitions=1;

1971

for k=num_columns:-1:1

1971

for k=num_columns:-1:1

1972

this_column=in{k}(:);

1972

this_column=in{k}(:);

1973

%copy the column into a matrix to create the repetitions needed

1973

%copy the column into a matrix to create the repetitions needed

1974

B=repmat(this_column,[1 num_repetitions]);

1974

B=repmat(this_column,[1 num_repetitions]);

1975

%reshape into single column (actual repetitions)

1975

%reshape into single column (actual repetitions)

1976

C=reshape(B',[numel(B) 1]);

1976

C=reshape(B',[numel(B) 1]);

1977

%repeat the single column to build the entire length required

1977

%repeat the single column to build the entire length required

1978

num_repeats=num_cases/length(C);

1978

num_repeats=num_cases/length(C);

1979

D=repmat(C,[num_repeats 1]);

1979

D=repmat(C,[num_repeats 1]);

1980

out(:,k)=D;

1980

out(:,k)=D;

1981

%determine how many repetitions the next column needs

1981

%determine how many repetitions the next column needs

1982

num_repetitions=num_repetitions*length(this_column);

1982

num_repetitions=num_repetitions*length(this_column);

1983

end

1983

end

1984

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1984

function pdf=Init_PDF_Fast( EmptyPDF, values, probs)

1985

% p=cpdf(type, ...)

1985

% p=cpdf(type, ...)

1986

%

1986

%

1987

% CPDF is a probability mass function for discrete distributions or an

1987

% CPDF is a probability mass function for discrete distributions or an

1988

% approxmation of a PDF for continuous distributions.

1988

% approxmation of a PDF for continuous distributions.

1989

%

1989

%

1990

% cpdf is internally normalized so that the sum of probabilities is 1

1990

% cpdf is internally normalized so that the sum of probabilities is 1

1991

% (regardless of bin size).

1991

% (regardless of bin size).

1992

1992

1993

% Internal fields:

1993

% Internal fields:

1994

% Min: *bin number* of minimum value.

1994

% Min: *bin number* of minimum value.

1995

% BinSize: size of PDF bins. Bin center is the representative value.

1995

% BinSize: size of PDF bins. Bin center is the representative value.

1996

% Vec: vector of probabilities per bin.

1996

% Vec: vector of probabilities per bin.

1997

1997

1998

pdf=EmptyPDF;

1998

pdf=EmptyPDF;

1999

1999

2000

rounded_values_div_binsize=round(values/pdf.BinSize);

2000

rounded_values_div_binsize=round(values/pdf.BinSize);

2001

%values=pdf.BinSize*rounded_values_div_binsize;

2001

%values=pdf.BinSize*rounded_values_div_binsize;

2002

2002

2003

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2003

% %speed up for small values round to 0 (because they are all much smaller than binsize)

2004

% if all(values==0)

2004

% if all(values==0)

2005

% return;

2005

% return;

2006

% end

2006

% end

2007

%

2007

%

2008

% %speed up for all values rounded to the same bin

2008

% %speed up for all values rounded to the same bin

2009

% %The output pdf is the same as the

2009

% %The output pdf is the same as the

2010

% %empty pdf, but the x value is non-zero (but still scalar)

2010

% %empty pdf, but the x value is non-zero (but still scalar)

2011

% if all(values==values(1))

2011

% if all(values==values(1))

2012

% pdf.Min=rounded_values_div_binsize(1);

2012

% pdf.Min=rounded_values_div_binsize(1);

2013

% pdf.x=values(1);

2013

% pdf.x=values(1);

2014

% return;

2014

% return;

2015

% end

2015

% end

2016

%

2016

%

2017

% %The code below requires that values is

2017

% %The code below requires that values is

2018

% %sorted. Generally this should be true, but check to be sure

2018

% %sorted. Generally this should be true, but check to be sure

2019

% if ~issorted(values)

2019

% if ~issorted(values)

2020

% [values,si]=sort(values);

2020

% [values,si]=sort(values);

2021

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2021

% rounded_values_div_binsize=rounded_values_div_binsize(si);

2022

% probs=probs(si);

2022

% probs=probs(si);

2023

% end

2023

% end

2024

2024

2025

2025

2026

%pdf.x=values(1):pdf.BinSize:values(end);

2026

%pdf.x=values(1):pdf.BinSize:values(end);

2027

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2027

pdf.x=pdf.BinSize*rounded_values_div_binsize(1):pdf.BinSize:pdf.BinSize*rounded_values_div_binsize(end);

2028

pdf.Min=rounded_values_div_binsize(1);

2028

pdf.Min=rounded_values_div_binsize(1);

2029

2029

2030

pdf.y=zeros(size(pdf.x));

2030

pdf.y=zeros(size(pdf.x));

2031

%The rounded values divided by binsize will reveal the bin number if

2031

%The rounded values divided by binsize will reveal the bin number if

2032

%pdf.Min is subtracted from it

2032

%pdf.Min is subtracted from it

2033

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2033

bin_placement=rounded_values_div_binsize-pdf.Min+1;

2034

%Can avoid one addition by inserting the first probability

2034

%Can avoid one addition by inserting the first probability

2035

%actually helps when calling this 2 million times

2035

%actually helps when calling this 2 million times

2036

pdf.y(bin_placement(1))=probs(1);

2036

pdf.y(bin_placement(1))=probs(1);

2037

for k=2:length(values)

2037

for k=2:length(values)

2038

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2038

pdf.y(bin_placement(k)) = pdf.y(bin_placement(k))+probs(k);

2039

end

2039

end

2040

2040

2041

2041

2042

%Have already ensured that sum(pdf.y)=1

2042

%Have already ensured that sum(pdf.y)=1

2043

%pdf.y=pdf.y/sum(pdf.y);

2043

%pdf.y=pdf.y/sum(pdf.y);

2044

2044

2045

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2045

% if any(~isreal(pdf.y)) || any(pdf.y<0)

2046

% error('PDF must be real and nonnegative');

2046

% error('PDF must be real and nonnegative');

2047

% end

2047

% end

2048

2048

2049

% pMax=pdf.Min+length(pdf.y)-1;

2049

% pMax=pdf.Min+length(pdf.y)-1;

2050

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2050

% pdf.x = values(1):pdf.BinSize:pMax*pdf.BinSize;

2051

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2051

function [MLSE_results] = MLSE(param,alpha,A_s,A_ni,PDF,CDF)

2052

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2052

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2053

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2053

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2054

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2054

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2055

2055

2056

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2056

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2057

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2057

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2058

2058

2059

%% step 0

2059

%% step 0

2060

COM_from_matlab=20*log10(A_s/A_ni);

2060

COM_from_matlab=20*log10(A_s/A_ni);

2061

L=param.levels;

2061

L=param.levels;

2062

DER0=param.specBER;

2062

DER0=param.specBER;

2063

%% step 1 from slide 6/5

2063

%% step 1 from slide 6/5

2064

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2064

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2065

main=A_peak;

2065

main=A_peak;

2066

k_DER=qfuncinv(param.specBER);

2066

k_DER=qfuncinv(param.specBER);

2067

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2067

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2068

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2068

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2069

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2069

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2070

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2070

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2071

if A_s >= A_ni

2071

if A_s >= A_ni

2072

%% step 2 slide 10/8

2072

%% step 2 slide 10/8

2073

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2073

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2074

%% step 2 slide 10/8

2074

%% step 2 slide 10/8

2075

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2075

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2076

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2076

% DER_DFE_CDF=2/ ( L/(L-1)-CDF_ev( (1-2*alpha)*main/(L-1),PDF,CDF ) )*CDF_ev((main/(L-1)),PDF,CDF);

2077

%% step 3 side 11/9

2077

%% step 3 side 11/9

2078

j=1:200;

2078

j=1:200;

2079

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2079

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2080

DER_MLSE_CDF=0; jj=1;

2080

DER_MLSE_CDF=0; jj=1;

2081

DER_delta = inf;

2081

DER_delta = inf;

2082

while DER_delta > .001

2082

while DER_delta > .001

2083

last_DER_MLSE_CDF=DER_MLSE_CDF;

2083

last_DER_MLSE_CDF=DER_MLSE_CDF;

2084

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2084

DER_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;

2085

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2085

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2086

jj=jj+1;

2086

jj=jj+1;

2087

end

2087

end

2088

%% step 4 slide 12/10

2088

%% step 4 slide 12/10

2089

SNR_DFE_eqivalent=SNR_DFE*(...

2089

SNR_DFE_eqivalent=SNR_DFE*(...

2090

(L-1)*sigma_noise/main * qfuncinv(...

2090

(L-1)*sigma_noise/main * qfuncinv(...

2091

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2091

1/2 *DER_MLSE*(L/(L-1) - qfunc((1-2*alpha)*main/(L-1)*sigma_noise )) ...

2092

) ...

2092

) ...

2093

)^2;

2093

)^2;

2094

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2094

SNR_DFE_eqivalent_CDF=SNR_DFE*(...

2095

(L-1)/main * CDF_inv_ev(...

2095

(L-1)/main * CDF_inv_ev(...

2096

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2096

1/2 *DER_MLSE_CDF*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2097

,PDF, CDF ) ...

2097

,PDF, CDF ) ...

2098

)^2;

2098

)^2;

2099

2099

2100

%% step 5 slide 13/11

2100

%% step 5 slide 13/11

2101

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2101

delta_com=10*log10(SNR_DFE_eqivalent/SNR_DFE);

2102

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2102

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2103

new_com_CDF=COM_from_matlab+delta_com_CDF;

2103

new_com_CDF=COM_from_matlab+delta_com_CDF;

2104

else

2104

else

2105

warning('MLSE not applied because there is more noise than signal')

2105

warning('MLSE not applied because there is more noise than signal')

2106

DER_MLSE=[];

2106

DER_MLSE=[];

2107

DER_MLSE_CDF=[];

2107

DER_MLSE_CDF=[];

2108

SNR_DFE_eqivalent=[];

2108

SNR_DFE_eqivalent=[];

2109

SNR_DFE_eqivalent_CDF=[];

2109

SNR_DFE_eqivalent_CDF=[];

2110

new_com_CDF=COM_from_matlab;

2110

new_com_CDF=COM_from_matlab;

2111

delta_com_CDF=0;

2111

delta_com_CDF=0;

2112

delta_com=0;

2112

delta_com=0;

2113

SNR_DFE=[];

2113

SNR_DFE=[];

2114

end

2114

end

2115

2115

2116

%%

2116

%%

2117

MLSE_results.COM_from_matlab=COM_from_matlab;

2117

MLSE_results.COM_from_matlab=COM_from_matlab;

2118

MLSE_results.SNR_DFE=SNR_DFE;

2118

MLSE_results.SNR_DFE=SNR_DFE;

2119

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2119

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2120

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2120

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2121

MLSE_results.sigma_noise=sigma_noise;

2121

MLSE_results.sigma_noise=sigma_noise;

2122

MLSE_results.SNR_dB=SNR_dB ;

2122

MLSE_results.SNR_dB=SNR_dB ;

2123

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2123

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2124

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2124

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2125

MLSE_results.COM_Gaussian=new_com_CDF;

2125

MLSE_results.COM_Gaussian=new_com_CDF;

2126

MLSE_results.COM_CDF=new_com_CDF;

2126

MLSE_results.COM_CDF=new_com_CDF;

2127

MLSE_results.k_DER=k_DER;

2127

MLSE_results.k_DER=k_DER;

2128

MLSE_results.delta_com_CDF=delta_com_CDF;

2128

MLSE_results.delta_com_CDF=delta_com_CDF;

2129

MLSE_results.delta_com_Gaussian=delta_com;

2129

MLSE_results.delta_com_Gaussian=delta_com;

2130

2130

2131

2131

2132

2132

2133

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2133

function [MLSE_results] = MLSE_U1_c(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2134

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2134

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2135

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2135

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2136

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2136

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2137

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2137

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2138

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2138

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2139

%% step 0

2139

%% step 0

2140

COM_from_matlab=20*log10(A_s/A_ni);

2140

COM_from_matlab=20*log10(A_s/A_ni);

2141

L=param.levels;

2141

L=param.levels;

2142

DER0=param.specBER;

2142

DER0=param.specBER;

2143

%% step 1 from slide 6 shakiba_3dj_01_230116

2143

%% step 1 from slide 6 shakiba_3dj_01_230116

2144

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2144

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2145

main=A_peak;

2145

main=A_peak;

2146

k_DER=qfuncinv(param.specBER);

2146

k_DER=qfuncinv(param.specBER);

2147

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2147

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2148

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2148

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2149

% if A_s >= A_ni

2149

% if A_s >= A_ni

2150

if 1

2150

if 1

2151

%% step 2 slide 10 shakiba_3dj_01_230116

2151

%% step 2 slide 10 shakiba_3dj_01_230116

2152

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2152

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2153

%% step 2 slide 10 not used

2153

%% step 2 slide 10 not used

2154

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2154

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2155

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2155

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2156

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2156

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2157

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2157

S_n=PSD_results.Sn_rho; % total agregate noise PSD

2158

Rn=ifft(S_n)*param.fb;

2158

Rn=ifft(S_n)*param.fb;

2159

Rho_row=Rn/Rn(1);

2159

Rho_row=Rn/Rn(1);

2160

Rn_len=length(Rn);

2160

Rn_len=length(Rn);

2161

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2161

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2162

for j=1:Rn_len

2162

for j=1:Rn_len

2163

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2163

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2164

end

2164

end

2165

rho_noiseEE_row=Rho_row.*alphas_row;

2165

rho_noiseEE_row=Rho_row.*alphas_row;

2166

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2166

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2167

for j=1:Rn_len

2167

for j=1:Rn_len

2168

rho_noiseEE(j,j)=(1-alpha)^2;

2168

rho_noiseEE(j,j)=(1-alpha)^2;

2169

end

2169

end

2170

rho_noiseEE(1,1)=1;

2170

rho_noiseEE(1,1)=1;

2171

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2171

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2172

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2172

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2173

% determine complete matrix

2173

% determine complete matrix

2174

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2174

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2175

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2175

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2176

%% shakiba_3dj_elec_01a_230504 slide 17

2176

%% shakiba_3dj_elec_01a_230504 slide 17

2177

j=1:Rn_len;

2177

j=1:Rn_len;

2178

DER_MLSE=[];

2178

DER_MLSE=[];

2179

DER_MLSE_CDF=0; jj=1;

2179

DER_MLSE_CDF=0; jj=1;

2180

DER_MLSE_CDFold=0;

2180

DER_MLSE_CDFold=0;

2181

DER_delta = inf;

2181

DER_delta = inf;

2182

% slight modified for PAM4 DER vs SER

2182

% slight modified for PAM4 DER vs SER

2183

while DER_delta > .0001 && jj<=Rn_len || jj==1

2183

while DER_delta > .0001 && jj<=Rn_len || jj==1

2184

last_DER_MLSE_CDF=DER_MLSE_CDF;

2184

last_DER_MLSE_CDF=DER_MLSE_CDF;

2185

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2185

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2186

DER_MLSE_CDF= ...

2186

DER_MLSE_CDF= ...

2187

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2187

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2188

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2188

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2189

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2189

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2190

jj=jj+1;

2190

jj=jj+1;

2191

end

2191

end

2192

%% shakiba_3dj_elec_01a_230504 slide 19

2192

%% shakiba_3dj_elec_01a_230504 slide 19

2193

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2193

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2194

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2194

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2195

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2195

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2196

(L-1)/main * CDF_inv_ev(...

2196

(L-1)/main * CDF_inv_ev(...

2197

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2197

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2198

,PDF, CDF ) ...

2198

,PDF, CDF ) ...

2199

)^2;

2199

)^2;

2200

%% step 5 shakiba_3dj_01_230116 slide 13

2200

%% step 5 shakiba_3dj_01_230116 slide 13

2201

delta_com=[];

2201

delta_com=[];

2202

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2202

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2203

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2203

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2204

2205

new_com_CDF=COM_from_matlab+delta_com_CDF;

2204

new_com_CDF=COM_from_matlab+delta_com_CDF;

2206

else

2205

else

2207

warning('MLSE not applied because there is more noise than signal')

2206

warning('MLSE not applied because there is more noise than signal')

2208

DER_MLSE=[];

2207

DER_MLSE=[];

2209

DER_MLSE_CDF=[];

2208

DER_MLSE_CDF=[];

2210

SNR_DFE_eqivalent=[];

2209

SNR_DFE_eqivalent=[];

2211

SNR_DFE_eqivalent_CDF=[];

2210

SNR_DFE_eqivalent_CDF=[];

2212

new_com_CDF=COM_from_matlab;

2211

new_com_CDF=COM_from_matlab;

2213

delta_com_CDF=0;

2212

delta_com_CDF=0;

2214

delta_com=0;

2213

delta_com=0;

2215

SNR_DFE=[];

2214

SNR_DFE=[];

2216

end

2215

end

2217

SNR_DFE_eqivalent=[];

2216

SNR_DFE_eqivalent=[];

2218

%%

2217

%%

2219

MLSE_results.COM_from_matlab=COM_from_matlab;

2218

MLSE_results.COM_from_matlab=COM_from_matlab;

2220

MLSE_results.SNR_DFE=SNR_DFE;

2219

MLSE_results.SNR_DFE=SNR_DFE;

2221

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2220

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2222

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2221

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2223

MLSE_results.sigma_noise=sigma_noise;

2222

MLSE_results.sigma_noise=sigma_noise;

2224

MLSE_results.SNR_dB=SNR_dB ;

2223

MLSE_results.SNR_dB=SNR_dB ;

2225

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2224

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2226

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2225

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2227

MLSE_results.COM_Gaussian=new_com_CDF;

2226

MLSE_results.COM_Gaussian=new_com_CDF;

2228

MLSE_results.COM_CDF=new_com_CDF;

2227

MLSE_results.COM_CDF=new_com_CDF;

2229

MLSE_results.k_DER=k_DER;

2228

MLSE_results.k_DER=k_DER;

2230

MLSE_results.delta_com_CDF=delta_com_CDF;

2229

MLSE_results.delta_com_CDF=delta_com_CDF;

2231

MLSE_results.delta_com_Gaussian=delta_com;

2230

MLSE_results.delta_com_Gaussian=delta_com;

2232

2233

2234

2235

function [MLSE_results] = MLSE_U1_c_178A(param,b,A_s,A_ni,PDF,CDF,PSD_results)

2236

if 1

2237

num_ui=param.num_ui_RXFF_noise;

2238

M=param.samples_per_ui;

2239

L=param.levels;

2240

sigma_X2=(L^2-1)/(3*(L-1)^2);

2241

f_b=param.fb;

2242

end

2243

COM_from_matlab=20*log10(A_s/A_ni);

2244

DER_DFE= 2*(L-1)/L*CDF_ev(A_s,PDF, CDF);

2245

S_ni=PSD_results.Sn_rho;

2246

R_ni=ifft(S_ni)*f_b;

2247

p_scaled_by_b=scalePDF(PDF,b(1));

2248

p_j=conv_fct(PDF,p_scaled_by_b);

2249

p_scaled_by_1mb=scalePDF(PDF,1-b(1));

2250

%

2251

j=1; DER_MLSE=0; DER_MLSE_j= inf;

2252

P_j.y=cumsum(p_j.y);

2253

smallest_relative_change=.0001;

2254

%% 178A–37

2255

rou=R_ni'/R_ni(1);

2256

if DER_DFE <= param.DER_CDR

2257

while j <= floor(num_ui/2) && DER_MLSE_j> DER_MLSE*smallest_relative_change

2258

u_j=[ 1;(1-b(1))*ones(j-1,1); (-1)^(j+1)*b(1) ] ;% Eq slide (178A–38)

2259

u_j(2:2:end-1)=-u_j(2:2:end-1);

2260

% V_j=toeplitz(R_ni(1:j+1).'/R_ni(1));

2261

V_j=toeplitz(rou(1:j+1));

2262

P_j=cumsum(p_j.y);

2263

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-CDF)

2264

% 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)

2265

DER_MLSE=DER_MLSE+DER_MLSE_j;

2266

p_j=conv_fct(p_j,p_scaled_by_1mb);

2267

j=j+1;

2268

end

2269

%% Eq (178A–36) a

2270

delta_com=20*log10(1/A_s *-CDF_inv_ev ( DER_MLSE,PDF,CDF ) )- param.Q ;% shakiba_3dj_01_2405

2271

% delta_com=20*log10(1/A_s *-CDF_inv_ev ( 2/3*DER_MLSE,PDF,CDF ) )- param.Q ;% (178A–36)

2272

new_com=COM_from_matlab+delta_com;

2273

else

2274

warning('MLSE not applied because the DER is less than that required for the CDR to lock')

2275

DER_MLSE=NaN;

2276

new_com=COM_from_matlab;

2277

delta_com=0;

2278

delta_com=0;

2279

end

2280

2281

%%

2282

MLSE_results.COM_from_matlab=COM_from_matlab;

2283

MLSE_results.DER_MLSE=DER_MLSE;

2284

MLSE_results.DER_DFE=DER_DFE;

2285

MLSE_results.COM=new_com;

2286

MLSE_results.delta_com=delta_com;

2287

2231

2288

2232

2289

2233

2290

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2234

function [MLSE_results] = MLSE_U3(param,alpha,A_s,A_ni,PDF,CDF,PSD_results)

2291

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2235

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2292

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2236

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2293

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2237

% Based IEEE802.3dj presenations shakiba_3dj_01_230116 and shakiba_3dj_elec_01a_230504

2294

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2238

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2295

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2239

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2296

%% step 0

2240

%% step 0

2297

COM_from_matlab=20*log10(A_s/A_ni);

2241

COM_from_matlab=20*log10(A_s/A_ni);

2298

L=param.levels;

2242

L=param.levels;

2299

DER0=param.specBER;

2243

DER0=param.specBER;

2300

%% step 1 from slide 6 shakiba_3dj_01_230116

2244

%% step 1 from slide 6 shakiba_3dj_01_230116

2301

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2245

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2302

main=A_peak;

2246

main=A_peak;

2303

k_DER=qfuncinv(param.specBER);

2247

k_DER=qfuncinv(param.specBER);

2304

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2248

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2305

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2249

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2306

% if A_s >= A_ni

2250

% if A_s >= A_ni

2307

if 1

2251

if 1

2308

%% step 2 slide 10 shakiba_3dj_01_230116

2252

%% step 2 slide 10 shakiba_3dj_01_230116

2309

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2253

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2310

%% step 2 slide 10 not used

2254

%% step 2 slide 10 not used

2311

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2255

% DER_DFE= 2/ ( L/(L-1) -qfunc( (1-2*alpha)*main/(L-1)/sigma_noise ) )*(qfunc(main/(L-1)/sigma_noise));

2312

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2256

DER_DFE_CDF=2*(L-1)/L*(CDF_ev(main/(L-1),PDF,CDF ) );

2313

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2257

%% step 3 side 18 shakiba_3dj_elec_01a_230504

2314

S_n=PSD_results.S_n; % total agregate noise PSD

2258

S_n=PSD_results.S_n; % total agregate noise PSD

2315

Rn=ifft(S_n)*param.fb;

2259

Rn=ifft(S_n)*param.fb;

2316

Rho_row=Rn/Rn(1);

2260

Rho_row=Rn/Rn(1);

2317

Rn_len=length(Rn);

2261

Rn_len=length(Rn);

2318

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2262

alphas_row=[ 1 ones(1,Rn_len-2)*(1-alpha) alpha];

2319

for j=1:Rn_len

2263

for j=1:Rn_len

2320

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2264

alphas_row(j)=alphas_row(j)*(-1)^(j+1);

2321

end

2265

end

2322

rho_noiseEE_row=Rho_row.*alphas_row;

2266

rho_noiseEE_row=Rho_row.*alphas_row;

2323

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2267

rho_noiseEE=toeplitz(rho_noiseEE_row,rho_noiseEE_row);

2324

for j=1:Rn_len

2268

for j=1:Rn_len

2325

rho_noiseEE(j,j)=(1-alpha)^2;

2269

rho_noiseEE(j,j)=(1-alpha)^2;

2326

end

2270

end

2327

rho_noiseEE(1,1)=1;

2271

rho_noiseEE(1,1)=1;

2328

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2272

rho_noiseEE(Rn_len,Rn_len)=alpha^2;

2329

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2273

rho_noiseEE=rho_noiseEE*sigma_noise^2;

2330

% determine complete matrix

2274

% determine complete matrix

2331

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2275

PDFnoiseiEE=(conv_fct( scalePDF(PDF,(1-alpha) ) , scalePDF( PDF,alpha) ));

2332

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2276

CDFnoiseiEE=cumsum(PDFnoiseiEE.y);

2333

%% shakiba_3dj_elec_01a_230504 slide 17

2277

%% shakiba_3dj_elec_01a_230504 slide 17

2334

j=1:Rn_len;

2278

j=1:Rn_len;

2335

DER_MLSE=[];

2279

DER_MLSE=[];

2336

DER_MLSE_CDF=0; jj=1;

2280

DER_MLSE_CDF=0; jj=1;

2337

DER_MLSE_CDFold=0;

2281

DER_MLSE_CDFold=0;

2338

DER_delta = inf;

2282

DER_delta = inf;

2339

% slight modified for PAM4 DER vs SER

2283

% slight modified for PAM4 DER vs SER

2340

while DER_delta > .0001 && jj<=Rn_len || jj==1

2284

while DER_delta > .0001 && jj<=Rn_len || jj==1

2341

last_DER_MLSE_CDF=DER_MLSE_CDF;

2285

last_DER_MLSE_CDF=DER_MLSE_CDF;

2342

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2286

rho_noiseJEE=rho_noiseEE(1:jj,1:jj);

2343

DER_MLSE_CDF= ...

2287

DER_MLSE_CDF= ...

2344

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2288

2*( (L-1)/L )^jj *( CDF_ev( main/(L-1) * sqrt(trace(rho_noiseJEE))/sqrt(sum(sum((rho_noiseJEE))))*3/2 ,PDF,CDF) )+DER_MLSE_CDF;

2345

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2289

DER_MLSE_CDFold=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDFold;

2346

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2290

DER_delta= abs(last_DER_MLSE_CDF-DER_MLSE_CDF)/DER_MLSE_CDF;

2347

jj=jj+1;

2291

jj=jj+1;

2348

end

2292

end

2349

%% shakiba_3dj_elec_01a_230504 slide 19

2293

%% shakiba_3dj_elec_01a_230504 slide 19

2350

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2294

SNR_DFE_eqivalent_CDF=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1/2*L/(L-1)*DER_MLSE_CDF ,PDFnoiseiEE, CDFnoiseiEE) )^2 ;

2351

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2295

% SNR_DFE_eqivalent_CDF1=SNR_DFE*( (L-1)/main * CDF_inv_ev( 1-1/2*L/(L-1)*DER_MLSE_CDF1 ,PDF, CDF ) )^2 ;

2352

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2296

SNR_DFE_eqivalent_CDFold=SNR_DFE*(...

2353

(L-1)/main * CDF_inv_ev(...

2297

(L-1)/main * CDF_inv_ev(...

2354

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2298

1/2 *DER_MLSE_CDFold*(L/(L-1) - CDF_ev((1-2*alpha)*main/(L-1),PDF,CDF )) ...

2355

,PDF, CDF ) ...

2299

,PDF, CDF ) ...

2356

)^2;

2300

)^2;

2357

%% step 5 shakiba_3dj_01_230116 slide 13

2301

%% step 5 shakiba_3dj_01_230116 slide 13

2358

delta_com=[];

2302

delta_com=[];

2359

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2303

delta_com_CDF=10*log10(SNR_DFE_eqivalent_CDF/SNR_DFE);

2360

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2304

delta_com_CDFold=10*log10(SNR_DFE_eqivalent_CDFold/SNR_DFE);

2361

new_com_CDF=COM_from_matlab+delta_com_CDF;

2305

new_com_CDF=COM_from_matlab+delta_com_CDF;

2362

else

2306

else

2363

warning('MLSE not applied because there is more noise than signal')

2307

warning('MLSE not applied because there is more noise than signal')

2364

DER_MLSE=[];

2308

DER_MLSE=[];

2365

DER_MLSE_CDF=[];

2309

DER_MLSE_CDF=[];

2366

SNR_DFE_eqivalent=[];

2310

SNR_DFE_eqivalent=[];

2367

SNR_DFE_eqivalent_CDF=[];

2311

SNR_DFE_eqivalent_CDF=[];

2368

new_com_CDF=COM_from_matlab;

2312

new_com_CDF=COM_from_matlab;

2369

delta_com_CDF=0;

2313

delta_com_CDF=0;

2370

delta_com=0;

2314

delta_com=0;

2371

SNR_DFE=[];

2315

SNR_DFE=[];

2372

end

2316

end

2373

SNR_DFE_eqivalent=[];

2317

SNR_DFE_eqivalent=[];

2374

%%

2318

%%

2375

MLSE_results.COM_from_matlab=COM_from_matlab;

2319

MLSE_results.COM_from_matlab=COM_from_matlab;

2376

MLSE_results.SNR_DFE=SNR_DFE;

2320

MLSE_results.SNR_DFE=SNR_DFE;

2377

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2321

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2378

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2322

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2379

MLSE_results.sigma_noise=sigma_noise;

2323

MLSE_results.sigma_noise=sigma_noise;

2380

MLSE_results.SNR_dB=SNR_dB ;

2324

MLSE_results.SNR_dB=SNR_dB ;

2381

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2325

MLSE_results.SNR_DFE_eqivalent_Gaussian=SNR_DFE_eqivalent;

2382

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2326

MLSE_results.SNR_DFE_eqivalent_CDF=SNR_DFE_eqivalent_CDF;

2383

MLSE_results.COM_Gaussian=new_com_CDF;

2327

MLSE_results.COM_Gaussian=new_com_CDF;

2384

MLSE_results.COM_CDF=new_com_CDF;

2328

MLSE_results.COM_CDF=new_com_CDF;

2385

MLSE_results.k_DER=k_DER;

2329

MLSE_results.k_DER=k_DER;

2386

MLSE_results.delta_com_CDF=delta_com_CDF;

2330

MLSE_results.delta_com_CDF=delta_com_CDF;

2387

MLSE_results.delta_com_Gaussian=delta_com;

2331

MLSE_results.delta_com_Gaussian=delta_com;

2388

2332

2389

2333

2390

2334

2391

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2335

function [MLSE_results] = MLSE_instu(param,alpha,A_s,A_ni,PDF,CDF)

2392

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2336

% OP.MLSE= 1 ... COM and VEC will be adjusted with MLSE CDF

2393

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2337

% OP.MLSE= 2 ... COM and VEC will be adjusted with MLSE Gaussian assumptions

2394

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2338

% Based on oif2022.580.00 / IEEE802. shakiba_3dj_01_230116 by Hossein Shakiba

2395

2339

2396

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2340

qfuncinv = @(x) sqrt(2)*erfcinv(2*x);

2397

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2341

qfunc = @(x) 0.5*erfc(x/sqrt(2));

2398

2342

2399

%% step 0

2343

%% step 0

2400

COM_from_matlab=20*log10(A_s/A_ni);

2344

COM_from_matlab=20*log10(A_s/A_ni);

2401

L=param.levels;

2345

L=param.levels;

2402

DER0=param.specBER;

2346

DER0=param.specBER;

2403

%% step 1 from slide 6/5

2347

%% step 1 from slide 6/5

2404

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2348

A_peak=(L-1)*A_s; % slide 6 A_s is main in appendix a

2405

main=A_peak;

2349

main=A_peak;

2406

k_DER=qfuncinv(param.specBER);

2350

k_DER=qfuncinv(param.specBER);

2407

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2351

sigma_noise=sqrt(sum(PDF.y.*PDF.x.^2));

2408

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2352

SNR_dB=10*log10( 1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2) ;

2409

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2353

COM=SNR_dB-10*log10((L^2-1)/3*k_DER^2);

2410

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2354

% sprintf('COM from Matlab %g dB\n COM from slide 6 using Gaussian asumptions %g dB\n', COM_from_matlab ,COM)

2411

if A_s >= A_ni

2355

if A_s >= A_ni

2412

%% step 2 slide 10/8

2356

%% step 2 slide 10/8

2413

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2357

SNR_DFE=1/3*(L+1)/(L-1)*(A_peak^2)/sigma_noise^2;

2414

%% step 2 slide 10/8

2358

%% step 2 slide 10/8

2415

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2359

snr_dfe = @(der,PDF,CDF) -10*log10((A_s./CDF_inv_ev(der,PDF,CDF)).^2)+10*log10((L^2-1)/3*qfuncinv(der).^2) ;

2416

2360

2417

%% step 3 side 11/9

2361

%% step 3 side 11/9

2418

j=1:200;

2362

j=1:200;

2419

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2363

DER_MLSE=2*sum( j .* ((L-1)/L).^j .* qfunc( sqrt(1+(j-1)*(1-alpha)^2+alpha^2).* main/((L-1)*sigma_noise ) ));

2420

DER_MLSE_CDF=0; jj=1;

2364

DER_MLSE_CDF=0; jj=1;

2421

DER_delta = inf;

2365

DER_delta = inf;

2422

while DER_delta > .001

2366

while DER_delta > .001

2423

last_DER_MLSE_CDF=DER_MLSE_CDF;

2367

last_DER_MLSE_CDF=DER_MLSE_CDF;

2424

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2368

DER_MLSE_CDF=2*( jj .* ((L-1)/L).^jj .* CDF_ev( sqrt(1+(jj-1)*(1-alpha)^2+alpha^2).* main/((L-1) ),PDF,CDF ))+DER_MLSE_CDF;

2425

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2369

DER_delta= 1-last_DER_MLSE_CDF/DER_MLSE_CDF;

2426

jj=jj+1;

2370

jj=jj+1;

2427

end

2371

end

2428

%%

2372

%%

2429

dscale=.05;

2373

dscale=.05;

2430

scale=1;

2374

scale=1;

2431

last_scale_tune=inf;

2375

last_scale_tune=inf;

2432

scale_tune=inf;

2376

scale_tune=inf;

2433

while abs(scale_tune) >= .1

2377

while abs(scale_tune) >= .1

2434

istart=-PDF.Min+1;

2378

istart=-PDF.Min+1;

2435

scale=scale-dscale;

2379

scale=scale-dscale;

2436

PDF_SCALED = scalePDF(PDF,scale);

2380

PDF_SCALED = scalePDF(PDF,scale);

2437

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2381

cdf_scaled=pdf_to_cdf(PDF_SCALED);

2438

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2382

test_snr=snr_dfe(DER_MLSE_CDF,PDF_SCALED,cdf_scaled.y);

2439

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2383

test_DER=2*(L-1)/L* (CDF_ev(main/(L-1),PDF_SCALED,cdf_scaled.y) );

2440

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2384

scale_tune=(test_DER-DER_MLSE_CDF)/DER_MLSE_CDF;

2441

if sign(scale_tune) ~= sign(last_scale_tune)

2385

if sign(scale_tune) ~= sign(last_scale_tune)

2442

% scale=scale+dscale % back up

2386

% scale=scale+dscale % back up

2443

dscale=-dscale/2;

2387

dscale=-dscale/2;

2444

end

2388

end

2445

last_scale_tune=scale_tune;

2389

last_scale_tune=scale_tune;

2446

end

2390

end

2447

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2391

new_com_CDF=10*log10((A_s./CDF_inv_ev(DER0,PDF_SCALED,cdf_scaled.y)).^2);

2448

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2392

delta_com=new_com_CDF-10*log10((A_s./CDF_inv_ev(DER0,PDF,CDF)).^2);

2449

else

2393

else

2450

warning('MLSE not applied because there is more noise than signal')

2394

warning('MLSE not applied because there is more noise than signal')

2451

DER_MLSE=[];

2395

DER_MLSE=[];

2452

DER_MLSE_CDF=[];

2396

DER_MLSE_CDF=[];

2453

SNR_DFE_eqivalent=[];

2397

SNR_DFE_eqivalent=[];

2454

SNR_DFE_eqivalent_CDF=[];

2398

SNR_DFE_eqivalent_CDF=[];

2455

new_com_CDF=COM_from_matlab;

2399

new_com_CDF=COM_from_matlab;

2456

delta_com_CDF=0;

2400

delta_com_CDF=0;

2457

delta_com=0;

2401

delta_com=0;

2458

SNR_DFE=[];

2402

SNR_DFE=[];

2459

PDF_SCALED=[];

2403

PDF_SCALED=[];

2460

cdf_scaled=[];

2404

cdf_scaled=[];

2461

end

2405

end

2462

2406

2463

%%

2407

%%

2464

MLSE_results.COM_from_matlab=COM_from_matlab;

2408

MLSE_results.COM_from_matlab=COM_from_matlab;

2465

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2409

MLSE_results.DER_MLSE_Gaussian=DER_MLSE;

2466

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2410

MLSE_results.DER_MLSE_CDF=DER_MLSE_CDF;

2467

MLSE_results.sigma_noise=sigma_noise;

2411

MLSE_results.sigma_noise=sigma_noise;

2468

MLSE_results.k_DER=k_DER;

2412

MLSE_results.k_DER=k_DER;

2469

MLSE_results.COM_CDF=new_com_CDF;

2413

MLSE_results.COM_CDF=new_com_CDF;

2470

MLSE_results.delta_com_CDF=delta_com;

2414

MLSE_results.delta_com_CDF=delta_com;

2471

MLSE_results.delta_com_Gaussian=delta_com;

2415

MLSE_results.delta_com_Gaussian=delta_com;

2472

MLSE_results.PDF=PDF_SCALED;

2416

MLSE_results.PDF=PDF_SCALED;

2473

MLSE_results.CDF=cdf_scaled.y;

2417

MLSE_results.CDF=cdf_scaled.y;

2474

MLSE_results.PDF_scale=scale;

2418

MLSE_results.PDF_scale=scale;

2475

2419

2476

2420

2477

2421

2478

2422

2479

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2423

function MMSE_results = MMSE(PSD_results,sbr, cursor_i ,param, OP )

2480

if 1

2424

if 1

2481

num_ui=param.num_ui_RXFF_noise;

2425

num_ui=param.num_ui_RXFF_noise;

2482

M=param.samples_per_ui;

2426

M=param.samples_per_ui;

2483

L=param.levels;

2427

L=param.levels;

2484

sigma_X2=(L^2-1)/(3*(L-1)^2);

2428

sigma_X2=(L^2-1)/(3*(L-1)^2);

2485

fb=param.fb;

2429

fb=param.fb;

2486

R_LM=param.R_LM;

2430

R_LM=param.R_LM;

2487

end

2431

end

2488

% h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2432

h=sbr(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

2489

% h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2433

h=sbr(mod(cursor_i - 1,M)+1:end); % align to sample point % from Tobey (Pei-Rong Li 02/29/2024)

2490

% h=reshape(h,1,[]); % make row vectors

2434

h=reshape(h,1,[]); % make row vectors

2491

% h=[ h(1:floor(length(h)/M)*M) ];

2435

h=[ h(1:floor(length(h)/M)*M) ];

2492

% h= [h zeros(1,num_ui*M-length(h)) ];

2436

h= [h zeros(1,num_ui*M-length(h)) ];

2493

% h=h(1:M:end);% resample

2437

h=h(1:M:end);% resample

2494

% N=length(h);

2438

N=length(h);

2495

% dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2439

dw=param.RxFFE_cmx ; % equalizer precuror tapsindx(1:N)=(1:N)-5-1;

2496

% dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2440

dh=(cursor_i-mod(cursor_i,M))/M ; % precuror taps in h

2497

2498

samp_idx = (mod(cursor_i-1,M )+1):M:length(sbr);

2499

dh= find(samp_idx == cursor_i)-1;

2500

dw=param.RxFFE_cmx;

2501

h = reshape(sbr(samp_idx),1,[]); % make row vector

2502

h(end+1:num_ui)=0;

2503

h = h(1:num_ui); % h needs to have num_ui points

2504

N=length(h); % used in subsequent expressions

2505

2506

if param.N_bg == 0

2441

if param.N_bg == 0

2507

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2442

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2508

bmax=param.bmax;

2443

bmax=param.bmax;

2509

bmin=param.bmin ;

2444

bmin=param.bmin ;

2510

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2445

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2511

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2446

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ];

2512

idx=[];

2447

idx=[];

2513

else

2448

else

2514

Nfloating_taps=param.N_bf*param.N_bg;

2449

Nfloating_taps=param.N_bf*param.N_bg;

2515

Nmax=param.N_bmax;

2450

Nmax=param.N_bmax;

2516

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2451

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2517

Ng=param.N_bg;

2452

Ng=param.N_bg;

2518

Nf=param.N_bf;

2453

Nf=param.N_bf;

2519

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2454

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2520

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2455

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2521

% hisi=h(dh+2:((dh-dw)+Nw));

2456

% hisi=h(dh+2:((dh-dw)+Nw));

2522

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2457

% [idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,Nf,inf,param.bmaxg,Ng ); % using maximum power in hisi

2523

% idx=sort(idx);

2458

% idx=sort(idx);

2524

bmax=param.bmax;

2459

bmax=param.bmax;

2525

bmin=param.bmin ;

2460

bmin=param.bmin ;

2526

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2461

wmax= [ ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max param.ffe_pre_tap1_max 1.0 param.ffe_post_tap1_max ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max ones(1,Nfloating_taps)*param.bmaxg ];

2527

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2462

wmin= [ -ones(1,param.RxFFE_cmx-1)*param.ffe_tapn_max -param.ffe_pre_tap1_max 1.0 -param.ffe_post_tap1_max -ones(1,param.RxFFE_cpx-1)*param.ffe_tapn_max -ones(1,Nfloating_taps)*param.bmaxg ];

2528

end

2463

end

2529

Nb=param.ndfe; % DFE taps

2464

Nb=param.ndfe; % DFE taps

2530

d=dw+dh; % used for index in algorithms

2465

d=dw+dh; % used for index in algorithms

2531

indx(1:N)=(1:N)-dh-1;

2466

indx(1:N)=(1:N)-dh-1;

2532

S_n=PSD_results.S_n; % total agregate noise PSD

2467

S_n=PSD_results.S_n; % total agregate noise PSD

2533

Rn=ifft(S_n)*fb;

2468

Rn=ifft(S_n)*fb;

2534

%% HH and R

2469

%% HH and R

2535

2470

2536

%Test routine finding rxffe floating taps using best FOM for each bank

2471

%Test routine finding rxffe floating taps using best FOM for each bank

2537

isi_start = dh+2;

2472

isi_start = dh+2;

2538

isi_end = (dh-dw)+Nw;

2473

isi_end = (dh-dw)+Nw;

2539

2540

%check for num_ui too small

2541

if isi_end > length(h)

2542

error('num_ui_RXFF_noise (%d) is too small',num_ui);

2543

end

2544

2545

hc1=[ h zeros(1,Nw-1) ];

2474

hc1=[ h zeros(1,Nw-1) ];

2546

hr1=[ h(1) zeros(1,Nw-1)];

2475

hr1=[ h(1) zeros(1,Nw-1)];

2547

H=toeplitz(hc1,hr1);

2476

H=toeplitz(hc1,hr1);

2548

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2477

Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2549

if param.N_bg ~= 0

2478

if param.N_bg ~= 0

2550

switch lower(OP.RXFFE_FLOAT_CTL)

2479

switch lower(OP.RXFFE_FLOAT_CTL)

2551

case 'isi'

2480

case 'isi'

2552

hisi=h(dh+2:((dh-dw)+Nw));

2481

hisi=h(dh+2:((dh-dw)+Nw));

2553

[idx]=findbankloc( hisi ,param.RxFFE_cpx+1,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2482

[idx]=findbankloc( hisi ,param.N_tail_start,param.N_bmax,param.N_bf,inf,param.bmaxg,param.N_bg ); % using maximum power in hisi

2554

idx=sort(idx);

2483

idx=sort(idx);

2555

otherwise

2484

otherwise

2556

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2485

idx = FOM_rxffe_floating_taps(param,h,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,isi_start,isi_end);

2557

idx=sort(idx);

2486

idx=sort(idx);

2558

end

2487

end

2559

end

2488

end

2560

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2489

[sigma_e,FOM,w,idx] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx);

2561

MMSE_results.sigma_e=sigma_e; %

2490

MMSE_results.sigma_e=sigma_e; %

2562

MMSE_results.FOM=FOM;

2491

MMSE_results.FOM=FOM;

2563

Craw=w/w(dw+1); % returned Rx FFE taps

2492

Craw=w/w(dw+1); % returned Rx FFE taps

2564

% re-align Cmod to floating tap locations

2493

% re-align Cmod to floating tap locations

2565

if param.N_bg ~= 0

2494

if param.N_bg ~= 0

2566

C=Craw;

2495

C=Craw;

2567

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2496

C(Nfix+1:Nmax+param.ffe_pre_tap_len+1)=0;% from Tobey (Pei-Rong Li 02/28/2024)

2568

C(idx+param.RxFFE_cmx+1 )=Craw(Nfix+(1:Nfloating_taps));

2497

C(idx-param.N_tail_start+1+Nfix)=Craw(Nfix+(1:Nfloating_taps));

2569

else

2498

else

2570

C=Craw;

2499

C=Craw;

2571

end

2500

end

2572

MMSE_results.floating_tap_locations=idx + param.RxFFE_cmx+1;

2501

MMSE_results.floating_tap_locations=idx;

2573

MMSE_results.C=C;

2502

MMSE_results.C=C;

2574

2503

2575

2504

2576

2505

2577

2506

2578

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2507

function [sigma_e,FOM,w,idx,Nw] = MMSE_FOM(param,H,Nb,Rnn,dw,d,wmax,wmin,bmin,bmax,sigma_X2,idx)

2579

if isempty(idx)

2508

if isempty(idx)

2580

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2509

Nw= param.RxFFE_cmx+1+param.RxFFE_cpx; % total number of equalizer taps

2581

bmax=param.bmax;

2510

bmax=param.bmax;

2582

bmin=param.bmin ;

2511

bmin=param.bmin ;

2583

else

2512

else

2584

Nfloating_taps=param.N_bf*param.N_bg;

2513

Nfloating_taps=param.N_bf*param.N_bg;

2585

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2514

%If using the routine that finds RXFFE floating taps bank-by-bank, the number of total floating taps can be less than the final amount

2586

Nfloating_taps = length(idx);

2515

Nfloating_taps = length(idx);

2587

Nmax=param.N_bmax;

2516

Nmax=param.N_bmax;

2588

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2517

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2589

Ng=param.N_bg;

2518

Ng=param.N_bg;

2590

Nf=param.N_bf;

2519

Nf=param.N_bf;

2591

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2520

Nw= dw+Nmax+1;% total span of equalizer taps including floating taps

2592

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2521

Nwft=param.RxFFE_cmx+1+param.RxFFE_cpx+Nfloating_taps;% total number of equalizer taps including floating taps

2593

end

2522

end

2594

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2523

Nfix=param.RxFFE_cmx+1+param.RxFFE_cpx;

2595

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2524

%Rnn=toeplitz(Rn(1:Nw),Rn(1:Nw));

2596

% hc1=[ h zeros(1,Nw-1) ];

2525

% hc1=[ h zeros(1,Nw-1) ];

2597

% hr1=[ h(1) zeros(1,Nw-1)];

2526

% hr1=[ h(1) zeros(1,Nw-1)];

2598

% H=toeplitz(hc1,hr1);

2527

% H=toeplitz(hc1,hr1);

2599

2528

2600

if param.N_bg ~= 0

2529

if param.N_bg ~= 0

2601

H=H( :,[1:Nfix idx+param.RxFFE_cmx+1 ]);

2530

H=H( :,[1:Nfix idx-param.N_tail_start+1+Nfix]); % from Tobey (Pei-Rong Li 02/28/2024)

2602

end

2531

end

2603

%% HH and R

2532

%% HH and R

2604

HH= H'*H;

2533

HH= H'*H;

2605

if param.N_bg ~= 0

2534

if param.N_bg ~= 0

2606

Rnn=Rnn( [1:Nfix idx+param.RxFFE_cmx+1],[1:Nfix idx+param.RxFFE_cmx+1]);

2535

Rnn=Rnn( [1:Nfix idx-param.N_tail_start+1+Nfix],[1:Nfix idx-param.N_tail_start+1+Nfix]);

2607

end

2536

end

2608

R=HH+Rnn/sigma_X2;

2537

R=HH+Rnn/sigma_X2;

2609

%% hb and h0

2538

%% hb and h0

2610

Hb= H(d+2:d+Nb+1,:);

2539

Hb= H(d+2:d+Nb+1,:);

2611

h0=H(d+1,:);

2540

h0=H(d+1,:);

2612

% display(floor(h0));

2541

% display(floor(h0));

2613

2542

2614

%% Ib and zb (slide 10)

2543

%% Ib and zb (slide 10)

2615

ib=eye(Nb);

2544

ib=eye(Nb);

2616

zb=zeros(1,Nb);

2545

zb=zeros(1,Nb);

2617

wbl= [ R -Hb' -h0';...

2546

wbl= [ R -Hb' -h0';...

2618

-Hb ib zb'; ...

2547

-Hb ib zb'; ...

2619

h0 zb 0]\[h0'; zb' ;1];

2548

h0 zb 0]\[h0'; zb' ;1];

2620

2549

2621

%% re-adjust Nw to number of used taps

2550

%% re-adjust Nw to number of used taps

2622

if param.N_bg ~= 0

2551

if param.N_bg ~= 0

2623

Nw=Nwft;

2552

Nw=Nwft;

2624

end

2553

end

2625

%% check equalized pulse

2554

%% check equalized pulse

2626

w=wbl(1:Nw);

2555

w=wbl(1:Nw);

2627

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2556

b=wbl(Nw+1:length(wbl)-1); % dfe taps before limits are applied

2628

2557

2629

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2558

%% apply blim (slide 11) <---- need help here How do I get to RxFFE tap coefficents, C?

2630

blim = min(bmax(:), max(bmin(:), b));

2559

blim = min(bmax(:), max(bmin(:), b));

2631

if (Nb > 0) && ~isequal(b, blim)

2560

if (Nb > 0) && ~isequal(b, blim)

2632

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2561

wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2633

w = wl(1:Nw);

2562

w = wl(1:Nw);

2634

end

2563

end

2635

2564

2636

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2565

%If doing floating RXFFE one bank at a time, the length of w may be less than wmin and wmax

2637

%so need to chop off the extra indices on wmax and wmin

2566

%so need to chop off the extra indices on wmax and wmin

2638

if length(w)<length(wmax)

2567

if length(w)<length(wmax)

2639

wmax=wmax(1:length(w));

2568

wmax=wmax(1:length(w));

2640

wmin=wmin(1:length(w));

2569

wmin=wmin(1:length(w));

2641

end

2570

end

2642

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2571

wlim = min(wmax(:)*w(1+dw), max(wmin(:)*w(1+dw), w));

2643

if ~isequal(w, wlim)

2572

if ~isequal(w, wlim)

2644

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2573

wlim = wlim/(h0*wlim); % Ensure the equalized pulse amplitude is 1.

2645

if Nb > 0

2574

if Nb > 0

2646

b = Hb*wlim; % Update the feedback coefficients.

2575

b = Hb*wlim; % Update the feedback coefficients.

2647

blim = min(bmax(:), max(bmin(:), b));

2576

blim = min(bmax(:), max(bmin(:), b));

2648

end

2577

end

2649

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2578

% wl = [R, -h0'; h0, 0]\[h0'+Hb'*blim; 1];

2650

% wl = wl(1:Nw);

2579

% wl = wl(1:Nw);

2651

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2580

% w = min(wmax(:)*wl(1+dw), max(wmin(:)*wl(1+dw), wl));

2652

end

2581

end

2653

% w=w(1:Nw) ;

2582

% w=w(1:Nw) ;

2654

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2583

% sigma_e=sqrt(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b); % from Tobey (Pei-Rong Li 02/29/2024)

2655

w=wlim;

2584

w=wlim;

2656

b=blim;

2585

b=blim;

2657

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

2586

sigma_e=sqrt(sigma_X2*(w'*R*w+1+b'*b-2*w'*h0'-2*w'*Hb'*b)); % Commit request 4p4_5 from healey_3dj_COM_01_240416

2658

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2587

FOM=20*log10((param.R_LM/(param.levels-1)/sigma_e));

2659

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2588

function output_args=Output_Arg_Fill(output_args,sigma_bn,Noise_Struct,COM_SNR_Struct,param,chdata,fom_result,OP)

2660

2589

2661

%not all output_args are filled here but most are

2590

%not all output_args are filled here but most are

2662

2591

2663

switch lower(OP.TDECQ)

2592

switch lower(OP.TDECQ)

2664

case { false 'none' } % should be the default

2593

case { false 'none' } % should be the default

2665

output_args.VMA=[];

2594

output_args.VMA=[];

2666

case 'vma'

2595

case 'vma'

2667

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2596

est_vma=vma(fom_result.sbr,param.samples_per_ui);

2668

output_args.VMA=est_vma.VMA;

2597

output_args.VMA=est_vma.VMA;

2669

otherwise

2598

otherwise

2670

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2599

error('%s not recognized for Histogram_Window_Weigh this feature is limited',OP.TDECQ)

2671

end

2600

end

2672

2601

2673

fileset_str=str2csv({chdata.base});

2602

fileset_str=str2csv({chdata.base});

2674

output_args.file_names=sprintf('"%s"', fileset_str);

2603

output_args.file_names=sprintf('"%s"', fileset_str);

2675

% [ahealey] Echo the termination parameters in the output arguments..

2604

% [ahealey] Echo the termination parameters in the output arguments..

2676

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2605

for odt_param = {'R_diepad', 'C_diepad', 'L_comp', 'C_bump'}

2677

output_args.(odt_param{:}) = param.(odt_param{:});

2606

output_args.(odt_param{:}) = param.(odt_param{:});

2678

end

2607

end

2679

% [ahealey] End of modifications.

2608

% [ahealey] End of modifications.

2680

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2609

for pkg_params = {'levels', 'Pkg_len_TX', 'Pkg_len_NEXT', 'Pkg_len_FEXT', 'Pkg_len_RX','R_diepad','pkg_Z_c','C_v'}

2681

output_args.(pkg_params{:})= param.(pkg_params{:});

2610

output_args.(pkg_params{:})= param.(pkg_params{:});

2682

end

2611

end

2683

output_args.baud_rate_GHz=param.fb/1e9;

2612

output_args.baud_rate_GHz=param.fb/1e9;

2684

output_args.f_Nyquist_GHz = param.fb/2e9;

2613

output_args.f_Nyquist_GHz = param.fb/2e9;

2685

output_args.BER=param.specBER;

2614

output_args.BER=param.specBER;

2686

output_args.FOM = fom_result.FOM;

2615

output_args.FOM = fom_result.FOM;

2687

output_args.sigma_N=Noise_Struct.sigma_N;

2616

output_args.sigma_N=Noise_Struct.sigma_N;

2688

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2617

output_args.DFE4_RSS=norm(fom_result.DFE_taps(4:end));

2689

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2618

output_args.DFE2_RSS=norm(fom_result.DFE_taps(2:end));

2690

output_args.tail_RSS=fom_result.tail_RSS;

2619

output_args.tail_RSS=fom_result.tail_RSS;

2691

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2620

output_args.channel_operating_margin_dB=COM_SNR_Struct.COM;

2692

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2621

output_args.available_signal_after_eq_mV=1000*COM_SNR_Struct.A_s;

2693

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2622

output_args.peak_uneq_pulse_mV=1000*max(abs(chdata(1).uneq_pulse_response));

2694

try

2623

try

2695

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2624

output_args.uneq_FIR_peak_time=chdata(1).t(chdata(1).uneq_imp_response==max(chdata(1).uneq_imp_response));

2696

catch

2625

catch

2697

output_args.uneq_FIR_peak_time=[];

2626

output_args.uneq_FIR_peak_time=[];

2698

end

2627

end

2699

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2628

output_args.steady_state_voltage_mV = 1000*fom_result.A_f; % RIM 7/03/2019 use peak from optimize_FOM

2700

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2629

its=find(chdata(1).eq_pulse_response>=max(chdata(1).eq_pulse_response),1,'first');

2701

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2630

isumend=min(its+param.N_v*param.samples_per_ui,length(chdata(1).eq_pulse_response));

2702

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2631

output_args.steady_state_voltage_weq_mV = 1000*sum(chdata(1).eq_pulse_response(1:isumend) )/param.samples_per_ui;

2703

2632

2704

if OP.RX_CALIBRATION== 1

2633

if OP.RX_CALIBRATION== 1

2705

output_args.sigma_bn=sigma_bn;

2634

output_args.sigma_bn=sigma_bn;

2706

else

2635

else

2707

output_args.sigma_bn=[];

2636

output_args.sigma_bn=[];

2708

end

2637

end

2709

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2638

output_args.Peak_ISI_XTK_and_Noise_interference_at_BER_mV=1000*COM_SNR_Struct.A_ni;

2710

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2639

output_args.peak_ISI_XTK_interference_at_BER_mV=1000*Noise_Struct.peak_interference_at_BER;

2711

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2640

output_args.peak_ISI_interference_at_BER_mV=1000*Noise_Struct.thru_peak_interference_at_BER;

2712

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2641

output_args.equivalent_ICI_sigma_assuming_PDF_is_Gaussian_mV=Noise_Struct.sci_sigma*1000;

2713

2642

2714

if OP.RX_CALIBRATION == 0

2643

if OP.RX_CALIBRATION == 0

2715

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2644

output_args.peak_MDXTK_interference_at_BER_mV=1000*Noise_Struct.crosstalk_peak_interference_at_BER;

2716

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2645

output_args.peak_MDNEXT_interference_at_BER_mV=1000*Noise_Struct.MDNEXT_peak_interference;

2717

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2646

output_args.peak_MDFEXT_interference_at_BER_mV=1000*Noise_Struct.MDFEXT_peak_interference;

2718

else

2647

else

2719

output_args.peak_MDXTK_interference_at_BER_mV=[];

2648

output_args.peak_MDXTK_interference_at_BER_mV=[];

2720

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2649

output_args.peak_MDNEXT_interference_at_BER_mV=[];

2721

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2650

output_args.peak_MDFEXT_interference_at_BER_mV=[];

2722

end

2651

end

2723

%output_args.ICN_mV=ICN*1000;

2652

%output_args.ICN_mV=ICN*1000;

2724

% output_args.ICN_test_mV=ICN_test*1000;

2653

% output_args.ICN_test_mV=ICN_test*1000;

2725

xtk=param.num_next+param.num_fext;

2654

xtk=param.num_next+param.num_fext;

2726

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2655

if xtk>0 && OP.RX_CALIBRATION ==0 && OP.TDMODE==0

2727

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2656

%output_args.MDNEXT_ICN_92_46_mV=MDNEXT_ICN*1000;

2728

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2657

%output_args.MDFEXT_ICN_92_47_mV=MDFEXT_ICN*1000;

2729

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2658

output_args.equivalent_ICN_assuming_Gaussian_PDF_mV=Noise_Struct.cci_sigma*1000;

2730

else

2659

else

2731

output_args.MDNEXT_ICN_92_46_mV=0;

2660

output_args.MDNEXT_ICN_92_46_mV=0;

2732

output_args.MDFEXT_ICN_92_47_mV=0;

2661

output_args.MDFEXT_ICN_92_47_mV=0;

2733

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2662

output_args.equivalent_ICN_assuming_PDF_is_Gaussian_mV=0;

2734

end

2663

end

2735

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2664

%output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(A_s/(peak_interference_at_BER/qfuncinv(param.specBER))); modified by Yasuo Hidaka, 8/7/17

2736

if 1

2665

if 1

2737

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2666

output_args.SNR_ISI_XTK_normalized_1_sigma=20*log10(COM_SNR_Struct.A_s/(Noise_Struct.peak_interference_at_BER/sqrt(2)/erfcinv(2*param.specBER)));

2738

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2667

output_args.SNR_ISI_est=fom_result.SNR_ISI;

2739

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2668

output_args.Pmax_by_Vf_est=fom_result.Pmax_by_Vf;

2740

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2669

output_args.Tr_measured_from_step_ps=fom_result.Tr_measured_from_step/1e-12;

2741

end

2670

end

2742

2671

2743

2672

2744

switch param.CTLE_type

2673

switch param.CTLE_type

2745

case 'CL93'

2674

case 'CL93'

2746

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2675

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2747

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2676

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2748

output_args.g_DC_HP=[];

2677

output_args.g_DC_HP=[];

2749

output_args.HP_poles_zero=[];

2678

output_args.HP_poles_zero=[];

2750

case 'CL120d'

2679

case 'CL120d'

2751

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2680

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle)];

2752

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2681

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2753

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2682

output_args.g_DC_HP=param.g_DC_HP_values(fom_result.best_G_high_pass);

2754

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2683

output_args.HP_poles_zero=param.f_HP(fom_result.best_G_high_pass);

2755

case 'CL120e'

2684

case 'CL120e'

2756

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2685

output_args.CTLE_zero_poles=[param.CTLE_fz(fom_result.ctle) param.f_HP_Z(fom_result.ctle) param.CTLE_fp2(fom_result.ctle) param.CTLE_fp1(fom_result.ctle) param.f_HP_P(fom_result.ctle)];

2757

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2686

output_args.CTLE_DC_gain_dB=param.ctle_gdc_values(fom_result.ctle);

2758

output_args.g_DC_HP=[];

2687

output_args.g_DC_HP=[];

2759

output_args.HP_poles_zero=[];

2688

output_args.HP_poles_zero=[];

2760

end

2689

end

2761

output_args.TXLE_taps=fom_result.txffe;

2690

output_args.TXLE_taps=fom_result.txffe;

2762

if length(output_args.TXLE_taps) >= 3

2691

if length(output_args.TXLE_taps) >= 3

2763

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2692

output_args.Pre2Pmax = -output_args.TXLE_taps(end-2)/output_args.TXLE_taps(end-1);

2764

else

2693

else

2765

output_args.Pre2Pmax=[];

2694

output_args.Pre2Pmax=[];

2766

end

2695

end

2767

output_args.DFE_taps=fom_result.DFE_taps;

2696

output_args.DFE_taps=fom_result.DFE_taps;

2768

if param.Floating_DFE || param.Floating_RXFFE

2697

if param.Floating_DFE || param.Floating_RXFFE

2769

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2698

output_args.floating_tap_locations=fom_result.floating_tap_locations;

2770

else

2699

else

2771

output_args.floating_tap_locations=[];

2700

output_args.floating_tap_locations=[];

2772

end

2701

end

2773

2702

2774

if OP.RxFFE

2703

if OP.RxFFE

2775

output_args.RxFFE=fom_result.RxFFE;

2704

output_args.RxFFE=fom_result.RxFFE;

2776

output_args.RxFFEgain=param.current_ffegain;

2705

output_args.RxFFEgain=param.current_ffegain;

2777

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2706

else % Yasou Hidaka 11/20/2018 help to align csv file columns

2778

output_args.RxFFE=[];

2707

output_args.RxFFE=[];

2779

output_args.RxFFEgain=[];

2708

output_args.RxFFEgain=[];

2780

end

2709

end

2781

2710

2782

output_args.itick=fom_result.itick;

2711

output_args.itick=fom_result.itick;

2783

2712

2784

% Calculation of error propagation and burst probability

2713

% Calculation of error propagation and burst probability

2785

if OP.nburst>0

2714

if OP.nburst>0

2786

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2715

[p_burst,p_error_propagation]=Burst_Probability_Calc(COM_SNR_Struct,fom_result.DFE_taps,param,OP);

2787

output_args.error_propagation_probability = p_error_propagation;

2716

output_args.error_propagation_probability = p_error_propagation;

2788

output_args.burst_probabilities = p_burst;

2717

output_args.burst_probabilities = p_burst;

2789

else

2718

else

2790

output_args.error_propagation_probability = [];

2719

output_args.error_propagation_probability = [];

2791

output_args.burst_probabilities = [];

2720

output_args.burst_probabilities = [];

2792

end

2721

end

2793

2722

2794

2723

2795

%begin yasuo patch 12/11/2018

2724

%begin yasuo patch 12/11/2018

2796

% collect sigma values to report

2725

% collect sigma values to report

2797

% pdf2sgm() is a function to calculate sigma value from PDF

2726

% pdf2sgm() is a function to calculate sigma value from PDF

2798

% It is added at the end of this file code.

2727

% It is added at the end of this file code.

2799

% I am not sure if an equivalent function already exists.

2728

% I am not sure if an equivalent function already exists.

2800

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2729

output_args.sgm_Ani__isi_xt_noise = pdf2sgm(COM_SNR_Struct.combined_interference_and_noise_pdf);

2801

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2730

output_args.sgm_isi_xt = pdf2sgm(Noise_Struct.isi_and_xtalk_pdf);

2802

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2731

output_args.sgm_noise__gaussian_noise_p_DD = pdf2sgm(Noise_Struct.noise_pdf);

2803

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2732

output_args.sgm_p_DD = pdf2sgm(Noise_Struct.p_DD);

2804

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2733

output_args.sgm_gaussian_noise = pdf2sgm(Noise_Struct.gaussian_noise_pdf);

2805

output_args.sgm_G = Noise_Struct.sigma_G;

2734

output_args.sgm_G = Noise_Struct.sigma_G;

2806

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2735

output_args.sgm_rjit = Noise_Struct.sigma_rjit;

2807

output_args.sgm_N = Noise_Struct.sigma_N;

2736

output_args.sgm_N = Noise_Struct.sigma_N;

2808

output_args.sgm_TX = Noise_Struct.sigma_TX;

2737

output_args.sgm_TX = Noise_Struct.sigma_TX;

2809

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2738

output_args.sgm_isi = pdf2sgm(Noise_Struct.sci_pdf);

2810

if OP.RX_CALIBRATION == 0

2739

if OP.RX_CALIBRATION == 0

2811

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2740

output_args.sgm_xt = pdf2sgm(Noise_Struct.cci_pdf);

2812

else

2741

else

2813

output_args.sgm_xt=[];

2742

output_args.sgm_xt=[];

2814

end

2743

end

2815

% end yasuo patch

2744

% end yasuo patch

2816

2745

2817

% r259 putting COM, VEO and loss last in report

2746

% r259 putting COM, VEO and loss last in report

2818

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2747

% output_args.VEO_normalized = (A_s-A_ni)/A_s;

2819

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2748

output_args.VEC_dB = COM_SNR_Struct.VEC_dB;

2820

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2749

output_args.VEO_mV = COM_SNR_Struct.VEO_mV;

2821

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2750

if OP.RX_CALIBRATION ==0 && OP.EW == 1

2822

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2751

output_args.EW_UI_est=COM_SNR_Struct.EW_UI;

2823

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2752

output_args.eye_contour=COM_SNR_Struct.eye_contour;

2824

output_args.VEO_window_mUI= param.T_O;

2753

output_args.VEO_window_mUI= param.T_O;

2825

else

2754

else

2826

output_args.EW_UI_est=[];

2755

output_args.EW_UI_est=[];

2827

output_args.eye_contour=[];

2756

output_args.eye_contour=[];

2828

output_args.VEO_window_mUI= [];

2757

output_args.VEO_window_mUI= [];

2829

end

2758

end

2830

2759

2831

if sum(param.AC_CM_RMS) ~= 0

2760

if sum(param.AC_CM_RMS) ~= 0

2832

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2761

output_args.sigma_ACCM_at_tp0_mV=chdata(1).sigma_ACCM_at_tp0*1000;

2833

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2762

fprintf(' AC RMS at TP0 = %.3g mV \n',output_args.sigma_ACCM_at_tp0_mV)

2834

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2763

output_args.sigma_AC_CCM_at_rxpkg_output_mV=chdata(1).CD_CM_RMS*1000; %

2835

else

2764

else

2836

output_args.sigma_ACCM_at_tp0_mV=[];

2765

output_args.sigma_ACCM_at_tp0_mV=[];

2837

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2766

output_args.sigma_AC_CCM_at_rxpkg_output_mV=[];

2838

end

2767

end

2839

if OP.MLSE

2768

if OP.MLSE

2840

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2769

output_args.COM_orig=COM_SNR_Struct.COM_orig;

2841

output_args.delta_COM = COM_SNR_Struct.delta_COM;

2842

output_args.DER_DFE= COM_SNR_Struct.DER_DFE;

2843

output_args.DER_MLSE= COM_SNR_Struct.DER_MLSE;

2844

if strcmpi(upper(OP.PHY),'C2M')

2845

output_args.VEC_dB_orig= COM_SNR_Struct.VEC_dB_orig;

2770

output_args.VEC_dB_orig=COM_SNR_Struct.VEC_dB_orig;

2846

output_args.delta_VEC = COM_SNR_Struct.delta_VEC;

2847

output_args.VEC_dB_orig = COM_SNR_Struct.VEC_dB_orig;

2848

output_args.VEC_dB= COM_SNR_Struct.VEC_dB;

2849

end

2850

end

2771

end

2851

%

2772

%

2852

output_args.COM_dB=COM_SNR_Struct.COM;

2773

output_args.COM_dB=COM_SNR_Struct.COM;

2853

% end yasuo patch

2774

% end yasuo patch

2854

% begin yasuo patch 3/18/2019

2775

% begin yasuo patch 3/18/2019

2855

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2776

output_args.DER_thresh = COM_SNR_Struct.threshold_DER;

2856

% end yasuo patch

2777

% end yasuo patch

2857

function [ seq syms syms_nrz ] = PRBS13Q( )

2778

function [ seq syms syms_nrz ] = PRBS13Q( )

2858

%UNTITLED Summary of this function goes here

2779

%UNTITLED Summary of this function goes here

2859

% Detailed explanation goes here

2780

% Detailed explanation goes here

2860

2781

2861

2782

2862

taps = ([13 12 2 1]);

2783

taps = ([13 12 2 1]);

2863

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2784

seed =([0 0 0 0 0 1 0 1 0 1 0 1 1]);

2864

[seq_nrz c] =LFSR(seed,taps);

2785

[seq_nrz c] =LFSR(seed,taps);

2865

seq_nrz=2*(seq_nrz-0.5);

2786

seq_nrz=2*(seq_nrz-0.5);

2866

seq=pam(seq_nrz);

2787

seq=pam(seq_nrz);

2867

% syms=round(2*(seq+1));

2788

% syms=round(2*(seq+1));

2868

syms((round(2*(seq+1))/2==2))=3;

2789

syms((round(2*(seq+1))/2==2))=3;

2869

syms((round(2*(seq+1))/2==1.5))=2;

2790

syms((round(2*(seq+1))/2==1.5))=2;

2870

syms((round(2*(seq+1))/2==.5))=1;

2791

syms((round(2*(seq+1))/2==.5))=1;

2871

syms((round(2*(seq+1))/2==0))=0;

2792

syms((round(2*(seq+1))/2==0))=0;

2872

2793

2873

% syms_nrz=((seq_nrz+1)/2);

2794

% syms_nrz=((seq_nrz+1)/2);

2874

2795

2875

syms_nrz=seq_nrz;

2796

syms_nrz=seq_nrz;

2876

2797

2877

2798

2878

function[seq c]=LFSR(s,t)

2799

function[seq c]=LFSR(s,t)

2879

%s=initial state of LFSR, you can choose any lenght of LFSR

2800

%s=initial state of LFSR, you can choose any lenght of LFSR

2880

%Instruction:==========

2801

%Instruction:==========

2881

%Save LFSR.m in your current directory and type following

2802

%Save LFSR.m in your current directory and type following

2882

%on Command window for simulating 5 bit LFSR with tap [5 2]

2803

%on Command window for simulating 5 bit LFSR with tap [5 2]

2883

%---------------------

2804

%---------------------

2884

%>>s=[1 1 0 0 1]

2805

%>>s=[1 1 0 0 1]

2885

%>>t=[5 2]

2806

%>>t=[5 2]

2886

%>>[seq c] =LFSR(s,t)

2807

%>>[seq c] =LFSR(s,t)

2887

%---------------------------

2808

%---------------------------

2888

%seq = generated sequence

2809

%seq = generated sequence

2889

%c will be matrix containing the states of LFSR raw wise

2810

%c will be matrix containing the states of LFSR raw wise

2890

%

2811

%

2891

%-----------------------------------------------------------

2812

%-----------------------------------------------------------

2892

%If any doubt, confusion or feedback please contact me

2813

%If any doubt, confusion or feedback please contact me

2893

% NIKESH BAJAJ

2814

% NIKESH BAJAJ

2894

% bajaj.nikkey@gmail.com (+91-9915522564)

2815

% bajaj.nikkey@gmail.com (+91-9915522564)

2895

% Asst. Professor at Lovely Profesional University

2816

% Asst. Professor at Lovely Profesional University

2896

% Masters from Aligarh Muslim University,INDIA

2817

% Masters from Aligarh Muslim University,INDIA

2897

%--------------------------------------------------

2818

%--------------------------------------------------

2898

n=length(s);

2819

n=length(s);

2899

c(1,:)=s;

2820

c(1,:)=s;

2900

m=length(t);

2821

m=length(t);

2901

for k=1:2^n-2;

2822

for k=1:2^n-2;

2902

b(1)=xor(s(t(1)), s(t(2)));

2823

b(1)=xor(s(t(1)), s(t(2)));

2903

if m>2;

2824

if m>2;

2904

for i=1:m-2;

2825

for i=1:m-2;

2905

b(i+1)=xor(s(t(i+2)), b(i));

2826

b(i+1)=xor(s(t(i+2)), b(i));

2906

end

2827

end

2907

end

2828

end

2908

j=1:n-1;

2829

j=1:n-1;

2909

s(n+1-j)=s(n-j);

2830

s(n+1-j)=s(n-j);

2910

s(1)=b(m-1);

2831

s(1)=b(m-1);

2911

c(k+1,:)=s;

2832

c(k+1,:)=s;

2912

end

2833

end

2913

seq=c(:,n)';

2834

seq=c(:,n)';

2914

2835

2915

function [ dataout ] = pam( data )

2836

function [ dataout ] = pam( data )

2916

% mapping data usng Grey Coding

2837

% mapping data usng Grey Coding

2917

for i=1:2:floor(length(data)/2)*2

2838

for i=1:2:floor(length(data)/2)*2

2918

if data(i:i+1)==[ -1 -1 ]

2839

if data(i:i+1)==[ -1 -1 ]

2919

dataout(ceil(i/2)) = -1;

2840

dataout(ceil(i/2)) = -1;

2920

elseif data(i:i+1)==[ -1 1 ]

2841

elseif data(i:i+1)==[ -1 1 ]

2921

dataout(ceil(i/2)) = -1/3;

2842

dataout(ceil(i/2)) = -1/3;

2922

elseif data(i:i+1)==[ 1 1 ]

2843

elseif data(i:i+1)==[ 1 1 ]

2923

dataout(ceil(i/2)) = 1/3;

2844

dataout(ceil(i/2)) = 1/3;

2924

elseif data(i:i+1)==[ 1 -1 ]

2845

elseif data(i:i+1)==[ 1 -1 ]

2925

dataout(ceil(i/2)) = 1;

2846

dataout(ceil(i/2)) = 1;

2926

end

2847

end

2927

end

2848

end

2928

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2849

function RILN_TD_struct=RILN_TD(sdd21,RIL,faxis_f2,OP,param,A_T)

2929

db = @(x) 20*log10(abs(x));

2850

db = @(x) 20*log10(abs(x));

2930

disp('computing TD_RILN...')

2851

disp('computing TD_RILN...')

2931

sdd21=squeeze(sdd21);

2852

sdd21=squeeze(sdd21);

2932

if iscolumn(sdd21)

2853

if iscolumn(sdd21)

2933

sdd21=sdd21.';

2854

sdd21=sdd21.';

2934

end

2855

end

2935

RIL=squeeze(RIL);

2856

RIL=squeeze(RIL);

2936

if iscolumn(RIL)

2857

if iscolumn(RIL)

2937

RIL=RIL.';

2858

RIL=RIL.';

2938

end

2859

end

2939

print_for_codereview=1;

2860

print_for_codereview=1;

2940

if exist('OP','var')

2861

if exist('OP','var')

2941

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2862

X=sinc(faxis_f2*param.ui)*param.ui*1e9;

2942

2863

2943

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2864

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

2944

H_bw=Butterworth_Filter(param,faxis_f2,1);

2865

H_bw=Butterworth_Filter(param,faxis_f2,1);

2945

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2866

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

2946

H_tw=Tukey_Window(faxis_f2,param);

2867

H_tw=Tukey_Window(faxis_f2,param);

2947

H_tw=ones(1,length(faxis_f2) );

2868

H_tw=ones(1,length(faxis_f2) );

2948

[RILN_TD_struct.REF.FIR, ...

2869

[RILN_TD_struct.REF.FIR, ...

2949

RILN_TD_struct.REF.t, ...

2870

RILN_TD_struct.REF.t, ...

2950

RILN_TD_struct.REF.causality_correction_dB, ...

2871

RILN_TD_struct.REF.causality_correction_dB, ...

2951

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2872

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2952

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2873

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

2953

[RILN_TD_struct.FIT.FIR, ...

2874

[RILN_TD_struct.FIT.FIR, ...

2954

RILN_TD_struct.FIT.t, ...

2875

RILN_TD_struct.FIT.t, ...

2955

RILN_TD_struct.FIT.causality_correction_dB, ...

2876

RILN_TD_struct.FIT.causality_correction_dB, ...

2956

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2877

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

2957

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2878

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

2958

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2879

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

2959

NrangeUI=1000;

2880

NrangeUI=1000;

2960

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2881

range_end=min(ipeak+param.samples_per_ui*NrangeUI,min(length(RILN_TD_struct.FIT.FIR), length(RILN_TD_struct.REF.FIR) ) ) ;

2961

range=ipeak:range_end;

2882

range=ipeak:range_end;

2962

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2883

RILN_TD_struct.ILN=RILN_TD_struct.FIT.PR(range)-RILN_TD_struct.REF.PR(range);

2963

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2884

RILN_TD_struct.t=RILN_TD_struct.FIT.t(range);

2964

RILN_TD_struct.FOM=-inf;

2885

RILN_TD_struct.FOM=-inf;

2965

RILN_TD_struct.FOM_PDF=-inf;

2886

RILN_TD_struct.FOM_PDF=-inf;

2966

rms_fom=-inf;

2887

rms_fom=-inf;

2967

for im=1:param.samples_per_ui

2888

for im=1:param.samples_per_ui

2968

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2889

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

2969

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2890

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

2970

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2891

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

2971

cdf=pdf; cdf.y=cumsum(pdf.y);

2892

cdf=pdf; cdf.y=cumsum(pdf.y);

2972

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2893

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

2973

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2894

% signal_and_isi_pdf = conv_fct(cursors, pdf);

2974

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2895

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

2975

if print_for_codereview % remove once all checked out

2896

if print_for_codereview % remove once all checked out

2976

h=figure(191);set(gcf,'Tag','COM');

2897

h=figure(191);set(gcf,'Tag','COM');

2977

semilogy(-cdf.x,cdf.y);

2898

semilogy(-cdf.x,cdf.y);

2978

% xlim ([0,-cdf.x(1)])

2899

% xlim ([0,-cdf.x(1)])

2979

ylim([param.specBER 1]);title ('CDF of RILN')

2900

ylim([param.specBER 1]);title ('CDF of RILN')

2980

hold on

2901

hold on

2981

end

2902

end

2982

if rms>rms_fom

2903

if rms>rms_fom

2983

rms_fom=rms;

2904

rms_fom=rms;

2984

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2905

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

2985

RILN_TD_struct.PDF=pdf;

2906

RILN_TD_struct.PDF=pdf;

2986

end

2907

end

2987

end

2908

end

2988

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2909

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

2989

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2910

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

2990

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2911

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

2991

if print_for_codereview % remove once all checked out

2912

if print_for_codereview % remove once all checked out

2992

figure(9003);set(gcf,'Tag','COM');

2913

figure(9003);set(gcf,'Tag','COM');

2993

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2914

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td riln')

2994

hold on

2915

hold on

2995

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2916

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

2996

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2917

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

2997

hold off

2918

hold off

2998

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2919

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

2999

figure(9004);set(gcf,'Tag','COM');

2920

figure(9004);set(gcf,'Tag','COM');

3000

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

2921

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

3001

hold on

2922

hold on

3002

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

2923

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

3003

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

2924

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

3004

grid on

2925

grid on

3005

legend('show')

2926

legend('show')

3006

end

2927

end

3007

end

2928

end

3008

function is_illegal=RXFFE_Illegal(C,param,last_index)

2929

function is_illegal=RXFFE_Illegal(C,param,last_index)

3009

2930

3010

%check if RXFFE taps are illegal

2931

%check if RXFFE taps are illegal

3011

%C = RXFFE taps

2932

%C = RXFFE taps

3012

%param = COM param struct

2933

%param = COM param struct

3013

%last_index is used when computing illegality prior to Backoff. It will be set so taps

2934

%last_index is used when computing illegality prior to Backoff. It will be set so taps

3014

% in the Backoff region are not considered in the legality check.

2935

% in the Backoff region are not considered in the legality check.

3015

2936

3016

%If last index is omitted, set it to length(C)

2937

%If last index is omitted, set it to length(C)

3017

if nargin<3

2938

if nargin<3

3018

last_index=length(C);

2939

last_index=length(C);

3019

end

2940

end

3020

2941

3021

is_illegal=0;

2942

is_illegal=0;

3022

2943

3023

%Check cursor tap

2944

%Check cursor tap

3024

Ccur_i=param.RxFFE_cmx+1;

2945

Ccur_i=param.RxFFE_cmx+1;

3025

if C(Ccur_i) < param.ffe_main_cursor_min

2946

if C(Ccur_i) < param.ffe_main_cursor_min

3026

is_illegal=1;

2947

is_illegal=1;

3027

return;

2948

return;

3028

end

2949

end

3029

2950

3030

%Check postcursors

2951

%Check postcursors

3031

if param.ffe_post_tap_len ~=0

2952

if param.ffe_post_tap_len ~=0

3032

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

2953

if abs(C(Ccur_i +1)) > param.ffe_post_tap1_max

3033

is_illegal=1;

2954

is_illegal=1;

3034

return;

2955

return;

3035

end

2956

end

3036

if (param.ffe_post_tap_len > 1)

2957

if (param.ffe_post_tap_len > 1)

3037

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

2958

if sum(abs(C((Ccur_i +2):last_index)) > param.ffe_tapn_max)

3038

is_illegal=1;

2959

is_illegal=1;

3039

return;

2960

return;

3040

end

2961

end

3041

end

2962

end

3042

end

2963

end

3043

2964

3044

%Check precursors

2965

%Check precursors

3045

if param.ffe_pre_tap_len ~=0

2966

if param.ffe_pre_tap_len ~=0

3046

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

2967

if abs(C(Ccur_i -1)) > param.ffe_pre_tap1_max

3047

is_illegal=1;

2968

is_illegal=1;

3048

return;

2969

return;

3049

end

2970

end

3050

if (param.ffe_pre_tap_len > 1)

2971

if (param.ffe_pre_tap_len > 1)

3051

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

2972

% if sum(abs(C((Ccur_i +2):end)) > param.ffe_tapn_max) , continue; end

3052

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

2973

if sum(abs(C(1:(Ccur_i - 2))) > param.ffe_tapn_max)

3053

is_illegal=1;

2974

is_illegal=1;

3054

return;

2975

return;

3055

end % 11.22.2018 Yasou Hadaka

2976

end % 11.22.2018 Yasou Hadaka

3056

end

2977

end

3057

end

2978

end

3058

function S =R_series2(zref,f,R)

2979

function S =R_series2(zref,f,R)

3059

r=ones(1,length(f))*R;

2980

r=ones(1,length(f))*R;

3060

S.Parameters(1,1,:) = r./(r + 2*zref);

2981

S.Parameters(1,1,:) = r./(r + 2*zref);

3061

S.Parameters(2,2,:) = r./(r + 2*zref);

2982

S.Parameters(2,2,:) = r./(r + 2*zref);

3062

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

2983

S.Parameters(2,1,:) = (2*zref)./(r + 2*zref);

3063

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

2984

S.Parameters(1,2,:) = (2*zref)./(r + 2*zref);

3064

% Sm=sparameters(S.Parameters,f,zref);

2985

% Sm=sparameters(S.Parameters,f,zref);

3065

2986

3066

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

2987

function H_tw=Raised_Cosine_Filter(param,f,use_RC)

3067

2988

3068

if use_RC

2989

if use_RC

3069

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

2990

H_tw = Tukey_Window(f,param ,param.RC_Start, param.RC_end);% add tw filter;

3070

else

2991

else

3071

H_tw=ones(1,length(f));

2992

H_tw=ones(1,length(f));

3072

end

2993

end

3073

function SLD=SL(S,f,R)

2994

function SLD=SL(S,f,R)

3074

% source load impact return loss add to S21

2995

% source load impact return loss add to S21

3075

% S and SLD are the same structure

2996

% S and SLD are the same structure

3076

% S.Parameters

2997

% S.Parameters

3077

% S.Impedance

2998

% S.Impedance

3078

% S.NumPorts

2999

% S.NumPorts

3079

% S.Frequencies

3000

% S.Frequencies

3080

SLD=S; % assign the fields

3001

SLD=S; % assign the fields

3081

zref=100;

3002

zref=100;

3082

if R==0

3003

if R==0

3083

warndlg('Termination should not be set to zero');

3004

warndlg('Termination should not be set to zero');

3084

SLD=S;

3005

SLD=S;

3085

return

3006

return

3086

end

3007

end

3087

3008

3088

if R > zref

3009

if R > zref

3089

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3010

spr =R_series2(zref,f,(R-zref)); % make series sparameter

3090

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3011

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance); % Casdeade

3091

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3012

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3092

combines4p( ...

3013

combines4p( ...

3093

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3014

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3094

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3015

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3095

);

3016

);

3096

elseif R < zref

3017

elseif R < zref

3097

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3018

spr =r_parrelell2(zref,f,-R*zref/(R-zref)); % make parrellel sparameter

3098

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3019

% SLD=sparameters(cascadesparams(S.Parameters,spr.Parameters),f,S.Impedance);

3099

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3020

[ SLD.Parameters(1,1,:), SLD.Parameters(1,2,:), SLD.Parameters(2,1,:), SLD.Parameters(2,2,:)] = ...

3100

combines4p( ...

3021

combines4p( ...

3101

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3022

spr.Parameters(1,1,:), spr.Parameters(1,2,:), spr.Parameters(2,1,:), spr.Parameters(2,2,:),...

3102

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3023

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) ...

3103

);

3024

);

3104

else

3025

else

3105

SLD=S;

3026

SLD=S;

3106

end

3027

end

3107

3028

3108

%%

3029

%%

3109

3030

3110

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3031

function S_RN_of_f = S_RN(f,G_DC,G_DC2,param)

3111

p1=param.CTLE_fp1(1);

3032

p1=param.CTLE_fp1(1);

3112

z1=param.CTLE_fz(1);

3033

z1=param.CTLE_fz(1);

3113

p2=param.CTLE_fp2(1);

3034

p2=param.CTLE_fp2(1);

3114

zlf=param.f_HP(1);

3035

zlf=param.f_HP(1);

3115

plf=param.f_HP(1);

3036

plf=param.f_HP(1);

3116

f_b=param.fb;

3037

f_b=param.fb;

3117

f_r=param.f_r;

3038

f_r=param.f_r;

3118

eta_0=param.eta_0;

3039

eta_0=param.eta_0;

3119

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3040

H_CTF = ( 10^(G_DC/20)+ 1i*f/z1 ) .*( 10^(G_DC2/20) + 1i*f/zlf )./ ( ( 1+1i*f/p1) .* ( 1+1i*f/p2) .* ( 1+1i*f/plf));

3120

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3041

H_R =1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(f_r*f_b));

3121

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3042

S_RN_of_f = eta_0/2.*abs( H_CTF.*H_R).^2; %EQ healey_3dj_01_2401 slide 5

3122

if 0

3043

if 0

3123

figure

3044

figure

3124

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3045

set(gcf, 'tag', 'COM');movegui(gcf,'southeast');

3125

% see if it looks correct

3046

% see if it looks correct

3126

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3047

semilogx(f/1e9, 20*log10( abs( H_CTF.*H_R)) );

3127

ylabel('dB');

3048

ylabel('dB');

3128

xlabel('GHz');

3049

xlabel('GHz');

3129

title( 'H_ctf with H_r')

3050

title( 'H_ctf with H_r')

3130

grid on

3051

grid on

3131

ylim([-30 0])

3052

ylim([-30 0])

3132

end

3053

end

3133

3054

3134

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3055

function [output_args,ERL,min_ERL]=TDR_ERL_Processing(output_args,OP,package_testcase_i,chdata,param)

3135

3056

3136

%Fill TDR data

3057

%Fill TDR data

3137

if package_testcase_i == 1

3058

if package_testcase_i == 1

3138

if OP.TDR

3059

if OP.TDR

3139

output_args.Z11est=chdata(1).TDR11.avgZport;

3060

output_args.Z11est=chdata(1).TDR11.avgZport;

3140

if ~param.FLAG.S2P

3061

if ~param.FLAG.S2P

3141

output_args.Z22est=chdata(1).TDR22.avgZport;

3062

output_args.Z22est=chdata(1).TDR22.avgZport;

3142

else

3063

else

3143

output_args.Z22est=[];

3064

output_args.Z22est=[];

3144

end

3065

end

3145

if OP.AUTO_TFX

3066

if OP.AUTO_TFX

3146

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3067

output_args.tfx_estimate=param.tfx(2);% 11/03/2021 RIM added for nbx estimate

3147

else

3068

else

3148

output_args.tfx_estimate=[];

3069

output_args.tfx_estimate=[];

3149

end

3070

end

3150

else

3071

else

3151

output_args.Z11est=[];

3072

output_args.Z11est=[];

3152

output_args.Z22est=[];

3073

output_args.Z22est=[];

3153

output_args.tfx_estimate=[];

3074

output_args.tfx_estimate=[];

3154

end

3075

end

3155

end

3076

end

3156

3077

3157

% Process ERL

3078

% Process ERL

3158

if package_testcase_i == 1

3079

if package_testcase_i == 1

3159

if OP.ERL

3080

if OP.ERL

3160

output_args.ERL11=chdata(1).TDR11.ERL;

3081

output_args.ERL11=chdata(1).TDR11.ERL;

3161

if ~param.FLAG.S2P

3082

if ~param.FLAG.S2P

3162

output_args.ERL22=chdata(1).TDR22.ERL;

3083

output_args.ERL22=chdata(1).TDR22.ERL;

3163

else

3084

else

3164

output_args.ERL22=[];

3085

output_args.ERL22=[];

3165

end

3086

end

3166

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3087

% output_args.ERL11RMS=chdata(1).TDR11.ERLRMS;

3167

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3088

% if ~param.FLAG.S2P,output_args.ERL22RMS=chdata(1).TDR22.ERLRMS;

3168

else

3089

else

3169

output_args.ERL11=[];

3090

output_args.ERL11=[];

3170

output_args.ERL22=[];

3091

output_args.ERL22=[];

3171

end

3092

end

3172

end

3093

end

3173

if OP.ERL

3094

if OP.ERL

3174

if OP.TDR_W_TXPKG

3095

if OP.TDR_W_TXPKG

3175

min_ERL=output_args.ERL22;

3096

min_ERL=output_args.ERL22;

3176

ERL= [ nan output_args.ERL22 ];

3097

ERL= [ nan output_args.ERL22 ];

3177

else

3098

else

3178

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3099

if ~isfield(output_args,'ERL22') || isempty(output_args.ERL22)

3179

min_ERL=output_args.ERL11;

3100

min_ERL=output_args.ERL11;

3180

ERL= [ output_args.ERL11 nan ];

3101

ERL= [ output_args.ERL11 nan ];

3181

else

3102

else

3182

min_ERL=min(output_args.ERL11,output_args.ERL22);

3103

min_ERL=min(output_args.ERL11,output_args.ERL22);

3183

ERL= [ output_args.ERL11 output_args.ERL22 ];

3104

ERL= [ output_args.ERL11 output_args.ERL22 ];

3184

end

3105

end

3185

end

3106

end

3186

output_args.ERL=min_ERL;

3107

output_args.ERL=min_ERL;

3187

else

3108

else

3188

min_ERL=[];

3109

min_ERL=[];

3189

ERL= [];

3110

ERL= [];

3190

output_args.ERL=[];

3111

output_args.ERL=[];

3191

end

3112

end

3192

if OP.ERL_ONLY

3113

if OP.ERL_ONLY

3193

if OP.BREAD_CRUMBS

3114

if OP.BREAD_CRUMBS

3194

output_args.OP=OP;

3115

output_args.OP=OP;

3195

output_args.param=param;

3116

output_args.param=param;

3196

output_args.chdata=chdata;

3117

output_args.chdata=chdata;

3197

%This seems to be the intent of setting fom_result.ran=0. Add it

3118

%This seems to be the intent of setting fom_result.ran=0. Add it

3198

%to output_args so there is a fom_result field.

3119

%to output_args so there is a fom_result field.

3199

fom_result.ran=0;

3120

fom_result.ran=0;

3200

output_args.fom_result=fom_result;

3121

output_args.fom_result=fom_result;

3201

end

3122

end

3202

output_args.Z_t=param.Z_t;

3123

output_args.Z_t=param.Z_t;

3203

fileset_str=str2csv({chdata(1).base});

3124

fileset_str=str2csv({chdata(1).base});

3204

output_args.file_names=sprintf('"%s"', fileset_str);

3125

output_args.file_names=sprintf('"%s"', fileset_str);

3205

if OP.DISPLAY_WINDOW

3126

if OP.DISPLAY_WINDOW

3206

savefigs(param, OP);

3127

savefigs(param, OP);

3207

end

3128

end

3208

end

3129

end

3209

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3130

function [impulse_response, p1_ctle, p2_ctle, z_ctle] = TD_CTLE(ir_in, fb, f_z, f_p1, f_p2, kacdc_dB, oversampling)

3210

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3131

%% Equation 93A-22 implemented in z-space and applied to the impulse response.

3211

p1_ctle = -2*pi*f_p1;

3132

p1_ctle = -2*pi*f_p1;

3212

p2_ctle = -2*pi*f_p2;

3133

p2_ctle = -2*pi*f_p2;

3213

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3134

z_ctle = -2*pi*f_z*10^(kacdc_dB/20);

3214

k_ctle = -p2_ctle;

3135

k_ctle = -p2_ctle;

3215

bilinear_fs = 2*fb*oversampling;

3136

bilinear_fs = 2*fb*oversampling;

3216

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3137

p2d = (1+p2_ctle/bilinear_fs)./(1-p2_ctle/bilinear_fs);

3217

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3138

p1d = (1+p1_ctle/bilinear_fs)./(1-p1_ctle/bilinear_fs);

3218

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3139

zd = (1+z_ctle/bilinear_fs)./(1-z_ctle/bilinear_fs);

3219

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3140

% kd = (bilinear_fs-z_ctle)/((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle));

3220

% allow for different pole zeros RIM 9-29-2015

3141

% allow for different pole zeros RIM 9-29-2015

3221

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3142

kd = (bilinear_fs-z_ctle)./((bilinear_fs-p1_ctle)*(bilinear_fs-p2_ctle))*f_p1/f_z;

3222

B_filt =k_ctle*kd*poly([zd, -1]);

3143

B_filt =k_ctle*kd*poly([zd, -1]);

3223

A_filt=poly([p1d, p2d]);

3144

A_filt=poly([p1d, p2d]);

3224

impulse_response=filter(B_filt,A_filt,ir_in);

3145

impulse_response=filter(B_filt,A_filt,ir_in);

3225

3146

3226

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3147

function [chdata, param, SDDch,SDDp2p] = TD_FD_fillin(param, OP, chdata)

3227

Over_sample=2;

3148

Over_sample=2;

3228

num_files=length(chdata);

3149

num_files=length(chdata);

3229

for i=1:num_files

3150

for i=1:num_files

3230

V=chdata(i).uneq_pulse_response;

3151

V=chdata(i).uneq_pulse_response;

3231

T=chdata(i).t;

3152

T=chdata(i).t;

3232

dt=T(2)-T(1);

3153

dt=T(2)-T(1);

3233

f=0:1/max(T):1/dt;

3154

f=0:1/max(T):1/dt;

3234

chdata(i).faxis=f;

3155

chdata(i).faxis=f;

3235

f75=find(f >= param.fb*.75,1,'first');

3156

f75=find(f >= param.fb*.75,1,'first');

3236

fnq=find(f >= param.fb*.5,1,'first');

3157

fnq=find(f >= param.fb*.5,1,'first');

3237

chdata(i).fmaxi = length(f);

3158

chdata(i).fmaxi = length(f);

3238

chdata(i).faxis = f;

3159

chdata(i).faxis = f;

3239

UI=param.ui; % unit interval

3160

UI=param.ui; % unit interval

3240

M=param.samples_per_ui; % sample per UI

3161

M=param.samples_per_ui; % sample per UI

3241

N_v=param.N_v; % number of UI for Vf determination

3162

N_v=param.N_v; % number of UI for Vf determination

3242

3163

3243

% filters

3164

% filters

3244

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3165

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

3245

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3166

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

3246

H_ftr=H_bw.*H_bt;

3167

H_ftr=H_bw.*H_bt;

3247

H_ftr=H_ftr(:);

3168

H_ftr=H_ftr(:);

3248

% fd of PR

3169

% fd of PR

3249

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3170

prr=sin(f*UI*pi)./(f*UI*pi); %nremoving sinc function to avoid using sig proc toolbox

3250

prr = prr(:);

3171

prr = prr(:);

3251

if f(1)==0, prr(1)=1; end %remove NaN

3172

if f(1)==0, prr(1)=1; end %remove NaN

3252

fd=fft(V);

3173

fd=fft(V);

3253

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3174

fd=fd(1:floor(length(fd)/2)); % un process freq domain response

3254

3175

3255

%% get Vf

3176

%% get Vf

3256

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3177

shifting_vector=kron(ones(1,200) ,[ 1 zeros(1,M-1) ]) ;

3257

step_response=filter(V,1, shifting_vector);

3178

step_response=filter(V,1, shifting_vector);

3258

Vf=step_response(end);

3179

Vf=step_response(end);

3259

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3180

STEP=timeseries(step_response(1:length(shifting_vector)),T(1:length(shifting_vector)));

3260

%%

3181

%%

3261

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3182

% ILest=20.*log10(abs(fd(1:f75)/Vf/M/Over_sample)) - 20.*log10(abs(prr(1:f75))) - 20*log10(abs(squeeze(H_ftr(1:f75)))) ; %removing db function to avoid using sig proc toolbox

3262

% figure

3183

% figure

3263

% plot(f(1:f75),ILest)

3184

% plot(f(1:f75),ILest)

3264

3185

3265

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3186

IL_conv=fd(1:f75)/Vf/M/Over_sample ./ prr(1:f75) ./ H_ftr(1:f75) ; %removing db function to avoid using sig proc toolbox

3266

% set same variables as get_s4p_files

3187

% set same variables as get_s4p_files

3267

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3188

IL_fields={'sdd12_raw' 'sdd21_raw' 'sdd12_orig' 'sdd21_orig' 'sdd12' 'sdd21' 'sdd21p' 'sdd21f'};

3268

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3189

Zero_fields={'sdd22_raw' 'sdd11_raw' 'sdc12_raw' 'sdc21_raw' 'sdc22_raw' 'sdc11_raw' ...

3269

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3190

'sdd11_orig' 'sdd22_orig' 'sdd11' 'sdd22' 'sdc12' 'sdc21' 'sdc11' 'sdc22' 'sdc21p'};

3270

zero_vector=zeros(length(IL_conv),1);

3191

zero_vector=zeros(length(IL_conv),1);

3271

for j=1:length(IL_fields)

3192

for j=1:length(IL_fields)

3272

chdata(i).(IL_fields{j})=IL_conv;

3193

chdata(i).(IL_fields{j})=IL_conv;

3273

end

3194

end

3274

for j=1:length(Zero_fields)

3195

for j=1:length(Zero_fields)

3275

chdata(i).(Zero_fields{j})=zero_vector;

3196

chdata(i).(Zero_fields{j})=zero_vector;

3276

end

3197

end

3277

3198

3278

if i==1

3199

if i==1

3279

SDDch(:,1,2)=chdata.sdd12_raw;

3200

SDDch(:,1,2)=chdata.sdd12_raw;

3280

SDDch(:,2,1)=chdata.sdd21_raw;

3201

SDDch(:,2,1)=chdata.sdd21_raw;

3281

SDDch(:,1,1)=chdata.sdd11_raw;

3202

SDDch(:,1,1)=chdata.sdd11_raw;

3282

SDDch(:,2,2)=chdata.sdd22_raw;

3203

SDDch(:,2,2)=chdata.sdd22_raw;

3283

SDDp2p= zeros(length(IL_conv),1);

3204

SDDp2p= zeros(length(IL_conv),1);

3284

end

3205

end

3285

chdata(i).TX_RL=[];

3206

chdata(i).TX_RL=[];

3286

chdata(i).TDR11=[];

3207

chdata(i).TDR11=[];

3287

chdata(i).PDTR11=[];

3208

chdata(i).PDTR11=[];

3288

chdata(i).TDR22=[];

3209

chdata(i).TDR22=[];

3289

chdata(i).PDTR22=[];

3210

chdata(i).PDTR22=[];

3290

end

3211

end

3291

3212

3292

3213

3293

function H_tw=Tukey_Window(f,param,fr,fb)

3214

function H_tw=Tukey_Window(f,param,fr,fb)

3294

% RIM 05/26/2022 added optional fr and fb

3215

% RIM 05/26/2022 added optional fr and fb

3295

% fr is the start of the raised cosine window

3216

% fr is the start of the raised cosine window

3296

% fb is the end of the raised cosine window

3217

% fb is the end of the raised cosine window

3297

if ~exist('fr','var') && ~exist('fb','var')

3218

if ~exist('fr','var') && ~exist('fb','var')

3298

fb=param.fb;

3219

fb=param.fb;

3299

fr=param.f_r*param.fb;

3220

fr=param.f_r*param.fb;

3300

end

3221

end

3301

fperiod=2*(fb-fr);

3222

fperiod=2*(fb-fr);

3302

H_tw = [ ones(1,length(f(f<fr))) ...

3223

H_tw = [ ones(1,length(f(f<fr))) ...

3303

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3224

0.5*cos(2*pi*(f( f>=fr & f<=fb) -fb ) /fperiod-pi)+.5 ...

3304

zeros(1,length(f(f>fb)) )];

3225

zeros(1,length(f(f>fb)) )];

3305

H_tw=H_tw(1:length(f));

3226

H_tw=H_tw(1:length(f));

3306

if 0

3227

if 0

3307

plot(f/1e9,H_tw)

3228

plot(f/1e9,H_tw)

3308

end

3229

end

3309

3230

3310

3231

3311

3232

3312

%% moved output control to functions

3233

%% moved output control to functions

3313

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3234

function [H_TxFFE] = Tx_FFE_Filter(varargin)

3314

% Author: Richard Mellitz

3235

% Author: Richard Mellitz

3315

% Date: 7/29/2022

3236

% Date: 7/29/2022

3316

% generate FD tx ffe system function

3237

% generate FD tx ffe system function

3317

% varagins...

3238

% varagins...

3318

% param - stucture

3239

% param - stucture

3319

% param.fb baud rate

3240

% param.fb baud rate

3320

% param.Tx_FFE Tx FFE coef

3241

% param.Tx_FFE Tx FFE coef

3321

% f - freq array

3242

% f - freq array

3322

% Use_Tx_FFE = flag to use or not

3243

% Use_Tx_FFE = flag to use or not

3323

% H_TxFFE is system function for Tx_FFE

3244

% H_TxFFE is system function for Tx_FFE

3324

db = @(x) 20*log10(abs(x));

3245

db = @(x) 20*log10(abs(x));

3325

[param,varargin]=varargin_extractor(varargin{:});

3246

[param,varargin]=varargin_extractor(varargin{:});

3326

[f,varargin]=varargin_extractor(varargin{:});

3247

[f,varargin]=varargin_extractor(varargin{:});

3327

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3248

[Use_Tx_FFE,varargin]=varargin_extractor(varargin{:});

3328

if isempty(Use_Tx_FFE)

3249

if isempty(Use_Tx_FFE)

3329

Use_Tx_FFE=0;

3250

Use_Tx_FFE=0;

3330

end

3251

end

3331

if isempty(param)

3252

if isempty(param)

3332

param.fb=106.25e9;

3253

param.fb=106.25e9;

3333

Tx_FFE=[1 ];

3254

Tx_FFE=[1 ];

3334

else

3255

else

3335

if ~isfield(param, 'Pkg_TXFFE_preset')

3256

if ~isfield(param, 'Pkg_TXFFE_preset')

3336

Tx_FFE=[ 1 ];

3257

Tx_FFE=[ 1 ];

3337

else

3258

else

3338

Tx_FFE=param.Pkg_TXFFE_preset;

3259

Tx_FFE=param.Pkg_TXFFE_preset;

3339

end

3260

end

3340

end

3261

end

3341

if isempty(f)

3262

if isempty(f)

3342

f=0:10e6:param.fb;

3263

f=0:10e6:param.fb;

3343

end

3264

end

3344

3265

3345

3266

3346

if Use_Tx_FFE ~=0

3267

if Use_Tx_FFE ~=0

3347

[mcur,icur] = max(Tx_FFE);

3268

[mcur,icur] = max(Tx_FFE);

3348

H_TxFFE=zeros(1,length(f));

3269

H_TxFFE=zeros(1,length(f));

3349

for ii=1:length(Tx_FFE)

3270

for ii=1:length(Tx_FFE)

3350

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3271

H_TxFFE = Tx_FFE(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+H_TxFFE;

3351

end

3272

end

3352

else

3273

else

3353

H_TxFFE=ones(1,length(f));

3274

H_TxFFE=ones(1,length(f));

3354

end

3275

end

3355

% figure (1102320)

3276

% figure (1102320)

3356

% plot(f/1e9,db(H_TxFFE))

3277

% plot(f/1e9,db(H_TxFFE))

3357

% hold on

3278

% hold on

3358

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3279

function C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs)

3359

cmx=param.RxFFE_cmx;

3280

cmx=param.RxFFE_cmx;

3360

cpx=param.RxFFE_cpx;

3281

cpx=param.RxFFE_cpx;

3361

% do this early on so we can reuse the old code

3282

% do this early on so we can reuse the old code

3362

% to be replaced with MMSE function from healey...

3283

% to be replaced with MMSE function from healey...

3363

if param.N_bg ~=0 % must be floating taps

3284

if param.N_bg ~=0 % must be floating taps

3364

cpx=param.N_bmax; % N_f in spreadsheet

3285

cpx=param.N_bmax; % N_f in spreadsheet

3365

end

3286

end

3366

num_taps=cmx+cpx+1;

3287

num_taps=cmx+cpx+1;

3367

ndfe=param.ndfe;

3288

ndfe=param.ndfe;

3368

spui=param.samples_per_ui;

3289

spui=param.samples_per_ui;

3369

%% Start of WIENER-HOPF MMSE EQ code

3290

%% Start of WIENER-HOPF MMSE EQ code

3370

R_n = zeros(num_taps,num_taps);

3291

R_n = zeros(num_taps,num_taps);

3371

R_xt = zeros(num_taps,num_taps);

3292

R_xt = zeros(num_taps,num_taps);

3372

3293

3373

if OP.Do_Colored_Noise

3294

if OP.Do_Colored_Noise

3374

% Form Noise Autocorrelation matrix

3295

% Form Noise Autocorrelation matrix

3375

Noise_XC = reshape (Noise_XC,1,[]);

3296

Noise_XC = reshape (Noise_XC,1,[]);

3376

len = length(Noise_XC);

3297

len = length(Noise_XC);

3377

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3298

if len < num_taps, Noise_XC = [Noise_XC,zeros(1,num_taps-len)]; end

3378

Noise_XC = Noise_XC(1:num_taps);

3299

Noise_XC = Noise_XC(1:num_taps);

3379

R_n = toeplitz (Noise_XC,Noise_XC);

3300

R_n = toeplitz (Noise_XC,Noise_XC);

3380

end

3301

end

3381

%% Calculate Cross Talk Correlation matrix at T intervals.

3302

%% Calculate Cross Talk Correlation matrix at T intervals.

3382

if OP.Do_XT_Noise

3303

if OP.Do_XT_Noise

3383

% Calculate variance of Tx signal based on +/-1 outer limits

3304

% Calculate variance of Tx signal based on +/-1 outer limits

3384

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3305

Tx_sigma = sqrt( (param.levels^2-1)/(3*(param.levels-1)^2) );

3385

for jj = 2:length(chdata)

3306

for jj = 2:length(chdata)

3386

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3307

if isequal(chdata(jj).type, 'FEXT') || isequal(chdata(jj).type, 'NEXT')

3387

if isequal(chdata(jj).type, 'FEXT')

3308

if isequal(chdata(jj).type, 'FEXT')

3388

% len = length(chdata(jj).ctle_imp_response);

3309

% len = length(chdata(jj).ctle_imp_response);

3389

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3310

% ch_imp = ifft( fft(reshape(chdata(jj).ctle_imp_response,1,[])) .* fft(reshape(upsample(txffe, param.samples_per_ui),1,[]),len) );

3390

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3311

ch_imp= FFE( txffe , cmx,param.samples_per_ui, chdata(jj).ctle_imp_response).';

3391

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3312

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3392

elseif isequal(chdata(jj).type, 'NEXT')

3313

elseif isequal(chdata(jj).type, 'NEXT')

3393

ch_imp = chdata(jj).ctle_imp_response;

3314

ch_imp = chdata(jj).ctle_imp_response;

3394

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3315

ch_imp = filter(ones(param.samples_per_ui, 1), 1, ch_imp);

3395

end

3316

end

3396

norms = zeros(1,spui);

3317

norms = zeros(1,spui);

3397

for ii = 1:spui

3318

for ii = 1:spui

3398

norms(ii) = norm(ch_imp(ii:spui:end));

3319

norms(ii) = norm(ch_imp(ii:spui:end));

3399

end

3320

end

3400

% Pick out sampling phase with largest noise contribution

3321

% Pick out sampling phase with largest noise contribution

3401

[~,cursor] = max(norms);

3322

[~,cursor] = max(norms);

3402

sub_sample_ch = ch_imp(cursor:spui:end);

3323

sub_sample_ch = ch_imp(cursor:spui:end);

3403

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3324

xc = xcorr(sub_sample_ch,num_taps)* Tx_sigma^2;

3404

xc = xc(num_taps+1:end);

3325

xc = xc(num_taps+1:end);

3405

xc = xc(1:num_taps);

3326

xc = xc(1:num_taps);

3406

R = toeplitz (xc,xc);

3327

R = toeplitz (xc,xc);

3407

R_xt = R_xt + R;

3328

R_xt = R_xt + R;

3408

end

3329

end

3409

end

3330

end

3410

end

3331

end

3411

%% Noise + Cross Talk contribution to R matrix

3332

%% Noise + Cross Talk contribution to R matrix

3412

R_n_xc = zeros(num_taps+ndfe);

3333

R_n_xc = zeros(num_taps+ndfe);

3413

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3334

R_n_xc(1:num_taps,1:num_taps) = R_n + R_xt ;

3414

%% For least means squares, we want to solve

3335

%% For least means squares, we want to solve

3415

%

3336

%

3416

% ro = |Ryy Ryx| * w

3337

% ro = |Ryy Ryx| * w

3417

% |Rxy Rxx|

3338

% |Rxy Rxx|

3418

% see Cioffi chapter 3, 3.7.3

3339

% see Cioffi chapter 3, 3.7.3

3419

3340

3420

himp = vsampled;

3341

himp = vsampled;

3421

RefTap = cmx+1;

3342

RefTap = cmx+1;

3422

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3343

Signal_Variance = mean ( [-1, -1/3, 1/3, 1].^2 );

3423

Ryy.r = [1:num_taps];

3344

Ryy.r = [1:num_taps];

3424

Ryy.c = [1:num_taps];

3345

Ryy.c = [1:num_taps];

3425

Ryx.r = 1:num_taps;

3346

Ryx.r = 1:num_taps;

3426

Ryx.c = num_taps + (1:ndfe);

3347

Ryx.c = num_taps + (1:ndfe);

3427

Rxy.r = num_taps + (1:ndfe);

3348

Rxy.r = num_taps + (1:ndfe);

3428

Rxy.c = 1:num_taps;

3349

Rxy.c = 1:num_taps;

3429

Rxx.r = num_taps+(1:ndfe);

3350

Rxx.r = num_taps+(1:ndfe);

3430

Rxx.c = num_taps+(1:ndfe);

3351

Rxx.c = num_taps+(1:ndfe);

3431

himp = reshape (himp,1,[]);

3352

himp = reshape (himp,1,[]);

3432

%% ro is simply the channel response reversed in time

3353

%% ro is simply the channel response reversed in time

3433

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3354

himp_lr = fliplr(himp); % make sure himp has enough pre/post cursors, e.g. numtaps+ndfe

3434

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3355

himp_lr = [zeros(1,num_taps+ndfe), himp_lr, zeros(1,num_taps+ndfe)];

3435

[~,pk] = max(himp_lr);

3356

[~,pk] = max(himp_lr);

3436

r_indx = (1:num_taps) - RefTap;

3357

r_indx = (1:num_taps) - RefTap;

3437

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3358

ro = [himp_lr(pk+r_indx), zeros(1,ndfe)].';

3438

ro = ro*Signal_Variance;

3359

ro = ro*Signal_Variance;

3439

%% Setup up the covariance matrix

3360

%% Setup up the covariance matrix

3440

R = zeros(num_taps+ndfe);

3361

R = zeros(num_taps+ndfe);

3441

% Form Ryy

3362

% Form Ryy

3442

% Note: important to use whole impulse response

3363

% Note: important to use whole impulse response

3443

% not just the part that spans the FFE.

3364

% not just the part that spans the FFE.

3444

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3365

[ryy,lags] = xcorr(himp,himp, num_taps-1);

3445

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3366

R(Ryy.r,Ryy.c) = toeplitz (ryy(num_taps:end));

3446

3367

3447

% Form Rxx

3368

% Form Rxx

3448

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3369

R(Rxx.r,Rxx.c) = diag(ones(1,ndfe));

3449

3370

3450

% Form Ryx columns

3371

% Form Ryx columns

3451

Ryx_indxs = (1:num_taps)-1;

3372

Ryx_indxs = (1:num_taps)-1;

3452

for jj = 0:ndfe-1

3373

for jj = 0:ndfe-1

3453

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3374

% R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk+1 + Ryx_indxs -jj ).';

3454

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3375

R(Ryx.r,Ryx.c(jj+1) ) = himp_lr(pk-cmx-1 + Ryx_indxs -jj ).';

3455

end

3376

end

3456

% Form Rxy rows

3377

% Form Rxy rows

3457

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3378

R(Rxy.r,Rxy.c ) = R(Ryx.r,Ryx.c )';

3458

3379

3459

% add in Signal Variance

3380

% add in Signal Variance

3460

R = R*Signal_Variance;

3381

R = R*Signal_Variance;

3461

Rtmp = R;

3382

Rtmp = R;

3462

% Add in Xt and colored noise terms

3383

% Add in Xt and colored noise terms

3463

R = R + R_n_xc;

3384

R = R + R_n_xc;

3464

3385

3465

% SNR = 25 dB

3386

% SNR = 25 dB

3466

SNR = OP.FFE_SNR;

3387

SNR = OP.FFE_SNR;

3467

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3388

Noise_var = max(vsampled)^2*Signal_Variance/10^(SNR/10);

3468

R_noise = diag(ones(1,num_taps))*Noise_var;

3389

R_noise = diag(ones(1,num_taps))*Noise_var;

3469

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3390

if ~OP.Do_Colored_Noise && ~OP.Do_XT_Noise

3470

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3391

R(Ryy.r,Ryy.c) = R(Ryy.r,Ryy.c) + R_noise;

3471

end

3392

end

3472

3393

3473

3394

3474

%% Solve for equalizer weights

3395

%% Solve for equalizer weights

3475

w = inv(R)*ro;

3396

w = inv(R)*ro;

3476

C = w;

3397

C = w;

3477

%% Deal with 1st post Cursor DFE weight saturation

3398

%% Deal with 1st post Cursor DFE weight saturation

3478

% ro = Rw by moving "saturated" weights over to the LHS

3399

% ro = Rw by moving "saturated" weights over to the LHS

3479

DFE_h1_indx = num_taps+1;

3400

DFE_h1_indx = num_taps+1;

3480

Indx_full = 1:length(C);

3401

Indx_full = 1:length(C);

3481

ws = C;

3402

ws = C;

3482

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3403

if ndfe>0 && abs(C(DFE_h1_indx)) > param.bmax(1)

3483

rtmp = reshape (ro,[],1);

3404

rtmp = reshape (ro,[],1);

3484

Rtmp = R;

3405

Rtmp = R;

3485

% Move saturated DFE weights over to left hand side of equation

3406

% Move saturated DFE weights over to left hand side of equation

3486

ws = zeros (size(C));

3407

ws = zeros (size(C));

3487

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3408

ws (DFE_h1_indx) = sign(C(DFE_h1_indx))*param.bmax(1);

3488

rtmp = rtmp - Rtmp*ws;

3409

rtmp = rtmp - Rtmp*ws;

3489

3410

3490

% and remove the corresponding column from R

3411

% and remove the corresponding column from R

3491

Rtmp(:,DFE_h1_indx) = [];

3412

Rtmp(:,DFE_h1_indx) = [];

3492

Indx_full (DFE_h1_indx) = [];

3413

Indx_full (DFE_h1_indx) = [];

3493

% now Rtmp isn't square so have to use the R'R trick

3414

% now Rtmp isn't square so have to use the R'R trick

3494

% Probably a little dicey "theoretically" because

3415

% Probably a little dicey "theoretically" because

3495

% w = inv(R)*ro is already the mmse solution

3416

% w = inv(R)*ro is already the mmse solution

3496

% now we at doing a R'R operation, but hey

3417

% now we at doing a R'R operation, but hey

3497

% seems to work

3418

% seems to work

3498

% Alternative, since R is now over specified, more rows than

3419

% Alternative, since R is now over specified, more rows than

3499

% columns, one could try removing one of the DFE rows from the

3420

% columns, one could try removing one of the DFE rows from the

3500

% Rxy Rxx portion of the R matrix.

3421

% Rxy Rxx portion of the R matrix.

3501

3422

3502

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3423

w_partial = inv(Rtmp'*Rtmp)*(Rtmp'*rtmp);

3503

ws (Indx_full,:) = w_partial;

3424

ws (Indx_full,:) = w_partial;

3504

C = ws;

3425

C = ws;

3505

end

3426

end

3506

% From Cioffi, Chapter 3

3427

% From Cioffi, Chapter 3

3507

var_ffe_dfe = Signal_Variance-ws.'*ro;

3428

var_ffe_dfe = Signal_Variance-ws.'*ro;

3508

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3429

SNR_Eq = 10*log10(Signal_Variance/var_ffe_dfe-1);

3509

3430

3510

%% Scale FFE gain to target output voltage

3431

%% Scale FFE gain to target output voltage

3511

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3432

Target_ouput = vsampled(ivs)*10^(param.current_ffegain/20);

3512

C = C*Target_ouput;

3433

C = C*Target_ouput;

3513

C = C(1:num_taps);

3434

C = C(1:num_taps);

3514

%% End MMSE dfe code

3435

%% End MMSE dfe code

3515

function Write_CSV(output_args,csv_file)

3436

function Write_CSV(output_args,csv_file)

3516

3437

3517

items = fieldnames(output_args);

3438

items = fieldnames(output_args);

3518

item_value_strings = cell(size(items));

3439

item_value_strings = cell(size(items));

3519

for field_id=1:length(items)

3440

for field_id=1:length(items)

3520

field_name=items{field_id};

3441

field_name=items{field_id};

3521

field_value=output_args.(field_name);

3442

field_value=output_args.(field_name);

3522

if isstruct(output_args.(field_name))

3443

if isstruct(output_args.(field_name))

3523

field_value='struct';

3444

field_value='struct';

3524

end

3445

end

3525

if ischar(field_value)

3446

if ischar(field_value)

3526

item_value_strings{field_id}=field_value;

3447

item_value_strings{field_id}=field_value;

3527

elseif isempty(field_value)

3448

elseif isempty(field_value)

3528

item_value_strings{field_id}='';

3449

item_value_strings{field_id}='';

3529

elseif numel(field_value)==1

3450

elseif numel(field_value)==1

3530

item_value_strings{field_id}=num2str(field_value);

3451

item_value_strings{field_id}=num2str(field_value);

3531

else

3452

else

3532

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3453

item_value_strings{field_id}=sprintf('"%s"', mat2str(field_value));

3533

end

3454

end

3534

end

3455

end

3535

3456

3536

header_string = str2csv(items);

3457

header_string = str2csv(items);

3537

data_string = str2csv(item_value_strings);

3458

data_string = str2csv(item_value_strings);

3538

fid = fopen(csv_file,'w');

3459

fid = fopen(csv_file,'w');

3539

fprintf(fid,'%s\n', header_string);

3460

fprintf(fid,'%s\n', header_string);

3540

fprintf(fid,'%s\n', data_string);

3461

fprintf(fid,'%s\n', data_string);

3541

fclose(fid);

3462

fclose(fid);

3542

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3463

function [ s11out, s12out, s21out, s22out ] = add_brd(chdata, param, OP)

3543

%% Used in Clause 92 for adding board trace between TP0 and TP2

3464

%% Used in Clause 92 for adding board trace between TP0 and TP2

3544

3465

3545

switch chdata.type

3466

switch chdata.type

3546

case 'THRU'

3467

case 'THRU'

3547

z_bp_tx = param.z_bp_tx;

3468

z_bp_tx = param.z_bp_tx;

3548

z_bp_rx = param.z_bp_rx;

3469

z_bp_rx = param.z_bp_rx;

3549

case 'NEXT'

3470

case 'NEXT'

3550

z_bp_tx = param.z_bp_rx;

3471

z_bp_tx = param.z_bp_rx;

3551

z_bp_rx = param.z_bp_next;

3472

z_bp_rx = param.z_bp_next;

3552

case 'FEXT'

3473

case 'FEXT'

3553

z_bp_tx = param.z_bp_fext;

3474

z_bp_tx = param.z_bp_fext;

3554

z_bp_rx = param.z_bp_rx;

3475

z_bp_rx = param.z_bp_rx;

3555

end

3476

end

3556

% Same cap on each tx and rx three is a data stratue for bifrucation but

3477

% Same cap on each tx and rx three is a data stratue for bifrucation but

3557

% logic no implemented here RIM 06/28/2019

3478

% logic no implemented here RIM 06/28/2019

3558

zref=param.Z0;

3479

zref=param.Z0;

3559

c1=param.C_0;

3480

c1=param.C_0;

3560

c2=param.C_1;

3481

c2=param.C_1;

3561

f=chdata.faxis;

3482

f=chdata.faxis;

3562

f(f<eps)=eps;

3483

f(f<eps)=eps;

3563

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3484

s11pad1t= -1i*2*pi.*f*c1(1)*zref./(2+1i*2*pi.*f*c1(1)*zref);

3564

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3485

s21pad1t= 2./(2+1i*2*pi.*f*c1(1)*zref);

3565

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3486

s11pad2t= -1i*2*pi.*f*c2(1)*zref./(2+1i*2*pi.*f*c2(1)*zref);

3566

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3487

s21pad2t= 2./(2+1i*2*pi.*f*c2(1)*zref);

3567

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3488

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3568

% add Tx caps

3489

% add Tx caps

3569

[s11tx, s12tx, s21tx, s22tx ]= ...

3490

[s11tx, s12tx, s21tx, s22tx ]= ...

3570

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3491

combines4p( s11pad1t, s21pad1t, s21pad1t, s11pad1t, s11tx, s12tx, s21tx, s22tx );

3571

[s11tx, s12tx, s21tx, s22tx ]= ...

3492

[s11tx, s12tx, s21tx, s22tx ]= ...

3572

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3493

combines4p( s11tx, s12tx, s21tx, s22tx,s11pad2t, s21pad2t, s21pad2t, s11pad2t );

3573

3494

3574

3495

3575

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3496

s11pad1r= -1i*2*pi.*f*c1(2)*zref./(2+1i*2*pi.*f*c1(2)*zref);

3576

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3497

s21pad1r= 2./(2+1i*2*pi.*f*c1(2)*zref);

3577

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3498

s11pad2r= -1i*2*pi.*f*c2(2)*zref./(2+1i*2*pi.*f*c2(2)*zref);

3578

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3499

s21pad2r= 2./(2+1i*2*pi.*f*c2(2)*zref);

3579

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3500

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_rx);

3580

% add Rx caps

3501

% add Rx caps

3581

[s11rx, s12rx, s21rx, s22rx ]= ...

3502

[s11rx, s12rx, s21rx, s22rx ]= ...

3582

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3503

combines4p( s11pad2r, s21pad2r, s21pad2r, s11pad2r, s11rx, s12rx, s21rx, s22rx );

3583

[s11rx, s12rx, s21rx, s22rx ]= ...

3504

[s11rx, s12rx, s21rx, s22rx ]= ...

3584

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3505

combines4p( s11rx, s12rx, s21rx, s22rx,s11pad1r, s21pad1r, s21pad1r, s11pad1r );

3585

3506

3586

3507

3587

switch OP.include_pcb

3508

switch OP.include_pcb

3588

case 1

3509

case 1

3589

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3510

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3590

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3511

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3591

case 2

3512

case 2

3592

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3513

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3593

end

3514

end

3594

3515

3595

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3516

function [ s11out, s12out, s21out, s22out ] = add_brdorig(chdata, param, OP)

3596

% Used in Clause 92 for adding board trace between TP0 and TP2

3517

% Used in Clause 92 for adding board trace between TP0 and TP2

3597

switch chdata.type

3518

switch chdata.type

3598

case 'THRU'

3519

case 'THRU'

3599

z_bp_tx = param.z_bp_tx;

3520

z_bp_tx = param.z_bp_tx;

3600

case 'NEXT'

3521

case 'NEXT'

3601

z_bp_tx = param.z_bp_next;

3522

z_bp_tx = param.z_bp_next;

3602

case 'FEXT'

3523

case 'FEXT'

3603

z_bp_tx = param.z_bp_fext;

3524

z_bp_tx = param.z_bp_fext;

3604

end

3525

end

3605

3526

3606

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3527

[ s11tx, s12tx, s21tx, s22tx ] = synth_tline(chdata.faxis, param.brd_Z_c(1), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, z_bp_tx);

3607

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3528

[ s11rx, s12rx, s21rx, s22rx ] = synth_tline(chdata.faxis, param.brd_Z_c(2), param.Z0, param.brd_gamma0_a1_a2, param.brd_tau, param.z_bp_rx);

3608

3529

3609

switch OP.include_pcb

3530

switch OP.include_pcb

3610

case 1

3531

case 1

3611

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3532

[ s11out1, s12out1, s21out1, s22out1 ]=combines4p( s11tx, s12tx, s21tx, s22tx, chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw );

3612

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3533

[ s11out, s12out, s21out, s22out ]=combines4p( s11out1, s12out1, s21out1, s22out1, s11rx, s12rx, s21rx, s22rx);

3613

case 2

3534

case 2

3614

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3535

[ s11out, s12out, s21out, s22out ]=combines4p( chdata.sdd11_raw, chdata.sdd12_raw, chdata.sdd21_raw, chdata.sdd22_raw, s11rx, s12rx, s21rx, s22rx);

3615

end

3536

end

3616

3537

3617

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3538

function [hisi,tap_coef,hisi_ref]=applyDFEbk(hisi,hisi_ref,idx,tap_bk,curval,bmaxg,dfe_delta)

3618

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3539

% hrem=applyDFEbk(hsis,idx,tap_bk,bmaxg)

3619

% applying a bank of DFE at desired location

3540

% applying a bank of DFE at desired location

3620

% hisi: waveform with cursor values;

3541

% hisi: waveform with cursor values;

3621

% idx: starting index of the bank;

3542

% idx: starting index of the bank;

3622

% tap_bk: number of taps in bank;

3543

% tap_bk: number of taps in bank;

3623

% bmaxg: maxmum coefficient in bank;

3544

% bmaxg: maxmum coefficient in bank;

3624

3545

3625

if nargin<6

3546

if nargin<6

3626

dfe_delta=0;

3547

dfe_delta=0;

3627

end

3548

end

3628

3549

3629

rng=idx:idx+tap_bk-1;

3550

rng=idx:idx+tap_bk-1;

3630

flt_curval=hisi(rng);

3551

flt_curval=hisi(rng);

3631

3552

3632

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3553

%floor(abs(floatingcursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(floatingcursors)*sbr(cursor_i);

3633

3554

3634

if dfe_delta~=0

3555

if dfe_delta~=0

3635

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3556

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

3636

dfe_delta.*sign(flt_curval)*curval;

3557

dfe_delta.*sign(flt_curval)*curval;

3637

else

3558

else

3638

flt_curval_q=hisi(rng);

3559

flt_curval_q=hisi(rng);

3639

end

3560

end

3640

3561

3641

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3562

tap_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

3642

hisi(rng)= hisi(rng) - curval*tap_coef;

3563

hisi(rng)= hisi(rng) - curval*tap_coef;

3643

hisi_ref(rng)=0;

3564

hisi_ref(rng)=0;

3644

3565

3645

%AJG021820

3566

%AJG021820

3646

function [ a] = bessel( n )

3567

function [ a] = bessel( n )

3647

% bessel polynomial

3568

% bessel polynomial

3648

for ii= 0:n

3569

for ii= 0:n

3649

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3570

a(ii+1) = factorial(2*n-ii) / (2^(n-ii)*factorial(ii)*factorial(n-ii));

3650

end

3571

end

3651

3572

3652

3573

3653

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3574

function [delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(freq, sdd21, param, OP)

3654

% History:

3575

% History:

3655

% 1. 14th October, 2021 (Intial release)

3576

% 1. 14th October, 2021 (Intial release)

3656

3577

3657

% Definition:

3578

% Definition:

3658

% This function captures the channel delay through the time domain using causality enforcement.

3579

% This function captures the channel delay through the time domain using causality enforcement.

3659

% Following are the steps being followed.

3580

% Following are the steps being followed.

3660

% Step 1. Cascade negative frequencies

3581

% Step 1. Cascade negative frequencies

3661

% Step 2. Extract magnitude

3582

% Step 2. Extract magnitude

3662

% Step 3. IFFT of the magnitude

3583

% Step 3. IFFT of the magnitude

3663

% Step 4. Multiply by the sign(t)

3584

% Step 4. Multiply by the sign(t)

3664

% Step 5. Calculate the phase of the 1j*causal_phase

3585

% Step 5. Calculate the phase of the 1j*causal_phase

3665

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3586

% Step 6. casual_function= |original|*exp(-1j*causal_phase)

3666

% Step 7. f-domain to t-domain pulse response

3587

% Step 7. f-domain to t-domain pulse response

3667

% Step 8. Calculate the delay

3588

% Step 8. Calculate the delay

3668

3589

3669

% Author:

3590

% Author:

3670

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3591

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3671

3592

3672

% Reference:

3593

% Reference:

3673

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3594

% 1] "IEEE Standard for Electrical Characterization of Printed Circuit Board and Related Interconnects at Frequencies up to 50 GHz," in IEEE Std 370-2020 , vol., no., pp.1-147, 8 Jan. 2021, doi: 10.1109/IEEESTD.2021.9316329.

3674

3595

3675

% Input:

3596

% Input:

3676

% freq %frequency in hertz (odd number points)

3597

% freq %frequency in hertz (odd number points)

3677

% sdd21 %insertion loss in complex (odd number points)

3598

% sdd21 %insertion loss in complex (odd number points)

3678

% param %COM native structure passed

3599

% param %COM native structure passed

3679

% OP %COM native structure passed

3600

% OP %COM native structure passed

3680

3601

3681

% Output:

3602

% Output:

3682

% delay_sec %channel delay in seconds

3603

% delay_sec %channel delay in seconds

3683

% delay_idx %channel delay index

3604

% delay_idx %channel delay index

3684

3605

3685

if iscolumn(sdd21)

3606

if iscolumn(sdd21)

3686

sdd21= sdd21.';

3607

sdd21= sdd21.';

3687

end

3608

end

3688

if iscolumn(freq)

3609

if iscolumn(freq)

3689

freq= freq.';

3610

freq= freq.';

3690

end

3611

end

3691

3612

3692

%---start. Step 1. Cascade negative frequencies

3613

%---start. Step 1. Cascade negative frequencies

3693

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3614

% sdd21_conj= zeros(1, length(freq)+ length(freq) - 1);

3694

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3615

sdd21_conj= [sdd21, conj(sdd21(end:-1:2))];%For some reason this only works

3695

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3616

% sdd21_conj = [real(sdd21(1)), sdd21(2:end-1), real(sdd21(end)), flipud(conj(sdd21(2:end-1)))];

3696

%---end. Step 1. Cascade negative frequencies

3617

%---end. Step 1. Cascade negative frequencies

3697

3618

3698

%---start. Step 2. Extract magnitude

3619

%---start. Step 2. Extract magnitude

3699

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3620

sdd21_mag_conj = real(log(abs(sdd21_conj)));

3700

%---end. Step 2. Extract magnitude

3621

%---end. Step 2. Extract magnitude

3701

3622

3702

%---start. Step 3. IFFT of the magnitude

3623

%---start. Step 3. IFFT of the magnitude

3703

sdd21_mag_time = ifft(sdd21_mag_conj);

3624

sdd21_mag_time = ifft(sdd21_mag_conj);

3704

%---end. Step 3. IFFT of the magnitude

3625

%---end. Step 3. IFFT of the magnitude

3705

3626

3706

%---start. Step 4. Multiply by the sign(t)

3627

%---start. Step 4. Multiply by the sign(t)

3707

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3628

sdd21_mag_time(1:length(freq))= +1j*sdd21_mag_time(1:length(freq));

3708

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3629

sdd21_mag_time(length(freq)+1:end)= -1j*sdd21_mag_time(length(freq)+1:end);

3709

%---end. Step 4. Multiply by the sign(t)

3630

%---end. Step 4. Multiply by the sign(t)

3710

3631

3711

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3632

%---start. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3712

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3633

sdd21_phase_causality_enforced = real(fft(sdd21_mag_time));

3713

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3634

%---end. Step 5. Calculate the phase of the original_signal and the 1j*causal_phase

3714

3635

3715

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3636

%---start. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3716

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3637

sdd21_causality_enforced= abs(sdd21_conj).*exp(-1j*sdd21_phase_causality_enforced);

3717

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3638

sdd21_causality_enforced= sdd21_causality_enforced(1:length(freq));

3718

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3639

%---end. Step 6. casual_function= |original|*exp(-1j*causal_phase)

3719

3640

3720

%---start. Step 7. f-domain to t-domain pulse response

3641

%---start. Step 7. f-domain to t-domain pulse response

3721

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3642

%------Note. Do not use s21_to_impulse() for we do not want to truncate

3722

%--------- Extrapolation has been already done by the COM tool

3643

%--------- Extrapolation has been already done by the COM tool

3723

freq_array= freq;

3644

freq_array= freq;

3724

time_step= param.sample_dt;

3645

time_step= param.sample_dt;

3725

fmax=1/time_step/2;

3646

fmax=1/time_step/2;

3726

freq_step=(freq_array(3)-freq_array(2))/1;

3647

freq_step=(freq_array(3)-freq_array(2))/1;

3727

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3648

fout=0:1/round(fmax/freq_step)*fmax:fmax;

3728

3649

3729

ILin=sdd21;

3650

ILin=sdd21;

3730

IL=interp_Sparam(ILin,freq_array,fout, ...

3651

IL=interp_Sparam(ILin,freq_array,fout, ...

3731

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3652

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3732

IL_nan = find(isnan(IL));

3653

IL_nan = find(isnan(IL));

3733

for in=IL_nan

3654

for in=IL_nan

3734

IL(in)=IL(in-1);

3655

IL(in)=IL(in-1);

3735

end

3656

end

3736

IL = IL(:);

3657

IL = IL(:);

3737

% add padding for time steps

3658

% add padding for time steps

3738

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3659

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3739

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3660

sdd21_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3740

clear IL IL_nan IL_symmetric

3661

clear IL IL_nan IL_symmetric

3741

3662

3742

ILin=sdd21_causality_enforced;

3663

ILin=sdd21_causality_enforced;

3743

IL=interp_Sparam(ILin,freq_array,fout, ...

3664

IL=interp_Sparam(ILin,freq_array,fout, ...

3744

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3665

OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

3745

IL_nan = find(isnan(IL));

3666

IL_nan = find(isnan(IL));

3746

for in=IL_nan

3667

for in=IL_nan

3747

IL(in)=IL(in-1);

3668

IL(in)=IL(in-1);

3748

end

3669

end

3749

IL = IL(:);

3670

IL = IL(:);

3750

% add padding for time steps

3671

% add padding for time steps

3751

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3672

% IL_symmetric = [IL(1:end-1); 0; flipud(conj(IL(2:end-1)))];

3752

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3673

% IL_symmetric = [IL(1:end); flipud(conj(IL(2:end-1)))];

3753

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3674

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

3754

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3675

sdd21_causality_enforced_PR = filter(ones(1, param.samples_per_ui), 1, real(ifft(IL_symmetric)));%real(ifft(IL_symmetric));

3755

clear IL IL_nan IL_symmetric

3676

clear IL IL_nan IL_symmetric

3756

3677

3757

clear time_step fmax freq_step freq_array

3678

clear time_step fmax freq_step freq_array

3758

3679

3759

freq_step=(fout(3)-fout(2))/1;

3680

freq_step=(fout(3)-fout(2))/1;

3760

L= length(sdd21_PR);

3681

L= length(sdd21_PR);

3761

t_base = (0:L-1)/(freq_step*L);

3682

t_base = (0:L-1)/(freq_step*L);

3762

clear fout freq_step L

3683

clear fout freq_step L

3763

%---end. Step 7. f-domain to t-domain pulse response

3684

%---end. Step 7. f-domain to t-domain pulse response

3764

3685

3765

%---start. Step 8. Calculate the delay

3686

%---start. Step 8. Calculate the delay

3766

%------start. Remove the last 5% of the waveform for noise due to IFFT

3687

%------start. Remove the last 5% of the waveform for noise due to IFFT

3767

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3688

sdd21_causality_enforced_PR_reduced= sdd21_PR(1:floor(end*95/100));

3768

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3689

sdd21_PR_reduced= sdd21_causality_enforced_PR(1:floor(end*95/100));

3769

%------end. Remove the last 5% of the waveform for noise due to IFFT

3690

%------end. Remove the last 5% of the waveform for noise due to IFFT

3770

3691

3771

%---start. calculate the difference in index between the peaks

3692

%---start. calculate the difference in index between the peaks

3772

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3693

[~, peak_x_idx] = max(sdd21_causality_enforced_PR_reduced);

3773

[~, peak_y_idx] = max(sdd21_PR_reduced);

3694

[~, peak_y_idx] = max(sdd21_PR_reduced);

3774

peak_idx_difference = peak_x_idx - peak_y_idx;

3695

peak_idx_difference = peak_x_idx - peak_y_idx;

3775

%---end. calculate the difference in index between the peaks

3696

%---end. calculate the difference in index between the peaks

3776

3697

3777

if peak_idx_difference~=0

3698

if peak_idx_difference~=0

3778

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3699

search_bounds = min(peak_x_idx, peak_y_idx);%<----one may fix it to 1e3; using minimum of the peaks in assuming the other signal has zero delay

3779

error_value = length(sdd21_causality_enforced_PR_reduced);

3700

error_value = length(sdd21_causality_enforced_PR_reduced);

3780

error_idx = 0;

3701

error_idx = 0;

3781

% i= 1;

3702

% i= 1;

3782

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3703

for shift_value= peak_idx_difference-search_bounds:peak_idx_difference+search_bounds

3783

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3704

sdd21_PR_reduced_shifted = circshift(sdd21_PR_reduced,shift_value);

3784

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3705

current_error = norm(sdd21_PR_reduced_shifted-sdd21_PR_reduced);

3785

if (error_value > current_error)

3706

if (error_value > current_error)

3786

error_idx = shift_value;

3707

error_idx = shift_value;

3787

error_value = current_error;

3708

error_value = current_error;

3788

end

3709

end

3789

% error_idx_H(i)= error_idx;

3710

% error_idx_H(i)= error_idx;

3790

% i= i+ 1;

3711

% i= i+ 1;

3791

end

3712

end

3792

%plot(error_idx_H);

3713

%plot(error_idx_H);

3793

3714

3794

if error_idx==0

3715

if error_idx==0

3795

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3716

error('An odd case has occured when calcualting the channel delay. Please contact the tool developer.');

3796

end

3717

end

3797

3718

3798

delay_idx = error_idx;

3719

delay_idx = error_idx;

3799

else

3720

else

3800

delay_idx= 1;

3721

delay_idx= 1;

3801

end

3722

end

3802

3723

3803

delay_sec= t_base(abs(delay_idx));

3724

delay_sec= t_base(abs(delay_idx));

3804

3725

3805

3726

3806

function [return_struct]= capture_RIL_RILN(chdata)

3727

function [return_struct]= capture_RIL_RILN(chdata)

3807

% History:

3728

% History:

3808

% 1. 12th April, 2019 (Intial release)

3729

% 1. 12th April, 2019 (Intial release)

3809

%

3730

%

3810

% 2. 11th October, 2021

3731

% 2. 11th October, 2021

3811

% - Details:

3732

% - Details:

3812

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3733

% 1] Revised the equation of RIL for missing conj(rho_port1) and conj(rho_port2).

3813

% 2] Revised the selection criteria for the solution of the quadratic

3734

% 2] Revised the selection criteria for the solution of the quadratic

3814

% equation in finding the reflection coefficient (rho).

3735

% equation in finding the reflection coefficient (rho).

3815

% - Impact:

3736

% - Impact:

3816

% => Zero impact in |RIL|, while impact on angle(RIL).

3737

% => Zero impact in |RIL|, while impact on angle(RIL).

3817

% - Previous:

3738

% - Previous:

3818

% %---start. For passive networks the reflection coefficient should be less than one

3739

% %---start. For passive networks the reflection coefficient should be less than one

3819

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3740

% if all(abs(solution_1(idx_start:end))< 1) && ~all(abs(solution_2(idx_start:end))< 1)

3820

% rho_port2= solution_1;

3741

% rho_port2= solution_1;

3821

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3742

% elseif all(abs(solution_2(idx_start:end))< 1) && ~all(abs(solution_1(idx_start:end))< 1)

3822

% rho_port2= solution_2;

3743

% rho_port2= solution_2;

3823

% else

3744

% else

3824

% rho_port2= solution_1;

3745

% rho_port2= solution_1;

3825

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3746

% % error('Please contact the tool developer. It appears a odd case has appeared.');

3826

% end

3747

% end

3827

% %---end. For passive networks the reflection coefficient should be less than one

3748

% %---end. For passive networks the reflection coefficient should be less than one

3828

%

3749

%

3829

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3750

% RIL= conj((1- rho_port1).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- rho_port2).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3830

% - Change:

3751

% - Change:

3831

% %---start. Given the real part of the impedance is to be positive

3752

% %---start. Given the real part of the impedance is to be positive

3832

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3753

% Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3833

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3754

% Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3834

%

3755

%

3835

% rho_port2= zeros(length(solution_1), 1);

3756

% rho_port2= zeros(length(solution_1), 1);

3836

% for solution_idx= 1:length(solution_1)

3757

% for solution_idx= 1:length(solution_1)

3837

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3758

% if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3838

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3759

% rho_port2(solution_idx, 1)= solution_1(solution_idx);

3839

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3760

% elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3840

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3761

% rho_port2(solution_idx, 1)= solution_2(solution_idx);

3841

% else

3762

% else

3842

% error('An odd case has occured. Please contact the tool developer.');

3763

% error('An odd case has occured. Please contact the tool developer.');

3843

% end

3764

% end

3844

% end

3765

% end

3845

% %---end. Given the real part of the impedance is to be positive

3766

% %---end. Given the real part of the impedance is to be positive

3846

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3767

% RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3847

3768

3848

% Definition:

3769

% Definition:

3849

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3770

% This function captures the reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter

3850

3771

3851

% Author:

3772

% Author:

3852

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3773

% Hansel Dsilva (dsilvahansel@gmail.com or hanseldsilva@achronix.com)

3853

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3774

% Acknowledgement: Adam Gregory, Richard Mellitz, Beomtaek Lee and Amit Kumar.

3854

3775

3855

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3776

% This function has been shared by Hansel for others to evaluate for reflectionless insertion loss (RIL) and reflective insertion loss nois (RILN) for any arbitary S-parameter.

3856

3777

3857

% Reference:

3778

% Reference:

3858

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3779

% 1] H. Dsilva et al., "Finding Reflective Insertion Loss Noise and Reflectionless Insertion Loss," 2020 DesignCon.

3859

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3780

% 2] H. Dsilva, A. Jain, J. Sasikala and A. Kumar, "Novel Signal Integrity Application of Power Wave Scattering Matrix theory," 2019 IEEE MTT-S International Microwave and RF Conference (IMARC), 2019, pp. 1-7, doi: 10.1109/IMaRC45935.2019.9118701.

3860

3781

3861

% Input:

3782

% Input:

3862

% 1] SCH: S-matrix structure

3783

% 1] SCH: S-matrix structure

3863

% SCH.Frequencies= faxis;

3784

% SCH.Frequencies= faxis;

3864

% SCH.Parameters(1,1,:)= sdd11;

3785

% SCH.Parameters(1,1,:)= sdd11;

3865

% SCH.Parameters(2,2,:)= sdd22;

3786

% SCH.Parameters(2,2,:)= sdd22;

3866

% SCH.Parameters(1,2,:)= sdd12;

3787

% SCH.Parameters(1,2,:)= sdd12;

3867

% SCH.Parameters(2,1,:)= sdd21;

3788

% SCH.Parameters(2,1,:)= sdd21;

3868

% SCH.NumPorts= 2;

3789

% SCH.NumPorts= 2;

3869

% SCH.Impedance= 100;

3790

% SCH.Impedance= 100;

3870

3791

3871

% Output: Struct returned has the following,

3792

% Output: Struct returned has the following,

3872

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3793

% return_struct.RIL %Reflectionless Insertion Loss as a complex number

3873

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3794

% return_struct.RIL_dB %Reflectionless Insertion Loss in decibel

3874

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3795

% return_struct.RILN %Reflective Insertion Loss Noise as a complex number

3875

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3796

% return_struct.RILN_dB %Reflective Insertion Loss Noise in decibel

3876

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3797

% return_struct.Z_port1 %Frequency dependent, complex values of impedance for termination of port 1

3877

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3798

% return_struct.Z_port2 %Frequency dependent, complex values of impedance for termination of port 2

3878

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3799

% return_struct.rho_port1 %Frequency dependent, complex values of the reflection coefficient of port 1

3879

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3800

% return_struct.rho_port2 %Frequency dependent, complex values of reflection coefficient of port 2

3880

% return_struct.freq %Frequency axis

3801

% return_struct.freq %Frequency axis

3881

3802

3882

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3803

SCH.Parameters(1,1,:)=chdata(1).sdd11_orig;

3883

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3804

SCH.Parameters(2,2,:)=chdata(1).sdd22_orig;

3884

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3805

SCH.Parameters(1,2,:)=chdata(1).sdd12_orig;

3885

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3806

SCH.Parameters(2,1,:)=chdata(1).sdd21_orig;

3886

SCH.Frequencies=chdata(1).faxis;

3807

SCH.Frequencies=chdata(1).faxis;

3887

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3808

SCH.Impedance=100;%<------------------in a future release, may want to parameterize this based on the read .sNp

3888

SCH.NumPorts= 2;

3809

SCH.NumPorts= 2;

3889

3810

3890

%---start. allowed is only a 2-port network having a transmitter and receiver

3811

%---start. allowed is only a 2-port network having a transmitter and receiver

3891

if size(SCH.Parameters, 1)~=2

3812

if size(SCH.Parameters, 1)~=2

3892

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3813

fprintf('Size of given S matrix is %d.', size(SCH.Parameters, 3) );

3893

error('Allowed is only a 2-port network having a transmitter and receiver.');

3814

error('Allowed is only a 2-port network having a transmitter and receiver.');

3894

end

3815

end

3895

%---end. allowed is only a 2-port network having a transmitter and receiver

3816

%---end. allowed is only a 2-port network having a transmitter and receiver

3896

3817

3897

%---start. do not include the DC point given sinusoidals at DC are not

3818

%---start. do not include the DC point given sinusoidals at DC are not

3898

%defined

3819

%defined

3899

if SCH.Frequencies(1)==0

3820

if SCH.Frequencies(1)==0

3900

idx_start= 2;

3821

idx_start= 2;

3901

else

3822

else

3902

idx_start= 1;

3823

idx_start= 1;

3903

end

3824

end

3904

%---end. do not include the DC point given sinusoidals at DC are not

3825

%---end. do not include the DC point given sinusoidals at DC are not

3905

%defined

3826

%defined

3906

3827

3907

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3828

Sdd11= squeeze(SCH.Parameters(1,1,idx_start:end));

3908

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3829

Sdd12= squeeze(SCH.Parameters(1,2,idx_start:end));

3909

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3830

Sdd21= squeeze(SCH.Parameters(2,1,idx_start:end));

3910

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3831

Sdd22= squeeze(SCH.Parameters(2,2,idx_start:end));

3911

3832

3912

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3833

a= -Sdd22+ Sdd11.*Sdd22.*conj(Sdd11)- Sdd21.*Sdd12.*conj(Sdd11);

3913

b= 1+ Sdd22.*conj(Sdd22)+...

3834

b= 1+ Sdd22.*conj(Sdd22)+...

3914

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3835

Sdd11.*Sdd22.*conj(Sdd21).*conj(Sdd12)-...

3915

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3836

Sdd21.*Sdd12.*conj(Sdd21).*conj(Sdd12)-...

3916

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3837

Sdd11.*Sdd22.*conj(Sdd11).*conj(Sdd22)+...

3917

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3838

Sdd12.*Sdd21.*conj(Sdd11).*conj(Sdd22)-...

3918

Sdd11.*conj(Sdd11);

3839

Sdd11.*conj(Sdd11);

3919

c= -conj(Sdd22)-...

3840

c= -conj(Sdd22)-...

3920

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3841

Sdd11.*conj(Sdd21).*conj(Sdd12)+...

3921

Sdd11.*conj(Sdd11).*conj(Sdd22);

3842

Sdd11.*conj(Sdd11).*conj(Sdd22);

3922

3843

3923

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3844

solution_1= (-b+sqrt((b.^2)-(4*a.*c)))./(2*a);

3924

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3845

solution_2= (-b-sqrt((b.^2)-(4*a.*c)))./(2*a);

3925

3846

3926

clear a b c

3847

clear a b c

3927

3848

3928

%---start. Given the real part of the impedance is to be positive

3849

%---start. Given the real part of the impedance is to be positive

3929

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3850

Z_solution_1= (solution_1*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_1);

3930

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3851

Z_solution_2= (solution_2*conj(SCH.Impedance)+ SCH.Impedance)./(1-solution_2);

3931

3852

3932

rho_port2= zeros(length(solution_1), 1);

3853

rho_port2= zeros(length(solution_1), 1);

3933

for solution_idx= 1:length(solution_1)

3854

for solution_idx= 1:length(solution_1)

3934

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3855

if real(Z_solution_1(solution_idx))>0 && real(Z_solution_2(solution_idx))<=0

3935

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3856

rho_port2(solution_idx, 1)= solution_1(solution_idx);

3936

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3857

elseif real(Z_solution_2(solution_idx))>0 && real(Z_solution_1(solution_idx))<=0

3937

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3858

rho_port2(solution_idx, 1)= solution_2(solution_idx);

3938

else

3859

else

3939

error('An odd case has occured. Please contact the tool developer.');

3860

error('An odd case has occured. Please contact the tool developer.');

3940

end

3861

end

3941

end

3862

end

3942

%---end. Given the real part of the impedance is to be positive

3863

%---end. Given the real part of the impedance is to be positive

3943

3864

3944

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3865

rho_port1= conj(Sdd11+ ((rho_port2.*Sdd21.*Sdd12)./(1-(rho_port2.*Sdd22))));

3945

3866

3946

%---start. calculate the equivalent port impedance

3867

%---start. calculate the equivalent port impedance

3947

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3868

Z_port1= (rho_port1*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port1);

3948

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3869

Z_port2= (rho_port2*conj(SCH.Impedance)+ SCH.Impedance)./(1-rho_port2);

3949

%---end. calculate the equivalent port impedance

3870

%---end. calculate the equivalent port impedance

3950

3871

3951

3872

3952

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3873

% %---start. The reflectionless insertion loss is the insertion loss corresponding

3953

% %to zero reflections.

3874

% %to zero reflections.

3954

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3875

RIL= conj((1- conj(rho_port1)).*(sqrt(abs(1- rho_port1.*conj(rho_port1)))./abs(1-rho_port1) )).*( Sdd21.*(1- rho_port2.*Sdd22)+ (Sdd22- conj(rho_port2)).*rho_port2.*Sdd21 )./ ( ((1- conj(rho_port2)).*(sqrt(abs(1- rho_port2.*conj(rho_port2)))./abs(1-rho_port2) )) .* ( -rho_port1.*rho_port2.*Sdd21.*Sdd12+ (1- rho_port2.*Sdd22).*(1- rho_port1.*Sdd11) ) );

3955

%---end. The reflectionless insertion loss is the insertion loss corresponding

3876

%---end. The reflectionless insertion loss is the insertion loss corresponding

3956

%to zero reflections.

3877

%to zero reflections.

3957

3878

3958

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3879

%---start. Calculate RILN (Reflective Insertion Loss Noise)

3959

RILN= RIL- Sdd21;

3880

RILN= RIL- Sdd21;

3960

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3881

RILN_dB= 20*log10(abs(Sdd21))- 20*log10(abs(RIL));

3961

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3882

%---end. Calculate RILN (Reflective Insertion Loss Noise)

3962

3883

3963

%---start. preparing returns struct

3884

%---start. preparing returns struct

3964

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3885

return_struct.RIL= RIL; %Reflectionless Insertion Loss as a complex number

3965

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3886

return_struct.RIL_dB= 20*log10(abs(RIL)); %Reflectionless Insertion Loss in decibel

3966

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3887

return_struct.RILN= RILN; %Reflective Insertion Loss Noise as a complex number

3967

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3888

return_struct.RILN_dB= RILN_dB; %Reflective Insertion Loss Noise in decibel

3968

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3889

return_struct.Z_port1= Z_port1; %Frequency dependent, complex values of impedance for termination of port 1

3969

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3890

return_struct.Z_port2= Z_port2; %Frequency dependent, complex values of impedance for termination of port 2

3970

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3891

return_struct.rho_port1= rho_port1; %Frequency dependent, complex values of the reflection coefficient of port 1

3971

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3892

return_struct.rho_port2= rho_port2; %Frequency dependent, complex values of reflection coefficient of port 2

3972

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3893

return_struct.freq= SCH.Frequencies(idx_start:end); %Frequency axis

3973

%---end. preparing returns struct

3894

%---end. preparing returns struct

3974

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3895

function [noise_bottom,noise_top]=cdf_to_ber_contour(cdf,specBER)

3975

3896

3976

3897

3977

%For the given BER, find the top & bottom voltage level in the CDF

3898

%For the given BER, find the top & bottom voltage level in the CDF

3978

3899

3979

%for the top, just find the first index at the spec BER

3900

%for the top, just find the first index at the spec BER

3980

nidx=find(cdf.y>specBER, 1, 'first');

3901

nidx=find(cdf.y>specBER, 1, 'first');

3981

noise_bottom = cdf.x(nidx);

3902

noise_bottom = cdf.x(nidx);

3982

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3903

%for top, flip the cdf. need to operate on row vector for fliplr: cdf.y(:)'

3983

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3904

nidx=find(fliplr(cdf.y(:)')>specBER, 1, 'first');

3984

%the true index without flipping

3905

%the true index without flipping

3985

nidx=length(cdf.y)-nidx+1;

3906

nidx=length(cdf.y)-nidx+1;

3986

noise_top = cdf.x(nidx);

3907

noise_top = cdf.x(nidx);

3987

function p=comb_fct(p1, p2)

3908

function p=comb_fct(p1, p2)

3988

if p1.BinSize ~= p2.BinSize

3909

if p1.BinSize ~= p2.BinSize

3989

error('bin size must be equal')

3910

error('bin size must be equal')

3990

end

3911

end

3991

3912

3992

p=p1;

3913

p=p1;

3993

p.BinSize=p1.BinSize;

3914

p.BinSize=p1.BinSize;

3994

%p.Min=p1.Min+p2.Min;

3915

%p.Min=p1.Min+p2.Min;

3995

p.Min=min(p1.Min,p2.Min);

3916

p.Min=min(p1.Min,p2.Min);

3996

difsz=abs(p1.Min-p2.Min);

3917

difsz=abs(p1.Min-p2.Min);

3997

lp1=length(p1.y);

3918

lp1=length(p1.y);

3998

lp2=length(p2.y);

3919

lp2=length(p2.y);

3999

if p1.Min == p.Min

3920

if p1.Min == p.Min

4000

p2.y(difsz+1:lp2+difsz)=p2.y;

3921

p2.y(difsz+1:lp2+difsz)=p2.y;

4001

p2.y(1:difsz)=0;

3922

p2.y(1:difsz)=0;

4002

p2.y(lp2+difsz+1:lp1)=0;

3923

p2.y(lp2+difsz+1:lp1)=0;

4003

elseif p2.Min == p.Min

3924

elseif p2.Min == p.Min

4004

p1.y(difsz+1:lp1+difsz)=p1.y;

3925

p1.y(difsz+1:lp1+difsz)=p1.y;

4005

p1.y(1:difsz)=0;

3926

p1.y(1:difsz)=0;

4006

p1.y(lp1+difsz+1:lp2)=0;

3927

p1.y(lp1+difsz+1:lp2)=0;

4007

end

3928

end

4008

% p.y=conv(p1.y, p2.y);

3929

% p.y=conv(p1.y, p2.y);

4009

p.y=(p1.y+p2.y);

3930

p.y=(p1.y+p2.y);

4010

% p.y=p.y/sum(p.y);

3931

% p.y=p.y/sum(p.y);

4011

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

3932

% p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4012

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

3933

p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4013

3934

4014

3935

4015

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

3936

function out_pdf=combine_pdf_same_voltage_axis(pdf1,pdf2)

4016

3937

4017

if pdf1.BinSize ~= pdf2.BinSize

3938

if pdf1.BinSize ~= pdf2.BinSize

4018

error('bin size must be equal')

3939

error('bin size must be equal')

4019

end

3940

end

4020

3941

4021

x1=pdf1.x;

3942

x1=pdf1.x;

4022

y1=pdf1.y;

3943

y1=pdf1.y;

4023

x2=pdf2.x;

3944

x2=pdf2.x;

4024

y2=pdf2.y;

3945

y2=pdf2.y;

4025

%find the pdf with a larger min, force it to have the same min, and insert

3946

%find the pdf with a larger min, force it to have the same min, and insert

4026

%probability = 0

3947

%probability = 0

4027

min1=pdf1.x(1);

3948

min1=pdf1.x(1);

4028

min2=pdf2.x(1);

3949

min2=pdf2.x(1);

4029

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

3950

shift_amount=round(abs(min1-min2)/pdf1.BinSize);

4030

if min1<min2

3951

if min1<min2

4031

x2=[pdf1.x(1:shift_amount) pdf2.x];

3952

x2=[pdf1.x(1:shift_amount) pdf2.x];

4032

y2=[zeros(1,shift_amount) pdf2.y];

3953

y2=[zeros(1,shift_amount) pdf2.y];

4033

else

3954

else

4034

x1=[pdf2.x(1:shift_amount) pdf1.x];

3955

x1=[pdf2.x(1:shift_amount) pdf1.x];

4035

y1=[zeros(1,shift_amount) pdf1.y];

3956

y1=[zeros(1,shift_amount) pdf1.y];

4036

end

3957

end

4037

%find the pdf with smaller max, force it to have the same max, and insert

3958

%find the pdf with smaller max, force it to have the same max, and insert

4038

%probability=0

3959

%probability=0

4039

L1=length(x1);

3960

L1=length(x1);

4040

L2=length(x2);

3961

L2=length(x2);

4041

Ldiff=abs(L1-L2);

3962

Ldiff=abs(L1-L2);

4042

if L1>L2

3963

if L1>L2

4043

out_x=x1;

3964

out_x=x1;

4044

y2=[y2 zeros(1,Ldiff)];

3965

y2=[y2 zeros(1,Ldiff)];

4045

else

3966

else

4046

out_x=x2;

3967

out_x=x2;

4047

y1=[y1 zeros(1,Ldiff)];

3968

y1=[y1 zeros(1,Ldiff)];

4048

end

3969

end

4049

%now the 2 pdfs have the same voltage axis, add probabilities together

3970

%now the 2 pdfs have the same voltage axis, add probabilities together

4050

%renormalization is not handled here, so the output pdf will not have sum=1

3971

%renormalization is not handled here, so the output pdf will not have sum=1

4051

%It is the responsibility of the calling function to handle renormalization

3972

%It is the responsibility of the calling function to handle renormalization

4052

%if needed

3973

%if needed

4053

out_y=y1+y2;

3974

out_y=y1+y2;

4054

out_pdf.x=out_x;

3975

out_pdf.x=out_x;

4055

out_pdf.y=out_y;

3976

out_pdf.y=out_y;

4056

out_pdf.BinSize=pdf1.BinSize;

3977

out_pdf.BinSize=pdf1.BinSize;

4057

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

3978

function [ s11out, s12out, s21out, s22out ] = combines4p( s11in1, s12in1, s21in1, s22in1, s11in2, s12in2, s21in2, s22in2)

4058

3979

4059

%original method:

3980

%original method:

4060

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

3981

% s1=zeros(2,2,length(s11in1)); s2=s1; t3=s1;

4061

% for i=1:length(s11in1)

3982

% for i=1:length(s11in1)

4062

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

3983

% s1(:,:,i)=[s11in1(i) s12in1(i); s21in1(i) s22in1(i) ];

4063

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

3984

% s2(:,:,i)=[s11in2(i) s12in2(i); s21in2(i) s22in2(i) ];

4064

% end

3985

% end

4065

% t1=stot(s1);

3986

% t1=stot(s1);

4066

% t2=stot(s2);

3987

% t2=stot(s2);

4067

% for i=1:length(s11in1)

3988

% for i=1:length(s11in1)

4068

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

3989

% t3(:,:,i)=t1(:,:,i)*t2(:,:,i);

4069

% end

3990

% end

4070

% s3=ttos(t3);

3991

% s3=ttos(t3);

4071

% s11out=s3(1,1,:);

3992

% s11out=s3(1,1,:);

4072

% s11out=transpose(s11out(:));

3993

% s11out=transpose(s11out(:));

4073

% s12out=s3(1,2,:);

3994

% s12out=s3(1,2,:);

4074

% s12out=transpose(s12out(:));

3995

% s12out=transpose(s12out(:));

4075

% s21out=s3(2,1,:);

3996

% s21out=s3(2,1,:);

4076

% s21out=transpose(s21out(:));

3997

% s21out=transpose(s21out(:));

4077

% s22out=s3(2,2,:);

3998

% s22out=s3(2,2,:);

4078

% s22out=transpose(s22out(:));

3999

% s22out=transpose(s22out(:));

4079

4000

4080

4001

4081

%vectorized method:

4002

%vectorized method:

4082

s1(1,1,:)=s11in1;

4003

s1(1,1,:)=s11in1;

4083

s1(1,2,:)=s12in1;

4004

s1(1,2,:)=s12in1;

4084

s1(2,1,:)=s21in1;

4005

s1(2,1,:)=s21in1;

4085

s1(2,2,:)=s22in1;

4006

s1(2,2,:)=s22in1;

4086

s2(1,1,:)=s11in2;

4007

s2(1,1,:)=s11in2;

4087

s2(1,2,:)=s12in2;

4008

s2(1,2,:)=s12in2;

4088

s2(2,1,:)=s21in2;

4009

s2(2,1,:)=s21in2;

4089

s2(2,2,:)=s22in2;

4010

s2(2,2,:)=s22in2;

4090

4011

4091

4012

4092

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4013

N = (1-s1(2,2,:).*s2(1,1,:)) ;

4093

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4014

s11out = s1(1,1,:)+(s1(1,2,:).*s1(2,1,:).*s2(1,1,:))./N ;

4094

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4015

s12out = s1(1,2,:).*s2(1,2,:)./N ;

4095

s21out = s2(2,1,:).*s1(2,1,:)./N;

4016

s21out = s2(2,1,:).*s1(2,1,:)./N;

4096

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4017

s22out = s2(2,2,:)+(s2(1,2,:).*s2(2,1,:).*s1(2,2,:))./N ;

4097

4018

4098

s11out=transpose(squeeze(s11out));

4019

s11out=transpose(squeeze(s11out));

4099

s12out=transpose(squeeze(s12out));

4020

s12out=transpose(squeeze(s12out));

4100

s21out=transpose(squeeze(s21out));

4021

s21out=transpose(squeeze(s21out));

4101

s22out=transpose(squeeze(s22out));

4022

s22out=transpose(squeeze(s22out));

4102

function p=conv_fct(p1, p2)

4023

function p=conv_fct(p1, p2)

4103

if p1.BinSize ~= p2.BinSize

4024

if p1.BinSize ~= p2.BinSize

4104

error('bin size must be equal')

4025

error('bin size must be equal')

4105

end

4026

end

4106

4027

4107

p=p1;

4028

p=p1;

4108

%p.BinSize=p1.BinSize;

4029

%p.BinSize=p1.BinSize;

4109

%p.Min=p1.Min+p2.Min;

4030

%p.Min=p1.Min+p2.Min;

4110

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4031

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4111

p.y=conv2(p1.y, p2.y);

4032

p.y=conv2(p1.y, p2.y);

4112

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4033

%p.x =p.Min*p.BinSize:p.BinSize:-p.Min*p.BinSize;

4113

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4034

%p.x =(p.Min:-p.Min)*p.BinSize; % modified by Yasuo Hidaka, 9/4/2016

4114

pMax=p.Min+length(p.y)-1;

4035

pMax=p.Min+length(p.y)-1;

4115

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4036

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4116

4037

4117

4038

4118

4039

4119

4040

4120

function p=conv_fct_MeanNotZero(p1, p2)

4041

function p=conv_fct_MeanNotZero(p1, p2)

4121

4042

4122

if p1.BinSize ~= p2.BinSize

4043

if p1.BinSize ~= p2.BinSize

4123

error('bin size must be equal')

4044

error('bin size must be equal')

4124

end

4045

end

4125

4046

4126

p=p1;

4047

p=p1;

4127

%p.BinSize=p1.BinSize;

4048

%p.BinSize=p1.BinSize;

4128

%p.Min=p1.Min+p2.Min;

4049

%p.Min=p1.Min+p2.Min;

4129

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4050

p.Min=round(p1.Min+p2.Min); % modified by Yasuo Hidaka, 9/4/2016

4130

p.y=conv2(p1.y, p2.y);

4051

p.y=conv2(p1.y, p2.y);

4131

4052

4132

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4053

%This is equivalent to (p.Min:p.Min+length(p.y)-1)*p.BinSize

4133

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4054

%But it is faster to pre-multiply BinSize instead of multiplying the entire

4134

%vector by BinSize

4055

%vector by BinSize

4135

pMax=p.Min+length(p.y)-1;

4056

pMax=p.Min+length(p.y)-1;

4136

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4057

p.x =(p.Min*p.BinSize:p.BinSize:pMax*p.BinSize);

4137

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4058

function [cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,peak_search_range)

4138

4059

4139

%IN:

4060

%IN:

4140

%sbr = pulse response

4061

%sbr = pulse response

4141

%param = COM "param" struct

4062

%param = COM "param" struct

4142

%OP = COM "OP" struct

4063

%OP = COM "OP" struct

4143

%peak_search_range= a limited range to search for the peak (for speed up)

4064

%peak_search_range= a limited range to search for the peak (for speed up)

4144

% it is usually +/- 20 UI

4065

% it is usually +/- 20 UI

4145

%

4066

%

4146

%OUT:

4067

%OUT:

4147

%cursor_i = sampling location

4068

%cursor_i = sampling location

4148

%no_zero_crossing = flag that reveals if sampling is not possible.

4069

%no_zero_crossing = flag that reveals if sampling is not possible.

4149

% When this function is called in optimize_fom, it signals to quit the current case

4070

% When this function is called in optimize_fom, it signals to quit the current case

4150

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4071

%sbr_peak_i = index of the pulse peak. Note: tens of thousands of calls to max(sbr) are very

4151

% time consuming, so saving the peak in one spot is advantageous

4072

% time consuming, so saving the peak in one spot is advantageous

4152

%zxi = zero crossing index (returned because RXFFE uses it)

4073

%zxi = zero crossing index (returned because RXFFE uses it)

4153

4074

4154

no_zero_crossing=0;

4075

no_zero_crossing=0;

4155

%need to set cursor_i to empty in case no_zero_crossing flag is set

4076

%need to set cursor_i to empty in case no_zero_crossing flag is set

4156

cursor_i=[];

4077

cursor_i=[];

4157

4078

4158

%get peak of pulse and peak index

4079

%get peak of pulse and peak index

4159

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4080

[max_of_sbr, sbr_peak_tmp]=max(sbr(peak_search_range));

4160

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4081

sbr_peak_i=sbr_peak_tmp+peak_search_range(1)-1;

4161

4082

4162

4083

4163

% initial guess at cursor location (t_s) - based on approximate zero crossing

4084

% initial guess at cursor location (t_s) - based on approximate zero crossing

4164

%limit search space for speed up

4085

%limit search space for speed up

4165

search_start=sbr_peak_i-4*param.samples_per_ui;

4086

search_start=sbr_peak_i-4*param.samples_per_ui;

4166

if search_start<1

4087

if search_start<1

4167

search_start=1;

4088

search_start=1;

4168

end

4089

end

4169

%Find zero crossings

4090

%Find zero crossings

4170

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4091

zxi = find(diff(sign(sbr(search_start:sbr_peak_i)-.01*max_of_sbr))>=1)+search_start-1;

4171

4092

4172

%Note: the original implementation of zxi:

4093

%Note: the original implementation of zxi:

4173

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4094

% zxi = find(diff(sign(sbr-.01*max(sbr)))>=1);

4174

% zxi = zxi(zxi<sbr_peak_i);

4095

% zxi = zxi(zxi<sbr_peak_i);

4175

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4096

% zxi = zxi(sbr_peak_i - zxi < 4*param.samples_per_ui);

4176

% The changes to limit search space and remember max(sbr) give 10x speed up

4097

% The changes to limit search space and remember max(sbr) give 10x speed up

4177

% A test case of 25k runs, reduced from 1.2s to 0.1s

4098

% A test case of 25k runs, reduced from 1.2s to 0.1s

4178

4099

4179

4100

4180

if isempty(zxi)

4101

if isempty(zxi)

4181

%if no zero crossing, the calling program must respond (since sample point will be empty)

4102

%if no zero crossing, the calling program must respond (since sample point will be empty)

4182

no_zero_crossing=1;

4103

no_zero_crossing=1;

4183

return;

4104

return;

4184

elseif length(zxi)>1

4105

elseif length(zxi)>1

4185

%only need the last zero crossing

4106

%only need the last zero crossing

4186

zxi=zxi(end);

4107

zxi=zxi(end);

4187

end

4108

end

4188

if param.ndfe==0

4109

if param.ndfe==0

4189

max_dfe1=0;

4110

max_dfe1=0;

4190

else

4111

else

4191

max_dfe1=param.bmax(1);

4112

max_dfe1=param.bmax(1);

4192

end

4113

end

4193

% adjust cursor_i to Solve equation 93A-25 %%

4114

% adjust cursor_i to Solve equation 93A-25 %%

4194

% Muller-Mueller criterion with DFE

4115

% Muller-Mueller criterion with DFE

4195

mm_range = zxi+(0:2*param.samples_per_ui);

4116

mm_range = zxi+(0:2*param.samples_per_ui);

4196

switch OP.CDR

4117

switch OP.CDR

4197

case 'Mod-MM'

4118

case 'Mod-MM'

4198

mm_metric = ...

4119

mm_metric = ...

4199

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4120

abs(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range));

4200

otherwise % MM

4121

otherwise % MM

4201

%MM is generally: first precursor = 0

4122

%MM is generally: first precursor = 0

4202

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4123

%but the actual requirement is for first precursor = first postcursor (after DFE is applied)

4203

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4124

%if first postcursor doesn't exceed max_dfe, then this equates to first precursor = 0

4204

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4125

%in cases where first postcursor exceeds max_dfe, the mismatch is balanced out so that

4205

%first precursor = first postcursor - max_dfe

4126

%first precursor = first postcursor - max_dfe

4206

mm_metric = ...

4127

mm_metric = ...

4207

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4128

abs(sbr(mm_range-param.samples_per_ui) - max(sbr(mm_range+param.samples_per_ui)-max_dfe1*sbr(mm_range), 0));

4208

end

4129

end

4209

[~, mm_cursor_offset] = min(mm_metric);

4130

[~, mm_cursor_offset] = min(mm_metric);

4210

4131

4211

%cursor_i = the sample location

4132

%cursor_i = the sample location

4212

cursor_i = zxi+mm_cursor_offset-1;

4133

cursor_i = zxi+mm_cursor_offset-1;

4213

function pdf=d_cpdf( binsize, values, probs)

4134

function pdf=d_cpdf( binsize, values, probs)

4214

% p=cpdf(type, ...)

4135

% p=cpdf(type, ...)

4215

%

4136

%

4216

% CPDF is a probability mass function for discrete distributions or an

4137

% CPDF is a probability mass function for discrete distributions or an

4217

% approxmation of a PDF for continuous distributions.

4138

% approxmation of a PDF for continuous distributions.

4218

%

4139

%

4219

% cpdf is internally normalized so that the sum of probabilities is 1

4140

% cpdf is internally normalized so that the sum of probabilities is 1

4220

% (regardless of bin size).

4141

% (regardless of bin size).

4221

4142

4222

% Internal fields:

4143

% Internal fields:

4223

% Min: *bin number* of minimum value.

4144

% Min: *bin number* of minimum value.

4224

% BinSize: size of PDF bins. Bin center is the representative value.

4145

% BinSize: size of PDF bins. Bin center is the representative value.

4225

% Vec: vector of probabilities per bin.

4146

% Vec: vector of probabilities per bin.

4226

4147

4227

%speed up for initializing empty pdf

4148

%speed up for initializing empty pdf

4228

if all(values==0)

4149

if all(values==0)

4229

pdf.BinSize=binsize;

4150

pdf.BinSize=binsize;

4230

pdf.Min=0;

4151

pdf.Min=0;

4231

pdf.y=1;

4152

pdf.y=1;

4232

pdf.x=0;

4153

pdf.x=0;

4233

return;

4154

return;

4234

end

4155

end

4235

4156

4236

if ~issorted(values)

4157

if ~issorted(values)

4237

[values,si]=sort(values);

4158

[values,si]=sort(values);

4238

probs=probs(si);

4159

probs=probs(si);

4239

end

4160

end

4240

values=binsize*round(values/binsize);

4161

values=binsize*round(values/binsize);

4241

t=(values(1):binsize:values(end));

4162

t=(values(1):binsize:values(end));

4242

pdf.Min=values(1)/binsize;

4163

pdf.Min=values(1)/binsize;

4243

pdf.y=zeros(size(t));

4164

pdf.y=zeros(size(t));

4244

for k=1:length(values)

4165

for k=1:length(values)

4245

if k==1

4166

if k==1

4246

bin=1;

4167

bin=1;

4247

elseif k==length(values)

4168

elseif k==length(values)

4248

bin=length(t);

4169

bin=length(t);

4249

else

4170

else

4250

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4171

[UNUSED_OUTPUT, bin]=min(abs(t-values(k))); %#ok<ASGLU>

4251

end

4172

end

4252

pdf.y(bin) = pdf.y(bin)+probs(k);

4173

pdf.y(bin) = pdf.y(bin)+probs(k);

4253

end

4174

end

4254

4175

4255

pdf.BinSize=binsize;

4176

pdf.BinSize=binsize;

4256

pdf.y=pdf.y/sum(pdf.y);

4177

pdf.y=pdf.y/sum(pdf.y);

4257

if any(~isreal(pdf.y)) || any(pdf.y<0)

4178

if any(~isreal(pdf.y)) || any(pdf.y<0)

4258

error('PDF must be real and nonnegative');

4179

error('PDF must be real and nonnegative');

4259

end

4180

end

4260

support=find(pdf.y);

4181

support=find(pdf.y);

4261

pdf.y=pdf.y(support(1):support(end));

4182

pdf.y=pdf.y(support(1):support(end));

4262

pdf.Min=pdf.Min+(support(1)-1);

4183

pdf.Min=pdf.Min+(support(1)-1);

4263

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4184

pdf.x=(pdf.Min:-pdf.Min)*binsize;

4264

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4185

function clip_output=dfe_clipper(input,max_threshold,min_threshold)

4265

4186

4266

if isrow(input)

4187

if isrow(input)

4267

max_threshold=max_threshold(:).';

4188

max_threshold=max_threshold(:).';

4268

min_threshold=min_threshold(:).';

4189

min_threshold=min_threshold(:).';

4269

else

4190

else

4270

max_threshold=max_threshold(:);

4191

max_threshold=max_threshold(:);

4271

min_threshold=min_threshold(:);

4192

min_threshold=min_threshold(:);

4272

end

4193

end

4273

4194

4274

clip_output=input;

4195

clip_output=input;

4275

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4196

clip_output(input>max_threshold)=max_threshold(input>max_threshold);

4276

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4197

clip_output(input<min_threshold)=min_threshold(input<min_threshold);

4277

4198

4278

4199

4279

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4200

function [msg] = end_display_control(msg,param,OP,output_args,COM,min_ERL,ERL,VEO_mV,VEC_dB,threshold_DER,DISPLAY_WINDOW)

4280

[ncases, mele]=size(param.z_p_tx_cases);

4201

[ncases, mele]=size(param.z_p_tx_cases);

4281

if mele ==2

4202

if mele ==2

4282

param.flex=2;

4203

param.flex=2;

4283

elseif mele==4

4204

elseif mele==4

4284

param.flex=4;

4205

param.flex=4;

4285

elseif mele==1

4206

elseif mele==1

4286

param.flex=1;

4207

param.flex=1;

4287

else

4208

else

4288

error(springf('config file syntax error'))

4209

error(springf('config file syntax error'))

4289

end

4210

end

4290

4211

4291

4212

4292

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4213

if DISPLAY_WINDOW && ~OP.RX_CALIBRATION

4293

% display bathtub curves in one axis per test case.

4214

% display bathtub curves in one axis per test case.

4294

% h=findall(0, 'Name', 'COM results');

4215

% h=findall(0, 'Name', 'COM results');

4295

if ~exist('h','var')

4216

if ~exist('h','var')

4296

msgtext = cell(1, length(OP.pkg_len_select));

4217

msgtext = cell(1, length(OP.pkg_len_select));

4297

msgcolor = 'g';

4218

msgcolor = 'g';

4298

else

4219

else

4299

msgtext=get(findobj(h, 'type', 'text'), 'string');

4220

msgtext=get(findobj(h, 'type', 'text'), 'string');

4300

msgcolor = get(h, 'color');

4221

msgcolor = get(h, 'color');

4301

close(h); % will be recreated

4222

close(h); % will be recreated

4302

end

4223

end

4303

msgctr=size(msgtext,1)+1;

4224

msgctr=size(msgtext,1)+1;

4304

if ~OP.ERL_ONLY

4225

if ~OP.ERL_ONLY

4305

switch OP.PHY

4226

switch OP.PHY

4306

case 'C2M'

4227

case 'C2M'

4307

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4228

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4308

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4229

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4309

msg, VEO_mV);

4230

msg, VEO_mV);

4310

else

4231

else

4311

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4232

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4312

msg, VEO_mV);

4233

msg, VEO_mV);

4313

msgcolor = 'r';

4234

msgcolor = 'r';

4314

end

4235

end

4315

4236

4316

if VEC_dB <= param.VEC_pass_threshold

4237

if VEC_dB <= param.VEC_pass_threshold

4317

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4238

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4318

(msg), VEC_dB);

4239

(msg), VEC_dB);

4319

else

4240

else

4320

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4241

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4321

(msg), VEC_dB);

4242

(msg), VEC_dB);

4322

msgcolor = 'r';

4243

msgcolor = 'r';

4323

end

4244

end

4324

case 'C2C'

4245

case 'C2C'

4325

if COM >= param.pass_threshold

4246

if COM >= param.pass_threshold

4326

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4247

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4327

% msg, COM);

4248

% msg, COM);

4328

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4249

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4329

msg, COM);

4250

msg, COM);

4330

else

4251

else

4331

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4252

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4332

% msg, COM);

4253

% msg, COM);

4333

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4254

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4334

msg, COM);

4255

msg, COM);

4335

msgcolor = 'r';

4256

msgcolor = 'r';

4336

end

4257

end

4337

% begin yasuo patch 3/18/2019

4258

% begin yasuo patch 3/18/2019

4338

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4259

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4339

% end yasuo patch

4260

% end yasuo patch

4340

case 'C2Mcom'

4261

case 'C2Mcom'

4341

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4262

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4342

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4263

msg=sprintf('%s: EH = %.3f mV (pass)\n', ...

4343

msg, VEO_mV);

4264

msg, VEO_mV);

4344

else

4265

else

4345

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4266

msg=sprintf('%s: EH = %.3f mV (FAIL)\n', ...

4346

msg, VEO_mV);

4267

msg, VEO_mV);

4347

msgcolor = 'r';

4268

msgcolor = 'r';

4348

end

4269

end

4349

4270

4350

if VEC_dB <= param.VEC_pass_threshold

4271

if VEC_dB <= param.VEC_pass_threshold

4351

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4272

msg=sprintf('%s: VEC = %.3f dB (pass)\n', ...

4352

(msg), VEC_dB);

4273

(msg), VEC_dB);

4353

else

4274

else

4354

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4275

msg=sprintf('%s: VEC = %.3f dB (FAIL)\n', ...

4355

(msg), VEC_dB);

4276

(msg), VEC_dB);

4356

msgcolor = 'r';

4277

msgcolor = 'r';

4357

end

4278

end

4358

if COM >= param.pass_threshold

4279

if COM >= param.pass_threshold

4359

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4280

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (pass)\n', ...

4360

% msg, COM);

4281

% msg, COM);

4361

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4282

msg=sprintf('%s: COM = %.3f dB (pass)\n', ...

4362

msg, COM);

4283

msg, COM);

4363

else

4284

else

4364

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4285

% msgtext{package_testcase_i}=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4365

% msg, COM);

4286

% msg, COM);

4366

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4287

msg=sprintf('%s: COM = %.3f dB (FAIL)\n', ...

4367

msg, COM);

4288

msg, COM);

4368

msgcolor = 'r';

4289

msgcolor = 'r';

4369

end

4290

end

4370

% begin yasuo patch 3/18/2019

4291

% begin yasuo patch 3/18/2019

4371

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4292

msg=sprintf('%s: DER = %.3e at COM threshold \n', msg, threshold_DER);

4372

% end yasuo patch

4293

% end yasuo patch

4373

end

4294

end

4374

end

4295

end

4375

if OP.ERL

4296

if OP.ERL

4376

if ~isempty(ERL)

4297

if ~isempty(ERL)

4377

if min_ERL >= param.ERL_pass_threshold

4298

if min_ERL >= param.ERL_pass_threshold

4378

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4299

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4379

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4300

msg=[sprintf('%s: PASS ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL)];

4380

else

4301

else

4381

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4302

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4382

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4303

msg=[ sprintf('%s: FAIL ... ERL = %.3f dB (%.3f dB,%.3f dB) \n',msg, min_ERL, ERL) ];

4383

msgcolor = 'r';

4304

msgcolor = 'r';

4384

end

4305

end

4385

end

4306

end

4386

end

4307

end

4387

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4308

h=msgbox(msg, ['COM r' output_args.code_revision ' results']);

4388

set(h, 'color', msgcolor, 'tag', 'COM');

4309

set(h, 'color', msgcolor, 'tag', 'COM');

4389

movegui(h, 'center');

4310

movegui(h, 'center');

4390

else % no windows

4311

else % no windows

4391

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4312

% display(['max noise at BER = ' num2str(peak_interference_at_BER)])

4392

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4313

% display(['signal after eq = ' num2str(A_s/(param.levels-1))])

4393

if ~OP.ERL_ONLY

4314

if ~OP.ERL_ONLY

4394

switch OP.PHY

4315

switch OP.PHY

4395

case 'C2C'

4316

case 'C2C'

4396

if COM >= param.pass_threshold

4317

if COM >= param.pass_threshold

4397

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4318

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4398

else

4319

else

4399

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4320

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4400

end

4321

end

4401

% begin yasuo patch 3/18/2019

4322

% begin yasuo patch 3/18/2019

4402

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4323

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4403

% end yasuo patch

4324

% end yasuo patch

4404

case 'C2Mcom'

4325

case 'C2Mcom'

4405

if VEC_dB <= param.VEC_pass_threshold

4326

if VEC_dB <= param.VEC_pass_threshold

4406

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4327

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4407

else

4328

else

4408

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4329

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4409

end

4330

end

4410

4331

4411

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4332

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4412

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4333

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4413

else

4334

else

4414

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4335

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4415

end

4336

end

4416

if COM >= param.pass_threshold

4337

if COM >= param.pass_threshold

4417

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4338

fprintf('%s <strong> PASS ... COM = %.3f dB</strong>\n', msg, COM);

4418

else

4339

else

4419

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4340

fprintf(2,'%s <strong> FAIL ... COM = %.3f dB</strong>\n', msg, COM);

4420

end

4341

end

4421

% begin yasuo patch 3/18/2019

4342

% begin yasuo patch 3/18/2019

4422

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4343

fprintf('%s DER = %.3e at COM threshold \n', msg, threshold_DER);

4423

% end yasuo patch

4344

% end yasuo patch

4424

case 'C2M'

4345

case 'C2M'

4425

if VEC_dB <= param.VEC_pass_threshold

4346

if VEC_dB <= param.VEC_pass_threshold

4426

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4347

fprintf('%s <strong> PASS ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4427

else

4348

else

4428

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4349

fprintf(2,'%s <strong> FAIL ... VEC = %.3f dB</strong>\n', msg, VEC_dB);

4429

end

4350

end

4430

4351

4431

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4352

if VEO_mV >= param.Min_VEO && VEO_mV <= param.Max_VEO

4432

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4353

fprintf('%s <strong> PASS ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4433

else

4354

else

4434

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4355

fprintf(2,'%s <strong> FAIL ... EH = %.3f mV</strong>\n', msg, VEO_mV);

4435

end

4356

end

4436

end

4357

end

4437

end

4358

end

4438

if OP.ERL

4359

if OP.ERL

4439

if ~isempty(ERL)

4360

if ~isempty(ERL)

4440

if min_ERL >= param.ERL_pass_threshold

4361

if min_ERL >= param.ERL_pass_threshold

4441

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4362

% msgtext{package_testcase_i+1}=[sprintf(' PASS ... ERL = %.3f dB\n', min_ERL)];

4442

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4363

fprintf('%s: <strong> PASS ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL );

4443

else

4364

else

4444

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4365

% msgtext{package_testcase_i+1}=[ sprintf(' FAIL ... ERL = %.3f dB\n', min_ERL) ];

4445

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4366

fprintf(2,'%s: <strong> FAIL ... ERL = %.3f dB (%.3f dB, %.3f dB)</strong>\n',msg, min_ERL, ERL) ;

4446

end

4367

end

4447

end

4368

end

4448

end

4369

end

4449

end

4370

end

4450

4371

4451

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4372

function [Left_EW,Right_EW]=find_eye_width(eye_contour,half_UI,samples_per_UI,vref)

4452

4373

4453

%Left eye Width (Top Eye)

4374

%Left eye Width (Top Eye)

4454

left_top=eye_contour(half_UI:-1:1,1);

4375

left_top=eye_contour(half_UI:-1:1,1);

4455

%vref_crossing is the first point less than vref (usually first point < 0)

4376

%vref_crossing is the first point less than vref (usually first point < 0)

4456

vref_crossing=find(left_top<vref,1,'first');

4377

vref_crossing=find(left_top<vref,1,'first');

4457

if isempty(vref_crossing)

4378

if isempty(vref_crossing)

4458

%this case handles completely open eye

4379

%this case handles completely open eye

4459

L1=half_UI;

4380

L1=half_UI;

4460

elseif vref_crossing==1

4381

elseif vref_crossing==1

4461

%this case handles completely closed eye

4382

%this case handles completely closed eye

4462

L1=0;

4383

L1=0;

4463

else

4384

else

4464

%this case handles the normal eye

4385

%this case handles the normal eye

4465

%INT is a linear interpolation between the 2 points on either side of

4386

%INT is a linear interpolation between the 2 points on either side of

4466

%vref to determine where the vref crossing occurred. In systems with

4387

%vref to determine where the vref crossing occurred. In systems with

4467

%a small number of samples_per_UI, interpolation improves accuracy over

4388

%a small number of samples_per_UI, interpolation improves accuracy over

4468

%just using the integer sample point

4389

%just using the integer sample point

4469

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4390

INT=vref_intersect(eye_contour(1:half_UI,1),half_UI-vref_crossing+1+1,vref);

4470

L1=half_UI-INT;

4391

L1=half_UI-INT;

4471

end

4392

end

4472

%Left eye Width (Bottom Eye)

4393

%Left eye Width (Bottom Eye)

4473

left_bot=eye_contour(half_UI:-1:1,2);

4394

left_bot=eye_contour(half_UI:-1:1,2);

4474

vref_crossing=find(left_bot>vref,1,'first');

4395

vref_crossing=find(left_bot>vref,1,'first');

4475

if isempty(vref_crossing)

4396

if isempty(vref_crossing)

4476

L0=half_UI;

4397

L0=half_UI;

4477

elseif vref_crossing==1

4398

elseif vref_crossing==1

4478

L0=0;

4399

L0=0;

4479

else

4400

else

4480

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4401

INT=vref_intersect(eye_contour(1:half_UI,2),half_UI-vref_crossing+1+1,vref);

4481

L0=half_UI-INT;

4402

L0=half_UI-INT;

4482

end

4403

end

4483

%Right eye Width (Top Eye)

4404

%Right eye Width (Top Eye)

4484

right_top=eye_contour(half_UI:end,1);

4405

right_top=eye_contour(half_UI:end,1);

4485

vref_crossing=find(right_top<vref,1,'first');

4406

vref_crossing=find(right_top<vref,1,'first');

4486

if isempty(vref_crossing)

4407

if isempty(vref_crossing)

4487

R1=samples_per_UI-half_UI;

4408

R1=samples_per_UI-half_UI;

4488

elseif vref_crossing==1

4409

elseif vref_crossing==1

4489

R1=0;

4410

R1=0;

4490

else

4411

else

4491

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4412

INT=vref_intersect(eye_contour(half_UI:end,1),vref_crossing,vref)+half_UI-1;

4492

R1=INT-half_UI;

4413

R1=INT-half_UI;

4493

end

4414

end

4494

%Right eye Width (Bottom Eye)

4415

%Right eye Width (Bottom Eye)

4495

right_bot=eye_contour(half_UI:end,2);

4416

right_bot=eye_contour(half_UI:end,2);

4496

vref_crossing=find(right_bot>vref,1,'first');

4417

vref_crossing=find(right_bot>vref,1,'first');

4497

if isempty(vref_crossing)

4418

if isempty(vref_crossing)

4498

R0=samples_per_UI-half_UI;

4419

R0=samples_per_UI-half_UI;

4499

elseif vref_crossing==1

4420

elseif vref_crossing==1

4500

R0=0;

4421

R0=0;

4501

else

4422

else

4502

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4423

INT=vref_intersect(eye_contour(half_UI:end,2),vref_crossing,vref)+half_UI-1;

4503

R0=INT-half_UI;

4424

R0=INT-half_UI;

4504

end

4425

end

4505

4426

4506

%L1 = top left eye width

4427

%L1 = top left eye width

4507

%L0 = bottom left eye width

4428

%L0 = bottom left eye width

4508

%Left eye width is the minimum

4429

%Left eye width is the minimum

4509

%R1 = top right eye width

4430

%R1 = top right eye width

4510

%R0 = bottom right eye width

4431

%R0 = bottom right eye width

4511

%Right eye width is the minimum

4432

%Right eye width is the minimum

4512

Left_EW=min([L1 L0]);

4433

Left_EW=min([L1 L0]);

4513

Right_EW=min([R1 R0]);

4434

Right_EW=min([R1 R0]);

4514

4435

4515

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4436

function [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk,curval,bmaxg,N_bg)

4516

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4437

% [idx]=findbankloc(hisi,idx_st,idx_en,tap_bk)

4517

% find the location of the DFE bank

4438

% find the location of the DFE bank

4518

% hisi: waveform with cursor values;

4439

% hisi: waveform with cursor values;

4519

% idx_st: starting index;

4440

% idx_st: starting index;

4520

% idx_en: ending index ;

4441

% idx_en: ending index ;

4521

% tap_bk: number of taps per bank;

4442

% tap_bk: number of taps per bank;

4522

% bmaxg: maximum coefficient;

4443

% bmaxg: maximum coefficient;

4523

4444

4524

hisi=hisi(:);

4445

hisi=hisi(:);

4525

len=idx_en-idx_st+1;

4446

len=idx_en-idx_st+1;

4526

h0=abs(hisi(idx_st:idx_en));

4447

h0=abs(hisi(idx_st:idx_en));

4527

h1=max(0,h0-bmaxg*curval);

4448

h1=max(0,h0-bmaxg*curval);

4528

4449

4529

%if cursor value is negative, force h1 to all zeros

4450

%if cursor value is negative, force h1 to all zeros

4530

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4451

%otherwise h1 will become larger than h0 and the values in ndiff will become inverted

4531

%this makes the weakest isi the most desirable to choose so everything breaks

4452

%this makes the weakest isi the most desirable to choose so everything breaks

4532

if curval<0

4453

if curval<0

4533

h1=zeros(size(h0));

4454

h1=zeros(size(h0));

4534

end

4455

end

4535

4456

4536

h0n=zeros(len-tap_bk+1,1);

4457

h0n=zeros(len-tap_bk+1,1);

4537

h1n=h0n;

4458

h1n=h0n;

4538

4459

4539

for ii=1:tap_bk

4460

for ii=1:tap_bk

4540

h0tmp=h0(ii:ii+len-tap_bk);

4461

h0tmp=h0(ii:ii+len-tap_bk);

4541

h0n=h0n+h0tmp.^2;

4462

h0n=h0n+h0tmp.^2;

4542

h1tmp=h1(ii:ii+len-tap_bk);

4463

h1tmp=h1(ii:ii+len-tap_bk);

4543

h1n=h1n+h1tmp.^2;

4464

h1n=h1n+h1tmp.^2;

4544

end

4465

end

4545

4466

4546

ndiff=h0n-h1n;

4467

ndiff=h0n-h1n;

4547

4468

4548

min_energy = -Inf;

4469

min_energy = -Inf;

4549

4470

4550

idx=zeros(1,tap_bk*N_bg);

4471

idx=zeros(1,tap_bk*N_bg);

4551

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4472

ordered_set=(1:(N_bg-1)*tap_bk+1)';

4552

set_next_bank=0;

4473

set_next_bank=0;

4553

%Loop through each group

4474

%Loop through each group

4554

for k=1:N_bg

4475

for k=1:N_bg

4555

%Sort to choose the strongest

4476

%Sort to choose the strongest

4556

[~,val_sort]=sort(ndiff,'descend');

4477

[~,val_sort]=sort(ndiff,'descend');

4557

if k==1

4478

if k==1

4558

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4479

%shortcut: Choose the first 1:N_bg*tap_bk taps if they are the strongest

4559

if isequal(sort(val_sort(ordered_set)),ordered_set)

4480

if isequal(sort(val_sort(ordered_set)),ordered_set)

4560

idx=1:N_bg*tap_bk;

4481

idx=1:N_bg*tap_bk;

4561

break;

4482

break;

4562

end

4483

end

4563

end

4484

end

4564

if set_next_bank>0

4485

if set_next_bank>0

4565

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4486

%when a previous bank (goodV) was found, automatically set the bank without going through the search

4566

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4487

new_bank=set_next_bank:set_next_bank+tap_bk-1;

4567

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4488

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4568

set_next_bank=0;

4489

set_next_bank=0;

4569

ndiff(new_bank)=min_energy;

4490

ndiff(new_bank)=min_energy;

4570

bad_start=new_bank(1)-tap_bk+1;

4491

bad_start=new_bank(1)-tap_bk+1;

4571

bad_end=new_bank(1)-1;

4492

bad_end=new_bank(1)-1;

4572

if bad_end<=0

4493

if bad_end<=0

4573

badV=[];

4494

badV=[];

4574

elseif bad_start>0

4495

elseif bad_start>0

4575

badV=bad_start:bad_end;

4496

badV=bad_start:bad_end;

4576

else

4497

else

4577

badV=1:bad_end;

4498

badV=1:bad_end;

4578

end

4499

end

4579

if ~isempty(badV)

4500

if ~isempty(badV)

4580

ndiff(badV)=min_energy;

4501

ndiff(badV)=min_energy;

4581

end

4502

end

4582

continue;

4503

continue;

4583

end

4504

end

4584

%potential bank = the strongest tap group

4505

%potential bank = the strongest tap group

4585

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4506

new_bank=val_sort(1):val_sort(1)+tap_bk-1;

4586

if k==N_bg

4507

if k==N_bg

4587

%Last group: just choose the strongest

4508

%Last group: just choose the strongest

4588

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4509

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4589

break;

4510

break;

4590

end

4511

end

4591

4512

4592

do_it_again=1;

4513

do_it_again=1;

4593

first_time=1;

4514

first_time=1;

4594

num_loops=0;

4515

num_loops=0;

4595

while do_it_again

4516

while do_it_again

4596

do_it_again=0;

4517

do_it_again=0;

4597

if num_loops>length(ndiff)

4518

if num_loops>length(ndiff)

4598

break;

4519

break;

4599

end

4520

end

4600

%note badV: taps smaller and less than 1 group away

4521

%note badV: taps smaller and less than 1 group away

4601

bad_start=new_bank(1)-tap_bk+1;

4522

bad_start=new_bank(1)-tap_bk+1;

4602

bad_end=new_bank(1)-1;

4523

bad_end=new_bank(1)-1;

4603

if bad_end<=0

4524

if bad_end<=0

4604

badV=[];

4525

badV=[];

4605

elseif bad_start>0

4526

elseif bad_start>0

4606

badV=bad_start:bad_end;

4527

badV=bad_start:bad_end;

4607

else

4528

else

4608

badV=1:bad_end;

4529

badV=1:bad_end;

4609

end

4530

end

4610

for j=length(badV):-1:1

4531

for j=length(badV):-1:1

4611

if any(badV(j)-idx==0)

4532

if any(badV(j)-idx==0)

4612

badV(j)=[];

4533

badV(j)=[];

4613

end

4534

end

4614

end

4535

end

4615

%note goodV: the tap exactly 1 tap_bk smaller

4536

%note goodV: the tap exactly 1 tap_bk smaller

4616

goodV=new_bank(1)-tap_bk;

4537

goodV=new_bank(1)-tap_bk;

4617

if ~isempty(badV)

4538

if ~isempty(badV)

4618

if ~first_time

4539

if ~first_time

4619

[~,val_sort]=sort(ndiff,'descend');

4540

[~,val_sort]=sort(ndiff,'descend');

4620

end

4541

end

4621

first_time=0;

4542

first_time=0;

4622

checkV=[badV new_bank];

4543

checkV=[badV new_bank];

4623

4544

4624

badV_pos=zeros(1,length(badV));

4545

badV_pos=zeros(1,length(badV));

4625

for j=1:length(badV)

4546

for j=1:length(badV)

4626

badV_pos(j)=find(badV(j)==val_sort);

4547

badV_pos(j)=find(badV(j)==val_sort);

4627

end

4548

end

4628

4549

4629

%loop through the sorted list to find the first tap outside the group and not a member of badV

4550

%loop through the sorted list to find the first tap outside the group and not a member of badV

4630

found_goodV=0;

4551

found_goodV=0;

4631

for ii=1:length(val_sort)

4552

for ii=1:length(val_sort)

4632

if val_sort(ii)==goodV

4553

if val_sort(ii)==goodV

4633

found_goodV=1;

4554

found_goodV=1;

4634

break;

4555

break;

4635

end

4556

end

4636

if all(val_sort(ii)-checkV~=0)

4557

if all(val_sort(ii)-checkV~=0)

4637

break;

4558

break;

4638

end

4559

end

4639

end

4560

end

4640

4561

4641

if ~found_goodV && min(badV_pos)<ii

4562

if ~found_goodV && min(badV_pos)<ii

4642

%if goodV wasn't found and bad taps occur before non group members are found

4563

%if goodV wasn't found and bad taps occur before non group members are found

4643

%throw out the strongest tap and take the next strongest

4564

%throw out the strongest tap and take the next strongest

4644

do_it_again=1;

4565

do_it_again=1;

4645

ndiff(new_bank(1))=min_energy;

4566

ndiff(new_bank(1))=min_energy;

4646

%speed up: new max_val is always val_sort(2)

4567

%speed up: new max_val is always val_sort(2)

4647

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4568

new_bank=val_sort(2):val_sort(2)+tap_bk-1;

4648

end

4569

end

4649

if found_goodV

4570

if found_goodV

4650

%if goodV was found, set the next bank to goodV

4571

%if goodV was found, set the next bank to goodV

4651

set_next_bank=goodV;

4572

set_next_bank=goodV;

4652

end

4573

end

4653

end

4574

end

4654

num_loops=num_loops+1;

4575

num_loops=num_loops+1;

4655

end

4576

end

4656

%at the end, the floating taps are set to idx

4577

%at the end, the floating taps are set to idx

4657

%and ndiff has illegal values set to zero

4578

%and ndiff has illegal values set to zero

4658

ndiff(new_bank)=min_energy;

4579

ndiff(new_bank)=min_energy;

4659

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4580

idx(tap_bk*(k-1)+1:tap_bk*k)=new_bank;

4660

if ~isempty(badV)

4581

if ~isempty(badV)

4661

ndiff(badV)=min_energy;

4582

ndiff(badV)=min_energy;

4662

end

4583

end

4663

end

4584

end

4664

4585

4665

4586

4666

idx=idx+idx_st-1;

4587

idx=idx+idx_st-1;

4667

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4588

function [tap_loc,tap_coef,hisi,b]=floatingDFE( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg, curval, dfe_delta)

4668

4589

4669

% hisi = postcursor isi

4590

% hisi = postcursor isi

4670

% N_b = number of fixed dfe taps (before floating taps begin)

4591

% N_b = number of fixed dfe taps (before floating taps begin)

4671

% N_bf = number of floating taps per group

4592

% N_bf = number of floating taps per group

4672

% N_bg = nubmber of groups

4593

% N_bg = nubmber of groups

4673

% N_bmax = max tap number that can be used for floating tap

4594

% N_bmax = max tap number that can be used for floating tap

4674

% bmaxg = max tap strength for floating taps

4595

% bmaxg = max tap strength for floating taps

4675

% curval = value of the cursor

4596

% curval = value of the cursor

4676

4597

4677

4598

4678

if nargin<8, dfe_delta=0;end

4599

if nargin<8, dfe_delta=0;end

4679

4600

4680

4601

4681

tap_coef=zeros(1,length(hisi));

4602

tap_coef=zeros(1,length(hisi));

4682

b=zeros(1,length(hisi));

4603

b=zeros(1,length(hisi));

4683

4604

4684

4605

4685

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4606

[tap_loc]=findbankloc(hisi,N_b+1,N_bmax,N_bf,curval,bmaxg,N_bg);

4686

4607

4687

%Apply DFE to all taps

4608

%Apply DFE to all taps

4688

flt_curval=hisi(tap_loc);

4609

flt_curval=hisi(tap_loc);

4689

if dfe_delta~=0

4610

if dfe_delta~=0

4690

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4611

flt_curval_q=floor(abs(flt_curval/curval)./dfe_delta) .* ...

4691

dfe_delta.*sign(flt_curval)*curval;

4612

dfe_delta.*sign(flt_curval)*curval;

4692

else

4613

else

4693

flt_curval_q=hisi(tap_loc);

4614

flt_curval_q=hisi(tap_loc);

4694

end

4615

end

4695

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4616

applied_coef=min(abs(flt_curval_q/curval),bmaxg).*sign(flt_curval_q);

4696

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4617

hisi(tap_loc)= hisi(tap_loc) - curval*applied_coef;

4697

tap_coef(tap_loc)=applied_coef;

4618

tap_coef(tap_loc)=applied_coef;

4698

4619

4699

4620

4700

4621

4701

tap_loc=sort(tap_loc,'ascend');

4622

tap_loc=sort(tap_loc,'ascend');

4702

b(tap_loc)=bmaxg;

4623

b(tap_loc)=bmaxg;

4703

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4624

function [ bmax floating_tap_locations] = floating_taps_1sttest( hisi,N_b,N_bf,N_bg,N_bmax, bmaxg, COOP )

4704

% Richard Mellitz: 04/23/2019

4625

% Richard Mellitz: 04/23/2019

4705

% hisi is the isi 1 ui/sample

4626

% hisi is the isi 1 ui/sample

4706

% N_b number of fixed dfe taps

4627

% N_b number of fixed dfe taps

4707

% N_bf number of floating taps per group

4628

% N_bf number of floating taps per group

4708

% N_bg number of floating tap groups. 1 2 or 3 right now

4629

% N_bg number of floating tap groups. 1 2 or 3 right now

4709

% N_bmax number of ui for the max reach of the floating taps

4630

% N_bmax number of ui for the max reach of the floating taps

4710

% bmaxg limit for the floating taps

4631

% bmaxg limit for the floating taps

4711

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4632

% COOP = 1 co-optimize banks , -0 sequenatial optmization

4712

%

4633

%

4713

%

4634

%

4714

% function to remove isi or add noise above bmaxg

4635

% function to remove isi or add noise above bmaxg

4715

if ~exist('COOP','var'), COOP=0;end

4636

if ~exist('COOP','var'), COOP=0;end

4716

if iscolumn(hisi); hisi=hisi.';end

4637

if iscolumn(hisi); hisi=hisi.';end

4717

hsis_in=hisi;

4638

hsis_in=hisi;

4718

% find all the reduction group taken N_bf at a time

4639

% find all the reduction group taken N_bf at a time

4719

% we are looking for the group when when remove yield the miminim isi, h, power

4640

% we are looking for the group when when remove yield the miminim isi, h, power

4720

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4641

best_sigma=inf;best_ig1=-1;best_ig2=-1;best_ig3=-1;

4721

% add on switch and loop for each potential group

4642

% add on switch and loop for each potential group

4722

switch N_bg

4643

switch N_bg

4723

case 0

4644

case 0

4724

bmax=0;

4645

bmax=0;

4725

return

4646

return

4726

case 1

4647

case 1

4727

end1=N_bmax-N_bf;

4648

end1=N_bmax-N_bf;

4728

end2=N_b+1;

4649

end2=N_b+1;

4729

end3=N_b+1;

4650

end3=N_b+1;

4730

case 2

4651

case 2

4731

end1=N_bmax-N_bf;

4652

end1=N_bmax-N_bf;

4732

end2=N_bmax-N_bf;

4653

end2=N_bmax-N_bf;

4733

end3=N_b+1;

4654

end3=N_b+1;

4734

case 3

4655

case 3

4735

end1=N_bmax-N_bf;

4656

end1=N_bmax-N_bf;

4736

end2=N_bmax-N_bf;

4657

end2=N_bmax-N_bf;

4737

end3=N_bmax-N_bf;

4658

end3=N_bmax-N_bf;

4738

end

4659

end

4739

if COOP

4660

if COOP

4740

for ig1= N_b+1:end1 % now remove the 2nd group

4661

for ig1= N_b+1:end1 % now remove the 2nd group

4741

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4662

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4742

% loop for 2rd group

4663

% loop for 2rd group

4743

for ig2= N_b+1: end2

4664

for ig2= N_b+1: end2

4744

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4665

hcap2= hrem(hcap,ig2,N_bf,bmaxg) ;

4745

if N_bg < 2; hcap2 =hcap; end

4666

if N_bg < 2; hcap2 =hcap; end

4746

for ig3= N_b+1: end3

4667

for ig3= N_b+1: end3

4747

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4668

hcap3= hrem(hcap2,ig3,N_bf,bmaxg) ;

4748

if N_bg < 3 ; hcap3=hcap2 ; end

4669

if N_bg < 3 ; hcap3=hcap2 ; end

4749

sigma=norm( hcap3 );

4670

sigma=norm( hcap3 );

4750

if sigma < best_sigma

4671

if sigma < best_sigma

4751

best_sigma=sigma;

4672

best_sigma=sigma;

4752

best_ig1=ig1;

4673

best_ig1=ig1;

4753

best_ig2=ig2;

4674

best_ig2=ig2;

4754

best_ig3=ig3;

4675

best_ig3=ig3;

4755

best_hcap=hcap3;

4676

best_hcap=hcap3;

4756

end

4677

end

4757

end

4678

end

4758

end

4679

end

4759

end

4680

end

4760

else % sequentail

4681

else % sequentail

4761

for ig1= N_b+1:end1 % now remove the 1st group

4682

for ig1= N_b+1:end1 % now remove the 1st group

4762

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4683

hcap= hrem(hisi,ig1,N_bf,bmaxg) ;

4763

sigma=norm( hcap );

4684

sigma=norm( hcap );

4764

if sigma < best_sigma

4685

if sigma < best_sigma

4765

best_sigma=sigma;

4686

best_sigma=sigma;

4766

best_ig1=ig1;

4687

best_ig1=ig1;

4767

best_hcap=hcap;

4688

best_hcap=hcap;

4768

end

4689

end

4769

end

4690

end

4770

% loop for 2rd group

4691

% loop for 2rd group

4771

hisi=best_hcap;

4692

hisi=best_hcap;

4772

for ig2= N_b+1: end2

4693

for ig2= N_b+1: end2

4773

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4694

hcap= hrem(hisi,ig2,N_bf,bmaxg) ;

4774

sigma=norm( hcap );

4695

sigma=norm( hcap );

4775

if sigma < best_sigma

4696

if sigma < best_sigma

4776

best_sigma=sigma;

4697

best_sigma=sigma;

4777

best_ig2=ig2;

4698

best_ig2=ig2;

4778

best_hcap=hcap;

4699

best_hcap=hcap;

4779

end

4700

end

4780

end

4701

end

4781

hisi=best_hcap;

4702

hisi=best_hcap;

4782

% loop for 3rd group

4703

% loop for 3rd group

4783

for ig3= N_b+1: end3

4704

for ig3= N_b+1: end3

4784

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4705

hcap= hrem(hisi, ig3,N_bf,bmaxg) ;

4785

sigma=norm( hcap );

4706

sigma=norm( hcap );

4786

if sigma < best_sigma

4707

if sigma < best_sigma

4787

best_sigma=sigma;

4708

best_sigma=sigma;

4788

best_ig3=ig3;

4709

best_ig3=ig3;

4789

best_hcap=hcap;

4710

best_hcap=hcap;

4790

end

4711

end

4791

end

4712

end

4792

4713

4793

end

4714

end

4794

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4715

bmax(N_b+1:N_bmax)=zeros(1,N_bmax-N_b);

4795

switch N_bg

4716

switch N_bg

4796

case 1

4717

case 1

4797

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4718

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4798

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4719

floating_tap_locations= [best_ig1:best_ig1+N_bf-1];

4799

case 2

4720

case 2

4800

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4721

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4801

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4722

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4802

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4723

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 ];

4803

case 3

4724

case 3

4804

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4725

bmax(best_ig1:best_ig1+N_bf-1)=ones(1,N_bf)*bmaxg;

4805

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4726

bmax(best_ig2:best_ig2+N_bf-1)=ones(1,N_bf)*bmaxg;

4806

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4727

bmax(best_ig3:best_ig3+N_bf-1)=ones(1,N_bf)*bmaxg;

4807

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4728

floating_tap_locations= [best_ig1:best_ig1+N_bf-1 best_ig2:best_ig2+N_bf-1 best_ig3:best_ig3+N_bf-1 ];

4808

end

4729

end

4809

floating_tap_locations=sort(floating_tap_locations);

4730

floating_tap_locations=sort(floating_tap_locations);

4810

if 0 % for code debug

4731

if 0 % for code debug

4811

close force all

4732

close force all

4812

stem(best_hcap,'disp','hcap')

4733

stem(best_hcap,'disp','hcap')

4813

hold on

4734

hold on

4814

stem(bmax,'-k','disp','bmax')

4735

stem(bmax,'-k','disp','bmax')

4815

stem(hisi,'disp','hisi')

4736

stem(hisi,'disp','hisi')

4816

hold off

4737

hold off

4817

end

4738

end

4818

4739

4819

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4740

% function [ bmax floating_tap_locations] = floating_taps( hisi, N_b, N_bf, N_bg, N_bmax, bmaxg. COO))

4820

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4741

function [ Vfiltered, Cmod, idx ]= force( V ,param, OP , ix, C, return_V, chdata, txffe, Noise_XC)

4821

% Vfilter is vector forced filtered sbr

4742

% Vfilter is vector forced filtered sbr

4822

% Cmod is the ffe tap co-efficient vector

4743

% Cmod is the ffe tap co-efficient vector

4823

% if C is passed, just process V with C else compute C

4744

% if C is passed, just process V with C else compute C

4824

% cmx=param.rx_cmx; number of pre cursor taps

4745

% cmx=param.rx_cmx; number of pre cursor taps

4825

% cpx=param.rx_cps; number of post cursor taps

4746

% cpx=param.rx_cps; number of post cursor taps

4826

% V=sbr; pass pulse response

4747

% V=sbr; pass pulse response

4827

% ix the sample point in the passed pulse response

4748

% ix the sample point in the passed pulse response

4828

% the sample point is recomputed by optimize_fom

4749

% the sample point is recomputed by optimize_fom

4829

% idx - return floating tap location (RIM 9-19-2023)

4750

% idx - return floating tap location (RIM 9-19-2023)

4830

% OP not used for now

4751

% OP not used for now

4831

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4752

%return_V is a flag with default value = 1. If 0, Vfiltered is not returned

4832

% this allows significant speed up in optimize_fom since FFE is time consuming

4753

% this allows significant speed up in optimize_fom since FFE is time consuming

4833

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4754

% and many combinatiFons of "Cmod" result in illegal combinations that do not need

4834

% Vfiltered to be calculated

4755

% Vfiltered to be calculated

4835

% test with load('SBR_FIR_resp.mydata','-mat')

4756

% test with load('SBR_FIR_resp.mydata','-mat')

4836

idx=[];

4757

idx=[];

4837

if nargin<4

4758

if nargin<4

4838

ix=find(V==max(V),1,'first');

4759

ix=find(V==max(V),1,'first');

4839

end

4760

end

4840

if nargin<5

4761

if nargin<5

4841

C=[];

4762

C=[];

4842

end

4763

end

4843

if nargin<6

4764

if nargin<6

4844

return_V=1;

4765

return_V=1;

4845

end

4766

end

4846

cmx=param.RxFFE_cmx;

4767

cmx=param.RxFFE_cmx;

4847

cpx=param.RxFFE_cpx;

4768

cpx=param.RxFFE_cpx;

4848

% do this early on so we can reuse the old code

4769

% do this early on so we can reuse the old code

4849

if param.N_bg ~=0 % must be floating taps

4770

if param.N_bg ~=0 % must be floating taps

4850

cpx=param.N_bmax; % N_f in spreadsheet

4771

cpx=param.N_bmax; % N_f in spreadsheet

4851

end

4772

end

4852

num_taps=cmx+cpx+1;

4773

num_taps=cmx+cpx+1;

4853

cstep=param.RxFFE_stepz;

4774

cstep=param.RxFFE_stepz;

4854

ndfe=param.ndfe;

4775

ndfe=param.ndfe;

4855

spui=param.samples_per_ui;

4776

spui=param.samples_per_ui;

4856

param.current_ffegain=0;

4777

param.current_ffegain=0;

4857

if return_V && ~isempty(C)

4778

if return_V && ~isempty(C)

4858

% RIM 2-3-23 when we just want to EQ not find EQ

4779

% RIM 2-3-23 when we just want to EQ not find EQ

4859

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4780

Vfiltered=FFE( C , param.RxFFE_cmx,spui, V );

4860

Cmod=C;

4781

Cmod=C;

4861

return

4782

return

4862

end

4783

end

4863

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4784

% Aling V to ix ( the sample point) and then create the sampled vector vsampled_raw

4864

if ix < length(V)

4785

if ix < length(V)

4865

if isrow(V)

4786

if isrow(V)

4866

if mod(ix,spui) == 0

4787

if mod(ix,spui) == 0

4867

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4788

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4868

else

4789

else

4869

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4790

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1)))'; V(ix:spui:end)'];

4870

end

4791

end

4871

4792

4872

else

4793

else

4873

if mod(ix,spui) == 0

4794

if mod(ix,spui) == 0

4874

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4795

vsampled_raw = [V(spui+mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4875

else

4796

else

4876

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4797

vsampled_raw = [V(mod(ix,spui):spui:(mod(ix,spui)+spui*(floor(ix/spui)-1))); V(ix:spui:end)];

4877

end

4798

end

4878

end

4799

end

4879

else

4800

else

4880

if isrow(V)

4801

if isrow(V)

4881

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4802

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4882

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4803

vsampled_raw = V(spui+mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4883

else

4804

else

4884

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4805

vsampled_raw = V(mod(ix,spui):spui:end)';%Yasou Hidaka 11/16/2018

4885

end

4806

end

4886

else

4807

else

4887

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4808

if mod(ix,spui) == 0%Yasou Hidaka 11/16/2018

4888

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4809

vsampled_raw = V(spui+mod(ix,spui):spui:end) ;

4889

else

4810

else

4890

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4811

vsampled_raw = V(mod(ix,spui):spui:end) ;%Yasou Hidaka 11/16/2018

4891

end

4812

end

4892

end

4813

end

4893

end

4814

end

4894

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4815

% zero pad vsampled to account for PR with short delay. RIM 10-02-2023

4895

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4816

vsampled=[zeros(1,num_taps) vsampled_raw' zeros(1,cpx)];% pad for pre and post cursor prior to shifting

4896

4817

4897

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4818

%% find the index, ivs, for the sample point but in the UI resample vector, vsampled

4898

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4819

% ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4899

% Upen Kareti suggested fix for indexing 11/04/18

4820

% Upen Kareti suggested fix for indexing 11/04/18

4900

if ix < length(V)

4821

if ix < length(V)

4901

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4822

ivs=find(vsampled==V(ix),1,'first');% ivs is the sample point for V

4902

else

4823

else

4903

ivs=find(vsampled == max(vsampled),1,'first');

4824

ivs=find(vsampled == max(vsampled),1,'first');

4904

end

4825

end

4905

4826

4906

4827

4907

%% create VV matrix of shifted UI spaced sample of the pulse response

4828

%% create VV matrix of shifted UI spaced sample of the pulse response

4908

% only consider the VV matrix that correstonds to the FFE taps

4829

% only consider the VV matrix that correstonds to the FFE taps

4909

VV=zeros(num_taps,num_taps);

4830

VV=zeros(num_taps,num_taps);

4910

for i=1:num_taps

4831

for i=1:num_taps

4911

start_idx=ivs+i-1;

4832

start_idx=ivs+i-1;

4912

end_idx=start_idx-num_taps+1;

4833

end_idx=start_idx-num_taps+1;

4913

VV(:,i)=vsampled(start_idx:-1:end_idx);

4834

VV(:,i)=vsampled(start_idx:-1:end_idx);

4914

end

4835

end

4915

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4836

% may want to test VV*VV' for rcond here not sure what value to use but 1e-5 is always bad

4916

%% Apply RXFFE

4837

%% Apply RXFFE

4917

if isempty(C)

4838

if isempty(C)

4918

switch upper(OP.FFE_OPT_METHOD)

4839

switch upper(OP.FFE_OPT_METHOD)

4919

case 'WIENER-HOPF'

4840

case 'WIENER-HOPF'

4920

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4841

C= WIENER_HOPF_MMSE(vsampled ,param, OP , chdata, txffe, Noise_XC,ivs) ;

4921

Cmod=C(1:num_taps);

4842

Cmod=C(1:num_taps);

4922

otherwise

4843

otherwise

4923

% cmx+1 is the cursor or sample point

4844

% cmx+1 is the cursor or sample point

4924

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4845

%VV=VV(:,ivs-cmx:ivs+cpx); % only consider the VV matrix that correstonds to the FFE taps

4925

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4846

FV=zeros(1,num_taps); % zero the forceing vector, FV first

4926

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4847

FV(cmx+1)=vsampled(ivs)*10^(param.current_ffegain/20); % force the voltage at sample point

4927

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4848

if param.ndfe~=0 && (cpx > 0) % Yasuo Hidaka suggest fix for no postC 11/11/18

4928

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4849

% FV(cmx+2)=param.bmax(1)*FV(cmx+1); % force the post cursor to bmax if dfe exists

4929

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4850

FV(cmx+2)=min(param.bmax(1)*FV(cmx+1),abs(vsampled(ivs+1)))*sign(vsampled(ivs+1));

4930

end

4851

end

4931

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4852

%C=((VV'*VV)^-1*VV')'*FV'; % sikve for FFE taps, C

4932

if diff(size(VV))==0

4853

if diff(size(VV))==0

4933

%For square matrix, can solve C using simple inv(VV')*FV'

4854

%For square matrix, can solve C using simple inv(VV')*FV'

4934

C=VV'\FV';

4855

C=VV'\FV';

4935

else

4856

else

4936

%otherwise use the general solution with psuedo inverse

4857

%otherwise use the general solution with psuedo inverse

4937

%note: this is the same as doing pinv(VV') but pinv is far slower

4858

%note: this is the same as doing pinv(VV') but pinv is far slower

4938

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4859

% C=(inv(VV'*VV)*VV')'*FV'; % sikve for FFE taps, C

4939

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4860

C=(inv(VV*VV')*VV)*FV'; % sikve for FFE taps, C

4940

end

4861

end

4941

4862

4942

Cmod=C(1:num_taps);

4863

Cmod=C(1:num_taps);

4943

end

4864

end

4944

4865

4945

4866

4946

% added for 4.2 find floating taps with either ISI or taps

4867

% added for 4.2 find floating taps with either ISI or taps

4947

switch lower(OP.RXFFE_FLOAT_CTL)

4868

switch lower(OP.RXFFE_FLOAT_CTL)

4948

case 'taps'

4869

case 'taps'

4949

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4870

[idx]=findbankloc(Cmod,param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4950

otherwise

4871

otherwise

4951

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4872

[idx]=findbankloc(VV(cmx+1,:),param.N_tail_start,param.N_bmax,param.N_bf,Cmod(cmx+1),param.bmaxg,param.N_bg);

4952

end

4873

end

4953

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4874

switch lower(OP.RXFFE_TAP_CONSTRAINT)

4954

case 'unity cursor'

4875

case 'unity cursor'

4955

Cmod=Cmod/Cmod(cmx+1);

4876

Cmod=Cmod/Cmod(cmx+1);

4956

otherwise

4877

otherwise

4957

Cmod=C;

4878

Cmod=C;

4958

end

4879

end

4959

if cstep ~= 0

4880

if cstep ~= 0

4960

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4881

Cmod=floor(abs(Cmod/cstep)).*sign(Cmod)*cstep;% r250 quantize with floor ad sign(C)

4961

end

4882

end

4962

4883

4963

if ~isempty(idx)

4884

if ~isempty(idx)

4964

idx=sort(idx);

4885

idx=sort(idx);

4965

C1=Cmod;

4886

C1=Cmod;

4966

% C1(param.N_tail_start:end)=0;

4887

% C1(param.N_tail_start:end)=0;

4967

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4888

C1(param.RxFFE_cmx+param.RxFFE_cpx+2:end)=0; % zero out flosting taps

4968

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4889

C1(cmx+1+idx)=Cmod(cmx+1+idx);

4969

Cmod=C1;

4890

Cmod=C1;

4970

else

4891

else

4971

% Cmod=C;

4892

% Cmod=C;

4972

end

4893

end

4973

4894

4974

% now when ussing RxFFE floating taps need to tag stems correctly and

4895

% now when ussing RxFFE floating taps need to tag stems correctly and

4975

% make sure DFEfloating tap code does not get exectuted

4896

% make sure DFEfloating tap code does not get exectuted

4976

4897

4977

%

4898

%

4978

else

4899

else

4979

Cmod=C;%just us the FFE taps, C, passed for filtering

4900

Cmod=C;%just us the FFE taps, C, passed for filtering

4980

end

4901

end

4981

%%

4902

%%

4982

%% filter the pulse response with the solved FFE

4903

%% filter the pulse response with the solved FFE

4983

% (now option to avoid this and just return Cmod for speed up)

4904

% (now option to avoid this and just return Cmod for speed up)

4984

if return_V

4905

if return_V

4985

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4906

Vfiltered=FFE( Cmod , param.RxFFE_cmx,spui, V );

4986

else

4907

else

4987

Vfiltered=[];

4908

Vfiltered=[];

4988

end

4909

end

4989

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4910

function [ILN, efit]= get_ILN(sdd21,faxis_f2)

4990

% used for FD IL fitting

4911

% used for FD IL fitting

4991

% sdd21 us a complex insertion loss

4912

% sdd21 us a complex insertion loss

4992

db = @(x) 20*log10(abs(x));

4913

db = @(x) 20*log10(abs(x));

4993

sdd21=squeeze(sdd21);

4914

sdd21=squeeze(sdd21);

4994

if iscolumn(sdd21)

4915

if iscolumn(sdd21)

4995

sdd21=sdd21.';

4916

sdd21=sdd21.';

4996

end

4917

end

4997

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4918

fmbg=[ones(length(faxis_f2),1).*transpose(abs(sdd21)) transpose(sqrt(faxis_f2)).*transpose(abs(sdd21)) transpose(faxis_f2).*transpose(abs(sdd21)) transpose(faxis_f2.^2).*transpose(abs(sdd21)) ];

4998

warning('off','MATLAB:nearlySingularMatrix');

4919

warning('off','MATLAB:nearlySingularMatrix');

4999

LGw=transpose(abs(sdd21).*db(sdd21));

4920

LGw=transpose(abs(sdd21).*db(sdd21));

5000

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4921

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5001

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4922

efit=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5002

ILN = db(sdd21)-efit;

4923

ILN = db(sdd21)-efit;

5003

4924

5004

4925

5005

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

4926

function [ILN, efit, TD_ILN]= get_ILN_cmp_td(sdd21,faxis_f2,OP,param,A_T)

5006

% Complex IL fitting

4927

% Complex IL fitting

5007

% sdd21 us a complex insertion loss

4928

% sdd21 us a complex insertion loss

5008

% efit and ILN are in db

4929

% efit and ILN are in db

5009

% faxix_f2 needs to be at least to fb

4930

% faxix_f2 needs to be at least to fb

5010

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

4931

% return reflections TD_ILN.FOM based on time domain PR fit from pulse peak

5011

% still need to settle on voltage scaling.

4932

% still need to settle on voltage scaling.

5012

% maybe db(peak/Rss

4933

% maybe db(peak/Rss

5013

4934

5014

OP.interp_sparam_mag= 'trend_to_DC';

4935

OP.interp_sparam_mag= 'trend_to_DC';

5015

OP.interp_sparam_phase= 'interp_to_DC';

4936

OP.interp_sparam_phase= 'interp_to_DC';

5016

% OP.interp_sparam_mag= 'linear_trend_to_DC';

4937

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5017

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

4938

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5018

4939

5019

print_for_codereview=0;

4940

print_for_codereview=0;

5020

if ~exist('A_T','var')

4941

if ~exist('A_T','var')

5021

A_T=1;

4942

A_T=1;

5022

end

4943

end

5023

4944

5024

db = @(x) 20*log10(abs(x));

4945

db = @(x) 20*log10(abs(x));

5025

sdd21=squeeze(sdd21);

4946

sdd21=squeeze(sdd21);

5026

if iscolumn(sdd21)

4947

if iscolumn(sdd21)

5027

sdd21=sdd21.';

4948

sdd21=sdd21.';

5028

end

4949

end

5029

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

4950

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5030

warning('off','MATLAB:nearlySingularMatrix');

4951

warning('off','MATLAB:nearlySingularMatrix');

5031

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

4952

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5032

LGw=transpose(sdd21.*unwraplog);

4953

LGw=transpose(sdd21.*unwraplog);

5033

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

4954

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5034

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

4955

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5035

FIT=transpose(exp(transpose(efit_C)));

4956

FIT=transpose(exp(transpose(efit_C)));

5036

efit=db(abs(FIT));

4957

efit=db(abs(FIT));

5037

ILN = db(sdd21)-efit;

4958

ILN = db(sdd21)-efit;

5038

% time domain

4959

% time domain

5039

fprintf('computing TD_ILN (dB) ...')

4960

fprintf('computing TD_ILN (dB) ...')

5040

if exist('OP','var')

4961

if exist('OP','var')

5041

% OP.fraction_of_F_range_start_extrap_from=.95;

4962

% OP.fraction_of_F_range_start_extrap_from=.95;

5042

OP.impulse_response_truncation_threshold =1e-7;

4963

OP.impulse_response_truncation_threshold =1e-7;

5043

4964

5044

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

4965

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5045

H_bw=Butterworth_Filter(param,faxis_f2,1);

4966

H_bw=Butterworth_Filter(param,faxis_f2,1);

5046

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

4967

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5047

H_tw=Tukey_Window(faxis_f2,param);

4968

H_tw=Tukey_Window(faxis_f2,param);

5048

H_tw=ones(1,length(faxis_f2) );

4969

H_tw=ones(1,length(faxis_f2) );

5049

4970

5050

[TD_ILN.REF.FIR, ...

4971

[TD_ILN.REF.FIR, ...

5051

TD_ILN.REF.t, ...

4972

TD_ILN.REF.t, ...

5052

TD_ILN.REF.causality_correction_dB, ...

4973

TD_ILN.REF.causality_correction_dB, ...

5053

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4974

TD_ILN.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5054

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

4975

TD_ILN.REF.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.REF.FIR);

5055

4976

5056

[TD_ILN.FIT.FIR, ...

4977

[TD_ILN.FIT.FIR, ...

5057

TD_ILN.FIT.t, ...

4978

TD_ILN.FIT.t, ...

5058

TD_ILN.FIT.causality_correction_dB, ...

4979

TD_ILN.FIT.causality_correction_dB, ...

5059

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

4980

TD_ILN.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bt.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5060

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

4981

TD_ILN.FIT.PR=filter(ones(1, param.samples_per_ui), 1, TD_ILN.FIT.FIR);

5061

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

4982

ipeak=find(TD_ILN.REF.PR==max(TD_ILN.REF.PR),1,'first');

5062

% NrangeUI=1000;

4983

% NrangeUI=1000;

5063

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

4984

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(TD_ILN.FIT.PR)-param.samples_per_ui ),length(TD_ILN.REF.PR)-param.samples_per_ui);

5064

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

4985

range_end= min(length(TD_ILN.REF.PR), length(TD_ILN.FIT.PR));

5065

range=ipeak:range_end;

4986

range=ipeak:range_end;

5066

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

4987

TD_ILN.ILN=TD_ILN.FIT.PR(range)-TD_ILN.REF.PR(range);

5067

TD_ILN.t=TD_ILN.FIT.t(range);

4988

TD_ILN.t=TD_ILN.FIT.t(range);

5068

TD_ILN.FOM=-inf;

4989

TD_ILN.FOM=-inf;

5069

TD_ILN.FOM_PDF=-inf;

4990

TD_ILN.FOM_PDF=-inf;

5070

rms_fom=-inf;

4991

rms_fom=-inf;

5071

for im=1:param.samples_per_ui

4992

for im=1:param.samples_per_ui

5072

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

4993

TD_ILN.FOM=max(TD_ILN.FOM, norm( TD_ILN.ILN(im:param.samples_per_ui:end)));

5073

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

4994

[ pdf ] = get_pdf_from_sampled_signal( TD_ILN.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5074

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

4995

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5075

cdf=pdf; cdf.y=cumsum(pdf.y);

4996

cdf=pdf; cdf.y=cumsum(pdf.y);

5076

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

4997

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5077

% signal_and_isi_pdf = conv_fct(cursors, pdf);

4998

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5078

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

4999

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5079

if print_for_codereview % remove once all checked out

5000

if print_for_codereview % remove once all checked out

5080

h=figure(190);set(gcf,'Tag','COM');

5001

h=figure(190);set(gcf,'Tag','COM');

5081

semilogy(-cdf.x,cdf.y);

5002

semilogy(-cdf.x,cdf.y);

5082

% xlim ([0,-cdf.x(1)])

5003

% xlim ([0,-cdf.x(1)])

5083

ylim([param.specBER 1]);title ('CDF of ILN')

5004

ylim([param.specBER 1]);title ('CDF of ILN')

5084

hold on

5005

hold on

5085

end

5006

end

5086

if rms>rms_fom

5007

if rms>rms_fom

5087

rms_fom=rms;

5008

rms_fom=rms;

5088

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5009

TD_ILN.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5089

TD_ILN.PDF=pdf;

5010

TD_ILN.PDF=pdf;

5090

end

5011

end

5091

end

5012

end

5092

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5013

pdf_from_norm=normal_dist(TD_ILN.FOM, 7 , OP.BinSize);

5093

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5014

TD_ILN.SNR_ISI_FOM=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM);

5094

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5015

TD_ILN.SNR_ISI_FOM_PDF=db(TD_ILN.FIT.PR(ipeak)/TD_ILN.FOM_PDF);

5095

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5016

% fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM)

5096

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5017

fprintf('%g dB\n',TD_ILN.SNR_ISI_FOM_PDF)

5097

if print_for_codereview % remove once all checked out

5018

if print_for_codereview % remove once all checked out

5098

figure(9000);set(gcf,'Tag','COM');

5019

figure(9000);set(gcf,'Tag','COM');

5099

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5020

plot(TD_ILN.t,TD_ILN.ILN,'disp','td iln')

5100

hold on

5021

hold on

5101

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5022

plot(TD_ILN.FIT.t,TD_ILN.FIT.PR,'disp','fit')

5102

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5023

plot(TD_ILN.REF.t,TD_ILN.REF.PR,'disp','ref')

5103

hold off

5024

hold off

5104

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5025

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',TD_ILN.SNR_ISI_FOM,TD_ILN.SNR_ISI_FOM_PDF)

5105

figure(9002);set(gcf,'Tag','COM');

5026

figure(9002);set(gcf,'Tag','COM');

5106

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5027

semilogy(TD_ILN.PDF.x,TD_ILN.PDF.y,'disp','actual PDF')

5107

hold on

5028

hold on

5108

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5029

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5109

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5030

ylim([param.specBER max([TD_ILN.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5110

grid on

5031

grid on

5111

legend('show')

5032

legend('show')

5112

end

5033

end

5113

end

5034

end

5114

% display('got to end of get_ILN_cmp_td')

5035

% display('got to end of get_ILN_cmp_td')

5115

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5036

function result = get_PSDs(result,h,cursor_i, txffe,G_DC,G_DC2,param,chdata,OP)

5116

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5037

% OP.COMPUTE_COM is when called after the optimization and returns sigma_Gbest_hk

5117

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5038

% as well the Sn with the Rx ffe and Hisi included as sigma ISI inclued

5118

if 1 % force indent for doc

5039

if 1 % force indent for doc

5119

num_ui=param.num_ui_RXFF_noise;

5040

num_ui=param.num_ui_RXFF_noise;

5120

M=param.samples_per_ui;

5041

M=param.samples_per_ui;

5121

L=param.levels;

5042

L=param.levels;

5122

f_b=param.fb;

5043

f_b=param.fb;

5123

SNR_TX=param.SNR_TX;

5044

SNR_TX=param.SNR_TX;

5124

dw=param.RxFFE_cmx;

5045

dw=param.RxFFE_cmx;

5125

bmax=param.bmax;

5046

bmax=param.bmax;

5126

bmin=param.bmin ;

5047

bmin=param.bmin ;

5127

Nb=param.ndfe;

5048

Nb=param.ndfe;

5128

sigma_X2=(L^2-1)/(3*(L-1)^2);

5049

sigma_X2=(L^2-1)/(3*(L-1)^2);

5129

eta_0=param.eta_0; %V^2/GHz

5050

eta_0=param.eta_0; %V^2/GHz

5130

T_b=1/f_b;

5051

T_b=1/f_b;

5131

delta_f = f_b/num_ui; % Units are Hz.

5052

delta_f = f_b/num_ui; % Units are Hz.

5132

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5053

fvec = (0:num_ui*M/2)*delta_f; % Single-sided frequency axis.

5133

result.fvec=fvec;

5054

result.fvec=fvec;

5134

end

5055

end

5135

if OP.COMPUTE_COM

5056

if OP.COMPUTE_COM

5136

%% H_rxffe eq 178A-28 d1.0

5057

%% H_rxffe eq 178A-29 d0.2

5137

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5058

% chdata(xchan).ctle_imp_response is conputed with the RxFFE during the COM compuatation

5138

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5059

% H_rxffe.^2 is distributed S_jn and S_rn since they do not use use chdata(xchan).ctle_imp_response

5139

H_rxffe=0;

5060

H_rxffe=0;

5140

for nn=1:length(result.w)

5061

for nn=1:length(result.w)

5141

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5062

H_rxffe=result.w(nn)*exp(-1j*2*pi*fvec*T_b*(nn-dw-1))+H_rxffe;

5142

end

5063

end

5143

H_rxffe_2_of_f=abs(H_rxffe).^2;

5064

H_rxffe_2_of_f=abs(H_rxffe).^2;

5144

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5065

H_rxffe_2=H_rxffe_2_of_f(1:num_ui/2+1);

5145

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5066

H_rxffe_2= [real( H_rxffe_2(1)), H_rxffe_2(2:end-1), real( H_rxffe_2(end)), conj( H_rxffe_2(end-1:-1:2))];

5146

else

5067

else

5147

H_rxffe_2=1;

5068

H_rxffe_2=1;

5148

end

5069

end

5149

5070

5150

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5071

if OP.WO_TXFFE % to speed up loop find sn onlu first time ctle is case

5151

% --->this is the point in the code may fork where we add extra rx noise

5072

% --->this is the point in the code may fork where we add extra rx noise

5152

%% compute S_rn ( eq 178A-15 d0.2 )

5073

%% compute S_rn ( eq 178A-15 d0.2 )

5153

if ~OP.COMPUTE_COM

5074

if ~OP.COMPUTE_COM

5154

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5075

S_RN_of_f=S_RN(fvec,G_DC,G_DC2,param);

5155

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5076

rxn_psd=[real(S_RN_of_f(1)), S_RN_of_f(2:end-1), real(S_RN_of_f(end)), conj(S_RN_of_f(end-1:-1:2))]; % Convert single-sided frequency response to conjugate-symmetric

5156

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5077

rxn_psd=rxn_psd/1e9;% Units are V^2/Hz.

5157

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5078

rxn_rms = sqrt(sum(rxn_psd)* delta_f);

5158

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5079

S_rn = sum(reshape(rxn_psd, num_ui, M).');

5159

S_rn=S_rn(1:num_ui/2+1);

5080

S_rn=S_rn(1:num_ui/2+1);

5160

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5081

S_rn= [real( S_rn(1)), S_rn(2:end-1), real( S_rn(end)), conj( S_rn(end-1:-1:2))];

5161

result.S_rn=S_rn;

5082

result.S_rn=S_rn;

5162

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5083

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5163

else

5084

else

5164

result.S_rn=result.S_rn.*H_rxffe_2;

5085

result.S_rn=result.S_rn.*H_rxffe_2;

5165

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5086

result.S_rn_rms = sqrt(sum(result.S_rn)* delta_f);

5166

end

5087

end

5167

5088

5168

else % find noise for item that set have tx ffe for each loop

5089

else % find noise for item that set have tx ffe for each loop

5169

%% S_xn from eq 178A-16

5090

%% S_xn from eq 178A-16

5170

%% Crosstalk power spectral density

5091

%% Crosstalk power spectral density

5171

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5092

if ~OP.COMPUTE_COM % result.S_xn and result.S_xn_rms were found in optimizes_fom and passed in with the variable result

5172

result.S_xn=0;

5093

result.S_xn=0;

5173

if length(chdata)~=1

5094

if length(chdata)~=1

5174

for xchan=2:length(chdata)

5095

for xchan=2:length(chdata)

5175

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5096

pulse_ctle=filter(ones(1,M),1,chdata(xchan).ctle_imp_response(:).');

5176

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5097

pulse_ctle=[ pulse_ctle(1:floor(length(pulse_ctle)/M)*M) ];

5177

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5098

hk(xchan).k=chdata(xchan).pulse_response_w_CFT_TXFFE_noRxFFE.';

5178

% enable less UI for computation speed improvement

5099

% enable less UI for computation speed improvement

5179

%%

5100

%%

5180

if num_ui*M > length(pulse_ctle)

5101

if num_ui*M > length(pulse_ctle)

5181

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5102

hk(xchan).k= [ hk(xchan).k zeros(1,num_ui*M-length(hk(xchan).k)) ];% crosstalk pulse responces

5182

else

5103

else

5183

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5104

hk(xchan).k=hk(xchan).k(1:num_ui*M);

5184

end

5105

end

5185

for i1=1:M

5106

for i1=1:M

5186

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5107

hxn(i1)=norm(hk(xchan).k(i1:M:length(hk(xchan).k)) );

5187

end

5108

end

5188

iphase(xchan)=find(hxn==max(hxn));

5109

iphase(xchan)=find(hxn==max(hxn));

5189

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5110

hk(xchan).hrn= hk(xchan).k(iphase(xchan):M:length(hk(xchan).k));

5190

result.hk(xchan).hrn= hk(xchan).hrn;

5111

result.hk(xchan).hrn= hk(xchan).hrn;

5191

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5112

hk(xchan).S_xn=sigma_X2*(abs(fft(hk(xchan).hrn))).^2/param.fb;

5192

result.S_xn=hk(xchan).S_xn+result.S_xn;

5113

result.S_xn=hk(xchan).S_xn+result.S_xn;

5193

end

5114

end

5194

result.S_xn=result.S_xn;

5115

result.S_xn=result.S_xn;

5195

result.hk=hk;

5116

result.hk=hk;

5196

result.iphase=iphase;

5117

result.iphase=iphase;

5197

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5118

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5198

else % if no crosstalk, perserve structure and return 0 for S_xn

5119

else % if no crosstalk, perserve structure and return 0 for S_xn

5199

result.S_xn=0;

5120

result.S_xn=0;

5200

result.hk=[];

5121

result.hk=[];

5201

result.iphase=1;

5122

result.iphase=1;

5202

result.S_xn_rms = 0;

5123

result.S_xn_rms = 0;

5203

end

5124

end

5204

else % adjust for H_rxffe when computing COM

5125

else % adjust for H_rxffe when computing COM

5205

result.S_xn=result.S_xn.*H_rxffe_2;

5126

result.S_xn=result.S_xn.*H_rxffe_2;

5206

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5127

result.S_xn_rms = sqrt(sum(result.S_xn)* delta_f);

5207

end

5128

end

5208

%% S_tn from eq 178A-17

5129

%% S_tn from eq 178A-17

5209

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5130

%% if not in the opimization use value found in optimize_fom times |Hrxffe|^2

5210

%% Transmitter noise power spectral density

5131

%% Transmitter noise power spectral density

5211

if ~OP.COMPUTE_COM

5132

if ~OP.COMPUTE_COM

5212

if ~OP.TDMODE

5133

if ~OP.TDMODE

5213

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5134

htn=filter(ones(1,M),1,chdata(1).ctle_imp_response); % ctle_imp_response does not have TxFFE included

5214

else % only use when the input was a pulse response not s-parameters

5135

else % only use when the input was a pulse response not s-parameters

5215

if isfield(chdata(1),'ctle_pulse_response')

5136

if isfield(chdata(1),'ctle_pulse_response')

5216

htn=chdata(1).ctle_pulse_response;

5137

htn=chdata(1).ctle_pulse_response;

5217

else

5138

else

5218

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5139

htn=filter(ones(1,param.samples_per_ui),1, chdata(1).ctle_imp_response);

5219

end

5140

end

5220

end

5141

end

5221

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5142

htn=htn(mod(cursor_i,M)+1:end-mod(cursor_i,M)); % align to sample point

5222

htn=reshape(htn,1,[]); % make row vectors

5143

htn=reshape(htn,1,[]); % make row vectors

5223

htn=[ htn(1:floor(length(htn)/M)*M) ];

5144

htn=[ htn(1:floor(length(htn)/M)*M) ];

5224

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5145

htn= [htn zeros(1,num_ui*M-length(htn)) ];

5225

htn=htn(1:M:end);% resample

5146

htn=htn(1:M:end);% resample

5226

if num_ui>length(htn)

5147

if num_ui>length(htn)

5227

hext=[htn zeros(1,num_ui-length(htn))];

5148

hext=[htn zeros(1,num_ui-length(htn))];

5228

else

5149

else

5229

hext=htn(1:num_ui);

5150

hext=htn(1:num_ui);

5230

end

5151

end

5231

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5152

result.S_tn=sigma_X2*10^(-SNR_TX/10)*(abs(fft(hext))).^2/param.fb; % this corresponds to +/- pi

5232

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5153

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5233

else

5154

else

5234

result.S_tn=result.S_tn.*H_rxffe_2;

5155

result.S_tn=result.S_tn.*H_rxffe_2;

5235

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5156

result.S_tn_rms = sqrt(sum(result.S_tn)* delta_f);

5236

end

5157

end

5237

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5158

%% S_jn from eq 178A-17 Srj_jn from eq 178A-31

5238

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5159

%% RxFFE,CTLE, and TxFFE was applied in Apply_EQ when called after optimize_fom

5239

%% Power spectral density of noise due to jitter

5160

%% Power spectral density of noise due to jitter

5240

%% Eq. 93A-28 %%

5161

%% Eq. 93A-28 %%

5241

if ~OP.COMPUTE_COM

5162

if ~OP.COMPUTE_COM

5242

sampling_offset = mod(cursor_i, M);

5163

sampling_offset = mod(cursor_i, M);

5243

%ensure we can take early sample

5164

%ensure we can take early sample

5244

if sampling_offset<=1

5165

if sampling_offset<=1

5245

sampling_offset=sampling_offset+M;

5166

sampling_offset=sampling_offset+M;

5246

end

5167

end

5247

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5168

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

5248

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5169

cursors_early_sample = h(cursor_i-1+M*(-1:param.ndfe));

5249

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5170

cursors_late_sample = h(cursor_i+1+M*(-1:param.ndfe));

5250

else

5171

else

5251

cursors_early_sample = h(sampling_offset-1:M:end);

5172

cursors_early_sample = h(sampling_offset-1:M:end);

5252

cursors_late_sample = h(sampling_offset+1:M:end);

5173

cursors_late_sample = h(sampling_offset+1:M:end);

5253

end

5174

end

5254

% ensure lengths are equal

5175

% ensure lengths are equal

5255

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5176

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

5256

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5177

h_J = (cursors_late_sample-cursors_early_sample)/2*M;

5257

h_J=reshape(h_J,1,[]); % make row vectors

5178

h_J=reshape(h_J,1,[]); % make row vectors

5258

if num_ui>length(h_J)

5179

if num_ui>length(h_J)

5259

h_J=[h_J zeros(1,num_ui-length(h_J))];

5180

h_J=[h_J zeros(1,num_ui-length(h_J))];

5260

else

5181

else

5261

h_J=h_J(1:num_ui);

5182

h_J=h_J(1:num_ui);

5262

end

5183

end

5263

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5184

result.S_jn=sigma_X2*(param.A_DD^2+param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5264

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5185

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5265

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5186

result.S_rj_jn=sigma_X2*(param.sigma_RJ^2)*(abs(fft(h_J))).^2/param.fb; % this corresponds to +/- pi

5266

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5187

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5267

else

5188

else

5268

result.S_jn=result.S_jn.*H_rxffe_2;

5189

result.S_jn=result.S_jn.*H_rxffe_2;

5269

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5190

result.S_jn_rms = sqrt(sum(result.S_jn)* delta_f);

5270

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5191

result.S_rj_jn= result.S_rj_jn.*H_rxffe_2;

5271

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5192

result.S_rj_rms = sqrt(sum(result.S_rj_jn)* delta_f);

5272

end

5193

end

5273

% result.S_jn

5194

% result.S_jn

5274

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5195

result.S_n=result.S_rn+ result.S_tn+ result.S_xn+ result.S_jn;

5275

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5196

result.S_n_rms = sqrt(sum(result.S_n)* delta_f);

5276

5197

5277

%%

5198

%%

5278

%% Hisi to be included in MLSE rho eq 178a-28

5199

%% Hisi to be included in MLSE rho eq 178a-28

5279

if OP.COMPUTE_COM

5200

if OP.COMPUTE_COM

5280

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5201

%% Hisi psd h include CTLE(CFT), TxFFE, and RxFFE but not sigma_X2

5281

% sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5202

sampling_offset = mod(cursor_i-1, M)+1; % Commit request 4p4_6, healey_3dj_COM_01_240416

5282

% hisi=h(sampling_offset:M:end);

5203

hisi=h(sampling_offset:M:end);

5283

% hisi=hisi(:).';

5204

hisi=hisi(:).';

5284

% if num_ui>length(hisi)

5205

if num_ui>length(hisi)

5285

% hisi=[hisi zeros(1,num_ui-length(hisi))];

5206

hisi=[hisi zeros(1,num_ui-length(hisi))];

5286

% else

5207

else

5287

% hisi=hisi(1:num_ui);% sometime cable channels need a bigger num_ui. prehap compare to the tripple transit time and compute num_ui

5208

hisi=hisi(1:num_ui);

5288

% end

5209

end

5289

% cursor_n=find(hisi==max(hisi),1','first');

5290

samp_idx = (mod(cursor_i-1,M)+1):M:length(h);% Commit request 4p5_2, healey_3dj_COM_01_240521.pdf

5210

cursor_n=floor(cursor_i/M)+1;

5291

cursor_n=find(samp_idx == cursor_i);

5292

hisi=h(samp_idx);

5293

hisi(end+1:num_ui)=0;

5294

hisi=reshape(hisi(1:num_ui),1,[]);

5295

%% Eq 178a-29

5296

for ii=1:length(hisi)

5211

for ii=1:length(hisi)

5297

if ii==cursor_n % cursor

5212

if ii==cursor_n % cursor

5298

cursor=hisi(ii);

5213

cursor=hisi(ii);

5299

hisi(ii)= 0;

5214

hisi(ii)= 0;

5300

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5215

elseif ii >= cursor_n+1 && ii <=cursor_n+Nb

5301

ib_indx=ii-cursor_n;

5216

ib_indx=ii-cursor_n;

5302

if hisi(ii) >= bmax(ib_indx)*cursor

5217

if hisi(ii) >= bmax(ib_indx)*cursor

5303

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5218

hisi(ii) = hisi(ii) - bmax(ib_indx)*cursor;

5304

elseif hisi(ii) <= bmin(ib_indx)*cursor

5219

elseif hisi(ii) <= bmin(ib_indx)*cursor

5305

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5220

hisi(ii) = hisi(ii) - bmin(ib_indx)*cursor;

5306

else

5221

else

5307

hisi(ii)=0;

5222

hisi(ii)=0;

5308

end

5223

end

5309

end

5224

end

5310

end

5225

end

5311

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5226

result.S_isi=sigma_X2*(abs(fft(hisi))).^2/param.fb;

5312

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5227

result.S_isi_rms = sqrt(sum(result.S_isi)* delta_f);

5313

%%

5228

%%

5314

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5229

result.S_G=result.S_tn+ result.S_rj_jn + result.S_rn; % eq 178A-30

5315

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5230

result.S_G_rms = sqrt(sum(result.S_G)* delta_f);

5316

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5231

result.Sn_rho=result.S_isi +result.S_n; % need to include xtalk and isi

5317

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5232

result.Sn_rho_rms = sqrt(sum(result.Sn_rho)* delta_f);

5318

end

5233

end

5319

end

5234

end

5320

function result=get_PulseR(ir,param,cb_step,ZT)

5235

function result=get_PulseR(ir,param,cb_step,ZT)

5321

%ir = impulse response

5236

%ir = impulse response

5322

%t_base=time array with equal time steps

5237

%t_base=time array with equal time steps

5323

%samp_UI = number of samples per UI for ir

5238

%samp_UI = number of samples per UI for ir

5324

5239

5325

% t for debug

5240

% t for debug

5326

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5241

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5327

5242

5328

if cb_step

5243

if cb_step

5329

Ag=1;

5244

Ag=1;

5330

dt=1/param.fb/param.samples_per_ui;

5245

dt=1/param.fb/param.samples_per_ui;

5331

edge_time=param.TR_TDR*1e-9;

5246

edge_time=param.TR_TDR*1e-9;

5332

fedge=1/edge_time;

5247

fedge=1/edge_time;

5333

tedge=0:dt:edge_time*2;

5248

tedge=0:dt:edge_time*2;

5334

%

5249

%

5335

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5250

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5336

drive_pulse=[edge ones(1,param.samples_per_ui)];

5251

drive_pulse=[edge ones(1,param.samples_per_ui)];

5337

%pulse=filter(UI_ones,1,ir);

5252

%pulse=filter(UI_ones,1,ir);

5338

% t for debug

5253

% t for debug

5339

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5254

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5340

5255

5341

pulse=filter(drive_pulse,1,ir);

5256

pulse=filter(drive_pulse,1,ir);

5342

else

5257

else

5343

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5258

pulse=filter( ones(1,param.samples_per_ui),1,ir);

5344

end

5259

end

5345

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5260

PDR_response=(1+pulse)./(1-pulse).*ZT*2;

5346

result.PDR=PDR_response;

5261

result.PDR=PDR_response;

5347

result.pulse=pulse;

5262

result.pulse=pulse;

5348

5263

5349

5264

5350

5265

5351

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5266

function [ FIR t] =get_RAW_FIR(H,f,OP,param)

5352

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5267

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*f./(0.75*param.fb));

5353

if ~iscolumn(H), H=H.';end

5268

if ~iscolumn(H), H=H.';end

5354

if ~iscolumn(H_r), H_r=H_r.';end

5269

if ~iscolumn(H_r), H_r=H_r.';end

5355

H=H(:).*H_r;

5270

H=H(:).*H_r;

5356

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5271

[FIR, t, ~,~] = s21_to_impulse_DC(H ,f, param.sample_dt, OP) ;

5357

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5272

% SBR=filter(ones(1, param.samples_per_ui), 1, FIR);

5358

5273

5359

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5274

function RILN_TD_struct= get_RILN_cmp_td(sdd21,RIL_struct,faxis_f2,OP,param,A_T)

5360

% Complex reflection and re-reflection noise using the concept of zero'ing

5275

% Complex reflection and re-reflection noise using the concept of zero'ing

5361

% out of reflections

5276

% out of reflections

5362

% sdd21 us a complex insertion loss

5277

% sdd21 us a complex insertion loss

5363

% RIL_struct is the output of capture_RIL_RILN()

5278

% RIL_struct is the output of capture_RIL_RILN()

5364

% faxix_f2 needs to be at least to fb

5279

% faxix_f2 needs to be at least to fb

5365

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5280

% return reflections RILN_TD_struct.FOM based on time domain PR fit from pulse peak

5366

% still need to settle on voltage scaling.

5281

% still need to settle on voltage scaling.

5367

% maybe db(peak/Rss

5282

% maybe db(peak/Rss

5368

db = @(x) 20*log10(abs(x));

5283

db = @(x) 20*log10(abs(x));

5369

fprintf('computing TD_RILN (dB) ...');

5284

fprintf('computing TD_RILN (dB) ...');

5370

5285

5371

OP.interp_sparam_mag= 'trend_to_DC';

5286

OP.interp_sparam_mag= 'trend_to_DC';

5372

OP.interp_sparam_phase= 'interp_to_DC';

5287

OP.interp_sparam_phase= 'interp_to_DC';

5373

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5288

% OP.interp_sparam_mag= 'linear_trend_to_DC';

5374

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5289

% OP.interp_sparam_phase= 'extrap_cubic_to_dc_linear_to_inf';

5375

5290

5376

sdd21=squeeze(sdd21);

5291

sdd21=squeeze(sdd21);

5377

if iscolumn(sdd21)

5292

if iscolumn(sdd21)

5378

sdd21=sdd21.';

5293

sdd21=sdd21.';

5379

end

5294

end

5380

RIL=squeeze(RIL_struct.RIL);

5295

RIL=squeeze(RIL_struct.RIL);

5381

if iscolumn(RIL)

5296

if iscolumn(RIL)

5382

RIL=RIL.';

5297

RIL=RIL.';

5383

end

5298

end

5384

rho_port1=squeeze(RIL_struct.rho_port1);

5299

rho_port1=squeeze(RIL_struct.rho_port1);

5385

if iscolumn(rho_port1)

5300

if iscolumn(rho_port1)

5386

rho_port1=rho_port1.';

5301

rho_port1=rho_port1.';

5387

end

5302

end

5388

rho_port2=squeeze(RIL_struct.rho_port2);

5303

rho_port2=squeeze(RIL_struct.rho_port2);

5389

if iscolumn(rho_port2)

5304

if iscolumn(rho_port2)

5390

rho_port2=rho_port2.';

5305

rho_port2=rho_port2.';

5391

end

5306

end

5392

RIL_f=squeeze(RIL_struct.freq);

5307

RIL_f=squeeze(RIL_struct.freq);

5393

if iscolumn(RIL_f)

5308

if iscolumn(RIL_f)

5394

RIL_f=RIL_f.';

5309

RIL_f=RIL_f.';

5395

end

5310

end

5396

5311

5397

%---start. Calculate the reflection and re-reflection noise

5312

%---start. Calculate the reflection and re-reflection noise

5398

number_of_echos= 1e3;

5313

number_of_echos= 1e3;

5399

fmin= 1e9;%<-------------

5314

fmin= 1e9;%<-------------

5400

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5315

port2_reflection_rereflection_noise= zeros(1, length(RIL));

5401

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5316

port1_reflection_rereflection_noise= zeros(1, length(RIL));

5402

for m= 1:number_of_echos

5317

for m= 1:number_of_echos

5403

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5318

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m)).*(rho_port1.^m).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port2);

5404

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5319

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise+ abs(RIL).*(RIL.^(2*m-1)).*(rho_port1.^(m-1)).*(rho_port2.^m).*(1+rho_port1).*(1+rho_port1);

5405

end

5320

end

5406

5321

5407

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5322

%-----start. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5408

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5323

fmin_idx= find(RIL_f>= fmin, 1, 'first');

5409

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5324

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise(fmin_idx:end);

5410

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5325

port1_reflection_rereflection_noise= port1_reflection_rereflection_noise(fmin_idx:end);

5411

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5326

f_reflection_rereflection_noise= RIL_f(fmin_idx:end);

5412

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5327

%-----end. In the case of reflections, observed is bad TD conversion and hence removing data before 1GHz

5413

5328

5414

% clear RIL RIL_f rho_port1 rho_port2

5329

% clear RIL RIL_f rho_port1 rho_port2

5415

% clear fmin m

5330

% clear fmin m

5416

%---end. Calculate the reflection and re-reflection noise

5331

%---end. Calculate the reflection and re-reflection noise

5417

5332

5418

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5333

fmbg=[ones(length(faxis_f2),1).*transpose(sdd21) transpose(sqrt(faxis_f2)).*transpose(sdd21) transpose(faxis_f2).*transpose(sdd21) transpose(faxis_f2.^2).*transpose(sdd21) ];

5419

warning('off','MATLAB:nearlySingularMatrix');

5334

warning('off','MATLAB:nearlySingularMatrix');

5420

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5335

unwraplog=log(abs(sdd21))+1i*unwrap(angle(sdd21));

5421

LGw=transpose(sdd21.*unwraplog);

5336

LGw=transpose(sdd21.*unwraplog);

5422

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5337

alpha = ((fmbg'*fmbg)^-1)*fmbg'*LGw;

5423

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5338

efit_C=(alpha(1)+alpha(2).*sqrt(faxis_f2)+alpha(3).*faxis_f2 +faxis_f2.^2.*alpha(4) );

5424

FIT=transpose(exp(transpose(efit_C)));

5339

FIT=transpose(exp(transpose(efit_C)));

5425

efit=db(abs(FIT));

5340

efit=db(abs(FIT));

5426

ILN = db(sdd21)-efit;

5341

ILN = db(sdd21)-efit;

5427

5342

5428

5343

5429

OP.impulse_response_truncation_threshold =1e-7;

5344

OP.impulse_response_truncation_threshold =1e-7;

5430

5345

5431

print_for_codereview=0;

5346

print_for_codereview=0;

5432

if exist('OP','var')

5347

if exist('OP','var')

5433

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5348

H_bt=Bessel_Thomson_Filter(param,faxis_f2,1);

5434

H_bw=Butterworth_Filter(param,faxis_f2,1);

5349

H_bw=Butterworth_Filter(param,faxis_f2,1);

5435

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5350

H_t = exp(-(pi*faxis_f2/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5436

H_tw=Tukey_Window(faxis_f2,param);

5351

H_tw=Tukey_Window(faxis_f2,param);

5437

H_tw=ones(1,length(faxis_f2) );

5352

H_tw=ones(1,length(faxis_f2) );

5438

[RILN_TD_struct.REF.FIR, ...

5353

[RILN_TD_struct.REF.FIR, ...

5439

RILN_TD_struct.REF.t, ...

5354

RILN_TD_struct.REF.t, ...

5440

RILN_TD_struct.REF.causality_correction_dB, ...

5355

RILN_TD_struct.REF.causality_correction_dB, ...

5441

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5356

RILN_TD_struct.REF.truncation_dB] = s21_to_impulse_DC(sdd21.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5442

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5357

RILN_TD_struct.REF.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF.FIR);

5443

5358

5444

5359

5445

[RILN_TD_struct.FIT.FIR, ...

5360

[RILN_TD_struct.FIT.FIR, ...

5446

RILN_TD_struct.FIT.t, ...

5361

RILN_TD_struct.FIT.t, ...

5447

RILN_TD_struct.FIT.causality_correction_dB, ...

5362

RILN_TD_struct.FIT.causality_correction_dB, ...

5448

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5363

RILN_TD_struct.FIT.truncation_dB] = s21_to_impulse_DC(FIT.*H_bw.*H_t.*H_tw ,faxis_f2, param.sample_dt, OP) ;

5449

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5364

RILN_TD_struct.FIT.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.FIT.FIR);

5450

5365

5451

5366

5452

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5367

H_bt=Bessel_Thomson_Filter(param,RIL_f,1);

5453

H_bw=Butterworth_Filter(param,RIL_f,1);

5368

H_bw=Butterworth_Filter(param,RIL_f,1);

5454

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5369

H_t = exp(-(pi*RIL_f/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5455

H_tw=Tukey_Window(RIL_f,param);

5370

H_tw=Tukey_Window(RIL_f,param);

5456

H_tw=ones(1,length(RIL_f) );

5371

H_tw=ones(1,length(RIL_f) );

5457

[RILN_TD_struct.RIL.FIR, ...

5372

[RILN_TD_struct.RIL.FIR, ...

5458

RILN_TD_struct.RIL.t, ...

5373

RILN_TD_struct.RIL.t, ...

5459

RILN_TD_struct.RIL.causality_correction_dB, ...

5374

RILN_TD_struct.RIL.causality_correction_dB, ...

5460

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5375

RILN_TD_struct.RIL.truncation_dB] = s21_to_impulse_DC(RIL.*H_bw.*H_t.*H_tw ,RIL_f, param.sample_dt, OP) ;

5461

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5376

RILN_TD_struct.RIL.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.RIL.FIR);

5462

5377

5463

5378

5464

%---start. Calculate the channel delay

5379

%---start. Calculate the channel delay

5465

try

5380

try

5466

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5381

[delay_sec, delay_idx]= calculate_delay_CausalityEnforcement(faxis_f2, sdd21, param, OP);

5467

catch

5382

catch

5468

end

5383

end

5469

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5384

port2_reflection_rereflection_noise= port2_reflection_rereflection_noise.*exp(-1j*2*pi*f_reflection_rereflection_noise*delay_sec);

5470

clear delay_sec delay_idx

5385

clear delay_sec delay_idx

5471

%---end. Calculate the channel delay

5386

%---end. Calculate the channel delay

5472

5387

5473

5388

5474

5389

5475

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5390

H_bt=Bessel_Thomson_Filter(param,f_reflection_rereflection_noise,1);

5476

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5391

H_bw=Butterworth_Filter(param,f_reflection_rereflection_noise,1);

5477

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5392

H_t = exp(-(pi*f_reflection_rereflection_noise/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

5478

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5393

H_tw=Tukey_Window(f_reflection_rereflection_noise,param);

5479

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5394

H_tw=ones(1,length(f_reflection_rereflection_noise) );

5480

[RILN_TD_struct.REF_noise.FIR, ...

5395

[RILN_TD_struct.REF_noise.FIR, ...

5481

RILN_TD_struct.REF_noise.t, ...

5396

RILN_TD_struct.REF_noise.t, ...

5482

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5397

RILN_TD_struct.REF_noise.causality_correction_dB, ...

5483

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5398

RILN_TD_struct.REF_noise.truncation_dB] = s21_to_impulse_DC(port2_reflection_rereflection_noise.*H_bw.*H_t.*H_tw ,f_reflection_rereflection_noise, param.sample_dt, OP) ;

5484

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5399

RILN_TD_struct.REF_noise.PR=filter(ones(1, param.samples_per_ui), 1, RILN_TD_struct.REF_noise.FIR);

5485

5400

5486

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5401

ipeak=find(RILN_TD_struct.REF.PR==max(RILN_TD_struct.REF.PR),1,'first');

5487

% NrangeUI=1000;

5402

% NrangeUI=1000;

5488

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5403

% range_end=min(min(ipeak+param.samples_per_ui*NrangeUI,length(RILN_TD_struct.FIT.PR)-param.samples_per_ui ),length(RILN_TD_struct.REF.PR)-param.samples_per_ui);

5489

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5404

range_end= min(length(RILN_TD_struct.REF.PR), length(RILN_TD_struct.REF_noise.PR));

5490

range=ipeak:range_end;

5405

range=ipeak:range_end;

5491

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5406

RILN_TD_struct.ILN=RILN_TD_struct.REF_noise.PR(range);

5492

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5407

RILN_TD_struct.t=RILN_TD_struct.REF_noise.t(range);

5493

RILN_TD_struct.FOM=-inf;

5408

RILN_TD_struct.FOM=-inf;

5494

RILN_TD_struct.FOM_PDF=-inf;

5409

RILN_TD_struct.FOM_PDF=-inf;

5495

rms_fom=-inf;

5410

rms_fom=-inf;

5496

for im=1:param.samples_per_ui

5411

for im=1:param.samples_per_ui

5497

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5412

RILN_TD_struct.FOM=max(RILN_TD_struct.FOM, norm( RILN_TD_struct.ILN(im:param.samples_per_ui:end)));

5498

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5413

[ pdf ] = get_pdf_from_sampled_signal( RILN_TD_struct.ILN(im:param.samples_per_ui:end), param.levels, OP.BinSize ,0);

5499

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5414

rms=sqrt(pdf.y*pdf.x(:).^2)*sqrt(2);

5500

cdf=pdf; cdf.y=cumsum(pdf.y);

5415

cdf=pdf; cdf.y=cumsum(pdf.y);

5501

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5416

% cursors = d_cpdf(OP.BinSize,param.a_thru*[-1 1], [1 1]/2);

5502

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5417

% signal_and_isi_pdf = conv_fct(cursors, pdf);

5503

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5418

% cdf=signal_and_isi_pdf; cdf.y=cumsum(signal_and_isi_pdf.y);

5504

if print_for_codereview % remove once all checked out

5419

if print_for_codereview % remove once all checked out

5505

h=figure(190);set(gcf,'Tag','COM');

5420

h=figure(190);set(gcf,'Tag','COM');

5506

semilogy(-cdf.x,cdf.y);

5421

semilogy(-cdf.x,cdf.y);

5507

% xlim ([0,-cdf.x(1)])

5422

% xlim ([0,-cdf.x(1)])

5508

ylim([param.specBER 1]);title ('CDF of ILN')

5423

ylim([param.specBER 1]);title ('CDF of ILN')

5509

hold on

5424

hold on

5510

end

5425

end

5511

if rms>rms_fom

5426

if rms>rms_fom

5512

rms_fom=rms;

5427

rms_fom=rms;

5513

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5428

RILN_TD_struct.FOM_PDF= -cdf.x(find(cdf.y >= param.specBER, 1, 'first'));

5514

RILN_TD_struct.PDF=pdf;

5429

RILN_TD_struct.PDF=pdf;

5515

end

5430

end

5516

end

5431

end

5517

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5432

pdf_from_norm=normal_dist(RILN_TD_struct.FOM, 7 , OP.BinSize);

5518

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5433

RILN_TD_struct.SNR_ISI_FOM=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM);

5519

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5434

RILN_TD_struct.SNR_ISI_FOM_PDF=db(RILN_TD_struct.FIT.PR(ipeak)/RILN_TD_struct.FOM_PDF);

5520

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5435

% fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM)

5521

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5436

fprintf('%g dB\n',RILN_TD_struct.SNR_ISI_FOM_PDF)

5522

if print_for_codereview % remove once all checked out

5437

if print_for_codereview % remove once all checked out

5523

figure(9000);set(gcf,'Tag','COM');

5438

figure(9000);set(gcf,'Tag','COM');

5524

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5439

plot(RILN_TD_struct.REF.t,RILN_TD_struct.REF.PR,'disp','ref')

5525

hold on

5440

hold on

5526

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5441

plot(RILN_TD_struct.FIT.t,RILN_TD_struct.FIT.PR,'disp','fit')

5527

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5442

plot(RILN_TD_struct.RIL.t,RILN_TD_struct.RIL.PR,'disp','RILN')

5528

yyaxis right

5443

yyaxis right

5529

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5444

plot(RILN_TD_struct.t,RILN_TD_struct.ILN,'disp','td RILN')

5530

hold off

5445

hold off

5531

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5446

fprintf('SNR ISI FOM rms = %g dB; SNR ISI FOM PDF = %g dB\n',RILN_TD_struct.SNR_ISI_FOM,RILN_TD_struct.SNR_ISI_FOM_PDF)

5532

figure(9002);set(gcf,'Tag','COM');

5447

figure(9002);set(gcf,'Tag','COM');

5533

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5448

semilogy(RILN_TD_struct.PDF.x,RILN_TD_struct.PDF.y,'disp','actual PDF')

5534

hold on

5449

hold on

5535

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5450

semilogy(pdf_from_norm.x,pdf_from_norm.y,'disp','PDF using Gaussian assumed PDF');

5536

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5451

ylim([param.specBER max([RILN_TD_struct.PDF.y pdf_from_norm.y])]);title ('Compare actual PDF to Gaussian')

5537

grid on

5452

grid on

5538

legend('show')

5453

legend('show')

5539

end

5454

end

5540

end

5455

end

5541

function result=get_StepR(ir,param,cb_step,ZT)

5456

function result=get_StepR(ir,param,cb_step,ZT)

5542

%ir = impulse response

5457

%ir = impulse response

5543

%t_base=time array with equal time steps

5458

%t_base=time array with equal time steps

5544

%samp_UI = number of samples per UI for ir

5459

%samp_UI = number of samples per UI for ir

5545

% result.SBR

5460

% result.SBR

5546

% t for debug

5461

% t for debug

5547

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5462

t=(1/param.fb)/param.samples_per_ui*(0:length(ir)-1);

5548

5463

5549

if cb_step

5464

if cb_step

5550

Ag=1;

5465

Ag=1;

5551

dt=1/param.fb/param.samples_per_ui;

5466

dt=1/param.fb/param.samples_per_ui;

5552

edge_time=param.TR_TDR*1e-9;

5467

edge_time=param.TR_TDR*1e-9;

5553

fedge=1/edge_time;

5468

fedge=1/edge_time;

5554

tedge=0:dt:edge_time*2;

5469

tedge=0:dt:edge_time*2;

5555

%

5470

%

5556

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5471

edge=Ag*(2*cos(2*pi*(tedge)*fedge/16-pi/4).^2-1);

5557

drive_pulse=[edge ones(1,param.samples_per_ui)];

5472

drive_pulse=[edge ones(1,param.samples_per_ui)];

5558

%pulse=filter(UI_ones,1,ir);

5473

%pulse=filter(UI_ones,1,ir);

5559

5474

5560

pulse=filter(drive_pulse,1,ir);

5475

pulse=filter(drive_pulse,1,ir);

5561

else

5476

else

5562

pulse=cumsum(ir);

5477

pulse=cumsum(ir);

5563

end

5478

end

5564

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5479

TDR_response=(1+pulse)./(1-pulse)*ZT*2;

5565

result.ZSR=TDR_response;

5480

result.ZSR=TDR_response;

5566

result.pulse=pulse;

5481

result.pulse=pulse;

5567

5482

5568

5483

5569

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5484

function TDR_results = get_TDR(sdd, OP, param,ZT,np)

5570

% sdd is differential s-parameters structure (2 port assumed)

5485

% sdd is differential s-parameters structure (2 port assumed)

5571

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5486

% input parameter structure for s parameters sdd--> sdd.Impedance, sdd.Frequencies, sdd.Parameters, sdd.NumPorts

5572

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5487

% TDR_results.delay pre t=0 delay for TDR... help with time domain responce quaility

5573

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5488

% TDR_results.tdr the TDR responce (ohms vs TDR_results.t

5574

% TDR_results.t starting at t=0

5489

% TDR_results.t starting at t=0

5575

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5490

% TDR_results.tx_filter transmitter filter vs TDR_results.f

5576

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5491

% TDR_results.Rx_filter receiver filter vs TDR_results.f

5577

% TDR_results.f frequency for filter and s parameters

5492

% TDR_results.f frequency for filter and s parameters

5578

% TDR_results.ptdr_RL reflection waveform from the pulse

5493

% TDR_results.ptdr_RL reflection waveform from the pulse

5579

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5494

% TDR_results.WC_ptdr_samples_t worst case time sample of the reflection pulse

5580

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5495

% TDR_results.WC_ptdr_samples worst case reflection samples of the reflection pulse

5581

% TDR_results.ERL reported effective return loss

5496

% TDR_results.ERL reported effective return loss

5582

%

5497

%

5583

db = @(x) 20*log10(abs(x));

5498

db = @(x) 20*log10(abs(x));

5584

rms =@(x) norm(x)/sqrt(length(x));

5499

rms =@(x) norm(x)/sqrt(length(x));

5585

if isfield(OP,'TDR_duration')

5500

if isfield(OP,'TDR_duration')

5586

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5501

TDR_duration=OP.TDR_duration; % approximate transit time multipler

5587

else

5502

else

5588

TDR_duration=5;

5503

TDR_duration=5;

5589

end

5504

end

5590

if ~isfield(OP,'DISPLAY_WINDOW')

5505

if ~isfield(OP,'DISPLAY_WINDOW')

5591

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5506

OP.DISPLAY_WINDOW=1; % approximate transit time multipler

5592

end

5507

end

5593

f=sdd.Frequencies;

5508

f=sdd.Frequencies;

5594

TDR_results.f=f;

5509

TDR_results.f=f;

5595

% OP.Zt_adj=2;

5510

% OP.Zt_adj=2;

5596

if param.FLAG.S2P == 0

5511

if param.FLAG.S2P == 0

5597

5512

5598

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5513

% re-normalize reference of s-parameterss: this seems correct for a s4p input file

5599

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5514

TDR_RL =@(Zin,Zout,s11,s12,s21,s22)(Zin.^2.*s11+Zin.^2.*s22+Zout.^2.*s11+Zout.^2.*s22+Zin.^2-Zout.^2+Zin.*Zout.*s11.*2.0-Zin.*Zout.*s22.*2.0+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21-Zout.^2.*s11.*s22+Zout.^2.*s12.*s21)./(Zin.*Zout.*2.0+Zin.^2.*s11+Zin.^2.*s22-Zout.^2.*s11-Zout.^2.*s22+Zin.^2+Zout.^2+Zin.^2.*s11.*s22-Zin.^2.*s12.*s21+Zout.^2.*s11.*s22-Zout.^2.*s12.*s21-Zin.*Zout.*s11.*s22.*2.0+Zin.*Zout.*s12.*s21.*2.0);

5600

5515

5601

if param.RL_sel==1, other_port=2;end

5516

if param.RL_sel==1, other_port=2;end

5602

if param.RL_sel==2, other_port=1;end

5517

if param.RL_sel==2, other_port=1;end

5603

for i = 1:length(sdd.Frequencies)

5518

for i = 1:length(sdd.Frequencies)

5604

if size(sdd.Parameters,2) ==1 % for s2p files

5519

if size(sdd.Parameters,2) ==1 % for s2p files

5605

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5520

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,1, 1 ,sdd.Parameters(param.RL_sel,param.RL_sel,i) );

5606

else

5521

else

5607

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5522

RL(i)=TDR_RL(sdd.Impedance,2*ZT,sdd.Parameters(param.RL_sel,param.RL_sel,i) ,sdd.Parameters( 1,2 ,i), sdd.Parameters( 2,1 ,i),sdd.Parameters( other_port,other_port ,i) );

5608

end

5523

end

5609

end

5524

end

5610

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5525

% elseif OP.Zt_adj ==2 % only adjust z_t drive impedance

5611

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5526

% RL=squeeze((sdd.Parameters(param.RL_sel,param.RL_sel,:)));

5612

% Z_t=ZT;

5527

% Z_t=ZT;

5613

% zref=sdd.Impedance/2;

5528

% zref=sdd.Impedance/2;

5614

% if Z_t > zref

5529

% if Z_t > zref

5615

% radjust= (zref-Z_t);

5530

% radjust= (zref-Z_t);

5616

% S11adjust= radjust./(radjust + 2*zref);

5531

% S11adjust= radjust./(radjust + 2*zref);

5617

% RL=RL +S11adjust;

5532

% RL=RL +S11adjust;

5618

% elseif Z_t < zref

5533

% elseif Z_t < zref

5619

% rpad=-Z_t*zref/(Z_t-zref);

5534

% rpad=-Z_t*zref/(Z_t-zref);

5620

% S11adjust=zref/(rpad*(zref/rpad + 2));

5535

% S11adjust=zref/(rpad*(zref/rpad + 2));

5621

% RL=RL + S11adjust;

5536

% RL=RL + S11adjust;

5622

% else

5537

% else

5623

% RL=RL;

5538

% RL=RL;

5624

% end

5539

% end

5625

else

5540

else

5626

for i = 1:length(sdd.Frequencies)

5541

for i = 1:length(sdd.Frequencies)

5627

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5542

rho= (2*ZT - sdd.Impedance) / (2*ZT + sdd.Impedance);

5628

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5543

interim = sqrt(1-abs(rho)^2) * (1 - rho) / abs(1-rho);

5629

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5544

RL(i) = interim \ (sdd.Parameters(param.RL_sel,param.RL_sel,i) - rho) / ...

5630

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5545

(1 - rho *sdd.Parameters(param.RL_sel,param.RL_sel,i) ) * interim;

5631

end

5546

end

5632

end

5547

end

5633

5548

5634

% end

5549

% end

5635

RL=squeeze(RL);

5550

RL=squeeze(RL);

5636

f9=f/1e9;

5551

f9=f/1e9;

5637

tr=param.TR_TDR;

5552

tr=param.TR_TDR;

5638

TDR_results.delay=500e-12 ;

5553

TDR_results.delay=500e-12 ;

5639

% determine max time from thue

5554

% determine max time from thue

5640

% if sdd.NumPorts==1

5555

% if sdd.NumPorts==1

5641

% try

5556

% try

5642

% maxtime=OP.N*param.ui;

5557

% maxtime=OP.N*param.ui;

5643

% catch

5558

% catch

5644

% maxtime=2e-9;

5559

% maxtime=2e-9;

5645

% end

5560

% end

5646

% pix=1;

5561

% pix=1;

5647

% else

5562

% else

5648

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5563

% [ fir4del, tu] =get_RAW_FSIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5649

% pix=find(fir4del==max(fir4del),1);

5564

% pix=find(fir4del==max(fir4del),1);

5650

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5565

% maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5651

% if maxtime > tu(end); maxtime=tu(end);end

5566

% if maxtime > tu(end); maxtime=tu(end);end

5652

% endS

5567

% endS

5653

5568

5654

try

5569

try

5655

maxtime=OP.N*param.ui;

5570

maxtime=OP.N*param.ui;

5656

catch

5571

catch

5657

maxtime=2e-9;

5572

maxtime=2e-9;

5658

end

5573

end

5659

if OP.N==0

5574

if OP.N==0

5660

if sdd.NumPorts==1

5575

if sdd.NumPorts==1

5661

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5576

fprintf('<strong> Warning for s2p files N must not be zero<\strong> ');

5662

else

5577

else

5663

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5578

[ fir4del, tu] =get_RAW_FIR(squeeze(sdd.Parameters(2,1,:)),f,OP,param);

5664

pix=find(fir4del==max(fir4del),1);

5579

pix=find(fir4del==max(fir4del),1);

5665

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5580

maxtime=tu(pix)*TDR_duration+TDR_results.delay;

5666

if maxtime > tu(end); maxtime=tu(end);end

5581

if maxtime > tu(end); maxtime=tu(end);end

5667

end

5582

end

5668

end

5583

end

5669

5584

5670

5585

5671

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5586

% add delay 500 ps for TDR and 3 times Gaussnan transtion time

5672

% (makes gausian edge somewhat causal)

5587

% (makes gausian edge somewhat causal)

5673

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5588

H_t = exp( -2*(pi*f9*(tr)/1.6832).^2 ).*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9).*exp(-1j*2*pi*f9*tr*3);

5674

if ~isfield(OP,'cb_Guassian')

5589

if ~isfield(OP,'cb_Guassian')

5675

Use_gaussian=1;

5590

Use_gaussian=1;

5676

else

5591

else

5677

Use_gaussian=OP.cb_Guassian;

5592

Use_gaussian=OP.cb_Guassian;

5678

end

5593

end

5679

if Use_gaussian

5594

if Use_gaussian

5680

if iscolumn(H_t), H_t=H_t.'; end

5595

if iscolumn(H_t), H_t=H_t.'; end

5681

RLf=RL(:).'.*H_t;

5596

RLf=RL(:).'.*H_t;

5682

else % add extra 3x tr delay for causality

5597

else % add extra 3x tr delay for causality

5683

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5598

RLf=RL.*exp(-(1j)*2*pi*f9*TDR_results.delay/1e-9);

5684

end

5599

end

5685

5600

5686

%Bessesl-Thomson turned off here (3rd input=0)

5601

%Bessesl-Thomson turned off here (3rd input=0)

5687

H_bt=Bessel_Thomson_Filter(param,f,0);

5602

H_bt=Bessel_Thomson_Filter(param,f,0);

5688

5603

5689

if isfield(OP,'TDR_Butterworth')

5604

if isfield(OP,'TDR_Butterworth')

5690

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5605

H_bw=Butterworth_Filter(param,f,OP.TDR_Butterworth);

5691

else

5606

else

5692

H_bw=ones(1,length(f));

5607

H_bw=ones(1,length(f));

5693

end

5608

end

5694

5609

5695

5610

5696

if param.Tukey_Window ~= 0

5611

if param.Tukey_Window ~= 0

5697

H_tw= Tukey_Window(f,param);

5612

H_tw= Tukey_Window(f,param);

5698

else

5613

else

5699

H_tw=ones(1,length(f));

5614

H_tw=ones(1,length(f));

5700

end

5615

end

5701

5616

5702

5617

5703

if iscolumn(H_tw), H_tw=H_tw.';end

5618

if iscolumn(H_tw), H_tw=H_tw.';end

5704

if iscolumn(H_bt), H_bt=H_bt.';end

5619

if iscolumn(H_bt), H_bt=H_bt.';end

5705

if iscolumn(H_bw), H_bw=H_bw.';end

5620

if iscolumn(H_bw), H_bw=H_bw.';end

5706

if iscolumn(RLf), RLf=RLf.';end

5621

if iscolumn(RLf), RLf=RLf.';end

5707

5622

5708

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5623

TDR_results.Rx_filter=H_bt.*H_bw.*H_tw;

5709

RLf=RLf.*TDR_results.Rx_filter;

5624

RLf=RLf.*TDR_results.Rx_filter;

5710

TDR_results.tx_filter=H_t;

5625

TDR_results.tx_filter=H_t;

5711

5626

5712

5627

5713

[IR, t, causality_correction_dB, truncation_dB] = ...

5628

[IR, t, causality_correction_dB, truncation_dB] = ...

5714

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5629

s21_to_impulse_DC(RLf, sdd.Frequencies(:), param.sample_dt,OP);

5715

5630

5716

5631

5717

%

5632

%

5718

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5633

% param.tfx =4.2e-10; % need to put in xls file and comment this out

5719

tfx=param.tfx(np); % use fixture delay for port (np)

5634

tfx=param.tfx(np); % use fixture delay for port (np)

5720

5635

5721

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5636

% IR(abs(IR)<=OP.impulse_response_truncation_threshold)=0; % noise filter

5722

5637

5723

t = t-TDR_results.delay;

5638

t = t-TDR_results.delay;

5724

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5639

tend=find(t>=maxtime+tfx,1); % n starts at tfx

5725

if isempty(tend), tend=length(t); end

5640

if isempty(tend), tend=length(t); end

5726

IR=IR(1:tend);

5641

IR=IR(1:tend);

5727

t=t(1:tend);

5642

t=t(1:tend);

5728

if isempty(tend), tend=length(t); end

5643

if isempty(tend), tend=length(t); end

5729

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5644

tstart=find(t>=tr*1e-9,1); % account for Gaussian precursor

5730

if isempty(tstart), tstart=1;end

5645

if isempty(tstart), tstart=1;end

5731

if isempty(tend) || tstart >= tend

5646

if isempty(tend) || tstart >= tend

5732

if isempty(tend) || tstart >= tend

5647

if isempty(tend) || tstart >= tend

5733

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5648

% warndlg('TDR compuation not valid, try decreasing truncation tolerance, increasing samples, or adding a transmisson line','WrnTDR');

5734

end

5649

end

5735

tend=length(t);

5650

tend=length(t);

5736

tstart=1;

5651

tstart=1;

5737

end

5652

end

5738

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5653

OP.cb_step=0; % step is a basically a cos^2 form -pi/4 to 0. not activated.

5739

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5654

ch=get_StepR(IR(tstart:tend),param,OP.cb_step,ZT);

5740

TDR_results.tdr= ch.ZSR;

5655

TDR_results.tdr= ch.ZSR;

5741

TDR_results.t = t(tstart:tend);

5656

TDR_results.t = t(tstart:tend);

5742

5657

5743

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5658

PTDR=get_PulseR(IR(tstart:tend),param,OP.cb_step,ZT);

5744

if OP.TDR || OP.PTDR % determin average impededance with

5659

if OP.TDR || OP.PTDR % determin average impededance with

5745

try

5660

try

5746

tfstart=find(t>=3*tr*1e-9,1);

5661

tfstart=find(t>=3*tr*1e-9,1);

5747

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5662

x=squeeze(TDR_results.t(tfstart:end));TDR_results.x=TDR_results.tdr(:);

5748

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5663

y=squeeze(TDR_results.tdr(tfstart:end));TDR_results.y=TDR_results.t(:);

5749

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5664

w= exp(-(x-x(1))/OP.T_k ) ; % weighting function

5750

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5665

TDR_results.avgZport=mean(y.*w.')/mean(w.');

5751

catch

5666

catch

5752

TDR_results.avgZport=0;

5667

TDR_results.avgZport=0;

5753

fit=zeros(1,1);

5668

fit=zeros(1,1);

5754

p=[0 0 0 0 ];

5669

p=[0 0 0 0 ];

5755

end

5670

end

5756

TDR_results.RL=RL;

5671

TDR_results.RL=RL;

5757

end

5672

end

5758

if OP.PTDR

5673

if OP.PTDR

5759

% param.N_bx=param.ndfe;

5674

% param.N_bx=param.ndfe;

5760

RL_equiv=-inf;

5675

RL_equiv=-inf;

5761

L=param.levels;

5676

L=param.levels;

5762

BinSize=OP.BinSize;

5677

BinSize=OP.BinSize;

5763

% param.specBER=1e-5;

5678

% param.specBER=1e-5;

5764

if OP.DISPLAY_WINDOW

5679

if OP.DISPLAY_WINDOW

5765

hwaitbar=waitbar(0);

5680

hwaitbar=waitbar(0);

5766

else

5681

else

5767

fprintf('Worst ERL searching');

5682

fprintf('Worst ERL searching');

5768

end

5683

end

5769

% adjust PTDR for NDFE

5684

% adjust PTDR for NDFE

5770

% ---------------------- 2.7 code

5685

% ---------------------- 2.7 code

5771

% ntx=find(TDR_results.t >= tfx,1,'first');

5686

% ntx=find(TDR_results.t >= tfx,1,'first');

5772

% % gatestartt=TDR_results.t(ntx);

5687

% % gatestartt=TDR_results.t(ntx);

5773

% % gatestartV=PTDR.pulse(ntx);

5688

% % gatestartV=PTDR.pulse(ntx);

5774

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5689

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5775

% tk=param.ui*1*(param.N_bx+1)+tfx;

5690

% tk=param.ui*1*(param.N_bx+1)+tfx;

5776

% -------------------

5691

% -------------------

5777

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5692

% [ahealey 09/06/2019] Need to account for the 3*TR_TDR delay included in the rise

5778

% time filter.

5693

% time filter.

5779

% ntx=find(TDR_results.t >= tfx,1,'first');

5694

% ntx=find(TDR_results.t >= tfx,1,'first');

5780

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5695

ntx=find(TDR_results.t >= tfx+3*tr*1e-9,1,'first');

5781

% gatestartt=TDR_results.t(ntx);

5696

% gatestartt=TDR_results.t(ntx);

5782

% gatestartV=PTDR.pulse(ntx);

5697

% gatestartV=PTDR.pulse(ntx);

5783

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5698

% ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx,1,'first');

5784

% tk=param.ui*1*(param.N_bx+1)+tfx;

5699

% tk=param.ui*1*(param.N_bx+1)+tfx;

5785

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5700

ndfex=find(TDR_results.t > (param.N_bx+1)*param.ui+tfx+3*tr*1e-9,1,'first');

5786

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5701

tk=param.ui*1*(param.N_bx+1)+tfx+3*tr*1e-9;

5787

% [ahealey] End of modifications.

5702

% [ahealey] End of modifications.

5788

if isempty(ndfex), ndfex=length(TDR_results.t); end

5703

if isempty(ndfex), ndfex=length(TDR_results.t); end

5789

PTDR.pulse_orig=PTDR.pulse;

5704

PTDR.pulse_orig=PTDR.pulse;

5790

5705

5791

switch param.Grr

5706

switch param.Grr

5792

case 0 % pre .3cd release

5707

case 0 % pre .3cd release

5793

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5708

fctrx(1:length(PTDR.pulse_orig))=(1+param.rho_x)*param.rho_x;

5794

case 1 % .3cd release

5709

case 1 % .3cd release

5795

fctrx(1:length(PTDR.pulse_orig))=1;

5710

fctrx(1:length(PTDR.pulse_orig))=1;

5796

case 2 % .3ck working

5711

case 2 % .3ck working

5797

fctrx(1:length(PTDR.pulse_orig))=1;

5712

fctrx(1:length(PTDR.pulse_orig))=1;

5798

end

5713

end

5799

Gloss(1:length(TDR_results.t))=1;

5714

Gloss(1:length(TDR_results.t))=1;

5800

Grr(1:length(TDR_results.t))=1;

5715

Grr(1:length(TDR_results.t))=1;

5801

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5716

fctrx(1:ntx)=0; % moved out of loop for beta x and n_bx

5802

5717

5803

for ii=ntx:ndfex

5718

for ii=ntx:ndfex

5804

% adjust for near end loss

5719

% adjust for near end loss

5805

if param.N_bx>0 && param.beta_x~=0;

5720

if param.N_bx>0 && param.beta_x~=0;

5806

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5721

Gloss(ii)= 10.^(param.beta_x*(TDR_results.t(ii)-tk)/20);

5807

else

5722

else

5808

Gloss(ii)=1;

5723

Gloss(ii)=1;

5809

end

5724

end

5810

% ---------------------- 2.7 code

5725

% ---------------------- 2.7 code

5811

% x=(TDR_results.t(ii)-tfx)/param.ui;

5726

% x=(TDR_results.t(ii)-tfx)/param.ui;

5812

% ----------------------

5727

% ----------------------

5813

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5728

% [ahealey9/06/2019] Need to account for the 3*TR_TDR delay included in the

5814

% rise time filter.

5729

% rise time filter.

5815

% x=(TDR_results.t(ii)-tfx)/param.ui;

5730

% x=(TDR_results.t(ii)-tfx)/param.ui;

5816

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5731

x=(TDR_results.t(ii)-tfx-3*tr*1e-9)/param.ui;

5817

% determine how much of the return loss to use base on expected

5732

% determine how much of the return loss to use base on expected

5818

% missing reflections

5733

% missing reflections

5819

switch param.Grr

5734

switch param.Grr

5820

case 0 % pre .3cd release

5735

case 0 % pre .3cd release

5821

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5736

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5822

case 1 % .3cd release

5737

case 1 % .3cd release

5823

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5738

Grr(ii)= (1+param.rho_x)*param.rho_x*exp(-(x-1*param.N_bx-1).^2/(1+param.N_bx)^2);

5824

case 2 % .3ck working

5739

case 2 % .3ck working

5825

Grr(ii)= param.rho_x ;

5740

Grr(ii)= param.rho_x ;

5826

end

5741

end

5827

fctrx(ii)=Gloss(ii).*Grr(ii);

5742

fctrx(ii)=Gloss(ii).*Grr(ii);

5828

end

5743

end

5829

5744

5830

if isrow(fctrx), fctrx=fctrx(:);end

5745

if isrow(fctrx), fctrx=fctrx(:);end

5831

PTDR.pulse=PTDR.pulse.*fctrx;

5746

PTDR.pulse=PTDR.pulse.*fctrx;

5832

if 0

5747

if 0

5833

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5748

figure(10101+param.RL_sel);set(gcf,'Tag','COM');

5834

s1=subplot(2,1,1);

5749

s1=subplot(2,1,1);

5835

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5750

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,fctrx(ntx:end),'disp','G_l_o_s_s*G_r_r');

5836

hold on

5751

hold on

5837

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5752

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Gloss(ntx:end),'disp','G_l_o_s_s');

5838

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5753

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,Grr(ntx:end),'disp','G_r_r');

5839

grid on

5754

grid on

5840

ylim([ 0 1.2])

5755

ylim([ 0 1.2])

5841

s2=subplot(2,1,2);

5756

s2=subplot(2,1,2);

5842

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5757

plot((TDR_results.t(ntx:end)- TDR_results.t(ntx))/param.ui,PTDR.pulse(ntx:end)./fctrx(ntx:end),'disp','PTDR');

5843

grid on

5758

grid on

5844

linkaxes([s1,s2],'x')

5759

linkaxes([s1,s2],'x')

5845

xlabel 'UI'

5760

xlabel 'UI'

5846

xlim ([ 1 200])

5761

xlim ([ 1 200])

5847

end

5762

end

5848

5763

5849

FAST_NOISE_CONV=0;

5764

FAST_NOISE_CONV=0;

5850

ERLRMS=rms(PTDR.pulse);

5765

ERLRMS=rms(PTDR.pulse);

5851

for ki=1:param.samples_per_ui

5766

for ki=1:param.samples_per_ui

5852

progress = ki/param.samples_per_ui;

5767

progress = ki/param.samples_per_ui;

5853

if OP.DISPLAY_WINDOW

5768

if OP.DISPLAY_WINDOW

5854

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5769

waitbar(progress, hwaitbar, 'ERL computing'); figure(hwaitbar); drawnow;

5855

else

5770

else

5856

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5771

if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5857

end

5772

end

5858

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5773

tps=PTDR.pulse(ki:param.samples_per_ui:end);

5859

if OP.RL_norm_test

5774

if OP.RL_norm_test

5860

rl_fom=(norm(tps));

5775

rl_fom=(norm(tps));

5861

else

5776

else

5862

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5777

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5863

cdf_test=cumsum(testpdf.y);

5778

cdf_test=cumsum(testpdf.y);

5864

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5779

rl_test=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5865

rl_fom=rl_test;

5780

rl_fom=rl_test;

5866

end

5781

end

5867

if rl_fom > RL_equiv

5782

if rl_fom > RL_equiv

5868

RL_equiv=rl_fom;

5783

RL_equiv=rl_fom;

5869

best_ki=ki;

5784

best_ki=ki;

5870

end

5785

end

5871

if ~OP.RL_norm_test

5786

if ~OP.RL_norm_test

5872

best_erl=rl_test;

5787

best_erl=rl_test;

5873

best_pdf=testpdf;

5788

best_pdf=testpdf;

5874

best_cdf=cdf_test;

5789

best_cdf=cdf_test;

5875

end

5790

end

5876

5791

5877

end

5792

end

5878

if OP.RL_norm_test

5793

if OP.RL_norm_test

5879

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5794

tps=PTDR.pulse(best_ki:param.samples_per_ui:end);

5880

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5795

testpdf=get_pdf_from_sampled_signal( tps,L, BinSize*10, FAST_NOISE_CONV );

5881

cdf_test=cumsum(testpdf.y);

5796

cdf_test=cumsum(testpdf.y);

5882

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5797

best_erl=(-testpdf.x(find(cdf_test>=param.specBER,1,'first')));

5883

end

5798

end

5884

5799

5885

fprintf('\n');

5800

fprintf('\n');

5886

try

5801

try

5887

close(hwaitbar)

5802

close(hwaitbar)

5888

catch

5803

catch

5889

end

5804

end

5890

if ~exist('best_ki','var'),best_ki=1;end

5805

if ~exist('best_ki','var'),best_ki=1;end

5891

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5806

TDR_results.ptdr_RL=PTDR.pulse; % reflection waveform from the pulse

5892

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5807

TDR_results.WC_ptdr_samples_t=TDR_results.t(best_ki:param.samples_per_ui:end);

5893

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5808

TDR_results.WC_ptdr_samples=PTDR.pulse(best_ki:param.samples_per_ui:end);

5894

TDR_results.ERL=-db(best_erl);

5809

TDR_results.ERL=-db(best_erl);

5895

TDR_results.ERLRMS=-db(ERLRMS);

5810

TDR_results.ERLRMS=-db(ERLRMS);

5896

5811

5897

end

5812

end

5898

5813

5899

5814

5900

% end get TDR

5815

% end get TDR

5901

%%

5816

%%

5902

5817

5903

5818

5904

5819

5905

5820

5906

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5821

function [chdata, param] = get_TD_files(param, OP, num_fext, num_next, file_list)

5907

% filename parsing and acquisition

5822

% filename parsing and acquisition

5908

%------------------------------------------------------------------

5823

%------------------------------------------------------------------

5909

%----------put files names into chdata structure ---------

5824

%----------put files names into chdata structure ---------

5910

% The thru file has the index of 1

5825

% The thru file has the index of 1

5911

% crosstalk file are indexed from 2

5826

% crosstalk file are indexed from 2

5912

% nxi is incremented each time a file is read in so that nxi will end

5827

% nxi is incremented each time a file is read in so that nxi will end

5913

filepath=[]; % path name for file

5828

filepath=[]; % path name for file

5914

nxi=0; % file index

5829

nxi=0; % file index

5915

% get the THRU file

5830

% get the THRU file

5916

if size(file_list,2) ~= 0

5831

if size(file_list,2) ~= 0

5917

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5832

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

5918

[filepath, basename, fileext]=fileparts(file_list{1});

5833

[filepath, basename, fileext]=fileparts(file_list{1});

5919

5834

5920

else

5835

else

5921

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5836

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5922

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5837

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

5923

movegui(h,'northeast')

5838

movegui(h,'northeast')

5924

end

5839

end

5925

dir=fullfile(filepath, '*.csv');

5840

dir=fullfile(filepath, '*.csv');

5926

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5841

[basename,filepath]=uigetfile(dir,'input thru channel response .cav ');

5927

if filepath == 0

5842

if filepath == 0

5928

error('No Thru file')

5843

error('No Thru file')

5929

end

5844

end

5930

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5845

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5931

end

5846

end

5932

nxi=nxi+1;

5847

nxi=nxi+1;

5933

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5848

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5934

chdata(nxi).ext = fileext;

5849

chdata(nxi).ext = fileext;

5935

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5850

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5936

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5851

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

5937

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5852

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

5938

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5853

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

5939

chdata(nxi).type='THRU';

5854

chdata(nxi).type='THRU';

5940

chdata(nxi).ftr=param.fb*param.f_v;

5855

chdata(nxi).ftr=param.fb*param.f_v;

5941

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5856

param.base=chdata(nxi).base; %for print out function that don't pass chdata

5942

5857

5943

% now get FEXT file names into chdata structure

5858

% now get FEXT file names into chdata structure

5944

kxi=nxi;

5859

kxi=nxi;

5945

for nxi=kxi+1:num_fext+kxi

5860

for nxi=kxi+1:num_fext+kxi

5946

lastfilepath=filepath;

5861

lastfilepath=filepath;

5947

if size(file_list,2) ~= 0

5862

if size(file_list,2) ~= 0

5948

[filepath, basename, fileext]=fileparts(file_list{nxi});

5863

[filepath, basename, fileext]=fileparts(file_list{nxi});

5949

else

5864

else

5950

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5865

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5951

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5866

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

5952

movegui(h,'northeast')

5867

movegui(h,'northeast')

5953

end

5868

end

5954

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5869

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

5955

dir=fullfile(filepath, '*.csv');

5870

dir=fullfile(filepath, '*.csv');

5956

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5871

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5957

if filepath==0

5872

if filepath==0

5958

error('Not enough NEXT files')

5873

error('Not enough NEXT files')

5959

end

5874

end

5960

else

5875

else

5961

dir=fullfile(filepath, '*.csv');

5876

dir=fullfile(filepath, '*.csv');

5962

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5877

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

5963

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5878

[basename,filepath]=uigetfile(dir,'input noise channel response .csv');

5964

else

5879

else

5965

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5880

[basename,filepath]=uigetfile(dir,['input fext channel response .csv #', num2str(nxi-kxi)]);

5966

end

5881

end

5967

if filepath==0

5882

if filepath==0

5968

error('Not enough NEXT files')

5883

error('Not enough NEXT files')

5969

end

5884

end

5970

end

5885

end

5971

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5886

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5972

end

5887

end

5973

if isempty( filepath), filepath=lastfilepath; end

5888

if isempty( filepath), filepath=lastfilepath; end

5974

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5889

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5975

chdata(nxi).ext = fileext;

5890

chdata(nxi).ext = fileext;

5976

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5891

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5977

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5892

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5978

% chdata(nxi).A=param.a_fext;

5893

% chdata(nxi).A=param.a_fext;

5979

chdata(nxi).ftr=param.fb*param.f_f;

5894

chdata(nxi).ftr=param.fb*param.f_f;

5980

chdata(nxi).type='FEXT';

5895

chdata(nxi).type='FEXT';

5981

end

5896

end

5982

% now get NEXT file names into chdata structure

5897

% now get NEXT file names into chdata structure

5983

kxi=num_fext+kxi;

5898

kxi=num_fext+kxi;

5984

for nxi=kxi+1:num_next+kxi

5899

for nxi=kxi+1:num_next+kxi

5985

lastfilepath=filepath;

5900

lastfilepath=filepath;

5986

if size(file_list,2) ~= 0

5901

if size(file_list,2) ~= 0

5987

[filepath, basename, fileext]=fileparts(file_list{nxi});

5902

[filepath, basename, fileext]=fileparts(file_list{nxi});

5988

else

5903

else

5989

dir=fullfile(filepath, '*.csv');

5904

dir=fullfile(filepath, '*.csv');

5990

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5905

[basename,filepath]=uigetfile(dir,['input next channel response .csv ', num2str(nxi-kxi)]);

5991

if filepath==0

5906

if filepath==0

5992

error('Not enough NEXT files')

5907

error('Not enough NEXT files')

5993

end

5908

end

5994

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5909

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

5995

end

5910

end

5996

if isempty( filepath), filepath=lastfilepath; end

5911

if isempty( filepath), filepath=lastfilepath; end

5997

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5912

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

5998

chdata(nxi).ext = fileext;

5913

chdata(nxi).ext = fileext;

5999

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

5914

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6000

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

5915

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6001

% chdata(nxi).A=param.A_next;

5916

% chdata(nxi).A=param.A_next;

6002

chdata(nxi).ftr=param.fb*param.f_n;

5917

chdata(nxi).ftr=param.fb*param.f_n;

6003

chdata(nxi).type='NEXT';

5918

chdata(nxi).type='NEXT';

6004

end

5919

end

6005

function half_UI=get_center_of_UI(samples_per_UI)

5920

function half_UI=get_center_of_UI(samples_per_UI)

6006

5921

6007

%half_UI reveals which value to use for the center of the UI. For eye

5922

%half_UI reveals which value to use for the center of the UI. For eye

6008

%width calculations, it is necessary to place the cursor in the center of the

5923

%width calculations, it is necessary to place the cursor in the center of the

6009

%UI window to ensure a 0 crossing on both left/right inside the window.

5924

%UI window to ensure a 0 crossing on both left/right inside the window.

6010

%This function was written in order to support even and odd samples_per_UI

5925

%This function was written in order to support even and odd samples_per_UI

6011

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

5926

%and to prevent the ambiguity of using samples_per_UI/2 vs. samples_per_UI/2+1

6012

5927

6013

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

5928

%The UI window goes from 0 to 1 with 1/samples_per_UI steps

6014

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

5929

UI_window=0:1/samples_per_UI:1-1/samples_per_UI;

6015

%the center of the UI is sample closest to 0.5

5930

%the center of the UI is sample closest to 0.5

6016

[temp_diff,half_UI]=min(abs(UI_window-0.5));

5931

[temp_diff,half_UI]=min(abs(UI_window-0.5));

6017

function results= get_cm_noise(M,PR,L,BER,OP)

5932

function results= get_cm_noise(M,PR,L,BER,OP)

6018

5933

6019

if ~exist('OP')

5934

if ~exist('OP')

6020

OP.DC_norm_test=0;

5935

OP.DC_norm_test=0;

6021

OP.DISPLAY_WINDOW=1;

5936

OP.DISPLAY_WINDOW=1;

6022

end

5937

end

6023

param.BinSize=1e-5;

5938

param.BinSize=1e-5;

6024

PR_test=-inf;

5939

PR_test=-inf;

6025

PR_fom_best=-inf;

5940

PR_fom_best=-inf;

6026

% hwaitbar=waitbar(0);

5941

% hwaitbar=waitbar(0);

6027

for ki=1:M

5942

for ki=1:M

6028

progress = ki/M;

5943

progress = ki/M;

6029

% if OP.DISPLAY_WINDOW

5944

% if OP.DISPLAY_WINDOW

6030

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

5945

% waitbar(progress, hwaitbar, 'DM to CM computing'); figure(hwaitbar); drawnow;

6031

% else

5946

% else

6032

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

5947

% if ~mod(progress*100,1), fprintf('%i%% ', progress*100 );end

6033

% end

5948

% end

6034

tps=PR(ki:M:end);

5949

tps=PR(ki:M:end);

6035

if OP.DC_norm_test

5950

if OP.DC_norm_test

6036

PR_fom=(norm(tps));

5951

PR_fom=(norm(tps));

6037

else

5952

else

6038

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

5953

testpdf=get_pdf_from_sampled_signal( tps,L, param.BinSize*10 );

6039

cdf_test=cumsum(testpdf.y);

5954

cdf_test=cumsum(testpdf.y);

6040

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

5955

PRn_test=(-testpdf.x(find(cdf_test>=BER,1,'first')));

6041

PR_fom=PRn_test;

5956

PR_fom=PRn_test;

6042

end

5957

end

6043

if PR_fom > PR_fom_best

5958

if PR_fom > PR_fom_best

6044

PR_fom_best=PR_fom;

5959

PR_fom_best=PR_fom;

6045

best_ki=ki;

5960

best_ki=ki;

6046

end

5961

end

6047

if ~OP.DC_norm_test

5962

if ~OP.DC_norm_test

6048

results.DCn=PR_fom_best;

5963

results.DCn=PR_fom_best;

6049

results.DCn_pdf=testpdf;

5964

results.DCn_pdf=testpdf;

6050

results.DCn_cdf=cdf_test;

5965

results.DCn_cdf=cdf_test;

6051

else

5966

else

6052

results.DCn=PR_fom_best;

5967

results.DCn=PR_fom_best;

6053

end

5968

end

6054

results.DCn_p2p=max(PR)-min(PR);

5969

results.DCn_p2p=max(PR)-min(PR);

6055

end

5970

end

6056

5971

6057

5972

6058

5973

6059

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

5974

function pdf=get_pdf(chdata, delta_y, t_s, param, OP,ixphase)

6060

SBR=chdata.eq_pulse_response(:)'; % row vector

5975

SBR=chdata.eq_pulse_response(:)'; % row vector

6061

type=chdata.type;

5976

type=chdata.type;

6062

samp_UI=param.samples_per_ui;

5977

samp_UI=param.samples_per_ui;

6063

residual_response = SBR;

5978

residual_response = SBR;

6064

5979

6065

if isequal(type, 'THRU')

5980

if isequal(type, 'THRU')

6066

% for thru pulse response:

5981

% for thru pulse response:

6067

% remove the cursor and the DFE postcursors (up to their limit), since

5982

% remove the cursor and the DFE postcursors (up to their limit), since

6068

% we only care about the residuals.

5983

% we only care about the residuals.

6069

5984

6070

if ~param.Floating_DFE

5985

if ~param.Floating_DFE

6071

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

5986

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.ndfe));

6072

else

5987

else

6073

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

5988

ideal_cancelled_cursors = SBR(t_s+param.samples_per_ui*(0:param.N_bmax));

6074

end

5989

end

6075

if param.dfe_delta ~= 0

5990

if param.dfe_delta ~= 0

6076

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

5991

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6077

else

5992

else

6078

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

5993

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6079

end

5994

end

6080

5995

6081

%AJG021820

5996

%AJG021820

6082

if ~param.Floating_DFE

5997

if ~param.Floating_DFE

6083

bmax_vec=residual_response(t_s)*[1,param.bmax];

5998

bmax_vec=residual_response(t_s)*[1,param.bmax];

6084

bmin_vec=residual_response(t_s)*[1,param.bmin];

5999

bmin_vec=residual_response(t_s)*[1,param.bmin];

6085

else

6000

else

6086

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6001

bmax_vec=residual_response(t_s)*[1,param.use_bmax];

6087

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6002

bmin_vec=residual_response(t_s)*[1,param.use_bmin];

6088

end

6003

end

6089

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6004

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6090

6005

6091

6006

6092

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6007

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, param.samples_per_ui));

6093

dfetaps=effective_cancelled_cursors/SBR(t_s);

6008

dfetaps=effective_cancelled_cursors/SBR(t_s);

6094

6009

6095

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6010

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6096

% really needed for COM, but helps debugging. May be factored out in future revisions.

6011

% really needed for COM, but helps debugging. May be factored out in future revisions.

6097

start_cancel = t_s-param.samples_per_ui/2;

6012

start_cancel = t_s-param.samples_per_ui/2;

6098

if ~param.Floating_DFE

6013

if ~param.Floating_DFE

6099

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6014

end_cancel = t_s+(1/2+param.ndfe)*param.samples_per_ui - 1;

6100

else

6015

else

6101

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6016

end_cancel = t_s+(1/2+param.N_bmax)*param.samples_per_ui - 1;

6102

end

6017

end

6103

residual_response(start_cancel:end_cancel) = ...

6018

residual_response(start_cancel:end_cancel) = ...

6104

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6019

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6105

%else

6020

%else

6106

% for crosstalk pulse responses, nothing is cancelled, and all phases

6021

% for crosstalk pulse responses, nothing is cancelled, and all phases

6107

% are equally important.

6022

% are equally important.

6108

end

6023

end

6109

6024

6110

nui=round(length(residual_response)/param.samples_per_ui);

6025

nui=round(length(residual_response)/param.samples_per_ui);

6111

6026

6112

vs=zeros(nui-2, param.samples_per_ui);

6027

vs=zeros(nui-2, param.samples_per_ui);

6113

for i=1:param.samples_per_ui

6028

for i=1:param.samples_per_ui

6114

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6029

vs(:,i)=residual_response(param.samples_per_ui*(1:nui-2)+i);

6115

end

6030

end

6116

6031

6117

if OP.DISPLAY_WINDOW,

6032

if OP.DISPLAY_WINDOW,

6118

hwaitbar=waitbar(0);

6033

hwaitbar=waitbar(0);

6119

end

6034

end

6120

6035

6121

% determine which pdf to use

6036

% determine which pdf to use

6122

if isequal(type, 'THRU')

6037

if isequal(type, 'THRU')

6123

% one phase is interesting for thru

6038

% one phase is interesting for thru

6124

phases = mod(t_s,param.samples_per_ui);

6039

phases = mod(t_s,param.samples_per_ui);

6125

if phases==0, phases = param.samples_per_ui; end

6040

if phases==0, phases = param.samples_per_ui; end

6126

else

6041

else

6127

phases=1:samp_UI;

6042

phases=1:samp_UI;

6128

end

6043

end

6129

6044

6130

mxV = zeros(size(phases));

6045

mxV = zeros(size(phases));

6131

% we already found the phase in the PSD process for MMSE

6046

% we already found the phase in the PSD process for MMSE

6132

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6047

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

6133

if isequal(type, 'THRU')

6048

if isequal(type, 'THRU')

6134

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6049

pdf=get_pdf_from_sampled_signal(vs(:,phases), param.levels, delta_y); %#ok<AGROW>

6135

else

6050

else

6136

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6051

pdf=get_pdf_from_sampled_signal(vs(:,ixphase), param.levels, delta_y);

6137

end

6052

end

6138

else

6053

else

6139

for k=phases

6054

for k=phases

6140

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6055

pdf_samples(k)=get_pdf_from_sampled_signal(vs(:,k), param.levels, delta_y); %#ok<AGROW>

6141

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6056

mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6142

progress = k/length(phases);

6057

progress = k/length(phases);

6143

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6058

if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6144

end

6059

end

6145

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6060

[UNUSED_OUTPU, pxi]=max(mxV); %#ok<ASGLU>

6146

pdf=pdf_samples(pxi);

6061

pdf=pdf_samples(pxi);

6147

end

6062

end

6148

6063

6149

6064

6150

6065

6151

if OP.DISPLAY_WINDOW

6066

if OP.DISPLAY_WINDOW

6152

close(hwaitbar);

6067

close(hwaitbar);

6153

end

6068

end

6154

6069

6155

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6070

function [ pdf ] = get_pdf_from_sampled_signal( input_vector, L, BinSize ,FAST_NOISE_CONV)

6156

% Create PDF from interference vector using successive delta-set convolutions.

6071

% Create PDF from interference vector using successive delta-set convolutions.

6157

% input_vector = list of values of samples

6072

% input_vector = list of values of samples

6158

% return

6073

% return

6159

% pdf.x

6074

% pdf.x

6160

% pdf.y

6075

% pdf.y

6161

% pdf.vec

6076

% pdf.vec

6162

% pdf.bin

6077

% pdf.bin

6163

if ~exist('FAST_NOISE_CONV','var')

6078

if ~exist('FAST_NOISE_CONV','var')

6164

FAST_NOISE_CONV=0;

6079

FAST_NOISE_CONV=0;

6165

end

6080

end

6166

if max(input_vector) > BinSize

6081

if max(input_vector) > BinSize

6167

input_vector=input_vector(abs(input_vector)>BinSize);

6082

input_vector=input_vector(abs(input_vector)>BinSize);

6168

end

6083

end

6169

% for i = 1:length(input_vector)

6084

% for i = 1:length(input_vector)

6170

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6085

% if abs(input_vector(i)) < BinSize , input_vector(i)=0; end

6171

%end

6086

%end

6172

6087

6173

input_vector(abs(input_vector)<BinSize) = 0;

6088

input_vector(abs(input_vector)<BinSize) = 0;

6174

b=sign(input_vector);

6089

b=sign(input_vector);

6175

[input_vector,index]=sort(abs(input_vector),'descend');

6090

[input_vector,index]=sort(abs(input_vector),'descend');

6176

input_vector=input_vector.*b(index);

6091

input_vector=input_vector.*b(index);

6177

if FAST_NOISE_CONV

6092

if FAST_NOISE_CONV

6178

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6093

sig_res=norm(input_vector(find(abs(input_vector)<.001,1)+1:end));

6179

res_pdf= normal_dist(sig_res,5,BinSize);

6094

res_pdf= normal_dist(sig_res,5,BinSize);

6180

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6095

input_vector=input_vector(1:find(abs(input_vector)<.001,1));

6181

end

6096

end

6182

%% Equation 93A-39 %%

6097

%% Equation 93A-39 %%

6183

values = 2*(0:L-1)/(L-1)-1;

6098

values = 2*(0:L-1)/(L-1)-1;

6184

prob = ones(1,L)/L;

6099

prob = ones(1,L)/L;

6185

6100

6186

%% Initialize pdf to delta at 0

6101

%% Initialize pdf to delta at 0

6187

pdf=d_cpdf(BinSize, 0, 1);

6102

pdf=d_cpdf(BinSize, 0, 1);

6188

empty_pdf=pdf;

6103

empty_pdf=pdf;

6189

for k = 1:length(input_vector)

6104

for k = 1:length(input_vector)

6190

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6105

% pdfn=d_cpdf(BinSize, abs(input_vector(k))*values, prob);

6191

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6106

pdfn=Init_PDF_Fast(empty_pdf, abs(input_vector(k))*values, prob);

6192

pdf=conv_fct(pdf, pdfn);

6107

pdf=conv_fct(pdf, pdfn);

6193

end

6108

end

6194

if FAST_NOISE_CONV

6109

if FAST_NOISE_CONV

6195

% pdf=conv_fct(pdf,res_pdf);

6110

% pdf=conv_fct(pdf,res_pdf);

6196

pdf=conv_fct_TEST(pdf,res_pdf);

6111

pdf=conv_fct_TEST(pdf,res_pdf);

6197

end

6112

end

6198

6113

6199

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6114

function [pdf,h_j_full,A_s_vec]=get_pdf_full(chdata, delta_y, t_s, param, OP,pdf_range)

6200

t_s_orig=t_s;

6115

t_s_orig=t_s;

6201

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6116

%SBR=chdata.eq_pulse_response(:)'; % row vector SBR(1:t_s-14)=0;SBR(t_s+15:end)=0; for debug (AJG edit)

6202

type=chdata.type;

6117

type=chdata.type;

6203

6118

6204

pulse_orig=chdata.eq_pulse_response(:)';

6119

pulse_orig=chdata.eq_pulse_response(:)';

6205

%build arbitrary time axis with step size = 1/samples per ui

6120

%build arbitrary time axis with step size = 1/samples per ui

6206

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6121

old_time=[0:length(pulse_orig)-1]/param.samples_per_ui;

6207

%force t_s at time =0 (makes the other things below easy)

6122

%force t_s at time =0 (makes the other things below easy)

6208

original_sample_time=old_time(t_s_orig);

6123

original_sample_time=old_time(t_s_orig);

6209

old_time=old_time-original_sample_time;

6124

old_time=old_time-original_sample_time;

6210

%build new time axis that forces time=0 to be in the axis

6125

%build new time axis that forces time=0 to be in the axis

6211

%unless the new/old samples per UI are integer ratios, time 0 will not be

6126

%unless the new/old samples per UI are integer ratios, time 0 will not be

6212

%there by default

6127

%there by default

6213

samp_UI=param.samples_for_C2M;

6128

samp_UI=param.samples_for_C2M;

6214

new_timea=[0:-1/samp_UI:min(old_time)];

6129

new_timea=[0:-1/samp_UI:min(old_time)];

6215

new_timeb=[0:1/samp_UI:max(old_time)];

6130

new_timeb=[0:1/samp_UI:max(old_time)];

6216

new_time=[fliplr(new_timea) new_timeb(2:end)];

6131

new_time=[fliplr(new_timea) new_timeb(2:end)];

6217

SBR=interp1(old_time,pulse_orig,new_time);

6132

SBR=interp1(old_time,pulse_orig,new_time);

6218

%new sample time is simply the point where new_time = 0

6133

%new sample time is simply the point where new_time = 0

6219

[tmp,t_s]=min(abs(new_time));

6134

[tmp,t_s]=min(abs(new_time));

6220

6135

6221

residual_response = SBR;

6136

residual_response = SBR;

6222

6137

6223

half_UI=get_center_of_UI(samp_UI);

6138

half_UI=get_center_of_UI(samp_UI);

6224

6139

6225

if isequal(type, 'THRU')

6140

if isequal(type, 'THRU')

6226

% for thru pulse response:

6141

% for thru pulse response:

6227

% remove the cursor and the DFE postcursors (up to their limit), since

6142

% remove the cursor and the DFE postcursors (up to their limit), since

6228

% we only care about the residuals.

6143

% we only care about the residuals.

6229

6144

6230

%AJG021820

6145

%AJG021820

6231

if ~param.Floating_DFE

6146

if ~param.Floating_DFE

6232

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6147

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.ndfe));

6233

else

6148

else

6234

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6149

ideal_cancelled_cursors = SBR(t_s+samp_UI*(1:param.N_bmax));

6235

end

6150

end

6236

if param.dfe_delta ~= 0

6151

if param.dfe_delta ~= 0

6237

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6152

ideal_cancelled_cursors_q=floor(abs( ideal_cancelled_cursors/(residual_response(t_s).*param.dfe_delta) )).*residual_response(t_s)*param.dfe_delta.*sign(ideal_cancelled_cursors);

6238

else

6153

else

6239

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6154

ideal_cancelled_cursors_q=ideal_cancelled_cursors;

6240

end

6155

end

6241

6156

6242

if ~param.Floating_DFE

6157

if ~param.Floating_DFE

6243

bmax_vec=residual_response(t_s)*[param.bmax];

6158

bmax_vec=residual_response(t_s)*[param.bmax];

6244

bmin_vec=residual_response(t_s)*[param.bmin];

6159

bmin_vec=residual_response(t_s)*[param.bmin];

6245

else

6160

else

6246

bmax_vec=residual_response(t_s)*[param.use_bmax];

6161

bmax_vec=residual_response(t_s)*[param.use_bmax];

6247

bmin_vec=residual_response(t_s)*[param.use_bmin];

6162

bmin_vec=residual_response(t_s)*[param.use_bmin];

6248

end

6163

end

6249

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6164

effective_cancelled_cursors=dfe_clipper(ideal_cancelled_cursors_q,bmax_vec,bmin_vec);

6250

6165

6251

6166

6252

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6167

effective_cancellation_samples = kron(effective_cancelled_cursors, ones(1, samp_UI));

6253

dfetaps=effective_cancelled_cursors/SBR(t_s);

6168

dfetaps=effective_cancelled_cursors/SBR(t_s);

6254

6169

6255

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6170

% Apply a constant DFE coefficient 1/2 UI before and after each postcursor. Not

6256

% really needed for COM, but helps debugging. May be factored out in future revisions.

6171

% really needed for COM, but helps debugging. May be factored out in future revisions.

6257

6172

6258

%avoid dividing samp_UI by 2 in case it is not even

6173

%avoid dividing samp_UI by 2 in case it is not even

6259

start_cancel=t_s-half_UI+1+samp_UI;

6174

start_cancel=t_s-half_UI+1+samp_UI;

6260

%AJG021820

6175

%AJG021820

6261

if ~param.Floating_DFE

6176

if ~param.Floating_DFE

6262

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6177

end_cancel=start_cancel+param.ndfe*samp_UI-1;

6263

else

6178

else

6264

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6179

end_cancel=start_cancel+param.N_bmax*samp_UI-1;

6265

end

6180

end

6266

residual_response(start_cancel:end_cancel) = ...

6181

residual_response(start_cancel:end_cancel) = ...

6267

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6182

residual_response(start_cancel:end_cancel) - effective_cancellation_samples;

6268

%else

6183

%else

6269

% for crosstalk pulse responses, nothing is cancelled, and all phases

6184

% for crosstalk pulse responses, nothing is cancelled, and all phases

6270

% are equally important.

6185

% are equally important.

6271

6186

6272

%remove entire cursor UI

6187

%remove entire cursor UI

6273

uiv_start=start_cancel-samp_UI;

6188

uiv_start=start_cancel-samp_UI;

6274

uiv_end=uiv_start+samp_UI-1;

6189

uiv_end=uiv_start+samp_UI-1;

6275

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6190

A_s_vec = param.R_LM*SBR(uiv_start:uiv_end)/(param.levels-1);

6276

residual_response(uiv_start:uiv_end)=0;

6191

residual_response(uiv_start:uiv_end)=0;

6277

end

6192

end

6278

6193

6279

nui=round(length(residual_response)/samp_UI);

6194

nui=round(length(residual_response)/samp_UI);

6280

6195

6281

6196

6282

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6197

vs=transpose(reshape(residual_response(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6283

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6198

%added vs_raw in order to calculate h_j. vs_raw uses the pulse

6284

%response without DFE included. (Can't include DFE for jitter calc)

6199

%response without DFE included. (Can't include DFE for jitter calc)

6285

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6200

vs_raw=transpose(reshape(SBR(samp_UI+1:samp_UI*(nui-1)),samp_UI,nui-2));

6286

6201

6287

% if OP.DISPLAY_WINDOW,

6202

% if OP.DISPLAY_WINDOW,

6288

% hwaitbar=waitbar(0);

6203

% hwaitbar=waitbar(0);

6289

% end

6204

% end

6290

6205

6291

% determine which pdf to use

6206

% determine which pdf to use

6292

if isequal(type, 'THRU')

6207

if isequal(type, 'THRU')

6293

% one phase is interesting for thru

6208

% one phase is interesting for thru

6294

phases = mod(t_s,samp_UI);

6209

phases = mod(t_s,samp_UI);

6295

if phases==0, phases = samp_UI; end

6210

if phases==0, phases = samp_UI; end

6296

else

6211

else

6297

phases=1:samp_UI;

6212

phases=1:samp_UI;

6298

end

6213

end

6299

6214

6300

mxV = zeros(size(phases));

6215

mxV = zeros(size(phases));

6301

6216

6302

%phases reveals the raw position in the UI window of the cursor.

6217

%phases reveals the raw position in the UI window of the cursor.

6303

%shift_amount is the amount to shift so that it aligns with half_UI

6218

%shift_amount is the amount to shift so that it aligns with half_UI

6304

shift_amount=half_UI-phases;

6219

shift_amount=half_UI-phases;

6305

%vs_shift puts the cursor at the center

6220

%vs_shift puts the cursor at the center

6306

vs_shift=circshift(vs,[0 shift_amount]);

6221

vs_shift=circshift(vs,[0 shift_amount]);

6307

L=size(vs_raw,1);

6222

L=size(vs_raw,1);

6308

%allow partial UI computation through pdf_range

6223

%allow partial UI computation through pdf_range

6309

%if pdf_range is empty, do full UI

6224

%if pdf_range is empty, do full UI

6310

if isempty(pdf_range)

6225

if isempty(pdf_range)

6311

pdf_range=1:samp_UI;

6226

pdf_range=1:samp_UI;

6312

else

6227

else

6313

pdf_range=min(pdf_range):max(pdf_range);

6228

pdf_range=min(pdf_range):max(pdf_range);

6314

end

6229

end

6315

h_j_full=zeros(L,samp_UI);

6230

h_j_full=zeros(L,samp_UI);

6316

for k=pdf_range

6231

for k=pdf_range

6317

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6232

pdf(k)=get_pdf_from_sampled_signal(vs_shift(:,k), param.levels, delta_y); %#ok<AGROW>

6318

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6233

%mxV(k)=sqrt(sum( pdf_samples(k).x.^2.*pdf_samples(k).y)); % standard deviation of PDF

6319

%progress = k/length(phases);

6234

%progress = k/length(phases);

6320

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6235

%if OP.DISPLAY_WINDOW, waitbar(progress, hwaitbar, ['processing COM pdf ' chdata.base ] ); figure(hwaitbar); drawnow; end

6321

6236

6322

%build the circshift of h_j_full into the loop to support a reduced

6237

%build the circshift of h_j_full into the loop to support a reduced

6323

%range of sampling points. circshift at the end only works if doing the

6238

%range of sampling points. circshift at the end only works if doing the

6324

%full range of sampling points. And shifting before the loop will

6239

%full range of sampling points. And shifting before the loop will

6325

%yield the wrong answer at the edges of the UI

6240

%yield the wrong answer at the edges of the UI

6326

hk=k-shift_amount;

6241

hk=k-shift_amount;

6327

if hk<1

6242

if hk<1

6328

hk=hk+samp_UI;

6243

hk=hk+samp_UI;

6329

elseif hk>samp_UI

6244

elseif hk>samp_UI

6330

hk=hk-samp_UI;

6245

hk=hk-samp_UI;

6331

end

6246

end

6332

if hk==1

6247

if hk==1

6333

%when hk=1, the early UI is the last column

6248

%when hk=1, the early UI is the last column

6334

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6249

h_j_full(1:L-1,k)=(vs_raw(2:end,hk+1)-vs_raw(1:end-1,samp_UI))/2*samp_UI;

6335

elseif hk==samp_UI

6250

elseif hk==samp_UI

6336

%when hk=samp_UI, the late UI is the first column

6251

%when hk=samp_UI, the late UI is the first column

6337

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6252

h_j_full(1:L-1,k)=(vs_raw(2:end,1)-vs_raw(1:end-1,hk-1))/2*samp_UI;

6338

else

6253

else

6339

%for all other cases, do the normal late=+1, early = -1

6254

%for all other cases, do the normal late=+1, early = -1

6340

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6255

h_j_full(1:L,k)=(vs_raw(:,hk+1)-vs_raw(:,hk-1))/2*samp_UI;

6341

end

6256

end

6342

end

6257

end

6343

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6258

function [chdata, param] = get_s4p_files(param, OP, num_fext, num_next, file_list)

6344

% filename parsing and acquisition

6259

% filename parsing and acquisition

6345

%------------------------------------------------------------------

6260

%------------------------------------------------------------------

6346

%----------put files names into chdata structure ---------

6261

%----------put files names into chdata structure ---------

6347

% The thru file has the index of 1

6262

% The thru file has the index of 1

6348

% crosstalk file are indexed from 2

6263

% crosstalk file are indexed from 2

6349

% nxi is incremented each time a file is read in so that nxi will end

6264

% nxi is incremented each time a file is read in so that nxi will end

6350

filepath=[]; % path name for file

6265

filepath=[]; % path name for file

6351

nxi=0; % file index

6266

nxi=0; % file index

6352

% get the THRU file

6267

% get the THRU file

6353

if size(file_list,2) ~= 0

6268

if size(file_list,2) ~= 0

6354

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6269

file_list(1)=strrep(file_list(1),'\', filesep); % OS file convention conversion

6355

[filepath, basename, fileext]=fileparts(file_list{1});

6270

[filepath, basename, fileext]=fileparts(file_list{1});

6356

6271

6357

else

6272

else

6358

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6273

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6359

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6274

h = msgbox('enter test channel s-parameter file'); set(h,'Color',[1 .85 0]);

6360

movegui(h,'northeast')

6275

movegui(h,'northeast')

6361

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6276

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6362

end

6277

end

6363

if OP.ERL == 2

6278

if OP.ERL == 2

6364

dir=fullfile(filepath, '*.s2p');

6279

dir=fullfile(filepath, '*.s2p');

6365

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6280

[basename,filepath]=uigetfile(dir,'input RL measurement .s2p ');

6366

if filepath == 0

6281

if filepath == 0

6367

error('No RL measurement file')

6282

error('No RL measurement file')

6368

end

6283

end

6369

else

6284

else

6370

dir=fullfile(filepath, '*.s4p');

6285

dir=fullfile(filepath, '*.s4p');

6371

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6286

[basename,filepath]=uigetfile(dir,'input thru channel response .s4p ');

6372

if filepath == 0

6287

if filepath == 0

6373

error('No Thru file')

6288

error('No Thru file')

6374

end

6289

end

6375

end

6290

end

6376

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6291

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6377

end

6292

end

6378

nxi=nxi+1;

6293

nxi=nxi+1;

6379

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6294

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6380

chdata(nxi).ext = fileext;

6295

chdata(nxi).ext = fileext;

6381

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6296

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6382

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6297

% chdata(nxi).base=[pth(max(strfind(pth,filesep))+1:end) '--' basename]; % add 1 directory back to basename

6383

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6298

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename]; % add 1 directory back to basename

6384

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6299

% chdata(nxi).A=param.A_thru; % pam encoding amplitude reduction is do in reporting but is comprehending in crosstalk PDF

6385

chdata(nxi).type='THRU';

6300

chdata(nxi).type='THRU';

6386

chdata(nxi).ftr=param.fb*param.f_v;

6301

chdata(nxi).ftr=param.fb*param.f_v;

6387

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6302

param.base=chdata(nxi).base; %for print out function that don't pass chdata

6388

6303

6389

% now get FEXT file names into chdata structure

6304

% now get FEXT file names into chdata structure

6390

kxi=nxi;

6305

kxi=nxi;

6391

for nxi=kxi+1:num_fext+kxi

6306

for nxi=kxi+1:num_fext+kxi

6392

lastfilepath=filepath;

6307

lastfilepath=filepath;

6393

if size(file_list,2) ~= 0

6308

if size(file_list,2) ~= 0

6394

[filepath, basename, fileext]=fileparts(file_list{nxi});

6309

[filepath, basename, fileext]=fileparts(file_list{nxi});

6395

else

6310

else

6396

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6311

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6397

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6312

h = msgbox('enter noise channel s-parameter file'); set(h,'Color',[1 .85 0]);

6398

movegui(h,'northeast')

6313

movegui(h,'northeast')

6399

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6314

set(h,'Tag','COM') % RIM 06-13-2022 ... tak msg box for closing later

6400

end

6315

end

6401

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6316

if param.tfx(1) == -1 && OP.ERL_ONLY && OP.ERL == 2;

6402

dir=fullfile(filepath, '*.s4p');

6317

dir=fullfile(filepath, '*.s4p');

6403

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6318

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6404

if filepath==0

6319

if filepath==0

6405

error('Not enough NEXT files')

6320

error('Not enough NEXT files')

6406

end

6321

end

6407

else

6322

else

6408

dir=fullfile(filepath, '*.s4p');

6323

dir=fullfile(filepath, '*.s4p');

6409

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6324

if OP.RX_CALIBRATION == 1 || OP.FIXTURE_CALIBRATION

6410

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6325

[basename,filepath]=uigetfile(dir,'input noise channel response .s4p');

6411

else

6326

else

6412

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6327

[basename,filepath]=uigetfile(dir,['input fext channel response .s4p #', num2str(nxi-kxi)]);

6413

end

6328

end

6414

if filepath==0

6329

if filepath==0

6415

error('Not enough NEXT files')

6330

error('Not enough NEXT files')

6416

end

6331

end

6417

end

6332

end

6418

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6333

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6419

end

6334

end

6420

if isempty( filepath), filepath=lastfilepath; end

6335

if isempty( filepath), filepath=lastfilepath; end

6421

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6336

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6422

chdata(nxi).ext = fileext;

6337

chdata(nxi).ext = fileext;

6423

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6338

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6424

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6339

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6425

% chdata(nxi).A=param.a_fext;

6340

% chdata(nxi).A=param.a_fext;

6426

chdata(nxi).ftr=param.fb*param.f_f;

6341

chdata(nxi).ftr=param.fb*param.f_f;

6427

chdata(nxi).type='FEXT';

6342

chdata(nxi).type='FEXT';

6428

end

6343

end

6429

% now get NEXT file names into chdata structure

6344

% now get NEXT file names into chdata structure

6430

kxi=num_fext+kxi;

6345

kxi=num_fext+kxi;

6431

for nxi=kxi+1:num_next+kxi

6346

for nxi=kxi+1:num_next+kxi

6432

lastfilepath=filepath;

6347

lastfilepath=filepath;

6433

if size(file_list,2) ~= 0

6348

if size(file_list,2) ~= 0

6434

[filepath, basename, fileext]=fileparts(file_list{nxi});

6349

[filepath, basename, fileext]=fileparts(file_list{nxi});

6435

else

6350

else

6436

dir=fullfile(filepath, '*.s4p');

6351

dir=fullfile(filepath, '*.s4p');

6437

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6352

[basename,filepath]=uigetfile(dir,['input next channel response .s4p ', num2str(nxi-kxi)]);

6438

if filepath==0

6353

if filepath==0

6439

error('Not enough NEXT files')

6354

error('Not enough NEXT files')

6440

end

6355

end

6441

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6356

[UNUSED_OUTPUT, basename, fileext]=fileparts(basename); %#ok<ASGLU>

6442

end

6357

end

6443

if isempty( filepath), filepath=lastfilepath; end

6358

if isempty( filepath), filepath=lastfilepath; end

6444

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6359

chdata(nxi).filename = fullfile(filepath, [basename fileext]);

6445

chdata(nxi).ext = fileext;

6360

chdata(nxi).ext = fileext;

6446

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6361

[UNUSED_OUTPUT, dirname]=fileparts(filepath); %#ok<ASGLU>

6447

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6362

chdata(nxi).base=[OP.RUNTAG ' ' dirname '--' basename ];

6448

% chdata(nxi).A=param.A_next;

6363

% chdata(nxi).A=param.A_next;

6449

chdata(nxi).ftr=param.fb*param.f_n;

6364

chdata(nxi).ftr=param.fb*param.f_n;

6450

chdata(nxi).type='NEXT';

6365

chdata(nxi).type='NEXT';

6451

end

6366

end

6452

6367

6453

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6368

function [sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf)

6454

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6369

% 11-25-2020 correct integratation limits, should be infinity or highest specified frequency

6455

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6370

% H_sy - PSD for Tx power delivery, not normally used and set to a vector 1's

6456

% H_r - receiver filter, Butterworth

6371

% H_r - receiver filter, Butterworth

6457

% H_ctf - total gain of CTLE and low freq filtering

6372

% H_ctf - total gain of CTLE and low freq filtering

6458

% H_dc - the common mode channel gain

6373

% H_dc - the common mode channel gain

6459

% param.eta_0 -input referred Rx noise

6374

% param.eta_0 -input referred Rx noise

6460

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6375

% param.AC_CM_RMS - AC CM source before Tx series source resistor.

6461

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6376

% param.ACCM_MAX_Freq - Max frequency for ACCM source intergration

6462

%% Equation 93A-35 - independent of FFE setting %%

6377

%% Equation 93A-35 - independent of FFE setting %%

6463

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6378

sigma_N1 = sqrt(param.eta_0*sum( abs(H_sy(2:end) .* H_r(2:end) .* H_ctf(2:end) ).^2 .* diff(chdata(1).faxis)/1e9));% eta_0 is V^2/Ghz i.e. /1

6464

if sum(param.AC_CM_RMS) ~= 0

6379

if sum(param.AC_CM_RMS) ~= 0

6465

sigma_ACCM=0;

6380

sigma_ACCM=0;

6466

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6381

f_int= chdata(1).faxis( chdata(1).faxis<=param.ACCM_MAX_Freq );

6467

for i=1:length(chdata)

6382

for i=1:length(chdata)

6468

H_dc=abs(squeeze(chdata(i).sdc21));

6383

H_dc=abs(squeeze(chdata(i).sdc21));

6469

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6384

sigma_ACCM_acc= sqrt( 2*param.AC_CM_RMS_TX^2.*sum( abs(H_sy(2:length(f_int)) .* H_r(2:length(f_int)) .* H_ctf(2:length(f_int)).*H_dc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end) );

6470

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6385

sigma_ACCM=norm([sigma_ACCM_acc,sigma_ACCM]);

6471

end

6386

end

6472

sigma_N=norm([sigma_N1,sigma_ACCM]);

6387

sigma_N=norm([sigma_N1,sigma_ACCM]);

6473

else

6388

else

6474

sigma_N=sigma_N1;

6389

sigma_N=sigma_N1;

6475

end

6390

end

6476

%%

6391

%%

6477

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6392

function [ sigma_NE , sigma_HP] = get_sigma_noise( H_ctf, param, chdata, sigma_bn )

6478

% for Rx calibratrion only

6393

% for Rx calibratrion only

6479

% the FEXT channel for calibration basically a DC connection unlike normal

6394

% the FEXT channel for calibration basically a DC connection unlike normal

6480

% FEXT channels which are nearly open at DC channels

6395

% FEXT channels which are nearly open at DC channels

6481

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6396

H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(2).faxis/(param.f_r*param.fb));

6482

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6397

idxfbby2=find( chdata(2).faxis(:) >= param.fb/2, 1);

6483

if size(chdata,2) >= 2

6398

if size(chdata,2) >= 2

6484

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6399

Hnoise_channel=chdata(2).sdd21;% rx package is already included tx is not

6485

else

6400

else

6486

Hnoise_channel=1;

6401

Hnoise_channel=1;

6487

end

6402

end

6488

f=chdata(2).faxis;

6403

f=chdata(2).faxis;

6489

f_hp=param.f_hp;

6404

f_hp=param.f_hp;

6490

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6405

if f_hp ~=0 % param.f_hp is a key indicating that Tx bbn is used as in clause 162

6491

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6406

H_hp=(-1j*f./f_hp)./(1+1j*f./f_hp);

6492

else

6407

else

6493

H_hp=ones(1,length(f));

6408

H_hp=ones(1,length(f));

6494

end

6409

end

6495

%% Equation 93A-47 or 162-12

6410

%% Equation 93A-47 or 162-12

6496

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6411

H_np=Hnoise_channel.*H_ctf.*H_r.*H_hp;

6497

6412

6498

%% Equation 93A-48 or 162-14%%

6413

%% Equation 93A-48 or 162-14%%

6499

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6414

sigma_NE = sigma_bn*sqrt(mean(abs(H_np(1:idxfbby2).^2)));

6500

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6415

sigma_HP = sigma_bn*(mean(abs(H_hp(1:idxfbby2).^2)));

6501

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6416

function [sigma_XT, sigma_FEXT, sigma_NEXT] = get_xtlk_noise( upsampled_txffe, type, param, chdata, phase_memory,C )

6502

% Modified not to double count crosstalk: John Ewen 13/12/2018

6417

% Modified not to double count crosstalk: John Ewen 13/12/2018

6503

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6418

% function sigma_XT = get_xtlk_noise( upsampled_txffe, type, param, chdata,ctle_indx,clow_indx, C,cursor_i)

6504

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6419

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

6505

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6420

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

6506

f=chdata(1).faxis;

6421

f=chdata(1).faxis;

6507

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6422

temp_angle=(param.samples_per_ui*param.sample_dt)*pi.*chdata(1).faxis;

6508

if(f(1)==0)

6423

if(f(1)==0)

6509

temp_angle(1)=1e-20;% we don't want to divide by zero

6424

temp_angle(1)=1e-20;% we don't want to divide by zero

6510

end

6425

end

6511

PWF_tx=ones(1,length(f));

6426

PWF_tx=ones(1,length(f));

6512

if max(upsampled_txffe) > 0

6427

if max(upsampled_txffe) > 0

6513

PWF_tx=zeros(1,length(f));

6428

PWF_tx=zeros(1,length(f));

6514

[mcur,icur] = max(upsampled_txffe);

6429

[mcur,icur] = max(upsampled_txffe);

6515

if exist('phase_memory','var') && ~isempty(phase_memory)

6430

if exist('phase_memory','var') && ~isempty(phase_memory)

6516

pre_calc=1;

6431

pre_calc=1;

6517

else

6432

else

6518

pre_calc=0;

6433

pre_calc=0;

6519

end

6434

end

6520

for ii=1:length(upsampled_txffe)

6435

for ii=1:length(upsampled_txffe)

6521

if upsampled_txffe(ii)==0

6436

if upsampled_txffe(ii)==0

6522

%speed up: skip cases when txffe=0

6437

%speed up: skip cases when txffe=0

6523

continue;

6438

continue;

6524

end

6439

end

6525

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6440

% PWF_tx=upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb)+PWF_tx;

6526

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6441

% Adee Ran 2020-06-03 remove create large 2D matrix when 1D is all

6527

% that is needed

6442

% that is needed

6528

if ii==icur

6443

if ii==icur

6529

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6444

%speed up: ii-icur=0, so just scalar addition and avoid exp calc

6530

PWF_tx = PWF_tx + upsampled_txffe(ii);

6445

PWF_tx = PWF_tx + upsampled_txffe(ii);

6531

else

6446

else

6532

if pre_calc

6447

if pre_calc

6533

%speed up: avoid vector exp calculation by externally pre-calculating it

6448

%speed up: avoid vector exp calculation by externally pre-calculating it

6534

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6449

term_ii = upsampled_txffe(ii).*phase_memory(:,ii);

6535

else

6450

else

6536

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6451

term_ii = upsampled_txffe(ii).*exp(-1j*2*pi*(ii-icur).*f/param.fb);

6537

end

6452

end

6538

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6453

%bug fix: use transpose instead of ' to avoid taking complex conjugate

6539

PWF_tx = PWF_tx + transpose(term_ii(:));

6454

PWF_tx = PWF_tx + transpose(term_ii(:));

6540

end

6455

end

6541

% /Adee

6456

% /Adee

6542

end

6457

end

6543

end

6458

end

6544

PWF_rx=ones(1,length(f));

6459

PWF_rx=ones(1,length(f));

6545

if exist('C','var')

6460

if exist('C','var')

6546

PWF_rx=zeros(1,length(f));

6461

PWF_rx=zeros(1,length(f));

6547

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6462

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

6548

if C(ii+param.RxFFE_cmx+1)==0

6463

if C(ii+param.RxFFE_cmx+1)==0

6549

%speed up: skip cases when rxffe=0

6464

%speed up: skip cases when rxffe=0

6550

continue;

6465

continue;

6551

end

6466

end

6552

if ii+1==0

6467

if ii+1==0

6553

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6468

%speed up: ii+1=0, so just scalar addition and avoid exp calc

6554

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6469

PWF_rx = PWF_rx + C(ii+param.RxFFE_cmx+1);

6555

else

6470

else

6556

if pre_calc

6471

if pre_calc

6557

%speed up: avoid vector exp calculation by externally pre-calculating it

6472

%speed up: avoid vector exp calculation by externally pre-calculating it

6558

%The latter columns of phase_memory hold RXFFE shift vectors

6473

%The latter columns of phase_memory hold RXFFE shift vectors

6559

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6474

term_ii=C(ii+param.RxFFE_cmx+1).*phase_memory(:,ii+param.RxFFE_cmx+1+length(upsampled_txffe));

6560

term_ii=transpose(term_ii);

6475

term_ii=transpose(term_ii);

6561

else

6476

else

6562

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6477

term_ii=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb);

6563

end

6478

end

6564

PWF_rx=PWF_rx+term_ii;

6479

PWF_rx=PWF_rx+term_ii;

6565

end

6480

end

6566

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6481

%PWF_rx=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+PWF_rx;

6567

end

6482

end

6568

end

6483

end

6569

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6484

MDFEXT=0;MDNEXT=0;MDNEXT_ICN=0;MDFEXT_ICN=0;

6570

for ii=2:size(chdata,2)

6485

for ii=2:size(chdata,2)

6571

SINC = sin(temp_angle)./temp_angle;

6486

SINC = sin(temp_angle)./temp_angle;

6572

PWF_data=SINC.^2;

6487

PWF_data=SINC.^2;

6573

PWF=PWF_data.*PWF_rx; % power weight function

6488

PWF=PWF_data.*PWF_rx; % power weight function

6574

PWFnext=abs(PWF);

6489

PWFnext=abs(PWF);

6575

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6490

PWF=PWF_data.*PWF_rx.*PWF_tx; % power weight function

6576

PWFfext=abs(PWF);

6491

PWFfext=abs(PWF);

6577

if isequal(chdata(ii).type, 'FEXT')

6492

if isequal(chdata(ii).type, 'FEXT')

6578

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6493

MDFEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDFEXT.^2); % power sum xtk

6579

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6494

MDFEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFfext(1:index_f2).*abs(MDFEXT(1:index_f2)).^2)); %eq 46

6580

elseif isequal(chdata(ii).type, 'NEXT')

6495

elseif isequal(chdata(ii).type, 'NEXT')

6581

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6496

MDNEXT=sqrt(abs(chdata(ii).sdd21ctf).^2+MDNEXT.^2); % power sum xtk

6582

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6497

MDNEXT_ICN=sqrt(2*chdata(ii).delta_f/param.f2*sum( chdata(ii).A^2*PWFnext(1:index_f2).*abs(MDNEXT(1:index_f2)).^2)); %eq 47

6583

end

6498

end

6584

end

6499

end

6585

if nargout == 1 && isequal(type,'NEXT')

6500

if nargout == 1 && isequal(type,'NEXT')

6586

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6501

sigma_XT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6587

elseif nargout == 1 && isequal(type,'FEXT')

6502

elseif nargout == 1 && isequal(type,'FEXT')

6588

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6503

sigma_XT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6589

elseif nargout == 3

6504

elseif nargout == 3

6590

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6505

sigma_XT=norm([ MDNEXT_ICN MDFEXT_ICN ])*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6591

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6506

sigma_NEXT = MDNEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6592

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6507

sigma_FEXT = MDFEXT_ICN*sqrt((param.levels^2-1)/(3*(param.levels-1)^2));

6593

end

6508

end

6594

6509

6595

function out=hrem(h,index,N_bf,bmaxg)

6510

function out=hrem(h,index,N_bf,bmaxg)

6596

6511

6597

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6512

out=[ h(1:index-1) h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) h(index+N_bf:end) ];

6598

% faster than single line function

6513

% faster than single line function

6599

% hrem =@(h,index,N_bf,bmaxg) ...

6514

% hrem =@(h,index,N_bf,bmaxg) ...

6600

% [ h(1:index-1) ...

6515

% [ h(1:index-1) ...

6601

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6516

% h(index:index+N_bf-1)- sign(h(index:index+N_bf-1)).* (min( bmaxg, abs( h(index:index+N_bf-1) ))) ...

6602

% h(index+N_bf:end) ]...

6517

% h(index+N_bf:end) ]...

6603

% ;

6518

% ;

6604

6519

6605

%% floating DFE taps

6520

%% floating DFE taps

6606

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6521

function [Sout] = interp_Sparam(Sin,fin,fout, ...

6607

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6522

opt_interp_Sparam_mag, opt_interp_Sparam_phase,OP)

6608

% Sout = interp_Sparam(Sin,fin,fout)

6523

% Sout = interp_Sparam(Sin,fin,fout)

6609

%

6524

%

6610

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6525

% Interpolate S-parameters Sin from frequency grid fin to frequency grid

6611

% fout.

6526

% fout.

6612

6527

6613

if ( fin(end)<fout(end) )

6528

if ( fin(end)<fout(end) )

6614

% warning('Channel high frequencies extrapolation might be inaccurate!');

6529

% warning('Channel high frequencies extrapolation might be inaccurate!');

6615

end

6530

end

6616

6531

6617

H_mag = abs(Sin);

6532

H_mag = abs(Sin);

6618

H_mag(H_mag<eps)=eps; % handle ill cases...

6533

H_mag(H_mag<eps)=eps; % handle ill cases...

6619

H_ph = unwrap(angle(Sin));

6534

H_ph = unwrap(angle(Sin));

6620

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6535

% For long delay channels, the result can turn anti-causal if frequency step is too coarse. Don't let the

6621

% user ignore that.

6536

% user ignore that.

6622

if mean(diff(H_ph))>0

6537

if mean(diff(H_ph))>0

6623

if OP.DEBUG

6538

if OP.DEBUG

6624

warning('Anti-causal response found. Finer frequency step is required for this channel');

6539

warning('Anti-causal response found. Finer frequency step is required for this channel');

6625

else

6540

else

6626

error('Anti-causal response found. Finer frequency step is required for this channel');

6541

error('Anti-causal response found. Finer frequency step is required for this channel');

6627

end

6542

end

6628

end

6543

end

6629

6544

6630

%opt_interp_Sparam_mag='linear_trend_to_DC';

6545

%opt_interp_Sparam_mag='linear_trend_to_DC';

6631

switch opt_interp_Sparam_mag

6546

switch opt_interp_Sparam_mag

6632

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6547

case {'linear_trend_to_DC','linear_trend_to_DC_log_trend_to_inf'}

6633

if -iscolumn(H_mag), H_mag=H_mag.';end

6548

if -iscolumn(H_mag), H_mag=H_mag.';end

6634

if -iscolumn(fin), fin=fin.';end

6549

if -iscolumn(fin), fin=fin.';end

6635

fin_x=fin;

6550

fin_x=fin;

6636

H_mag_x=H_mag(:);

6551

H_mag_x=H_mag(:);

6637

if fin(1)>0

6552

if fin(1)>0

6638

p=polyfit(fin(1:10), H_mag(1:10), 1);

6553

p=polyfit(fin(1:10), H_mag(1:10), 1);

6639

dc_trend_val=polyval(p, 0);

6554

dc_trend_val=polyval(p, 0);

6640

fin_x=[0, fin_x];

6555

fin_x=[0, fin_x];

6641

H_mag_x = [dc_trend_val; H_mag_x];

6556

H_mag_x = [dc_trend_val; H_mag_x];

6642

end

6557

end

6643

if fin(end)<fout(end)

6558

if fin(end)<fout(end)

6644

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6559

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6645

mid_freq_ind=round(length(fin)/2);

6560

mid_freq_ind=round(length(fin)/2);

6646

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6561

p=polyfit(fin(mid_freq_ind:end), H_mag(mid_freq_ind:end), 1);

6647

warning(warn_state);

6562

warning(warn_state);

6648

hf_trend_val=polyval(p, fout(end));

6563

hf_trend_val=polyval(p, fout(end));

6649

if hf_trend_val>H_mag(end)

6564

if hf_trend_val>H_mag(end)

6650

hf_trend_val=H_mag(end);

6565

hf_trend_val=H_mag(end);

6651

hf_logtrend_val = H_mag(end);

6566

hf_logtrend_val = H_mag(end);

6652

elseif hf_trend_val<eps

6567

elseif hf_trend_val<eps

6653

hf_trend_val=eps;

6568

hf_trend_val=eps;

6654

hf_logtrend_val = realmin;

6569

hf_logtrend_val = realmin;

6655

end

6570

end

6656

fin_x=[fin_x, fout(end)];

6571

fin_x=[fin_x, fout(end)];

6657

H_mag_x = [H_mag_x; hf_trend_val];

6572

H_mag_x = [H_mag_x; hf_trend_val];

6658

end

6573

end

6659

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6574

H_mag_i = interp1(fin_x, H_mag_x, fout, 'linear', 'extrap');

6660

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6575

if strcmp(opt_interp_Sparam_mag,'linear_trend_to_DC_log_trend_to_inf')

6661

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6576

H_logmag_i = exp(interp1(fin_x, log([H_mag_x(1:end-1);hf_logtrend_val]), fout, 'linear', 'extrap'));

6662

indx = find(fout > fin(end),1,'first');

6577

indx = find(fout > fin(end),1,'first');

6663

H_mag_i(indx:end) = H_logmag_i(indx:end);

6578

H_mag_i(indx:end) = H_logmag_i(indx:end);

6664

end

6579

end

6665

case 'trend_to_DC'

6580

case 'trend_to_DC'

6666

% extrapolate to trend value at DC.

6581

% extrapolate to trend value at DC.

6667

if -iscolumn(H_mag), H_mag=H_mag.';end

6582

if -iscolumn(H_mag), H_mag=H_mag.';end

6668

if -iscolumn(fin), fin=fin.';end

6583

if -iscolumn(fin), fin=fin.';end

6669

fin_x=fin;

6584

fin_x=fin;

6670

H_mag_x=H_mag;

6585

H_mag_x=H_mag;

6671

if fin(1)>0

6586

if fin(1)>0

6672

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6587

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6673

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6588

p=polyfit(fin(1:10), log10(H_mag(1:10)), 1);

6674

dc_trend_val=10^polyval(p, 0);

6589

dc_trend_val=10^polyval(p, 0);

6675

fin_x=[0, fin_x];

6590

fin_x=[0, fin_x];

6676

H_mag_x = [dc_trend_val H_mag_x];

6591

H_mag_x = [dc_trend_val H_mag_x];

6677

end

6592

end

6678

if fin(end)<fout(end)

6593

if fin(end)<fout(end)

6679

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6594

warn_state=warning('off', 'MATLAB:polyfit:RepeatedPointsOrRescale');

6680

mid_freq_ind=round(length(fin)/2);

6595

mid_freq_ind=round(length(fin)/2);

6681

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6596

p=polyfit(fin(mid_freq_ind:end), log10(H_mag(mid_freq_ind:end)), 1);

6682

warning(warn_state);

6597

warning(warn_state);

6683

hf_trend_val=10^polyval(p, fout(end));

6598

hf_trend_val=10^polyval(p, fout(end));

6684

if hf_trend_val>H_mag(end)

6599

if hf_trend_val>H_mag(end)

6685

hf_trend_val=H_mag(end);

6600

hf_trend_val=H_mag(end);

6686

end

6601

end

6687

fin_x=[fin_x, fout(end)];

6602

fin_x=[fin_x, fout(end)];

6688

H_mag_x = [H_mag_x hf_trend_val];

6603

H_mag_x = [H_mag_x hf_trend_val];

6689

end

6604

end

6690

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6605

H_mag_i = 10.^interp1(fin_x,log10(H_mag_x),fout,'linear', 'extrap');

6691

case 'extrap_to_DC_or_zero'

6606

case 'extrap_to_DC_or_zero'

6692

% same as extrap_to_DC but detect AC-coupled channels and

6607

% same as extrap_to_DC but detect AC-coupled channels and

6693

% extrapolate them to 0.

6608

% extrapolate them to 0.

6694

if fin(1)>0 && 20*log10(H_mag(1))<-20

6609

if fin(1)>0 && 20*log10(H_mag(1))<-20

6695

% assume AC coupling, with 0 at DC

6610

% assume AC coupling, with 0 at DC

6696

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6611

H_mag_i = 10.^interp1([0, fin],[-100; log10(H_mag)],fout(fout<=fin(end)),'linear', 'extrap');

6697

else

6612

else

6698

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6613

H_mag_i = 10.^interp1(fin, log10(H_mag), fout(fout<=fin(end)),'linear', 'extrap');

6699

end

6614

end

6700

H_mag_i(fout>fin(end)) = H_mag(end);

6615

H_mag_i(fout>fin(end)) = H_mag(end);

6701

case 'extrap_to_DC'

6616

case 'extrap_to_DC'

6702

% first extrapolate down to DC, then use highest available frequency

6617

% first extrapolate down to DC, then use highest available frequency

6703

% for higher frequencies

6618

% for higher frequencies

6704

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6619

H_mag_i = 10.^interp1(fin,log10(H_mag),fout(fout<=fin(end)),'linear', 'extrap');

6705

H_mag_i(fout>fin(end)) = H_mag(end);

6620

H_mag_i(fout>fin(end)) = H_mag(end);

6706

case 'old'

6621

case 'old'

6707

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6622

H_mag_i = interp1(fin,H_mag,fout,'linear','extrap');

6708

otherwise

6623

otherwise

6709

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6624

error('COM:Extrap:InvalidOption', 'opt_interp_Sparam_mag valid values are "old", "extrap_to_DC"');

6710

end

6625

end

6711

6626

6712

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6627

H_ph_i = interp1(fin,squeeze(H_ph),fout,'linear', 'extrap');

6713

6628

6714

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6629

%opt_interp_Sparam_phase='trend_and_shift_to_DC';

6715

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6630

%opt_interp_Sparam_phase='interp_cubic_to_dc_linear_to_inf';

6716

switch opt_interp_Sparam_phase

6631

switch opt_interp_Sparam_phase

6717

case 'old'

6632

case 'old'

6718

H_ph_i = H_ph_i-H_ph_i(1);

6633

H_ph_i = H_ph_i-H_ph_i(1);

6719

case 'zero_DC'

6634

case 'zero_DC'

6720

H_ph_i(1) = 0;

6635

H_ph_i(1) = 0;

6721

case 'interp_to_DC'

6636

case 'interp_to_DC'

6722

if fin(1) ~= 0

6637

if fin(1) ~= 0

6723

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6638

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)], fout, 'linear', 'extrap');

6724

end

6639

end

6725

case 'extrap_cubic_to_dc_linear_to_inf'

6640

case 'extrap_cubic_to_dc_linear_to_inf'

6726

if fin(1) ~= 0

6641

if fin(1) ~= 0

6727

% estimate low frequency group delay

6642

% estimate low frequency group delay

6728

group_delay = -diff(H_ph(:))./diff(fin(:));

6643

group_delay = -diff(H_ph(:))./diff(fin(:));

6729

low_freq_gd = group_delay(1:50);

6644

low_freq_gd = group_delay(1:50);

6730

% calculate trend, throwing away outliers

6645

% calculate trend, throwing away outliers

6731

m = median(low_freq_gd); sigma = std(low_freq_gd);

6646

m = median(low_freq_gd); sigma = std(low_freq_gd);

6732

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6647

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6733

% correct outliers in first 10 phase samples

6648

% correct outliers in first 10 phase samples

6734

for k=10:-1:1

6649

for k=10:-1:1

6735

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6650

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6736

end

6651

end

6737

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6652

H_ph_cubic = interp1(fin, H_ph, fout, 'pchip', 'extrap');

6738

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6653

H_ph_linear = interp1(fin, H_ph, fout, 'linear', 'extrap');

6739

% modification - trend to inf

6654

% modification - trend to inf

6740

if (1)

6655

if (1)

6741

high_freq_gd = group_delay(end-50:end);

6656

high_freq_gd = group_delay(end-50:end);

6742

% calculate trend, throwing away outliers

6657

% calculate trend, throwing away outliers

6743

m = median(high_freq_gd); sigma = std(high_freq_gd);

6658

m = median(high_freq_gd); sigma = std(high_freq_gd);

6744

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6659

hf_trend = -mean(high_freq_gd(abs(high_freq_gd-m)<sigma));

6745

hf_extrap_range = find(fout>fin(end));

6660

hf_extrap_range = find(fout>fin(end));

6746

last_data_sample = hf_extrap_range(1)-1;

6661

last_data_sample = hf_extrap_range(1)-1;

6747

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6662

H_ph_linear(hf_extrap_range) = H_ph_linear(last_data_sample) + (fout(hf_extrap_range)-fout(last_data_sample))*hf_trend;

6748

% for k=hf_range

6663

% for k=hf_range

6749

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6664

% H_ph_linear(k) = H_ph_linear(k-1) + hf_trend*(fout(k)-fout(k-1));

6750

% end

6665

% end

6751

end

6666

end

6752

6667

6753

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6668

[UNUSED_OUTPUT, indx] = min(abs(H_ph_cubic-H_ph_linear)); %#ok<ASGLU>

6754

H_ph_i=H_ph_cubic;

6669

H_ph_i=H_ph_cubic;

6755

H_ph_i(indx:end) = H_ph_linear(indx:end);

6670

H_ph_i(indx:end) = H_ph_linear(indx:end);

6756

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6671

H_ph_i = H_ph_linear; % John Ewen 12/13/2019

6757

end

6672

end

6758

case 'interp_and_shift_to_DC'

6673

case 'interp_and_shift_to_DC'

6759

if fin(1) ~= 0

6674

if fin(1) ~= 0

6760

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6675

dc_phase_trend = H_ph(1)-(H_ph(2)-H_ph(1))/(fin(2)-fin(1))*fin(1);

6761

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6676

H_ph_i = interp1([0; fin(:)], [0; H_ph(:)-dc_phase_trend], fout, 'linear', 'extrap');

6762

end

6677

end

6763

case 'trend_and_shift_to_DC'

6678

case 'trend_and_shift_to_DC'

6764

% estimate low frequency group delay

6679

% estimate low frequency group delay

6765

group_delay = -diff(H_ph(:))./diff(fin(:));

6680

group_delay = -diff(H_ph(:))./diff(fin(:));

6766

low_freq_gd = group_delay(1:50);

6681

low_freq_gd = group_delay(1:50);

6767

% calculate trend, throwing away outliers

6682

% calculate trend, throwing away outliers

6768

m = median(low_freq_gd); sigma = std(low_freq_gd);

6683

m = median(low_freq_gd); sigma = std(low_freq_gd);

6769

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6684

lf_trend = mean(low_freq_gd(abs(low_freq_gd-m)<sigma));

6770

fin_x=fin;

6685

fin_x=fin;

6771

H_ph_x=H_ph(:);

6686

H_ph_x=H_ph(:);

6772

if fin(1) ~= 0

6687

if fin(1) ~= 0

6773

% correct outliers in first 10 phase samples

6688

% correct outliers in first 10 phase samples

6774

for k=10:-1:1

6689

for k=10:-1:1

6775

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6690

H_ph(k) = H_ph(k+1) + lf_trend*(fin(k+1)-fin(k));

6776

end

6691

end

6777

6692

6778

% shift all phase data so that DC extrapolation to 0 follows trend

6693

% shift all phase data so that DC extrapolation to 0 follows trend

6779

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6694

dc_phase_trend = H_ph(1)+lf_trend*(fin(1)-0);

6780

fin_x=[0, fin_x];

6695

fin_x=[0, fin_x];

6781

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6696

H_ph_x=[0; H_ph(:)-dc_phase_trend];

6782

end

6697

end

6783

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6698

% Modification: extrapolate using trend. (interp1 with "extrap" extrapolates using just

6784

% the last two samples, so noise can create an inverted slope and

6699

% the last two samples, so noise can create an inverted slope and

6785

% non-causal response).

6700

% non-causal response).

6786

if fout(end)>fin(end)

6701

if fout(end)>fin(end)

6787

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6702

group_delay = -diff(H_ph_x(:))./diff(fin_x(:));

6788

% p=polyfit(fin_x', H_ph_x, 1);

6703

% p=polyfit(fin_x', H_ph_x, 1);

6789

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6704

hf_phase_trend = H_ph_x(end)-median(group_delay)*(max(fout)-max(fin_x));

6790

% hf_phase_trend=polyval(p,max(fout));

6705

% hf_phase_trend=polyval(p,max(fout));

6791

fin_x=[fin_x, fout(end)];

6706

fin_x=[fin_x, fout(end)];

6792

H_ph_x=[H_ph_x; hf_phase_trend];

6707

H_ph_x=[H_ph_x; hf_phase_trend];

6793

end

6708

end

6794

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6709

H_ph_i = interp1(fin_x, H_ph_x, fout, 'linear', 'extrap');

6795

6710

6796

otherwise

6711

otherwise

6797

error('COM:Extrap:InvalidOption', ...

6712

error('COM:Extrap:InvalidOption', ...

6798

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6713

'debug_interp_Sparam valid values are "old", "zero_DC", "interp_to_DC", "interp_and_shift_to_DC", "trend_and_shift_to_DC", "interp_cubic_to_dc_linear_to_inf"');

6799

end

6714

end

6800

H_i = H_mag_i.*exp(1j*H_ph_i);

6715

H_i = H_mag_i.*exp(1j*H_ph_i);

6801

Sout=H_i;

6716

Sout=H_i;

6802

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6717

function [ s11out, s12out, s21out, s22out]=make_full_pkg(type,faxis,param,channel_type,mode,include_die)

6803

6718

6804

%This function makes the TX or RX package. The type input must be

6719

%This function makes the TX or RX package. The type input must be

6805

%'TX' or 'RX'

6720

%'TX' or 'RX'

6806

%If the mode argument is omitted, mode='dd' is assumed. Currently

6721

%If the mode argument is omitted, mode='dd' is assumed. Currently

6807

%mode='dc' is only used when making the TX package for AC CM noise

6722

%mode='dc' is only used when making the TX package for AC CM noise

6808

%inclusion. The Rx package for 'dc' mode is still generated using

6723

%inclusion. The Rx package for 'dc' mode is still generated using

6809

%the same parameters as 'dd' mode

6724

%the same parameters as 'dd' mode

6810

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6725

%channel_type should be 'THRU' 'FEXT' or 'NEXT'

6811

%

6726

%

6812

%One instance of package block looks like this (if no elements are set to 0):

6727

%One instance of package block looks like this (if no elements are set to 0):

6813

%-------------Lcomp----------Tline---------------

6728

%-------------Lcomp----------Tline---------------

6814

% | | |

6729

% | | |

6815

% Cpad Cbump Cball

6730

% Cpad Cbump Cball

6816

% | | |

6731

% | | |

6817

%------------------------------------------------

6732

%------------------------------------------------

6818

6733

6819

if nargin<6

6734

if nargin<6

6820

%optional input "include_die"=0 allows die parameters to be forced to 0

6735

%optional input "include_die"=0 allows die parameters to be forced to 0

6821

%this includes Cpad, Lcomp, and Cbump

6736

%this includes Cpad, Lcomp, and Cbump

6822

include_die=1;

6737

include_die=1;

6823

end

6738

end

6824

if nargin<5

6739

if nargin<5

6825

mode='dd';

6740

mode='dd';

6826

end

6741

end

6827

6742

6828

6743

6829

if ~isempty(param.PKG_NAME)

6744

if ~isempty(param.PKG_NAME)

6830

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6745

%The gamma and tau parameters do not currently have a separate Tx and Rx home to live (they were locked for both sides originally)

6831

%so they are swapped in depending on if Tx or Rx is set for type

6746

%so they are swapped in depending on if Tx or Rx is set for type

6832

%Note that param is not returned from this function, so the swap does not persist

6747

%Note that param is not returned from this function, so the swap does not persist

6833

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6748

swap_fields = {'pkg_gamma0_a1_a2' 'pkg_tau'};

6834

if strcmpi(type,'tx')

6749

if strcmpi(type,'tx')

6835

pkg_name = param.PKG_NAME{1};

6750

pkg_name = param.PKG_NAME{1};

6836

elseif strcmpi(type,'rx')

6751

elseif strcmpi(type,'rx')

6837

pkg_name = param.PKG_NAME{2};

6752

pkg_name = param.PKG_NAME{2};

6838

else

6753

else

6839

error('Pkg type must be Tx or Rx');

6754

error('Pkg type must be Tx or Rx');

6840

end

6755

end

6841

pkg_parameter_struct = param.PKG.(pkg_name);

6756

pkg_parameter_struct = param.PKG.(pkg_name);

6842

6757

6843

6758

6844

for j=1:length(swap_fields)

6759

for j=1:length(swap_fields)

6845

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6760

param.(swap_fields{j}) = pkg_parameter_struct.(swap_fields{j});

6846

end

6761

end

6847

6762

6848

end

6763

end

6849

6764

6850

C_diepad = param.C_diepad;

6765

C_diepad = param.C_diepad;

6851

C_pkg_board = param.C_pkg_board;

6766

C_pkg_board = param.C_pkg_board;

6852

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6767

% [ahealey] Unpack optional compensating L and "bump" C model parameters.

6853

L_comp = param.L_comp;

6768

L_comp = param.L_comp;

6854

C_bump = param.C_bump;

6769

C_bump = param.C_bump;

6855

if ~include_die

6770

if ~include_die

6856

%best to multiply by 0. that way vectors maintain original size

6771

%best to multiply by 0. that way vectors maintain original size

6857

C_diepad=C_diepad*0;

6772

C_diepad=C_diepad*0;

6858

L_comp=L_comp*0;

6773

L_comp=L_comp*0;

6859

C_bump=C_bump*0;

6774

C_bump=C_bump*0;

6860

end

6775

end

6861

% [ahealey] End of modifications.

6776

% [ahealey] End of modifications.

6862

% generate TX package according to channel type.

6777

% generate TX package according to channel type.

6863

[ncases, mele]=size(param.z_p_next_cases);

6778

[ncases, mele]=size(param.z_p_next_cases);

6864

6779

6865

%Syntax update for C_diepad and L_comp

6780

%Syntax update for C_diepad and L_comp

6866

%Allow a chain of values to be entered as a matrix:

6781

%Allow a chain of values to be entered as a matrix:

6867

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6782

%[L_Tx1 L_Tx2 L_Tx3 ; L_Rx1 L_Rx2 L_Rx3]

6868

if isvector(C_diepad)

6783

if isvector(C_diepad)

6869

Cd_Tx=C_diepad(1);

6784

Cd_Tx=C_diepad(1);

6870

Cd_Rx=C_diepad(2);

6785

Cd_Rx=C_diepad(2);

6871

L_comp_Tx=L_comp(1);

6786

L_comp_Tx=L_comp(1);

6872

L_comp_Rx=L_comp(2);

6787

L_comp_Rx=L_comp(2);

6873

num_blocks=mele;

6788

num_blocks=mele;

6874

else

6789

else

6875

Cd_Tx=C_diepad(1,:);

6790

Cd_Tx=C_diepad(1,:);

6876

Cd_Rx=C_diepad(2,:);

6791

Cd_Rx=C_diepad(2,:);

6877

L_comp_Tx=L_comp(1,:);

6792

L_comp_Tx=L_comp(1,:);

6878

L_comp_Rx=L_comp(2,:);

6793

L_comp_Rx=L_comp(2,:);

6879

num_blocks=mele+length(Cd_Tx)-1;

6794

num_blocks=mele+length(Cd_Tx)-1;

6880

end

6795

end

6881

extra_LC=length(Cd_Tx)-1;

6796

extra_LC=length(Cd_Tx)-1;

6882

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6797

%note: "insert_zeros" is empty if length(Cd_Tx) = 1

6883

insert_zeros=zeros([1 extra_LC]);

6798

insert_zeros=zeros([1 extra_LC]);

6884

6799

6885

%Updated technique of building Tx/Rx packages

6800

%Updated technique of building Tx/Rx packages

6886

%each index corresponds to the package segment

6801

%each index corresponds to the package segment

6887

switch type

6802

switch type

6888

case 'TX'

6803

case 'TX'

6889

switch mele

6804

switch mele

6890

case 1

6805

case 1

6891

Cpad=Cd_Tx;

6806

Cpad=Cd_Tx;

6892

Lcomp=L_comp_Tx;

6807

Lcomp=L_comp_Tx;

6893

Cbump=C_bump(1);

6808

Cbump=C_bump(1);

6894

Cball=C_pkg_board(1);

6809

Cball=C_pkg_board(1);

6895

Zpkg=param.pkg_Z_c(1);

6810

Zpkg=param.pkg_Z_c(1);

6896

case 4

6811

case 4

6897

Cpad=[Cd_Tx 0 0 0];

6812

Cpad=[Cd_Tx 0 0 0];

6898

Lcomp=[L_comp_Tx 0 0 0];

6813

Lcomp=[L_comp_Tx 0 0 0];

6899

Cbump=[C_bump(1) 0 0 0];

6814

Cbump=[C_bump(1) 0 0 0];

6900

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6815

Cball=[0 0 param.C_v(1) C_pkg_board(1)];

6901

Zpkg=param.pkg_Z_c(1,:);

6816

Zpkg=param.pkg_Z_c(1,:);

6902

otherwise

6817

otherwise

6903

error('package syntax error')

6818

error('package syntax error')

6904

end

6819

end

6905

switch upper(channel_type)

6820

switch upper(channel_type)

6906

case 'THRU'

6821

case 'THRU'

6907

Len=param.Pkg_len_TX;

6822

Len=param.Pkg_len_TX;

6908

case 'NEXT'

6823

case 'NEXT'

6909

Len=param.Pkg_len_NEXT;

6824

Len=param.Pkg_len_NEXT;

6910

case 'FEXT'

6825

case 'FEXT'

6911

Len=param.Pkg_len_FEXT;

6826

Len=param.Pkg_len_FEXT;

6912

end

6827

end

6913

case 'RX'

6828

case 'RX'

6914

switch mele

6829

switch mele

6915

case 1

6830

case 1

6916

Cpad=Cd_Rx;

6831

Cpad=Cd_Rx;

6917

Lcomp=L_comp_Rx;

6832

Lcomp=L_comp_Rx;

6918

Cbump=C_bump(2);

6833

Cbump=C_bump(2);

6919

Cball=C_pkg_board(2);

6834

Cball=C_pkg_board(2);

6920

Zpkg=param.pkg_Z_c(2);

6835

Zpkg=param.pkg_Z_c(2);

6921

case 4

6836

case 4

6922

Cpad=[Cd_Rx 0 0 0];

6837

Cpad=[Cd_Rx 0 0 0];

6923

Lcomp=[L_comp_Rx 0 0 0];

6838

Lcomp=[L_comp_Rx 0 0 0];

6924

Cbump=[C_bump(2) 0 0 0];

6839

Cbump=[C_bump(2) 0 0 0];

6925

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6840

Cball=[0 0 param.C_v(2) C_pkg_board(2)];

6926

Zpkg=param.pkg_Z_c(2,:);

6841

Zpkg=param.pkg_Z_c(2,:);

6927

otherwise

6842

otherwise

6928

error('package syntax error')

6843

error('package syntax error')

6929

end

6844

end

6930

switch upper(channel_type)

6845

switch upper(channel_type)

6931

case 'THRU'

6846

case 'THRU'

6932

Len=param.Pkg_len_RX;

6847

Len=param.Pkg_len_RX;

6933

case 'NEXT'

6848

case 'NEXT'

6934

Len=param.Pkg_len_RX;

6849

Len=param.Pkg_len_RX;

6935

case 'FEXT'

6850

case 'FEXT'

6936

Len=param.Pkg_len_RX;

6851

Len=param.Pkg_len_RX;

6937

end

6852

end

6938

end

6853

end

6939

6854

6940

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6855

%Insert the extra 0 at the front end of Cball, Cbump, Len, and Zpkg

6941

Cball=[insert_zeros Cball];

6856

Cball=[insert_zeros Cball];

6942

Cbump=[insert_zeros Cbump];

6857

Cbump=[insert_zeros Cbump];

6943

Len=[insert_zeros Len];

6858

Len=[insert_zeros Len];

6944

Zpkg=[insert_zeros Zpkg];

6859

Zpkg=[insert_zeros Zpkg];

6945

6860

6946

% debug_string='';

6861

% debug_string='';

6947

% for j=1:length(Zpkg)

6862

% for j=1:length(Zpkg)

6948

% if Cpad(j)~=0

6863

% if Cpad(j)~=0

6949

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6864

% debug_string=[debug_string sprintf(', Cd=%0.4g',Cpad(j))];

6950

% end

6865

% end

6951

% if Lcomp(j)~=0

6866

% if Lcomp(j)~=0

6952

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6867

% debug_string=[debug_string sprintf(', Ls=%0.4g',Lcomp(j))];

6953

% end

6868

% end

6954

% if Cbump(j)~=0

6869

% if Cbump(j)~=0

6955

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6870

% debug_string=[debug_string sprintf(', Cb=%0.4g',Cbump(j))];

6956

% end

6871

% end

6957

% if Len(j)~=0

6872

% if Len(j)~=0

6958

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6873

% debug_string=[debug_string sprintf(', Len=%0.4g Zc=%0.3g',Len(j),Zpkg(j))];

6959

% end

6874

% end

6960

% if Cball(j)~=0

6875

% if Cball(j)~=0

6961

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6876

% debug_string=[debug_string sprintf(', Cp=%0.4g',Cball(j))];

6962

% end

6877

% end

6963

% end

6878

% end

6964

% if length(debug_string)>2

6879

% if length(debug_string)>2

6965

% debug_string=debug_string(3:end);

6880

% debug_string=debug_string(3:end);

6966

% end

6881

% end

6967

6882

6968

% tx package

6883

% tx package

6969

pkg_param=param;

6884

pkg_param=param;

6970

if strcmpi(mode,'dc')

6885

if strcmpi(mode,'dc')

6971

% change tx package to CC mode

6886

% change tx package to CC mode

6972

pkg_param.Z0=pkg_param.Z0/2;

6887

pkg_param.Z0=pkg_param.Z0/2;

6973

Cpad=Cpad*2;

6888

Cpad=Cpad*2;

6974

Cball=Cball*2;

6889

Cball=Cball*2;

6975

Zpkg=Zpkg*2;

6890

Zpkg=Zpkg*2;

6976

Lcomp=Lcomp/2;

6891

Lcomp=Lcomp/2;

6977

Cbump=Cbump*2;

6892

Cbump=Cbump*2;

6978

end

6893

end

6979

switch num_blocks

6894

switch num_blocks

6980

case 1

6895

case 1

6981

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6896

[ s11out, s12out, s21out, s22out ]= make_pkg(faxis, Len(1), Cpad(1), Cball(1),Zpkg(1), pkg_param, Lcomp(1), Cbump(1));

6982

otherwise

6897

otherwise

6983

for j=1:num_blocks

6898

for j=1:num_blocks

6984

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6899

[spkg11,spkg12,spkg21,spkg22]=make_pkg(faxis, Len(j), Cpad(j),Cball(j) ,Zpkg(j), pkg_param, Lcomp(j),Cbump(j));

6985

if j==1

6900

if j==1

6986

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6901

s11out=spkg11; s12out=spkg12; s21out=spkg21; s22out=spkg22;

6987

else

6902

else

6988

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6903

[ s11out, s12out, s21out, s22out ]=combines4p( s11out, s12out, s21out, s22out, spkg11,spkg12,spkg21,spkg22 );

6989

end

6904

end

6990

end

6905

end

6991

end

6906

end

6992

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6907

function [ s11out, s12out, s21out, s22out ] = make_pkg(f, pkg_len, cpad, cball, pkg_z, param, varargin)

6993

f(f<eps)=eps;

6908

f(f<eps)=eps;

6994

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6909

tau = param.pkg_tau; gamma0_a1_a2=param.pkg_gamma0_a1_a2; Lenscale=pkg_len; zref=param.Z0;

6995

%% Equation 93A-8

6910

%% Equation 93A-8

6996

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6911

s11pad= -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

6997

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6912

s21pad= 2./(2+1i*2*pi.*f*cpad*zref);

6998

6913

6999

% [ahealey] Add compensating L and shunt C (bump) when requested.

6914

% [ahealey] Add compensating L and shunt C (bump) when requested.

7000

s12pad = s21pad;

6915

s12pad = s21pad;

7001

s22pad = s11pad;

6916

s22pad = s11pad;

7002

if nargin > 6

6917

if nargin > 6

7003

lcomp = varargin{1};

6918

lcomp = varargin{1};

7004

if lcomp>0

6919

if lcomp>0

7005

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

6920

s11comp = (1i*2*pi*f*lcomp/zref)./(2+1i*2*pi*f*lcomp/zref);

7006

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

6921

s21comp = 2./(2+1i*2*pi*f*lcomp/zref);

7007

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6922

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7008

s11pad, s12pad, s21pad, s22pad, ...

6923

s11pad, s12pad, s21pad, s22pad, ...

7009

s11comp, s21comp, s21comp, s11comp);

6924

s11comp, s21comp, s21comp, s11comp);

7010

end

6925

end

7011

end

6926

end

7012

if nargin > 7

6927

if nargin > 7

7013

cbump = varargin{2};

6928

cbump = varargin{2};

7014

if cbump>0

6929

if cbump>0

7015

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

6930

s11bump = -1i*2*pi.*f*cbump*zref./(2+1i*2*pi.*f*cbump*zref);

7016

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

6931

s21bump = 2./(2+1i*2*pi.*f*cbump*zref);

7017

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

6932

[s11pad, s12pad, s21pad, s22pad] = combines4p( ...

7018

s11pad, s12pad, s21pad, s22pad, ...

6933

s11pad, s12pad, s21pad, s22pad, ...

7019

s11bump, s21bump, s21bump, s11bump);

6934

s11bump, s21bump, s21bump, s11bump);

7020

end

6935

end

7021

end

6936

end

7022

% [ahealey] End of modifications.

6937

% [ahealey] End of modifications.

7023

6938

7024

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

6939

[ S11, S12, S21, S22 ] = synth_tline(f, pkg_z, zref, gamma0_a1_a2, tau, Lenscale); %#ok<NASGU,ASGLU>

7025

% [ahealey] Symmetry cannot be assumed with more complex termination models.

6940

% [ahealey] Symmetry cannot be assumed with more complex termination models.

7026

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

6941

% [ s11out1, s12out1, s21out1, s22out1 ]= ...

7027

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

6942

% combines4p( s11pad, s21pad, s21pad, s11pad, S11, S21, S21, S11 ); % first part of equation 93A-15

7028

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

6943

[s11out1, s12out1, s21out1, s22out1] = combines4p( ...

7029

s11pad, s12pad, s21pad, s22pad, ...

6944

s11pad, s12pad, s21pad, s22pad, ...

7030

S11, S21, S21, S11);

6945

S11, S21, S21, S11);

7031

% [ahealey] End of modifications.

6946

% [ahealey] End of modifications.

7032

6947

7033

%% Equation 93A-8

6948

%% Equation 93A-8

7034

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

6949

s11ball= -1i*2*pi.*f*cball*zref./(2+1i*2*pi.*f*cball*zref);

7035

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

6950

s21ball= 2./(2+1i*2*pi.*f*cball*zref);

7036

[ s11out, s12out, s21out, s22out ]= ...

6951

[ s11out, s12out, s21out, s22out ]= ...

7037

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

6952

combines4p( s11out1, s12out1, s21out1, s22out1, s11ball, s21ball, s21ball, s11ball );% second part of equation 93A-15

7038

6953

7039

function missingParameter (parameterName)

6954

function missingParameter (parameterName)

7040

error( 'error:badParameterInformation', ...

6955

error( 'error:badParameterInformation', ...

7041

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

6956

'The data for mandatory parameter %s is missing or incorrect' , parameterName);

7042

6957

7043

function pdf = normal_dist(sigma,nsigma,binsize)

6958

function pdf = normal_dist(sigma,nsigma,binsize)

7044

pdf.BinSize=binsize;

6959

pdf.BinSize=binsize;

7045

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

6960

pdf.Min=-round(2*nsigma*sigma/binsize); % RIM 03/03/2023 capture more of the tails

7046

pdf.x=(pdf.Min:-pdf.Min)*binsize;

6961

pdf.x=(pdf.Min:-pdf.Min)*binsize;

7047

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

6962

pdf.y=exp(-pdf.x.^2/(2*sigma^2+eps));

7048

pdf.y=pdf.y/sum(pdf.y);

6963

pdf.y=pdf.y/sum(pdf.y);

7049

6964

7050

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

6965

function result=optimize_fom(OP, param, chdata, sigma_bn,do_C2M)

7051

%% input

6966

%% input

7052

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

6967

% chdata(1).uneq_imp_response is the impulse response input expected to be normalized to At, peak drive voltage

7053

% baud_rate - baud rate in seconds

6968

% baud_rate - baud rate in seconds

7054

% param.samples_per_ui = samples per UI of IR

6969

% param.samples_per_ui = samples per UI of IR

7055

% param.max_ctle - maximum ac to dc gain in dB

6970

% param.max_ctle - maximum ac to dc gain in dB

7056

% param.tx_ffe(1) - maximum pre cursor (positive value)

6971

% param.tx_ffe(1) - maximum pre cursor (positive value)

7057

% param.tx_ffe(2) - maximum post cursor (positive value)

6972

% param.tx_ffe(2) - maximum post cursor (positive value)

7058

% param.tx_ffe_step - sweep step size for tx pre and post taps

6973

% param.tx_ffe_step - sweep step size for tx pre and post taps

7059

% param.ndfe - number of reference dfe taps

6974

% param.ndfe - number of reference dfe taps

7060

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

6975

% do_C2M. set to 0 for standard optimize_fom. set to 1 for optimize_fom_for_C2M

7061

% output

6976

% output

7062

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

6977

% result.eq.txle - [ precusor curosr postcursor]: pre and post are negative

7063

% result.eq.ctle - index of CTLE parameters in table

6978

% result.eq.ctle - index of CTLE parameters in table

7064

% result.IR - impulse response

6979

% result.IR - impulse response

7065

% result.avail_signal - maximum signal after equalization

6980

% result.avail_signal - maximum signal after equalization

7066

% result.avail_sig_index - index in result.IR of max signal

6981

% result.avail_sig_index - index in result.IR of max signal

7067

% result.best_FOM - best raw ISI

6982

% result.best_FOM - best raw ISI

7068

6983

7069

min_number_of_UI_in_response=40;

6984

min_number_of_UI_in_response=40;

7070

baud_rate=1/param.ui;

6985

baud_rate=1/param.ui;

7071

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

6986

% H_r = 1./polyval([1 2.613126 3.414214 2.613126 1], 1i*chdata(1).faxis/(param.f_r*param.fb));

7072

f=chdata(1).faxis;

6987

f=chdata(1).faxis;

7073

6988

7074

%Read user input of ts_sample_adj_range

6989

%Read user input of ts_sample_adj_range

7075

%if one value was entered, go from 0 to that value

6990

%if one value was entered, go from 0 to that value

7076

%if 2 values were entered, go from the 1st value to the 2nd value

6991

%if 2 values were entered, go from the 1st value to the 2nd value

7077

if length(param.ts_sample_adj_range)==1

6992

if length(param.ts_sample_adj_range)==1

7078

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

6993

param.ts_sample_adj_range(2)=param.ts_sample_adj_range(1);

7079

param.ts_sample_adj_range(1)=0;

6994

param.ts_sample_adj_range(1)=0;

7080

end

6995

end

7081

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

6996

full_sample_range=param.ts_sample_adj_range(1):param.ts_sample_adj_range(2);

7082

6997

7083

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

6998

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

7084

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

6999

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

7085

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7000

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

7086

% need to include H_RCos in noise and when computing the system ir for thru

7001

% need to include H_RCos in noise and when computing the system ir for thru

7087

% and crosstalk

7002

% and crosstalk

7088

H_r=H_bw.*H_bt.*H_RCos;

7003

H_r=H_bw.*H_bt.*H_RCos;

7089

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7004

%% Bill Kirkland, need to get auto correlation of H_r.*HCTLE

7090

% Get f vector from 0 to Fs/2-delta_f.

7005

% Get f vector from 0 to Fs/2-delta_f.

7091

N_fft_by2 = 512;

7006

N_fft_by2 = 512;

7092

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7007

f_xc = ((1:N_fft_by2)-1)/N_fft_by2*baud_rate*param.samples_per_ui/2;

7093

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7008

H_bt_xc=Bessel_Thomson_Filter(param,f_xc,OP.Bessel_Thomson);

7094

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7009

H_bw_xc=Butterworth_Filter(param,f_xc,OP.Butterworth);

7095

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7010

H_RCos_xc=Raised_Cosine_Filter(param,f_xc,OP.Raised_Cosine);

7096

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7011

H_r_xc=H_bw_xc.*H_bt_xc.*H_RCos_xc;

7097

%%

7012

%%

7098

7013

7099

% system noise H_sy PSD

7014

% system noise H_sy PSD

7100

if OP.USE_ETA0_PSD

7015

if OP.USE_ETA0_PSD

7101

fspike=1e9;

7016

fspike=1e9;

7102

% requires communication tool box if used

7017

% requires communication tool box if used

7103

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7018

H_sy=sinc(sqrt(2)*(chdata(1).faxis-fspike)/(fspike)).^2;

7104

else

7019

else

7105

H_sy=ones(1,length(chdata(1).faxis));

7020

H_sy=ones(1,length(chdata(1).faxis));

7106

end

7021

end

7107

7022

7108

%Build txffe values dynamically

7023

%Build txffe values dynamically

7109

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7024

%any param field that is "tx_ffe_cm<X>_values" is a precursor

7110

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7025

%any param field that is "tx_ffe_cp<X>_values" is a postcursor

7111

%where <X> is any integer

7026

%where <X> is any integer

7112

param_fields=fieldnames(param);

7027

param_fields=fieldnames(param);

7113

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7028

num_pre=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cm\d+_values'))));

7114

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7029

num_post=length(find(~cellfun('isempty',regexp(param_fields,'tx_ffe_cp\d+_values'))));

7115

num_taps=num_pre+num_post;

7030

num_taps=num_pre+num_post;

7116

cur=num_pre+1;

7031

cur=num_pre+1;

7117

%txffe_cell combines all the txffe values into a single cell array

7032

%txffe_cell combines all the txffe values into a single cell array

7118

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7033

%It is ordered: [precursorN precursorN-1 ... precursor1 postcursor1 ... postcursorN-1 postcursorN]

7119

txffe_cell=cell(1,num_taps);

7034

txffe_cell=cell(1,num_taps);

7120

for k=num_pre:-1:1

7035

for k=num_pre:-1:1

7121

idx=num_pre-k+1;

7036

idx=num_pre-k+1;

7122

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7037

this_tx_field=sprintf('tx_ffe_cm%d_values',k);

7123

txffe_cell{idx}=param.(this_tx_field);

7038

txffe_cell{idx}=param.(this_tx_field);

7124

end

7039

end

7125

for k=1:num_post

7040

for k=1:num_post

7126

idx=k+num_pre;

7041

idx=k+num_pre;

7127

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7042

this_tx_field=sprintf('tx_ffe_cp%d_values',k);

7128

txffe_cell{idx}=param.(this_tx_field);

7043

txffe_cell{idx}=param.(this_tx_field);

7129

end

7044

end

7130

%total number of txffe runs is the product of the lengths of each tap

7045

%total number of txffe runs is the product of the lengths of each tap

7131

txffe_lengths=cellfun('length',txffe_cell);

7046

txffe_lengths=cellfun('length',txffe_cell);

7132

if isempty(txffe_cell)

7047

if isempty(txffe_cell)

7133

num_txffe_runs=1;

7048

num_txffe_runs=1;

7134

else

7049

else

7135

num_txffe_runs=prod(txffe_lengths);

7050

num_txffe_runs=prod(txffe_lengths);

7136

end

7051

end

7137

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7052

%txffe_sweep_indices are used in the LOCAL_SEARCH block

7138

%any tap with length=1 can be ignored

7053

%any tap with length=1 can be ignored

7139

%Also is statistically likely that taps with greater number of values

7054

%Also is statistically likely that taps with greater number of values

7140

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7055

%will exceed the LOCAL SEARCH criteria, so searching those first is faster

7141

txffe_sweep_indices=find(txffe_lengths>1);

7056

txffe_sweep_indices=find(txffe_lengths>1);

7142

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7057

[~,length_sort]=sort(txffe_lengths(txffe_sweep_indices),'descend');

7143

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7058

txffe_sweep_indices=txffe_sweep_indices(length_sort);

7144

num_txffe_sweep_indices=length(txffe_sweep_indices);

7059

num_txffe_sweep_indices=length(txffe_sweep_indices);

7145

7060

7146

gdc_values = param.ctle_gdc_values;

7061

gdc_values = param.ctle_gdc_values;

7147

Gffe_values = param.cursor_gain;

7062

Gffe_values = param.cursor_gain;

7148

switch param.CTLE_type

7063

switch param.CTLE_type

7149

case 'CL93'

7064

case 'CL93'

7150

case 'CL120d'

7065

case 'CL120d'

7151

g_DC_HP_values =param.g_DC_HP_values;

7066

g_DC_HP_values =param.g_DC_HP_values;

7152

case 'CL120e'

7067

case 'CL120e'

7153

f_HP_Z=param.f_HP_Z;

7068

f_HP_Z=param.f_HP_Z;

7154

f_HP_P=param.f_HP_P;

7069

f_HP_P=param.f_HP_P;

7155

7070

7156

end

7071

end

7157

best_ctle = [];

7072

best_ctle = [];

7158

best_FOM = -inf;

7073

best_FOM = -inf;

7159

best_txffe = [];

7074

best_txffe = [];

7160

delta_sbr = [];

7075

delta_sbr = [];

7161

PSD_results=[];

7076

PSD_results=[];

7162

MMSE_results=[];

7077

MMSE_results=[];

7163

best_bmax=param.bmax;

7078

best_bmax=param.bmax;

7164

%AJG021820

7079

%AJG021820

7165

best_bmin=param.bmin;

7080

best_bmin=param.bmin;

7166

h_J=[];

7081

h_J=[];

7167

pxi=0;

7082

pxi=0;

7168

if OP.DISPLAY_WINDOW

7083

if OP.DISPLAY_WINDOW

7169

hwaitbar=waitbar(0);

7084

hwaitbar=waitbar(0);

7170

else

7085

else

7171

fprintf('FOM search ');

7086

fprintf('FOM search ');

7172

end

7087

end

7173

FOM=0;

7088

FOM=0;

7174

if ~OP.RxFFE

7089

if ~OP.RxFFE

7175

Gffe_values=0;

7090

Gffe_values=0;

7176

end

7091

end

7177

param.ndfe_passed=param.ndfe;

7092

param.ndfe_passed=param.ndfe;

7178

old_loops=0;

7093

old_loops=0;

7179

new_loops=0;

7094

new_loops=0;

7180

7095

7181

%GDC Qual construction

7096

%GDC Qual construction

7182

gqual= param.gqual;

7097

gqual= param.gqual;

7183

g2qual=param.g2qual;

7098

g2qual=param.g2qual;

7184

if ~strcmp(param.CTLE_type,'CL120d')

7099

if ~strcmp(param.CTLE_type,'CL120d')

7185

qual=ones(1,length(gdc_values));

7100

qual=ones(1,length(gdc_values));

7186

else

7101

else

7187

if isempty(gqual) && isempty(g2qual)

7102

if isempty(gqual) && isempty(g2qual)

7188

qual=ones(length(g_DC_HP_values),length(gdc_values));

7103

qual=ones(length(g_DC_HP_values),length(gdc_values));

7189

else

7104

else

7190

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7105

qual=zeros(length(g_DC_HP_values),length(gdc_values));

7191

7106

7192

%prepare gqual and g2qual

7107

%prepare gqual and g2qual

7193

[g2qual,si]=sort(g2qual,'descend');

7108

[g2qual,si]=sort(g2qual,'descend');

7194

gqual=gqual(si,:);

7109

gqual=gqual(si,:);

7195

tmp=g2qual;

7110

tmp=g2qual;

7196

g2qual=zeros(length(tmp),2);

7111

g2qual=zeros(length(tmp),2);

7197

for kk=1:length(tmp)

7112

for kk=1:length(tmp)

7198

if kk==1

7113

if kk==1

7199

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7114

g2qual(kk,:)=[tmp(kk)+eps tmp(kk)];

7200

else

7115

else

7201

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7116

g2qual(kk,:)=[tmp(kk-1) tmp(kk)];

7202

end

7117

end

7203

gqual(kk,:)=sort(gqual(kk,:),'descend');

7118

gqual(kk,:)=sort(gqual(kk,:),'descend');

7204

end

7119

end

7205

7120

7206

%Qual Construction

7121

%Qual Construction

7207

for jj=1:length(g_DC_HP_values)

7122

for jj=1:length(g_DC_HP_values)

7208

for ii=1:length(gdc_values)

7123

for ii=1:length(gdc_values)

7209

for kk=1:size(gqual,1)

7124

for kk=1:size(gqual,1)

7210

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7125

if g_DC_HP_values(jj) >= g2qual(kk,2) && g_DC_HP_values(jj) < g2qual(kk,1)

7211

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7126

if gdc_values(ii) >= gqual(kk,2) && gdc_values(ii) < gqual(kk,1)

7212

qual(jj,ii)=1;

7127

qual(jj,ii)=1;

7213

break;

7128

break;

7214

end

7129

end

7215

end

7130

end

7216

end

7131

end

7217

end

7132

end

7218

end

7133

end

7219

end

7134

end

7220

end

7135

end

7221

7136

7222

progress_interval=0.025;

7137

progress_interval=0.025;

7223

if do_C2M

7138

if do_C2M

7224

loop_count=[1 2];

7139

loop_count=[1 2];

7225

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7140

T_O=floor((param.T_O/1000)*param.samples_per_ui);

7226

T_O=max(0,T_O);

7141

T_O=max(0,T_O);

7227

else

7142

else

7228

loop_count=1;

7143

loop_count=1;

7229

T_O=0;

7144

T_O=0;

7230

end

7145

end

7231

switch param.CTLE_type

7146

switch param.CTLE_type

7232

case 'CL93'

7147

case 'CL93'

7233

lf_indx=1;

7148

lf_indx=1;

7234

case 'CL120d'

7149

case 'CL120d'

7235

lf_indx=length(g_DC_HP_values);

7150

lf_indx=length(g_DC_HP_values);

7236

case 'CL120e'

7151

case 'CL120e'

7237

lf_indx=1;

7152

lf_indx=1;

7238

end

7153

end

7239

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7154

runs=length(gdc_values)*lf_indx*length(Gffe_values)*num_txffe_runs;

7240

if OP.Optimize_loop_speed_up == 1

7155

if OP.Optimize_loop_speed_up == 1

7241

OP.BinSize = 1e-4;

7156

OP.BinSize = 1e-4;

7242

OP.impulse_response_truncation_threshold = 1e-3;

7157

OP.impulse_response_truncation_threshold = 1e-3;

7243

end

7158

end

7244

7159

7245

%Used to speed up FFE by only performing circshift when necessary

7160

%Used to speed up FFE by only performing circshift when necessary

7246

pulse_struc(1).pulse_ctle_circshift=[];

7161

pulse_struc(1).pulse_ctle_circshift=[];

7247

ctle_response_updated=1;

7162

ctle_response_updated=1;

7248

7163

7249

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7164

%Used to speed up get_xtlk_noise by pre-calculating all the phase shift exponentials

7250

calc_exp_phase=0;

7165

calc_exp_phase=0;

7251

7166

7252

%calculate cur index and pre/post indices outside of the loop

7167

%calculate cur index and pre/post indices outside of the loop

7253

cur_start=cur;

7168

cur_start=cur;

7254

precursor_indices=[];

7169

precursor_indices=[];

7255

postcursor_indices=[];

7170

postcursor_indices=[];

7256

auto_count_trigger=0;

7171

auto_count_trigger=0;

7257

for kv=1:num_taps

7172

for kv=1:num_taps

7258

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7173

if ~auto_count_trigger && length(txffe_cell{kv})==1 && txffe_cell{kv}==0

7259

%precursor values fill the beginning of the vector. Any empty precursor means

7174

%precursor values fill the beginning of the vector. Any empty precursor means

7260

%cursor position must be subtracted by 1

7175

%cursor position must be subtracted by 1

7261

if kv<cur_start

7176

if kv<cur_start

7262

cur=cur-1;

7177

cur=cur-1;

7263

end

7178

end

7264

else

7179

else

7265

%non empty value: add to precursor or postcursor indices depending on position

7180

%non empty value: add to precursor or postcursor indices depending on position

7266

%in the vector

7181

%in the vector

7267

if kv<cur_start

7182

if kv<cur_start

7268

auto_count_trigger=1;

7183

auto_count_trigger=1;

7269

precursor_indices=[precursor_indices kv];

7184

precursor_indices=[precursor_indices kv];

7270

else

7185

else

7271

auto_count_trigger=0;

7186

auto_count_trigger=0;

7272

postcursor_indices=[postcursor_indices kv];

7187

postcursor_indices=[postcursor_indices kv];

7273

end

7188

end

7274

end

7189

end

7275

end

7190

end

7276

if ~isempty(postcursor_indices)

7191

if ~isempty(postcursor_indices)

7277

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7192

postcursor_indices=postcursor_indices(1):postcursor_indices(end);

7278

end

7193

end

7279

7194

7280

%Calculate the full grid matrix of all txffe combinations

7195

%Calculate the full grid matrix of all txffe combinations

7281

if isempty(txffe_cell)

7196

if isempty(txffe_cell)

7282

TXFFE_grid=0;

7197

TXFFE_grid=0;

7283

FULL_tx_index_vector=1;

7198

FULL_tx_index_vector=1;

7284

else

7199

else

7285

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7200

TXFFE_grid=Full_Grid_Matrix(txffe_cell);

7286

%Also calculate the full grid matrix for the index used in each txffe combination

7201

%Also calculate the full grid matrix for the index used in each txffe combination

7287

%(the index is used in the LOCAL SEARCH block)

7202

%(the index is used in the LOCAL SEARCH block)

7288

for k=1:num_taps

7203

for k=1:num_taps

7289

txffe_index_cell{k}=1:txffe_lengths(k);

7204

txffe_index_cell{k}=1:txffe_lengths(k);

7290

end

7205

end

7291

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7206

FULL_tx_index_vector=Full_Grid_Matrix(txffe_index_cell);

7292

end

7207

end

7293

7208

7294

%pre-calculate cursor to save time

7209

%pre-calculate cursor to save time

7295

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7210

txffe_cursor_vector=1-sum(abs(TXFFE_grid),2);

7296

7211

7297

%pre-calculate full txffe for each iteration to save time

7212

%pre-calculate full txffe for each iteration to save time

7298

precursor_matrix=TXFFE_grid(:,precursor_indices);

7213

precursor_matrix=TXFFE_grid(:,precursor_indices);

7299

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7214

postcursor_matrix=TXFFE_grid(:,postcursor_indices);

7300

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7215

txffe_matrix = [precursor_matrix txffe_cursor_vector postcursor_matrix];

7301

7216

7302

if OP.TDMODE

7217

if OP.TDMODE

7303

uneq_field='uneq_pulse_response';

7218

uneq_field='uneq_pulse_response';

7304

ctle_field='ctle_pulse_response';

7219

ctle_field='ctle_pulse_response';

7305

else

7220

else

7306

uneq_field='uneq_imp_response';

7221

uneq_field='uneq_imp_response';

7307

ctle_field='ctle_imp_response';

7222

ctle_field='ctle_imp_response';

7308

end

7223

end

7309

7224

7310

%Speed up search for max(sbr)

7225

%Speed up search for max(sbr)

7311

if OP.TDMODE

7226

if OP.TDMODE

7312

[~,init_max]=max(chdata(1).uneq_pulse_response);

7227

[~,init_max]=max(chdata(1).uneq_pulse_response);

7313

else

7228

else

7314

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7229

[~,init_max]=max(filter(ones(1,param.samples_per_ui),1,chdata(1).uneq_imp_response));

7315

end

7230

end

7316

UI_max_window=20;

7231

UI_max_window=20;

7317

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7232

start_max_idx=init_max-UI_max_window*param.samples_per_ui;

7318

if start_max_idx<1

7233

if start_max_idx<1

7319

start_max_idx=1;

7234

start_max_idx=1;

7320

end

7235

end

7321

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7236

end_max_idx=init_max+UI_max_window*param.samples_per_ui;

7322

if end_max_idx>length(chdata(1).(uneq_field))

7237

if end_max_idx>length(chdata(1).(uneq_field))

7323

end_max_idx=length(chdata(1).(uneq_field));

7238

end_max_idx=length(chdata(1).(uneq_field));

7324

end

7239

end

7325

7240

7326

itick_skips=0;

7241

itick_skips=0;

7327

itick_cases=0;

7242

itick_cases=0;

7328

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7243

FOM_TRACKER(1:length(Gffe_values),1:length(gdc_values),1:lf_indx,1:size(TXFFE_grid,1),1:length(full_sample_range))=0;

7329

for i=loop_count

7244

for i=loop_count

7330

7245

7331

for Gffe_index=1:length(Gffe_values)

7246

for Gffe_index=1:length(Gffe_values)

7332

param.current_ffegain=Gffe_values(Gffe_index);

7247

param.current_ffegain=Gffe_values(Gffe_index);

7333

for ctle_index=1:length(gdc_values)

7248

for ctle_index=1:length(gdc_values)

7334

g_dc = gdc_values(ctle_index);

7249

g_dc = gdc_values(ctle_index);

7335

kacdc = 10^(g_dc/20);

7250

kacdc = 10^(g_dc/20);

7336

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7251

CTLE_fp1 = param.CTLE_fp1(ctle_index);

7337

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7252

CTLE_fp2 = param.CTLE_fp2(ctle_index);

7338

CTLE_fz = param.CTLE_fz(ctle_index);

7253

CTLE_fz = param.CTLE_fz(ctle_index);

7339

switch param.CTLE_type

7254

switch param.CTLE_type

7340

case 'CL93'

7255

case 'CL93'

7341

%

7256

%

7342

case 'CL120d'

7257

case 'CL120d'

7343

%

7258

%

7344

case 'CL120e'

7259

case 'CL120e'

7345

HP_Z = param.f_HP_Z(ctle_index);

7260

HP_Z = param.f_HP_Z(ctle_index);

7346

HP_P = param.f_HP_P(ctle_index);

7261

HP_P = param.f_HP_P(ctle_index);

7347

end

7262

end

7348

%% HF Boost

7263

%% HF Boost

7349

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7264

ctle_gain = (kacdc + 1i*chdata(1).faxis/CTLE_fz) ./ ...

7350

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7265

((1+1i*chdata(1).faxis/CTLE_fp1).*(1+1i*chdata(1).faxis/CTLE_fp2));

7351

%% Mid Frequency Boost

7266

%% Mid Frequency Boost

7352

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7267

ctle_gain_xc = (kacdc + 1i*f_xc/CTLE_fz) ./ ...

7353

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7268

((1+1i*f_xc/CTLE_fp1).*(1+1i*f_xc/CTLE_fp2)); % Bill Kirkland

7354

for g_LP_index=1:lf_indx

7269

for g_LP_index=1:lf_indx

7355

7270

7356

%GDC Qual Check

7271

%GDC Qual Check

7357

if qual(g_LP_index,ctle_index)==0

7272

if qual(g_LP_index,ctle_index)==0

7358

pxi=pxi+num_txffe_runs;

7273

pxi=pxi+num_txffe_runs;

7359

continue;

7274

continue;

7360

end

7275

end

7361

7276

7362

switch param.CTLE_type

7277

switch param.CTLE_type

7363

case 'CL93'

7278

case 'CL93'

7364

H_low=1;

7279

H_low=1;

7365

kacde_DC_low=1;

7280

kacde_DC_low=1;

7366

case 'CL120d'

7281

case 'CL120d'

7367

g_DC_low = g_DC_HP_values(g_LP_index);

7282

g_DC_low = g_DC_HP_values(g_LP_index);

7368

f_HP=param.f_HP(g_LP_index);

7283

f_HP=param.f_HP(g_LP_index);

7369

kacde_DC_low = 10^(g_DC_low/20);

7284

kacde_DC_low = 10^(g_DC_low/20);

7370

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7285

H_low=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7371

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7286

H_low_xc = (kacde_DC_low + 1i*f_xc/f_HP)./(1 + 1i*f_xc/f_HP);% Bill Kirkland

7372

case 'CL120e' % z1 has been adusted on read in

7287

case 'CL120e' % z1 has been adusted on read in

7373

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7288

H_low=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7374

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7289

H_low_xc=(1 + 1i*f_xc/HP_Z)./(1 + 1i*f_xc/HP_P); % Bill Kirkland

7375

end

7290

end

7376

H_ctf=H_low.*ctle_gain;

7291

H_ctf=H_low.*ctle_gain;

7377

switch upper(OP.FFE_OPT_METHOD)

7292

switch upper(OP.FFE_OPT_METHOD)

7378

case 'WIENER-HOPF'

7293

case 'WIENER-HOPF'

7379

%% Bill Kirkland

7294

%% Bill Kirkland

7380

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7295

H_ctf_xc = H_low_xc.*ctle_gain_xc;

7381

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7296

H_rx_ctle_xc = H_r_xc.*H_ctf_xc;

7382

% use Fourier Transform pair for correlation as we have to

7297

% use Fourier Transform pair for correlation as we have to

7383

% take ifft of H_r anyways.

7298

% take ifft of H_r anyways.

7384

% onesided and two sided responses - tricky, tricky, tricky

7299

% onesided and two sided responses - tricky, tricky, tricky

7385

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7300

Var_eta0 = param.eta_0*f_xc(end)/1e9;

7386

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7301

XC_rx_ctle = ifft (H_rx_ctle_xc.*conj(H_rx_ctle_xc),2*length(H_rx_ctle_xc),'symmetric');

7387

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7302

Noise_XC = Var_eta0.*XC_rx_ctle(1:param.samples_per_ui:N_fft_by2);

7388

7303

7389

if OP.Do_White_Noise

7304

if OP.Do_White_Noise

7390

Noise_XC = Noise_XC(1);

7305

Noise_XC = Noise_XC(1);

7391

end

7306

end

7392

otherwise

7307

otherwise

7393

Noise_XC=[];

7308

Noise_XC=[];

7394

end

7309

end

7395

7310

7396

7311

7397

7312

7398

if OP.INCLUDE_CTLE==1

7313

if OP.INCLUDE_CTLE==1

7399

for k=1:param.num_s4p_files

7314

for k=1:param.num_s4p_files

7400

ir_peak = max(abs(chdata(k).(uneq_field)));

7315

ir_peak = max(abs(chdata(k).(uneq_field)));

7401

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7316

ir_last = find(abs(chdata(k).(uneq_field))>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

7402

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7317

chdata(k).(uneq_field) = chdata(k).(uneq_field)(1:ir_last);

7403

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7318

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(uneq_field), baud_rate ...

7404

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7319

, CTLE_fz, CTLE_fp1, CTLE_fp2, g_dc, param.samples_per_ui);

7405

switch param.CTLE_type

7320

switch param.CTLE_type

7406

case 'CL93'

7321

case 'CL93'

7407

case 'CL120d'

7322

case 'CL120d'

7408

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7323

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, f_HP, f_HP,100e100 , g_DC_low , param.samples_per_ui);

7409

case 'CL120e' % z1 has been adusted on read in

7324

case 'CL120e' % z1 has been adusted on read in

7410

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7325

chdata(k).(ctle_field) = TD_CTLE(chdata(k).(ctle_field), baud_rate, HP_Z,HP_P,100e100 , 0 , param.samples_per_ui);

7411

end

7326

end

7412

end

7327

end

7413

%set the flag to show ctle response was updated

7328

%set the flag to show ctle response was updated

7414

ctle_response_updated=1;

7329

ctle_response_updated=1;

7415

else

7330

else

7416

for k=1:param.num_s4p_files

7331

for k=1:param.num_s4p_files

7417

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7332

chdata(k).(ctle_field) = chdata(k).(uneq_field);

7418

end

7333

end

7419

end

7334

end

7420

for k=1:param.num_s4p_files

7335

for k=1:param.num_s4p_files

7421

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7336

chdata(k).sdd21ctf=chdata(k).sdd21.*H_ctf; % sdd21 is a VTF, includes H_t, H_f, and package

7422

end

7337

end

7423

%% Equation 93A-22 %%

7338

%% Equation 93A-22 %%

7424

% figure(1000)

7339

% figure(1000)

7425

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7340

% semilogx(chdata(1).faxis/1e9,db(H_ctf))

7426

% hold on

7341

% hold on

7427

if OP.RX_CALIBRATION

7342

if OP.RX_CALIBRATION

7428

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7343

ctle_gain2 = (kacdc + 1i*chdata(2).faxis/CTLE_fz) ./ ...

7429

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7344

((1+1i*chdata(2).faxis/CTLE_fp1).*(1+1i*chdata(2).faxis/CTLE_fp2));

7430

switch param.CTLE_type

7345

switch param.CTLE_type

7431

case 'CL93'

7346

case 'CL93'

7432

H_low2=1;

7347

H_low2=1;

7433

case 'CL120d'

7348

case 'CL120d'

7434

g_DC_low = g_DC_HP_values(g_LP_index);

7349

g_DC_low = g_DC_HP_values(g_LP_index);

7435

f_HP=param.f_HP(g_LP_index);

7350

f_HP=param.f_HP(g_LP_index);

7436

kacde_DC_low = 10^(g_DC_low/20);

7351

kacde_DC_low = 10^(g_DC_low/20);

7437

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7352

H_low2=(kacde_DC_low + 1i*chdata(1).faxis/f_HP)./(1 + 1i*chdata(1).faxis/f_HP);

7438

case 'CL120e' % z1 has been adusted on read in

7353

case 'CL120e' % z1 has been adusted on read in

7439

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7354

H_low2=(1 + 1i*chdata(1).faxis/HP_Z)./(1 + 1i*chdata(1).faxis/HP_P);

7440

end

7355

end

7441

H_ctf2=H_low2.*ctle_gain2;

7356

H_ctf2=H_low2.*ctle_gain2;

7442

end

7357

end

7443

% RIM 11-30-2020 moved to a subfunction

7358

% RIM 11-30-2020 moved to a subfunction

7444

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7359

[sigma_N] = get_sigma_eta_ACCM_noise(chdata,param,H_sy,H_r,H_ctf);

7445

if OP.RX_CALIBRATION

7360

if OP.RX_CALIBRATION

7446

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7361

sigma_ne = get_sigma_noise( H_ctf2, param, chdata, sigma_bn); %% Equation 93A-48 %%

7447

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7362

sigma_NEXT=sqrt(param.eta_0*sum( abs(H_sy(2:end).^2 .* H_r(2:end).*2 .* H_ctf(2:end).^2 ) .* diff(chdata(1).faxis)/1e9));% changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7448

else

7363

else

7449

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7364

%% Equations 93A-33 and 93A-34 for NEXT - independent of TXFFE setting %%

7450

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7365

% sigma_NEXT not used sigma_ne is one used in Rx calibration RIM 03-28-2024

7451

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7366

% sigma_NEXT = get_xtlk_noise( [0 1 0], 'NEXT', param, chdata );

7452

sigma_ne=0;

7367

sigma_ne=0;

7453

end

7368

end

7454

7369

7455

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7370

if param.GDC_MIN ~= 0 && gdc_values(ctle_index) + g_DC_HP_values(g_LP_index) > param.GDC_MIN

7456

pxi=pxi+num_txffe_runs;

7371

pxi=pxi+num_txffe_runs;

7457

continue; % change per 0.3k draft 2.3

7372

continue; % change per 0.3k draft 2.3

7458

end

7373

end

7459

%%

7374

%%

7460

PSD_results=[];

7375

PSD_results=[];

7461

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7376

if strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE

7462

OP.WO_TXFFE=1;

7377

OP.WO_TXFFE=1;

7463

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7378

PSD_results=get_PSDs(PSD_results,[],[],[],gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7464

end

7379

end

7465

%TXFFE Loop

7380

%TXFFE Loop

7466

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7381

%Originally this was a separate for loop for each tap, but it is now all contained in the TXFFE_grid matrix to use a single modular loop

7467

for TK=1:size(TXFFE_grid,1)

7382

for TK=1:size(TXFFE_grid,1)

7468

7383

7469

pxi=pxi+1;

7384

pxi=pxi+1;

7470

progress = pxi/runs;

7385

progress = pxi/runs;

7471

if OP.DISPLAY_WINDOW

7386

if OP.DISPLAY_WINDOW

7472

if ~mod(pxi,floor(runs*progress_interval))

7387

if ~mod(pxi,floor(runs*progress_interval))

7473

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7388

waitbar(progress, hwaitbar, 'Linear equalization tuning'); figure(hwaitbar); drawnow;

7474

end

7389

end

7475

else

7390

else

7476

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7391

if ~mod(pxi,floor(runs*progress_interval)), fprintf('%i%% ', round(progress*100) );end

7477

end

7392

end

7478

7393

7479

%get the cursor for this iteration

7394

%get the cursor for this iteration

7480

txffe_cur=txffe_cursor_vector(TK);

7395

txffe_cur=txffe_cursor_vector(TK);

7481

7396

7482

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7397

% Skip combinations with small values of c(0), not guaranteed to be supported by all transmitters.

7483

if txffe_cur<param.tx_ffe_c0_min

7398

if txffe_cur<param.tx_ffe_c0_min

7484

continue;

7399

continue;

7485

end

7400

end

7486

old_loops=old_loops+1;

7401

old_loops=old_loops+1;

7487

7402

7488

%get the index used for each tap on this iteration

7403

%get the index used for each tap on this iteration

7489

%this is needed for the LOCAL SEARCH block

7404

%this is needed for the LOCAL SEARCH block

7490

tx_index_vector=FULL_tx_index_vector(TK,:);

7405

tx_index_vector=FULL_tx_index_vector(TK,:);

7491

7406

7492

%Original LOCAL SEARCH Block:

7407

%Original LOCAL SEARCH Block:

7493

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7408

%Keeping this one as commented code because it is a bit more readable than the Modular Block below

7494

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7409

%But unlike the Modular Block, this one does not work if additional TXFFE taps are added

7495

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7410

% % speedup "local search" heuristic - Adee Ran 03-17-2020

7496

% % skip configurations more than

7411

% % skip configurations more than

7497

% % 2 steps away from current "best" point on any grid direction

7412

% % 2 steps away from current "best" point on any grid direction

7498

% % Matt Brown 11/19/2021 for cp2 and cp3

7413

% % Matt Brown 11/19/2021 for cp2 and cp3

7499

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7414

% if param.LOCAL_SEARCH>0 && ~isinf(best_FOM) && ...

7500

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7415

% ((k_cp2>1 && length(cp3_values)>1 && abs(k_cp3-find(cp3_values==best_txffe(cur+3)))>param.LOCAL_SEARCH) ...

7501

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7416

% || (k_cp1>1 && length(cp2_values)>1 && abs(k_cp2-find(cp2_values==best_txffe(cur+2)))>param.LOCAL_SEARCH) ...

7502

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7417

% || (k_cm1>1 && length(cp1_values)>1 && abs(k_cp1-find(cp1_values==best_txffe(cur+1)))>param.LOCAL_SEARCH) ...

7503

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7418

% || (k_cm2>1 && length(cm1_values)>1 && abs(k_cm1-find(cm1_values==best_txffe(cur-1)))>param.LOCAL_SEARCH) ...

7504

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7419

% || (k_cm3>1 && length(cm2_values)>1 && abs(k_cm2-find(cm2_values==best_txffe(cur-2)))>param.LOCAL_SEARCH) ...

7505

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7420

% || (k_cm4>1 && length(cm3_values)>1 && abs(k_cm3-find(cm3_values==best_txffe(cur-3)))>param.LOCAL_SEARCH) ...

7506

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7421

% || (g_LP_index>1 && length(cm4_values)>1 && abs(k_cm4-find(cm4_values==best_txffe(cur-4)))>param.LOCAL_SEARCH) ...

7507

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7422

% || (ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH))

7508

%

7423

%

7509

% continue;

7424

% continue;

7510

% end

7425

% end

7511

7426

7512

%Modular LOCAL_SEARCH block:

7427

%Modular LOCAL_SEARCH block:

7513

% speedup "local search" heuristic - Adee Ran 03-17-2020

7428

% speedup "local search" heuristic - Adee Ran 03-17-2020

7514

% skip configurations more than 2 steps away from current "best" point on any grid direction

7429

% skip configurations more than 2 steps away from current "best" point on any grid direction

7515

skip_it=0;

7430

skip_it=0;

7516

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7431

if param.LOCAL_SEARCH>0 && ~isinf(best_FOM)

7517

%instead of looping across all taps, only loop across

7432

%instead of looping across all taps, only loop across

7518

%those with length>1 (txffe_sweep_indices).

7433

%those with length>1 (txffe_sweep_indices).

7519

%It saves time since this block is encountered so often

7434

%It saves time since this block is encountered so often

7520

for kj=1:num_txffe_sweep_indices

7435

for kj=1:num_txffe_sweep_indices

7521

kv=txffe_sweep_indices(kj);

7436

kv=txffe_sweep_indices(kj);

7522

if kv==1

7437

if kv==1

7523

previous_loop_val=g_LP_index;

7438

previous_loop_val=g_LP_index;

7524

else

7439

else

7525

previous_loop_val=tx_index_vector(kv-1);

7440

previous_loop_val=tx_index_vector(kv-1);

7526

end

7441

end

7527

if previous_loop_val>1

7442

if previous_loop_val>1

7528

best_index_this_tap=best_txffe_index(kv);

7443

best_index_this_tap=best_txffe_index(kv);

7529

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7444

if abs(tx_index_vector(kv)-best_index_this_tap)>param.LOCAL_SEARCH

7530

skip_it=1;

7445

skip_it=1;

7531

break;

7446

break;

7532

end

7447

end

7533

end

7448

end

7534

end

7449

end

7535

7450

7536

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7451

if ~skip_it && ctle_index>1 && abs(g_LP_index-best_G_high_pass)>param.LOCAL_SEARCH

7537

skip_it=1;

7452

skip_it=1;

7538

end

7453

end

7539

end

7454

end

7540

if skip_it

7455

if skip_it

7541

continue;

7456

continue;

7542

end

7457

end

7543

%End Modular LOCAL SEARCH block

7458

%End Modular LOCAL SEARCH block

7544

7459

7545

new_loops=new_loops+1;

7460

new_loops=new_loops+1;

7546

7461

7547

%fetch txffe for this iteration

7462

%fetch txffe for this iteration

7548

txffe=txffe_matrix(TK,:);

7463

txffe=txffe_matrix(TK,:);

7549

7464

7550

%The phase shift exponentials used in get_xtlk_noise are independent of

7465

%The phase shift exponentials used in get_xtlk_noise are independent of

7551

%everything except number of taps and cursor position

7466

%everything except number of taps and cursor position

7552

%So it can be calculated 1 time here to avoid thousands of re-calcs

7467

%So it can be calculated 1 time here to avoid thousands of re-calcs

7553

if ~calc_exp_phase

7468

if ~calc_exp_phase

7554

calc_exp_phase=1;

7469

calc_exp_phase=1;

7555

for k=1:length(txffe)

7470

for k=1:length(txffe)

7556

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7471

phase_memory(:,k)=exp(-1j*2*pi*(k-cur).*f/param.fb);

7557

end

7472

end

7558

if OP.RxFFE

7473

if OP.RxFFE

7559

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7474

for k=-1*param.RxFFE_cmx:param.RxFFE_cpx

7560

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7475

phase_memoryRXFFE(:,k+param.RxFFE_cmx+1)=exp(-1j*2*pi*(k+1).*f/param.fb);

7561

end

7476

end

7562

phase_memory=[phase_memory phase_memoryRXFFE];

7477

phase_memory=[phase_memory phase_memoryRXFFE];

7563

end

7478

end

7564

end

7479

end

7565

7480

7566

%% Unequalized Pulse Reponse & circshift for FFE

7481

%% Unequalized Pulse Reponse & circshift for FFE

7567

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7482

%Perform circshift for FFE only when CTLE is updated. The FFE_Fast function takes

7568

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7483

%in the pre-shifted matrix. FFE fast is scaled sum of rows of pulse_struc(ii).pulse_ctle_circshift

7569

if ctle_response_updated

7484

if ctle_response_updated

7570

ctle_response_updated=0;

7485

ctle_response_updated=0;

7571

num_pre=cur-1;

7486

num_pre=cur-1;

7572

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7487

%Another speed up: the unequalized pulse is also only unique for each CTLE update

7573

%Calculating here reduces number of convolutions by thousands

7488

%Calculating here reduces number of convolutions by thousands

7574

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7489

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7575

ich=1;

7490

ich=1;

7576

else

7491

else

7577

ich=param.num_s4p_files;

7492

ich=param.num_s4p_files;

7578

end

7493

end

7579

for ii=1:ich

7494

for ii=1:ich

7580

if OP.TDMODE

7495

if OP.TDMODE

7581

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7496

pulse_struc(ii).pulse_ctle=chdata(ii).(ctle_field)(:);

7582

else

7497

else

7583

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7498

%uneq_pulse=filter(ones(param.samples_per_ui, 1), 1, chdata(1).(ctle_field)(:));

7584

%"conv2" is faster than filter. Just need to chop off extra points at the end

7499

%"conv2" is faster than filter. Just need to chop off extra points at the end

7585

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7500

pulse_struc(ii).pulse_ctle=conv2(chdata(ii).(ctle_field)(:),ones(param.samples_per_ui, 1));

7586

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7501

pulse_struc(ii).pulse_ctle=pulse_struc(ii).pulse_ctle(1:end-param.samples_per_ui+1);

7587

end

7502

end

7588

for k=1:length(txffe)

7503

for k=1:length(txffe)

7589

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7504

pulse_struc(ii).pulse_ctle_circshift(:,k)=circshift(pulse_struc(ii).pulse_ctle,[(k-1-num_pre)*param.samples_per_ui 0]);

7590

end

7505

end

7591

end

7506

end

7592

end

7507

end

7593

7508

7594

%% Apply TXFFE to pre-shifted pulse response

7509

%% Apply TXFFE to pre-shifted pulse response

7595

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7510

%[sbr] = FFE( txffe, cur-1, param.samples_per_ui, uneq_pulse);

7596

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7511

sbr=FFE_Fast(txffe,pulse_struc(1).pulse_ctle_circshift);

7597

sbr_from_txffe=sbr;

7512

sbr_from_txffe=sbr;

7598

for ii=1:ich

7513

for ii=1:ich

7599

% this is sbr when ii=1; to be used in get_PSDs

7514

% this is sbr when ii=1; to be used in get_PSDs

7600

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7515

if isequal(chdata(ii).type, 'FEXT') || isequal(chdata(ii).type, 'THRU')

7601

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7516

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=FFE_Fast(txffe,pulse_struc(ii).pulse_ctle_circshift);

7602

else

7517

else

7603

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7518

chdata(ii).pulse_response_w_CFT_TXFFE_noRxFFE=pulse_struc(ii).pulse_ctle; % don't apply TxFFE for NEXT

7604

end

7519

end

7605

end

7520

end

7606

7521

7607

%% Find Sample Location

7522

%% Find Sample Location

7608

% If RXFFE is included, the sample location will be found again below

7523

% If RXFFE is included, the sample location will be found again below

7609

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7524

[cursor_i,no_zero_crossing,sbr_peak_i,zxi]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7610

if param.ts_anchor==0

7525

if param.ts_anchor==0

7611

%keep MM

7526

%keep MM

7612

elseif param.ts_anchor==1

7527

elseif param.ts_anchor==1

7613

%peak sample

7528

%peak sample

7614

cursor_i=sbr_peak_i;

7529

cursor_i=sbr_peak_i;

7615

no_zero_crossing=0;

7530

no_zero_crossing=0;

7616

elseif param.ts_anchor==2

7531

elseif param.ts_anchor==2

7617

%max DV

7532

%max DV

7618

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7533

possible_cursor=sbr(sbr_peak_i-param.samples_per_ui:sbr_peak_i+param.samples_per_ui);

7619

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7534

possible_precursor=sbr(sbr_peak_i-2*param.samples_per_ui:sbr_peak_i);

7620

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7535

[max_diff,d_idx]=max(possible_cursor-possible_precursor);

7621

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7536

cursor_i=sbr_peak_i-param.samples_per_ui+d_idx-1;

7622

no_zero_crossing=0;

7537

no_zero_crossing=0;

7623

else

7538

else

7624

error('ts_anchor parameter must be 0, 1, or 2');

7539

error('ts_anchor parameter must be 0, 1, or 2');

7625

end

7540

end

7626

if no_zero_crossing

7541

if no_zero_crossing

7627

continue;

7542

continue;

7628

end

7543

end

7629

raw_cursor_i=cursor_i;

7544

raw_cursor_i=cursor_i;

7630

7545

7631

%%%%%%%%%%

7546

%%%%%%%%%%

7632

%%%%%%%%%%

7547

%%%%%%%%%%

7633

%%%%%%%%%%

7548

%%%%%%%%%%

7634

%NEW ITICK LOOP (not indenting everything yet)

7549

%NEW ITICK LOOP (not indenting everything yet)

7635

[~,si]=sort(abs(full_sample_range));

7550

[~,si]=sort(abs(full_sample_range));

7636

best_positive_itick_FOM=-inf;

7551

best_positive_itick_FOM=-inf;

7637

best_negative_itick_FOM=-inf;

7552

best_negative_itick_FOM=-inf;

7638

best_positive_itick_in_loop=[];

7553

best_positive_itick_in_loop=[];

7639

best_negative_itick_in_loop=[];

7554

best_negative_itick_in_loop=[];

7640

best_itick_FOM=-inf;

7555

best_itick_FOM=-inf;

7641

best_itick_in_cluster=[];

7556

best_itick_in_cluster=[];

7642

best_cluster=[];

7557

best_cluster=[];

7643

7558

7644

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7559

%box_search: take the middle of 5 point windows, then use the best of those to search the rest of that window

7645

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7560

%middle_search: start from itick=0 and work outwards in negative and positive direction. stop searching when FOM starts to go down (using LOCAL SEARCH)

7646

% Commit request4p4_7 healey_3dj_COM_01_240416

7561

% Commit request4p4_7 healey_3dj_COM_01_240416

7647

%box_search=0;

7562

%box_search=0;

7648

%middle_search=1;% should set 0 so all Ts sample points are used

7563

%middle_search=1;% should set 0 so all Ts sample points are used

7649

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7564

switch lower(OP.TS_SRCH_MODE) % Commit request4p4_7 healey_3dj_COM_01_240416

7650

case 'full-sweep'

7565

case 'full-sweep'

7651

box_search=0;

7566

box_search=0;

7652

middle_search=0;

7567

middle_search=0;

7653

case 'middle'

7568

case 'middle'

7654

box_search=0;

7569

box_search=0;

7655

middle_search=1;

7570

middle_search=1;

7656

otherwise

7571

otherwise

7657

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7572

error('unsuported TS_SRCH_MODE (%s)!',OP.TS_SRCH_MODE);

7658

end

7573

end

7659

if box_search

7574

if box_search

7660

box_size=5;

7575

box_size=5;

7661

box_mid=floor(box_size/2);

7576

box_mid=floor(box_size/2);

7662

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7577

cluster=full_sample_range(1)+box_mid:box_size:full_sample_range(end);

7663

CL=length(cluster);

7578

CL=length(cluster);

7664

loop_range=1:CL+box_mid*2;

7579

loop_range=1:CL+box_mid*2;

7665

elseif middle_search

7580

elseif middle_search

7666

loop_range=si;

7581

loop_range=si;

7667

else

7582

else

7668

loop_range=1:length(full_sample_range);

7583

loop_range=1:length(full_sample_range);

7669

end

7584

end

7670

7585

7671

for itickn=loop_range

7586

for itickn=loop_range

7672

if box_search

7587

if box_search

7673

if itickn<=CL

7588

if itickn<=CL

7674

itick=cluster(itickn);

7589

itick=cluster(itickn);

7675

else

7590

else

7676

if itickn==CL+1

7591

if itickn==CL+1

7677

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7592

best_cluster=setdiff([best_itick_in_cluster-box_mid:best_itick_in_cluster+box_mid],best_itick_in_cluster);

7678

end

7593

end

7679

if isempty(best_cluster)

7594

if isempty(best_cluster)

7680

continue;

7595

continue;

7681

end

7596

end

7682

itick=best_cluster(itickn-CL);

7597

itick=best_cluster(itickn-CL);

7683

end

7598

end

7684

else

7599

else

7685

itick=full_sample_range(itickn);

7600

itick=full_sample_range(itickn);

7686

end

7601

end

7687

7602

7688

itick_cases=itick_cases+1;

7603

itick_cases=itick_cases+1;

7689

7604

7690

sbr=sbr_from_txffe;

7605

sbr=sbr_from_txffe;

7691

cursor_i = raw_cursor_i+itick;

7606

cursor_i = raw_cursor_i+itick;

7692

7607

7693

%Local Search for +/- itick sweep

7608

%Local Search for +/- itick sweep

7694

if middle_search && param.LOCAL_SEARCH>0

7609

if middle_search && param.LOCAL_SEARCH>0

7695

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7610

if itick>=0 && ~isinf(best_positive_itick_FOM) && abs(best_positive_itick_in_loop-itick)>=param.LOCAL_SEARCH

7696

itick_skips=itick_skips+1;

7611

itick_skips=itick_skips+1;

7697

continue;

7612

continue;

7698

end

7613

end

7699

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7614

if itick<=0 && ~isinf(best_negative_itick_FOM) && abs(best_negative_itick_in_loop-itick)>=param.LOCAL_SEARCH

7700

itick_skips=itick_skips+1;

7615

itick_skips=itick_skips+1;

7701

continue;

7616

continue;

7702

end

7617

end

7703

end

7618

end

7704

7619

7705

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7620

triple_transit_time = round(sbr_peak_i*2/param.samples_per_ui)+20;

7706

if min_number_of_UI_in_response < triple_transit_time

7621

if min_number_of_UI_in_response < triple_transit_time

7707

min_number_of_UI_in_response = triple_transit_time;

7622

min_number_of_UI_in_response = triple_transit_time;

7708

end

7623

end

7709

7624

7710

cursor = sbr(cursor_i);

7625

cursor = sbr(cursor_i);

7711

7626

7712

%% RXFFE

7627

%% RXFFE

7713

if OP.RxFFE

7628

if OP.RxFFE

7714

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7629

% [ sbr, C]=force(sbr,param,OP,cursor_i);

7715

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7630

%[ sbr, C]=force(sbr,param,OP,zxi+param.samples_per_ui);

7716

%if isrow(sbr), sbr=sbr';end

7631

%if isrow(sbr), sbr=sbr';end

7717

7632

7718

%AJG: do not return sbr here (run time improvement)

7633

%AJG: do not return sbr here (run time improvement)

7719

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7634

%UPDATE: use cursor_i in RXFFE instead of zero crossing + 1 UI

7720

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7635

%[ ~, C]=force(sbr,param,OP,zxi+param.samples_per_ui,[],0);

7721

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7636

% [ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0);

7722

% sbr at this point include the current setting

7637

% sbr at this point include the current setting

7723

% under consideration of txffe h21 ctf and fr

7638

% under consideration of txffe h21 ctf and fr

7724

switch upper(OP.FFE_OPT_METHOD)

7639

switch upper(OP.FFE_OPT_METHOD)

7725

case 'MMSE'

7640

case 'MMSE'

7726

OP.WO_TXFFE=0;

7641

OP.WO_TXFFE=0;

7727

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7642

PSD_results=get_PSDs(PSD_results,sbr,cursor_i,txffe,gdc_values(ctle_index),g_DC_low,param,chdata,OP);

7728

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7643

S_n=PSD_results.S_rn+PSD_results.S_tn+PSD_results.S_xn+PSD_results.S_jn;

7729

if 0 % for debug

7644

if 0 % for debug

7730

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7645

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_rn*1000/100) ,'disp','Srn')

7731

hold on

7646

hold on

7732

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7647

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_xn*1000/100) ,'disp','Sxn')

7733

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7648

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_tn*1000/100) ,'disp','Stn')

7734

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7649

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_jn*1000/100) ,'disp','Sjn')

7735

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7650

plot(PSD_results.fvec(1:param.num_ui_RXFF_noise)/param.fb,10*log10(PSD_results.S_n*1000/100) ,'disp','Sn')

7736

xlim([0 0.5])

7651

xlim([0 0.5])

7737

% ylim([-190 -160])

7652

% ylim([-190 -160])

7738

set(gcf,'defaulttextinterpreter','none')

7653

set(gcf,'defaulttextinterpreter','none')

7739

xlabel('Normalized Frequency')

7654

xlabel('Normalized Frequency')

7740

ylabel('PSD dBm/Hz')

7655

ylabel('PSD dBm/Hz')

7741

hold on

7656

hold on

7742

grid on

7657

grid on

7743

legend show

7658

legend show

7744

title('PSD')

7659

title('PSD')

7745

end

7660

end

7746

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7661

MMSE_results = MMSE(PSD_results,sbr,cursor_i, param, OP ) ;

7747

% floating_tap_locations=MMSE_results.MLSE_results;

7662

% floating_tap_locations=MMSE_results.MLSE_results;

7748

C=MMSE_results.C;

7663

C=MMSE_results.C;

7749

FOM=MMSE_results.FOM;

7664

FOM=MMSE_results.FOM;

7750

floating_tap_locations=MMSE_results.floating_tap_locations;

7665

floating_tap_locations=MMSE_results.floating_tap_locations;

7751

otherwise

7666

otherwise

7752

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7667

[ ~, C, floating_tap_locations]=force(sbr,param,OP,cursor_i,[],0, chdata, txffe, Noise_XC);

7753

end

7668

end

7754

%Now there is a stand alone function for determining if RXFFE taps are illegal

7669

%Now there is a stand alone function for determining if RXFFE taps are illegal

7755

%This is because the "force" function will also do a legality check when "backoff" is enabled

7670

%This is because the "force" function will also do a legality check when "backoff" is enabled

7756

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7671

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7757

if RXFFE_Illegal(C,param)

7672

if RXFFE_Illegal(C,param)

7758

continue;

7673

continue;

7759

end

7674

end

7760

end

7675

end

7761

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7676

%AJG: speed up: calculate sbr after checks for illegal taps (many tap combinations are illegal and "FFE" is time consuming)

7762

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7677

sbr=FFE(C,param.RxFFE_cmx,param.samples_per_ui,sbr);

7763

if isrow(sbr), sbr=sbr';end

7678

if isrow(sbr), sbr=sbr';end

7764

7679

7765

%% second guess at cursor location (t_s) - based on approximate zero crossing

7680

%% second guess at cursor location (t_s) - based on approximate zero crossing

7766

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7681

%This entire block is now inside the "if OP.RxFFE" to avoid unnecessary re-calculation

7767

%UPDATE: NOT RESAMPLING AFTER RXFFE

7682

%UPDATE: NOT RESAMPLING AFTER RXFFE

7768

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7683

% [cursor_i,no_zero_crossing,sbr_peak_i]=cursor_sample_index(sbr,param,OP,start_max_idx:end_max_idx);

7769

% if no_zero_crossing

7684

% if no_zero_crossing

7770

% continue;

7685

% continue;

7771

% end

7686

% end

7772

7687

7773

cursor = sbr(cursor_i);

7688

cursor = sbr(cursor_i);

7774

end

7689

end

7775

A_p=sbr(sbr_peak_i);

7690

A_p=sbr(sbr_peak_i);

7776

%% 93A.1.6 step c defines A_s %%

7691

%% 93A.1.6 step c defines A_s %%

7777

A_s = param.R_LM*cursor/(param.levels-1);

7692

A_s = param.R_LM*cursor/(param.levels-1);

7778

if isempty(delta_sbr)

7693

if isempty(delta_sbr)

7779

delta_sbr = sbr;

7694

delta_sbr = sbr;

7780

end

7695

end

7781

sbr=sbr(:);

7696

sbr=sbr(:);

7782

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7697

%% Equation 93A-27 "otherwise" case %% param.N_bmax is param.ndfe if groups are not used

7783

7698

7784

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7699

if(param.Floating_DFE), param.ndfe=param.N_bmax; end

7785

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7700

far_cursors = sbr(cursor_i-T_O+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:end);

7786

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7701

t=((cursor_i+param.samples_per_ui*(param.ndfe+1):param.samples_per_ui:length(sbr))-(cursor_i+param.samples_per_ui*(param.ndfe+1)))*...

7787

param.ui/param.samples_per_ui;

7702

param.ui/param.samples_per_ui;

7788

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7703

precursors = sbr(cursor_i-param.samples_per_ui:-param.samples_per_ui:1);

7789

precursors = precursors(end:-1:1);

7704

precursors = precursors(end:-1:1);

7790

7705

7791

% % Error message if the sbr is not long enough for the specified range of Nb

7706

% % Error message if the sbr is not long enough for the specified range of Nb

7792

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7707

% if length(sbr) < cursor_i+param.samples_per_ui*(param.ndfe+1)

7793

% close(hwaitbar);

7708

% close(hwaitbar);

7794

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7709

% error('Pulse Response contains %d samples after the cursor. Specified Nb requires %d samples after the cursor.' ...

7795

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7710

% , length(sbr)-cursor_i, param.samples_per_ui*(param.ndfe+1));

7796

% end

7711

% end

7797

7712

7798

7713

7799

7714

7800

%% skip this case if FOM has no chance of beating old FOM

7715

%% skip this case if FOM has no chance of beating old FOM

7801

%this is also done below but with excess_dfe_cursors included.

7716

%this is also done below but with excess_dfe_cursors included.

7802

%excess_dfe_cursors requires the floating DFE computation which is

7717

%excess_dfe_cursors requires the floating DFE computation which is

7803

%time consuming, so checking here can have significant run time improvements

7718

%time consuming, so checking here can have significant run time improvements

7804

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7719

sigma_ISI_ignoreDFE = param.sigma_X*norm([precursors; far_cursors]);

7805

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7720

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7806

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7721

if (20*log10(A_s/sigma_ISI_ignoreDFE) < best_FOM)

7807

continue

7722

continue

7808

end

7723

end

7809

end

7724

end

7810

7725

7811

%% Equation 93A-27, when 1<=n<=N_b

7726

%% Equation 93A-27, when 1<=n<=N_b

7812

%required length = cursor + all DFE UI + 1 additional UI

7727

%required length = cursor + all DFE UI + 1 additional UI

7813

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7728

sbr_required_length=cursor_i+param.samples_per_ui*(param.ndfe+1);

7814

if length(sbr)<sbr_required_length

7729

if length(sbr)<sbr_required_length

7815

sbr(end+1:sbr_required_length)=0;

7730

sbr(end+1:sbr_required_length)=0;

7816

end

7731

end

7817

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7732

dfecursors=sbr(cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe));

7818

if param.dfe_delta ~= 0

7733

if param.dfe_delta ~= 0

7819

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7734

dfecursors_q=floor(abs(dfecursors/sbr(cursor_i))./param.dfe_delta).*param.dfe_delta.*sign(dfecursors)*sbr(cursor_i);

7820

7735

7821

else

7736

else

7822

dfecursors_q=dfecursors;

7737

dfecursors_q=dfecursors;

7823

end

7738

end

7824

if param.Floating_DFE

7739

if param.Floating_DFE

7825

%% floating taps

7740

%% floating taps

7826

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7741

postcurors= sbr(cursor_i+param.samples_per_ui:param.samples_per_ui:end);

7827

7742

7828

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7743

[floating_tap_locations, floating_tap_coef, hisi, bmax]= floatingDFE( postcurors ,param.ndfe_passed,param.N_bf,param.N_bg,param.N_bmax, param.bmaxg, sbr(cursor_i), param.dfe_delta );

7829

7744

7830

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7745

newbmax= [ param.bmax bmax(param.ndfe_passed+1:param.N_bmax)].';

7831

param.use_bmax=newbmax;

7746

param.use_bmax=newbmax;

7832

%AJG021820

7747

%AJG021820

7833

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7748

param.use_bmin=[param.bmin bmax(param.ndfe_passed+1:param.N_bmax)*-1].';

7834

else

7749

else

7835

param.use_bmax=param.bmax;

7750

param.use_bmax=param.bmax;

7836

%AJG021820

7751

%AJG021820

7837

param.use_bmin=param.bmin;

7752

param.use_bmin=param.bmin;

7838

end

7753

end

7839

7754

7840

%AJG021820

7755

%AJG021820

7841

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7756

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7842

if do_C2M

7757

if do_C2M

7843

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7758

dfecursors_windowed=sbr(cursor_i-T_O+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe)-T_O);

7844

% readjust SBR

7759

% readjust SBR

7845

if 0

7760

if 0

7846

%PR_DFE_center not currently used, so this is in "if 0" statement

7761

%PR_DFE_center not currently used, so this is in "if 0" statement

7847

PR_DFE_center=sbr;

7762

PR_DFE_center=sbr;

7848

for n=1:param.ndfe

7763

for n=1:param.ndfe

7849

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7764

% for ix=-param.samples_per_ui/2: param.samples_per_ui/2

7850

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7765

% i_sample=ix+n*param.samples_per_ui+cursor_i;

7851

% dper=sbr(i_sample)- actual_dfecursors(n);

7766

% dper=sbr(i_sample)- actual_dfecursors(n);

7852

% PR_DFE_center(i_sample)=dper;

7767

% PR_DFE_center(i_sample)=dper;

7853

% end

7768

% end

7854

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7769

i_sample=(-param.samples_per_ui/2: param.samples_per_ui/2)+n*param.samples_per_ui+cursor_i;

7855

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7770

PR_DFE_center(i_sample)=sbr(i_sample)-actual_dfecursors(n);

7856

end

7771

end

7857

end

7772

end

7858

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7773

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7859

else

7774

else

7860

excess_dfe_cursors=dfecursors-actual_dfecursors;

7775

excess_dfe_cursors=dfecursors-actual_dfecursors;

7861

end

7776

end

7862

dfetaps=actual_dfecursors/sbr(cursor_i);

7777

dfetaps=actual_dfecursors/sbr(cursor_i);

7863

7778

7864

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7779

if length(dfetaps) >= param.N_tail_start && param.N_tail_start ~=0

7865

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7780

tail_RSS=norm(dfetaps(param.N_tail_start:end));

7866

if tail_RSS ~= 0

7781

if tail_RSS ~= 0

7867

if tail_RSS >= param.B_float_RSS_MAX

7782

if tail_RSS >= param.B_float_RSS_MAX

7868

param.use_bmax(param.N_tail_start:end)= ...

7783

param.use_bmax(param.N_tail_start:end)= ...

7869

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7784

min(tail_RSS, param.B_float_RSS_MAX) * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7870

%AJG021820

7785

%AJG021820

7871

param.use_bmin(param.N_tail_start:end)= ...

7786

param.use_bmin(param.N_tail_start:end)= ...

7872

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7787

min(tail_RSS, param.B_float_RSS_MAX) * -1 * sign(dfetaps(param.N_tail_start:end)).*dfetaps(param.N_tail_start:end) /tail_RSS;

7873

end

7788

end

7874

end

7789

end

7875

7790

7876

%AJG021820

7791

%AJG021820

7877

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7792

actual_dfecursors=dfe_clipper(dfecursors_q,sbr(cursor_i)*param.use_bmax(:),sbr(cursor_i)*param.use_bmin(:));

7878

if do_C2M

7793

if do_C2M

7879

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7794

excess_dfe_cursors=dfecursors_windowed-actual_dfecursors;

7880

else

7795

else

7881

excess_dfe_cursors=dfecursors-actual_dfecursors;

7796

excess_dfe_cursors=dfecursors-actual_dfecursors;

7882

end

7797

end

7883

dfetaps=actual_dfecursors/sbr(cursor_i);

7798

dfetaps=actual_dfecursors/sbr(cursor_i);

7884

7799

7885

else

7800

else

7886

tail_RSS=0;

7801

tail_RSS=0;

7887

end

7802

end

7888

%% Eq. 93A-28 %%

7803

%% Eq. 93A-28 %%

7889

sampling_offset = mod(cursor_i, param.samples_per_ui);

7804

sampling_offset = mod(cursor_i, param.samples_per_ui);

7890

%ensure we can take early sample

7805

%ensure we can take early sample

7891

if sampling_offset<=1

7806

if sampling_offset<=1

7892

sampling_offset=sampling_offset+param.samples_per_ui;

7807

sampling_offset=sampling_offset+param.samples_per_ui;

7893

end

7808

end

7894

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7809

if (OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN)

7895

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7810

cursors_early_sample = sbr(cursor_i-1+param.samples_per_ui*(-1:param.ndfe));

7896

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7811

cursors_late_sample = sbr(cursor_i+1+param.samples_per_ui*(-1:param.ndfe));

7897

else

7812

else

7898

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7813

cursors_early_sample = sbr(sampling_offset-1:param.samples_per_ui:end);

7899

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7814

cursors_late_sample = sbr(sampling_offset+1:param.samples_per_ui:end);

7900

end

7815

end

7901

% ensure lengths are equal

7816

% ensure lengths are equal

7902

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7817

cursors_early_sample = cursors_early_sample(1:length(cursors_late_sample));

7903

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7818

h_J = (cursors_late_sample-cursors_early_sample)/2*param.samples_per_ui;

7904

if ~OP.SNR_TXwC0

7819

if ~OP.SNR_TXwC0

7905

%% Equation 93A-30 %%

7820

%% Equation 93A-30 %%

7906

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7821

% since A_s = param.R_LM*cursor/(param.levels-1), cursor=(param.levels-1)*A_s/param.R_LM

7907

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7822

sigma_TX = (param.levels-1)*A_s/param.R_LM*10^(-param.SNR_TX/20);

7908

else

7823

else

7909

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7824

sigma_TX = (param.levels-1)*A_s/txffe(cur)/param.R_LM*10^(-param.SNR_TX/20);% SNER_TX mod from Adee

7910

end

7825

end

7911

%% Equation 93A-31 %%

7826

%% Equation 93A-31 %%

7912

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7827

sigma_ISI = param.sigma_X*norm([precursors; excess_dfe_cursors; far_cursors]);

7913

ISI_N=param.sigma_X*norm( far_cursors);

7828

ISI_N=param.sigma_X*norm( far_cursors);

7914

%% break if FOM has no chance of beating old e

7829

%% break if FOM has no chance of beating old e

7915

OP.exe_mode=1;

7830

OP.exe_mode=1;

7916

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7831

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7917

switch OP.EXE_MODE

7832

switch OP.EXE_MODE

7918

case 0

7833

case 0

7919

case 1

7834

case 1

7920

if (20*log10(A_s/sigma_ISI) < best_FOM)

7835

if (20*log10(A_s/sigma_ISI) < best_FOM)

7921

continue

7836

continue

7922

end

7837

end

7923

case 2

7838

case 2

7924

if (20*log10(A_s/sigma_ISI) < best_FOM)

7839

if (20*log10(A_s/sigma_ISI) < best_FOM)

7925

break

7840

break

7926

end

7841

end

7927

end

7842

end

7928

end

7843

end

7929

%% Equation 93A-32 %%

7844

%% Equation 93A-32 %%

7930

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7845

sigma_J = norm([param.A_DD param.sigma_RJ])*param.sigma_X*norm(h_J);

7931

7846

7932

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7847

%% Equations 93A-33 and 93A-34 for FEXT (depends on TXFFE setting) %%

7933

if OP.RX_CALIBRATION

7848

if OP.RX_CALIBRATION

7934

sigma_XT=0;

7849

sigma_XT=0;

7935

else

7850

else

7936

if ~OP.RxFFE

7851

if ~OP.RxFFE

7937

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7852

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata,phase_memory); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7938

%% Equation 93A-36 denominator (actually its sqrt)

7853

%% Equation 93A-36 denominator (actually its sqrt)

7939

else % John Ewen: 13/12/20018

7854

else % John Ewen: 13/12/20018

7940

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7855

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE'))

7941

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7856

[sigma_XT,~,~] = get_xtlk_noise( txffe, 'FEXT', param ,chdata, phase_memory,C); %with three outputs, the sigma_XT includes both FEXT and NEXT zhilei huang 01/11/2019

7942

else % use results from get_PSDs RIM 3/28/2024

7857

else % use results from get_PSDs RIM 3/28/2024

7943

sigma_XT=PSD_results.S_xn_rms;

7858

sigma_XT=PSD_results.S_xn_rms;

7944

end

7859

end

7945

end

7860

end

7946

end

7861

end

7947

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7862

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7948

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7863

if OP.RxFFE % modify sigma_N with rx noise from the rx ffe

7949

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7864

index_f2=find(chdata(1).faxis(:)>param.fb,1,'first');

7950

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7865

if isempty(index_f2), index_f2=length(chdata(1).faxis);end

7951

f=chdata(1).faxis;

7866

f=chdata(1).faxis;

7952

H_Rx_FFE=zeros(1,length(f));

7867

H_Rx_FFE=zeros(1,length(f));

7953

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7868

for ii=-param.RxFFE_cmx:param.RxFFE_cpx

7954

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7869

%H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*exp(-1j*2*pi*(ii+1).*f/param.fb)+H_Rx_FFE;

7955

if C(ii+param.RxFFE_cmx+1)==0

7870

if C(ii+param.RxFFE_cmx+1)==0

7956

%speed up: skip cases when rxffe=0

7871

%speed up: skip cases when rxffe=0

7957

continue;

7872

continue;

7958

end

7873

end

7959

if ii+1==0

7874

if ii+1==0

7960

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7875

%speed up: ii+1=0, so just scalar addition and avoid exp calc

7961

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7876

H_Rx_FFE = H_Rx_FFE + C(ii+param.RxFFE_cmx+1);

7962

else

7877

else

7963

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7878

H_Rx_FFE=C(ii+param.RxFFE_cmx+1).*transpose(phase_memory(:,ii+param.RxFFE_cmx+1+length(txffe)))+H_Rx_FFE;

7964

end

7879

end

7965

end

7880

end

7966

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7881

sigma_N =sqrt(param.eta_0*sum(H_sy(2:end) .* abs(H_r(2:end) .* H_ctf(2:end) .*H_Rx_FFE(2:end)).^2 .* diff(chdata(1).faxis)/1e9)); % changed from /chdata(1).faxis(end) B. Kirkland S. Elnagar 11/6/2021

7967

end

7882

end

7968

end

7883

end

7969

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7884

%% Equation 93A-36 (note log argument is voltage rather than power ratio)

7970

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7885

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE)

7971

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7886

total_noise_rms = norm([sigma_ISI sigma_J sigma_XT sigma_N sigma_TX sigma_ne]);

7972

else

7887

else

7973

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7888

total_noise_rms = norm([sigma_ISI PSD_results.S_n_rms sigma_ne]);

7974

end

7889

end

7975

if do_C2M

7890

if do_C2M

7976

if param.Noise_Crest_Factor == 0

7891

if param.Noise_Crest_Factor == 0

7977

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7892

ber_q = sqrt(2)*erfcinv(2*param.specBER);

7978

else

7893

else

7979

ber_q=param.Noise_Crest_Factor;

7894

ber_q=param.Noise_Crest_Factor;

7980

end

7895

end

7981

if OP.force_pdf_bin_size

7896

if OP.force_pdf_bin_size

7982

delta_y = OP.BinSize;

7897

delta_y = OP.BinSize;

7983

else

7898

else

7984

delta_y = min(A_s/1000, OP.BinSize);

7899

delta_y = min(A_s/1000, OP.BinSize);

7985

end

7900

end

7986

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7901

ne_noise_pdf = normal_dist(0, ber_q, delta_y);

7987

cci_pdf = normal_dist(0, ber_q, delta_y);

7902

cci_pdf = normal_dist(0, ber_q, delta_y);

7988

chdata(1).eq_pulse_response=sbr;

7903

chdata(1).eq_pulse_response=sbr;

7989

tmp_result.t_s= cursor_i;

7904

tmp_result.t_s= cursor_i;

7990

tmp_result.A_s=A_s;

7905

tmp_result.A_s=A_s;

7991

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7906

EH_1st= 2*(A_s-erfcinv(param.specBER*2)*2/sqrt(2)*total_noise_rms);

7992

if EH_1st <= param.Min_VEO_Test/1000 -.001

7907

if EH_1st <= param.Min_VEO_Test/1000 -.001

7993

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7908

% sprintf( '%g.1 As .. %g.1 EH\n',A_s*1000,EH_1st*1000)

7994

continue

7909

continue

7995

else

7910

else

7996

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7911

% sprintf( ' OK before %g As .. %g EH\n',A_s*1000,EH_1st*1000)

7997

end

7912

end

7998

Struct_Noise.sigma_N=sigma_N;

7913

Struct_Noise.sigma_N=sigma_N;

7999

Struct_Noise.sigma_TX=sigma_TX;

7914

Struct_Noise.sigma_TX=sigma_TX;

8000

Struct_Noise.cci_pdf=cci_pdf;

7915

Struct_Noise.cci_pdf=cci_pdf;

8001

Struct_Noise.ber_q=ber_q;

7916

Struct_Noise.ber_q=ber_q;

8002

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

7917

Struct_Noise.ne_noise_pdf=ne_noise_pdf;

8003

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

7918

[Left_EW,Right_EW,eye_contour,EH_T_C2M,EH_B_C2M]=COM_eye_width(chdata,delta_y,tmp_result,param,OP,Struct_Noise,1);

8004

EH=EH_T_C2M-EH_B_C2M;

7919

EH=EH_T_C2M-EH_B_C2M;

8005

N_i=(A_s*2-EH)/2;

7920

N_i=(A_s*2-EH)/2;

8006

if EH <= param.Min_VEO_Test/1000

7921

if EH <= param.Min_VEO_Test/1000

8007

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

7922

% sprintf( 'After As=%.1f .. EH=%.1f EH_1st=%.1f \n',A_s*1000,EH*1000, EH_1st*1000)

8008

continue

7923

continue

8009

else

7924

else

8010

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

7925

% sprintf( '<strong> After As=%.1f .. EH=%.1f EH_1st=%.1f </strong> \n',A_s*1000,EH*1000, EH_1st*1000)

8011

end

7926

end

8012

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7927

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8013

FOM =20*log10(A_s/N_i);

7928

FOM =20*log10(A_s/N_i);

8014

end

7929

end

8015

else

7930

else

8016

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

7931

if ~(strcmp(OP.FFE_OPT_METHOD,'MMSE') && OP.RxFFE) % MMSE defines its own FOM

8017

FOM = 20*log10(A_s/total_noise_rms);

7932

FOM = 20*log10(A_s/total_noise_rms);

8018

end

7933

end

8019

% if strfind(param.CTLE_type,'CL120e')

7934

% if strfind(param.CTLE_type,'CL120e')

8020

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

7935

% FOM = A_s*C(param.RxFFE_cmx+1)-total_noise_rms_ffe;

8021

end

7936

end

8022

if 0 % for loop analysis

7937

if 0 % for loop analysis

8023

result.FOM_array(new_loops)=FOM;

7938

result.FOM_array(new_loops)=FOM;

8024

end

7939

end

8025

7940

8026

if FOM>best_itick_FOM

7941

if FOM>best_itick_FOM

8027

best_itick_FOM=FOM;

7942

best_itick_FOM=FOM;

8028

best_itick_in_cluster=itick;

7943

best_itick_in_cluster=itick;

8029

end

7944

end

8030

7945

8031

if itick>=0 && FOM>best_positive_itick_FOM

7946

if itick>=0 && FOM>best_positive_itick_FOM

8032

best_positive_itick_FOM=FOM;

7947

best_positive_itick_FOM=FOM;

8033

best_positive_itick_in_loop=itick;

7948

best_positive_itick_in_loop=itick;

8034

end

7949

end

8035

if itick<=0 && FOM>best_negative_itick_FOM

7950

if itick<=0 && FOM>best_negative_itick_FOM

8036

best_negative_itick_FOM=FOM;

7951

best_negative_itick_FOM=FOM;

8037

best_negative_itick_in_loop=itick;

7952

best_negative_itick_in_loop=itick;

8038

end

7953

end

8039

7954

8040

itick_index=find(itick==full_sample_range);

7955

itick_index=find(itick==full_sample_range);

8041

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

7956

FOM_TRACKER(Gffe_index,ctle_index,g_LP_index,TK,itick_index)=FOM;

8042

7957

8043

if (FOM > best_FOM)

7958

if (FOM > best_FOM)

8044

best_current_ffegain=param.current_ffegain;

7959

best_current_ffegain=param.current_ffegain;

8045

best_txffe = txffe;

7960

best_txffe = txffe;

8046

%along with best_txffe, save the indices of the best_txffe

7961

%along with best_txffe, save the indices of the best_txffe

8047

%(saves time in LOCAL SEARCH block)

7962

%(saves time in LOCAL SEARCH block)

8048

best_txffe_index=tx_index_vector;

7963

best_txffe_index=tx_index_vector;

8049

best_sbr = sbr;

7964

best_sbr = sbr;

8050

best_ctle = ctle_index;

7965

best_ctle = ctle_index;

8051

best_G_high_pass =g_LP_index;

7966

best_G_high_pass =g_LP_index;

8052

best_FOM = FOM;

7967

best_FOM = FOM;

8053

best_cursor_i = cursor_i;

7968

best_cursor_i = cursor_i;

8054

best_itick = itick;

7969

best_itick = itick;

8055

if ~OP.TDMODE

7970

if ~OP.TDMODE

8056

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

7971

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8057

best_IR=effective_channel;

7972

best_IR=effective_channel;

8058

end

7973

end

8059

best_sigma_N = sigma_N;

7974

best_sigma_N = sigma_N;

8060

best_h_J = h_J;

7975

best_h_J = h_J;

8061

best_A_s=A_s;

7976

best_A_s=A_s;

8062

best_A_p=A_p;

7977

best_A_p=A_p;

8063

best_ISI=ISI_N;

7978

best_ISI=ISI_N;

8064

best_bmax=param.use_bmax;

7979

best_bmax=param.use_bmax;

8065

%AJG021820

7980

%AJG021820

8066

best_bmin=param.use_bmin;

7981

best_bmin=param.use_bmin;

8067

best_tail_RSS=tail_RSS;

7982

best_tail_RSS=tail_RSS;

8068

best_dfetaps=dfetaps;

7983

best_dfetaps=dfetaps;

8069

if param.Floating_DFE

7984

if param.Floating_DFE

8070

best_floating_tap_locations=floating_tap_locations;

7985

best_floating_tap_locations=floating_tap_locations;

8071

best_floating_tap_coef=floating_tap_coef;

7986

best_floating_tap_coef=floating_tap_coef;

8072

end

7987

end

8073

if param.Floating_RXFFE

7988

if param.Floating_RXFFE

8074

best_floating_tap_locations=floating_tap_locations;

7989

best_floating_tap_locations=floating_tap_locations;

8075

% best_floating_tap_coef=floating_tap_coef;

7990

% best_floating_tap_coef=floating_tap_coef;

8076

end

7991

end

8077

if OP.RxFFE

7992

if OP.RxFFE

8078

best_RxFFE=C;

7993

best_RxFFE=C;

8079

best_PSD_results=PSD_results;

7994

best_PSD_results=PSD_results;

8080

best_MMSE_results=MMSE_results;

7995

best_MMSE_results=MMSE_results;

8081

end

7996

end

8082

end

7997

end

8083

end

7998

end

8084

end

7999

end

8085

8000

8086

end

8001

end

8087

end

8002

end

8088

end

8003

end

8089

if do_C2M

8004

if do_C2M

8090

if best_FOM == -inf

8005

if best_FOM == -inf

8091

param.Min_VEO_Test=0;

8006

param.Min_VEO_Test=0;

8092

else

8007

else

8093

break

8008

break

8094

end

8009

end

8095

end

8010

end

8096

end

8011

end

8097

if 0

8012

if 0

8098

fprintf('old loops = %d\n',old_loops);

8013

fprintf('old loops = %d\n',old_loops);

8099

fprintf('new loops = %d\n',new_loops);

8014

fprintf('new loops = %d\n',new_loops);

8100

display(sprintf('\n :loops = %g',pxi))

8015

display(sprintf('\n :loops = %g',pxi))

8101

end

8016

end

8102

8017

8103

%turn this on to review if FOM changes sign more than once in an itick loop

8018

%turn this on to review if FOM changes sign more than once in an itick loop

8104

if 0

8019

if 0

8105

DIR_CHANGE={};

8020

DIR_CHANGE={};

8106

for m=1:length(Gffe_values)

8021

for m=1:length(Gffe_values)

8107

for n=1:length(gdc_values)

8022

for n=1:length(gdc_values)

8108

for k=1:lf_indx

8023

for k=1:lf_indx

8109

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8024

FOM_this_mat=squeeze(FOM_TRACKER(m,n,k,:,:));

8110

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8025

%x reveals if FOM on a particular row (locked txffe, moving itick) goes up or down

8111

%1 = goes up, -1=goes down

8026

%1 = goes up, -1=goes down

8112

x=sign(diff(FOM_this_mat')');

8027

x=sign(diff(FOM_this_mat')');

8113

%y = change in sign on x. the location of a "2" is where FOM changes direction

8028

%y = change in sign on x. the location of a "2" is where FOM changes direction

8114

y=abs(diff(x'))';

8029

y=abs(diff(x'))';

8115

%the goal is the FOM only changes direction once. so count the occurences of the 2

8030

%the goal is the FOM only changes direction once. so count the occurences of the 2

8116

for j=1:size(FOM_this_mat,1)

8031

for j=1:size(FOM_this_mat,1)

8117

z{j}=find(y(j,:)==2);

8032

z{j}=find(y(j,:)==2);

8118

end

8033

end

8119

zL=cellfun('length',z);

8034

zL=cellfun('length',z);

8120

%return any row where FOM changed direction more than once

8035

%return any row where FOM changed direction more than once

8121

DIR_CHANGE{j,k}=find(zL>1);

8036

DIR_CHANGE{j,k}=find(zL>1);

8122

end

8037

end

8123

end

8038

end

8124

end

8039

end

8125

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8040

multi_direction_change=find(~cellfun('isempty',DIR_CHANGE))

8126

end

8041

end

8127

8042

8128

if ~exist('best_cursor_i', 'var')% take last setting

8043

if ~exist('best_cursor_i', 'var')% take last setting

8129

result.eq_failed=true;

8044

result.eq_failed=true;

8130

display('equalization failed')

8045

display('equalization failed')

8131

best_bmax=param.bmax;

8046

best_bmax=param.bmax;

8132

%AJG021820

8047

%AJG021820

8133

best_bmin=param.bmin;

8048

best_bmin=param.bmin;

8134

best_tail_RSS=0;

8049

best_tail_RSS=0;

8135

best_current_ffegain=0;

8050

best_current_ffegain=0;

8136

best_txffe = txffe;

8051

best_txffe = txffe;

8137

best_sbr = sbr;

8052

best_sbr = sbr;

8138

best_ctle = ctle_index;

8053

best_ctle = ctle_index;

8139

if OP.RxFFE

8054

if OP.RxFFE

8140

best_PSD_results=PSD_results;

8055

best_PSD_results=PSD_results;

8141

best_MMSE_results=MMSE_results;

8056

best_MMSE_results=MMSE_results;

8142

best_RxFFE=C;

8057

best_RxFFE=C;

8143

end

8058

end

8144

best_G_high_pass =g_LP_index;

8059

best_G_high_pass =g_LP_index;

8145

best_FOM = FOM;

8060

best_FOM = FOM;

8146

%if this block is reached, the last encountered EQ parameters are used

8061

%if this block is reached, the last encountered EQ parameters are used

8147

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8062

%if it so happened that there was no zero crossing in the last encountered EQ set, then cursor_i will be empty

8148

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8063

%EQ search has failed, so it is not important to give an exact sample location, so just use the peak of the pulse

8149

if isempty(cursor_i)

8064

if isempty(cursor_i)

8150

[~,cursor_i]=max(sbr);

8065

[~,cursor_i]=max(sbr);

8151

end

8066

end

8152

best_cursor_i = cursor_i;

8067

best_cursor_i = cursor_i;

8153

best_itick = itick;

8068

best_itick = itick;

8154

if ~OP.TDMODE

8069

if ~OP.TDMODE

8155

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8070

[ effective_channel ] = FFE( txffe , cur-1, param.samples_per_ui, chdata(1).ctle_imp_response );

8156

best_IR=effective_channel;

8071

best_IR=effective_channel;

8157

end

8072

end

8158

best_sigma_N = sigma_N;

8073

best_sigma_N = sigma_N;

8159

best_h_J = h_J;

8074

best_h_J = h_J;

8160

best_A_p=max(sbr);

8075

best_A_p=max(sbr);

8161

best_ISI=1;

8076

best_ISI=1;

8162

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8077

best_dfetaps= sbr( cursor_i+param.samples_per_ui*(1):param.samples_per_ui:cursor_i+param.samples_per_ui*(param.ndfe))/sbr(cursor_i) ;

8163

best_A_s= sbr( cursor_i);

8078

best_A_s= sbr( cursor_i);

8164

if param.Floating_DFE

8079

if param.Floating_DFE

8165

best_floating_tap_locations=[];

8080

best_floating_tap_locations=[];

8166

best_floating_tap_coef=[];

8081

best_floating_tap_coef=[];

8167

end

8082

end

8168

if do_C2M

8083

if do_C2M

8169

return

8084

return

8170

end

8085

end

8171

% return

8086

% return

8172

else

8087

else

8173

result.eq_failed=false; % RIM 12/30/2023

8088

result.eq_failed=false; % RIM 12/30/2023

8174

end

8089

end

8175

8090

8176

best_cursor = best_sbr(best_cursor_i);

8091

best_cursor = best_sbr(best_cursor_i);

8177

% report during debug

8092

% report during debug

8178

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8093

PRin=filter(ones(param.samples_per_ui, 1),1, chdata(1).uneq_imp_response);

8179

%If sbr was zero padded, then PRin needs to do so as well)

8094

%If sbr was zero padded, then PRin needs to do so as well)

8180

if length(PRin)<length(best_sbr)

8095

if length(PRin)<length(best_sbr)

8181

PRin(end+1:length(best_sbr))=0;

8096

PRin(end+1:length(best_sbr))=0;

8182

end

8097

end

8183

f=1e8:1e8:100e9;

8098

f=1e8:1e8:100e9;

8184

8099

8185

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8100

H_bt=Bessel_Thomson_Filter(param,f,OP.Bessel_Thomson);

8186

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8101

H_bw=Butterworth_Filter(param,f,OP.Butterworth);

8187

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8102

H_RCos=Raised_Cosine_Filter(param,f,OP.Raised_Cosine);% experiment with RCos

8188

% need to include H_RCos in noise and when computing the system ir for thru

8103

% need to include H_RCos in noise and when computing the system ir for thru

8189

% and crosstalk

8104

% and crosstalk

8190

H_r=H_bw.*H_bt.*H_RCos;

8105

H_r=H_bw.*H_bt.*H_RCos;

8191

8106

8192

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8107

ctle_gain1 = (10^(gdc_values(best_ctle)/20) + 1i*f/param.CTLE_fz(best_ctle)) ./ ...

8193

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8108

((1+1i*f/param.CTLE_fp1(best_ctle)).*(1+1i*f/param.CTLE_fp2(best_ctle)));

8194

8109

8195

switch param.CTLE_type

8110

switch param.CTLE_type

8196

case 'CL93'

8111

case 'CL93'

8197

H_low=1;

8112

H_low=1;

8198

case 'CL120d'

8113

case 'CL120d'

8199

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8114

H_low=(10^(param.g_DC_HP_values(best_G_high_pass)/20) + 1i*f/param.f_HP(best_G_high_pass))./(1 + 1i*f/param.f_HP(best_G_high_pass));

8200

case 'CL120e'

8115

case 'CL120e'

8201

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8116

H_low=(1 + 1i*f/param.f_HP_Z(best_ctle))./ (1 + 1i*f/param.f_HP_P(best_ctle));

8202

end

8117

end

8203

ctle_gain=H_low.*ctle_gain1.*H_r;

8118

ctle_gain=H_low.*ctle_gain1.*H_r;

8204

8119

8205

8120

8206

8121

8207

%lsbr=length(sbr);

8122

%lsbr=length(sbr);

8208

%use length of best_sbr in case zero padding was performed

8123

%use length of best_sbr in case zero padding was performed

8209

%check "sbr_required_length" variable

8124

%check "sbr_required_length" variable

8210

lsbr=length(best_sbr);

8125

lsbr=length(best_sbr);

8211

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8126

t=0:param.ui/param.samples_per_ui:(lsbr-1)*param.ui/param.samples_per_ui;

8212

8127

8213

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8128

sampled_best_sbr_precursors_t = (best_cursor_i/param.samples_per_ui:-1:1/param.samples_per_ui)*param.ui;

8214

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8129

sampled_best_sbr_precursors_t = sampled_best_sbr_precursors_t(end:-1:2); % exclude cursor

8215

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8130

sampled_best_sbr_precursors = best_sbr(round(sampled_best_sbr_precursors_t/param.ui*param.samples_per_ui));

8216

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8131

sampled_best_sbr_postcursors_t = (best_cursor_i:param.samples_per_ui:lsbr)/param.samples_per_ui*param.ui;

8217

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8132

sampled_best_sbr_postcursors_t = sampled_best_sbr_postcursors_t(2:end); % exclude cursor

8218

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8133

sampled_best_sbr_postcursors = best_sbr(round(sampled_best_sbr_postcursors_t/param.ui*param.samples_per_ui));

8219

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8134

sampled_best_sbr_dfecursors_t = (best_cursor_i/param.samples_per_ui+(1:param.ndfe_passed))*param.ui;

8220

if param.Floating_DFE

8135

if param.Floating_DFE

8221

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8136

sampled_best_sbr_fdfecursors_t = (best_cursor_i/param.samples_per_ui+(best_floating_tap_locations))*param.ui;

8222

end

8137

end

8223

% apply max tap value constraint

8138

% apply max tap value constraint

8224

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8139

dfe_cursors = sampled_best_sbr_postcursors(1:param.ndfe);

8225

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8140

dfe_SBRcursors = sampled_best_sbr_postcursors(1:param.ndfe);

8226

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8141

if isrow(best_bmax) == 1, best_bmax=best_bmax.';end

8227

8142

8228

%AJG021820

8143

%AJG021820

8229

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8144

if isrow(best_bmin) == 1, best_bmin=best_bmin.';end

8230

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8145

DFE_taps_mV=dfe_clipper(dfe_cursors,best_cursor*best_bmax(1:param.ndfe),best_cursor*best_bmin(1:param.ndfe));

8231

if param.Floating_DFE

8146

if param.Floating_DFE

8232

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8147

FDFE_taps_mV=DFE_taps_mV(best_floating_tap_locations);

8233

end

8148

end

8234

8149

8235

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8150

sampled_best_sbr_postcursors(1:param.ndfe) = dfe_SBRcursors-DFE_taps_mV;

8236

Symbol_Adj = (param.levels-1);% 3A.1.6

8151

Symbol_Adj = (param.levels-1);% 3A.1.6

8237

if OP.DEBUG ~=0

8152

if OP.DEBUG ~=0

8238

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8153

if OP.DISPLAY_WINDOW && ~OP.RX_CALIBRATION

8239

% display pulse responses in one axis per test case.

8154

% display pulse responses in one axis per test case.

8240

switch upper(OP.TIME_AXIS)

8155

switch upper(OP.TIME_AXIS)

8241

case 'S' % RIM 11-13-2023 added user selectable xaxis

8156

case 'S' % RIM 11-13-2023 added user selectable xaxis

8242

xnorm=1;

8157

xnorm=1;

8243

xaxis_label='seconds';

8158

xaxis_label='seconds';

8244

offset=0;

8159

offset=0;

8245

case 'UI'

8160

case 'UI'

8246

xnorm=param.ui;

8161

xnorm=param.ui;

8247

xaxis_label='UI';

8162

xaxis_label='UI';

8248

offset=t(best_cursor_i)/xnorm;

8163

offset=t(best_cursor_i)/xnorm;

8249

otherwise

8164

otherwise

8250

xnorm=1;

8165

xnorm=1;

8251

xaxis_label='seconds';

8166

xaxis_label='seconds';

8252

offset=0;

8167

offset=0;

8253

end

8168

end

8254

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8169

figure_name = sprintf('PKG %d: Equalization effect: %s : ', OP.pkg_len_select( param.package_testcase_i), param.base);

8255

fig=findobj('Name', figure_name);

8170

fig=findobj('Name', figure_name);

8256

if isempty(fig), fig=figure('Name', figure_name); end

8171

if isempty(fig), fig=figure('Name', figure_name); end

8257

figure(fig);set(gcf,'Tag','COM');

8172

figure(fig);set(gcf,'Tag','COM');

8258

movegui(fig,'north')

8173

movegui(fig,'north')

8259

%figure(fig.Number);

8174

%figure(fig.Number);

8260

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8175

% hax = subplot(length(OP.pkg_len_select), 1, param.package_testcase_i);

8261

if OP.RxFFE

8176

if OP.RxFFE

8262

ax1=subplot(2,1,1);

8177

ax1=subplot(2,1,1);

8263

end

8178

end

8264

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8179

plot(t/xnorm-offset,best_sbr/Symbol_Adj,'disp', '1/2 Symbol 0-3 Equalized PR');

8265

hold on

8180

hold on

8266

8181

8267

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8182

PRplt(1:param.samples_per_ui+5)=PRin(1); % line up with the ffe introduced delay

8268

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8183

PRplt(param.samples_per_ui+6:length(t))=PRin(1:length(t)-param.samples_per_ui-5);

8269

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8184

plot((t-param.ui-t(6))/xnorm-offset,PRplt/Symbol_Adj,'r','disp', '1/2 Symbol 0-3 Unequalized (tp5d) PR');

8270

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8185

stem(t(best_cursor_i)/xnorm-offset,best_sbr(best_cursor_i)/Symbol_Adj,'g','disp','Cursor (sample point)');

8271

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8186

title(sprintf('PKG Case %d', OP.pkg_len_select( param.package_testcase_i)));

8272

ylabel('volts')

8187

ylabel('volts')

8273

xlabel(xaxis_label)

8188

xlabel(xaxis_label)

8274

grid on

8189

grid on

8275

legend show

8190

legend show

8276

legend( 'Location', 'best')

8191

legend( 'Location', 'best')

8277

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8192

plot((sampled_best_sbr_precursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_precursors'/Symbol_Adj, 'kx', 'disp','Pre cursors');

8278

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8193

plot((sampled_best_sbr_postcursors_t-param.ui/param.samples_per_ui)/xnorm-offset, sampled_best_sbr_postcursors'/Symbol_Adj, 'ko', 'disp','Post cursors');

8279

if param.ndfe_passed ~=0

8194

if param.ndfe_passed ~=0

8280

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8195

stem((sampled_best_sbr_dfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,DFE_taps_mV(1:param.ndfe_passed)/Symbol_Adj','m', 'LineWidth',2,'disp','DFE-canceled cursors');

8281

end

8196

end

8282

if param.Floating_DFE

8197

if param.Floating_DFE

8283

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8198

stem((sampled_best_sbr_fdfecursors_t-param.ui/param.samples_per_ui)/xnorm-offset,FDFE_taps_mV/Symbol_Adj, 'MarkerFaceColor','red','MarkerEdgeColor','m','LineWidth',1,'disp','FDFE-canceled cursors');

8284

end

8199

end

8285

if OP.RxFFE

8200

if OP.RxFFE

8286

ax2=subplot(2,1,2);

8201

ax2=subplot(2,1,2);

8287

if param.Floating_RXFFE

8202

if param.Floating_RXFFE

8288

%AJG: floating tap x-axis location needs offset by -(RxFFE_cmx+1) because the floating tap indices include precursor indices

8289

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)...

8203

stem((t(best_cursor_i+(best_floating_tap_locations)*param.samples_per_ui))/xnorm-offset,best_RxFFE(best_floating_tap_locations)...

8290

,'filled','disp','RxFFE floating FFE taps')

8204

,'filled','disp','RxFFE floating FFE taps')

8291

hold on

8205

hold on

8292

end

8206

end

8293

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8207

stem((t(best_cursor_i+param.samples_per_ui*(-param.RxFFE_cmx:param.RxFFE_cpx)))/xnorm-offset,best_RxFFE(1:param.RxFFE_cmx+param.RxFFE_cpx+1)...

8294

,'filled','disp','RxFFE fixted FFE taps')

8208

,'filled','disp','RxFFE fixted FFE taps')

8295

legend show

8209

legend show

8296

zoom xon

8210

zoom xon

8297

linkaxes([ax1 ax2],'x')

8211

linkaxes([ax1 ax2],'x')

8298

end

8212

end

8299

8213

8300

8214

8301

grid on

8215

grid on

8302

legend show

8216

legend show

8303

legend( 'Location', 'best')

8217

legend( 'Location', 'best')

8304

zoom xon

8218

zoom xon

8305

% set(hax, 'tag', 'EQE');

8219

% set(hax, 'tag', 'EQE');

8306

%

8220

%

8307

figure(110);set(gcf,'Tag','COM');

8221

figure(110);set(gcf,'Tag','COM');

8308

set(gcf, 'Name', 'CTLE selection');

8222

set(gcf, 'Name', 'CTLE selection');

8309

movegui(gcf, 'southeast');

8223

movegui(gcf, 'southeast');

8310

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8224

semilogx(f,20*log10(abs(ctle_gain)), 'disp', sprintf('Case %d', param.package_testcase_i));

8311

hold on

8225

hold on

8312

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8226

semilogx(f,20*log10(abs(H_r)), 'disp', sprintf('Rx filter Case %d', param.package_testcase_i));

8313

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8227

semilogx(f,20*log10(abs(H_low.*ctle_gain1)), 'disp', sprintf('CTF Case %d', param.package_testcase_i));

8314

fbaud_tick=find(f >= baud_rate, 1);

8228

fbaud_tick=find(f >= baud_rate, 1);

8315

fnq_tick=find(f >= baud_rate/2, 1);

8229

fnq_tick=find(f >= baud_rate/2, 1);

8316

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8230

stem(f(fnq_tick),20*log10(abs(ctle_gain(fnq_tick))),'g', 'handlevisibility', 'off');

8317

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8231

stem(f(fbaud_tick),20*log10(abs(ctle_gain(fbaud_tick))),'g', 'handlevisibility', 'off');

8318

recolor_plots(gca);

8232

recolor_plots(gca);

8319

title('CTF/w Rx Filter Response')

8233

title('CTF/w Rx Filter Response')

8320

ylabel('dB')

8234

ylabel('dB')

8321

xlabel('Hz')

8235

xlabel('Hz')

8322

legend show

8236

legend show

8323

end

8237

end

8324

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8238

display(['FOM: ' ,num2str(best_FOM, 2),' dB']);

8325

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8239

display(['TXFFE coefficients: ' ,mat2str(best_txffe) ] );

8326

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8240

display(['SNR ISI: ' ,num2str(20*log10(best_A_p/best_ISI), 2),' dB']);

8327

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8241

display(['CTLE DC gain: ' ,num2str(gdc_values(best_ctle)), ' dB']);

8328

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8242

display(['CTF peaking gain: ' ,num2str(20*log10(max(abs(ctle_gain))), 2), ' dB']);

8329

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8243

display(['Symbol Available signal: ' ,num2str(best_cursor/Symbol_Adj)]);

8330

end

8244

end

8331

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8245

if OP.DEBUG && OP.DISPLAY_WINDOW && OP.RX_CALIBRATION==0

8332

eqe_axes = findobj('tag', 'EQE');

8246

eqe_axes = findobj('tag', 'EQE');

8333

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8247

if ~isempty(eqe_axes), linkaxes(eqe_axes, 'xy'); end

8334

end

8248

end

8335

if OP.DISPLAY_WINDOW

8249

if OP.DISPLAY_WINDOW

8336

close(hwaitbar);

8250

close(hwaitbar);

8337

else

8251

else

8338

fprintf('\n');

8252

fprintf('\n');

8339

end

8253

end

8340

8254

8341

% % eq_data

8255

% % eq_data

8342

result.cur=cur;

8256

result.cur=cur;

8343

result.txffe = best_txffe;

8257

result.txffe = best_txffe;

8344

result.ctle = best_ctle;

8258

result.ctle = best_ctle;

8345

result.best_G_high_pass=best_G_high_pass;

8259

result.best_G_high_pass=best_G_high_pass;

8346

result.DFE_taps = best_dfetaps; %relative

8260

result.DFE_taps = best_dfetaps; %relative

8347

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8261

result.DFE_taps_i = best_cursor_i+(1:param.ndfe)*param.samples_per_ui;

8348

if param.Floating_DFE

8262

if param.Floating_DFE

8349

result.floating_tap_locations=best_floating_tap_locations;

8263

result.floating_tap_locations=best_floating_tap_locations;

8350

result.floating_tap_coef=best_floating_tap_coef;

8264

result.floating_tap_coef=best_floating_tap_coef;

8351

end

8265

end

8352

if param.Floating_RXFFE

8266

if param.Floating_RXFFE

8353

result.floating_tap_locations=best_floating_tap_locations;

8267

result.floating_tap_locations=best_floating_tap_locations;

8354

end

8268

end

8355

result.A_s = best_A_s;

8269

result.A_s = best_A_s;

8356

result.t_s = best_cursor_i;

8270

result.t_s = best_cursor_i;

8357

result.itick = best_itick;

8271

result.itick = best_itick;

8358

result.sigma_N = best_sigma_N;

8272

result.sigma_N = best_sigma_N;

8359

result.h_J = best_h_J;

8273

result.h_J = best_h_J;

8360

result.FOM = best_FOM;

8274

result.FOM = best_FOM;

8361

if ~OP.TDMODE

8275

if ~OP.TDMODE

8362

%If sbr was zero padded, then best_IR needs to do so as well)

8276

%If sbr was zero padded, then best_IR needs to do so as well)

8363

if length(best_IR)<length(best_sbr)

8277

if length(best_IR)<length(best_sbr)

8364

best_IR(end+1:length(best_sbr))=0;

8278

best_IR(end+1:length(best_sbr))=0;

8365

end

8279

end

8366

result.IR = best_IR;

8280

result.IR = best_IR;

8367

end

8281

end

8368

result.t=t;

8282

result.t=t;

8369

result.sbr=best_sbr;

8283

result.sbr=best_sbr;

8370

if OP.RxFFE

8284

if OP.RxFFE

8371

result.RxFFE=best_RxFFE;

8285

result.RxFFE=best_RxFFE;

8372

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8286

if strcmp(OP.FFE_OPT_METHOD,'MMSE')

8373

result.PSD_results=best_PSD_results;

8287

result.PSD_results=best_PSD_results;

8374

result.MMSE_results=best_MMSE_results;

8288

result.MMSE_results=best_MMSE_results;

8375

end

8289

end

8376

end

8290

end

8377

8291

8378

8292

8379

8293

8380

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8294

% changed RIM 4/17/2019 use sum(IR) for Vf of originl IR at N_b UI

8381

% updated RIM 12/17/2021

8295

% updated RIM 12/17/2021

8382

result.A_p = max(chdata(1).uneq_pulse_response);

8296

result.A_p = max(chdata(1).uneq_pulse_response);

8383

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8297

its=find(chdata(1).uneq_pulse_response>=max(chdata(1).uneq_pulse_response),1,'first');

8384

PR=chdata(1).uneq_pulse_response;

8298

PR=chdata(1).uneq_pulse_response;

8385

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8299

iend = its+param.N_v*param.samples_per_ui-param.samples_per_ui/2; % from eq: 163A-3

8386

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8300

ibeg= its-param.D_p*param.samples_per_ui-param.samples_per_ui/2;% from eq: 163A-3

8387

if iend >= length(PR)

8301

if iend >= length(PR)

8388

iend = length (PR);

8302

iend = length (PR);

8389

end

8303

end

8390

if ibeg < 1

8304

if ibeg < 1

8391

ibeg = 1;

8305

ibeg = 1;

8392

end

8306

end

8393

PR=PR(ibeg:iend);

8307

PR=PR(ibeg:iend);

8394

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8308

result.A_f = sum(PR/param.samples_per_ui); %% eq 163A-3

8395

SRn=PR;

8309

SRn=PR;

8396

for ik=1:floor(length(PR)/param.samples_per_ui)

8310

for ik=1:floor(length(PR)/param.samples_per_ui)

8397

SPR=circshift(PR,param.samples_per_ui*ik);

8311

SPR=circshift(PR,param.samples_per_ui*ik);

8398

SPR(1:ik*param.samples_per_ui)=0;

8312

SPR(1:ik*param.samples_per_ui)=0;

8399

SRn=SRn+ SPR;

8313

SRn=SRn+ SPR;

8400

end

8314

end

8401

codedebug=0;

8315

codedebug=0;

8402

if codedebug

8316

if codedebug

8403

fig=figure('Name', 'step and pulse response for code debug');

8317

fig=figure('Name', 'step and pulse response for code debug');

8404

figure(fig);set(gcf,'Tag','COM');

8318

figure(fig);set(gcf,'Tag','COM');

8405

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8319

UI=(1:length(SRn))/param.samples_per_ui-param.D_p;

8406

plot(UI,SRn)

8320

plot(UI,SRn)

8407

hold on

8321

hold on

8408

plot(UI,PR)

8322

plot(UI,PR)

8409

xlim([-param.D_p param.N_v])

8323

xlim([-param.D_p param.N_v])

8410

grid on;hold off;

8324

grid on;hold off;

8411

result.step=SRn;

8325

result.step=SRn;

8412

end

8326

end

8413

i20=find(SRn>=0.20*result.A_f,1,'first');

8327

i20=find(SRn>=0.20*result.A_f,1,'first');

8414

i80=find(SRn>=0.80*result.A_f,1,'first');

8328

i80=find(SRn>=0.80*result.A_f,1,'first');

8415

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8329

result.Tr_measured_from_step=(i80-i20)/(param.fb*param.samples_per_ui);

8416

result.Pmax_by_Vf=result.A_p/result.A_f;

8330

result.Pmax_by_Vf=result.A_p/result.A_f;

8417

result.ISI =best_ISI;

8331

result.ISI =best_ISI;

8418

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8332

result.SNR_ISI=20*log10(best_A_p/best_ISI);

8419

result.best_current_ffegain=best_current_ffegain;

8333

result.best_current_ffegain=best_current_ffegain;

8420

result.best_bmax=best_bmax;

8334

result.best_bmax=best_bmax;

8421

%AJG021820

8335

%AJG021820

8422

result.best_bmin=best_bmin;

8336

result.best_bmin=best_bmin;

8423

result.tail_RSS=best_tail_RSS;

8337

result.tail_RSS=best_tail_RSS;

8424

function param=parameter_size_adjustment(param,OP)

8338

function param=parameter_size_adjustment(param,OP)

8425

8339

8426

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8340

make_length2={'C_pkg_board' 'C_diepad' 'L_comp' 'C_bump' 'tfx' 'C_v' 'C_0' 'C_1' 'pkg_Z_c' 'brd_Z_c' 'R_diepad'};

8427

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8341

make_length_WCPORTZ={'a_thru' 'a_fext' 'a_next' 'SNDR'};

8428

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8342

make_length_GDC={'CTLE_fp1' 'CTLE_fp2' 'CTLE_fz' 'f_HP_Z' 'f_HP_P'};

8429

make_length_DCHP={'f_HP'};

8343

make_length_DCHP={'f_HP'};

8430

make_length_ncases={'AC_CM_RMS'};

8344

make_length_ncases={'AC_CM_RMS'};

8431

8345

8432

%ncases used by make_length_ncases fields

8346

%ncases used by make_length_ncases fields

8433

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8347

[ncases, mele]=size(param.z_p_tx_cases); % need find the number of test cases RIM 01-08-20

8434

8348

8435

%PORTZ_mult used by make_length_WCPORTZ fields

8349

%PORTZ_mult used by make_length_WCPORTZ fields

8436

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8350

pkg_sel_vec=ones(1,max(OP.pkg_len_select));

8437

if OP.WC_PORTZ

8351

if OP.WC_PORTZ

8438

PORTZ_mult=[1 1];

8352

PORTZ_mult=[1 1];

8439

else

8353

else

8440

PORTZ_mult=pkg_sel_vec;

8354

PORTZ_mult=pkg_sel_vec;

8441

end

8355

end

8442

8356

8443

%Parameters that have length = 2

8357

%Parameters that have length = 2

8444

for j=1:length(make_length2)

8358

for j=1:length(make_length2)

8445

if numel(param.(make_length2{j}))==1

8359

if numel(param.(make_length2{j}))==1

8446

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8360

param.(make_length2{j}) = param.(make_length2{j})*[1 1];

8447

end

8361

end

8448

end

8362

end

8449

8363

8450

%Parameters that have length = ncases

8364

%Parameters that have length = ncases

8451

for j=1:length(make_length_ncases)

8365

for j=1:length(make_length_ncases)

8452

if numel(param.(make_length_ncases{j}))==1

8366

if numel(param.(make_length_ncases{j}))==1

8453

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8367

param.(make_length_ncases{j}) = param.(make_length_ncases{j})*ones(1,ncases);

8454

end

8368

end

8455

end

8369

end

8456

8370

8457

%Parameters that have length = length(ctle_gdc_values)

8371

%Parameters that have length = length(ctle_gdc_values)

8458

for j=1:length(make_length_GDC)

8372

for j=1:length(make_length_GDC)

8459

if numel(param.(make_length_GDC{j}))==1

8373

if numel(param.(make_length_GDC{j}))==1

8460

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8374

param.(make_length_GDC{j}) = param.(make_length_GDC{j})*ones(size(param.ctle_gdc_values));

8461

end

8375

end

8462

end

8376

end

8463

8377

8464

%Parameters that have length = length(g_DC_HP_values)

8378

%Parameters that have length = length(g_DC_HP_values)

8465

for j=1:length(make_length_DCHP)

8379

for j=1:length(make_length_DCHP)

8466

if numel(param.(make_length_DCHP{j}))==1

8380

if numel(param.(make_length_DCHP{j}))==1

8467

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8381

param.(make_length_DCHP{j}) = param.(make_length_DCHP{j})*ones(size(param.g_DC_HP_values));

8468

end

8382

end

8469

end

8383

end

8470

8384

8471

%Parameters that have length associated with PORTZ_mult

8385

%Parameters that have length associated with PORTZ_mult

8472

for j=1:length(make_length_WCPORTZ)

8386

for j=1:length(make_length_WCPORTZ)

8473

if numel(param.(make_length_WCPORTZ{j}))==1

8387

if numel(param.(make_length_WCPORTZ{j}))==1

8474

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8388

param.(make_length_WCPORTZ{j}) = param.(make_length_WCPORTZ{j})*PORTZ_mult;

8475

end

8389

end

8476

end

8390

end

8477

function sgm = pdf2sgm(pdf)

8391

function sgm = pdf2sgm(pdf)

8478

avg = sum(pdf.x .* pdf.y);

8392

avg = sum(pdf.x .* pdf.y);

8479

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8393

sgm = sqrt(sum((pdf.x - avg).^2 .* pdf.y));

8480

% end yasuo patch

8394

% end yasuo patch

8481

8395

8482

8396

8483

%% adding tx packgage

8397

%% adding tx packgage

8484

function cdf=pdf_to_cdf(pdf)

8398

function cdf=pdf_to_cdf(pdf)

8485

8399

8486

%Transform PDF to CDF

8400

%Transform PDF to CDF

8487

%The CDF is natively calculated from negative-to-positive voltage.

8401

%The CDF is natively calculated from negative-to-positive voltage.

8488

%This only gives BER calculation for bottom eye. Need to also

8402

%This only gives BER calculation for bottom eye. Need to also

8489

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8403

%calculate a CDF of reversed PDF to get top eye. The final CDF is the

8490

%min of top and bottom CDF values.

8404

%min of top and bottom CDF values.

8491

%If only interested in one side, a simple cumsum on y is all that is needed.

8405

%If only interested in one side, a simple cumsum on y is all that is needed.

8492

8406

8493

cdf.yB=cumsum(pdf.y);

8407

cdf.yB=cumsum(pdf.y);

8494

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8408

cdf.yT=fliplr(cumsum(fliplr(pdf.y)));

8495

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8409

cdf.y=min([cdf.yB(:) cdf.yT(:)],[],2);

8496

cdf.x=pdf.x;

8410

cdf.x=pdf.x;

8497

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8411

function plot_bathtub_curves(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf,jitt_pdf, combined_interference_and_noise_pdf, bin_size)

8498

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8412

cursors = d_cpdf(bin_size,max_signal*[-1 1], [1 1]/2);

8499

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8413

signal_and_isi_pdf = conv_fct(cursors, sci_pdf);

8500

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8414

signal_and_xtalk_pdf = conv_fct(cursors, cci_pdf);

8501

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8415

signal_and_channel_noise_pdf = conv_fct(cursors, isi_and_xtalk_pdf);

8502

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8416

signal_and_system_noise_pdf = conv_fct(cursors, noise_pdf);

8503

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8417

signal_and_system_jitt_pdf = conv_fct(cursors, jitt_pdf);

8504

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8418

signal_and_total_noise_pdf = conv_fct(cursors, combined_interference_and_noise_pdf);

8505

%% Added by Bill Kirkland, June 14, 2017

8419

%% Added by Bill Kirkland, June 14, 2017

8506

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8420

cursors_l = cursors; cursors_l.y(cursors_l.x>0) = 0;

8507

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8421

cursors_r = cursors; cursors_r.y(cursors_r.x<0) = 0;

8508

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8422

signal_and_total_noise_pdf_l = conv_fct(cursors_l, combined_interference_and_noise_pdf);

8509

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8423

signal_and_total_noise_pdf_r = conv_fct(cursors_r, combined_interference_and_noise_pdf);

8510

8424

8511

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8425

semilogy(signal_and_isi_pdf.x, abs(cumsum(signal_and_isi_pdf.y)-0.5) ,'r','Disp','ISI', 'parent', hax)

8512

hold on

8426

hold on

8513

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8427

semilogy(signal_and_xtalk_pdf.x, abs(cumsum(signal_and_xtalk_pdf.y)-0.5) ,'b','Disp','Xtalk', 'parent', hax)

8514

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8428

semilogy(signal_and_channel_noise_pdf.x, abs(cumsum(signal_and_channel_noise_pdf.y)-0.5) ,'c','Disp','ISI+Xtalk', 'parent', hax)

8515

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8429

semilogy(signal_and_system_noise_pdf.x, abs(cumsum(signal_and_system_noise_pdf.y)-0.5) ,'m','Disp','Jitter, SNR_TX,RL_M, eta_0 noise', 'parent', hax)

8516

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8430

semilogy(signal_and_system_jitt_pdf.x, abs(cumsum(signal_and_system_jitt_pdf.y)-0.5) ,'g','Disp','Jitter noise', 'parent', hax)

8517

8431

8518

%% Added by Bill Kirkland, June 14, 2017

8432

%% Added by Bill Kirkland, June 14, 2017

8519

% modification allows bathtub curves to cross over and hence one can

8433

% modification allows bathtub curves to cross over and hence one can

8520

% directly read the noise component.

8434

% directly read the noise component.

8521

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8435

%semilogy(signal_and_total_noise_pdf.x, abs(cumsum(signal_and_total_noise_pdf.y)-0.5) ,'k','Disp','total noise PDF', 'parent', hax)

8522

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8436

vbt_l = abs(0.5-cumsum(signal_and_total_noise_pdf_l.y));

8523

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8437

vbt_r = fliplr(0.5-(cumsum(fliplr(signal_and_total_noise_pdf_r.y))));

8524

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8438

semilogy(signal_and_total_noise_pdf_l.x, vbt_l ,'k','Disp','total noise PDF left', 'parent', hax)

8525

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8439

semilogy(signal_and_total_noise_pdf_r.x, vbt_r ,'k','Disp','total noise PDF right', 'parent', hax)

8526

8440

8527

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8441

hc=semilogy(max_signal*[-1 -1 1 1], [0.5 1e-20 1e-20 0.5], '--ok');

8528

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8442

set(get(get(hc,'Annotation'),'LegendInformation'), 'IconDisplayStyle','off');

8529

8443

8530

ylabel(hax, 'Probability')

8444

ylabel(hax, 'Probability')

8531

xlabel(hax, 'volts')

8445

xlabel(hax, 'volts')

8532

legend(hax, 'show')

8446

legend(hax, 'show')

8533

% testing code

8447

% testing code

8534

if 0

8448

if 0

8535

figure_name = 'COM curves';

8449

figure_name = 'COM curves';

8536

fig=findobj('Name', figure_name);

8450

fig=findobj('Name', figure_name);

8537

if isempty(fig), fig=figure('Name', figure_name); end

8451

if isempty(fig), fig=figure('Name', figure_name); end

8538

figure(fig);set(gcf,'Tag','COM');

8452

figure(fig);set(gcf,'Tag','COM');

8539

grid on

8453

grid on

8540

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8454

semilogy(db(max_signal./(signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','SNR CDF')

8541

hold on

8455

hold on

8542

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8456

semilogy(db(max_signal./(max_signal-signal_and_total_noise_pdf_r.x)), 2*vbt_r ,'Disp','COM CDF')

8543

ylim([ 1e-6 0.25])

8457

ylim([ 1e-6 0.25])

8544

xlim([0 30])

8458

xlim([0 30])

8545

grid on

8459

grid on

8546

end

8460

end

8547

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8461

function plot_pie_com(hax, max_signal, sci_pdf, cci_pdf, isi_and_xtalk_pdf, noise_pdf, combined_interference_and_noise_pdf, bin_size,param)

8548

BER=param.specBER;

8462

BER=param.specBER;

8549

delta_dB=param.delta_IL;

8463

delta_dB=param.delta_IL;

8550

8464

8551

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8465

iex.combined_interference_and_noise_pdf=find(abs(cumsum(combined_interference_and_noise_pdf.y))>= BER, 1, 'first');

8552

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8466

iex.noise_pdf=find(abs(cumsum(noise_pdf.y))>= BER, 1, 'first');

8553

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8467

iex.cci_pdf=find(abs(cumsum(cci_pdf.y))>= BER, 1, 'first');

8554

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8468

iex.sci_pdf=find(abs(cumsum(sci_pdf.y))>= BER, 1, 'first');

8555

8469

8556

8470

8557

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8471

maxn(1)=abs(sci_pdf.x(iex.sci_pdf));

8558

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8472

maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8559

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8473

maxn(3)=abs(cci_pdf.x(iex.cci_pdf));

8560

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8474

maxn_tot=abs(combined_interference_and_noise_pdf.x(iex.combined_interference_and_noise_pdf));

8561

8475

8562

COM=20*log10(max_signal/maxn_tot);

8476

COM=20*log10(max_signal/maxn_tot);

8563

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8477

COM_per_noise(1:3)=COM*(maxn(1:3).^2/sum(maxn.^2));

8564

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8478

COM_ISI=sprintf( '%.2g%%',100*COM_per_noise(1)/sum(COM_per_noise));

8565

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8479

COM_SYS=sprintf( '%.2g%%',100*COM_per_noise(2)/sum(COM_per_noise));

8566

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8480

COM_xtalk=sprintf('%.2g%%',100*COM_per_noise(3)/sum(COM_per_noise));

8567

8481

8568

pfctr=exp(-0.09054*delta_dB);% less loss

8482

pfctr=exp(-0.09054*delta_dB);% less loss

8569

mfctr=exp(0.09054*delta_dB); % more loss

8483

mfctr=exp(0.09054*delta_dB); % more loss

8570

8484

8571

%less loss

8485

%less loss

8572

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8486

plus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*pfctr;

8573

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8487

plus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8574

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8488

plus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*pfctr;

8575

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8489

% plus_maxn_tot=(maxn(1)*pfctr+maxn(2)+maxn(3)*pfctr)*maxn_tot/sum(plus_maxn);

8576

plus_maxn_tot=norm(plus_maxn);

8490

plus_maxn_tot=norm(plus_maxn);

8577

8491

8578

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8492

minus_maxn(1)=abs(sci_pdf.x(iex.sci_pdf))*mfctr;

8579

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8493

minus_maxn(2)=abs(noise_pdf.x(iex.noise_pdf));

8580

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8494

minus_maxn(3)=abs(cci_pdf.x(iex.cci_pdf))*mfctr;

8581

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8495

% minus_maxn_tot=(maxn(1)*mfctr+maxn(2)+maxn(3)*mfctr)*maxn_tot/sum(minus_maxn);

8582

minus_maxn_tot=norm(minus_maxn);

8496

minus_maxn_tot=norm(minus_maxn);

8583

8497

8584

% more loss

8498

% more loss

8585

COMp=20*log10(max_signal*pfctr/maxn_tot);

8499

COMp=20*log10(max_signal*pfctr/maxn_tot);

8586

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8500

COMp_per_noise(1:3)=COMp*(plus_maxn(1:3).^2/plus_maxn_tot^2);

8587

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8501

COMp_ISI=sprintf( '%.2gdB',COMp_per_noise(1));

8588

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8502

COMp_SYS=sprintf( '%.2gdB',COMp_per_noise(2));

8589

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8503

COMp_xtalk=sprintf('%.2gdB',COMp_per_noise(3));

8590

% less loss

8504

% less loss

8591

COMm=20*log10(max_signal*mfctr/maxn_tot);

8505

COMm=20*log10(max_signal*mfctr/maxn_tot);

8592

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8506

COMm_per_noise(1:3)=COMm*(minus_maxn(1:3).^2/minus_maxn_tot^2);

8593

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8507

COMm_ISI=sprintf( '%.2gdB',COMm_per_noise(1));

8594

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8508

COMm_SYS=sprintf( '%.2gdB',COMm_per_noise(2));

8595

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8509

COMm_xtalk=sprintf('%.2gdB',COMm_per_noise(3));

8596

8510

8597

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8511

xax=[[delta_dB delta_dB delta_dB];[ 0 0 0 ]; [ -delta_dB -delta_dB -delta_dB]];

8598

8512

8599

8513

8600

if(COM<0)

8514

if(COM<0)

8601

return

8515

return

8602

end

8516

end

8603

8517

8604

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8518

labels= { ['ISI ' COM_ISI] ['System noise/jitter ' COM_SYS] [' Crosstalk ' COM_xtalk]};

8605

8519

8606

% pie(COM_per_noise,labels)

8520

% pie(COM_per_noise,labels)

8607

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8521

% legend(labels,{'ISI COM','System noise/jitter COM','Crosstalk COM'});

8608

% legend('show','Location','bestoutside')

8522

% legend('show','Location','bestoutside')

8609

nullbar= [ 0 0 0 ];

8523

nullbar= [ 0 0 0 ];

8610

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8524

bar(xax,[nullbar ;COM_per_noise; nullbar],'stacked')

8611

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8525

% bar(xax,[COMp_per_noise;COM_per_noise;COMm_per_noise],'stacked')

8612

hold on

8526

hold on

8613

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8527

bar(xax,[[COMp 0 0 ];nullbar;nullbar],'stacked','w','barwidth',.5)

8614

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8528

bar(xax,[nullbar ;nullbar; [0 0 COMm]],'stacked','w','barwidth',.5)

8615

8529

8616

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8530

plot([-delta_dB,0, delta_dB], [param.pass_threshold ,param.pass_threshold ,param.pass_threshold ],'r')

8617

% ax=gca;

8531

% ax=gca;

8618

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8532

% ax.XTickLabels = {'decreasing loss','-','increasing loss'};

8619

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8533

set(gca,'XTickLabel', {'decreasing loss','-','increasing loss'})

8620

grid on

8534

grid on

8621

legend(labels,'Location','north')

8535

legend(labels,'Location','north')

8622

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8536

xlabel(['if loss is changed by ' sprintf('%.2gdB',delta_dB) ])

8623

ylabel('COM (dB)')

8537

ylabel('COM (dB)')

8624

hold off

8538

hold off

8625

8539

8626

8540

8627

8541

8628

8542

8629

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8543

function [chdata, param] = process_sxp(param, OP, chdata, SDDch)

8630

num_files=length(chdata);

8544

num_files=length(chdata);

8631

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8545

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8632

for i=1:num_files

8546

for i=1:num_files

8633

if param.package_testcase_i==1 && i==1

8547

if param.package_testcase_i==1 && i==1

8634

if OP.TDR && i==1

8548

if OP.TDR && i==1

8635

S.Frequencies=chdata(i).faxis;

8549

S.Frequencies=chdata(i).faxis;

8636

S.Impedance=100;

8550

S.Impedance=100;

8637

if ~OP.SHOW_BRD

8551

if ~OP.SHOW_BRD

8638

Sfield='_orig';

8552

Sfield='_orig';

8639

else

8553

else

8640

Sfield='_raw';

8554

Sfield='_raw';

8641

end

8555

end

8642

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8556

S.Parameters(1,1,:)=chdata(i).(['sdd11' Sfield]) ;

8643

if ~param.FLAG.S2P

8557

if ~param.FLAG.S2P

8644

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8558

S.Parameters(1,2,:)=chdata(i).(['sdd12' Sfield]) ;

8645

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8559

S.Parameters(2,1,:)=chdata(i).(['sdd21' Sfield]) ;

8646

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8560

S.Parameters(2,2,:)=chdata(i).(['sdd22' Sfield]) ;

8647

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8561

S.NumPorts=2; % rim 2/26/2019 correct from S.NumPorts=4;

8648

else

8562

else

8649

S.NumPorts=1;

8563

S.NumPorts=1;

8650

end

8564

end

8651

if OP.TDR_W_TXPKG

8565

if OP.TDR_W_TXPKG

8652

if OP.ERL == 2

8566

if OP.ERL == 2

8653

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8567

error('Cannot add pacakge to s2p files. ERL==2 not supportted if TDR_W_TXPKG = 1')

8654

end

8568

end

8655

R_diepad = param.R_diepad;

8569

R_diepad = param.R_diepad;

8656

% RX package length is assumed to be the same for all

8570

% RX package length is assumed to be the same for all

8657

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8571

% channel types. swap Cp and Cd for Tx. TDR_W_TXPKG only

8658

% for Rx pkg

8572

% for Rx pkg

8659

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8573

[ s11in, s12in, s21in, s22in]=make_full_pkg('TX',S.Frequencies,param,'THRU');

8660

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8574

[ S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:)] = ...

8661

combines4p( s11in, s12in, s21in, s22in, ...

8575

combines4p( s11in, s12in, s21in, s22in, ...

8662

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8576

S.Parameters(1,1,:), S.Parameters(1,2,:), S.Parameters(2,1,:), S.Parameters(2,2,:) );

8663

% S=sparameters(S.Parameters,S.Frequencies,100);

8577

% S=sparameters(S.Parameters,S.Frequencies,100);

8664

S=SL(S,S.Frequencies,R_diepad(1)*2);

8578

S=SL(S,S.Frequencies,R_diepad(1)*2);

8665

chdata(i).TX_RL=S.Parameters(2,2,:);

8579

chdata(i).TX_RL=S.Parameters(2,2,:);

8666

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8580

S.Parameters(1,1,:)=chdata(i).sdd11_orig; % when looking at Tx don't include package

8667

end

8581

end

8668

8582

8669

% need to combine S wiht is page and channel

8583

% need to combine S wiht is page and channel

8670

if param.FLAG.S2P

8584

if param.FLAG.S2P

8671

port_sel=1;

8585

port_sel=1;

8672

else

8586

else

8673

port_sel=[1 2];

8587

port_sel=[1 2];

8674

if OP.AUTO_TFX

8588

if OP.AUTO_TFX

8675

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8589

[ fir4del, tu] =get_RAW_FIR(squeeze(chdata(i).sdd12_orig),S.Frequencies,OP,param);

8676

pix=find(fir4del==max(fir4del),1);

8590

pix=find(fir4del==max(fir4del),1);

8677

param.tfx(2)=2*tu(pix);

8591

param.tfx(2)=2*tu(pix);

8678

end

8592

end

8679

end

8593

end

8680

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8594

OP.impulse_response_truncation_threshold=1e-5; %Only for TDR not returned out of "process_sxp" function

8681

for ipsl=1:length(port_sel) % do for both port if s4p

8595

for ipsl=1:length(port_sel) % do for both port if s4p

8682

for izt=1:length(param.Z_t) % do for all tdr impedances

8596

for izt=1:length(param.Z_t) % do for all tdr impedances

8683

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8597

param.RL_sel=port_sel(ipsl); % this used in get_TDR

8684

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8598

% OP.interp_sparam_phase='interp_to_DC'; % better for return loss

8685

% OP.interp_sparam_mag='trend_to_DC';

8599

% OP.interp_sparam_mag='trend_to_DC';

8686

OP.interp_sparam_mag='linear_trend_to_DC';

8600

OP.interp_sparam_mag='linear_trend_to_DC';

8687

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8601

% OP.interp_sparam_mag='extrap_to_DC_or_zero';

8688

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8602

OP.interp_sparam_phase='extrap_cubic_to_dc_linear_to_inf';

8689

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8603

TDR_results(izt,ipsl) = get_TDR(S, OP, param,param.Z_t(izt),ipsl);

8690

if ipsl ==1

8604

if ipsl ==1

8691

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8605

chdata(i).TDR11(izt).ZSR=[TDR_results(izt,1).tdr];

8692

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8606

chdata(i).TDR11(izt).t=TDR_results(izt,1).t;

8693

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8607

chdata(i).TDR11(izt).avgZport=[TDR_results(izt,1).avgZport];

8694

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8608

if OP.PTDR, chdata(i).PDTR11(izt).ptdr=TDR_results(izt,1).ptdr_RL;end

8695

else

8609

else

8696

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8610

chdata(i).TDR22(izt).ZSR=[TDR_results(izt,2).tdr];

8697

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8611

chdata(i).TDR22(izt).t=TDR_results(izt,2).t;

8698

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8612

chdata(i).TDR22(izt).avgZport=[TDR_results(izt,2).avgZport];

8699

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8613

if OP.PTDR, chdata(i).PDTR22(izt).ptdr=TDR_results(izt,2).ptdr_RL;end

8700

end

8614

end

8701

if OP.PTDR && i==1

8615

if OP.PTDR && i==1

8702

if ipsl ==1

8616

if ipsl ==1

8703

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8617

chdata(i).TDR11(izt).ERL=[TDR_results(izt,1).ERL];

8704

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8618

chdata(i).TDR11(izt).ERLRMS=[TDR_results(izt,1).ERLRMS];

8705

else

8619

else

8706

if ~param.FLAG.S2P

8620

if ~param.FLAG.S2P

8707

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8621

chdata(i).TDR22(izt).ERL=[TDR_results(izt,2).ERL];

8708

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8622

chdata(i).TDR22(izt).ERLRMS=[TDR_results(izt,2).ERLRMS];

8709

else

8623

else

8710

chdata(i).TDR22(izt).ERL=[];

8624

chdata(i).TDR22(izt).ERL=[];

8711

chdata(i).TDR22(izt).ERLRMS=[];

8625

chdata(i).TDR22(izt).ERLRMS=[];

8712

end

8626

end

8713

end

8627

end

8714

else

8628

else

8715

chdata(i).TDR11(izt).ERL=[];

8629

chdata(i).TDR11(izt).ERL=[];

8716

chdata(i).TDR22(izt).ERL=[];

8630

chdata(i).TDR22(izt).ERL=[];

8717

chdata(i).TDR11(izt).ERLRMS=[];

8631

chdata(i).TDR11(izt).ERLRMS=[];

8718

chdata(i).TDR22(izt).ERLRMS=[];

8632

chdata(i).TDR22(izt).ERLRMS=[];

8719

end

8633

end

8720

end

8634

end

8721

end

8635

end

8722

end

8636

end

8723

8637

8724

end

8638

end

8725

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8639

if OP.DISPLAY_WINDOW && OP.DEBUG && OP.TDR

8726

h=figure(180);set(gcf,'Tag','COM');

8640

h=figure(180);set(gcf,'Tag','COM');

8727

if param.package_testcase_i==1 && i == 1

8641

if param.package_testcase_i==1 && i == 1

8728

if i==1

8642

if i==1

8729

htabgroup = uitabgroup(h);

8643

htabgroup = uitabgroup(h);

8730

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8644

htab1 = uitab(htabgroup, 'Title', 'TDR TX');

8731

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8645

htab3 = uitab(htabgroup, 'Title', 'PTDR TX');

8732

hax1 = axes('Parent', htab1);

8646

hax1 = axes('Parent', htab1);

8733

hax3 = axes('Parent', htab3);

8647

hax3 = axes('Parent', htab3);

8734

if ~param.FLAG.S2P

8648

if ~param.FLAG.S2P

8735

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8649

htab2 = uitab(htabgroup, 'Title', 'TDR RX');

8736

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8650

htab4 = uitab(htabgroup, 'Title', 'PTDR RX');

8737

hax2 = axes('Parent', htab2);

8651

hax2 = axes('Parent', htab2);

8738

hax4 = axes('Parent', htab4);

8652

hax4 = axes('Parent', htab4);

8739

end

8653

end

8740

end

8654

end

8741

set(h,'CurrentAxes',hax1)

8655

set(h,'CurrentAxes',hax1)

8742

hold on

8656

hold on

8743

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8657

plot(chdata(i).TDR11(izt).t(:),chdata(i).TDR11(izt).ZSR,'disp',[ chdata(i).base ' Tx port']);

8744

hold off

8658

hold off

8745

legend (hax1, 'off');grid on;zoom xon;

8659

legend (hax1, 'off');grid on;zoom xon;

8746

set(legend (hax1, 'show'), 'interp', 'none');

8660

set(legend (hax1, 'show'), 'interp', 'none');

8747

8661

8748

if ~param.FLAG.S2P

8662

if ~param.FLAG.S2P

8749

set(h,'CurrentAxes',hax2)

8663

set(h,'CurrentAxes',hax2)

8750

hold on

8664

hold on

8751

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8665

plot(chdata(i).TDR22(izt).t(:),chdata(i).TDR22(izt).ZSR,'disp',[ chdata(i).base ' Rx port']);

8752

hold off

8666

hold off

8753

legend (hax2, 'off');grid on;zoom xon;

8667

legend (hax2, 'off');grid on;zoom xon;

8754

set(legend (hax2, 'show'), 'interp', 'none');

8668

set(legend (hax2, 'show'), 'interp', 'none');

8755

end

8669

end

8756

8670

8757

set(h,'CurrentAxes',hax3)

8671

set(h,'CurrentAxes',hax3)

8758

hold on

8672

hold on

8759

if OP.PTDR

8673

if OP.PTDR

8760

for izt=1:length(param.Z_t)

8674

for izt=1:length(param.Z_t)

8761

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8675

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR11(izt).ERL, 3) 'db'];

8762

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8676

plot(chdata(i).TDR11(izt).t/param.ui,chdata(i).PDTR11(izt).ptdr,'disp',msg);

8763

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8677

msg=['PTDR Zt=' num2str(param.Z_t(izt)/param.ui,3) ' worst sampled noise cursors ' 'Tx port Zt=' num2str(param.Z_t(izt),3) ];

8764

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8678

stem(TDR_results(izt,1).WC_ptdr_samples_t/param.ui,TDR_results(izt,1).WC_ptdr_samples,'disp',msg);

8765

end

8679

end

8766

end

8680

end

8767

hold off

8681

hold off

8768

legend (hax3, 'off');grid on;zoom xon;

8682

legend (hax3, 'off');grid on;zoom xon;

8769

set(legend (hax3, 'show'), 'interp', 'none');

8683

set(legend (hax3, 'show'), 'interp', 'none');

8770

if ~param.FLAG.S2P

8684

if ~param.FLAG.S2P

8771

set(h,'CurrentAxes',hax4)

8685

set(h,'CurrentAxes',hax4)

8772

hold on

8686

hold on

8773

if OP.PTDR

8687

if OP.PTDR

8774

for izt=1:length(param.Z_t)

8688

for izt=1:length(param.Z_t)

8775

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8689

msg=[ chdata(i).base ' Tx port Zt=' num2str(param.Z_t(izt),3) ' ERL=', num2str(chdata(i).TDR22(izt).ERL, 3) 'db'];

8776

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8690

plot(chdata(i).TDR22(izt).t/param.ui,chdata(i).PDTR22(izt).ptdr,'disp',msg);

8777

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8691

msg=['PTDR Zt=' num2str(param.Z_t(izt),3)/param.ui ' worst sampled noise cursors ' 'Rx port Zt=' num2str(param.Z_t(izt),3) ];

8778

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8692

stem(TDR_results(izt,2).WC_ptdr_samples_t/param.ui,TDR_results(izt,2).WC_ptdr_samples,'disp',msg);

8779

end

8693

end

8780

end

8694

end

8781

hold off

8695

hold off

8782

legend (hax4, 'off');grid on;zoom xon;

8696

legend (hax4, 'off');grid on;zoom xon;

8783

set(legend (hax4, 'show'), 'interp', 'none');

8697

set(legend (hax4, 'show'), 'interp', 'none');

8784

end

8698

end

8785

end

8699

end

8786

end

8700

end

8787

if param.FLAG.S2P, return; end

8701

if param.FLAG.S2P, return; end

8788

end

8702

end

8789

function S =r_parrelell2(zref,f,rpad)

8703

function S =r_parrelell2(zref,f,rpad)

8790

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8704

S.Parameters(1,1,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8791

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8705

S.Parameters(2,2,:) = -zref/(rpad*(zref/rpad + 2)).*ones(1,length(f));

8792

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8706

S.Parameters(2,1,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8793

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8707

S.Parameters(1,2,:) = 2/(zref/rpad + 2).*ones(1,length(f));

8794

% Sm=sparameters(S.Parameters,f,zref);

8708

% Sm=sparameters(S.Parameters,f,zref);

8795

8709

8796

8710

8797

8711

8798

8712

8799

8713

8800

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8714

function [sch,schFreqAxis]=read_Nport_touchstone(touchstone_file,port_order)

8801

8715

8802

%touchstone_file: .sNp touchstone file to read

8716

%touchstone_file: .sNp touchstone file to read

8803

%port_order: port reorder vector

8717

%port_order: port reorder vector

8804

%

8718

%

8805

%sch: sparameter matrix

8719

%sch: sparameter matrix

8806

%schFreqAxis: frequency axis

8720

%schFreqAxis: frequency axis

8807

8721

8808

[file_path,root_name,extension]=fileparts(touchstone_file);

8722

[file_path,root_name,extension]=fileparts(touchstone_file);

8809

fid=fopen(touchstone_file);

8723

fid=fopen(touchstone_file);

8810

8724

8811

%fetch number of ports from extension

8725

%fetch number of ports from extension

8812

num_ports=str2num(char(regexp(extension,'\d*','match')));

8726

num_ports=str2num(char(regexp(extension,'\d*','match')));

8813

8727

8814

%Get option line

8728

%Get option line

8815

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8729

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8816

optcell=textscan(optstr{1}{1},'%s');

8730

optcell=textscan(optstr{1}{1},'%s');

8817

optcell=optcell{1};

8731

optcell=optcell{1};

8818

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8732

while isempty(optcell) || isempty(strfind(optcell{1},'#'))

8819

%Some touchstone files need this. can't remember why now. maybe lines

8733

%Some touchstone files need this. can't remember why now. maybe lines

8820

%with whitespace but not empty but not commented

8734

%with whitespace but not empty but not commented

8821

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8735

[optstr,opt_pos] = textscan(fid,'%s',1,'Delimiter','','CommentStyle','!');

8822

optcell=textscan(optstr{1}{1},'%s');

8736

optcell=textscan(optstr{1}{1},'%s');

8823

optcell=optcell{1};

8737

optcell=optcell{1};

8824

end

8738

end

8825

8739

8826

%read the entire file

8740

%read the entire file

8827

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8741

raw_read_data = textscan(fid,'%f %f %f %f %f %f %f %f %f','CollectOutput',true,'CommentStyle','!');

8828

raw_column_data=raw_read_data{1};

8742

raw_column_data=raw_read_data{1};

8829

fclose(fid);

8743

fclose(fid);

8830

8744

8831

%number of columns for 2D matrix

8745

%number of columns for 2D matrix

8832

columns=num_ports*num_ports*2+1;

8746

columns=num_ports*num_ports*2+1;

8833

8747

8834

%find the frequency lines by searching for the right number of NaN

8748

%find the frequency lines by searching for the right number of NaN

8835

a=sum(isnan(raw_column_data),2);

8749

a=sum(isnan(raw_column_data),2);

8836

if num_ports==3

8750

if num_ports==3

8837

b=find(a==2);

8751

b=find(a==2);

8838

elseif num_ports==1

8752

elseif num_ports==1

8839

b=find(a==6);

8753

b=find(a==6);

8840

else

8754

else

8841

b=find(a==0);

8755

b=find(a==0);

8842

end

8756

end

8843

8757

8844

num_freq=length(b);

8758

num_freq=length(b);

8845

8759

8846

%toss out the NaN and reshape into a 2D matrix

8760

%toss out the NaN and reshape into a 2D matrix

8847

raw_input = raw_column_data.';

8761

raw_input = raw_column_data.';

8848

raw_input = raw_input(~isnan(raw_input));

8762

raw_input = raw_input(~isnan(raw_input));

8849

raw_input = reshape(raw_input,columns,num_freq).';

8763

raw_input = reshape(raw_input,columns,num_freq).';

8850

8764

8851

%get the frequency mult

8765

%get the frequency mult

8852

frequency_mult_text=optcell{2};

8766

frequency_mult_text=optcell{2};

8853

if(strcmpi(frequency_mult_text,'hz'))

8767

if(strcmpi(frequency_mult_text,'hz'))

8854

frequency_mult=1;

8768

frequency_mult=1;

8855

elseif(strcmpi(frequency_mult_text,'khz'))

8769

elseif(strcmpi(frequency_mult_text,'khz'))

8856

frequency_mult=1e3;

8770

frequency_mult=1e3;

8857

elseif(strcmpi(frequency_mult_text,'mhz'))

8771

elseif(strcmpi(frequency_mult_text,'mhz'))

8858

frequency_mult=1e6;

8772

frequency_mult=1e6;

8859

elseif(strcmpi(frequency_mult_text,'ghz'))

8773

elseif(strcmpi(frequency_mult_text,'ghz'))

8860

frequency_mult=1e9;

8774

frequency_mult=1e9;

8861

else

8775

else

8862

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8776

error('Unsupported format for frequency multiplier %s',frequency_mult_text);

8863

end

8777

end

8864

8778

8865

%get the RI/MA/DB format

8779

%get the RI/MA/DB format

8866

format=optcell{4};

8780

format=optcell{4};

8867

%get Z0

8781

%get Z0

8868

port_impedance=str2double(optcell(6:end))';

8782

port_impedance=str2double(optcell(6:end))';

8869

8783

8870

8784

8871

%grab frequency

8785

%grab frequency

8872

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8786

raw_input(:,1)=raw_input(:,1)*frequency_mult;

8873

Spar.F=raw_input(:,1);

8787

Spar.F=raw_input(:,1);

8874

Spar.F=transpose(Spar.F(:));

8788

Spar.F=transpose(Spar.F(:));

8875

8789

8876

8790

8877

%transform data to real imaginary

8791

%transform data to real imaginary

8878

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8792

%for 2.0 support, keep it in 2D form instead of 3D because we may need to process upper/lower sparse matrix definitions

8879

if(strcmpi(format,'ri'))

8793

if(strcmpi(format,'ri'))

8880

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8794

ri_data_2D=raw_input(:,2:2:end)+raw_input(:,3:2:end)*1i;

8881

elseif(strcmpi(format,'ma'))

8795

elseif(strcmpi(format,'ma'))

8882

mag_data=raw_input(:,2:2:end);

8796

mag_data=raw_input(:,2:2:end);

8883

rad_data=raw_input(:,3:2:end)*pi/180;

8797

rad_data=raw_input(:,3:2:end)*pi/180;

8884

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8798

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8885

elseif(strcmpi(format,'db'))

8799

elseif(strcmpi(format,'db'))

8886

mag_data=10.^(raw_input(:,2:2:end)/20);

8800

mag_data=10.^(raw_input(:,2:2:end)/20);

8887

rad_data=raw_input(:,3:2:end)*pi/180;

8801

rad_data=raw_input(:,3:2:end)*pi/180;

8888

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8802

ri_data_2D=mag_data.*cos(rad_data)+mag_data.*sin(rad_data)*1i;

8889

else

8803

else

8890

error('Format %s is not supported. Use RI MA or DB',format);

8804

error('Format %s is not supported. Use RI MA or DB',format);

8891

end

8805

end

8892

8806

8893

8807

8894

8808

8895

%transform to 3D

8809

%transform to 3D

8896

%allow for upper/lower matrix specification for touchstone 2.0 support

8810

%allow for upper/lower matrix specification for touchstone 2.0 support

8897

matrix_format=0;

8811

matrix_format=0;

8898

if(matrix_format==0)

8812

if(matrix_format==0)

8899

%full

8813

%full

8900

for j=1:num_ports

8814

for j=1:num_ports

8901

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8815

pre_out.sp(j,1:num_ports,:)=transpose(ri_data_2D( :,(j-1)*num_ports+1:j*num_ports));

8902

end

8816

end

8903

elseif(matrix_format==1)

8817

elseif(matrix_format==1)

8904

%upper

8818

%upper

8905

used_ports=0;

8819

used_ports=0;

8906

for j=1:num_ports

8820

for j=1:num_ports

8907

stated_ports=num_ports-j+1;

8821

stated_ports=num_ports-j+1;

8908

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8822

pre_out.sp(j,j:num_ports,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8909

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8823

pre_out.sp(j:num_ports,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8910

used_ports=used_ports+stated_ports;

8824

used_ports=used_ports+stated_ports;

8911

end

8825

end

8912

elseif(matrix_format==2)

8826

elseif(matrix_format==2)

8913

%lower

8827

%lower

8914

used_ports=0;

8828

used_ports=0;

8915

for j=1:num_ports

8829

for j=1:num_ports

8916

stated_ports=j;

8830

stated_ports=j;

8917

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8831

pre_out.sp(j,1:j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8918

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8832

pre_out.sp(1:j,j,:)=transpose(ri_data_2D( :,used_ports+1:used_ports+stated_ports));

8919

used_ports=used_ports+stated_ports;

8833

used_ports=used_ports+stated_ports;

8920

end

8834

end

8921

else

8835

else

8922

error('Matrix format is not supported. Use Full, Lower, or Upper');

8836

error('Matrix format is not supported. Use Full, Lower, or Upper');

8923

end

8837

end

8924

8838

8925

8839

8926

%check for swapping the 2 port matrix (required on 1.x spec)

8840

%check for swapping the 2 port matrix (required on 1.x spec)

8927

two_port_swap=1;

8841

two_port_swap=1;

8928

if(num_ports==2 && two_port_swap==1)

8842

if(num_ports==2 && two_port_swap==1)

8929

temp=pre_out.sp(1,2,:);

8843

temp=pre_out.sp(1,2,:);

8930

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8844

pre_out.sp(1,2,:)=pre_out.sp(2,1,:);

8931

pre_out.sp(2,1,:)=temp;

8845

pre_out.sp(2,1,:)=temp;

8932

end

8846

end

8933

8847

8934

Spar.S=pre_out.sp;

8848

Spar.S=pre_out.sp;

8935

Spar.Z0=transpose(port_impedance(:));

8849

Spar.Z0=transpose(port_impedance(:));

8936

8850

8937

if length(Spar.Z0)>1

8851

if length(Spar.Z0)>1

8938

error('Each port must have the same reference impedance');

8852

error('Each port must have the same reference impedance');

8939

end

8853

end

8940

if ~isequal(Spar.Z0,50)

8854

if ~isequal(Spar.Z0,50)

8941

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8855

warning('Reference impedance of %0.6g ohms renormalized to 50 ohms',Spar.Z0);

8942

%Renormalize to 50 ohms

8856

%Renormalize to 50 ohms

8943

rho=(50-Spar.Z0)/(50+Spar.Z0);

8857

rho=(50-Spar.Z0)/(50+Spar.Z0);

8944

p=num_ports;

8858

p=num_ports;

8945

s_old=Spar.S;

8859

s_old=Spar.S;

8946

for k=1:num_freq

8860

for k=1:num_freq

8947

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8861

Spar.S(:,:,k)=inv(eye(p,p)-rho*s_old(:,:,k))*(s_old(:,:,k)-rho*eye(p,p));

8948

end

8862

end

8949

end

8863

end

8950

8864

8951

%These operations sync up with COM style Spar matrix

8865

%These operations sync up with COM style Spar matrix

8952

%1: put frequency as first dimension

8866

%1: put frequency as first dimension

8953

sch=shiftdim(Spar.S,2);

8867

sch=shiftdim(Spar.S,2);

8954

%2: reorder ports according to "ports" input

8868

%2: reorder ports according to "ports" input

8955

sch=sch(:,port_order,port_order);

8869

sch=sch(:,port_order,port_order);

8956

schFreqAxis=Spar.F;

8870

schFreqAxis=Spar.F;

8957

function [chdata, param] = read_PR_files(param, OP, chdata)

8871

function [chdata, param] = read_PR_files(param, OP, chdata)

8958

%% Read in pulse response

8872

%% Read in pulse response

8959

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8873

% extract s-parameter data from files and apply tx and rx filters as well as package filters

8960

num_files=length(chdata);

8874

num_files=length(chdata);

8961

M=param.samples_per_ui;

8875

M=param.samples_per_ui;

8962

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8876

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

8963

for i=1:num_files

8877

for i=1:num_files

8964

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8878

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

8965

progress = i/num_files;

8879

progress = i/num_files;

8966

if OP.DISPLAY_WINDOW

8880

if OP.DISPLAY_WINDOW

8967

[~,a]=fileparts(chdata(i).filename);

8881

[~,a]=fileparts(chdata(i).filename);

8968

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8882

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

8969

else

8883

else

8970

fprintf('%i ',i);

8884

fprintf('%i ',i);

8971

end

8885

end

8972

switch chdata(i).ext

8886

switch chdata(i).ext

8973

case '.csv'

8887

case '.csv'

8974

vt=load(chdata(i).filename);

8888

vt=load(chdata(i).filename);

8975

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8889

% many PR's need to have precursors added: we'll a 2 here RIM 5-24-2021

8976

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8890

chdata(i).uneq_pulse_response=[ zeros(3*param.samples_per_ui, 1) ; vt(:,2) ];

8977

dt=vt(2,1)-vt(1,1);

8891

dt=vt(2,1)-vt(1,1);

8978

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8892

chdata(i).t= [ (0:3*param.samples_per_ui-1).'*dt ; vt(:,1)+3*param.samples_per_ui*dt];

8979

8893

8980

8894

8981

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8895

step_shifting_vector=kron(ones(1,floor(length( chdata(i).uneq_pulse_response)/M)) ,[ 1 zeros(1,M-1) ]) ;

8982

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8896

step_response=filter(step_shifting_vector,1,chdata(i).uneq_pulse_response);

8983

Vf=step_response(end);

8897

Vf=step_response(end);

8984

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8898

chdata(i).uneq_imp_response=step_response-circshift(step_response,1); % too noisey to be usefull

8985

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8899

chdata(i).uneq_imp_response(1)=chdata(i).uneq_imp_response(2);

8986

8900

8987

end

8901

end

8988

end

8902

end

8989

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8903

function [param,OP]= read_ParamConfigFile(paramFile,OP)

8990

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8904

%warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8991

[filepath,name,ext] = fileparts(paramFile);

8905

[filepath,name,ext] = fileparts(paramFile);

8992

if ~isempty(filepath)

8906

if ~isempty(filepath)

8993

filepath=[filepath '\'];

8907

filepath=[filepath '\'];

8994

end

8908

end

8995

matcongfile=[filepath name '.mat'];

8909

matcongfile=[filepath name '.mat'];

8996

try

8910

try

8997

switch upper(ext)

8911

switch upper(ext)

8998

case upper('.mat')

8912

case upper('.mat')

8999

load(matcongfile)

8913

load(matcongfile)

9000

case upper('.csv')

8914

case upper('.csv')

9001

[na1, na2, parameter] = xlsread(paramFile);

8915

[na1, na2, parameter] = xlsread(paramFile);

9002

otherwise

8916

otherwise

9003

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8917

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','',''); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9004

end

8918

end

9005

8919

9006

catch ME %#ok<NASGU>

8920

catch ME %#ok<NASGU>

9007

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

8921

warning('off','MATLAB:xlsread:Mode'); % suppress warning messages for reading the settings file from XLS

9008

switch upper(ext)

8922

switch upper(ext)

9009

case upper('.mat')

8923

case upper('.mat')

9010

load(matcongfile)

8924

load(matcongfile)

9011

case upper('.csv')

8925

case upper('.csv')

9012

[na1, na2, parameter] = xlsread(paramFile);

8926

[na1, na2, parameter] = xlsread(paramFile);

9013

otherwise

8927

otherwise

9014

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

8928

[na1, na2, parameter] = xlsread(paramFile,'COM_Settings','','basic'); %#ok<ASGLU> % Import data from the settings file (imports the entire sheet)

9015

end

8929

end

9016

end

8930

end

9017

8931

9018

%% New section to parse .START package data

8932

%% New section to parse .START package data

9019

first_column_data = parameter(:,1);

8933

first_column_data = parameter(:,1);

9020

start_data_rows = find(strcmp(first_column_data,'.START'));

8934

start_data_rows = find(strcmp(first_column_data,'.START'));

9021

if ~isempty(start_data_rows)

8935

if ~isempty(start_data_rows)

9022

end_data_rows = find(strcmp(first_column_data,'.END'));

8936

end_data_rows = find(strcmp(first_column_data,'.END'));

9023

if length(start_data_rows) ~= length(end_data_rows)

8937

if length(start_data_rows) ~= length(end_data_rows)

9024

error('Number of .START and .END must be the same');

8938

error('Number of .START and .END must be the same');

9025

end

8939

end

9026

first_start_row = start_data_rows(1);

8940

first_start_row = start_data_rows(1);

9027

special_parameter = parameter;

8941

special_parameter = parameter;

9028

parameter = parameter(1:first_start_row-1,:);

8942

parameter = parameter(1:first_start_row-1,:);

9029

for j=1:length(start_data_rows)

8943

for j=1:length(start_data_rows)

9030

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

8944

this_block = special_parameter(start_data_rows(j)+1:end_data_rows(j)-1,:);

9031

pkg_name = special_parameter{start_data_rows(j),2};

8945

pkg_name = special_parameter{start_data_rows(j),2};

9032

8946

9033

%Read all the parameters that make up a package

8947

%Read all the parameters that make up a package

9034

PKG_param = read_package_parameters(this_block);

8948

PKG_param = read_package_parameters(this_block);

9035

8949

9036

%save the data in a field revealed by pkg_name

8950

%save the data in a field revealed by pkg_name

9037

param.PKG.(pkg_name) = PKG_param;

8951

param.PKG.(pkg_name) = PKG_param;

9038

8952

9039

8953

9040

end

8954

end

9041

end

8955

end

9042

%Allow specification of TX and RX package section through PKG_NAME keyword

8956

%Allow specification of TX and RX package section through PKG_NAME keyword

9043

%the values must match package blocks specified in .START sections

8957

%the values must match package blocks specified in .START sections

9044

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

8958

param.PKG_NAME= xls_parameter(parameter, 'PKG_NAME', false,'');

9045

if isnan(param.PKG_NAME)

8959

if isnan(param.PKG_NAME)

9046

param.PKG_NAME = '';

8960

param.PKG_NAME = '';

9047

end

8961

end

9048

if isempty(param.PKG_NAME)

8962

if isempty(param.PKG_NAME)

9049

param.PKG_NAME = {};

8963

param.PKG_NAME = {};

9050

else

8964

else

9051

param.PKG_NAME = strsplit(param.PKG_NAME);

8965

param.PKG_NAME = strsplit(param.PKG_NAME);

9052

end

8966

end

9053

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

8967

if ~isempty(param.PKG_NAME) && ~isfield(param,'PKG')

9054

error('PKG_NAME can only be used if .START blocks for package parameters are used');

8968

error('PKG_NAME can only be used if .START blocks for package parameters are used');

9055

end

8969

end

9056

for j=1:length(param.PKG_NAME)

8970

for j=1:length(param.PKG_NAME)

9057

if ~isfield(param.PKG,param.PKG_NAME{j})

8971

if ~isfield(param.PKG,param.PKG_NAME{j})

9058

error('Package Block "%s" not found',param.PKG_NAME{j});

8972

error('Package Block "%s" not found',param.PKG_NAME{j});

9059

end

8973

end

9060

end

8974

end

9061

8975

9062

%%

8976

%%

9063

% just need to define so we can pass

8977

% just need to define so we can pass

9064

param.c=[.4e-12 .4e-12];

8978

param.c=[.4e-12 .4e-12];

9065

param.alen=[ 20 30 550 ];

8979

param.alen=[ 20 30 550 ];

9066

param.az=[100 120 100];

8980

param.az=[100 120 100];

9067

8981

9068

% make control for package/channel reflection control

8982

% make control for package/channel reflection control

9069

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

8983

param.kappa1= xls_parameter(parameter, 'kappa1', true,1); % if set 0 reflection at tp0 are omitted from COM

9070

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

8984

param.kappa2= xls_parameter(parameter, 'kappa2', true,1); % if set 0 reflection at tp5 are omitted from COM

9071

8985

9072

8986

9073

% make compatible with presentation of kappa

8987

% make compatible with presentation of kappa

9074

8988

9075

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

8989

% Default values are given for parameters when they are common to all clauses in 802.3bj and 803.2bm.

9076

8990

9077

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

8991

OP.dynamic_txffe = xls_parameter(parameter, 'Dynamic TXFFE', false,1); % Temporary switch for testing new optimize_fom with dynamic txffe

9078

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

8992

OP.FloatingDFE_Development = xls_parameter(parameter, 'FloatingDFE_Development', false,1); % Temporary switch for testing new floating dfe routine

9079

8993

9080

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

8994

param.fb = xls_parameter(parameter, 'f_b')*1e9; % Baud (Signaling) rate in Gbaud

9081

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

8995

param.f2 = xls_parameter(parameter, 'f_2', true, param.fb/1e9 )*1e9; % frequency in GHz for intergration compuation of ICN or FOM_Ild in GHz

9082

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

8996

param.max_start_freq = xls_parameter(parameter, 'f_min')*1e9; % minimum required frequency start for s parameters

9083

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

8997

param.f1 = xls_parameter(parameter, 'f_1', true, param.max_start_freq/1e9)*1e9; % start frequency for ICN and ILD calculations in GHz

9084

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

8998

param.max_freq_step = xls_parameter(parameter, 'Delta_f')*1e9; % freqency step

9085

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

8999

param.tx_ffe_c0_min = xls_parameter(parameter, 'c(0)', false); % TX equalizer cursor minimum value (actual value is calculated as 1-sum(abs(tap)), Grid seat ingored for when C(0) is below this value

9086

9000

9087

if OP.dynamic_txffe

9001

if OP.dynamic_txffe

9088

found_pre=1;

9002

found_pre=1;

9089

pre_count=1;

9003

pre_count=1;

9090

while found_pre

9004

while found_pre

9091

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9005

[p,found_pre]=xls_parameter_txffe(parameter,sprintf('c(-%d)',pre_count));

9092

if found_pre

9006

if found_pre

9093

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9007

field_name=sprintf('tx_ffe_cm%d_values',pre_count);

9094

param.(field_name)=p;

9008

param.(field_name)=p;

9095

pre_count=pre_count+1;

9009

pre_count=pre_count+1;

9096

end

9010

end

9097

end

9011

end

9098

found_post=1;

9012

found_post=1;

9099

post_count=1;

9013

post_count=1;

9100

while found_post

9014

while found_post

9101

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9015

[p,found_post]=xls_parameter_txffe(parameter,sprintf('c(%d)',post_count));

9102

if found_post

9016

if found_post

9103

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9017

field_name=sprintf('tx_ffe_cp%d_values',post_count);

9104

param.(field_name)=p;

9018

param.(field_name)=p;

9105

post_count=post_count+1;

9019

post_count=post_count+1;

9106

end

9020

end

9107

end

9021

end

9108

else

9022

else

9109

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9023

param.tx_ffe_cm4_values = xls_parameter(parameter, 'c(-4)', true,0); % TX equalizer pre cursor tap -4 individual settings or range. If not present ignored

9110

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9024

param.tx_ffe_cm3_values = xls_parameter(parameter, 'c(-3)', true,0); % TX equalizer pre cursor tap -3 individual settings or range. If not present ignored

9111

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9025

param.tx_ffe_cm2_values = xls_parameter(parameter, 'c(-2)', true,0); % TX equalizer pre cursor tap -2 individual settings or range. If not present ignored

9112

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9026

param.tx_ffe_cm1_values = xls_parameter(parameter, 'c(-1)', true,0); % TX equalizer pre cursor tap -1 individual settings or range. If not present ignored

9113

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9027

param.tx_ffe_cp1_values = xls_parameter(parameter, 'c(1)', true,0); % TX equalizer post cursor tap 1 individual settings or range. If not present ignored

9114

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9028

param.tx_ffe_cp2_values = xls_parameter(parameter, 'c(2)', true,0); % TX equalizer post cursor tap 2 individual settings or range. If not present ignored

9115

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9029

param.tx_ffe_cp3_values = xls_parameter(parameter, 'c(3)', true,0); % TX equalizer post cursor tap 3 individual settings or range. If not present ignored

9116

end

9030

end

9117

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9031

param.ndfe = xls_parameter(parameter, 'N_b'); % Decision feedback fixed equalizer (DFE) length

9118

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9032

param.N_v = xls_parameter(parameter, 'N_v',true,param.ndfe); % number of UI used to compute Vf

9119

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9033

param.D_p = xls_parameter(parameter, 'D_p',true, 4 ); % number of precursor UI's used to compute Vf Default to 10

9120

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9034

param.N_bx = xls_parameter(parameter, 'N_bx', true, param.ndfe ); % Used for ERL to Compensate for a number of Ui assoicated with the DFE

9121

% support for floating taps

9035

% support for floating taps

9122

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9036

param.N_bg=xls_parameter(parameter, 'N_bg', true,0); % number of group of floating tap. Used as a switch, 0 means no float

9123

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9037

param.N_bf=xls_parameter(parameter, 'N_bf', true,6); % number of taps in group

9124

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9038

param.N_bmax=xls_parameter(parameter, 'N_bmax', true, param.ndfe); % UI span for floating taps

9125

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9039

param.N_bmax=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps. replaced by N_bmax

9126

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9040

param.N_f=xls_parameter(parameter, 'N_f', true, param.ndfe); % UI span for floating taps for rX FFE

9127

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9041

if param.N_bg == 0, param.N_bmax=param.ndfe; end

9128

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9042

param.bmaxg=xls_parameter(parameter, 'bmaxg', true,0.2); % max DFE value for floating taps

9129

9043

9130

% support for tail tap power limitations

9044

% support for tail tap power limitations

9131

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9045

param.B_float_RSS_MAX=xls_parameter(parameter, 'B_float_RSS_MAX', true,0); % floating DFE tap start for RSS floating tap limit

9132

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9046

param.N_tail_start=xls_parameter(parameter, 'N_tail_start', true,0); % start range for max RSS limit for DFE taps

9133

%

9047

%

9134

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9048

param.dfe_delta = xls_parameter(parameter, 'N_b_step', true,0); % discreatiztion of DFE, 0 disables and is not normally used

9135

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9049

param.ffe_pre_tap_len=xls_parameter(parameter, 'ffe_pre_tap_len', true,0); % RX ffe pre cursor tap length

9136

param.RxFFE_cmx=param.ffe_pre_tap_len;

9050

param.RxFFE_cmx=param.ffe_pre_tap_len;

9137

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9051

param.ffe_post_tap_len=xls_parameter(parameter, 'ffe_post_tap_len', true,0); % Rx FFE post cursor tap length

9138

param.RxFFE_cpx=param.ffe_post_tap_len;

9052

param.RxFFE_cpx=param.ffe_post_tap_len;

9139

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9053

param.ffe_tap_step_size=xls_parameter(parameter, 'ffe_tap_step_size', true,0); % Rx FFE tap step size

9140

param.RxFFE_stepz=param.ffe_tap_step_size;

9054

param.RxFFE_stepz=param.ffe_tap_step_size;

9141

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9055

param.ffe_main_cursor_min=xls_parameter(parameter, 'ffe_main_cursor_min', true,1); % Rx FFE main cursor miminum

9142

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9056

param.ffe_pre_tap1_max=xls_parameter(parameter, 'ffe_pre_tap1_max', true,.7); % Rx FFE precursor tap1 limit

9143

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9057

param.ffe_post_tap1_max=xls_parameter(parameter, 'ffe_post_tap1_max', true,.7); % Rx FFE post cursor tap1 limit

9144

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9058

param.ffe_tapn_max=xls_parameter(parameter, 'ffe_tapn_max', true,.7); % Rx FFE precursor tapn limit

9145

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9059

param.ffe_backoff=xls_parameter(parameter, 'ffe_backoff', true,0); % see if better zero foreced solution is better by backing off the number specified FFE taps one at at time

9146

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9060

if param.RxFFE_cmx ~= 0 || param.RxFFE_cpx ~=0

9147

OP.RxFFE= true;

9061

OP.RxFFE= true;

9148

else

9062

else

9149

OP.RxFFE=false;

9063

OP.RxFFE=false;

9150

end

9064

end

9151

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9065

param.num_ui_RXFF_noise=xls_parameter(parameter, 'num_ui_RXFF_noise', true,2048); % Rx FFE precursor tapn limit

9152

9066

9153

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9067

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % CTF AC-DC gain list (GDC2)

9154

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9068

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % CFT pole pole zero pair in GHz for low frequency CTF

9155

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9069

param.f_HP_Z = 1e9*xls_parameter(parameter, 'f_HP_Z', true, []); % CFT zero fz1 is in GHz. Normally a list for 120e. Not normally use elsewise

9156

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9070

param.f_HP_P = 1e9*xls_parameter(parameter, 'f_HP_P', true, []); % CFT pole fp2 is in GHz. Normally a list for 120e. Not normally use elsewise

9157

9071

9158

9072

9159

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9073

param.Min_VEO= xls_parameter(parameter, 'EH_min', true,0); % used when PMD_type is C2M

9160

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9074

param.Max_VEO= xls_parameter(parameter, 'EH_max', true,inf); % used when PMD_type is C2M and is not really computed per spec

9161

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9075

param.Min_VEO_Test= xls_parameter(parameter, 'EH_min_test', true,0); % Older syntax. Used when PMD_type is C2M. This allow EH to go below EH_min. If set to zero it is ignored (same as Min_VEO_test)

9162

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9076

param.Min_VEO_Test= xls_parameter(parameter, 'Min_VEO_Test', true,param.Min_VEO_Test); % used when PMD_type is C2M. This allow EH to go blow EH_min. If set to Zero it is ignored

9163

9077

9164

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9078

param.CTLE_type= xls_parameter(parameter, 'CTLE_type', false,'CL93'); % Sets the CTLE type default is poles and zeros (i.e. not a list of poles as in 120e)

9165

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9079

if ~isempty(param.g_DC_HP_values) ; param.CTLE_type='CL120d';end % overrides CL93 if g_DC_HP_values are a spreadsheet entry. Mostly used when baud rare is >= 50Gbps

9166

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9080

if ~isempty(param.f_HP_Z) ; param.CTLE_type='CL120e';end % overrides CL93 and CL120d if f_HP_Z is a spreadsheet entry

9167

% always read in main ctle values. They would be interpreted different baseed

9081

% always read in main ctle values. They would be interpreted different baseed

9168

% on the clause they apply because of different CTF equations

9082

% on the clause they apply because of different CTF equations

9169

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9083

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % AC-DC gain list

9170

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9084

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9171

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9085

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9172

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9086

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9173

% the contex of the poles an zeros are determined by the clause

9087

% the contex of the poles an zeros are determined by the clause

9174

switch param.CTLE_type

9088

switch param.CTLE_type

9175

case 'CL93'

9089

case 'CL93'

9176

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9090

param.ctle_gdc_values = xls_parameter(parameter, 'g_DC', true); % Continuous time filter DC gain settings (G_DC) or range as specified in Annex 93A

9177

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9091

param.CTLE_fp1 = 1e9*xls_parameter(parameter, 'f_p1', true, param.fb/4); % fp1 is in GHz

9178

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9092

param.CTLE_fp2 = 1e9*xls_parameter(parameter, 'f_p2', true, param.fb); % fp2 is in GHz

9179

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9093

param.CTLE_fz = 1e9*xls_parameter(parameter, 'f_z', true, param.fb/4); % fz is in GHz

9180

case 'CL120d'

9094

case 'CL120d'

9181

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9095

param.g_DC_HP_values = xls_parameter(parameter, 'g_DC_HP', true,[]); % Continuous time filter DC gain settings (G_DC2)

9182

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9096

param.f_HP = 1e9*xls_parameter(parameter, 'f_HP_PZ', true, []); % fLF is in GHz

9183

case 'CL120e'

9097

case 'CL120e'

9184

% re adjust to get TD_CTLE to work with C:120e equation without

9098

% re adjust to get TD_CTLE to work with C:120e equation without

9185

% changing TD_CTLE code

9099

% changing TD_CTLE code

9186

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9100

param.CTLE_fz =param.CTLE_fz ./ 10.^(param.ctle_gdc_values/20);

9187

end

9101

end

9188

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9102

param.GDC_MIN = xls_parameter(parameter, 'GDC_MIN',true, 0); % max ACDC gain, if 0 ignore

9189

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9103

param.cursor_gain=xls_parameter(parameter, 'crusor_gain', true,0); % only FFE and not supported

9190

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9104

param.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9191

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9105

param.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9192

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9106

param.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9193

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9107

param.a_icn_fext = xls_parameter(parameter, 'A_ft', true, param.a_fext); % FEXT aggressor amplitude for ICN. Defaults to A_fe if not specified

9194

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9108

param.a_icn_next = xls_parameter(parameter, 'A_nt', true, param.a_next );% NEXT aggressor amplitude for ICN. Defaults to A_ne if not specified

9195

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9109

param.levels = xls_parameter(parameter, 'L'); % number of symbols levels (PAM-4 is 4, NRZ is 2)

9196

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9110

param.specBER = xls_parameter(parameter, 'DER_0'); % Target detector error ratio

9197

param.DER_CDR = xls_parameter(parameter, 'DER_CDR',true,1e-2); % min DER required for a CDR

9198

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9111

param.pass_threshold = xls_parameter(parameter, 'COM Pass threshold',false,0); % the pass fail threshold for COM in dB

9199

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9112

param.ERL_pass_threshold = xls_parameter(parameter, 'ERL Pass threshold',false,0); % the pass fail threshold for ERL in dB

9200

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9113

param.VEC_pass_threshold = xls_parameter(parameter, 'VEC Pass threshold',false,0);% the pass fail threshold for VEC in dB only used when PMD_type is C2M

9201

9114

9202

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9115

param.sigma_RJ = xls_parameter(parameter, 'sigma_RJ'); % rms of of random jitter

9203

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9116

param.A_DD = xls_parameter(parameter, 'A_DD'); % Normalized peak dual-Dirac noise, this is half of the total bound uncorrelated jitter (BUJ) in UI

9204

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9117

param.eta_0 = xls_parameter(parameter, 'eta_0'); % One-sided noise spectral density (V^2/GHz).Input refered noise at TP5. Input referred noise at TP5

9205

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9118

param.SNDR = xls_parameter(parameter, 'SNR_TX', true); % Transmitter SNDR noise in dB

9206

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9119

param.R_LM = xls_parameter(parameter, 'R_LM'); % Ratio of level separation mismatch. Relevant when not PAM-2 (NRZ).

9207

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9120

param.samples_per_ui = xls_parameter(parameter, 'M', 32); % Samples per UI

9208

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9121

param.ts_sample_adj_range = xls_parameter(parameter, 'sample_adjustment', true, [0 0]); %sample point adjustment range

9209

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9122

param.ts_anchor = xls_parameter(parameter, 'ts_anchor', true, 0); %choice of sampling routine. 0=MM, 1=Peak, 2=max DV (max cursor minus precursor)

9210

% This will keep bmax length 0 if Nb=0

9123

% This will keep bmax length 0 if Nb=0

9211

9124

9212

%AJG021820

9125

%AJG021820

9213

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9126

param.bmax(1:param.ndfe) = xls_parameter(parameter, 'b_max(1)'); % DFE magnitude limit, first coefficient(ignored if Nb=0)

9214

if isempty(param.bmax)

9127

if isempty(param.bmax)

9215

param.bmin=param.bmax;

9128

param.bmin=param.bmax;

9216

else

9129

else

9217

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9130

param.bmin(1:param.ndfe) =xls_parameter(parameter, 'b_min(1)', true,-param.bmax(1) ); % DFE negative magnitude limit. If not specified it defaults to -bmax.

9218

9131

9219

end

9132

end

9220

if param.ndfe >= 2

9133

if param.ndfe >= 2

9221

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9134

param.bmax(2:param.ndfe) = xls_parameter(parameter, 'b_max(2..N_b)', true, .2); % DFE magnitude limit, second coefficient and on (ignored if Nb<2). Can be a regualar expression

9222

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9135

param.bmin(2:param.ndfe) = xls_parameter(parameter, 'b_min(2..N_b)', true, -1*param.bmax(2:param.ndfe) ); % DFE negative magnitude limit, if not specified it defaults to -b_max(2..N_b)

9223

end

9136

end

9224

9137

9225

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9138

param.gqual=xls_parameter(parameter, 'G_Qual', true,[]);% G_Qual are the dB ranges of g_DC g DC )which correspond tog_DC_HP (g DC2)

9226

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9139

param.g2qual=xls_parameter(parameter, 'G2_Qual', true,[]); % G2_Qual limit values of g_DC_HP (g DC2 ) which corresponds to ranges of g_DC g DC specified with G_QUAL

9227

%verify gqual and gqual2 input

9140

%verify gqual and gqual2 input

9228

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9141

if ~isempty(param.gqual) || ~isempty(param.g2qual)

9229

if size(param.gqual,1)~=length(param.g2qual)

9142

if size(param.gqual,1)~=length(param.g2qual)

9230

error('gqual and g2qual size mismatch');

9143

error('gqual and g2qual size mismatch');

9231

end

9144

end

9232

if size(param.gqual,2)~=2

9145

if size(param.gqual,2)~=2

9233

error('gqual must be Nx2 matrix');

9146

error('gqual must be Nx2 matrix');

9234

end

9147

end

9235

end

9148

end

9236

9149

9237

9150

9238

% eval if string for all three - can use different for TX and RX

9151

% eval if string for all three - can use different for TX and RX

9239

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9152

param.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9240

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9153

param.C_diepad = xls_parameter(parameter, 'C_d', true)*1e-9; % C_d in nF (single sided)

9241

% [ahealey] Read values for optional compensating L and "bump" C

9154

% [ahealey] Read values for optional compensating L and "bump" C

9242

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9155

param.L_comp = xls_parameter(parameter, 'L_s', true, 0)*1e-9; % L_s in nH (single sided)

9243

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9156

param.C_bump = xls_parameter(parameter, 'C_b', true, 0)*1e-9; % C_b in nF (single sided)

9244

% [ahealey] End of modifications.

9157

% [ahealey] End of modifications.

9245

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9158

param.C_v = xls_parameter(parameter, 'C_v', true,0)*1e-9; % C_v in nF (via cap) (single sided)

9246

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9159

param.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9247

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9160

param.Z_t = xls_parameter(parameter, 'Z_t', true,50); % single sided source termination reference resistance for TDR and ERL

9248

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9161

param.TR_TDR = xls_parameter(parameter, 'TR_TDR', true , 8e-3); % Gaussian shaped transition time for TDR source in ns

9249

9162

9250

9163

9251

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9164

param.Z0 = xls_parameter(parameter, 'R_0', 50); %

9252

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9165

param.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9253

[ncases, mele]=size(param.z_p_tx_cases);

9166

[ncases, mele]=size(param.z_p_tx_cases);

9254

if mele ==2

9167

if mele ==2

9255

param.flex=2;

9168

param.flex=2;

9256

elseif mele==4

9169

elseif mele==4

9257

param.flex=4;

9170

param.flex=4;

9258

elseif mele==1

9171

elseif mele==1

9259

param.flex=1;

9172

param.flex=1;

9260

else

9173

else

9261

error(sprintf('config file syntax error'))

9174

error(sprintf('config file syntax error'))

9262

end

9175

end

9263

9176

9264

% board parameters

9177

% board parameters

9265

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9178

param.C_0 = xls_parameter(parameter, 'C_0', true,0)*1e-9; % If Include PCB is set to 1, near device single ended capacitance C0 in nF is added

9266

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9179

param.C_1 = xls_parameter(parameter, 'C_1', true,0)*1e-9; % if Include PCB is set to 1, connector side single ended capacitance C1 in nF is added

9267

%

9180

%

9268

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9181

param.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9269

[ncases1, mele1]=size(param.z_p_next_cases);

9182

[ncases1, mele1]=size(param.z_p_next_cases);

9270

if ncases ~= ncases1 || mele ~= mele1

9183

if ncases ~= ncases1 || mele ~= mele1

9271

error('All TX, NEXT, FEXT, Rx cases must agree');

9184

error('All TX, NEXT, FEXT, Rx cases must agree');

9272

else

9185

else

9273

end

9186

end

9274

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9187

param.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9275

[ncases1, mele1]=size(param.z_p_fext_cases);

9188

[ncases1, mele1]=size(param.z_p_fext_cases);

9276

if ncases ~= ncases1 || mele ~= mele1

9189

if ncases ~= ncases1 || mele ~= mele1

9277

error('All TX, NEXT, FEXT, Rx cases must agree');

9190

error('All TX, NEXT, FEXT, Rx cases must agree');

9278

else

9191

else

9279

end

9192

end

9280

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9193

param.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9281

[ncases1, mele1]=size(param.z_p_rx_cases);

9194

[ncases1, mele1]=size(param.z_p_rx_cases);

9282

if ncases ~= ncases1 || mele ~= mele1

9195

if ncases ~= ncases1 || mele ~= mele1

9283

error('All TX, NEXT, FEXT, Rx cases must agree');

9196

error('All TX, NEXT, FEXT, Rx cases must agree');

9284

else

9197

else

9285

end

9198

end

9286

% Table 93A-3 parameters

9199

% Table 93A-3 parameters

9287

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9200

param.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9288

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9201

param.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9289

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9202

param.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9290

[ ncases1, mele1]=size(param.pkg_Z_c);%

9203

[ ncases1, mele1]=size(param.pkg_Z_c);%

9291

if mele ~= mele1

9204

if mele ~= mele1

9292

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9205

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9293

else

9206

else

9294

end

9207

end

9295

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9208

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9296

for ii=1:ncases

9209

for ii=1:ncases

9297

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9210

param.z_p_fext_casesx(ii,:)= [param.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9298

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9211

param.z_p_next_casesx(ii,:)= [param.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9299

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9212

param.z_p_tx_casesx(ii,:)= [param.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9300

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9213

param.z_p_rx_casesx(ii,:)= [param.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9301

end

9214

end

9302

param.z_p_fext_cases = param.z_p_fext_casesx;

9215

param.z_p_fext_cases = param.z_p_fext_casesx;

9303

param.z_p_next_cases= param.z_p_next_casesx;

9216

param.z_p_next_cases= param.z_p_next_casesx;

9304

param.z_p_tx_cases= param.z_p_tx_casesx;

9217

param.z_p_tx_cases= param.z_p_tx_casesx;

9305

param.z_p_rx_cases= param.z_p_rx_casesx;

9218

param.z_p_rx_cases= param.z_p_rx_casesx;

9306

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9219

param.pkg_Z_c=[param.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9307

end

9220

end

9308

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9221

param.PKG_Tx_FFE_preset =xls_parameter(parameter, 'PKG_Tx_FFE_preset', true, 0); % RIM 08-18-2022 for Tx preset capability

9309

9222

9310

% Table 92-12 parameters

9223

% Table 92-12 parameters

9311

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9224

param.brd_gamma0_a1_a2 = xls_parameter(parameter, 'board_tl_gamma0_a1_a2', true, [0 4.114e-4 2.547e-4]); % Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9312

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9225

param.brd_tau = xls_parameter(parameter, 'board_tl_tau', true, 6.191e-3);% Board model transmission line delay ns/mm

9313

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9226

param.brd_Z_c = xls_parameter(parameter, 'board_Z_c', true, 109.8); % Board model transmission line characteristic impedance [ Tx , Rx ]

9314

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9227

param.z_bp_tx = xls_parameter(parameter, 'z_bp (TX)', true, 151); % Victim transmitter board trace lengths in mm

9315

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9228

param.z_bp_next = xls_parameter(parameter, 'z_bp (NEXT)', true, 72);% Next Assessor transmitter board trace lengths in mm

9316

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9229

param.z_bp_fext = xls_parameter(parameter, 'z_bp (FEXT)', true, 72);% Rext Assessor transmitter board trace lengths in mm

9317

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9230

param.z_bp_rx = xls_parameter(parameter, 'z_bp (RX)', true, 151);% Victim receiver board trace lengths in mm

9318

9231

9319

% Unofficial parameters

9232

% Unofficial parameters

9320

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9233

param.snpPortsOrder = xls_parameter(parameter, 'Port Order', true, [1 3 2 4]); % s parameter port order [ tx+ tx- rx+ rx-]

9321

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9234

param.delta_IL=xls_parameter(parameter, 'delta_IL', false, 1); % experiemnal

9322

% Deprecated parameters - affect only frequency domain analysis.

9235

% Deprecated parameters - affect only frequency domain analysis.

9323

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9236

param.f_v = xls_parameter(parameter, 'f_v', true, 4); % For FOM_ILD: Transiton rate cut off frequency for ICN/ILD calc in terms of fb

9324

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9237

param.f_f = xls_parameter(parameter, 'f_f', true, 4); % For ICN: Fext transiton rate cut off frequency for ICN calc in terms of fb

9325

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9238

param.f_n = xls_parameter(parameter, 'f_n', true, 4); % For ICN: Next transiton rate cut off frequency for ICN calc in terms of fb

9326

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9239

param.f_r = xls_parameter(parameter, 'f_r', true, 4); % reference receive filter in COM and in ICN/FOM_ILD calcs in terms of fb

9327

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9240

param.fb_BT_cutoff= xls_parameter(parameter, 'TDR_f_BT_3db', true, 0.4730); % Bessel-Thomson 3 dB cut off freqeuncy in terms of fb

9328

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9241

param.BTorder = xls_parameter(parameter, 'BTorder', false, 4); % Bessel function order

9329

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9242

param.RC_Start = xls_parameter(parameter, 'RC_Start', false, param.fb/2); % start frequency for raised cosine filter

9330

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9243

param.RC_end = xls_parameter(parameter, 'RC_end', false, param.fb*param.f_r ); % end frequency for raised cosine filter

9331

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9244

param.beta_x= xls_parameter(parameter, 'beta_x', false, 0);% (for ERL) use default

9332

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9245

param.rho_x= xls_parameter(parameter, 'rho_x', false, .618); % (for ERL) use default

9333

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9246

param.tfx= xls_parameter(parameter, 'fixture delay time', true, -1);% fixture delay time (for ERL)

9334

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9247

param.Grr_limit=xls_parameter(parameter, 'Grr_limit', false, 1); % either do no use or set to 1 (for ERL)

9335

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9248

param.Grr=xls_parameter(parameter, 'Grr', false, param.Grr_limit);% either do no use or set to 1 (for ERL)

9336

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9249

param.Gx=xls_parameter(parameter, 'Gx', false, 0); % ERL parameter param.Grr, This is used is the COM code

9337

switch param.Gx

9250

switch param.Gx

9338

case 0

9251

case 0

9339

param.Grr=param.Grr; % just use older Grr ir gx not specified

9252

param.Grr=param.Grr; % just use older Grr ir gx not specified

9340

case 1

9253

case 1

9341

param.Grr=2; % use newer Grr

9254

param.Grr=2; % use newer Grr

9342

end

9255

end

9343

9256

9344

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9257

param.LOCAL_SEARCH=xls_parameter(parameter,'Local Search',true,0); % Decreases COM compute time. Aetting to 2 seems ok ,if 0 search is full grid

9345

% Operational control variables

9258

% Operational control variables

9346

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9259

%OP.include_pcb = xls_parameter(parameter, 'Include PCB (table 92-13)', false, 0);

9347

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9260

param.Tukey_Window=xls_parameter(parameter,'Tukey_Window',true,0); % required for ERL. Set to 1. Default is 0.

9348

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9261

param.Noise_Crest_Factor= xls_parameter(parameter, 'Noise_Crest_Factor', true, 0); % Normally not used. If set this is q factor used for quantized Gaussian PDFs

9349

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9262

param.AC_CM_RMS = xls_parameter(parameter, 'AC_CM_RMS', true, 0); % AC_CM_RMS is the CM BBN AWGN RMS at COM source point. Default is 0. Adds common mode noise source to the COM signal path for the through channel

9350

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9263

param.ACCM_MAX_Freq=xls_parameter(parameter, 'ACCM_MAX_Freq', true, param.fb); % F max for integrating ACCM voltage in Hz. Default is fb

9351

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9264

param.T_O = xls_parameter(parameter, 'T_O', true, 0 ); % Units are mUI. Histogram for VEC and VEO are computed over T_s +/- T_O.

9352

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9265

param.T_O = xls_parameter(parameter, 'T_h', true, param.T_O ); % superceded with T_O but is the internal values that is used. Do not use.

9353

9266

9354

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9267

param.samples_for_C2M =xls_parameter(parameter, 'samples_for_C2M', true, 100 ); % Finer sampling in terms of samples per UI for c2m histgram analysis.

9355

9268

9356

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9269

OP.Histogram_Window_Weight=xls_parameter(parameter, 'Histogram_Window_Weight', false, 'rectangle' ); %Weighting for VEC and VEO are histogram processing. Type are Gaussian,Dual Rayleigh,Triangle, and Rectangle (default)

9357

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9270

param.sigma_r=xls_parameter(parameter, 'sigma_r', true, .020 ); % sigma_r for 0.3ck Gaussian histogram window. Unit are UI. Preferred usage.

9358

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9271

param.Qr=xls_parameter(parameter, 'Qr', true, param.sigma_r ); % sigma_r replaces Qr gasussian histogram window. Unit are UI

9359

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9272

param.QL=xls_parameter(parameter, 'QL', true, param.T_O/param.Qr/1000 ); % superceded with sigma_r but is the internal values that is used

9360

9273

9361

%%

9274

%%

9362

9275

9363

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9276

param.skew_ps=xls_parameter(parameter, 'skew_ps', true, 0 );% experiment p/n skew. Not used.

9364

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9277

param.imb_Z_fctr=xls_parameter(parameter, 'imb_Z_fctr', true, 1 ); % exprimental p/n impedance missmatch. Not used.

9365

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9278

param.imb_C_fctr=xls_parameter(parameter, 'imb_C_fctr', true, 1 ); % exprimental p/n capacitance missmatch. Not used.

9366

param.awgn_mv=param.AC_CM_RMS;

9279

param.awgn_mv=param.AC_CM_RMS;

9367

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9280

param.flip=xls_parameter(parameter, 'flip', true, 0 ); % exprimental p/n missmatch flip. Not used.

9368

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9281

param.f_hp=xls_parameter(parameter, 'f_hp', true, 0 ); % for rx testing for eq 162-12 if 0 (default) then rx test using rx bbn

9369

param.Q=xls_parameter(parameter, 'Q', true, 0 ); % Implementation penalty for MLSE in EQ 178a-36

+9282

9370

9283

9371

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9284

%% Adding new parameters to reveal whether Floating DFE or Floating RXFFE is used

9372

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9285

% This removes the dependency on checking param.N_bg (that is no longer valid to reveal if floating DFE is used)

9373

param.Floating_RXFFE=false;

9286

param.Floating_RXFFE=false;

9374

param.Floating_DFE=false;

9287

param.Floating_DFE=false;

9375

if param.N_bg > 0

9288

if param.N_bg > 0

9376

param.Floating_DFE=true;

9289

param.Floating_DFE=true;

9377

end

9290

end

9378

if OP.RxFFE

9291

if OP.RxFFE

9379

param.Floating_DFE=false;

9292

param.Floating_DFE=false;

9380

if param.N_bg > 0

9293

if param.N_bg > 0

9381

param.Floating_RXFFE=true;

9294

param.Floating_RXFFE=true;

9382

end

9295

end

9383

end

9296

end

9384

%% for introducing Tx or Rx skew on p leg or n leg

9297

%% for introducing Tx or Rx skew on p leg or n leg

9385

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9298

param.Txpskew=xls_parameter(parameter, 'Txpskew', true, 0 ); % Tx p skew in ps

9386

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9299

param.Txnskew=xls_parameter(parameter, 'Txnskew', true, 0 ); % Tx n skew in ps

9387

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9300

param.Rxpskew=xls_parameter(parameter, 'Rxpskew', true, 0 ); % Rx p skew in ps

9388

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9301

param.Rxnskew=xls_parameter(parameter, 'Rxnskew', true, 0 ); % Rx n skew in ps

9389

9302

9390

%%

9303

%%

9391

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9304

OP.include_pcb = xls_parameter(parameter, 'Include PCB', false); % Used to add a PCB one each side of the passed s-parameters.

9392

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9305

OP.exit_if_deployed = xls_parameter(parameter, 'exit if deployed', false,0); % may need set when COM is an exe

9393

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9306

OP.INCLUDE_CTLE = xls_parameter(parameter, 'INCLUDE_CTLE', false, 1); % do not use

9394

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9307

OP.EXE_MODE= xls_parameter(parameter, 'EXE_MODE', false, 1);% 12/21 0:legacy 1:fast 2:superfast default is 1.

9395

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9308

OP.INCLUDE_FILTER = xls_parameter(parameter, 'INCLUDE_TX_RX_FILTER', false, 1); % do not use

9396

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9309

OP.force_pdf_bin_size = xls_parameter(parameter, 'Force PDF bin size', false, 0); % do not use

9397

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9310

OP.BinSize = xls_parameter(parameter, 'PDF bin size', false, 1e-5); % set lower for faster computation time but less accuracy.

9398

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9311

OP.DEBUG = xls_parameter(parameter, 'DIAGNOSTICS', false, false); % supresss some interim compuation value printouts

9399

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9312

OP.DISPLAY_WINDOW = xls_parameter(parameter, 'DISPLAY_WINDOW', false, true); % controls if graph plots are displayed. Typically goes along with DIAGNOSTICS

9400

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9313

OP.CSV_REPORT = xls_parameter(parameter, 'CSV_REPORT', false, true); % saves all the output parameters to a CSV file in the results directory, If DIAGNOSTICS is set then a mat file is also created

9401

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9314

OP.SAVE_TD=xls_parameter(parameter, 'SAVE_TD', false, false); % Save the time domian waveforms. FIR, PR etc. in an output structure

9402

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9315

OP.SAVE_FIGURES=xls_parameter(parameter, 'SAVE_FIGURES', false, false); % save displayed figures in the results directory

9403

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9316

OP.SAVE_FIGURE_to_CSV=xls_parameter(parameter, 'SAVE_FIGURE_to_CSV', false, false); % does not work. do not use.

9404

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9317

OP.GET_FD = xls_parameter(parameter, 'Display frequency domain', false, OP.GET_FD); % Not normally set in the config file. It is normally just set to true to get FD plots

9405

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9318

OP.INC_PACKAGE = xls_parameter(parameter, 'INC_PACKAGE', false, true); % warning: INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1

9406

if ~OP.INC_PACKAGE

9319

if ~OP.INC_PACKAGE

9407

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9320

fprintf('<strong> Warning!!! INC_PACKAGE=0 not fully supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9408

end

9321

end

9409

9322

9410

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9323

OP.EW = xls_parameter(parameter, 'EW', false, false); % RIM 3-18-2021 change defaults

9411

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9324

OP.IDEAL_TX_TERM = xls_parameter(parameter, 'IDEAL_TX_TERM', false, false);

9412

if OP.IDEAL_TX_TERM

9325

if OP.IDEAL_TX_TERM

9413

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9326

fprintf('<strong> Warning!!! IDEAL_TX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9414

end

9327

end

9415

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9328

OP.IDEAL_RX_TERM = xls_parameter(parameter, 'IDEAL_RX_TERM', false, false);

9416

if OP.IDEAL_RX_TERM

9329

if OP.IDEAL_RX_TERM

9417

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9330

fprintf('<strong> Warning!!! IDEAL_RX_TERM not supported, instead, set Zp,Cd, and Cp parameters to zero and Zp select to 1 </strong>\n');

9418

end

9331

end

9419

9332

9420

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9333

OP.TDMODE = xls_parameter(parameter, 'TDMODE',false, OP.TDMODE); % Enables the the use of pulse response instead of s-parameters. Assumes no packages or the packages are included in the PR. Default is 0.

9421

9334

9422

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9335

OP.FT_COOP = xls_parameter(parameter, 'FT_COOP',false, false); % obsolete do not use.

9423

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9336

OP.RESULT_DIR = regexprep(xls_parameter(parameter, 'RESULT_DIR'), '\\', filesep); % directory where results like csv, mat, and/or figure files will be written

9424

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9337

OP.RESULT_DIR=strrep(OP.RESULT_DIR,'{date}',date);

9425

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9338

OP.BREAD_CRUMBS = xls_parameter(parameter, 'BREAD_CRUMBS',false, false); % if DIAGNOSTICS is set then param, OP, and chdata are include in the output for each run

9426

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9339

OP.BREAD_CRUMBS_FIELDS = xls_parameter(parameter, 'BREAD_CRUMBS_FIELDS',false, ''); % if BREAD_CRUMBs is enabled, this file controls what chdata fields are included

9427

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9340

OP.COM_CONTRIBUTION_CURVES = xls_parameter(parameter, 'COM_CONTRIBUTION',false,0); % Default is 0. If set to 1 then a bar graph of COM contributors is produce instead of bathtub curves

9428

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9341

OP.ENFORCE_CAUSALITY = xls_parameter(parameter, 'Enforce Causality', false, 0);% default is 0. Not recommended

9429

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9342

OP.EC_REL_TOL = xls_parameter(parameter, 'Enforce Causality REL_TOL', false, 1e-2); % Relative Tolerance parameter for causality, Hard enforcement, 1e-3, Soft enforcement, 1e-2

9430

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9343

OP.EC_DIFF_TOL = xls_parameter(parameter, 'Enforce Causality DIFF_TOL', false, 1e-3); % Difference Tolerance parameter for causality, Hard enforcement, 1e-4,Soft enforcement, 1e-3

9431

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9344

OP.EC_PULSE_TOL = xls_parameter(parameter, 'Enforce Causality pulse start tolerance', false, 0.01); % Tolerance parameter for causality, Hard enforcement, 0.05, Soft enforcement, .01

9432

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9345

OP.pkg_len_select = xls_parameter(parameter, 'z_p select', true, 1); % List of package length indexes used to run COM

9433

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9346

OP.RX_CALIBRATION = xls_parameter(parameter, 'RX_CALIBRATION', false, false); % Turn on RX_Calibration loop

9434

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9347

OP.sigma_bn_STEP = xls_parameter(parameter, 'Sigma BBN step', false, 5e-3); % BBN step for Rx Calibration in volts. Defaults is 0.5e-3

9435

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9348

OP.BBN_Q_factor = xls_parameter(parameter, 'BBN Q factor', false, 5); % Overrides NEXT/FEXT noise Qfactor for 'Force BBN Q factor' used for reporting. does not affect COM.

9436

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9349

OP.force_BBN_Q_factor = xls_parameter(parameter, 'Force BBN Q factor', false, false); % Used for reporting and bathtub curves. does not affect COM.

9437

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9350

OP.transmitter_transition_time = xls_parameter(parameter, 'T_r', true , 8e-3); % 20% to 80% transition time used for the Gaussian shaped source

9438

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9351

OP.RL_norm_test=xls_parameter(parameter, 'ERL_FOM', false, 1); % Defaults to 1 indicating variance is used for FOM determination. Do not change.

9439

9352

9440

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9353

OP.T_r_meas_point = xls_parameter(parameter, 'T_r_meas_point', false, 0); % included for earlier version support. Not recommended to use.

9441

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9354

OP.T_r_filter_type= xls_parameter(parameter, 'T_r_filter_type', false, 0);% included for earlier version support. Not recommended to use.

9442

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9355

OP.FORCE_TR = xls_parameter(parameter, 'FORCE_TR', false, false);% Included for earlier version support but should be set to 1 in most later config sheets.

9443

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9356

% Control with OP.T_r_filter_type and OP.T_r_meas_point for backward

9444

% compatibility

9357

% compatibility

9445

if OP.FORCE_TR

9358

if OP.FORCE_TR

9446

OP.T_r_meas_point=0;

9359

OP.T_r_meas_point=0;

9447

OP.T_r_filter_type=1;

9360

OP.T_r_filter_type=1;

9448

end

9361

end

9449

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9362

OP.TDR = xls_parameter(parameter, 'TDR', false, false); % Set to 1 to produce TDR results

9450

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9363

OP.TDR_duration= xls_parameter(parameter, 'TDR_duration', false, 5); % only used if N*UI is longer than the TDR duration time. Default is 5 times the raw s-parameter transit time.

9451

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9364

OP.N = xls_parameter(parameter, 'N', false, 0); % duration time in UI which is used for ERL (PTDR)

9452

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9365

OP.WC_PORTZ = xls_parameter(parameter, 'WC_PORTZ', false, false); % Do not use: Obsolete.

9453

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9366

OP.T_k= xls_parameter(parameter, 'T_k', false, .6)*1e-9; % Time span (ns) for which the impedance of port is determined using TDR.

9454

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9367

OP.ERL_ONLY = xls_parameter(parameter, 'ERL_ONLY', false,0); % Compute ERL only

9455

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9368

OP.ERL=xls_parameter(parameter, 'ERL', false, false); % Enables ERL. Needs TDR to be set as well.

9456

if OP.ERL

9369

if OP.ERL

9457

OP.PTDR=1;

9370

OP.PTDR=1;

9458

else

9371

else

9459

OP.PTDR=0;

9372

OP.PTDR=0;

9460

end % ERL needs to do a TDR

9373

end % ERL needs to do a TDR

9461

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9374

OP.SHOW_BRD= xls_parameter(parameter, 'SHOW_BRD', false,0);% indclude added board (PCB) in TDR and ERL. Default is 0.

9462

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9375

if OP.WC_PORTZ , OP.TDR=1;end % Obsolete: WC_PORTZ needs to do a TDR

9463

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9376

OP.TDR_W_TXPKG = xls_parameter(parameter, 'TDR_W_TXPKG', false,0);% adds tx package for TDR, PTDR, and ERL. Default is 0.

9464

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9377

OP.Bessel_Thomson=xls_parameter(parameter, 'Bessel_Thomson', false, false); % enable Bessel Thomsen filter for COM

9465

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9378

OP.TDR_Butterworth=xls_parameter(parameter, 'TDR_Butterworth', false, true); % enable Butterworth filter for TDR, PTDR, and ERL

9466

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9379

OP.Butterworth=xls_parameter(parameter, 'Butterworth', false, 1); % Enable Butterworth Rx filter for COM compuatetopm

9467

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9380

OP.Raised_Cosine=xls_parameter(parameter, 'Raised_Cosine', false,0); % Not used if 0. Default is zero. Should set BT and BW to false

9468

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9381

OP.inc_reflect_board=xls_parameter(parameter, 'inc_reflect_board', false,0); % Not used if 0. Default is zero.

9469

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9382

OP.AUTO_TFX=xls_parameter(parameter, 'AUTO_TFX', false,0); % Mostly used for device ERL. If sent to 1 the fixture tfx will be estimated.

9470

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9383

OP.LIMIT_JITTER_CONTRIB_TO_DFE_SPAN = xls_parameter(parameter, 'LIMIT_JITTER_CONTRIB_TO_DFE_SPAN', false, false); % Experimental. Default is 0.

9471

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9384

%OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncatio threshold', false, 1e-3);

9472

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9385

OP.impulse_response_truncation_threshold = xls_parameter(parameter, 'Impulse response truncation threshold', false, 1e-3); % zero padding threshold in fraction of IR peak for the impulse response. Effectively controls the length of time for the PR. Larger values decrease run time and accuracy. Default is 1e-3.

9473

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9386

OP.interp_sparam_mag = xls_parameter(parameter, 'S-parameter magnitude extrapolation policy', false, 'linear_trend_to_DC'); % magnitued extrapolation method

9474

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9387

OP.interp_sparam_phase = xls_parameter(parameter, 'S-parameter phase extrapolation policy', false, 'extrap_cubic_to_dc_linear_to_inf'); % phase extrapolation method

9475

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9388

OP.PMD_type= xls_parameter(parameter, 'PMD_type', false,'C2C'); % Either C2C or C2M. C2M is for computing VEC and VEO

9476

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9389

OP.PHY= xls_parameter(parameter, 'PHY', false, OP.PMD_type); % The keyword OP.PMD_type is now used

9477

if strcmpi(OP.PHY,'C2M')

9390

if strcmpi(OP.PHY,'C2M')

9478

OP.EW=true;

9391

OP.EW=true;

9479

else

9392

else

9480

param.T_O=0; % make sure when c2c that sample is at Ts

9393

param.T_O=0; % make sure when c2c that sample is at Ts

9481

end

9394

end

9482

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9395

if param.Min_VEO ~=0 && strcmpi(OP.PHY,'C2C')

9483

OP.PHY='C2Mcom';

9396

OP.PHY='C2Mcom';

9484

end

9397

end

9485

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9398

OP.TDECQ=xls_parameter(parameter, 'TDECQ', false, 0); % Experimental, for only option is none (0) or vma. Default is 0.

9486

switch lower(OP.TDECQ)

9399

switch lower(OP.TDECQ)

9487

case {false 'none' 'vma'}

9400

case {false 'none' 'vma'}

9488

otherwise

9401

otherwise

9489

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9402

error('%s unrecognized TDECQ keyword',OP.TDECQ)

9490

end

9403

end

9491

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9404

OP.RUNTAG = xls_parameter(parameter, 'RUNTAG', false, ''); % This string is appended to the begining of results files

9492

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9405

if isnan(OP.RUNTAG), OP.RUNTAG='';end

9493

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9406

if isnumeric(OP.RUNTAG), OP.RUNTAG=num2str(OP.RUNTAG);end

9494

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9407

OP.CDR=xls_parameter(parameter, 'CDR', false, 'MM');% 12/21 from Yuchun Lu to accomdate 'Mod-MM', Defautt is 'MM'

9495

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9408

OP.Optimize_loop_speed_up =xls_parameter(parameter, 'Optimize_loop_speed_up', true , 0);% If set to 0 (or default) normal looping, If set to 1 loop speedup by slightly reducing PD Fbin and FIR_threshold for optimize looping only

9496

% Parameters for error burst probability calculation. Not officially used

9409

% Parameters for error burst probability calculation. Not officially used

9497

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9410

OP.use_simple_EP_model = xls_parameter(parameter, 'Use simple error propagation model', false, false);% Use to calculate burst error rate (not normally used

9498

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9411

OP.nburst = xls_parameter(parameter, 'Max burst length calculated', false, 0); % Use to calculate burst error rate (not normally used)

9499

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9412

OP.COM_EP_margin = xls_parameter(parameter, 'Error propagation COM margin', false, 0); % Use to calculate error propogation (not normally used)

9500

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9413

OP.USE_ETA0_PSD = xls_parameter(parameter, 'USE_ETA0_PSD', false, 0); % Used eta_0 PSD equaiton for sigma_n. Default is 0. Do not use.

9501

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9414

OP.SAVE_CONFIG2MAT = xls_parameter(parameter, 'SAVE_CONFIG2MAT', false, 0); % If set to 1 (default) saves parameters in mat file. Requires DIAGNOSTICS to be set.

9502

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9415

OP.PLOT_CM = xls_parameter(parameter, 'PLOT_CM', false, 0); % Display CM plots if set to 1. Default is 0.

9503

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9416

OP.fraction_of_F_range_start_extrap_from= xls_parameter(parameter, 'fraction_of_F_range_start_extrap_from', true, 0.75); % Frequency (fb) where high frequency extropolation begins for computing IR. Helps control Gibbs phenomena. defualt is 0.75.

9504

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9417

OP.COMPUTE_RILN = xls_parameter(parameter, 'COMPUTE_RILN', false, 0); % Computes RILN default is 0. FOM_RILN reported

9505

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9418

OP.COMPUTE_TDILN = xls_parameter(parameter, 'COMPUTE_TDILN', false, OP.COMPUTE_RILN); % computes TD ILN from complex freq IL fit. FOM_TDILN reported.

9506

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9419

OP.SAVE_KEYWORD_FILE = xls_parameter(parameter, 'SAVE_KEYWORD_FILE', false, 0); % Save csv file of COM parameter (OP) and keywords. Not implemented.

9507

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9420

OP.SNR_TXwC0 = xls_parameter(parameter, 'SNR_TXwC0', false, 0); % Adjust SNR_TX with C0

9508

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9421

OP.MLSE = xls_parameter(parameter, 'MLSE', false, 0); % MLSE 0,1,2, 3 (no MLSE, U1 MLSE, experimetal MLSE, U3 MLSE)

9509

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9422

OP.RXFFE_FLOAT_CTL = xls_parameter(parameter, 'RXFFE FLOAT CTL', false, 'FOM'); % select taps (taps), pulse response (ISI), or FOM for floating taps determination

9510

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9423

OP.RXFFE_TAP_CONSTRAINT =xls_parameter(parameter, 'RXFFE TAP CONSTRAINT', false, 'Unity Cursor'); % "Unity sum taps", "Unity Cursor", of unbounded

9511

if OP.MLSE && param.ndfe==0

9424

if OP.MLSE && param.ndfe==0

9512

error('At least DFE 1 must be set to use MLSE');

9425

error('At least DFE 1 must be set to use MLSE');

9513

end

9426

end

9514

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9427

OP.TIME_AXIS = xls_parameter(parameter, 'TIME_AXIS', false, 'UI'); % if0 OP.display set pulse response xaxis to seconds or UI

9515

% MNSE parameters

9428

% MNSE parameters

9516

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9429

OP.Do_XT_Noise= xls_parameter(parameter, 'Do_XT_Noise', false, 1);

9517

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9430

OP.FFE_SNR= xls_parameter(parameter, 'FFE_SNR', false, 1);

9518

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9431

OP.Do_Colored_Noise= xls_parameter(parameter, 'Do_Colored_Noise', false, 1);

9519

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9432

OP.Do_White_Noise=xls_parameter(parameter, 'Do_White_Noise', false, 0);

9520

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9433

OP.FFE_OPT_METHOD=xls_parameter(parameter,'FFE_OPT_METHOD',false,'MMSE'); % 'MMSE','FV-LMS'

9521

% Commit request 4p4_7, healey_3dj_COM_01_240416

9434

% Commit request 4p4_7, healey_3dj_COM_01_240416

9522

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9435

OP.TS_SRCH_MODE=xls_parameter(parameter,'TS_SRCH_MODE',false,'full-sweep'); % full-sweep, middle

9523

% need to make sure TD mode does not invoke FD operations

9436

% need to make sure TD mode does not invoke FD operations

9524

if OP.TDMODE % need to set GET_FD false of TDMODE

9437

if OP.TDMODE % need to set GET_FD false of TDMODE

9525

OP.GET_FD=false;

9438

OP.GET_FD=false;

9526

OP.ERL_ONLY=0;

9439

OP.ERL_ONLY=0;

9527

OP.ERL=0;

9440

OP.ERL=0;

9528

OP.PTDR=0;

9441

OP.PTDR=0;

9529

OP.TDR=0;

9442

OP.TDR=0;

9530

OP.RX_CALIBRATION=0;

9443

OP.RX_CALIBRATION=0;

9531

end

9444

end

9532

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9445

if OP.SAVE_CONFIG2MAT || OP.CONFIG2MAT_ONLY

9533

save(matcongfile ,'parameter');

9446

save(matcongfile ,'parameter');

9534

end

9447

end

9535

9448

9536

9449

9537

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9450

%% At the very end of Parameter reading, swap in the proper Tx and Rx values for package parameters based on pkg name

9538

if ~isempty(param.PKG_NAME)

9451

if ~isempty(param.PKG_NAME)

9539

if length(param.PKG_NAME) == 1

9452

if length(param.PKG_NAME) == 1

9540

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9453

param.PKG_NAME = [param.PKG_NAME param.PKG_NAME];

9541

end

9454

end

9542

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9455

tx_rx_fields = {'C_pkg_board' 'R_diepad'};

9543

tx_rx_fields_matrix = {'pkg_Z_c'};

9456

tx_rx_fields_matrix = {'pkg_Z_c'};

9544

tx_fields = {'z_p_tx_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9457

tx_fields = {'z_p_tx_cases' 'z_p_next_cases' 'z_p_fext_cases' 'pkg_gamma0_a1_a2' 'pkg_tau' 'a_thru' 'a_fext'};

9545

rx_fields = {'z_p_rx_cases' 'a_next' 'z_p_next_cases'};

9458

rx_fields = {'z_p_rx_cases' 'a_next'};

9546

tx_pkg_name=param.PKG_NAME{1};

9459

tx_pkg_name=param.PKG_NAME{1};

9547

rx_pkg_name=param.PKG_NAME{2};

9460

rx_pkg_name=param.PKG_NAME{2};

9548

tx_pkg_struct=param.PKG.(tx_pkg_name);

9461

tx_pkg_struct=param.PKG.(tx_pkg_name);

9549

rx_pkg_struct=param.PKG.(rx_pkg_name);

9462

rx_pkg_struct=param.PKG.(rx_pkg_name);

9550

9463

9551

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9464

%tx_rx_fields: put the value from the tx package in the Tx position and the value from the rx package in the RX position

9552

for j=1:length(tx_rx_fields)

9465

for j=1:length(tx_rx_fields)

9553

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9466

tx_val = tx_pkg_struct.(tx_rx_fields{j});

9554

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9467

rx_val = rx_pkg_struct.(tx_rx_fields{j});

9555

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9468

param.(tx_rx_fields{j}) = [tx_val(1) rx_val(2)];

9556

end

9469

end

9557

9470

9558

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9471

%tx_rx_fields_matrix: same as tx_rx_fields but in matrix form

9559

for j=1:length(tx_rx_fields_matrix)

9472

for j=1:length(tx_rx_fields_matrix)

9560

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9473

tx_val = tx_pkg_struct.(tx_rx_fields_matrix{j})(1,:);

9561

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9474

rx_val = rx_pkg_struct.(tx_rx_fields_matrix{j})(2,:);

9562

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9475

param.(tx_rx_fields_matrix{j}) = [tx_val; rx_val];

9563

end

9476

end

9564

9477

9565

%tx_fields: use only the tx package values

9478

%tx_fields: use only the tx package values

9566

for j=1:length(tx_fields)

9479

for j=1:length(tx_fields)

9567

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9480

param.(tx_fields{j}) = tx_pkg_struct.(tx_fields{j});

9568

end

9481

end

9569

9482

9570

%rx_fields: use only the rx package values

9483

%rx_fields: use only the rx package values

9571

for j=1:length(rx_fields)

9484

for j=1:length(rx_fields)

9572

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9485

param.(rx_fields{j}) = rx_pkg_struct.(rx_fields{j});

9573

end

9486

end

9574

9487

9575

end

9488

end

9576

9489

9577

9490

9578

%%

9491

%%

9579

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9492

function [data, SDD, SDC] = read_p2_s2params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP)

9580

%% FUNCTION :: read_sp4_sparams

9493

%% FUNCTION :: read_sp4_sparams

9581

%

9494

%

9582

% Description

9495

% Description

9583

% Read the fid of single-ended 4-port complex S-parameters

9496

% Read the fid of single-ended 4-port complex S-parameters

9584

% in Touchstone format 'file' and convert to the internal

9497

% in Touchstone format 'file' and convert to the internal

9585

% format using the port transform 'ports'

9498

% format using the port transform 'ports'

9586

%

9499

%

9587

% Created by Mike Y. He

9500

% Created by Mike Y. He

9588

% April 22, 2005

9501

% April 22, 2005

9589

%

9502

%

9590

% Reused some code from

9503

% Reused some code from

9591

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9504

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9592

% for touchstone 4-port S-matrix import.

9505

% for touchstone 4-port S-matrix import.

9593

%

9506

%

9594

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9507

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9595

% optimized for quicker parameter matching and parsing. also, separated out

9508

% optimized for quicker parameter matching and parsing. also, separated out

9596

% the plotting algorithms into their own sub-function routines

9509

% the plotting algorithms into their own sub-function routines

9597

%

9510

%

9598

% Modified December 2021 to use read_Nport_touchstone

9511

% Modified December 2021 to use read_Nport_touchstone

9599

% This is faster reader that is capable of reading touchstone with any number of ports

9512

% This is faster reader that is capable of reading touchstone with any number of ports

9600

%

9513

%

9601

% Input Variables (required)

9514

% Input Variables (required)

9602

% infile -- The s4p file to be read and converted

9515

% infile -- The s4p file to be read and converted

9603

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9516

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9604

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9517

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9605

% ports -- Re-order the port layout

9518

% ports -- Re-order the port layout

9606

%

9519

%

9607

% Output/Return Variables

9520

% Output/Return Variables

9608

% data -- structure containing network parameter data points and frequency axis

9521

% data -- structure containing network parameter data points and frequency axis

9609

% sdc -- the differential in/common-mode out s-parameter data matrix

9522

% sdc -- the differential in/common-mode out s-parameter data matrix

9610

% sdd -- the differential in/differential out s-parameter data matrix

9523

% sdd -- the differential in/differential out s-parameter data matrix

9611

%

9524

%

9612

9525

9613

9526

9614

% backwards compatibility settings. can be removed in updated code.

9527

% backwards compatibility settings. can be removed in updated code.

9615

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9528

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9616

if isempty(ports); ports = [1 2]; end % default order normally used.

9529

if isempty(ports); ports = [1 2]; end % default order normally used.

9617

ports = [1 2];

9530

ports = [1 2];

9618

9531

9619

9532

9620

if OP.DISPLAY_WINDOW

9533

if OP.DISPLAY_WINDOW

9621

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9534

set(0,'defaulttextinterpreter','none') % prevents subscripting character in displayed messages

9622

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9535

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9623

end

9536

end

9624

9537

9625

%AJG: fast touchstone read for any number of ports

9538

%AJG: fast touchstone read for any number of ports

9626

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9539

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9627

9540

9628

9541

9629

9542

9630

D=NaN(size(sch));

9543

D=NaN(size(sch));

9631

% calculate differential s parameter matrix from single ended

9544

% calculate differential s parameter matrix from single ended

9632

for i=1:size(sch,1)

9545

for i=1:size(sch,1)

9633

S(:,:) = sch(i,:,:);

9546

S(:,:) = sch(i,:,:);

9634

T = [1 1 ; 1 -1 ];

9547

T = [1 1 ; 1 -1 ];

9635

W = T * (S / T);

9548

W = T * (S / T);

9636

D(i,:,:) = W(:,:);

9549

D(i,:,:) = W(:,:);

9637

end

9550

end

9638

9551

9639

% D matrix should be

9552

% D matrix should be

9640

% Scc11 Scd11 Scc12 Scd21

9553

% Scc11 Scd11 Scc12 Scd21

9641

% Sdc11 Sdd11 Sdc12 Sdd12

9554

% Sdc11 Sdd11 Sdc12 Sdd12

9642

% Scc21 Scd21 Scc22 Scd22

9555

% Scc21 Scd21 Scc22 Scd22

9643

% Sdc21 Sdd21 Sdc22 Sdd22

9556

% Sdc21 Sdd21 Sdc22 Sdd22

9644

9557

9645

% proper values

9558

% proper values

9646

%AJG: matrix can be properly referenced after fixing mapping

9559

%AJG: matrix can be properly referenced after fixing mapping

9647

SDD(:,1,1) = D(:,2,2);

9560

SDD(:,1,1) = D(:,2,2);

9648

SDC(:,1,1)= D(:,2,1);

9561

SDC(:,1,1)= D(:,2,1);

9649

SCC(:,1,1)= D(:,1,1);

9562

SCC(:,1,1)= D(:,1,1);

9650

SCD(:,1,1)= D(:,1,2);

9563

SCD(:,1,1)= D(:,1,2);

9651

9564

9652

9565

9653

9566

9654

% backwards compatibility output variables

9567

% backwards compatibility output variables

9655

data.m = sch;

9568

data.m = sch;

9656

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9569

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9657

data.freq = schFreqAxis;

9570

data.freq = schFreqAxis;

9658

colors = 'rgbk';

9571

colors = 'rgbk';

9659

9572

9660

if (plot_ini_s_params == 1)

9573

if (plot_ini_s_params == 1)

9661

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9574

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9662

for mj=1:4

9575

for mj=1:4

9663

% subplot(2,2,mj);

9576

% subplot(2,2,mj);

9664

for mi=1:4

9577

for mi=1:4

9665

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9578

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9666

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9579

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9667

hold on

9580

hold on

9668

end

9581

end

9669

xlabel('Frequency (Hz)');

9582

xlabel('Frequency (Hz)');

9670

ylabel('Magnitude (dB)');

9583

ylabel('Magnitude (dB)');

9671

legend show

9584

legend show

9672

grid on

9585

grid on

9673

title(sprintf('Output port %d', mj));

9586

title(sprintf('Output port %d', mj));

9674

end

9587

end

9675

end

9588

end

9676

plot_dif_s_params =0;

9589

plot_dif_s_params =0;

9677

if (plot_dif_s_params == 1)

9590

if (plot_dif_s_params == 1)

9678

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9591

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9679

% subplot(2,1,1);

9592

% subplot(2,1,1);

9680

for mj=1:1

9593

for mj=1:1

9681

for mi=1:1

9594

for mi=1:1

9682

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9595

plot(data.freq, 20*log10(abs(squeeze(SDD(:,mj,mi)))), ...

9683

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9596

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9684

hold on

9597

hold on

9685

end

9598

end

9686

end

9599

end

9687

xlabel('Frequency (Hz)');

9600

xlabel('Frequency (Hz)');

9688

ylabel('Magnitude (dB)');

9601

ylabel('Magnitude (dB)');

9689

legend show

9602

legend show

9690

grid on

9603

grid on

9691

title(infile);

9604

title(infile);

9692

9605

9693

% subplot(2,1,2);

9606

% subplot(2,1,2);

9694

% for mj=1:2

9607

% for mj=1:2

9695

% for mi=1:2

9608

% for mi=1:2

9696

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9609

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9697

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9610

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9698

% hold on

9611

% hold on

9699

% end

9612

% end

9700

% end

9613

% end

9701

% xlabel('Frequency (Hz)');

9614

% xlabel('Frequency (Hz)');

9702

% ylabel('Magnitude (dB)');

9615

% ylabel('Magnitude (dB)');

9703

% legend show

9616

% legend show

9704

% grid on

9617

% grid on

9705

end

9618

end

9706

9619

9707

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9620

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9708

% end read_sp2_sparam

9621

% end read_sp2_sparam

9709

9622

9710

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9623

function [data, SDD, SDC, SCC ] = read_p4_s4params(infile, plot_ini_s_params, plot_dif_s_params, ports,OP,param)

9711

%% FUNCTION :: read_sp4_sparams

9624

%% FUNCTION :: read_sp4_sparams

9712

%

9625

%

9713

% Description

9626

% Description

9714

% Read the fid of single-ended 4-port complex S-parameters

9627

% Read the fid of single-ended 4-port complex S-parameters

9715

% in Touchstone format 'file' and convert to the internal

9628

% in Touchstone format 'file' and convert to the internal

9716

% format using the port transform 'ports'

9629

% format using the port transform 'ports'

9717

%

9630

%

9718

% Created by Mike Y. He

9631

% Created by Mike Y. He

9719

% April 22, 2005

9632

% April 22, 2005

9720

%

9633

%

9721

% Reused some code from

9634

% Reused some code from

9722

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9635

% Anthony Sanders, Alex Deas, Bob Davidov (24 January 2005)

9723

% for touchstone 4-port S-matrix import.

9636

% for touchstone 4-port S-matrix import.

9724

%

9637

%

9725

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9638

% Modified (2012-July-27) by Ken Young to match current indexing scheme and

9726

% optimized for quicker parameter matching and parsing. also, separated out

9639

% optimized for quicker parameter matching and parsing. also, separated out

9727

% the plotting algorithms into their own sub-function routines

9640

% the plotting algorithms into their own sub-function routines

9728

%

9641

%

9729

% Modified December 2021 to use read_Nport_touchstone

9642

% Modified December 2021 to use read_Nport_touchstone

9730

% This is faster reader that is capable of reading touchstone with any number of ports

9643

% This is faster reader that is capable of reading touchstone with any number of ports

9731

%

9644

%

9732

% Input Variables (required)

9645

% Input Variables (required)

9733

% infile -- The s4p file to be read and converted

9646

% infile -- The s4p file to be read and converted

9734

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9647

% plot_ini_sparams -- Plot the initial s-parameter information. For debugging purposes

9735

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9648

% plot_dif_s_params -- Plot the differential s-parameter information. For debugging purposes

9736

% ports -- Re-order the port layout

9649

% ports -- Re-order the port layout

9737

% OP

9650

% OP

9738

% param

9651

% param

9739

% Output/Return Variables

9652

% Output/Return Variables

9740

% data -- structure containing network parameter data points and frequency axis

9653

% data -- structure containing network parameter data points and frequency axis

9741

% sdd -- the differential in/differential out s-parameter data matrix

9654

% sdd -- the differential in/differential out s-parameter data matrix

9742

% sdc -- the differential in/common-mode out s-parameter data matrix

9655

% sdc -- the differential in/common-mode out s-parameter data matrix

9743

% scc -- the common mode in/common-mode out s-parameter data matrix

9656

% scc -- the common mode in/common-mode out s-parameter data matrix

9744

%

9657

%

9745

%

9658

%

9746

9659

9747

9660

9748

% backwards compatibility settings. can be removed in updated code.

9661

% backwards compatibility settings. can be removed in updated code.

9749

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9662

if ~exist('OP', 'var'); OP.DISPLAY_WINDOW = true; end

9750

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9663

if isempty(ports); ports = [1 3 2 4]; end % default order normally used.

9751

9664

9752

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9665

% adjust ports to maintain the meaning [in1, in2 , out1, out2] when one

9753

% pair is reversed.

9666

% pair is reversed.

9754

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9667

%ports_adj=ports; for k=1:4, ports_adj(k)=find(ports==k); end; ports=ports_adj;

9755

9668

9756

if OP.DISPLAY_WINDOW

9669

if OP.DISPLAY_WINDOW

9757

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9670

hMsgBox = msgbox(infile, 'Reading S-Parameter File'); % display a progress bar for reading the s-parameter file(s)

9758

end

9671

end

9759

9672

9760

%AJG: fast touchstone read for any number of ports

9673

%AJG: fast touchstone read for any number of ports

9761

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9674

[sch,schFreqAxis]=read_Nport_touchstone(infile,ports);

9762

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9675

% matrix to introduce p or n skew on Tx or Rx RIM 12/29/2023

9763

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9676

% Sigma's will be form exp(2i*pi*f*skew*1e-12). i.e. if skew = 0 sigma = 1

9764

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9677

% need to swap sigma for 1 and 3 and 2 and 4 not RIM 12/29/2023

9765

Sigfct = ...

9678

Sigfct = ...

9766

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9679

@(sigma2,sigma1,sigma4,sigma3)reshape([sigma1.^2,sigma1.*sigma2,sigma1.*sigma3,sigma1.*sigma4,sigma1.*sigma2,sigma2.^2,sigma2.*sigma3,sigma2.*sigma4,sigma1.*sigma3,sigma2.*sigma3,sigma3.^2,sigma3.*sigma4,sigma1.*sigma4,sigma2.*sigma4,sigma3.*sigma4,sigma4.^2],[4,4]);

9767

D=NaN(size(sch));

9680

D=NaN(size(sch));

9768

% calculate differential s parameter matrix from single ended

9681

% calculate differential s parameter matrix from single ended

9769

% skew added RIM 12/29/2023

9682

% skew added RIM 12/29/2023

9770

for i=1:size(sch,1)

9683

for i=1:size(sch,1)

9771

f=schFreqAxis(i);

9684

f=schFreqAxis(i);

9772

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9685

sigma_matrix=Sigfct(exp(2i*pi*f*param.Txpskew*1e-12),exp(2i*pi*f*param.Txnskew*1e-12),exp(2i*pi*f*param.Rxpskew*1e-12),exp(2i*pi*f*param.Rxnskew*1e-12) );

9773

S(:,:) = sch(i,:,:);

9686

S(:,:) = sch(i,:,:);

9774

Snew=sigma_matrix.*S;

9687

Snew=sigma_matrix.*S;

9775

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9688

T = [1 1 0 0 ; 1 -1 0 0 ; 0 0 1 1 ; 0 0 1 -1];

9776

W = T * (Snew / T);

9689

W = T * (Snew / T);

9777

D(i,:,:) = W(:,:);

9690

D(i,:,:) = W(:,:);

9778

end

9691

end

9779

9692

9780

% D matrix should be

9693

% D matrix should be

9781

% Scc11 Scd11 Scc12 Scd21

9694

% Scc11 Scd11 Scc12 Scd21

9782

% Sdc11 Sdd11 Sdc12 Sdd12

9695

% Sdc11 Sdd11 Sdc12 Sdd12

9783

% Scc21 Scd21 Scc22 Scd22

9696

% Scc21 Scd21 Scc22 Scd22

9784

% Sdc21 Sdd21 Sdc22 Sdd22

9697

% Sdc21 Sdd21 Sdc22 Sdd22

9785

9698

9786

% proper values

9699

% proper values

9787

SDD(:,1,1) = D(:,2,2);

9700

SDD(:,1,1) = D(:,2,2);

9788

SDD(:,2,2) = D(:,4,4);

9701

SDD(:,2,2) = D(:,4,4);

9789

SDD(:,1,2) = D(:,2,4);

9702

SDD(:,1,2) = D(:,2,4);

9790

SDD(:,2,1) = D(:,4,2);

9703

SDD(:,2,1) = D(:,4,2);

9791

9704

9792

SDC(:,1,1) = D(:,2,1);

9705

SDC(:,1,1) = D(:,2,1);

9793

SDC(:,2,2) = D(:,4,3);

9706

SDC(:,2,2) = D(:,4,3);

9794

SDC(:,1,2) = D(:,2,3);

9707

SDC(:,1,2) = D(:,2,3);

9795

SDC(:,2,1) = D(:,4,1);

9708

SDC(:,2,1) = D(:,4,1);

9796

9709

9797

SCC(:,1,1) = D(:,1,1);

9710

SCC(:,1,1) = D(:,1,1);

9798

SCC(:,2,2) = D(:,3,3);

9711

SCC(:,2,2) = D(:,3,3);

9799

SCC(:,1,2) = D(:,1,3);

9712

SCC(:,1,2) = D(:,1,3);

9800

SCC(:,2,1) = D(:,3,1);

9713

SCC(:,2,1) = D(:,3,1);

9801

9714

9802

% backwards compatibility output variables

9715

% backwards compatibility output variables

9803

data.m = sch;

9716

data.m = sch;

9804

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9717

%schFreqAxis=schFreqAxis(1:freqCounter); % truncating preallocated array to number of freq points.

9805

data.freq = schFreqAxis;

9718

data.freq = schFreqAxis;

9806

colors = 'rgbk';

9719

colors = 'rgbk';

9807

9720

9808

if (plot_ini_s_params == 1)

9721

if (plot_ini_s_params == 1)

9809

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9722

figure('name', 'Single-ended s-parameters');set(gcf,'Tag','COM');

9810

for mj=1:4

9723

for mj=1:4

9811

subplot(2,2,mj);

9724

subplot(2,2,mj);

9812

for mi=1:4

9725

for mi=1:4

9813

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9726

plot(data.freq, 20*log10(abs(data.m(:,mj,mi)+1.0e-15)), ...

9814

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9727

colors(mi), 'linewidth', 2, 'disp', sprintf('S%d%d', mj, mi));

9815

hold on

9728

hold on

9816

end

9729

end

9817

xlabel('Frequency (Hz)');

9730

xlabel('Frequency (Hz)');

9818

ylabel('Magnitude (dB)');

9731

ylabel('Magnitude (dB)');

9819

legend show

9732

legend show

9820

grid on

9733

grid on

9821

title(sprintf('Output port %d', mj));

9734

title(sprintf('Output port %d', mj));

9822

end

9735

end

9823

end

9736

end

9824

plot_dif_s_params =0;

9737

plot_dif_s_params =0;

9825

if (plot_dif_s_params == 1)

9738

if (plot_dif_s_params == 1)

9826

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9739

figure('name', 'Mixed-mode s-parameters');set(gcf,'Tag','COM');

9827

% subplot(2,1,1);

9740

% subplot(2,1,1);

9828

for mj=1:2

9741

for mj=1:2

9829

for mi=1:2

9742

for mi=1:2

9830

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9743

plot(data.freq, 20*log10(abs(SDD(:,mj,mi))), ...

9831

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9744

colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDD%d%d', mj, mi));

9832

hold on

9745

hold on

9833

end

9746

end

9834

end

9747

end

9835

xlabel('Frequency (Hz)');

9748

xlabel('Frequency (Hz)');

9836

ylabel('Magnitude (dB)');

9749

ylabel('Magnitude (dB)');

9837

legend show

9750

legend show

9838

grid on

9751

grid on

9839

title(infile);

9752

title(infile);

9840

%

9753

%

9841

% subplot(2,1,2);

9754

% subplot(2,1,2);

9842

% for mj=1:2

9755

% for mj=1:2

9843

% for mi=1:2

9756

% for mi=1:2

9844

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9757

% plot(data.freq, 20*log10(abs(SDC(:,mj,mi))+1.0e-15), ...

9845

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9758

% colors((mj-1)*2+mi), 'linewidth',2, 'disp', sprintf('SDC%d%d', mj, mi));

9846

% hold on

9759

% hold on

9847

% end

9760

% end

9848

% end

9761

% end

9849

% xlabel('Frequency (Hz)');

9762

% xlabel('Frequency (Hz)');

9850

% ylabel('Magnitude (dB)');

9763

% ylabel('Magnitude (dB)');

9851

% legend show

9764

% legend show

9852

% grid on

9765

% grid on

9853

end

9766

end

9854

9767

9855

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9768

if OP.DISPLAY_WINDOW, close(hMsgBox); end

9856

% end read_sp4_sparam

9769

% end read_sp4_sparam

9857

function param_struct = read_package_parameters(parameter,param_struct)

9770

function param_struct = read_package_parameters(parameter,param_struct)

9858

9771

9859

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9772

%With the introduction of Package sections in COM spreadsheet, it makes sense to have a single function that grabs all package parameters from a parameter block

9860

%This block should eventually replace what is in read_ParamConfigFile

9773

%This block should eventually replace what is in read_ParamConfigFile

9861

%It can be called as: param = read_package_parameters(parameter, param)

9774

%It can be called as: param = read_package_parameters(parameter, param)

9862

9775

9863

if nargin<2

9776

if nargin<2

9864

%param_struct doesn't need to be passed when building a new package structure

9777

%param_struct doesn't need to be passed when building a new package structure

9865

%it is only needed when appending to regular param structure

9778

%it is only needed when appending to regular param structure

9866

param_struct=struct;

9779

param_struct=struct;

9867

end

9780

end

9868

9781

9869

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9782

param_struct.C_pkg_board = xls_parameter(parameter, 'C_p', true)*1e-9; % C_p in nF (single sided)

9870

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9783

param_struct.R_diepad = xls_parameter(parameter, 'R_d', true); % Die source termination resistance (single sided)

9871

9784

9872

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9785

param_struct.a_thru = xls_parameter(parameter, 'A_v', true); % Victim differential peak source output voltage (half of peak to peak)

9873

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9786

param_struct.a_fext = xls_parameter(parameter, 'A_fe', true); % FEXT aggressor differential peak source output voltage (half of peak to peak)

9874

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9787

param_struct.a_next = xls_parameter(parameter, 'A_ne', true); % NEXT aggressor differential peak source output voltage (half of peak to peak)

9875

9788

9876

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9789

param_struct.z_p_tx_cases = xls_parameter(parameter, 'z_p (TX)', true).'; % List of victim transmitter package trace lengths in mm, one per case

9877

[ncases, mele]=size(param_struct.z_p_tx_cases);

9790

[ncases, mele]=size(param_struct.z_p_tx_cases);

9878

if mele ==2

9791

if mele ==2

9879

param_struct.flex=2;

9792

param_struct.flex=2;

9880

elseif mele==4

9793

elseif mele==4

9881

param_struct.flex=4;

9794

param_struct.flex=4;

9882

elseif mele==1

9795

elseif mele==1

9883

param_struct.flex=1;

9796

param_struct.flex=1;

9884

else

9797

else

9885

error('config file syntax error')

9798

error('config file syntax error')

9886

end

9799

end

9887

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9800

param_struct.z_p_next_cases = xls_parameter(parameter, 'z_p (NEXT)', true).'; % List of NEXT transmitter package trace lengths in mm, one per case

9888

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9801

[ncases1, mele1]=size(param_struct.z_p_next_cases);

9889

if ncases ~= ncases1 || mele ~= mele1

9802

if ncases ~= ncases1 || mele ~= mele1

9890

error('All TX, NEXT, FEXT, Rx cases must agree');

9803

error('All TX, NEXT, FEXT, Rx cases must agree');

9891

else

9804

else

9892

end

9805

end

9893

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9806

param_struct.z_p_fext_cases = xls_parameter(parameter, 'z_p (FEXT)', true).'; % List of FEXT transmitter package trace lengths in mm, one per case

9894

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9807

[ncases1, mele1]=size(param_struct.z_p_fext_cases);

9895

if ncases ~= ncases1 || mele ~= mele1

9808

if ncases ~= ncases1 || mele ~= mele1

9896

error('All TX, NEXT, FEXT, Rx cases must agree');

9809

error('All TX, NEXT, FEXT, Rx cases must agree');

9897

else

9810

else

9898

end

9811

end

9899

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9812

param_struct.z_p_rx_cases = xls_parameter(parameter, 'z_p (RX)', true).'; % List of FEXT receiver package trace lengths in mm, one per case

9900

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9813

[ncases1, mele1]=size(param_struct.z_p_rx_cases);

9901

if ncases ~= ncases1 || mele ~= mele1

9814

if ncases ~= ncases1 || mele ~= mele1

9902

error('All TX, NEXT, FEXT, Rx cases must agree');

9815

error('All TX, NEXT, FEXT, Rx cases must agree');

9903

else

9816

else

9904

end

9817

end

9905

% Table 93A-3 parameters

9818

% Table 93A-3 parameters

9906

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9819

param_struct.pkg_gamma0_a1_a2 = xls_parameter(parameter, 'package_tl_gamma0_a1_a2', true, [0 1.734e-3 1.455e-4]); %Fitting parameters for package model per unit length. First element is in 1/mm and affects DC loss of package model . Second element is in ns1/2/mm and affects loss proportional to sqrt(f). Third element is in ns/mm and affects loss proportional to f.

9907

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9820

param_struct.pkg_tau = xls_parameter(parameter, 'package_tl_tau', true, 6.141e-3); % Package model transmission line delay ns/mm

9908

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9821

param_struct.pkg_Z_c = xls_parameter(parameter, 'package_Z_c', true, 78.2).';% Package model transmission line characteristic impedance [ Tx , Rx ]

9909

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9822

[ ncases1, mele1]=size(param_struct.pkg_Z_c);%

9910

if mele ~= mele1

9823

if mele ~= mele1

9911

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9824

error('tx rx pairs must have thesame number element entries as TX, NEXT, FEXT, Rx');

9912

else

9825

else

9913

end

9826

end

9914

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9827

if mele1==2 % fuill in a array if only a 2 element flex package is specified

9915

for ii=1:ncases

9828

for ii=1:ncases

9916

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9829

param_struct.z_p_fext_casesx(ii,:)= [param_struct.z_p_fext_cases(ii,:)' ;[ 0 ; 0 ]]';

9917

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9830

param_struct.z_p_next_casesx(ii,:)= [param_struct.z_p_next_cases(ii,:)' ;[ 0 ; 0 ]]';

9918

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9831

param_struct.z_p_tx_casesx(ii,:)= [param_struct.z_p_tx_cases(ii,:)' ;[ 0 ; 0 ]]';

9919

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9832

param_struct.z_p_rx_casesx(ii,:)= [param_struct.z_p_rx_cases(ii,:)' ;[ 0 ; 0 ]]';

9920

end

9833

end

9921

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9834

param_struct.z_p_fext_cases = param_struct.z_p_fext_casesx;

9922

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9835

param_struct.z_p_next_cases= param_struct.z_p_next_casesx;

9923

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9836

param_struct.z_p_tx_cases= param_struct.z_p_tx_casesx;

9924

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9837

param_struct.z_p_rx_cases= param_struct.z_p_rx_casesx;

9925

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9838

param_struct.pkg_Z_c=[param_struct.pkg_Z_c' ;[ 100 100 ; 100 100 ]]';

9926

end

9839

end

9927

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9840

function [chdata,SDDch,SDDp2p] = read_s4p_files(param, OP, chdata)

9928

%% extract s-parameter and convert to differential mode

9841

%% extract s-parameter and convert to differential mode

9929

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9842

% extract s-parameter data from files and apply tx and rx filters as well as package filters

9930

num_files=length(chdata);

9843

num_files=length(chdata);

9931

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9844

if ~OP.DISPLAY_WINDOW, fprintf('reading file '); end

9932

for i=1:num_files

9845

for i=1:num_files

9933

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9846

if OP.DISPLAY_WINDOW; hwaitbar=waitbar(0);end

9934

progress = i/num_files;

9847

progress = i/num_files;

9935

if OP.DISPLAY_WINDOW

9848

if OP.DISPLAY_WINDOW

9936

[~,a]=fileparts(chdata(i).filename);

9849

[~,a]=fileparts(chdata(i).filename);

9937

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9850

waitbar(progress, hwaitbar, ['Processing ' a]); figure(hwaitbar); drawnow;

9938

else

9851

else

9939

fprintf('%i ',i);

9852

fprintf('%i ',i);

9940

end

9853

end

9941

9854

9942

% Skip reading file if it was already read (multiple test cases)

9855

% Skip reading file if it was already read (multiple test cases)

9943

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9856

if (~isfield(chdata(i), 'faxis')) || isempty(chdata(i).faxis)

9944

switch lower(chdata(i).ext)

9857

switch lower(chdata(i).ext)

9945

case '.s2p' % for differential return loss

9858

case '.s2p' % for differential return loss

9946

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9859

[Sch,SDDch] = read_p2_s2params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP);

9947

chdata(i).fmaxi = length(Sch.freq);

9860

chdata(i).fmaxi = length(Sch.freq);

9948

chdata(i).faxis = Sch.freq;

9861

chdata(i).faxis = Sch.freq;

9949

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9862

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9950

SDDp2p(i)=NaN;

9863

SDDp2p(i)=NaN;

9951

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9864

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9952

chdata(i).sdd11=chdata(i).sdd11_raw;

9865

chdata(i).sdd11=chdata(i).sdd11_raw;

9953

case '.s4p'

9866

case '.s4p'

9954

if length(param.snpPortsOrder) ~= 4

9867

if length(param.snpPortsOrder) ~= 4

9955

error( 'warning:sNpFilePortMismatch', ...

9868

error( 'warning:sNpFilePortMismatch', ...

9956

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9869

'\n\t The number of ports defined (%G) does not match the sNp file type (%s)', ...

9957

length(param.snpPortsOrder), ...

9870

length(param.snpPortsOrder), ...

9958

chdata(i).ext ...

9871

chdata(i).ext ...

9959

);

9872

);

9960

end

9873

end

9961

% read function returns differnetial mode parameters

9874

% read function returns differnetial mode parameters

9962

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9875

if param.package_testcase_i==1 % added to speed up cases e.g. don't read file in twice

9963

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9876

[Sch, SDDch, SDCch] = read_p4_s4params(chdata(i).filename, 0, 0, param.snpPortsOrder, OP,param);

9964

% param.holdsdata(i).Sch= Sch;

9877

% param.holdsdata(i).Sch= Sch;

9965

% param.holdsdata(i).SDDch= SDDch;

9878

% param.holdsdata(i).SDDch= SDDch;

9966

% param.holdsdata(i).SDCch= SDCch;

9879

% param.holdsdata(i).SDCch= SDCch;

9967

else

9880

else

9968

error('If this line is reached, there is a logic error');

9881

error('If this line is reached, there is a logic error');

9969

% Sch=param.holdsdata(i).Sch;

9882

% Sch=param.holdsdata(i).Sch;

9970

% SDDch=param.holdsdata(i).SDDch;

9883

% SDDch=param.holdsdata(i).SDDch;

9971

% SDCch=param.holdsdata(i).SDCch;

9884

% SDCch=param.holdsdata(i).SDCch;

9972

end

9885

end

9973

chdata(i).fmaxi = length(Sch.freq);

9886

chdata(i).fmaxi = length(Sch.freq);

9974

9887

9975

9888

9976

if Sch.freq(chdata(i).fmaxi) < param.fb

9889

if Sch.freq(chdata(i).fmaxi) < param.fb

9977

warning('COM:read_s4p:MaxFreqTooLow', ...

9890

warning('COM:read_s4p:MaxFreqTooLow', ...

9978

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9891

'In %s: the maximum frequency provided, %g, is less than the signaling rate: %g', ...

9979

chdata(i).filename, Sch.freq(end), param.fb);

9892

chdata(i).filename, Sch.freq(end), param.fb);

9980

end

9893

end

9981

if Sch.freq(1) > param.max_start_freq

9894

if Sch.freq(1) > param.max_start_freq

9982

warning('COM:read_s4p:StartFreqTooHigh', ...

9895

warning('COM:read_s4p:StartFreqTooHigh', ...

9983

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9896

'In %s: minimum frequency, %.2g GHz, is larger than the recommended %.2g GHz', ...

9984

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9897

chdata(i).filename, Sch.freq(1)/1e9, param.max_start_freq/1e9);

9985

end

9898

end

9986

freqstep=diff(Sch.freq);

9899

freqstep=diff(Sch.freq);

9987

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9900

% ignore frequency differences up to 1 Hz - possible numerical artifacts

9988

if max(freqstep)-min(freqstep) > 1

9901

if max(freqstep)-min(freqstep) > 1

9989

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9902

warning('COM:read_s4p:NonUniformFreqSpacing', 'In %s: non-uniform frequency steps: min=%.3g GHz, max=%.3g GHz', ...

9990

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9903

chdata(i).filename, min(freqstep)/1e9, max(freqstep)/1e9);

9991

end

9904

end

9992

if max(freqstep) - param.max_freq_step > 1

9905

if max(freqstep) - param.max_freq_step > 1

9993

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9906

warning('COM:read_s4p:FreqStepTooHigh', 'In %s: frequency step, %.2g GHz, is larger than the recommended %.2g GHz', ...

9994

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9907

chdata(i).filename, max(freqstep)/1e9, param.max_freq_step/1e9);

9995

end

9908

end

9996

9909

9997

chdata(i).faxis = Sch.freq;

9910

chdata(i).faxis = Sch.freq;

9998

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9911

chdata(i).sdd12_raw = transpose(SDDch(1:chdata(i).fmaxi,1,2));

9999

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

9912

chdata(i).sdd21_raw = transpose(SDDch(1:chdata(i).fmaxi,2,1));

10000

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

9913

chdata(i).sdd22_raw = transpose(SDDch(1:chdata(i).fmaxi,2,2));

10001

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

9914

chdata(i).sdd11_raw = transpose(SDDch(1:chdata(i).fmaxi,1,1));

10002

% mode conversion

9915

% mode conversion

10003

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

9916

chdata(i).sdc12_raw = transpose(SDCch(1:chdata(i).fmaxi,1,2));

10004

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

9917

chdata(i).sdc21_raw = transpose(SDCch(1:chdata(i).fmaxi,2,1));

10005

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

9918

chdata(i).sdc22_raw = transpose(SDCch(1:chdata(i).fmaxi,2,2));

10006

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

9919

chdata(i).sdc11_raw = transpose(SDCch(1:chdata(i).fmaxi,1,1));

10007

%save original and add board (if required)

9920

%save original and add board (if required)

10008

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

9921

chdata(i).sdd11_orig=chdata(i).sdd11_raw;

10009

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

9922

chdata(i).sdd22_orig=chdata(i).sdd22_raw;

10010

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

9923

chdata(i).sdd12_orig=chdata(i).sdd12_raw;

10011

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

9924

chdata(i).sdd21_orig=chdata(i).sdd21_raw;

10012

if OP.include_pcb

9925

if OP.include_pcb

10013

% add boards to sdd

9926

% add boards to sdd

10014

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

9927

[chdata(i).sdd11_raw, chdata(i).sdd12_raw, chdata(i).sdd21_raw, chdata(i).sdd22_raw] = add_brd(chdata(i), param, OP);

10015

9928

10016

end

9929

end

10017

%save final return loss (after the boards were included)

9930

%save final return loss (after the boards were included)

10018

chdata(i).sdd11=chdata(i).sdd11_raw;

9931

chdata(i).sdd11=chdata(i).sdd11_raw;

10019

chdata(i).sdd22=chdata(i).sdd22_raw;

9932

chdata(i).sdd22=chdata(i).sdd22_raw;

10020

otherwise

9933

otherwise

10021

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

9934

error('Extension "%s" in file "%s" is not supported',chdata(i).ext,chdata(i).filename);

10022

end

9935

end

10023

9936

10024

%Crosstalk frequency axis must be the same as Thru

9937

%Crosstalk frequency axis must be the same as Thru

10025

if i>1

9938

if i>1

10026

%error on length difference

9939

%error on length difference

10027

if length(chdata(i).faxis)~=length(chdata(1).faxis)

9940

if length(chdata(i).faxis)~=length(chdata(1).faxis)

10028

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

9941

error('Crosstalk file "%s" has different number of frequency points',chdata(i).filename);

10029

end

9942

end

10030

%error if any value > 1Hz (don't want to check for exact

9943

%error if any value > 1Hz (don't want to check for exact

10031

%equality in case of floating point error)

9944

%equality in case of floating point error)

10032

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

9945

Fdiff=abs(chdata(i).faxis-chdata(1).faxis);

10033

if max(Fdiff)>1

9946

if max(Fdiff)>1

10034

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

9947

error('Crosstalk file "%s" has a different frequency axis',chdata(i).filename);

10035

end

9948

end

10036

end

9949

end

10037

else

9950

else

10038

SDDch(:,1,2)=chdata(i).sdd12_raw;

9951

SDDch(:,1,2)=chdata(i).sdd12_raw;

10039

SDDch(:,2,1)=chdata(i).sdd21_raw;

9952

SDDch(:,2,1)=chdata(i).sdd21_raw;

10040

SDDch(:,1,1)=chdata(i).sdd11_raw;

9953

SDDch(:,1,1)=chdata(i).sdd11_raw;

10041

SDDch(:,2,2)=chdata(i).sdd22_raw;

9954

SDDch(:,2,2)=chdata(i).sdd22_raw;

10042

end

9955

end

10043

chdata(i).sigma_ACCM_at_tp0=0;

9956

chdata(i).sigma_ACCM_at_tp0=0;

10044

if ~param.FLAG.S2P

9957

if ~param.FLAG.S2P

10045

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

9958

if OP.INC_PACKAGE ~= 0 || (OP.RX_CALIBRATION == 1 && i==1)

10046

if (OP.RX_CALIBRATION == 1 && i==2)

9959

if (OP.RX_CALIBRATION == 1 && i==2)

10047

chdata(i).sdd21=chdata(i).sdd21_raw;

9960

chdata(i).sdd21=chdata(i).sdd21_raw;

10048

else

9961

else

10049

%updated package construction with single function for both DD and DC

9962

%updated package construction with single function for both DD and DC

10050

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

9963

[chdata(i).sdd21p,SDDp2p(i)]= s21_pkg(chdata(i), param, OP, i);

10051

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

9964

[chdata(i).sdd21p_nodie]= s21_pkg(chdata(i), param, OP, i, 'dd', 0);

10052

chdata(i).sdd21=chdata(i).sdd21p;

9965

chdata(i).sdd21=chdata(i).sdd21p;

10053

if 1 % for AC CM noise inclusion

9966

if 1 % for AC CM noise inclusion

10054

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

9967

[chdata(i).sdc21p,SDCp2p(i),chdata(i).sigma_ACCM_at_tp0]= s21_pkg(chdata(i), param, OP, i,'dc');

10055

chdata(i).sdc21=chdata(i).sdc21p;

9968

chdata(i).sdc21=chdata(i).sdc21p;

10056

end

9969

end

10057

end

9970

end

10058

else

9971

else

10059

chdata(i).sdd21=chdata(i).sdd21_raw;

9972

chdata(i).sdd21=chdata(i).sdd21_raw;

10060

end

9973

end

10061

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

9974

chdata(i).sdd21f=chdata(i).sdd21_orig; % used for FD analysis i.e. not filtered (RIM 9/24/2021 without boards or packages)

10062

end

9975

end

10063

end

9976

end

10064

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

9977

if ~OP.DISPLAY_WINDOW, fprintf('\n'); end

10065

9978

10066

function result = readdataSnPx(filename, nport)

9979

function result = readdataSnPx(filename, nport)

10067

%function [freq, cs] = readdataSnPx(filename, nport)

9980

%function [freq, cs] = readdataSnPx(filename, nport)

10068

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

9981

% [freq, cs] = readdataSnP(filename, nport, format, nheader)

10069

%

9982

%

10070

% Read Touchstone file with frequencies in units of Hertz

9983

% Read Touchstone file with frequencies in units of Hertz

10071

%

9984

%

10072

% Input:

9985

% Input:

10073

% ======

9986

% ======

10074

% filename: Name of the Touchstone/SnP file

9987

% filename: Name of the Touchstone/SnP file

10075

% nport: Number of ports

9988

% nport: Number of ports

10076

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

9989

% format: 'RI' for real/imag, 'MA' for mag/angle (check option line in the

10077

% Touchstone file)

9990

% Touchstone file)

10078

% nheader: Number of header lines (comment lines plus option line in the

9991

% nheader: Number of header lines (comment lines plus option line in the

10079

% Touchstone file)

9992

% Touchstone file)

10080

%

9993

%

10081

% Output:

9994

% Output:

10082

% =======

9995

% =======

10083

% freq: Vector of frequencies [Hz]

9996

% freq: Vector of frequencies [Hz]

10084

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

9997

% cs: 3-D array of complex-valued S parameters where cs(i,j,k) is S(i,j)

10085

% at frequency freq(k)

9998

% at frequency freq(k)

10086

%

9999

%

10087

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10000

% Note: If frequency unit is not Hertz (but GHz, MHz etc.) simply scale

10088

% frequencies appropriately after reading the data.

10001

% frequencies appropriately after reading the data.

10089

%

10002

%

10090

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10003

% Ref.: Touchstone(R) File Format Specification, Rev.1.1,

10091

% EIA/IBIS Open Forum, 2002.

10004

% EIA/IBIS Open Forum, 2002.

10092

%

10005

%

10093

% Written by Henning Braunisch, September 2004.

10006

% Written by Henning Braunisch, September 2004.

10094

% Updated by Steven Krooswyk, April 2006.

10007

% Updated by Steven Krooswyk, April 2006.

10095

10008

10096

10009

10097

fid = fopen(filename, 'r');

10010

fid = fopen(filename, 'r');

10098

10011

10099

10012

10100

% Skip header lines

10013

% Skip header lines

10101

str = ' ';

10014

str = ' ';

10102

n = 0;

10015

n = 0;

10103

while ~strcmp(str(1),'#')

10016

while ~strcmp(str(1),'#')

10104

str = fgetl(fid);

10017

str = fgetl(fid);

10105

if isempty(str)

10018

if isempty(str)

10106

str=' ' ;

10019

str=' ' ;

10107

if n > 1000

10020

if n > 1000

10108

display('error: could not find config line (#)')

10021

display('error: could not find config line (#)')

10109

break

10022

break

10110

end

10023

end

10111

end

10024

end

10112

n = n + 1;

10025

n = n + 1;

10113

end

10026

end

10114

10027

10115

% parse configuration line

10028

% parse configuration line

10116

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10029

A=sscanf(str,'%1s %2s %1s %2s %1s %2s',[1,inf]);

10117

p = find(A=='S'); %position of 'S'

10030

p = find(A=='S'); %position of 'S'

10118

units = lower(A(2:p-1)); %units before 'S'

10031

units = lower(A(2:p-1)); %units before 'S'

10119

format = A(p+1:p+2); %format after 'S'

10032

format = A(p+1:p+2); %format after 'S'

10120

10033

10121

% skip any more header lines

10034

% skip any more header lines

10122

%while ~str

10035

%while ~str

10123

10036

10124

nk = 0; % frequency counter

10037

nk = 0; % frequency counter

10125

while 1

10038

while 1

10126

10039

10127

[temp, count] = fscanf(fid, '%f', 1);

10040

[temp, count] = fscanf(fid, '%f', 1);

10128

if count == 0

10041

if count == 0

10129

temp2 = fscanf(fid, '%s', 1);

10042

temp2 = fscanf(fid, '%s', 1);

10130

if ~isempty(temp2), fgetl(fid); continue, end;

10043

if ~isempty(temp2), fgetl(fid); continue, end;

10131

break

10044

break

10132

end

10045

end

10133

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10046

nk = nk+1; freq(1,nk) = temp; %#ok<AGROW>

10134

for ni = 1:nport

10047

for ni = 1:nport

10135

for nj = 1:nport

10048

for nj = 1:nport

10136

switch lower(format)

10049

switch lower(format)

10137

case 'ma'

10050

case 'ma'

10138

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10051

mag = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10139

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10052

cs(ni,nj,nk) = mag * exp(1i*ang*pi/180); %#ok<AGROW>

10140

case 'ri'

10053

case 'ri'

10141

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10054

re = fscanf(fid, '%f', 1); im = fscanf(fid, '%f', 1);

10142

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10055

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10143

case 'db'

10056

case 'db'

10144

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10057

db = fscanf(fid, '%f', 1); ang = fscanf(fid, '%f', 1);

10145

M = 10^(db/20);

10058

M = 10^(db/20);

10146

%re = M*cos(ang);

10059

%re = M*cos(ang);

10147

%im = M*sin(ang);

10060

%im = M*sin(ang);

10148

re = M*cos(ang * pi / 180);

10061

re = M*cos(ang * pi / 180);

10149

im = M*sin(ang * pi / 180);

10062

im = M*sin(ang * pi / 180);

10150

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10063

cs(ni,nj,nk) = complex(re, im); %#ok<AGROW>

10151

otherwise

10064

otherwise

10152

error('readdataSnP: Unknown data format');

10065

error('readdataSnP: Unknown data format');

10153

end

10066

end

10154

end

10067

end

10155

end

10068

end

10156

end

10069

end

10157

10070

10158

fclose(fid);

10071

fclose(fid);

10159

10072

10160

% If 2-port then swap S_12 and S_21 per Touchstone spec

10073

% If 2-port then swap S_12 and S_21 per Touchstone spec

10161

if nport == 2

10074

if nport == 2

10162

temp = cs(2,1,:);

10075

temp = cs(2,1,:);

10163

cs(2,1,:) = cs(1,2,:);

10076

cs(2,1,:) = cs(1,2,:);

10164

cs(1,2,:) = temp;

10077

cs(1,2,:) = temp;

10165

end

10078

end

10166

10079

10167

% Update freq units to Hz

10080

% Update freq units to Hz

10168

switch lower(units)

10081

switch lower(units)

10169

case 'hz'

10082

case 'hz'

10170

10083

10171

case 'khz'

10084

case 'khz'

10172

freq=freq.*1e3;

10085

freq=freq.*1e3;

10173

case 'mhz'

10086

case 'mhz'

10174

freq=freq.*1e6;

10087

freq=freq.*1e6;

10175

case 'ghz'

10088

case 'ghz'

10176

freq=freq.*1e9;

10089

freq=freq.*1e9;

10177

end

10090

end

10178

10091

10179

% passivity check

10092

% passivity check

10180

result.freq = freq;

10093

result.freq = freq;

10181

result.cs = cs;

10094

result.cs = cs;

10182

10095

10183

function recolor_plots(ax)

10096

function recolor_plots(ax)

10184

10097

10185

if ~verLessThan('matlab', '8.4.0')

10098

if ~verLessThan('matlab', '8.4.0')

10186

return

10099

return

10187

end

10100

end

10188

colors='brgcmk';

10101

colors='brgcmk';

10189

ch=flipud(get(ax, 'children'));

10102

ch=flipud(get(ax, 'children'));

10190

10103

10191

for k=1:length(ch)

10104

for k=1:length(ch)

10192

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10105

set(ch(k), 'Color', colors(mod(k-1, length(colors))+1));

10193

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10106

set(ch(k), 'LineWidth', 2*floor((k-1)/length(colors))+1);

10194

end

10107

end

10195

legend (ax, 'off');

10108

legend (ax, 'off');

10196

warning('off', 'MATLAB:legend:PlotEmpty');

10109

warning('off', 'MATLAB:legend:PlotEmpty');

10197

set(legend (ax, 'show'), 'interp', 'none');

10110

set(legend (ax, 'show'), 'interp', 'none');

10198

10111

10199

function result = reduce(var1)

10112

function result = reduce(var1)

10200

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10113

% --- Reduce 1x1xn array to 1xn (aka squeeze)

10201

out = zeros(1,length(var1));

10114

out = zeros(1,length(var1));

10202

out(1,:) = var1(1,1,:);

10115

out(1,:) = var1(1,1,:);

10203

result=out;

10116

result=out;

10204

10117

10205

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10118

function [s21p,SCH,sigma_ACCM_at_tp0] = s21_pkg(chdata, param, OP, channel_number,mode,include_die)

10206

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10119

% concatenates package reflections with s21,s11,and s22 with spec return loss (gammas)

10207

% faxis is the frequency array

10120

% faxis is the frequency array

10208

% s21, s11, s22 are the corresponding array of differential parameters

10121

% s21, s11, s22 are the corresponding array of differential parameters

10209

% s21p includes the VFT and Tx filter if include_die=1

10122

% s21p includes the VFT and Tx filter if include_die=1

10210

if nargin<6

10123

if nargin<6

10211

include_die=1;

10124

include_die=1;

10212

end

10125

end

10213

if nargin<5

10126

if nargin<5

10214

mode='dd';

10127

mode='dd';

10215

end

10128

end

10216

10129

10217

s21=chdata.(['s' mode '21_raw']);

10130

s21=chdata.(['s' mode '21_raw']);

10218

s12=chdata.(['s' mode '12_raw']);

10131

s12=chdata.(['s' mode '12_raw']);

10219

s11=chdata.(['s' mode '11_raw']);

10132

s11=chdata.(['s' mode '11_raw']);

10220

s22=chdata.(['s' mode '22_raw']);

10133

s22=chdata.(['s' mode '22_raw']);

10221

faxis=chdata.faxis;

10134

faxis=chdata.faxis;

10222

channel_type=chdata.type;

10135

channel_type=chdata.type;

10223

10136

10224

if strcmpi(mode,'dd')

10137

if strcmpi(mode,'dd')

10225

s11=s11*param.kappa1;

10138

s11=s11*param.kappa1;

10226

s22=s22*param.kappa2;

10139

s22=s22*param.kappa2;

10227

end

10140

end

10228

10141

10229

10142

10230

Z0=param.Z0;

10143

Z0=param.Z0;

10231

%sigma_ACCM_at_tp0 is only used when mode=DC

10144

%sigma_ACCM_at_tp0 is only used when mode=DC

10232

sigma_ACCM_at_tp0=0;

10145

sigma_ACCM_at_tp0=0;

10233

10146

10234

% The following three parameters have possibly different valuesF for TX and

10147

% The following three parameters have possibly different valuesF for TX and

10235

% RX (so can be 2-element vectors).

10148

% RX (so can be 2-element vectors).

10236

R_diepad = param.R_diepad;

10149

R_diepad = param.R_diepad;

10237

10150

10238

%Make TX Package

10151

%Make TX Package

10239

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10152

[ s11out, s12out, s21out, s22out]=make_full_pkg('TX',faxis,param,channel_type,mode,include_die);

10240

10153

10241

%Make RX Package

10154

%Make RX Package

10242

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10155

%Important: RX pkg doesn't change based on mode being dd or dc. So 'dd' is always passed

10243

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10156

[ s11in, s12in, s21in, s22in]=make_full_pkg('RX',faxis,param,channel_type,'dd',include_die);

10244

10157

10245

10158

10246

% p(1 ,1, :)=s11in;

10159

% p(1 ,1, :)=s11in;

10247

% p(2 ,2, :)=s22in;

10160

% p(2 ,2, :)=s22in;

10248

% p(1 ,2, :)=s12in;

10161

% p(1 ,2, :)=s12in;

10249

% p(2 ,1, :)=s21in;

10162

% p(2 ,1, :)=s21in;

10250

%

10163

%

10251

% S=sparameters(p,faxis);

10164

% S=sparameters(p,faxis);

10252

% rfwrite(S,'temp.s4p');

10165

% rfwrite(S,'temp.s4p');

10253

10166

10254

if strcmpi(mode,'dc')

10167

if strcmpi(mode,'dc')

10255

RTX=R_diepad(param.Tx_rd_sel)/2;

10168

RTX=R_diepad(param.Tx_rd_sel)/2;

10256

RRX=R_diepad(param.Rx_rd_sel)/2;

10169

RRX=R_diepad(param.Rx_rd_sel)/2;

10257

Z0gamma=Z0/2;

10170

Z0gamma=Z0/2;

10258

else

10171

else

10259

RTX=R_diepad(param.Tx_rd_sel);

10172

RTX=R_diepad(param.Tx_rd_sel);

10260

RRX=R_diepad(param.Rx_rd_sel);

10173

RRX=R_diepad(param.Rx_rd_sel);

10261

Z0gamma=Z0;

10174

Z0gamma=Z0;

10262

end

10175

end

10263

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10176

if OP.IDEAL_TX_TERM || (OP.RX_CALIBRATION == 1 && channel_number == 2) || OP.include_pcb == 2

10264

gamma_tx=0;

10177

gamma_tx=0;

10265

else

10178

else

10266

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10179

gamma_tx=(RTX-Z0gamma)/(RTX+Z0gamma);% equation 93A-17

10267

end

10180

end

10268

if OP.IDEAL_RX_TERM

10181

if OP.IDEAL_RX_TERM

10269

gamma_rx=0;

10182

gamma_rx=0;

10270

else

10183

else

10271

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10184

gamma_rx=(RRX-Z0gamma)/(RRX+Z0gamma);% equation 93A-17

10272

end

10185

end

10273

10186

10274

if OP.INC_PACKAGE==0

10187

if OP.INC_PACKAGE==0

10275

s21p= s21;

10188

s21p= s21;

10276

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10189

warning('do not use INC_PACKAGE = 0. Instead use package parameters)');

10277

else

10190

else

10278

if OP.RX_CALIBRATION == 1 && channel_number == 2

10191

if OP.RX_CALIBRATION == 1 && channel_number == 2

10279

% for calibration do not include the transmitter package

10192

% for calibration do not include the transmitter package

10280

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10193

[s11out_rx, s12out_rx, s21out_rx, s22out_rx ] = combines4p( s11, s12, s21, s22, s22out, s12out, s21out, s11out ); %#ok<ASGLU> % s22 is ball side of package

10281

SCH.Frequencies=faxis;

10194

SCH.Frequencies=faxis;

10282

SCH.Parameters(1,1,:)=s11out_rx;

10195

SCH.Parameters(1,1,:)=s11out_rx;

10283

SCH.Parameters(2,2,:)=s22out_rx;

10196

SCH.Parameters(2,2,:)=s22out_rx;

10284

SCH.Parameters(1,2,:)=s12out_rx;

10197

SCH.Parameters(1,2,:)=s12out_rx;

10285

SCH.Parameters(2,1,:)=s21out_rx;

10198

SCH.Parameters(2,1,:)=s21out_rx;

10286

SCH.NumPorts=2;

10199

SCH.NumPorts=2;

10287

SCH.Impedance=100;

10200

SCH.Impedance=100;

10288

%% Equation 93A-18

10201

%% Equation 93A-18

10289

if include_die

10202

if include_die

10290

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10203

s21p= s21out_rx.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11out_rx.*gamma_tx - s22out_rx.*gamma_rx -s21out_rx.^2.*gamma_tx.*gamma_rx +s11out_rx.*s22out_rx.*gamma_tx.*gamma_rx);

10291

else

10204

else

10292

s21p=s21out_rx; % if no die we do not want a VTF

10205

s21p=s21out_rx; % if no die we do not want a VTF

10293

end

10206

end

10294

else

10207

else

10295

%% Equations 93A-4 to 93A-7

10208

%% Equations 93A-4 to 93A-7

10296

if ~OP.IDEAL_TX_TERM

10209

if ~OP.IDEAL_TX_TERM

10297

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10210

[s11, s12, s21, s22] = combines4p( s11out, s12out, s21out, s22out, s11, s12, s21, s22 ); %#ok<ASGLU>

10298

end

10211

end

10299

H_t=ones(1,length(faxis)); % .3bj compatibility

10212

H_t=ones(1,length(faxis)); % .3bj compatibility

10300

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10213

if OP.IDEAL_TX_TERM || OP.T_r_filter_type == 1

10301

% for RITT testing with good termination as in some instruments

10214

% for RITT testing with good termination as in some instruments

10302

% and tx filter when required

10215

% and tx filter when required

10303

if OP.T_r_filter_type==0

10216

if OP.T_r_filter_type==0

10304

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10217

H_t = exp(-(pi*faxis/1e9*OP.transmitter_transition_time/1.6832).^2); %% Equation 93A-46 %%

10305

else

10218

else

10306

tr=OP.transmitter_transition_time;

10219

tr=OP.transmitter_transition_time;

10307

f9=faxis/1e9;

10220

f9=faxis/1e9;

10308

if OP.T_r_meas_point == 1

10221

if OP.T_r_meas_point == 1

10309

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10222

k=1.9466+7.12*sqrt(1-6.51e-3/tr);

10310

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10223

H_t=105./(f9.^4*(k*tr)^4 - f9.^3*(k*tr)^3*10i - 45*f9.^2*(k*tr)^2 + f9*(k*tr)*105i + 105);

10311

else

10224

else

10312

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10225

H_t = exp( -2*(pi*f9*tr/1.6832).^2 ).*exp(-1j*2*pi*f9*tr*3);

10313

end

10226

end

10314

10227

10315

end

10228

end

10316

end

10229

end

10317

if strcmpi(mode,'dc')

10230

if strcmpi(mode,'dc')

10318

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10231

% H_t=ones(1,length(faxis)); % not sure if we need a H_t or not. Is the CM noise correlated to the edge rate?

10319

end

10232

end

10320

if ~OP.IDEAL_RX_TERM

10233

if ~OP.IDEAL_RX_TERM

10321

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10234

[s11, s12, s21, s22] = combines4p( s11, s12, s21, s22, s22in, s21in, s12in, s11in ); %#ok<ASGLU> % s22 is ball side of package

10322

else

10235

else

10323

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10236

warning('do not use IDEAL_RX_TERM. Instead hard code package and TR parameters')

10324

end

10237

end

10325

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10238

%% Equation 93A-18 and part of 93A-1: Ht fix in V290 identified by Bill Kirkland and Ed Frlan ( s21^2 changed to s12*s21 )

10326

if include_die

10239

if include_die

10327

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10240

s21p= H_t.*s21.*(1-gamma_tx).*(1+gamma_rx)./(1.- s11.*gamma_tx - s22.*gamma_rx -s21.*s12.*gamma_tx.*gamma_rx +s11.*s22.*gamma_tx.*gamma_rx);

10328

else

10241

else

10329

s21p=s21; % if no die we do not want a VTF

10242

s21p=s21; % if no die we do not want a VTF

10330

end

10243

end

10331

end

10244

end

10332

10245

10333

if strcmpi(mode,'dc')

10246

if strcmpi(mode,'dc')

10334

% compute AC_CM_RMS at tp0

10247

% compute AC_CM_RMS at tp0

10335

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10248

OP.TX_BesselThomson=1; %AC CM is measured in scopes with at BT filter

10336

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10249

H_bt=Bessel_Thomson_Filter(param,faxis,OP.TX_BesselThomson);

10337

if channel_number == 1

10250

if channel_number == 1

10338

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10251

f_int= faxis( faxis<=param.ACCM_MAX_Freq );

10339

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10252

H_cc= s21out.*(1-gamma_tx)./(1.- s11out.*gamma_tx ).*H_bt;

10340

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10253

sigma_ACCM_at_tp0= sqrt(2*param.AC_CM_RMS_TX^2*sum( abs( H_cc(2:length(f_int)) ).^2 .* diff(f_int))/f_int(end)) ;

10341

% S=sparameters(p,faxis);

10254

% S=sparameters(p,faxis);

10342

% rfwrite(S,'temp.s4p');

10255

% rfwrite(S,'temp.s4p');

10343

end

10256

end

10344

end

10257

end

10345

10258

10346

SCH.Frequencies=faxis;

10259

SCH.Frequencies=faxis;

10347

SCH.Parameters(1,1,:)=s11;

10260

SCH.Parameters(1,1,:)=s11;

10348

SCH.Parameters(2,2,:)=s22;

10261

SCH.Parameters(2,2,:)=s22;

10349

SCH.Parameters(1,2,:)=s12;

10262

SCH.Parameters(1,2,:)=s12;

10350

SCH.Parameters(2,1,:)=s21;

10263

SCH.Parameters(2,1,:)=s21;

10351

SCH.NumPorts=2;

10264

SCH.NumPorts=2;

10352

if strcmpi(mode,'dc')

10265

if strcmpi(mode,'dc')

10353

SCH.Impedance=25;

10266

SCH.Impedance=25;

10354

else

10267

else

10355

SCH.Impedance=100;

10268

SCH.Impedance=100;

10356

end

10269

end

10357

10270

10358

end

10271

end

10359

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10272

function [voltage, t_base, causality_correction_dB, truncation_dB] = ...

10360

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10273

s21_to_impulse_DC(IL, freq_array, time_step, OP)

10361

% Creates a time-domain impulse response from frequency-domain IL data.

10274

% Creates a time-domain impulse response from frequency-domain IL data.

10362

% IL does not need to have DC but a corresponding frequency array

10275

% IL does not need to have DC but a corresponding frequency array

10363

% (freq_array) is required.

10276

% (freq_array) is required.

10364

%

10277

%

10365

% Causality is imposed using the Alternating Projections Method. See also:

10278

% Causality is imposed using the Alternating Projections Method. See also:

10366

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10279

% Quatieri and Oppenheim, "Iterative Techniques for Minimum Phase Signal

10367

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10280

% Reconstruction from Phase or Magnitude", IEEE Trans. ASSP-29, December

10368

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10281

% 1981 (http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=1163714)

10369

10282

10370

ILin=IL;

10283

ILin=IL;

10371

fmax=1/time_step/2;

10284

fmax=1/time_step/2;

10372

freq_step=(freq_array(3)-freq_array(2))/1;

10285

freq_step=(freq_array(3)-freq_array(2))/1;

10373

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10286

fout=0:1/round(fmax/freq_step)*fmax:fmax;

10374

if all(IL==0)

10287

if all(IL==0)

10375

%response with all zeros is problematic. set to all eps and avoid interp function

10288

%response with all zeros is problematic. set to all eps and avoid interp function

10376

IL=ones(1,length(fout))*eps;

10289

IL=ones(1,length(fout))*eps;

10377

else

10290

else

10378

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10291

IL=interp_Sparam(ILin,freq_array,fout, OP.interp_sparam_mag, OP.interp_sparam_phase,OP);

10379

IL_nan = find(isnan(IL));

10292

IL_nan = find(isnan(IL));

10380

for in=IL_nan

10293

for in=IL_nan

10381

IL(in)=IL(in-1);

10294

IL(in)=IL(in-1);

10382

end

10295

end

10383

end

10296

end

10384

IL = IL(:);

10297

IL = IL(:);

10385

% add padding for time steps

10298

% add padding for time steps

10386

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10299

% IL_symmetric = [IL(1:end-1);0; flipud(conj(IL(2:end-1)))];

10387

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10300

IL_symmetric = [real(IL(1)); IL(2:end-1); real(IL(end)); flipud(conj(IL(2:end-1)))];

10388

impulse_response = real(ifft(IL_symmetric));

10301

impulse_response = real(ifft(IL_symmetric));

10389

L = length(impulse_response);

10302

L = length(impulse_response);

10390

t_base = (0:L-1)/(freq_step*L);

10303

t_base = (0:L-1)/(freq_step*L);

10391

10304

10392

original_impulse_response=impulse_response;

10305

original_impulse_response=impulse_response;

10393

% Correct non-causal effects frequently caused by extrapolation of IL

10306

% Correct non-causal effects frequently caused by extrapolation of IL

10394

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10307

% Assumption: peak of impulse_response is in the first half, i.e. not anti-causal

10395

abs_ir=abs(impulse_response);

10308

abs_ir=abs(impulse_response);

10396

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10309

a = find(abs_ir(1:L/2) > max(abs_ir(1:L/2))*OP.EC_PULSE_TOL);

10397

start_ind = a(1);

10310

start_ind = a(1);

10398

10311

10399

err=inf;

10312

err=inf;

10400

while ~all(impulse_response==0)

10313

while ~all(impulse_response==0)

10401

impulse_response(1:start_ind)=0;

10314

impulse_response(1:start_ind)=0;

10402

impulse_response(floor(L/2):end)=0;

10315

impulse_response(floor(L/2):end)=0;

10403

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10316

IL_modified=abs(IL_symmetric).*exp(1j*angle(fft(impulse_response)));

10404

ir_modified = real(ifft(IL_modified));

10317

ir_modified = real(ifft(IL_modified));

10405

delta = abs(impulse_response-ir_modified);

10318

delta = abs(impulse_response-ir_modified);

10406

10319

10407

err_prev = err;

10320

err_prev = err;

10408

err=max(delta)/max(impulse_response);

10321

err=max(delta)/max(impulse_response);

10409

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10322

if err<OP.EC_REL_TOL || abs(err_prev-err)<OP.EC_DIFF_TOL

10410

break;

10323

break;

10411

end

10324

end

10412

10325

10413

impulse_response=ir_modified;

10326

impulse_response=ir_modified;

10414

end

10327

end

10415

10328

10416

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10329

causality_correction_dB=20*log10(norm(impulse_response-original_impulse_response)/norm(impulse_response));

10417

10330

10418

if ~OP.ENFORCE_CAUSALITY

10331

if ~OP.ENFORCE_CAUSALITY

10419

impulse_response = original_impulse_response;

10332

impulse_response = original_impulse_response;

10420

end

10333

end

10421

% truncate final samples smaller than 1e-3 of the peak

10334

% truncate final samples smaller than 1e-3 of the peak

10422

ir_peak = max(abs(impulse_response));

10335

ir_peak = max(abs(impulse_response));

10423

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10336

ir_last = find(abs(impulse_response)>ir_peak*OP.impulse_response_truncation_threshold, 1, 'last');

10424

10337

10425

voltage = impulse_response(1:ir_last);

10338

voltage = impulse_response(1:ir_last);

10426

t_base = t_base(1:ir_last);

10339

t_base = t_base(1:ir_last);

10427

10340

10428

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10341

truncation_dB=20*log10(norm(impulse_response(ir_last+1:end))/norm(voltage));

10429

10342

10430

function S =s_for_c2(zref,f,cpad)

10343

function S =s_for_c2(zref,f,cpad)

10431

% S is 2 port s parameters out

10344

% S is 2 port s parameters out

10432

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10345

S_Parameters(1,1,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10433

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10346

S_Parameters(2,2,:) = -1i*2*pi.*f*cpad*zref./(2+1i*2*pi.*f*cpad*zref);

10434

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10347

S_Parameters(2,1,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10435

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10348

S_Parameters(1,2,:) = 2./(2+1i*2*pi.*f*cpad*zref);

10436

S=sparameters(S_Parameters,f,zref);

10349

S=sparameters(S_Parameters,f,zref);

10437

10350

10438

function S =s_for_c4(zref,f,cpad)

10351

function S =s_for_c4(zref,f,cpad)

10439

10352

10440

S2 = s_for_c2(zref,f,cpad);

10353

S2 = s_for_c2(zref,f,cpad);

10441

S4P=s2_to_s4(S2.Parameters);

10354

S4P=s2_to_s4(S2.Parameters);

10442

S=sparameters(S4P,f,zref);

10355

S=sparameters(S4P,f,zref);

10443

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10356

S.Parameters=snp2smp(S.Parameters,zref,[ 1 3 2 4]);

10444

10357

10445

10358

10446

10359

10447

10360

10448

%%

10361

%%

10449

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10362

function [ cmd_str ] = save_cmd_line( config_file, chdata, num_fext,num_next, cli_name )

10450

% save commmend string

10363

% save commmend string

10451

% for saving from interactive queries

10364

% for saving from interactive queries

10452

10365

10453

10366

10454

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10367

cmd_str=[ cli_name '(' '''' config_file '''' ',' num2str(num_fext) ', ' num2str(num_next) ',' '''' chdata(1).filename ''''];

10455

for i=1:num_next+num_fext

10368

for i=1:num_next+num_fext

10456

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10369

cmd_str= [cmd_str ',' '''' chdata(i+1).filename ''''];

10457

end

10370

end

10458

cmd_str= [ cmd_str ')'];

10371

cmd_str= [ cmd_str ')'];

10459

10372

10460

10373

10461

%%%%% require the RF tool box

10374

%%%%% require the RF tool box

10462

%%

10375

%%

10463

function [ h ] = savefigs( param, OP )

10376

function [ h ] = savefigs( param, OP )

10464

10377

10465

%% find the figures

10378

%% find the figures

10466

hw = waitbar(0,'Saving figures...');

10379

hw = waitbar(0,'Saving figures...');

10467

h = findobj(0, 'Type', 'figure');

10380

h = findobj(0, 'Type', 'figure');

10468

for ii=1:length(h)

10381

for ii=1:length(h)

10469

10382

10470

figname= get(h(ii), 'Name'); % use the figure name as file name

10383

figname= get(h(ii), 'Name'); % use the figure name as file name

10471

if isempty(strfind(figname,param.base))

10384

if isempty(strfind(figname,param.base))

10472

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10385

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10473

end

10386

end

10474

if verLessThan('matlab', '8.4.0')

10387

if verLessThan('matlab', '8.4.0')

10475

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10388

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10476

else

10389

else

10477

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10390

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10478

end

10391

end

10479

figname = strrep(figname,':','-');

10392

figname = strrep(figname,':','-');

10480

figname = strrep(figname,' ','_');

10393

figname = strrep(figname,' ','_');

10481

if OP.SAVE_FIGURES==1

10394

if OP.SAVE_FIGURES==1

10482

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10395

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.fig']));

10483

end

10396

end

10484

%% get x y data

10397

%% get x y data

10485

if OP.SAVE_FIGURE_to_CSV==1

10398

if OP.SAVE_FIGURE_to_CSV==1

10486

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10399

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10487

M=[]; %ncol=1;

10400

M=[]; %ncol=1;

10488

for nk=1:length(h_L)

10401

for nk=1:length(h_L)

10489

% get x and data for a line.

10402

% get x and data for a line.

10490

x_data=get(h_L(nk),'xdata')';

10403

x_data=get(h_L(nk),'xdata')';

10491

y_data=get(h_L(nk),'ydata')';

10404

y_data=get(h_L(nk),'ydata')';

10492

% .........>> need to get data in the line structure (legend or label) for headers

10405

% .........>> need to get data in the line structure (legend or label) for headers

10493

M=[M; x_data; y_data]; %#ok<AGROW>

10406

M=[M; x_data; y_data]; %#ok<AGROW>

10494

end

10407

end

10495

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10408

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10496

% clear M y x header h_L

10409

% clear M y x header h_L

10497

end

10410

end

10498

waitbar(ii/length(h),hw)

10411

waitbar(ii/length(h),hw)

10499

10412

10500

end

10413

end

10501

10414

10502

close(hw)

10415

close(hw)

10503

10416

10504

%%

10417

%%

10505

function [ h ] = savefigs_png( param, OP )

10418

function [ h ] = savefigs_png( param, OP )

10506

10419

10507

%% find the figures

10420

%% find the figures

10508

hw = waitbar(0,'Saving figures...');

10421

hw = waitbar(0,'Saving figures...');

10509

h = findobj(0, 'Type', 'figure');

10422

h = findobj(0, 'Type', 'figure');

10510

for ii=1:length(h)

10423

for ii=1:length(h)

10511

10424

10512

figname= get(h(ii), 'Name'); % use the figure name as file name

10425

figname= get(h(ii), 'Name'); % use the figure name as file name

10513

if isempty(strfind(figname,param.base))

10426

if isempty(strfind(figname,param.base))

10514

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10427

figname = [figname ' ' OP.RUNTAG ' ' param.base ]; %#ok<AGROW>

10515

end

10428

end

10516

if verLessThan('matlab', '8.4.0')

10429

if verLessThan('matlab', '8.4.0')

10517

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10430

figname = ['f_' num2str(h(ii)) '_' figname]; %#ok<AGROW>

10518

else

10431

else

10519

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10432

figname = ['f_' num2str(h(ii).Number) '_' figname]; %#ok<AGROW>

10520

end

10433

end

10521

figname = strrep(figname,':','-');

10434

figname = strrep(figname,':','-');

10522

figname = strrep(figname,' ','_');

10435

figname = strrep(figname,' ','_');

10523

if OP.SAVE_FIGURES==1

10436

if OP.SAVE_FIGURES==1

10524

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10437

saveas(h(ii), fullfile(OP.RESULT_DIR, [figname '.png']));

10525

end

10438

end

10526

%% get x y data

10439

%% get x y data

10527

if OP.SAVE_FIGURE_to_CSV==1

10440

if OP.SAVE_FIGURE_to_CSV==1

10528

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10441

h_L = findobj(h(ii),'Type','line'); % find handles to all the lines

10529

M=[]; %ncol=1;

10442

M=[]; %ncol=1;

10530

for nk=1:length(h_L)

10443

for nk=1:length(h_L)

10531

% get x and data for a line.

10444

% get x and data for a line.

10532

x_data=get(h_L(nk),'xdata')';

10445

x_data=get(h_L(nk),'xdata')';

10533

y_data=get(h_L(nk),'ydata')';

10446

y_data=get(h_L(nk),'ydata')';

10534

% .........>> need to get data in the line structure (legend or label) for headers

10447

% .........>> need to get data in the line structure (legend or label) for headers

10535

M=[M; x_data; y_data]; %#ok<AGROW>

10448

M=[M; x_data; y_data]; %#ok<AGROW>

10536

end

10449

end

10537

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10450

csvwrite([OP.RESULT_DIR figname '.csv'],M);

10538

% clear M y x header h_L

10451

% clear M y x header h_L

10539

end

10452

end

10540

waitbar(ii/length(h),hw)

10453

waitbar(ii/length(h),hw)

10541

10454

10542

end

10455

end

10543

10456

10544

close(hw)

10457

close(hw)

10545

10458

10546

%%

10459

%%

10547

function pdf_out = scalePDF(pdf,scale_factor)

10460

function pdf_out = scalePDF(pdf,scale_factor)

10548

pdf_out=pdf;

10461

pdf_out=pdf;

10549

pdf_out.Min=floor(pdf.Min*scale_factor);

10462

pdf_out.Min=floor(pdf.Min*scale_factor);

10550

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10463

pdf_out.x=(pdf_out.Min:-pdf_out.Min)*pdf_out.BinSize;

10551

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10464

pdf_out.y=interp1(pdf.x*scale_factor,pdf.y,pdf_out.x);

10552

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10465

pdf_out.y(1)= pdf_out.y(2); % NAN interp work around

10553

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10466

pdf_out.y(end)= pdf_out.y(end-1); % NAN interp work around

10554

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10467

pdf_out.y=pdf_out.y/sum(pdf_out.y);

10555

function t_params = stot(s_params)

10468

function t_params = stot(s_params)

10556

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10469

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10557

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10470

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10558

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10471

[s11, s12, s21, s22] = deal(s_params(1,1,:), s_params(1,2,:), s_params(2,1,:), s_params(2,2,:));

10559

delta = (s11.*s22-s12.*s21);

10472

delta = (s11.*s22-s12.*s21);

10560

s21(s21==0)=eps;

10473

s21(s21==0)=eps;

10561

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10474

t_params = [1./s21, -s22./s21; s11./s21, -delta./s21];

10562

10475

10563

function csv_string = str2csv(c)

10476

function csv_string = str2csv(c)

10564

% convert a cell array of strings to a csv string

10477

% convert a cell array of strings to a csv string

10565

cell_tmp = cell(2, length(c));

10478

cell_tmp = cell(2, length(c));

10566

cell_tmp(1,:)=c;

10479

cell_tmp(1,:)=c;

10567

cell_tmp(2,:) = {','};

10480

cell_tmp(2,:) = {','};

10568

cell_tmp{2,end} = '';

10481

cell_tmp{2,end} = '';

10569

csv_string=strcat(cell_tmp{:});

10482

csv_string=strcat(cell_tmp{:});

10570

10483

10571

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10484

function [s11, s12, s21, s22] = synth_tline(f, Z_c, Z_0, gamma_coeff, tau, d)

10572

f_GHz=f/1e9;

10485

f_GHz=f/1e9;

10573

%% Equation 93A-10 %%

10486

%% Equation 93A-10 %%

10574

gamma_1 = gamma_coeff(2)*(1+1i);

10487

gamma_1 = gamma_coeff(2)*(1+1i);

10575

%% Equation 93A-11 %%

10488

%% Equation 93A-11 %%

10576

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10489

gamma_2 = gamma_coeff(3)*(1-2i/pi*log(f_GHz)) + 2i*pi*tau;

10577

%% Equation 93A-9 %%

10490

%% Equation 93A-9 %%

10578

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10491

gamma = gamma_coeff(1)+gamma_1.*sqrt(f_GHz)+gamma_2.*f_GHz;

10579

gamma(f_GHz==0) = gamma_coeff(1);

10492

gamma(f_GHz==0) = gamma_coeff(1);

10580

10493

10581

%% Equation 93A-12 %%

10494

%% Equation 93A-12 %%

10582

if d==0

10495

if d==0

10583

%force matched impedance if length is 0

10496

%force matched impedance if length is 0

10584

%otherwise divide by zero can occur if Z_c=0

10497

%otherwise divide by zero can occur if Z_c=0

10585

rho_rl=0;

10498

rho_rl=0;

10586

else

10499

else

10587

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10500

rho_rl=(Z_c-2*Z_0)/(Z_c+2*Z_0);

10588

end

10501

end

10589

10502

10590

exp_gamma_d = exp(-d*gamma);

10503

exp_gamma_d = exp(-d*gamma);

10591

%% Equations 93A-13 and 93A-14 %%

10504

%% Equations 93A-13 and 93A-14 %%

10592

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10505

s11 = rho_rl*(1-exp_gamma_d.^2)./(1-rho_rl^2*exp_gamma_d.^2);

10593

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10506

s21 = (1-rho_rl^2)*exp_gamma_d./(1-rho_rl^2*exp_gamma_d.^2);

10594

s12 = s21;

10507

s12 = s21;

10595

s22 = s11;

10508

s22 = s11;

10596

10509

10597

function s_params = ttos(t_params)

10510

function s_params = ttos(t_params)

10598

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10511

% p 67 R. Mavaddat. (1996). Network scattering parameter. Singapore: World Scientific.

10599

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10512

% ISBN 978-981-02-2305-2. http://books.google.com/?id=287g2NkRYxUC&lpg=PA65&dq=T-parameters+&pg=PA67.

10600

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10513

[t11, t12, t21, t22] = deal(t_params(1,1,:), t_params(1,2,:), t_params(2,1,:), t_params(2,2,:));

10601

delta = t11.*t22-t21.*t12;

10514

delta = t11.*t22-t21.*t12;

10602

t11(t11==0)=eps;

10515

t11(t11==0)=eps;

10603

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10516

s_params = [t21./t11, delta./t11; 1./t11, -t12./t11];

10604

10517

10605

function [out_var,varg_out]=varargin_extractor(varargin)

10518

function [out_var,varg_out]=varargin_extractor(varargin)

10606

10519

10607

if isempty(varargin)

10520

if isempty(varargin)

10608

out_var=[];

10521

out_var=[];

10609

varg_out={};

10522

varg_out={};

10610

else

10523

else

10611

out_var=varargin{1};

10524

out_var=varargin{1};

10612

varg_out=varargin;

10525

varg_out=varargin;

10613

varg_out(1)=[];

10526

varg_out(1)=[];

10614

end

10527

end

10615

10528

10616

10529

10617

function results= vma(PR, M)

10530

function results= vma(PR, M)

10618

% PR=sbr.Data;

10531

% PR=sbr.Data;

10619

% M=32;

10532

% M=32;

10620

% PR is the pulse response

10533

% PR is the pulse response

10621

% M is samples per UI

10534

% M is samples per UI

10622

[ seq, syms, syms_nrz ] = PRBS13Q( );

10535

[ seq, syms, syms_nrz ] = PRBS13Q( );

10623

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10536

% seq uses [ -1 -1/3 1/3 1] & syms uses [ 0 1 2 3 ]

10624

symbols=seq;

10537

symbols=seq;

10625

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10538

imaxPR=find(PR==max(PR),1,'first'); % find index for peak

10626

% start end symbols index for 7 3's and 6 0's

10539

% start end symbols index for 7 3's and 6 0's

10627

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10540

indx_S3x7_start=M*(strfind(syms,ones(1,7)*3)-1)+imaxPR;

10628

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10541

indx_S3x7_end=M*(strfind(syms,ones(1,7)*3)+5)+imaxPR;

10629

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10542

indx_S0x6_start=M*(strfind(syms,ones(1,6)*0))-1+imaxPR;

10630

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10543

indx_S0x6_end=M*(strfind(syms,ones(1,6)*0)+4)+imaxPR;

10631

% superposition code

10544

% superposition code

10632

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10545

shifting_vector=kron(symbols,[ 1 zeros(1,M-1) ]) ;

10633

Bit_stream_response=filter(PR,1, shifting_vector);

10546

Bit_stream_response=filter(PR,1, shifting_vector);

10634

% find center of 3's and 0's

10547

% find center of 3's and 0's

10635

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10548

icent3=floor((indx_S3x7_end-indx_S3x7_start)/2 + indx_S3x7_start);

10636

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10549

icent0=floor((indx_S0x6_end-indx_S0x6_start)/2 + indx_S0x6_start);

10637

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10550

% plot(Bit_stream_response(indx_S3x7_start:indx_S3x7_end))

10638

% hold on

10551

% hold on

10639

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10552

% plot(Bit_stream_response(indx_S0x6_start:indx_S0x6_end))

10640

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10553

P_3 = mean( Bit_stream_response((icent3-M):(icent3+M) ) );

10641

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10554

P_0 = mean( Bit_stream_response((icent0-M):(icent0+M) ) );

10642

VMA= P_3 - P_0;

10555

VMA= P_3 - P_0;

10643

results.P_3=P_3;

10556

results.P_3=P_3;

10644

results.P_0=P_0;

10557

results.P_0=P_0;

10645

results.VMA=VMA;

10558

results.VMA=VMA;

10646

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10559

function line_intersection=vref_intersect(eye_contour,x_in,vref)

10647

10560

10648

%slope of the 2 sample points around vref crossing

10561

%slope of the 2 sample points around vref crossing

10649

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10562

m1=(eye_contour(x_in,1)-eye_contour(x_in-1,1));

10650

%x-intercept for the line

10563

%x-intercept for the line

10651

b1=eye_contour(x_in,1)-m1*x_in;

10564

b1=eye_contour(x_in,1)-m1*x_in;

10652

% drawing a horizontal line through vref so slope = 0

10565

% drawing a horizontal line through vref so slope = 0

10653

m2=0;

10566

m2=0;

10654

%special case for horizontal line, b=y

10567

%special case for horizontal line, b=y

10655

b2=vref;

10568

b2=vref;

10656

%the x-value of line intersection = (b2-b1)/(m1-m2)

10569

%the x-value of line intersection = (b2-b1)/(m1-m2)

10657

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10570

%sinc m2 is always 0 and b2 is always vref, this could be stated as (vref-b1)/m1

10658

%And usually vref is 0, so it further reduces to -b1/m1

10571

%And usually vref is 0, so it further reduces to -b1/m1

10659

line_intersection=(b2-b1)/(m1-m2);

10572

line_intersection=(b2-b1)/(m1-m2);

10660

10573

10661

10574

10662

10575

10663

10576

10664

10577

10665

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10578

function p=xls_parameter(param_sheet, param_name, eval_if_string, default_value)

10666

% helper function to read parameter values from XLS file. Uses names to find values.

10579

% helper function to read parameter values from XLS file. Uses names to find values.

10667

if nargin<3, eval_if_string=0; end

10580

if nargin<3, eval_if_string=0; end

10668

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10581

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10669

if numel(row)*numel(col)==0

10582

if numel(row)*numel(col)==0

10670

if nargin<4

10583

if nargin<4

10671

missingParameter(param_name);

10584

missingParameter(param_name);

10672

else

10585

else

10673

p = default_value;

10586

p = default_value;

10674

end

10587

end

10675

elseif numel(row)*numel(col)>1

10588

elseif numel(row)*numel(col)>1

10676

% if there are several occurrences, use the first, but warn

10589

% if there are several occurrences, use the first, but warn

10677

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10590

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10678

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10591

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10679

error('COM:XLS_parameter:MultipleOccurrence', ...

10592

error('COM:XLS_parameter:MultipleOccurrence', ...

10680

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10593

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10681

p=param_sheet{row(1), col(1)+1};

10594

p=param_sheet{row(1), col(1)+1};

10682

else

10595

else

10683

p=param_sheet{row, col+1};

10596

p=param_sheet{row, col+1};

10684

end

10597

end

10685

if ischar(p) && eval_if_string

10598

if ischar(p) && eval_if_string

10686

p=eval(p);

10599

p=eval(p);

10687

end

10600

end

10688

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10601

OP.SAVE_KEYWORD_FILE=0; % OP not passed ... maybe later set to 1 manually to get keyword file.

10689

if OP.SAVE_KEYWORD_FILE

10602

if OP.SAVE_KEYWORD_FILE

10690

10603

10691

if nargin<3 || ~exist('default_value','var')

10604

if nargin<3 || ~exist('default_value','var')

10692

default_value=p;

10605

default_value=p;

10693

end

10606

end

10694

if isempty(default_value)

10607

if isempty(default_value)

10695

default_value='-';

10608

default_value='-';

10696

end

10609

end

10697

%%

10610

%%

10698

% Get call-stack info:

10611

% Get call-stack info:

10699

stDebug = dbstack;

10612

stDebug = dbstack;

10700

callerFileName = stDebug(2).file;

10613

callerFileName = stDebug(2).file;

10701

callerLineNumber = stDebug(2).line;

10614

callerLineNumber = stDebug(2).line;

10702

% Open caller file:

10615

% Open caller file:

10703

fCaller = fopen(callerFileName);

10616

fCaller = fopen(callerFileName);

10704

% Iterate through lines to get to desired line number:

10617

% Iterate through lines to get to desired line number:

10705

for iLine = 1 : callerLineNumber

10618

for iLine = 1 : callerLineNumber

10706

% Read current line of text:

10619

% Read current line of text:

10707

currLine = fgetl(fCaller);

10620

currLine = fgetl(fCaller);

10708

end

10621

end

10709

% (currLine) now reflects calling desired code: display this code:

10622

% (currLine) now reflects calling desired code: display this code:

10710

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10623

% fprintf('Complete text of calling code is : ''%s''\n',currLine);

10711

% Close caller file:

10624

% Close caller file:

10712

left_side=currLine(1:strfind(currLine,'=')-1);

10625

left_side=currLine(1:strfind(currLine,'=')-1);

10713

cmt_side=currLine(strfind(currLine,'%')+1:end);

10626

cmt_side=currLine(strfind(currLine,'%')+1:end);

10714

if isempty(cmt_side), cmt_side=' ';end

10627

if isempty(cmt_side), cmt_side=' ';end

10715

fclose(fCaller);

10628

fclose(fCaller);

10716

10629

10717

if ~ischar(default_value)

10630

if ~ischar(default_value)

10718

default_str=sprintf('%g ',default_value);

10631

default_str=sprintf('%g ',default_value);

10719

else

10632

else

10720

default_str=default_value;

10633

default_str=default_value;

10721

end

10634

end

10722

if ~isfile('keyworklog.mat')

10635

if ~isfile('keyworklog.mat')

10723

save_p=param_name;

10636

save_p=param_name;

10724

save_d=default_str;

10637

save_d=default_str;

10725

save_r=left_side;

10638

save_r=left_side;

10726

save_c=cmt_side;

10639

save_c=cmt_side;

10727

param_name = {'keyword'};

10640

param_name = {'keyword'};

10728

default_str = {'default'};

10641

default_str = {'default'};

10729

left_side={'matlab variable'};

10642

left_side={'matlab variable'};

10730

cmt_side={'info'};

10643

cmt_side={'info'};

10731

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10644

save('keyworklog.mat','left_side', 'param_name','default_str','cmt_side');

10732

param_name=save_p;

10645

param_name=save_p;

10733

default_str=save_d;

10646

default_str=save_d;

10734

left_side=save_r;

10647

left_side=save_r;

10735

cmt_side=save_c;

10648

cmt_side=save_c;

10736

data=load('keyworklog.mat');

10649

data=load('keyworklog.mat');

10737

else

10650

else

10738

load('keyworklog.mat');

10651

load('keyworklog.mat');

10739

end

10652

end

10740

data.left_side = [ data.left_side; left_side];

10653

data.left_side = [ data.left_side; left_side];

10741

data.param_name = [data.param_name; param_name];

10654

data.param_name = [data.param_name; param_name];

10742

data.default_str = [data.default_str; default_str ];

10655

data.default_str = [data.default_str; default_str ];

10743

data.cmt_side = [ data.cmt_side; cmt_side];

10656

data.cmt_side = [ data.cmt_side; cmt_side];

10744

if length(data.default_str)~=length(data.default_str)

10657

if length(data.default_str)~=length(data.default_str)

10745

a=1;

10658

a=1;

10746

end

10659

end

10747

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10660

T=table(data.left_side, data.param_name, data.default_str, data.cmt_side);

10748

save('keyworklog.mat','data');

10661

save('keyworklog.mat','data');

10749

writetable(T,[ 'keywords_' date '.csv' ]);

10662

writetable(T,[ 'keywords_' date '.csv' ]);

10750

end

10663

end

10751

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10664

function [p,found]=xls_parameter_txffe(param_sheet, param_name)

10752

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10665

% pretty much the same as "xls_parameter" but this is only used to dynamically find txffe

10753

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10666

% to make the search dynamic, the "found" output is returned to let the calling function know to stop searching

10754

10667

10755

found=1;

10668

found=1;

10756

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10669

[row, col]=find(strcmpi(param_sheet, param_name)); % RIM 08-26-2020 make case insensitive

10757

if numel(row)*numel(col)==0

10670

if numel(row)*numel(col)==0

10758

p = 0;

10671

p = 0;

10759

found=0;

10672

found=0;

10760

elseif numel(row)*numel(col)>1

10673

elseif numel(row)*numel(col)>1

10761

% if there are several occurrences, use the first, but warn

10674

% if there are several occurrences, use the first, but warn

10762

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10675

% warning('COM:XLS_parameter:MultipleOccurrence', ...

10763

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10676

% '%d occurrences of "%s" found. Using the first', numel(row), param_name);

10764

error('COM:XLS_parameter:MultipleOccurrence', ...

10677

error('COM:XLS_parameter:MultipleOccurrence', ...

10765

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10678

'%d occurrences of "%s" found. Please recheck spreadsheet', numel(row), param_name);% RIM 01-0 8-20

10766

p=param_sheet{row(1), col(1)+1};

10679

p=param_sheet{row(1), col(1)+1};

10767

else

10680

else

10768

p=param_sheet{row, col+1};

10681

p=param_sheet{row, col+1};

10769

end

10682

end

10770

if ischar(p)

10683

if ischar(p)

10771

p=eval(p);

10684

p=eval(p);

10772

end

10685

end

10773

function zzz_list_of_changes

10686

function zzz_list_of_changes

10774

% structures:

10687

% structures:

10775

% chdata(i)

10688

% chdata(i)

10776

% i= 1 --> THRU index

10689

% i= 1 --> THRU index

10777

% i= 2, num_fext+1 --> FEXT channel index

10690

% i= 2, num_fext+1 --> FEXT channel index

10778

% i= num_fext+2, num_next+num_fext+1

10691

% i= num_fext+2, num_next+num_fext+1

10779

% base: name of THRU file

10692

% base: name of THRU file

10780

% A: amplitude

10693

% A: amplitude

10781

% type: 'THRU', 'NEXT', or 'FEXT'

10694

% type: 'THRU', 'NEXT', or 'FEXT'

10782

% ftr: Rise time frequency

10695

% ftr: Rise time frequency

10783

% fmaxi: max number of frequency points

10696

% fmaxi: max number of frequency points

10784

% faxis: frequency array [Hz]

10697

% faxis: frequency array [Hz]

10785

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10698

% sdd21: (Htot) rewritten as product of ,vtf based on pkg RL ,tx filter, Rx filter

10786

% sdd22: differential RL

10699

% sdd22: differential RL

10787

% sdd11: differential RL

10700

% sdd11: differential RL

10788

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10701

% sdd21p: vtf based on pkg RL , this an interim parameter and set to sdd21

10789

% sdd21f: raw differential IL not filtered use for FD plots

10702

% sdd21f: raw differential IL not filtered use for FD plots

10790

% added output_args.peak_uneq_pulse_mV

10703

% added output_args.peak_uneq_pulse_mV

10791

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10704

% added output_args.cable_loss when "Include PCB" is not 0 in the config file

10792

% added: tap c(-2) c(2) and c(3)

10705

% added: tap c(-2) c(2) and c(3)

10793

% added: g_DC_HP and f_HP_PZ

10706

% added: g_DC_HP and f_HP_PZ

10794

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10707

% added: new value for "Include PCB" = 2 for cable Rx compliance test only Rx host added

10795

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10708

% added: BREAD_CRUMBS is 1 then a mat file with the structures params and OP is created in the results directory

10796

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10709

% added: T_r_filter_type for RITT testing when IDEAL_TX_TERM is 1:

10797

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10710

% added T_r_meas_point for RITT, if 0, measurement was at tp0, if 1 measurement was tp0a

10798

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10711

% 0 is for is for Gaussian filter and 1 is for a 4th order Bessel-Thomson filter

10799

% fixed INCLUDE_CTLE=0 to really remove from computation

10712

% fixed INCLUDE_CTLE=0 to really remove from computation

10800

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10713

% r161a fixed matlab version issue when for OP.INCLUDE_CTLE=0

10801

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10714

% r162 adjusting RITT rise time to Mike Dudek's recommendations also always enable risetime filter if T_r_filter_type=1

10802

% r162 tx and rx package impedance {Zc)

10715

% r162 tx and rx package impedance {Zc)

10803

% r162a Gaussian equation corrected

10716

% r162a Gaussian equation corrected

10804

% r163 cast snr_tx with package test case

10717

% r163 cast snr_tx with package test case

10805

% r164 fix pdf for very low noise and lo pass filter enhancements

10718

% r164 fix pdf for very low noise and lo pass filter enhancements

10806

% r164 add zero gain at nqyist CTLE as in CL12e

10719

% r164 add zero gain at nqyist CTLE as in CL12e

10807

% r165 add simpler congfig command called FORCE_TR (force risetime)

10720

% r165 add simpler congfig command called FORCE_TR (force risetime)

10808

% r200 cm3 and cm4 added cp3 removed

10721

% r200 cm3 and cm4 added cp3 removed

10809

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10722

% r200 fixed problem in s21_to_impulse_DC when s parameter have a DC entry

10810

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10723

% r200 ILD_FOM updated to EQ93A-55 ERL adde

10811

% r200 improved phase interpolation for return loss time conversion

10724

% r200 improved phase interpolation for return loss time conversion

10812

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10725

% r200a db = @(x) 20*log10(abs(x)) added so sig processing toolbox won't be required

10813

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10726

% r200b Fixed error in bifurcation of Tx/Rx Rd%

10814

% r200c missed on fix for interpolation

10727

% r200c missed on fix for interpolation

10815

% r210 new ERL with time gating function

10728

% r210 new ERL with time gating function

10816

% r224 update ERL with from D3.1

10729

% r224 update ERL with from D3.1

10817

% r226 fix s2p reading problem

10730

% r226 fix s2p reading problem

10818

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10731

% change SNR_ISI_XTK_normalized_1_sigma to SNR_ISI (with nulled noise)

10819

% Fix Rx calibration issue

10732

% Fix Rx calibration issue

10820

% added ERL limit and Nd

10733

% added ERL limit and Nd

10821

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10734

% r227 adding Pmax/Vf and peak of eq pulse, fixed issue with rx testing

10822

% INC_PACKAGE=0 not fully supported message

10735

% INC_PACKAGE=0 not fully supported message

10823

% if N=0 use TDR_duration

10736

% if N=0 use TDR_duration

10824

% red display text for fail ERL and COM

10737

% red display text for fail ERL and COM

10825

% r228 fixed ERL pass fail report, default Grr_limit to 1

10738

% r228 fixed ERL pass fail report, default Grr_limit to 1

10826

% r230 add rx ffe

10739

% r230 add rx ffe

10827

% r231 change crosstalk noise to icn like to speed things up

10740

% r231 change crosstalk noise to icn like to speed things up

10828

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10741

% r231 change default OP.impulse_response_truncation_threshold to 1e-3 from

10829

% 1e-5mof-

10742

% 1e-5mof-

10830

% r232 fix default for Rx eq so old spead sheets work

10743

% r232 fix default for Rx eq so old spead sheets work

10831

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10744

% r234 fix inadvertent typo for clause 120e ctle and problem with TXffe loop time reduction

10832

% r235 adding dfe quantization changed to normalized DFE taps reported

10745

% r235 adding dfe quantization changed to normalized DFE taps reported

10833

% r236 adding ffe gain loop and resample after RxFFE

10746

% r236 adding ffe gain loop and resample after RxFFE

10834

% r240 added output for C2M and setting defaults for some FFE eq

10747

% r240 added output for C2M and setting defaults for some FFE eq

10835

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10748

% r241 force FFE main cursor to 1 and remove sum of taps = 1

10836

% r250 adding more complex package

10749

% r250 adding more complex package

10837

% r251 post cursor fix for DFE in force() and ffe backoff

10750

% r251 post cursor fix for DFE in force() and ffe backoff

10838

% r251 remove TDR threshold noise filter

10751

% r251 remove TDR threshold noise filter

10839

% r252 add rx FFE filter to receiver noise filter

10752

% r252 add rx FFE filter to receiver noise filter

10840

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10753

% r252 change ICN in the xtk noise calculation to end at fb rather than fb/2

10841

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10754

% r253 a few bug fixes in force from i indexing and for no ffe postcursors

10842

% r254 precursor check fix in optimize_fom % mod fix in force

10755

% r254 precursor check fix in optimize_fom % mod fix in force

10843

% r254 help to align columns in csv file

10756

% r254 help to align columns in csv file

10844

% r254 accept syntax for 2 tline flex package model

10757

% r254 accept syntax for 2 tline flex package model

10845

% r256 speed up optimize FOM

10758

% r256 speed up optimize FOM

10846

% r256 fix problem reading in config file from q/a

10759

% r256 fix problem reading in config file from q/a

10847

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10760

% r256 added code from Yasou Hidaka for reading in parameter an and printing out noise

10848

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10761

% r257 fixed extrapolation of channel with lower bandwidths in s21_to_impulse_DC

10849

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10762

% r257 in get_xtlk_noise in optimize_FOM: reomove crosstalk double counting and apply TXFFE is FEXT

10850

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10763

% r258 EXE_MODE switch 12/21 0:legacy 1:fast 2:superfast

10851

% r258 CDR switch 'MM' or 'mod-MM'

10764

% r258 CDR switch 'MM' or 'mod-MM'

10852

% r258 correction for asymentirc tx/Rx packages

10765

% r258 correction for asymentirc tx/Rx packages

10853

% r258 revamped display results display window

10766

% r258 revamped display results display window

10854

% r259 fix problem if Min_VEO is set in spreadsheet.

10767

% r259 fix problem if Min_VEO is set in spreadsheet.

10855

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10768

% r259 fix problem in optimize_FOM. get_xtlk_noise need to have 3 output

10856

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10769

% parameter else only FEXT is considered for FOM.zhilei huang 01/11/2019

10857

% r259 putting COM_db and IL last in output to terminal

10770

% r259 putting COM_db and IL last in output to terminal

10858

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10771

% r259 msgtext change to msg for C2C case other cases not vetted but not presently used

10859

% r259 use N_bx for ERL rather than Nb (ndfe))

10772

% r259 use N_bx for ERL rather than Nb (ndfe))

10860

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10773

% r259 added TDR_W_TXPKG which performs TDR and ERL with the Tx package added

10861

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10774

% r260 r259 used rd for the reciever to terminate the package. It was changed to the rd of the transmitter

10862

% r260 used eta_0 PSD equation for sigma_n

10775

% r260 used eta_0 PSD equation for sigma_n

10863

% r260 fix IL graph legend to w/pkg and Tr

10776

% r260 fix IL graph legend to w/pkg and Tr

10864

% r260 define tfx for each port

10777

% r260 define tfx for each port

10865

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10778

% r262 fx parameter passing parsing for mod_string revert to 2.57 no COM computational impact

10866

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10779

% r262 Report estimate for DER for channel (Yasuo 2/30/19)

10867

% r262 reset on exit default text interpreter to tex

10780

% r262 reset on exit default text interpreter to tex

10868

% r262 localize run timer (John Buck 1/17/19)

10781

% r262 localize run timer (John Buck 1/17/19)

10869

% r262 set db as internal function in force to avoid tool box

10782

% r262 set db as internal function in force to avoid tool box

10870

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10783

% r262 changed loop for Grr and Gloss in get_tdr so that nbx and tfx works when beta x = 0

10871

% r263 added to output_args RL structure and report "struct" in csv file

10784

% r263 added to output_args RL structure and report "struct" in csv file

10872

% r264 added EW estimate

10785

% r264 added EW estimate

10873

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10786

% r266 using unequalized IR for Vf and Vf to compute ratio of Vp/Vf

10874

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10787

% r267 added floating taps with param.N_bf, param.N_bg, param.N_bmax, param.bmaxg. groups not used for ERL

10875

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10788

% r268 added sequential/co-optimization switch for floating tap banks OP.FT_COOP default 0 i.e. sequential

10876

% r269 changed param.N_bmax to param.N_f

10789

% r269 changed param.N_bmax to param.N_f

10877

% r270 implement JingBo Li's and Howard Heck's floating tap method

10790

% r270 implement JingBo Li's and Howard Heck's floating tap method

10878

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10791

% r270 modification by Adam Healey for Ls and Cb termination (aka t-coil emulation)

10879

% r270 added c_0 and c_1 for CA in add_brd

10792

% r270 added c_0 and c_1 for CA in add_brd

10880

% r272 fixed version syntax problem in output_args RL report

10793

% r272 fixed version syntax problem in output_args RL report

10881

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10794

% r272 fixed eye width computation problem crosstalk was missed in pervious versions

10882

% r272 removed eye width report if doing a Rx calibration

10795

% r272 removed eye width report if doing a Rx calibration

10883

% r273 better alignment and control for ICN reporting

10796

% r273 better alignment and control for ICN reporting

10884

% r273 fixed PSXTK graph

10797

% r273 fixed PSXTK graph

10885

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10798

% r275 fixed delay adjustment for ERL/TDR in get_TDR (Adam Healey 09/06/2019)

10886

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10799

% r276 go back to reporting channel IL results (output_args.IL_dB_channel_only_at_Fnq) with board added read_s4p_files (as in r270)

10887

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10800

% r276 chdata(i).Aicn=param.a_icn_fext should have been chdata(i).Aicn=param.a_icn_next for the next selection. Since in most spec's they are the same there is little no impact in results

10888

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10801

% r276 test for output_args for isfield(chdata(1),'sdd22_raw')

10889

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10802

% r276 change divisor for ICN and FOM_ILD to param.f2 from param.fb, may raise ICN and ILD value reported in r275

10890

% r276 C_1 was instantiated as C_0. This was fixed

10803

% r276 C_1 was instantiated as C_0. This was fixed

10891

% r276 fixed rounding problem in reporting of loss at f_nq

10804

% r276 fixed rounding problem in reporting of loss at f_nq

10892

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10805

% r276 power limit (RSS) for tail DFE taps (B_float_RSS_MAX, N_tail_start)

10893

% r277 added nv for deterining steady state voltage for fitting compatibility

10806

% r277 added nv for deterining steady state voltage for fitting compatibility

10894

% r278 added b_min to support asymmetric bmax

10807

% r278 added b_min to support asymmetric bmax

10895

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10808

% r278 added kappa1 and kappa2 to scale package to channel reflection for ERL experiments

10896

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10809

% r278 added keyword OP.SHOW_BRD which includes added board in TDR and ERL

10897

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10810

% r292 speed up for FOM search (Adee Ran) implemented by Adam Gregory.

10898

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10811

% r292 param.LOCAL_SEARCH set to is the heuristic step distance keyword is 'Local Search'

10899

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10812

% r292 fixing TDR for different impedance references in get_TDR and s2p file compatibility

10900

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10813

% r292 eq. 93A-19 and 93-20 code implementation bug when include .3by change% to fix edge rate equation 93A-46 (h_T). no effect if Rd=50 or IL > 5 dB

10901

% r292 H_t implemented in s21_pkg

10814

% r292 H_t implemented in s21_pkg

10902

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10815

% r292 plot and report for die to die IL remove the Tr effect "IL with pkgs & Tr filter" goes to "IL with pkgs"

10903

% r292 add GDC_MIN to optimize_FOM

10816

% r292 add GDC_MIN to optimize_FOM

10904

% r293 fix if ndfe-0 and ERL only and s2p issue

10817

% r293 fix if ndfe-0 and ERL only and s2p issue

10905

% r293a investigate the Tukey filtering

10818

% r293a investigate the Tukey filtering

10906

% r293a if fix if bmin is missing

10819

% r293a if fix if bmin is missing

10907

% r294 fix problems reading s2p files for ERL computation

10820

% r294 fix problems reading s2p files for ERL computation

10908

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10821

% r294 align Tukey_Window with .3ck definition for ERL and TDR computations

10909

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10822

% r294 add parameter param.Noise_Crest_Factor. Default is not to use

10910

% r294 add gdc and gdc2 range limitations

10823

% r294 add gdc and gdc2 range limitations

10911

% r295 add VEC Pass threshold

10824

% r295 add VEC Pass threshold

10912

% r295 removed close force all. Tagged all figures with "COM"

10825

% r295 removed close force all. Tagged all figures with "COM"

10913

% r295 consolidated print in new function "end_display_control"

10826

% r295 consolidated print in new function "end_display_control"

10914

% r295 report pre/pmax for Txffe

10827

% r295 report pre/pmax for Txffe

10915

% r295 speed up test cases by not re-reading in s4p files

10828

% r295 speed up test cases by not re-reading in s4p files

10916

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10829

% r297 add provisions for AC_CM_RMS for through CM (experimental)

10917

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10830

% r299 add keyword T_O (param.T_O) and samples_for_C2M (parsm.samples_for_C2M) for new C2M VEC and EH computations

10918

% r310 refine VEC and EH for C2M from Adam Gregory in

10831

% r310 refine VEC and EH for C2M from Adam Gregory in

10919

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10832

% r315 added keyword for Bessel_Thomson and Butterworth(default) filter.

10920

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10833

% cdf_to_ber_contour,COM_eye_width,combine_pdf_same_voltage_axis,

10921

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10834

% optimize_fom_for_C2M. pdf_to_cdf, conv_fct_MeanNotZero, and get_pdf_full

10922

% r311 added RILN

10835

% r311 added RILN

10923

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10836

% r314 when T_O is not zero 3 eyes are used to compute VEC and VEO

10924

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10837

% r315 Bessel_Thomson keyword is added mostly for measuring Pmax, Vf, and SNDR

10925

% r316 remove DC computation for RX Calibration loops

10838

% r316 remove DC computation for RX Calibration loops

10926

% r317 for SAVE_TD to include EQ and unEQ FIR

10839

% r317 for SAVE_TD to include EQ and unEQ FIR

10927

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10840

% r317 clean up bessel thomson and butterworth filter logic for ERL and normal COM

10928

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10841

% r318 if min_VEO_test fails to find a solution the loop is restarted with min_VEO_test to near zero. Makes sure COM returns results

10929

% r320 fixed RX_CALIBRATION which was broken in r310

10842

% r320 fixed RX_CALIBRATION which was broken in r310

10930

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10843

% r320 speed up for C2M by moving managing optimize loop distribution of computations

10931

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10844

% r320 for C2M added Gaussian window keyword, Gaussian_histogram_window, for T_O and keyword, QL which is at Q limit at +/-T_O

10932

% r320 removed external feature and replace with TDMODE

10845

% r320 removed external feature and replace with TDMODE

10933

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10846

% r320 added TDMODE which allows for the use of pulse resonance files (CSV) instead of s4p files

10934

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10847

% r330 changed FOM ILN to use a complex fit and compute FOM_ILN in the time domain330 added tfx to N for ERL

10935

% r335 fixed typo in when processing the bessel thompson filter option

10848

% r335 fixed typo in when processing the bessel thompson filter option

10936

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10849

% r335 process in CD mode instead of DC mode to get CM noise at Rx

10937

% r335 compute and report CD_CM_RMS

10850

% r335 compute and report CD_CM_RMS

10938

% r335 fixed where output_arg is save i.e. move to end

10851

% r335 fixed where output_arg is save i.e. move to end

10939

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10852

% r335 refine interp_Sparam to do zero fill instead of extrapolation

10940

% r335 change raw IL plot to not include boards

10853

% r335 change raw IL plot to not include boards

10941

% r335 set T_0 to zero if not C2M

10854

% r335 set T_0 to zero if not C2M

10942

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10855

% r335 change for s parameter interp: check fit sigma, if not OK zero fill

10943

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10856

% r335 added actual sdd12 (instead fo mirroring sdd21) to s21_pkg and 21dc_pkg and read_s4p_files

10944

% r335 TD_RILN changes from Hansel Dsilva

10857

% r335 TD_RILN changes from Hansel Dsilva

10945

% r335 Fixed sigma_N for RxFFE

10858

% r335 Fixed sigma_N for RxFFE

10946

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10859

% r335 added more to self documenting keyword capability from read_ParamConfigFile and xls_parameter routines

10947

% r335 added c(2) and C(3) back to read_ParamConfigFile

10860

% r335 added c(2) and C(3) back to read_ParamConfigFile

10948

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10861

% r335 Optimize_loop_speed_up keyword option added. Mostly speeds up c2m(vsr)

10949

% r335 corrected GDC_MIN per 0.3ck D2.3

10862

% r335 corrected GDC_MIN per 0.3ck D2.3

10950

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10863

% r335 sigma_r replaces Qr which replaced QL for Gaussian histogram window

10951

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10864

% r340 fix for when post cursor taps 2 and 3 are used (from Matt Brown)

10952

% r370 speed up

10865

% r370 speed up

10953

% r370 fix for floating tap missing locations

10866

% r370 fix for floating tap missing locations

10954

% r370 variable Tx FFE taps

10867

% r370 variable Tx FFE taps

10955

% r370 package die load with ladder circuit

10868

% r370 package die load with ladder circuit

10956

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10869

% r370 mods for SNDR_tx exporation using keyword SNR_TXwC0

10957

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10870

% r380 fix for Rx Calibaration (error introduced going from 3.4 to 3.7)

10958

% r380 added capabablity to enable a raised cosine Rx filter0

10871

% r380 added capabablity to enable a raised cosine Rx filter0

10959

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10872

% r380 keyword added: RC_Start, RC_end, Raised_Cosine

10960

% r380 added plot for VTF

10873

% r380 added plot for VTF

10961

% r385 added capability for additional Tx FFE per package

10874

% r385 added capability for additional Tx FFE per package

10962

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10875

% r385 keyword added: PKG_Tx_FFE_preset default is 0 i.e. noop

10963

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10876

% r385 SAVE_CONFIG2MAT set to 0 as default i.e. don't create a conifig mat file(

10964

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10877

% r388 Adjusted Rx caliberation for CL 162 i.e. adding Tx noise (sigma hn) instead of Rx noise line

10965

% r389 Improvement by A. Ran for reporting loss at Nq

10878

% r389 Improvement by A. Ran for reporting loss at Nq

10966

% r389 Fixed typo: changed VIM to VMP

10879

% r389 Fixed typo: changed VIM to VMP

10967

% r400 fixed PR with zero pad extension

10880

% r400 fixed PR with zero pad extension

10968

% r400 keyword MLSE and SNRADJ_EQUA for future work

10881

% r400 keyword MLSE and SNRADJ_EQUA for future work

10969

% r400 replaced function db with instances of 20*log10(abs(...))

10882

% r400 replaced function db with instances of 20*log10(abs(...))

10970

% r410 widen voltage distriution for normal_dist doubled max Q

10883

% r410 widen voltage distriution for normal_dist doubled max Q

10971

% r410 improve reading in of config files

10884

% r410 improve reading in of config files

10972

% r410 renormalize s-parameter if not 50 ohm ref

10885

% r410 renormalize s-parameter if not 50 ohm ref

10973

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10886

% r410 reference for RXFFE changed to MM from UI+zero first precursor

10974

% r410 remove RL from output_args bc not need and too much storage allocation

10887

% r410 remove RL from output_args bc not need and too much storage allocation

10975

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10888

% r410 s21^2 changed to s12*s21 in s21_pkg. Corrected VTF needed for non-passive sparameters

10976

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10889

% r420 updated equalization figures. if Rxffe is use a subplot of Rx FFE taps is graphed

10977

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10890

% r420 updated equalization figures. Now separate per pkg case in optimize_fom

10978

% r420 updade force to account for pulse responces with short delays in force

10891

% r420 updade force to account for pulse responces with short delays in force

10979

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10892

% r420 added Tx/Rx p/n skew with keywords Txpskew, Txnskew, Rxpskew, Pxnskew

10980

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10893

% r420 add common mode outputs: VMC_H_mV and SCMR_dB from CDF of CD PR and DD PR

10981

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10894

% r420 fixed and added control for RXFFE_TAP_CONSTRAINT and RXFFE_FLOAT_CTL

10982

% r420 Wiener-Kofp MMSE optimization for RxFFE

10895

% r420 Wiener-Kofp MMSE optimization for RxFFE

10983

% r430 first pass at healey_3dj_01_2401

10896

% r430 first pass at healey_3dj_01_2401

10984

% r430 RxFFE fixed taps

10897

% r430 RxFFE fixed taps

10985

% r440 RxffE fixed tap index corrections and floating taps

10898

% r440 RxffE fixed tap index corrections and floating taps

10986

% r440 first pass implemenation of MLSE U3

10899

% r440 first pass implemenation of MLSE U3

10987

% r450 fix MLSE_FOM typos, sigma_e,and FOM.

10988

% r450 incude Hisi in PSD in get_PSDs

10989

% r460 is working out reporting bug from RxFFE and package A,B invocations

10990

% r460 align package config Tx and Rx cases with selected casting 4p5_3

10991

% r460 fix RxFFE floating taps display (indexing error) 4p5_4

10992

10900